Skip to content

Commit 01ad8de

Browse files
XadillaXtargos
authored andcommitted
url,lib: pass urlsearchparams-constructor.any.js
According to WPT: 1. `URLSearchParams` constructor should throw exactly `TypeError` if any Error occurrs. 2. When a record passed to `URLSearchParams` constructor, two different key may result same after `toUVString()`. We should leave only the later one. PR-URL: #41197 Reviewed-By: Zijian Liu <[email protected]>
1 parent 524103d commit 01ad8de

File tree

4 files changed

+44
-13
lines changed

4 files changed

+44
-13
lines changed

lib/internal/per_context/domexception.js

+24-9
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,27 @@ const {
1010
TypeError,
1111
} = primordials;
1212

13-
class ERR_INVALID_THIS extends TypeError {
14-
constructor(type) {
15-
super('Value of "this" must be of ' + type);
16-
}
17-
18-
get code() { return 'ERR_INVALID_THIS'; }
13+
function throwInvalidThisError(Base, type) {
14+
const err = new Base();
15+
const key = 'ERR_INVALID_THIS';
16+
ObjectDefineProperties(err, {
17+
message: {
18+
value: `Value of "this" must be of ${type}`,
19+
enumerable: false,
20+
writable: true,
21+
configurable: true,
22+
},
23+
toString: {
24+
value() {
25+
return `${this.name} [${key}]: ${this.message}`;
26+
},
27+
enumerable: false,
28+
writable: true,
29+
configurable: true,
30+
},
31+
});
32+
err.code = key;
33+
throw err;
1934
}
2035

2136
let internalsMap;
@@ -51,7 +66,7 @@ class DOMException extends Error {
5166
ensureInitialized();
5267
const internals = internalsMap.get(this);
5368
if (internals === undefined) {
54-
throw new ERR_INVALID_THIS('DOMException');
69+
throwInvalidThisError(TypeError, 'DOMException');
5570
}
5671
return internals.name;
5772
}
@@ -60,7 +75,7 @@ class DOMException extends Error {
6075
ensureInitialized();
6176
const internals = internalsMap.get(this);
6277
if (internals === undefined) {
63-
throw new ERR_INVALID_THIS('DOMException');
78+
throwInvalidThisError(TypeError, 'DOMException');
6479
}
6580
return internals.message;
6681
}
@@ -69,7 +84,7 @@ class DOMException extends Error {
6984
ensureInitialized();
7085
const internals = internalsMap.get(this);
7186
if (internals === undefined) {
72-
throw new ERR_INVALID_THIS('DOMException');
87+
throwInvalidThisError(TypeError, 'DOMException');
7388
}
7489
const code = nameToCodeMap.get(internals.name);
7590
return code === undefined ? 0 : code;

lib/internal/url.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ class URLSearchParams {
219219
} else {
220220
// Record<USVString, USVString>
221221
// Need to use reflection APIs for full spec compliance.
222+
const visited = {};
222223
this[searchParams] = [];
223224
const keys = ReflectOwnKeys(init);
224225
for (let i = 0; i < keys.length; i++) {
@@ -227,7 +228,16 @@ class URLSearchParams {
227228
if (desc !== undefined && desc.enumerable) {
228229
const typedKey = toUSVString(key);
229230
const typedValue = toUSVString(init[key]);
230-
this[searchParams].push(typedKey, typedValue);
231+
232+
// Two different key may result same after `toUSVString()`, we only
233+
// leave the later one. Refers to WPT.
234+
if (visited[typedKey] !== undefined) {
235+
this[searchParams][visited[typedKey]] = typedValue;
236+
} else {
237+
visited[typedKey] = ArrayPrototypePush(this[searchParams],
238+
typedKey,
239+
typedValue) - 1;
240+
}
231241
}
232242
}
233243
}

test/wpt/status/url.json

-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@
1212
"urlencoded-parser.any.js": {
1313
"fail": "missing Request and Response"
1414
},
15-
"urlsearchparams-constructor.any.js": {
16-
"fail": "FormData is not defined"
17-
},
1815
"url-constructor.any.js": {
1916
"requires": ["small-icu"]
2017
},

test/wpt/test-url.js

+9
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ runner.setScriptModifier((obj) => {
1111
// created via `document.createElement`. So we need to ignore them and just
1212
// test `URL`.
1313
obj.code = obj.code.replace(/\["url", "a", "area"\]/, '[ "url" ]');
14+
} else if (typeof FormData === 'undefined' && // eslint-disable-line
15+
obj.filename.includes('urlsearchparams-constructor.any.js')) {
16+
// TODO(XadillaX): Remove this `else if` after `FormData` is supported.
17+
18+
// Ignore test named `URLSearchParams constructor, FormData.` because we do
19+
// not have `FormData`.
20+
obj.code = obj.code.replace(
21+
/('URLSearchParams constructor, object\.'\);[\w\W]+)test\(function\(\) {[\w\W]*?}, 'URLSearchParams constructor, FormData\.'\);/,
22+
'$1');
1423
}
1524
});
1625
runner.pretendGlobalThisAs('Window');

0 commit comments

Comments
 (0)