Skip to content

Commit 607ac90

Browse files
lundibundiMylesBorins
authored andcommitted
lib: improve value validation utils
Add common validators: `validateArray`, `validateBoolean`, `validateObject` and appropriate tests. PR-URL: #31480 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Gus Caplan <[email protected]>
1 parent eaf6723 commit 607ac90

File tree

2 files changed

+104
-15
lines changed

2 files changed

+104
-15
lines changed

lib/internal/validators.js

+28
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
const {
4+
ArrayIsArray,
45
NumberIsInteger,
56
NumberMAX_SAFE_INTEGER,
67
NumberMIN_SAFE_INTEGER,
@@ -123,6 +124,30 @@ function validateNumber(value, name) {
123124
throw new ERR_INVALID_ARG_TYPE(name, 'number', value);
124125
}
125126

127+
function validateBoolean(value, name) {
128+
if (typeof value !== 'boolean')
129+
throw new ERR_INVALID_ARG_TYPE(name, 'boolean', value);
130+
}
131+
132+
const validateObject = hideStackFrames(
133+
(value, name, { nullable = false } = {}) => {
134+
if ((!nullable && value === null) ||
135+
ArrayIsArray(value) ||
136+
typeof value !== 'object') {
137+
throw new ERR_INVALID_ARG_TYPE(name, 'Object', value);
138+
}
139+
});
140+
141+
const validateArray = hideStackFrames((value, name, { minLength = 0 } = {}) => {
142+
if (!ArrayIsArray(value)) {
143+
throw new ERR_INVALID_ARG_TYPE(name, 'Array', value);
144+
}
145+
if (value.length < minLength) {
146+
const reason = `must be longer than ${minLength}`;
147+
throw new ERR_INVALID_ARG_VALUE(name, value, reason);
148+
}
149+
});
150+
126151
function validateSignalName(signal, name = 'signal') {
127152
if (typeof signal !== 'string')
128153
throw new ERR_INVALID_ARG_TYPE(name, 'string', signal);
@@ -159,8 +184,11 @@ module.exports = {
159184
isInt32,
160185
isUint32,
161186
parseMode,
187+
validateArray,
188+
validateBoolean,
162189
validateBuffer,
163190
validateEncoding,
191+
validateObject,
164192
validateInteger,
165193
validateInt32,
166194
validateUint32,

test/parallel/test-validators.js

+76-15
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,87 @@
11
// Flags: --expose-internals
22
'use strict';
3+
34
require('../common');
45
const assert = require('assert');
56
const {
6-
validateInteger
7+
validateArray,
8+
validateBoolean,
9+
validateInteger,
10+
validateObject,
711
} = require('internal/validators');
812
const { MAX_SAFE_INTEGER, MIN_SAFE_INTEGER } = Number;
913
const outOfRangeError = {
1014
code: 'ERR_OUT_OF_RANGE',
11-
name: 'RangeError'
15+
name: 'RangeError',
16+
};
17+
const invalidArgTypeError = {
18+
code: 'ERR_INVALID_ARG_TYPE',
19+
name: 'TypeError',
1220
};
21+
const invalidArgValueError = {
22+
code: 'ERR_INVALID_ARG_VALUE',
23+
name: 'TypeError',
24+
};
25+
26+
{
27+
// validateInteger tests.
28+
29+
// validateInteger() defaults to validating safe integers.
30+
validateInteger(MAX_SAFE_INTEGER, 'foo');
31+
validateInteger(MIN_SAFE_INTEGER, 'foo');
32+
assert.throws(() => {
33+
validateInteger(MAX_SAFE_INTEGER + 1, 'foo');
34+
}, outOfRangeError);
35+
assert.throws(() => {
36+
validateInteger(MIN_SAFE_INTEGER - 1, 'foo');
37+
}, outOfRangeError);
38+
39+
// validateInteger() works with unsafe integers.
40+
validateInteger(MAX_SAFE_INTEGER + 1, 'foo', 0, MAX_SAFE_INTEGER + 1);
41+
validateInteger(MIN_SAFE_INTEGER - 1, 'foo', MIN_SAFE_INTEGER - 1);
42+
}
43+
44+
{
45+
// validateArray tests.
46+
validateArray([], 'foo');
47+
validateArray([1, 2, 3], 'foo');
48+
49+
[undefined, null, true, false, 0, 0.0, 42, '', 'string', {}]
50+
.forEach((val) => {
51+
assert.throws(() => {
52+
validateArray(val, 'foo');
53+
}, invalidArgTypeError);
54+
});
55+
56+
validateArray([1], 'foo', { minLength: 1 });
57+
assert.throws(() => {
58+
validateArray([], 'foo', { minLength: 1 });
59+
}, invalidArgValueError);
60+
}
61+
62+
{
63+
// validateBoolean tests.
64+
validateBoolean(true, 'foo');
65+
validateBoolean(false, 'foo');
66+
67+
[undefined, null, 0, 0.0, 42, '', 'string', {}, []].forEach((val) => {
68+
assert.throws(() => {
69+
validateBoolean(val, 'foo');
70+
}, invalidArgTypeError);
71+
});
72+
}
73+
74+
{
75+
// validateObject tests.
76+
validateObject({}, 'foo');
77+
validateObject({ a: 42, b: 'foo' }, 'foo');
78+
79+
[undefined, null, true, false, 0, 0.0, 42, '', 'string', []]
80+
.forEach((val) => {
81+
assert.throws(() => {
82+
validateObject(val, 'foo');
83+
}, invalidArgTypeError);
84+
});
1385

14-
// validateInteger() defaults to validating safe integers.
15-
validateInteger(MAX_SAFE_INTEGER, 'foo');
16-
validateInteger(MIN_SAFE_INTEGER, 'foo');
17-
assert.throws(() => {
18-
validateInteger(MAX_SAFE_INTEGER + 1, 'foo');
19-
}, outOfRangeError);
20-
assert.throws(() => {
21-
validateInteger(MIN_SAFE_INTEGER - 1, 'foo');
22-
}, outOfRangeError);
23-
24-
// validateInteger() works with unsafe integers.
25-
validateInteger(MAX_SAFE_INTEGER + 1, 'foo', 0, MAX_SAFE_INTEGER + 1);
26-
validateInteger(MIN_SAFE_INTEGER - 1, 'foo', MIN_SAFE_INTEGER - 1);
86+
validateObject(null, 'foo', { nullable: true });
87+
}

0 commit comments

Comments
 (0)