Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 04defba

Browse filesBrowse files
lundibundiBethGriggs
authored andcommitted
lib: allow to validate enums with validateOneOf
PR-URL: #34070 Reviewed-By: Zeyu Yang <himself65@outlook.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 258f64f commit 04defba
Copy full SHA for 04defba

File tree

Expand file treeCollapse file tree

10 files changed

+108
-40
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

10 files changed

+108
-40
lines changed
Open diff view settings
Collapse file

‎lib/_http_agent.js‎

Copy file name to clipboardExpand all lines: lib/_http_agent.js
+2-5Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,11 @@ const { async_id_symbol } = require('internal/async_hooks').symbols;
3939
const {
4040
codes: {
4141
ERR_INVALID_ARG_TYPE,
42-
ERR_INVALID_OPT_VALUE,
4342
ERR_OUT_OF_RANGE,
4443
},
4544
} = require('internal/errors');
4645
const { once } = require('internal/util');
47-
const { validateNumber } = require('internal/validators');
46+
const { validateNumber, validateOneOf } = require('internal/validators');
4847

4948
const kOnKeylog = Symbol('onkeylog');
5049
const kRequestOptions = Symbol('requestOptions');
@@ -99,9 +98,7 @@ function Agent(options) {
9998
this.maxTotalSockets = this.options.maxTotalSockets;
10099
this.totalSocketCount = 0;
101100

102-
if (this.scheduling !== 'fifo' && this.scheduling !== 'lifo') {
103-
throw new ERR_INVALID_OPT_VALUE('scheduling', this.scheduling);
104-
}
101+
validateOneOf(this.scheduling, 'scheduling', ['fifo', 'lifo'], true);
105102

106103
if (this.maxTotalSockets !== undefined) {
107104
validateNumber(this.maxTotalSockets, 'maxTotalSockets');
Collapse file

‎lib/dns.js‎

Copy file name to clipboardExpand all lines: lib/dns.js
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ const {
4949
const {
5050
validatePort,
5151
validateString,
52+
validateOneOf,
5253
} = require('internal/validators');
5354

5455
const {
@@ -114,8 +115,7 @@ function lookup(hostname, options, callback) {
114115
family = options >>> 0;
115116
}
116117

117-
if (family !== 0 && family !== 4 && family !== 6)
118-
throw new ERR_INVALID_OPT_VALUE('family', family);
118+
validateOneOf(family, 'family', [0, 4, 6], true);
119119

120120
if (!hostname) {
121121
emitInvalidHostnameWarning(hostname);
Collapse file

‎lib/internal/child_process.js‎

Copy file name to clipboardExpand all lines: lib/internal/child_process.js
+3-7Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const {
2121
ERR_MISSING_ARGS
2222
}
2323
} = require('internal/errors');
24-
const { validateString } = require('internal/validators');
24+
const { validateString, validateOneOf } = require('internal/validators');
2525
const EventEmitter = require('events');
2626
const net = require('net');
2727
const dgram = require('dgram');
@@ -345,13 +345,9 @@ ChildProcess.prototype.spawn = function(options) {
345345
const ipcFd = stdio.ipcFd;
346346
stdio = options.stdio = stdio.stdio;
347347

348-
if (options.serialization !== undefined &&
349-
options.serialization !== 'json' &&
350-
options.serialization !== 'advanced') {
351-
throw new ERR_INVALID_OPT_VALUE('options.serialization',
352-
options.serialization);
353-
}
354348

349+
validateOneOf(options.serialization, 'options.serialization',
350+
[undefined, 'json', 'advanced'], true);
355351
const serialization = options.serialization || 'json';
356352

357353
if (ipc !== undefined) {
Collapse file

‎lib/internal/dns/promises.js‎

Copy file name to clipboardExpand all lines: lib/internal/dns/promises.js
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ const {
3131
} = codes;
3232
const {
3333
validatePort,
34-
validateString
34+
validateString,
35+
validateOneOf,
3536
} = require('internal/validators');
3637

3738
function onlookup(err, addresses) {
@@ -116,8 +117,7 @@ function lookup(hostname, options) {
116117
family = options >>> 0;
117118
}
118119

119-
if (family !== 0 && family !== 4 && family !== 6)
120-
throw new ERR_INVALID_OPT_VALUE('family', family);
120+
validateOneOf(family, 'family', [0, 4, 6], true);
121121

122122
return createLookupPromise(family, hostname, all, hints, verbatim);
123123
}
Collapse file

‎lib/internal/validators.js‎

Copy file name to clipboardExpand all lines: lib/internal/validators.js
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const {
1313
ERR_SOCKET_BAD_PORT,
1414
ERR_INVALID_ARG_TYPE,
1515
ERR_INVALID_ARG_VALUE,
16+
ERR_INVALID_OPT_VALUE,
1617
ERR_OUT_OF_RANGE,
1718
ERR_UNKNOWN_SIGNAL,
1819
ERR_INVALID_CALLBACK,
@@ -126,6 +127,21 @@ function validateNumber(value, name) {
126127
throw new ERR_INVALID_ARG_TYPE(name, 'number', value);
127128
}
128129

130+
const validateOneOf = hideStackFrames((value, name, oneOf, option = false) => {
131+
if (!oneOf.includes(value)) {
132+
const allowed = oneOf
133+
.map((v) => (typeof v === 'string' ? `'${v}'` : String(v)))
134+
.join(', ');
135+
if (!option) {
136+
const reason = 'must be one of: ' + allowed;
137+
throw new ERR_INVALID_ARG_VALUE(name, value, reason);
138+
} else {
139+
const reason = 'Must be one of: ' + allowed;
140+
throw new ERR_INVALID_OPT_VALUE(name, value, reason);
141+
}
142+
}
143+
});
144+
129145
function validateBoolean(value, name) {
130146
if (typeof value !== 'boolean')
131147
throw new ERR_INVALID_ARG_TYPE(name, 'boolean', value);
@@ -212,6 +228,7 @@ module.exports = {
212228
validateInteger,
213229
validateNumber,
214230
validateObject,
231+
validateOneOf,
215232
validatePort,
216233
validateSignalName,
217234
validateString,
Collapse file

‎lib/vm.js‎

Copy file name to clipboardExpand all lines: lib/vm.js
+6-20Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ const {
3939
const {
4040
ERR_CONTEXT_NOT_INITIALIZED,
4141
ERR_INVALID_ARG_TYPE,
42-
ERR_INVALID_ARG_VALUE,
4342
} = require('internal/errors').codes;
4443
const {
4544
isArrayBufferView,
@@ -52,6 +51,7 @@ const {
5251
validateBoolean,
5352
validateBuffer,
5453
validateObject,
54+
validateOneOf,
5555
} = require('internal/validators');
5656
const {
5757
kVmBreakFirstLineSymbol,
@@ -246,17 +246,11 @@ function createContext(contextObject = {}, options = {}) {
246246

247247
let microtaskQueue = null;
248248
if (microtaskMode !== undefined) {
249-
validateString(microtaskMode, 'options.microtaskMode');
249+
validateOneOf(microtaskMode, 'options.microtaskMode',
250+
['afterEvaluate', undefined]);
250251

251-
if (microtaskMode === 'afterEvaluate') {
252+
if (microtaskMode === 'afterEvaluate')
252253
microtaskQueue = new MicrotaskQueue();
253-
} else {
254-
throw new ERR_INVALID_ARG_VALUE(
255-
'options.microtaskQueue',
256-
microtaskQueue,
257-
'must be \'afterEvaluate\' or undefined'
258-
);
259-
}
260254
}
261255

262256
makeContext(contextObject, name, origin, strings, wasm, microtaskQueue);
@@ -395,16 +389,8 @@ function measureMemory(options = {}) {
395389
emitExperimentalWarning('vm.measureMemory');
396390
validateObject(options, 'options');
397391
const { mode = 'summary', execution = 'default' } = options;
398-
if (mode !== 'summary' && mode !== 'detailed') {
399-
throw new ERR_INVALID_ARG_VALUE(
400-
'options.mode', options.mode,
401-
'must be either \'summary\' or \'detailed\'');
402-
}
403-
if (execution !== 'default' && execution !== 'eager') {
404-
throw new ERR_INVALID_ARG_VALUE(
405-
'options.execution', options.execution,
406-
'must be either \'default\' or \'eager\'');
407-
}
392+
validateOneOf(mode, 'options.mode', ['summary', 'detailed']);
393+
validateOneOf(execution, 'options.execution', ['default', 'eager']);
408394
const result = _measureMemory(measureMemoryModes[mode],
409395
measureMemoryExecutions[execution]);
410396
if (result === undefined) {
Collapse file

‎test/parallel/test-child-process-advanced-serialization.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-child-process-advanced-serialization.js
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ if (process.argv[2] !== 'child') {
1111
}, {
1212
code: 'ERR_INVALID_OPT_VALUE',
1313
message: `The value "${value}" is invalid ` +
14-
'for option "options.serialization"'
14+
'for option "options.serialization". ' +
15+
"Must be one of: undefined, 'json', 'advanced'"
1516
});
1617
}
1718

Collapse file

‎test/parallel/test-dns-lookup.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-dns-lookup.js
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ assert.throws(() => {
7272
const err = {
7373
code: 'ERR_INVALID_OPT_VALUE',
7474
name: 'TypeError',
75-
message: 'The value "20" is invalid for option "family"'
75+
message: 'The value "20" is invalid for option "family". ' +
76+
'Must be one of: 0, 4, 6'
7677
};
7778
const options = {
7879
hints: 0,
Collapse file

‎test/parallel/test-http-agent-scheduling.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-http-agent-scheduling.js
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ function badSchedulingOptionTest() {
137137
assert.strictEqual(err.code, 'ERR_INVALID_OPT_VALUE');
138138
assert.strictEqual(
139139
err.message,
140-
'The value "filo" is invalid for option "scheduling"'
140+
'The value "filo" is invalid for option "scheduling". ' +
141+
"Must be one of: 'fifo', 'lifo'"
141142
);
142143
}
143144
}
Collapse file
+69Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Flags: --expose-internals
2+
'use strict';
3+
4+
require('../common');
5+
const assert = require('assert');
6+
const { validateOneOf } = require('internal/validators');
7+
8+
{
9+
// validateOneOf number incorrect.
10+
const allowed = [2, 3];
11+
assert.throws(() => validateOneOf(1, 'name', allowed), {
12+
code: 'ERR_INVALID_ARG_VALUE',
13+
// eslint-disable-next-line quotes
14+
message: `The argument 'name' must be one of: 2, 3. Received 1`
15+
});
16+
assert.throws(() => validateOneOf(1, 'name', allowed, true), {
17+
code: 'ERR_INVALID_OPT_VALUE',
18+
message: 'The value "1" is invalid for option "name". ' +
19+
'Must be one of: 2, 3'
20+
});
21+
}
22+
23+
{
24+
// validateOneOf number correct.
25+
validateOneOf(2, 'name', [1, 2]);
26+
}
27+
28+
{
29+
// validateOneOf string incorrect.
30+
const allowed = ['b', 'c'];
31+
assert.throws(() => validateOneOf('a', 'name', allowed), {
32+
code: 'ERR_INVALID_ARG_VALUE',
33+
// eslint-disable-next-line quotes
34+
message: `The argument 'name' must be one of: 'b', 'c'. Received 'a'`
35+
});
36+
assert.throws(() => validateOneOf('a', 'name', allowed, true), {
37+
code: 'ERR_INVALID_OPT_VALUE',
38+
// eslint-disable-next-line quotes
39+
message: `The value "a" is invalid for option "name". ` +
40+
"Must be one of: 'b', 'c'",
41+
});
42+
}
43+
44+
{
45+
// validateOneOf string correct.
46+
validateOneOf('two', 'name', ['one', 'two']);
47+
}
48+
49+
{
50+
// validateOneOf Symbol incorrect.
51+
const allowed = [Symbol.for('b'), Symbol.for('c')];
52+
assert.throws(() => validateOneOf(Symbol.for('a'), 'name', allowed), {
53+
code: 'ERR_INVALID_ARG_VALUE',
54+
// eslint-disable-next-line quotes
55+
message: `The argument 'name' must be one of: Symbol(b), Symbol(c). ` +
56+
'Received Symbol(a)'
57+
});
58+
assert.throws(() => validateOneOf(Symbol.for('a'), 'name', allowed, true), {
59+
code: 'ERR_INVALID_OPT_VALUE',
60+
message: 'The value "Symbol(a)" is invalid for option "name". ' +
61+
'Must be one of: Symbol(b), Symbol(c)',
62+
});
63+
}
64+
65+
{
66+
// validateOneOf Symbol correct.
67+
const allowed = [Symbol.for('b'), Symbol.for('c')];
68+
validateOneOf(Symbol.for('b'), 'name', allowed);
69+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.