url: port WHATWG URL API to internal/errors
Also slightly revises grammar. PR-URL: https://github.com/nodejs/node/pull/12574 Refs: https://github.com/nodejs/node/issues/11273 Refs: https://github.com/nodejs/node/issues/11299 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com>
This commit is contained in:
parent
b7a341d7e5
commit
d457a986a0
@ -563,6 +563,13 @@ found [here][online].
|
|||||||
<a id="nodejs-error-codes"></a>
|
<a id="nodejs-error-codes"></a>
|
||||||
## Node.js Error Codes
|
## Node.js Error Codes
|
||||||
|
|
||||||
|
<a id="ERR_ARG_NOT_ITERABLE"></a>
|
||||||
|
### ERR_ARG_NOT_ITERABLE
|
||||||
|
|
||||||
|
The `'ERR_ARG_NOT_ITERABLE'` error code is used generically to identify that an
|
||||||
|
iterable argument (i.e. a value that works with `for...of` loops) is required,
|
||||||
|
but not provided to a Node.js API.
|
||||||
|
|
||||||
<a id="ERR_INVALID_ARG_TYPE"></a>
|
<a id="ERR_INVALID_ARG_TYPE"></a>
|
||||||
### ERR_INVALID_ARG_TYPE
|
### ERR_INVALID_ARG_TYPE
|
||||||
|
|
||||||
@ -575,6 +582,76 @@ an argument of the wrong type has been passed to a Node.js API.
|
|||||||
The `'ERR_INVALID_CALLBACK'` error code is used generically to identify that
|
The `'ERR_INVALID_CALLBACK'` error code is used generically to identify that
|
||||||
a callback function is required and has not been provided to a Node.js API.
|
a callback function is required and has not been provided to a Node.js API.
|
||||||
|
|
||||||
|
<a id="ERR_INVALID_FILE_URL_HOST"></a>
|
||||||
|
### ERR_INVALID_FILE_URL_HOST
|
||||||
|
|
||||||
|
An error with the `'ERR_INVALID_FILE_URL_HOST'` code may be thrown when a
|
||||||
|
Node.js API that consumes `file:` URLs (such as certain functions in the
|
||||||
|
[`fs`][] module) encounters a file URL with an incompatible host. Currently,
|
||||||
|
this situation can only occur on Unix-like systems, where only `localhost` or
|
||||||
|
an empty host is supported.
|
||||||
|
|
||||||
|
<a id="ERR_INVALID_FILE_URL_PATH"></a>
|
||||||
|
### ERR_INVALID_FILE_URL_PATH
|
||||||
|
|
||||||
|
An error with the `'ERR_INVALID_FILE_URL_PATH'` code may be thrown when a
|
||||||
|
Node.js API that consumes `file:` URLs (such as certain functions in the
|
||||||
|
[`fs`][] module) encounters a file URL with an incompatible path. The exact
|
||||||
|
semantics for determining whether a path can be used is platform-dependent.
|
||||||
|
|
||||||
|
<a id="ERR_INVALID_THIS"></a>
|
||||||
|
### ERR_INVALID_THIS
|
||||||
|
|
||||||
|
The `'ERR_INVALID_THIS'` error code is used generically to identify that a
|
||||||
|
Node.js API function is called with an incompatible `this` value.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { URLSearchParams } = require('url');
|
||||||
|
const urlSearchParams = new URLSearchParams('foo=bar&baz=new');
|
||||||
|
|
||||||
|
const buf = Buffer.alloc(1);
|
||||||
|
urlSearchParams.has.call(buf, 'foo');
|
||||||
|
// Throws a TypeError with code 'ERR_INVALID_THIS'
|
||||||
|
```
|
||||||
|
|
||||||
|
<a id="ERR_INVALID_TUPLE"></a>
|
||||||
|
### ERR_INVALID_TUPLE
|
||||||
|
|
||||||
|
An error with code `'ERR_INVALID_TUPLE'` is thrown when an element in the
|
||||||
|
`iterable` provided to the [WHATWG][WHATWG URL API] [`URLSearchParams`
|
||||||
|
constructor][`new URLSearchParams(iterable)`] does not represent a `[name,
|
||||||
|
value]` tuple – that is, if an element is not iterable, or does not consist of
|
||||||
|
exactly two elements.
|
||||||
|
|
||||||
|
<a id="ERR_INVALID_URL"></a>
|
||||||
|
### ERR_INVALID_URL
|
||||||
|
|
||||||
|
An error using the `'ERR_INVALID_URL'` code is thrown when an invalid URL is
|
||||||
|
passed to the [WHATWG][WHATWG URL API] [`URL` constructor][`new URL(input)`] to
|
||||||
|
be parsed. The thrown error object typically has an additional property
|
||||||
|
`'input'` that contains the URL that failed to parse.
|
||||||
|
|
||||||
|
<a id="ERR_INVALID_URL_SCHEME"></a>
|
||||||
|
### ERR_INVALID_URL_SCHEME
|
||||||
|
|
||||||
|
The code `'ERR_INVALID_URL_SCHEME'` is used generically to signify an attempt
|
||||||
|
to use a URL of an incompatible scheme (aka protocol) for a specific purpose.
|
||||||
|
It is currently only used in the [WHATWG URL API][] support in the [`fs`][]
|
||||||
|
module (which only accepts URLs with `'file'` scheme), but may be used in other
|
||||||
|
Node.js APIs as well in the future.
|
||||||
|
|
||||||
|
<a id="ERR_MISSING_ARGS"></a>
|
||||||
|
### ERR_MISSING_ARGS
|
||||||
|
|
||||||
|
The `'ERR_MISSING_ARGS'` error code is a generic error code for instances where
|
||||||
|
a required argument of a Node.js API is not passed. This is currently only used
|
||||||
|
in the [WHATWG URL API][] for strict compliance with the specification (which
|
||||||
|
in some cases may accept `func(undefined)` but not `func()`). In most native
|
||||||
|
Node.js APIs, `func(undefined)` and `func()` are treated identically, and the
|
||||||
|
[`ERR_INVALID_ARG_TYPE`][] error code may be used instead.
|
||||||
|
|
||||||
<a id="ERR_STDERR_CLOSE"></a>
|
<a id="ERR_STDERR_CLOSE"></a>
|
||||||
### ERR_STDERR_CLOSE
|
### ERR_STDERR_CLOSE
|
||||||
|
|
||||||
@ -627,11 +704,15 @@ likely an indication of a bug within Node.js itself.
|
|||||||
[`process.on('uncaughtException')`]: process.html#process_event_uncaughtexception
|
[`process.on('uncaughtException')`]: process.html#process_event_uncaughtexception
|
||||||
[domains]: domain.html
|
[domains]: domain.html
|
||||||
[event emitter-based]: events.html#events_class_eventemitter
|
[event emitter-based]: events.html#events_class_eventemitter
|
||||||
|
[`ERR_INVALID_ARG_TYPE`]: #ERR_INVALID_ARG_TYPE
|
||||||
[file descriptors]: https://en.wikipedia.org/wiki/File_descriptor
|
[file descriptors]: https://en.wikipedia.org/wiki/File_descriptor
|
||||||
[Node.js Error Codes]: #nodejs-error-codes
|
[Node.js Error Codes]: #nodejs-error-codes
|
||||||
[online]: http://man7.org/linux/man-pages/man3/errno.3.html
|
[online]: http://man7.org/linux/man-pages/man3/errno.3.html
|
||||||
[stream-based]: stream.html
|
[stream-based]: stream.html
|
||||||
[syscall]: http://man7.org/linux/man-pages/man2/syscall.2.html
|
[syscall]: http://man7.org/linux/man-pages/man2/syscall.2.html
|
||||||
[try-catch]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch
|
[try-catch]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch
|
||||||
|
[`new URL(input)`]: url.html#url_constructor_new_url_input_base
|
||||||
|
[`new URLSearchParams(iterable)`]: url.html#url_constructor_new_urlsearchparams_iterable
|
||||||
[V8's stack trace API]: https://github.com/v8/v8/wiki/Stack-Trace-API
|
[V8's stack trace API]: https://github.com/v8/v8/wiki/Stack-Trace-API
|
||||||
[vm]: vm.html
|
[vm]: vm.html
|
||||||
|
[WHATWG URL API]: url.html#url_the_whatwg_url_api
|
||||||
|
@ -79,9 +79,18 @@ module.exports = exports = {
|
|||||||
// Any error code added here should also be added to the documentation
|
// Any error code added here should also be added to the documentation
|
||||||
//
|
//
|
||||||
// Note: Please try to keep these in alphabetical order
|
// Note: Please try to keep these in alphabetical order
|
||||||
|
E('ERR_ARG_NOT_ITERABLE', '%s must be iterable');
|
||||||
E('ERR_ASSERTION', (msg) => msg);
|
E('ERR_ASSERTION', (msg) => msg);
|
||||||
E('ERR_INVALID_ARG_TYPE', invalidArgType);
|
E('ERR_INVALID_ARG_TYPE', invalidArgType);
|
||||||
E('ERR_INVALID_CALLBACK', 'callback must be a function');
|
E('ERR_INVALID_CALLBACK', 'callback must be a function');
|
||||||
|
E('ERR_INVALID_FILE_URL_HOST', 'File URL host %s');
|
||||||
|
E('ERR_INVALID_FILE_URL_PATH', 'File URL path %s');
|
||||||
|
E('ERR_INVALID_THIS', 'Value of "this" must be of type %s');
|
||||||
|
E('ERR_INVALID_TUPLE', '%s must be an iterable %s tuple');
|
||||||
|
E('ERR_INVALID_URL', 'Invalid URL: %s');
|
||||||
|
E('ERR_INVALID_URL_SCHEME',
|
||||||
|
(expected) => `The URL must be ${oneOf(expected, 'scheme')}`);
|
||||||
|
E('ERR_MISSING_ARGS', missingArgs);
|
||||||
E('ERR_STDERR_CLOSE', 'process.stderr cannot be closed');
|
E('ERR_STDERR_CLOSE', 'process.stderr cannot be closed');
|
||||||
E('ERR_STDOUT_CLOSE', 'process.stdout cannot be closed');
|
E('ERR_STDOUT_CLOSE', 'process.stdout cannot be closed');
|
||||||
E('ERR_UNKNOWN_STDIN_TYPE', 'Unknown stdin file type');
|
E('ERR_UNKNOWN_STDIN_TYPE', 'Unknown stdin file type');
|
||||||
@ -91,22 +100,49 @@ E('ERR_UNKNOWN_BUILTIN_MODULE', (id) => `No such built-in module: ${id}`);
|
|||||||
|
|
||||||
function invalidArgType(name, expected, actual) {
|
function invalidArgType(name, expected, actual) {
|
||||||
assert(name, 'name is required');
|
assert(name, 'name is required');
|
||||||
assert(expected, 'expected is required');
|
var msg = `The "${name}" argument must be ${oneOf(expected, 'type')}`;
|
||||||
var msg = `The "${name}" argument must be `;
|
|
||||||
if (Array.isArray(expected)) {
|
|
||||||
var len = expected.length;
|
|
||||||
expected = expected.map((i) => String(i));
|
|
||||||
if (len > 1) {
|
|
||||||
msg += `one of type ${expected.slice(0, len - 1).join(', ')}, or ` +
|
|
||||||
expected[len - 1];
|
|
||||||
} else {
|
|
||||||
msg += `of type ${expected[0]}`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
msg += `of type ${String(expected)}`;
|
|
||||||
}
|
|
||||||
if (arguments.length >= 3) {
|
if (arguments.length >= 3) {
|
||||||
msg += `. Received type ${actual !== null ? typeof actual : 'null'}`;
|
msg += `. Received type ${actual !== null ? typeof actual : 'null'}`;
|
||||||
}
|
}
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function missingArgs(...args) {
|
||||||
|
assert(args.length > 0, 'At least one arg needs to be specified');
|
||||||
|
let msg = 'The ';
|
||||||
|
const len = args.length;
|
||||||
|
args = args.map((a) => `"${a}"`);
|
||||||
|
switch (len) {
|
||||||
|
case 1:
|
||||||
|
msg += `${args[0]} argument`;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
msg += `${args[0]} and ${args[1]} arguments`;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
msg += args.slice(0, len - 1).join(', ');
|
||||||
|
msg += `, and ${args[len - 1]} arguments`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return `${msg} must be specified`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function oneOf(expected, thing) {
|
||||||
|
assert(expected, 'expected is required');
|
||||||
|
assert(typeof thing === 'string', 'thing is required');
|
||||||
|
if (Array.isArray(expected)) {
|
||||||
|
const len = expected.length;
|
||||||
|
assert(len > 0, 'At least one expected value needs to be specified');
|
||||||
|
expected = expected.map((i) => String(i));
|
||||||
|
if (len > 2) {
|
||||||
|
return `one of ${thing} ${expected.slice(0, len - 1).join(', ')}, or ` +
|
||||||
|
expected[len - 1];
|
||||||
|
} else if (len === 2) {
|
||||||
|
return `one of ${thing} ${expected[0]} or ${expected[1]}`;
|
||||||
|
} else {
|
||||||
|
return `of ${thing} ${expected[0]}`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return `of ${thing} ${String(expected)}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ const {
|
|||||||
isHexTable
|
isHexTable
|
||||||
} = require('internal/querystring');
|
} = require('internal/querystring');
|
||||||
const { getConstructorOf } = require('internal/util');
|
const { getConstructorOf } = require('internal/util');
|
||||||
|
const errors = require('internal/errors');
|
||||||
const binding = process.binding('url');
|
const binding = process.binding('url');
|
||||||
const context = Symbol('context');
|
const context = Symbol('context');
|
||||||
const cannotBeBase = Symbol('cannot-be-base');
|
const cannotBeBase = Symbol('cannot-be-base');
|
||||||
@ -14,9 +15,9 @@ const cannotHaveUsernamePasswordPort =
|
|||||||
const special = Symbol('special');
|
const special = Symbol('special');
|
||||||
const searchParams = Symbol('query');
|
const searchParams = Symbol('query');
|
||||||
const querystring = require('querystring');
|
const querystring = require('querystring');
|
||||||
const os = require('os');
|
|
||||||
|
|
||||||
const isWindows = process.platform === 'win32';
|
const { platform } = process;
|
||||||
|
const isWindows = platform === 'win32';
|
||||||
|
|
||||||
const kFormat = Symbol('format');
|
const kFormat = Symbol('format');
|
||||||
|
|
||||||
@ -88,7 +89,7 @@ function onParseComplete(flags, protocol, username, password,
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onParseError(flags, input) {
|
function onParseError(flags, input) {
|
||||||
const error = new TypeError('Invalid URL: ' + input);
|
const error = new errors.TypeError('ERR_INVALID_URL', input);
|
||||||
error.input = input;
|
error.input = input;
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@ -202,7 +203,7 @@ class URL {
|
|||||||
[util.inspect.custom](depth, opts) {
|
[util.inspect.custom](depth, opts) {
|
||||||
if (this == null ||
|
if (this == null ||
|
||||||
Object.getPrototypeOf(this[context]) !== URLContext.prototype) {
|
Object.getPrototypeOf(this[context]) !== URLContext.prototype) {
|
||||||
throw new TypeError('Value of `this` is not a URL');
|
throw new errors.TypeError('ERR_INVALID_THIS', 'URL');
|
||||||
}
|
}
|
||||||
|
|
||||||
const ctx = this[context];
|
const ctx = this[context];
|
||||||
@ -247,7 +248,7 @@ Object.defineProperties(URL.prototype, {
|
|||||||
// eslint-disable-next-line func-name-matching
|
// eslint-disable-next-line func-name-matching
|
||||||
value: function format(options) {
|
value: function format(options) {
|
||||||
if (options && typeof options !== 'object')
|
if (options && typeof options !== 'object')
|
||||||
throw new TypeError('options must be an object');
|
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'options', 'object');
|
||||||
options = Object.assign({
|
options = Object.assign({
|
||||||
fragment: true,
|
fragment: true,
|
||||||
unicode: false,
|
unicode: false,
|
||||||
@ -810,7 +811,7 @@ class URLSearchParams {
|
|||||||
this[searchParams] = childParams.slice();
|
this[searchParams] = childParams.slice();
|
||||||
} else if (method !== null && method !== undefined) {
|
} else if (method !== null && method !== undefined) {
|
||||||
if (typeof method !== 'function') {
|
if (typeof method !== 'function') {
|
||||||
throw new TypeError('Query pairs must be iterable');
|
throw new errors.TypeError('ERR_ARG_NOT_ITERABLE', 'Query pairs');
|
||||||
}
|
}
|
||||||
|
|
||||||
// sequence<sequence<USVString>>
|
// sequence<sequence<USVString>>
|
||||||
@ -819,7 +820,8 @@ class URLSearchParams {
|
|||||||
for (const pair of init) {
|
for (const pair of init) {
|
||||||
if (typeof pair !== 'object' ||
|
if (typeof pair !== 'object' ||
|
||||||
typeof pair[Symbol.iterator] !== 'function') {
|
typeof pair[Symbol.iterator] !== 'function') {
|
||||||
throw new TypeError('Each query pair must be iterable');
|
throw new errors.TypeError('ERR_INVALID_TUPLE', 'Each query pair',
|
||||||
|
'[name, value]');
|
||||||
}
|
}
|
||||||
pairs.push(Array.from(pair));
|
pairs.push(Array.from(pair));
|
||||||
}
|
}
|
||||||
@ -827,7 +829,8 @@ class URLSearchParams {
|
|||||||
this[searchParams] = [];
|
this[searchParams] = [];
|
||||||
for (const pair of pairs) {
|
for (const pair of pairs) {
|
||||||
if (pair.length !== 2) {
|
if (pair.length !== 2) {
|
||||||
throw new TypeError('Each query pair must be a name/value tuple');
|
throw new errors.TypeError('ERR_INVALID_TUPLE', 'Each query pair',
|
||||||
|
'[name, value]');
|
||||||
}
|
}
|
||||||
const key = toUSVString(pair[0]);
|
const key = toUSVString(pair[0]);
|
||||||
const value = toUSVString(pair[1]);
|
const value = toUSVString(pair[1]);
|
||||||
@ -855,7 +858,7 @@ class URLSearchParams {
|
|||||||
|
|
||||||
[util.inspect.custom](recurseTimes, ctx) {
|
[util.inspect.custom](recurseTimes, ctx) {
|
||||||
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
||||||
throw new TypeError('Value of `this` is not a URLSearchParams');
|
throw new errors.TypeError('ERR_INVALID_THIS', 'URLSearchParams');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof recurseTimes === 'number' && recurseTimes < 0)
|
if (typeof recurseTimes === 'number' && recurseTimes < 0)
|
||||||
@ -920,10 +923,10 @@ function merge(out, start, mid, end, lBuffer, rBuffer) {
|
|||||||
defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
|
defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
|
||||||
append(name, value) {
|
append(name, value) {
|
||||||
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
||||||
throw new TypeError('Value of `this` is not a URLSearchParams');
|
throw new errors.TypeError('ERR_INVALID_THIS', 'URLSearchParams');
|
||||||
}
|
}
|
||||||
if (arguments.length < 2) {
|
if (arguments.length < 2) {
|
||||||
throw new TypeError('"name" and "value" arguments must be specified');
|
throw new errors.TypeError('ERR_MISSING_ARGS', 'name', 'value');
|
||||||
}
|
}
|
||||||
|
|
||||||
name = toUSVString(name);
|
name = toUSVString(name);
|
||||||
@ -934,10 +937,10 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
|
|||||||
|
|
||||||
delete(name) {
|
delete(name) {
|
||||||
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
||||||
throw new TypeError('Value of `this` is not a URLSearchParams');
|
throw new errors.TypeError('ERR_INVALID_THIS', 'URLSearchParams');
|
||||||
}
|
}
|
||||||
if (arguments.length < 1) {
|
if (arguments.length < 1) {
|
||||||
throw new TypeError('"name" argument must be specified');
|
throw new errors.TypeError('ERR_MISSING_ARGS', 'name');
|
||||||
}
|
}
|
||||||
|
|
||||||
const list = this[searchParams];
|
const list = this[searchParams];
|
||||||
@ -955,10 +958,10 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
|
|||||||
|
|
||||||
get(name) {
|
get(name) {
|
||||||
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
||||||
throw new TypeError('Value of `this` is not a URLSearchParams');
|
throw new errors.TypeError('ERR_INVALID_THIS', 'URLSearchParams');
|
||||||
}
|
}
|
||||||
if (arguments.length < 1) {
|
if (arguments.length < 1) {
|
||||||
throw new TypeError('"name" argument must be specified');
|
throw new errors.TypeError('ERR_MISSING_ARGS', 'name');
|
||||||
}
|
}
|
||||||
|
|
||||||
const list = this[searchParams];
|
const list = this[searchParams];
|
||||||
@ -973,10 +976,10 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
|
|||||||
|
|
||||||
getAll(name) {
|
getAll(name) {
|
||||||
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
||||||
throw new TypeError('Value of `this` is not a URLSearchParams');
|
throw new errors.TypeError('ERR_INVALID_THIS', 'URLSearchParams');
|
||||||
}
|
}
|
||||||
if (arguments.length < 1) {
|
if (arguments.length < 1) {
|
||||||
throw new TypeError('"name" argument must be specified');
|
throw new errors.TypeError('ERR_MISSING_ARGS', 'name');
|
||||||
}
|
}
|
||||||
|
|
||||||
const list = this[searchParams];
|
const list = this[searchParams];
|
||||||
@ -992,10 +995,10 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
|
|||||||
|
|
||||||
has(name) {
|
has(name) {
|
||||||
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
||||||
throw new TypeError('Value of `this` is not a URLSearchParams');
|
throw new errors.TypeError('ERR_INVALID_THIS', 'URLSearchParams');
|
||||||
}
|
}
|
||||||
if (arguments.length < 1) {
|
if (arguments.length < 1) {
|
||||||
throw new TypeError('"name" argument must be specified');
|
throw new errors.TypeError('ERR_MISSING_ARGS', 'name');
|
||||||
}
|
}
|
||||||
|
|
||||||
const list = this[searchParams];
|
const list = this[searchParams];
|
||||||
@ -1010,10 +1013,10 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
|
|||||||
|
|
||||||
set(name, value) {
|
set(name, value) {
|
||||||
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
||||||
throw new TypeError('Value of `this` is not a URLSearchParams');
|
throw new errors.TypeError('ERR_INVALID_THIS', 'URLSearchParams');
|
||||||
}
|
}
|
||||||
if (arguments.length < 2) {
|
if (arguments.length < 2) {
|
||||||
throw new TypeError('"name" and "value" arguments must be specified');
|
throw new errors.TypeError('ERR_MISSING_ARGS', 'name', 'value');
|
||||||
}
|
}
|
||||||
|
|
||||||
const list = this[searchParams];
|
const list = this[searchParams];
|
||||||
@ -1098,7 +1101,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
|
|||||||
// must be set to `entries`.
|
// must be set to `entries`.
|
||||||
entries() {
|
entries() {
|
||||||
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
||||||
throw new TypeError('Value of `this` is not a URLSearchParams');
|
throw new errors.TypeError('ERR_INVALID_THIS', 'URLSearchParams');
|
||||||
}
|
}
|
||||||
|
|
||||||
return createSearchParamsIterator(this, 'key+value');
|
return createSearchParamsIterator(this, 'key+value');
|
||||||
@ -1106,10 +1109,10 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
|
|||||||
|
|
||||||
forEach(callback, thisArg = undefined) {
|
forEach(callback, thisArg = undefined) {
|
||||||
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
||||||
throw new TypeError('Value of `this` is not a URLSearchParams');
|
throw new errors.TypeError('ERR_INVALID_THIS', 'URLSearchParams');
|
||||||
}
|
}
|
||||||
if (typeof callback !== 'function') {
|
if (typeof callback !== 'function') {
|
||||||
throw new TypeError('"callback" argument must be a function');
|
throw new errors.TypeError('ERR_INVALID_CALLBACK');
|
||||||
}
|
}
|
||||||
|
|
||||||
let list = this[searchParams];
|
let list = this[searchParams];
|
||||||
@ -1128,7 +1131,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
|
|||||||
// https://heycam.github.io/webidl/#es-iterable
|
// https://heycam.github.io/webidl/#es-iterable
|
||||||
keys() {
|
keys() {
|
||||||
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
||||||
throw new TypeError('Value of `this` is not a URLSearchParams');
|
throw new errors.TypeError('ERR_INVALID_THIS', 'URLSearchParams');
|
||||||
}
|
}
|
||||||
|
|
||||||
return createSearchParamsIterator(this, 'key');
|
return createSearchParamsIterator(this, 'key');
|
||||||
@ -1136,7 +1139,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
|
|||||||
|
|
||||||
values() {
|
values() {
|
||||||
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
||||||
throw new TypeError('Value of `this` is not a URLSearchParams');
|
throw new errors.TypeError('ERR_INVALID_THIS', 'URLSearchParams');
|
||||||
}
|
}
|
||||||
|
|
||||||
return createSearchParamsIterator(this, 'value');
|
return createSearchParamsIterator(this, 'value');
|
||||||
@ -1146,7 +1149,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
|
|||||||
// https://url.spec.whatwg.org/#urlsearchparams-stringification-behavior
|
// https://url.spec.whatwg.org/#urlsearchparams-stringification-behavior
|
||||||
toString() {
|
toString() {
|
||||||
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
if (!this || !this[searchParams] || this[searchParams][searchParams]) {
|
||||||
throw new TypeError('Value of `this` is not a URLSearchParams');
|
throw new errors.TypeError('ERR_INVALID_THIS', 'URLSearchParams');
|
||||||
}
|
}
|
||||||
|
|
||||||
return serializeParams(this[searchParams]);
|
return serializeParams(this[searchParams]);
|
||||||
@ -1178,7 +1181,7 @@ defineIDLClass(URLSearchParamsIteratorPrototype, 'URLSearchParamsIterator', {
|
|||||||
next() {
|
next() {
|
||||||
if (!this ||
|
if (!this ||
|
||||||
Object.getPrototypeOf(this) !== URLSearchParamsIteratorPrototype) {
|
Object.getPrototypeOf(this) !== URLSearchParamsIteratorPrototype) {
|
||||||
throw new TypeError('Value of `this` is not a URLSearchParamsIterator');
|
throw new errors.TypeError('ERR_INVALID_THIS', 'URLSearchParamsIterator');
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -1215,7 +1218,7 @@ defineIDLClass(URLSearchParamsIteratorPrototype, 'URLSearchParamsIterator', {
|
|||||||
},
|
},
|
||||||
[util.inspect.custom](recurseTimes, ctx) {
|
[util.inspect.custom](recurseTimes, ctx) {
|
||||||
if (this == null || this[context] == null || this[context].target == null)
|
if (this == null || this[context] == null || this[context].target == null)
|
||||||
throw new TypeError('Value of `this` is not a URLSearchParamsIterator');
|
throw new errors.TypeError('ERR_INVALID_THIS', 'URLSearchParamsIterator');
|
||||||
|
|
||||||
if (typeof recurseTimes === 'number' && recurseTimes < 0)
|
if (typeof recurseTimes === 'number' && recurseTimes < 0)
|
||||||
return ctx.stylize('[Object]', 'special');
|
return ctx.stylize('[Object]', 'special');
|
||||||
@ -1254,7 +1257,7 @@ defineIDLClass(URLSearchParamsIteratorPrototype, 'URLSearchParamsIterator', {
|
|||||||
|
|
||||||
function domainToASCII(domain) {
|
function domainToASCII(domain) {
|
||||||
if (arguments.length < 1)
|
if (arguments.length < 1)
|
||||||
throw new TypeError('"domain" argument must be specified');
|
throw new errors.TypeError('ERR_MISSING_ARGS', 'domain');
|
||||||
|
|
||||||
// toUSVString is not needed.
|
// toUSVString is not needed.
|
||||||
return binding.domainToASCII(`${domain}`);
|
return binding.domainToASCII(`${domain}`);
|
||||||
@ -1262,7 +1265,7 @@ function domainToASCII(domain) {
|
|||||||
|
|
||||||
function domainToUnicode(domain) {
|
function domainToUnicode(domain) {
|
||||||
if (arguments.length < 1)
|
if (arguments.length < 1)
|
||||||
throw new TypeError('"domain" argument must be specified');
|
throw new errors.TypeError('ERR_MISSING_ARGS', 'domain');
|
||||||
|
|
||||||
// toUSVString is not needed.
|
// toUSVString is not needed.
|
||||||
return binding.domainToUnicode(`${domain}`);
|
return binding.domainToUnicode(`${domain}`);
|
||||||
@ -1299,8 +1302,9 @@ function getPathFromURLWin32(url) {
|
|||||||
var third = pathname.codePointAt(n + 2) | 0x20;
|
var third = pathname.codePointAt(n + 2) | 0x20;
|
||||||
if ((pathname[n + 1] === '2' && third === 102) || // 2f 2F /
|
if ((pathname[n + 1] === '2' && third === 102) || // 2f 2F /
|
||||||
(pathname[n + 1] === '5' && third === 99)) { // 5c 5C \
|
(pathname[n + 1] === '5' && third === 99)) { // 5c 5C \
|
||||||
return new TypeError(
|
return new errors.TypeError(
|
||||||
'Path must not include encoded \\ or / characters');
|
'ERR_INVALID_FILE_URL_PATH',
|
||||||
|
'must not include encoded \\ or / characters');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1319,7 +1323,8 @@ function getPathFromURLWin32(url) {
|
|||||||
var sep = pathname[2];
|
var sep = pathname[2];
|
||||||
if (letter < 97 || letter > 122 || // a..z A..Z
|
if (letter < 97 || letter > 122 || // a..z A..Z
|
||||||
(sep !== ':')) {
|
(sep !== ':')) {
|
||||||
return new TypeError('File URLs must specify absolute paths');
|
return new errors.TypeError('ERR_INVALID_FILE_URL_PATH',
|
||||||
|
'must be absolute');
|
||||||
}
|
}
|
||||||
return pathname.slice(1);
|
return pathname.slice(1);
|
||||||
}
|
}
|
||||||
@ -1327,16 +1332,16 @@ function getPathFromURLWin32(url) {
|
|||||||
|
|
||||||
function getPathFromURLPosix(url) {
|
function getPathFromURLPosix(url) {
|
||||||
if (url.hostname !== '') {
|
if (url.hostname !== '') {
|
||||||
return new TypeError(
|
return new errors.TypeError('ERR_INVALID_FILE_URL_HOST',
|
||||||
`File URLs on ${os.platform()} must use hostname 'localhost'` +
|
`must be "localhost" or empty on ${platform}`);
|
||||||
' or not specify any hostname');
|
|
||||||
}
|
}
|
||||||
var pathname = url.pathname;
|
var pathname = url.pathname;
|
||||||
for (var n = 0; n < pathname.length; n++) {
|
for (var n = 0; n < pathname.length; n++) {
|
||||||
if (pathname[n] === '%') {
|
if (pathname[n] === '%') {
|
||||||
var third = pathname.codePointAt(n + 2) | 0x20;
|
var third = pathname.codePointAt(n + 2) | 0x20;
|
||||||
if (pathname[n + 1] === '2' && third === 102) {
|
if (pathname[n + 1] === '2' && third === 102) {
|
||||||
return new TypeError('Path must not include encoded / characters');
|
return new errors.TypeError('ERR_INVALID_FILE_URL_PATH',
|
||||||
|
'must not include encoded / characters');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1349,7 +1354,7 @@ function getPathFromURL(path) {
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
if (path.protocol !== 'file:')
|
if (path.protocol !== 'file:')
|
||||||
return new TypeError('Only `file:` URLs are supported');
|
return new errors.TypeError('ERR_INVALID_URL_SCHEME', 'file');
|
||||||
return isWindows ? getPathFromURLWin32(path) : getPathFromURLPosix(path);
|
return isWindows ? getPathFromURLWin32(path) : getPathFromURLPosix(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -617,7 +617,9 @@ exports.WPT = {
|
|||||||
assert_false: (value, message) => assert.strictEqual(value, false, message),
|
assert_false: (value, message) => assert.strictEqual(value, false, message),
|
||||||
assert_throws: (code, func, desc) => {
|
assert_throws: (code, func, desc) => {
|
||||||
assert.throws(func, (err) => {
|
assert.throws(func, (err) => {
|
||||||
return typeof err === 'object' && 'name' in err && err.name === code.name;
|
return typeof err === 'object' &&
|
||||||
|
'name' in err &&
|
||||||
|
err.name.startsWith(code.name);
|
||||||
}, desc);
|
}, desc);
|
||||||
},
|
},
|
||||||
assert_array_equals: assert.deepStrictEqual,
|
assert_array_equals: assert.deepStrictEqual,
|
||||||
|
@ -30,9 +30,11 @@ fs.readFile(url, common.mustCall((err, data) => {
|
|||||||
// Check that using a non file:// URL reports an error
|
// Check that using a non file:// URL reports an error
|
||||||
const httpUrl = new URL('http://example.org');
|
const httpUrl = new URL('http://example.org');
|
||||||
fs.readFile(httpUrl, common.mustCall((err) => {
|
fs.readFile(httpUrl, common.mustCall((err) => {
|
||||||
assert(err);
|
common.expectsError({
|
||||||
assert.strictEqual(err.message,
|
code: 'ERR_INVALID_URL_SCHEME',
|
||||||
'Only `file:` URLs are supported');
|
type: TypeError,
|
||||||
|
message: 'The URL must be of scheme file'
|
||||||
|
})(err);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// pct-encoded characters in the path will be decoded and checked
|
// pct-encoded characters in the path will be decoded and checked
|
||||||
@ -46,25 +48,30 @@ if (common.isWindows) {
|
|||||||
// encoded back and forward slashes are not permitted on windows
|
// encoded back and forward slashes are not permitted on windows
|
||||||
['%2f', '%2F', '%5c', '%5C'].forEach((i) => {
|
['%2f', '%2F', '%5c', '%5C'].forEach((i) => {
|
||||||
fs.readFile(new URL(`file:///c:/tmp/${i}`), common.mustCall((err) => {
|
fs.readFile(new URL(`file:///c:/tmp/${i}`), common.mustCall((err) => {
|
||||||
assert(err);
|
common.expectsError({
|
||||||
assert.strictEqual(err.message,
|
code: 'ERR_INVALID_FILE_URL_PATH',
|
||||||
'Path must not include encoded \\ or / characters');
|
type: TypeError,
|
||||||
|
message: 'File URL path must not include encoded \\ or / characters'
|
||||||
|
})(err);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// encoded forward slashes are not permitted on other platforms
|
// encoded forward slashes are not permitted on other platforms
|
||||||
['%2f', '%2F'].forEach((i) => {
|
['%2f', '%2F'].forEach((i) => {
|
||||||
fs.readFile(new URL(`file:///c:/tmp/${i}`), common.mustCall((err) => {
|
fs.readFile(new URL(`file:///c:/tmp/${i}`), common.mustCall((err) => {
|
||||||
assert(err);
|
common.expectsError({
|
||||||
assert.strictEqual(err.message,
|
code: 'ERR_INVALID_FILE_URL_PATH',
|
||||||
'Path must not include encoded / characters');
|
type: TypeError,
|
||||||
|
message: 'File URL path must not include encoded / characters'
|
||||||
|
})(err);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
fs.readFile(new URL('file://hostname/a/b/c'), common.mustCall((err) => {
|
fs.readFile(new URL('file://hostname/a/b/c'), common.mustCall((err) => {
|
||||||
assert(err);
|
common.expectsError({
|
||||||
assert.strictEqual(err.message,
|
code: 'ERR_INVALID_FILE_URL_HOST',
|
||||||
`File URLs on ${os.platform()} must use ` +
|
type: TypeError,
|
||||||
'hostname \'localhost\' or not specify any hostname');
|
message: `File URL host must be "localhost" or empty on ${os.platform()}`
|
||||||
|
})(err);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE', ['a', 'b']),
|
|||||||
assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE', ['a', ['b']]),
|
assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE', ['a', ['b']]),
|
||||||
'The "a" argument must be of type b');
|
'The "a" argument must be of type b');
|
||||||
assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE', ['a', ['b', 'c']]),
|
assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE', ['a', ['b', 'c']]),
|
||||||
'The "a" argument must be one of type b, or c');
|
'The "a" argument must be one of type b or c');
|
||||||
assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE',
|
assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE',
|
||||||
['a', ['b', 'c', 'd']]),
|
['a', ['b', 'c', 'd']]),
|
||||||
'The "a" argument must be one of type b, c, or d');
|
'The "a" argument must be one of type b, c, or d');
|
||||||
@ -150,3 +150,29 @@ assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE',
|
|||||||
assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE',
|
assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE',
|
||||||
['a', 'b', null]),
|
['a', 'b', null]),
|
||||||
'The "a" argument must be of type b. Received type null');
|
'The "a" argument must be of type b. Received type null');
|
||||||
|
|
||||||
|
// Test ERR_INVALID_URL_SCHEME
|
||||||
|
assert.strictEqual(errors.message('ERR_INVALID_URL_SCHEME', ['file']),
|
||||||
|
'The URL must be of scheme file');
|
||||||
|
assert.strictEqual(errors.message('ERR_INVALID_URL_SCHEME', [['file']]),
|
||||||
|
'The URL must be of scheme file');
|
||||||
|
assert.strictEqual(errors.message('ERR_INVALID_URL_SCHEME', [['http', 'ftp']]),
|
||||||
|
'The URL must be one of scheme http or ftp');
|
||||||
|
assert.strictEqual(errors.message('ERR_INVALID_URL_SCHEME', [['a', 'b', 'c']]),
|
||||||
|
'The URL must be one of scheme a, b, or c');
|
||||||
|
assert.throws(
|
||||||
|
() => errors.message('ERR_INVALID_URL_SCHEME', [[]]),
|
||||||
|
/^AssertionError: At least one expected value needs to be specified$/
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test ERR_MISSING_ARGS
|
||||||
|
assert.strictEqual(errors.message('ERR_MISSING_ARGS', ['name']),
|
||||||
|
'The "name" argument must be specified');
|
||||||
|
assert.strictEqual(errors.message('ERR_MISSING_ARGS', ['name', 'value']),
|
||||||
|
'The "name" and "value" arguments must be specified');
|
||||||
|
assert.strictEqual(errors.message('ERR_MISSING_ARGS', ['a', 'b', 'c']),
|
||||||
|
'The "a", "b", and "c" arguments must be specified');
|
||||||
|
assert.throws(
|
||||||
|
() => errors.message('ERR_MISSING_ARGS'),
|
||||||
|
/^AssertionError: At least one arg needs to be specified$/
|
||||||
|
);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
require('../common');
|
const common = require('../common');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const url = require('url');
|
const url = require('url');
|
||||||
const URL = url.URL;
|
const URL = url.URL;
|
||||||
@ -17,11 +17,17 @@ assert.strictEqual(
|
|||||||
'http://xn--lck1c3crb1723bpq4a.com/a?a=b#c'
|
'http://xn--lck1c3crb1723bpq4a.com/a?a=b#c'
|
||||||
);
|
);
|
||||||
|
|
||||||
const errreg = /^TypeError: options must be an object$/;
|
{
|
||||||
assert.throws(() => url.format(myURL, true), errreg);
|
const expectedErr = common.expectsError({
|
||||||
assert.throws(() => url.format(myURL, 1), errreg);
|
code: 'ERR_INVALID_ARG_TYPE',
|
||||||
assert.throws(() => url.format(myURL, 'test'), errreg);
|
type: TypeError,
|
||||||
assert.throws(() => url.format(myURL, Infinity), errreg);
|
message: 'The "options" argument must be of type object'
|
||||||
|
});
|
||||||
|
assert.throws(() => url.format(myURL, true), expectedErr);
|
||||||
|
assert.throws(() => url.format(myURL, 1), expectedErr);
|
||||||
|
assert.throws(() => url.format(myURL, 'test'), expectedErr);
|
||||||
|
assert.throws(() => url.format(myURL, Infinity), expectedErr);
|
||||||
|
}
|
||||||
|
|
||||||
// Any falsy value other than undefined will be treated as false.
|
// Any falsy value other than undefined will be treated as false.
|
||||||
// Any truthy value will be treated as true.
|
// Any truthy value will be treated as true.
|
||||||
|
@ -13,10 +13,10 @@ const { domainToASCII, domainToUnicode } = require('url');
|
|||||||
const tests = require('../fixtures/url-idna.js');
|
const tests = require('../fixtures/url-idna.js');
|
||||||
|
|
||||||
{
|
{
|
||||||
assert.throws(() => domainToASCII(),
|
const expectedError = common.expectsError(
|
||||||
/^TypeError: "domain" argument must be specified$/);
|
{ code: 'ERR_MISSING_ARGS', type: TypeError });
|
||||||
assert.throws(() => domainToUnicode(),
|
assert.throws(() => domainToASCII(), expectedError);
|
||||||
/^TypeError: "domain" argument must be specified$/);
|
assert.throws(() => domainToUnicode(), expectedError);
|
||||||
assert.strictEqual(domainToASCII(undefined), 'undefined');
|
assert.strictEqual(domainToASCII(undefined), 'undefined');
|
||||||
assert.strictEqual(domainToUnicode(undefined), 'undefined');
|
assert.strictEqual(domainToUnicode(undefined), 'undefined');
|
||||||
}
|
}
|
||||||
|
@ -26,12 +26,18 @@ const failureTests = tests.filter((test) => test.failure).concat([
|
|||||||
{ input: common.noop }
|
{ input: common.noop }
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const expectedError = common.expectsError(
|
||||||
|
{ code: 'ERR_INVALID_URL', type: TypeError });
|
||||||
|
|
||||||
for (const test of failureTests) {
|
for (const test of failureTests) {
|
||||||
assert.throws(
|
assert.throws(
|
||||||
() => new URL(test.input, test.base),
|
() => new URL(test.input, test.base),
|
||||||
(error) => {
|
(error) => {
|
||||||
|
if (!expectedError(error))
|
||||||
|
return false;
|
||||||
|
|
||||||
// The input could be processed, so we don't do strict matching here
|
// The input could be processed, so we don't do strict matching here
|
||||||
const match = (error + '').match(/^TypeError: Invalid URL: (.*)$/);
|
const match = (error + '').match(/Invalid URL: (.*)$/);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -53,10 +53,18 @@ test(function() {
|
|||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.append.call(undefined);
|
params.append.call(undefined);
|
||||||
}, /^TypeError: Value of `this` is not a URLSearchParams$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_INVALID_THIS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'Value of "this" must be of type URLSearchParams'
|
||||||
|
}));
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.set('a');
|
params.append('a');
|
||||||
}, /^TypeError: "name" and "value" arguments must be specified$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_MISSING_ARGS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'The "name" and "value" arguments must be specified'
|
||||||
|
}));
|
||||||
|
|
||||||
const obj = {
|
const obj = {
|
||||||
toString() { throw new Error('toString'); },
|
toString() { throw new Error('toString'); },
|
||||||
|
@ -188,24 +188,31 @@ test(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
const iterableError = common.expectsError({
|
||||||
|
code: 'ERR_ARG_NOT_ITERABLE',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'Query pairs must be iterable'
|
||||||
|
});
|
||||||
|
const tupleError = common.expectsError({
|
||||||
|
code: 'ERR_INVALID_TUPLE',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'Each query pair must be an iterable [name, value] tuple'
|
||||||
|
});
|
||||||
|
|
||||||
let params;
|
let params;
|
||||||
// URLSearchParams constructor, undefined and null as argument
|
// URLSearchParams constructor, undefined and null as argument
|
||||||
params = new URLSearchParams(undefined);
|
params = new URLSearchParams(undefined);
|
||||||
assert.strictEqual(params.toString(), '');
|
assert.strictEqual(params.toString(), '');
|
||||||
params = new URLSearchParams(null);
|
params = new URLSearchParams(null);
|
||||||
assert.strictEqual(params.toString(), '');
|
assert.strictEqual(params.toString(), '');
|
||||||
assert.throws(() => new URLSearchParams([[1]]),
|
assert.throws(() => new URLSearchParams([[1]]), tupleError);
|
||||||
/^TypeError: Each query pair must be a name\/value tuple$/);
|
assert.throws(() => new URLSearchParams([[1, 2, 3]]), tupleError);
|
||||||
assert.throws(() => new URLSearchParams([[1, 2, 3]]),
|
|
||||||
/^TypeError: Each query pair must be a name\/value tuple$/);
|
|
||||||
assert.throws(() => new URLSearchParams({ [Symbol.iterator]: 42 }),
|
assert.throws(() => new URLSearchParams({ [Symbol.iterator]: 42 }),
|
||||||
/^TypeError: Query pairs must be iterable$/);
|
iterableError);
|
||||||
assert.throws(() => new URLSearchParams([{}]),
|
assert.throws(() => new URLSearchParams([{}]), tupleError);
|
||||||
/^TypeError: Each query pair must be iterable$/);
|
assert.throws(() => new URLSearchParams(['a']), tupleError);
|
||||||
assert.throws(() => new URLSearchParams(['a']),
|
|
||||||
/^TypeError: Each query pair must be iterable$/);
|
|
||||||
assert.throws(() => new URLSearchParams([{ [Symbol.iterator]: 42 }]),
|
assert.throws(() => new URLSearchParams([{ [Symbol.iterator]: 42 }]),
|
||||||
/^TypeError: Each query pair must be iterable$/);
|
tupleError);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -47,10 +47,18 @@ test(function() {
|
|||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.delete.call(undefined);
|
params.delete.call(undefined);
|
||||||
}, /^TypeError: Value of `this` is not a URLSearchParams$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_INVALID_THIS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'Value of "this" must be of type URLSearchParams'
|
||||||
|
}));
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.delete();
|
params.delete();
|
||||||
}, /^TypeError: "name" argument must be specified$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_MISSING_ARGS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'The "name" argument must be specified'
|
||||||
|
}));
|
||||||
|
|
||||||
const obj = {
|
const obj = {
|
||||||
toString() { throw new Error('toString'); },
|
toString() { throw new Error('toString'); },
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
require('../common');
|
const common = require('../common');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const URLSearchParams = require('url').URLSearchParams;
|
const URLSearchParams = require('url').URLSearchParams;
|
||||||
|
|
||||||
@ -28,7 +28,15 @@ assert.deepStrictEqual(entries.next(), {
|
|||||||
|
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
entries.next.call(undefined);
|
entries.next.call(undefined);
|
||||||
}, /^TypeError: Value of `this` is not a URLSearchParamsIterator$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_INVALID_THIS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'Value of "this" must be of type URLSearchParamsIterator'
|
||||||
|
}));
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.entries.call(undefined);
|
params.entries.call(undefined);
|
||||||
}, /^TypeError: Value of `this` is not a URLSearchParams$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_INVALID_THIS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'Value of "this" must be of type URLSearchParams'
|
||||||
|
}));
|
||||||
|
@ -50,5 +50,9 @@ test(function() {
|
|||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.forEach.call(undefined);
|
params.forEach.call(undefined);
|
||||||
}, /^TypeError: Value of `this` is not a URLSearchParams$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_INVALID_THIS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'Value of "this" must be of type URLSearchParams'
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
@ -38,10 +38,18 @@ test(function() {
|
|||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.get.call(undefined);
|
params.get.call(undefined);
|
||||||
}, /^TypeError: Value of `this` is not a URLSearchParams$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_INVALID_THIS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'Value of "this" must be of type URLSearchParams'
|
||||||
|
}));
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.get();
|
params.get();
|
||||||
}, /^TypeError: "name" argument must be specified$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_MISSING_ARGS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'The "name" argument must be specified'
|
||||||
|
}));
|
||||||
|
|
||||||
const obj = {
|
const obj = {
|
||||||
toString() { throw new Error('toString'); },
|
toString() { throw new Error('toString'); },
|
||||||
|
@ -42,10 +42,18 @@ test(function() {
|
|||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.getAll.call(undefined);
|
params.getAll.call(undefined);
|
||||||
}, /^TypeError: Value of `this` is not a URLSearchParams$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_INVALID_THIS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'Value of "this" must be of type URLSearchParams'
|
||||||
|
}));
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.getAll();
|
params.getAll();
|
||||||
}, /^TypeError: "name" argument must be specified$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_MISSING_ARGS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'The "name" argument must be specified'
|
||||||
|
}));
|
||||||
|
|
||||||
const obj = {
|
const obj = {
|
||||||
toString() { throw new Error('toString'); },
|
toString() { throw new Error('toString'); },
|
||||||
|
@ -41,10 +41,18 @@ test(function() {
|
|||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.has.call(undefined);
|
params.has.call(undefined);
|
||||||
}, /^TypeError: Value of `this` is not a URLSearchParams$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_INVALID_THIS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'Value of "this" must be of type URLSearchParams'
|
||||||
|
}));
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.has();
|
params.has();
|
||||||
}, /^TypeError: "name" argument must be specified$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_MISSING_ARGS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'The "name" argument must be specified'
|
||||||
|
}));
|
||||||
|
|
||||||
const obj = {
|
const obj = {
|
||||||
toString() { throw new Error('toString'); },
|
toString() { throw new Error('toString'); },
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
require('../common');
|
const common = require('../common');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const URLSearchParams = require('url').URLSearchParams;
|
const URLSearchParams = require('url').URLSearchParams;
|
||||||
|
|
||||||
@ -29,7 +29,15 @@ assert.deepStrictEqual(keys.next(), {
|
|||||||
|
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
keys.next.call(undefined);
|
keys.next.call(undefined);
|
||||||
}, /^TypeError: Value of `this` is not a URLSearchParamsIterator$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_INVALID_THIS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'Value of "this" must be of type URLSearchParamsIterator'
|
||||||
|
}));
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.keys.call(undefined);
|
params.keys.call(undefined);
|
||||||
}, /^TypeError: Value of `this` is not a URLSearchParams$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_INVALID_THIS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'Value of "this" must be of type URLSearchParams'
|
||||||
|
}));
|
||||||
|
@ -39,10 +39,18 @@ test(function() {
|
|||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.set.call(undefined);
|
params.set.call(undefined);
|
||||||
}, /^TypeError: Value of `this` is not a URLSearchParams$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_INVALID_THIS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'Value of "this" must be of type URLSearchParams'
|
||||||
|
}));
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.set('a');
|
params.set('a');
|
||||||
}, /^TypeError: "name" and "value" arguments must be specified$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_MISSING_ARGS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'The "name" and "value" arguments must be specified'
|
||||||
|
}));
|
||||||
|
|
||||||
const obj = {
|
const obj = {
|
||||||
toString() { throw new Error('toString'); },
|
toString() { throw new Error('toString'); },
|
||||||
|
@ -127,5 +127,9 @@ test(function() {
|
|||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.toString.call(undefined);
|
params.toString.call(undefined);
|
||||||
}, /^TypeError: Value of `this` is not a URLSearchParams$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_INVALID_THIS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'Value of "this" must be of type URLSearchParams'
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
require('../common');
|
const common = require('../common');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const URLSearchParams = require('url').URLSearchParams;
|
const URLSearchParams = require('url').URLSearchParams;
|
||||||
|
|
||||||
@ -29,7 +29,15 @@ assert.deepStrictEqual(values.next(), {
|
|||||||
|
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
values.next.call(undefined);
|
values.next.call(undefined);
|
||||||
}, /^TypeError: Value of `this` is not a URLSearchParamsIterator$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_INVALID_THIS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'Value of "this" must be of type URLSearchParamsIterator'
|
||||||
|
}));
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
params.values.call(undefined);
|
params.values.call(undefined);
|
||||||
}, /^TypeError: Value of `this` is not a URLSearchParams$/);
|
}, common.expectsError({
|
||||||
|
code: 'ERR_INVALID_THIS',
|
||||||
|
type: TypeError,
|
||||||
|
message: 'Value of "this" must be of type URLSearchParams'
|
||||||
|
}));
|
||||||
|
@ -71,10 +71,15 @@ sp.forEach(function(val, key, obj) {
|
|||||||
sp.forEach(function() {
|
sp.forEach(function() {
|
||||||
assert.strictEqual(this, m);
|
assert.strictEqual(this, m);
|
||||||
}, m);
|
}, m);
|
||||||
assert.throws(() => sp.forEach(),
|
|
||||||
/^TypeError: "callback" argument must be a function$/);
|
{
|
||||||
assert.throws(() => sp.forEach(1),
|
const callbackErr = common.expectsError({
|
||||||
/^TypeError: "callback" argument must be a function$/);
|
code: 'ERR_INVALID_CALLBACK',
|
||||||
|
type: TypeError
|
||||||
|
});
|
||||||
|
assert.throws(() => sp.forEach(), callbackErr);
|
||||||
|
assert.throws(() => sp.forEach(1), callbackErr);
|
||||||
|
}
|
||||||
|
|
||||||
m.search = '?a=a&b=b';
|
m.search = '?a=a&b=b';
|
||||||
assert.strictEqual(sp.toString(), 'a=a&b=b');
|
assert.strictEqual(sp.toString(), 'a=a&b=b');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user