• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Flags: --expose-internals
2'use strict';
3
4require('../common');
5const assert = require('assert');
6const {
7  validateArray,
8  validateBoolean,
9  validateInteger,
10  validateNumber,
11  validateObject,
12  validateString,
13  validateInt32,
14  validateUint32,
15  validateLinkHeaderValue,
16} = require('internal/validators');
17const { MAX_SAFE_INTEGER, MIN_SAFE_INTEGER } = Number;
18const outOfRangeError = {
19  code: 'ERR_OUT_OF_RANGE',
20  name: 'RangeError',
21};
22const invalidArgTypeError = {
23  code: 'ERR_INVALID_ARG_TYPE',
24  name: 'TypeError',
25};
26const invalidArgValueError = {
27  code: 'ERR_INVALID_ARG_VALUE',
28  name: 'TypeError',
29};
30
31{
32  // validateInteger tests.
33
34  // validateInteger() defaults to validating safe integers.
35  validateInteger(MAX_SAFE_INTEGER, 'foo');
36  validateInteger(MIN_SAFE_INTEGER, 'foo');
37  assert.throws(() => {
38    validateInteger(MAX_SAFE_INTEGER + 1, 'foo');
39  }, outOfRangeError);
40  assert.throws(() => {
41    validateInteger(MIN_SAFE_INTEGER - 1, 'foo');
42  }, outOfRangeError);
43
44  // validateInteger() works with unsafe integers.
45  validateInteger(MAX_SAFE_INTEGER + 1, 'foo', 0, MAX_SAFE_INTEGER + 1);
46  validateInteger(MIN_SAFE_INTEGER - 1, 'foo', MIN_SAFE_INTEGER - 1);
47
48  // validateInt32() and validateUint32()
49  [
50    Symbol(), 1n, {}, [], false, true, undefined, null, () => {}, '', '1',
51  ].forEach((val) => assert.throws(() => validateInt32(val, 'name'), {
52    code: 'ERR_INVALID_ARG_TYPE'
53  }));
54  [
55    2147483647 + 1, -2147483648 - 1, NaN,
56  ].forEach((val) => assert.throws(() => validateInt32(val, 'name'), {
57    code: 'ERR_OUT_OF_RANGE'
58  }));
59  [
60    0, 1, -1,
61  ].forEach((val) => validateInt32(val, 'name'));
62  [
63    Symbol(), 1n, {}, [], false, true, undefined, null, () => {}, '', '1',
64  ].forEach((val) => assert.throws(() => validateUint32(val, 'name'), {
65    code: 'ERR_INVALID_ARG_TYPE'
66  }));
67  [
68    4294967296, -1, NaN,
69  ].forEach((val) => assert.throws(() => validateUint32(val, 'name'), {
70    code: 'ERR_OUT_OF_RANGE'
71  }));
72  [
73    0, 1,
74  ].forEach((val) => validateUint32(val, 'name'));
75}
76
77{
78  // validateArray tests.
79  validateArray([], 'foo');
80  validateArray([1, 2, 3], 'foo');
81
82  [undefined, null, true, false, 0, 0.0, 42, '', 'string', {}]
83    .forEach((val) => {
84      assert.throws(() => {
85        validateArray(val, 'foo');
86      }, invalidArgTypeError);
87    });
88
89  validateArray([1], 'foo', 1);
90  assert.throws(() => {
91    validateArray([], 'foo', 1);
92  }, invalidArgValueError);
93}
94
95{
96  // validateBoolean tests.
97  validateBoolean(true, 'foo');
98  validateBoolean(false, 'foo');
99
100  [undefined, null, 0, 0.0, 42, '', 'string', {}, []].forEach((val) => {
101    assert.throws(() => {
102      validateBoolean(val, 'foo');
103    }, invalidArgTypeError);
104  });
105}
106
107{
108  // validateObject tests.
109  Object.prototype.nullable = true;
110  Object.prototype.allowArray = true;
111  Object.prototype.allowFunction = true;
112
113  validateObject({}, 'foo');
114  validateObject({ a: 42, b: 'foo' }, 'foo');
115
116  [undefined, null, true, false, 0, 0.0, 42, '', 'string', [], () => {}]
117    .forEach((val) => {
118      assert.throws(() => {
119        validateObject(val, 'foo');
120      }, invalidArgTypeError);
121    });
122
123  // validateObject options tests:
124  validateObject(null, 'foo', { nullable: true });
125  validateObject([], 'foo', { allowArray: true });
126  validateObject(() => {}, 'foo', { allowFunction: true });
127
128  // validateObject should not be affected by Object.prototype tampering.
129  assert.throws(() => validateObject(null, 'foo', { allowArray: true }), invalidArgTypeError);
130  assert.throws(() => validateObject([], 'foo', { nullable: true }), invalidArgTypeError);
131  assert.throws(() => validateObject(() => {}, 'foo', { nullable: true }), invalidArgTypeError);
132
133  delete Object.prototype.nullable;
134  delete Object.prototype.allowArray;
135  delete Object.prototype.allowFunction;
136}
137
138{
139  // validateString type validation.
140  [
141    -1, {}, [], false, true,
142    1, Infinity, -Infinity, NaN,
143    undefined, null, 1.1,
144  ].forEach((i) => assert.throws(() => validateString(i, 'name'), {
145    code: 'ERR_INVALID_ARG_TYPE'
146  }));
147}
148{
149  // validateNumber type validation.
150  [
151    'a', {}, [], false, true,
152    undefined, null, '', ' ', '0x',
153    '-0x1', '-0o1', '-0b1', '0o', '0b',
154  ].forEach((i) => assert.throws(() => validateNumber(i, 'name'), {
155    code: 'ERR_INVALID_ARG_TYPE'
156  }));
157}
158
159{
160  // validateLinkHeaderValue type validation.
161  [
162    ['</styles.css>; rel=preload; as=style', '</styles.css>; rel=preload; as=style'],
163    ['</styles.css>; rel=preload; title=hello', '</styles.css>; rel=preload; title=hello'],
164    ['</styles.css>; rel=preload; crossorigin=hello', '</styles.css>; rel=preload; crossorigin=hello'],
165    ['</styles.css>; rel=preload; disabled=true', '</styles.css>; rel=preload; disabled=true'],
166    ['</styles.css>; rel=preload; fetchpriority=high', '</styles.css>; rel=preload; fetchpriority=high'],
167    ['</styles.css>; rel=preload; referrerpolicy=origin', '</styles.css>; rel=preload; referrerpolicy=origin'],
168  ].forEach(([value, expected]) => assert.strictEqual(validateLinkHeaderValue(value), expected));
169}
170