mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-06 17:48:37 +00:00
Tests/LibWeb: Import the WPT URL test suite
This commit is contained in:
parent
20890d7b70
commit
2022c9e679
Notes:
github-actions[bot]
2025-03-18 09:01:32 +00:00
Author: https://github.com/shannonbooth
Commit: 2022c9e679
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3869
Reviewed-by: https://github.com/gmta ✅
Reviewed-by: https://github.com/vishalbiswas
59 changed files with 31488 additions and 0 deletions
|
@ -0,0 +1,83 @@
|
|||
(function() {
|
||||
var subTestKeyPattern = null;
|
||||
var match;
|
||||
var collectKeys = false;
|
||||
var collectCounts = false;
|
||||
var keys = {};
|
||||
var exclude = false;
|
||||
if (location.search) {
|
||||
match = /(?:^\?|&)(include|exclude)=([^&]+)?/.exec(location.search);
|
||||
if (match) {
|
||||
subTestKeyPattern = new RegExp(`^${match[2]}$`);
|
||||
if (match[1] === 'exclude') {
|
||||
exclude = true;
|
||||
}
|
||||
}
|
||||
// Below is utility code to generate <meta> for copy/paste into tests.
|
||||
// Sample usage:
|
||||
// test.html?get-keys
|
||||
match = /(?:^\?|&)get-keys(&get-counts)?(?:&|$)/.exec(location.search);
|
||||
if (match) {
|
||||
collectKeys = true;
|
||||
if (match[1]) {
|
||||
collectCounts = true;
|
||||
}
|
||||
add_completion_callback(() => {
|
||||
var metas = [];
|
||||
var template = '<meta name="variant" content="?include=%s">';
|
||||
if (collectCounts) {
|
||||
template += ' <!--%s-->';
|
||||
}
|
||||
for (var key in keys) {
|
||||
var meta = template.replace("%s", key);
|
||||
if (collectCounts) {
|
||||
meta = meta.replace("%s", keys[key]);
|
||||
}
|
||||
metas.push(meta);
|
||||
}
|
||||
var pre = document.createElement('pre');
|
||||
pre.textContent = metas.join('\n') + '\n';
|
||||
document.body.insertBefore(pre, document.body.firstChild);
|
||||
document.getSelection().selectAllChildren(pre);
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Check if `key` is in the subset specified in the URL.
|
||||
* @param {string} key
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function shouldRunSubTest(key) {
|
||||
if (key && subTestKeyPattern) {
|
||||
var found = subTestKeyPattern.test(key);
|
||||
if (exclude) {
|
||||
return !found;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Only test a subset of tests with `?include=Foo` or `?exclude=Foo` in the URL.
|
||||
* Can be used together with `<meta name="variant" content="...">`
|
||||
* Sample usage:
|
||||
* for (const test of tests) {
|
||||
* subsetTestByKey("Foo", async_test, test.fn, test.name);
|
||||
* }
|
||||
*/
|
||||
function subsetTestByKey(key, testFunc, ...args) {
|
||||
if (collectKeys) {
|
||||
if (collectCounts && key in keys) {
|
||||
keys[key]++;
|
||||
} else {
|
||||
keys[key] = 1;
|
||||
}
|
||||
}
|
||||
if (shouldRunSubTest(key)) {
|
||||
return testFunc(...args);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
self.shouldRunSubTest = shouldRunSubTest;
|
||||
self.subsetTestByKey = subsetTestByKey;
|
||||
})();
|
|
@ -0,0 +1,8 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
|
||||
<div id=log></div>
|
||||
<script src="../url/IdnaTestV2.window.js"></script>
|
24
Tests/LibWeb/Text/input/wpt-import/url/IdnaTestV2.window.js
Normal file
24
Tests/LibWeb/Text/input/wpt-import/url/IdnaTestV2.window.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
promise_test(() => fetch("resources/IdnaTestV2.json").then(res => res.json()).then(runTests), "Loading data…");
|
||||
|
||||
function runTests(idnaTests) {
|
||||
for (const idnaTest of idnaTests) {
|
||||
if (typeof idnaTest === "string") {
|
||||
continue // skip comments
|
||||
}
|
||||
if (idnaTest.input === "") {
|
||||
continue // cannot test empty string input through new URL()
|
||||
}
|
||||
|
||||
test(() => {
|
||||
if (idnaTest.output === null) {
|
||||
assert_throws_js(TypeError, () => new URL(`https://${idnaTest.input}/x`));
|
||||
} else {
|
||||
const url = new URL(`https://${idnaTest.input}/x`);
|
||||
assert_equals(url.host, idnaTest.output);
|
||||
assert_equals(url.hostname, idnaTest.output);
|
||||
assert_equals(url.pathname, "/x");
|
||||
assert_equals(url.href, `https://${idnaTest.output}/x`);
|
||||
}
|
||||
}, `ToASCII("${idnaTest.input}")${idnaTest.comment ? " " + idnaTest.comment : ""}`);
|
||||
}
|
||||
}
|
12
Tests/LibWeb/Text/input/wpt-import/url/a-element-origin.html
Normal file
12
Tests/LibWeb/Text/input/wpt-import/url/a-element-origin.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<script src=../resources/testharness.js></script>
|
||||
<script src=../resources/testharnessreport.js></script>
|
||||
<base id=base>
|
||||
<div id=log></div>
|
||||
<script src=resources/a-element-origin.js></script>
|
||||
<!--
|
||||
Other dependencies:
|
||||
* resources/urltestdata.json,
|
||||
* resources/urltestdata-javascript-only.json,
|
||||
-->
|
12803
Tests/LibWeb/Text/input/wpt-import/url/resources/IdnaTestV2.json
Normal file
12803
Tests/LibWeb/Text/input/wpt-import/url/resources/IdnaTestV2.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,39 @@
|
|||
promise_test(() => Promise.all([
|
||||
fetch("resources/urltestdata.json").then(res => res.json()),
|
||||
fetch("resources/urltestdata-javascript-only.json").then(res => res.json()),
|
||||
]).then((tests) => tests.flat()).then(runURLTests), "Loading data…");
|
||||
|
||||
function setBase(base) {
|
||||
document.getElementById("base").href = base
|
||||
}
|
||||
|
||||
function bURL(url, base) {
|
||||
setBase(base);
|
||||
const a = document.createElement("a");
|
||||
a.setAttribute("href", url);
|
||||
return a;
|
||||
}
|
||||
|
||||
function runURLTests(urlTests) {
|
||||
for (const expected of urlTests) {
|
||||
// Skip comments and tests without "origin" expectation
|
||||
if (typeof expected === "string" || !("origin" in expected))
|
||||
continue;
|
||||
|
||||
// Fragments are relative against "about:blank" (this might always be redundant due to requiring "origin" in expected)
|
||||
if (expected.base === null && expected.input.startsWith("#"))
|
||||
continue;
|
||||
|
||||
// HTML special cases data: and javascript: URLs in <base>
|
||||
if (expected.base !== null && (expected.base.startsWith("data:") || expected.base.startsWith("javascript:")))
|
||||
continue;
|
||||
|
||||
// We cannot use a null base for HTML tests
|
||||
const base = expected.base === null ? "about:blank" : expected.base;
|
||||
|
||||
test(function() {
|
||||
var url = bURL(expected.input, base)
|
||||
assert_equals(url.origin, expected.origin, "origin")
|
||||
}, "Parsing origin: <" + expected.input + "> against <" + base + ">")
|
||||
}
|
||||
}
|
2424
Tests/LibWeb/Text/input/wpt-import/url/resources/setters_tests.json
Normal file
2424
Tests/LibWeb/Text/input/wpt-import/url/resources/setters_tests.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,18 @@
|
|||
[
|
||||
"See ../README.md for a description of the format.",
|
||||
{
|
||||
"input": "http://example.com/\uD800\uD801\uDFFE\uDFFF\uFDD0\uFDCF\uFDEF\uFDF0\uFFFE\uFFFF?\uD800\uD801\uDFFE\uDFFF\uFDD0\uFDCF\uFDEF\uFDF0\uFFFE\uFFFF",
|
||||
"base": null,
|
||||
"href": "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF",
|
||||
"origin": "http://example.com",
|
||||
"protocol": "http:",
|
||||
"username": "",
|
||||
"password": "",
|
||||
"host": "example.com",
|
||||
"hostname": "example.com",
|
||||
"port": "",
|
||||
"pathname": "/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF",
|
||||
"search": "?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF",
|
||||
"hash": ""
|
||||
}
|
||||
]
|
10122
Tests/LibWeb/Text/input/wpt-import/url/resources/urltestdata.json
Normal file
10122
Tests/LibWeb/Text/input/wpt-import/url/resources/urltestdata.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<meta name="timeout" content="long">
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
<script src="../common/subset-tests-by-key.js"></script>
|
||||
<div id=log></div>
|
||||
<script src="../url/url-constructor.any.js"></script>
|
|
@ -0,0 +1,56 @@
|
|||
// META: script=/common/subset-tests-by-key.js
|
||||
// META: timeout=long
|
||||
// META: variant=?include=file
|
||||
// META: variant=?include=javascript
|
||||
// META: variant=?include=mailto
|
||||
// META: variant=?exclude=(file|javascript|mailto)
|
||||
|
||||
function runURLTests(urlTests) {
|
||||
for (const expected of urlTests) {
|
||||
// Skip comments
|
||||
if (typeof expected === "string")
|
||||
continue;
|
||||
|
||||
const base = expected.base !== null ? expected.base : undefined;
|
||||
|
||||
function getKey(expected) {
|
||||
if (expected.protocol) {
|
||||
return expected.protocol.replace(":", "");
|
||||
}
|
||||
if (expected.failure) {
|
||||
return expected.input.split(":")[0];
|
||||
}
|
||||
return "other";
|
||||
}
|
||||
|
||||
subsetTestByKey(getKey(expected), test, function() {
|
||||
if (expected.failure) {
|
||||
assert_throws_js(TypeError, function() {
|
||||
new URL(expected.input, base);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const url = new URL(expected.input, base);
|
||||
assert_equals(url.href, expected.href, "href")
|
||||
assert_equals(url.protocol, expected.protocol, "protocol")
|
||||
assert_equals(url.username, expected.username, "username")
|
||||
assert_equals(url.password, expected.password, "password")
|
||||
assert_equals(url.host, expected.host, "host")
|
||||
assert_equals(url.hostname, expected.hostname, "hostname")
|
||||
assert_equals(url.port, expected.port, "port")
|
||||
assert_equals(url.pathname, expected.pathname, "pathname")
|
||||
assert_equals(url.search, expected.search, "search")
|
||||
if ("searchParams" in expected) {
|
||||
assert_true("searchParams" in url)
|
||||
assert_equals(url.searchParams.toString(), expected.searchParams, "searchParams")
|
||||
}
|
||||
assert_equals(url.hash, expected.hash, "hash")
|
||||
}, `Parsing: <${expected.input}> ${base ? "against <" + base + ">" : "without base"}`)
|
||||
}
|
||||
}
|
||||
|
||||
promise_test(() => Promise.all([
|
||||
fetch("resources/urltestdata.json").then(res => res.json()),
|
||||
fetch("resources/urltestdata-javascript-only.json").then(res => res.json()),
|
||||
]).then((tests) => tests.flat()).then(runURLTests), "Loading data…");
|
15
Tests/LibWeb/Text/input/wpt-import/url/url-origin.any.html
Normal file
15
Tests/LibWeb/Text/input/wpt-import/url/url-origin.any.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
|
||||
<div id=log></div>
|
||||
<script src="../url/url-origin.any.js"></script>
|
19
Tests/LibWeb/Text/input/wpt-import/url/url-origin.any.js
Normal file
19
Tests/LibWeb/Text/input/wpt-import/url/url-origin.any.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
promise_test(() => Promise.all([
|
||||
fetch("resources/urltestdata.json").then(res => res.json()),
|
||||
fetch("resources/urltestdata-javascript-only.json").then(res => res.json()),
|
||||
]).then((tests) => tests.flat()).then(runURLTests), "Loading data…");
|
||||
|
||||
function runURLTests(urlTests) {
|
||||
for (const expected of urlTests) {
|
||||
// Skip comments and tests without "origin" expectation
|
||||
if (typeof expected === "string" || !("origin" in expected))
|
||||
continue;
|
||||
|
||||
const base = expected.base !== null ? expected.base : undefined;
|
||||
|
||||
test(() => {
|
||||
const url = new URL(expected.input, base);
|
||||
assert_equals(url.origin, expected.origin, "origin");
|
||||
}, `Origin parsing: <${expected.input}> ${base ? "against <" + base + ">" : "without base"}`);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
<script src="../common/subset-tests-by-key.js"></script>
|
||||
<div id=log></div>
|
||||
<script src="../url/url-setters-a-area.window.js"></script>
|
|
@ -0,0 +1,43 @@
|
|||
// META: script=/common/subset-tests-by-key.js
|
||||
// META: variant=?include=file
|
||||
// META: variant=?include=javascript
|
||||
// META: variant=?include=mailto
|
||||
// META: variant=?exclude=(file|javascript|mailto)
|
||||
|
||||
// Keep this file in sync with url-setters.any.js.
|
||||
|
||||
promise_test(() => fetch("resources/setters_tests.json").then(res => res.json()).then(runURLSettersTests), "Loading data…");
|
||||
|
||||
function runURLSettersTests(all_test_cases) {
|
||||
for (var attribute_to_be_set in all_test_cases) {
|
||||
if (attribute_to_be_set == "comment") {
|
||||
continue;
|
||||
}
|
||||
var test_cases = all_test_cases[attribute_to_be_set];
|
||||
for(var i = 0, l = test_cases.length; i < l; i++) {
|
||||
var test_case = test_cases[i];
|
||||
var name = "Setting <" + test_case.href + ">." + attribute_to_be_set +
|
||||
" = '" + test_case.new_value + "'";
|
||||
if ("comment" in test_case) {
|
||||
name += " " + test_case.comment;
|
||||
}
|
||||
const key = test_case.href.split(":")[0];
|
||||
subsetTestByKey(key, test, function() {
|
||||
var url = document.createElement("a");
|
||||
url.href = test_case.href;
|
||||
url[attribute_to_be_set] = test_case.new_value;
|
||||
for (var attribute in test_case.expected) {
|
||||
assert_equals(url[attribute], test_case.expected[attribute])
|
||||
}
|
||||
}, "<a>: " + name)
|
||||
subsetTestByKey(key, test, function() {
|
||||
var url = document.createElement("area");
|
||||
url.href = test_case.href;
|
||||
url[attribute_to_be_set] = test_case.new_value;
|
||||
for (var attribute in test_case.expected) {
|
||||
assert_equals(url[attribute], test_case.expected[attribute])
|
||||
}
|
||||
}, "<area>: " + name)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
|
||||
<div id=log></div>
|
||||
<script src="../url/url-setters-stripping.any.js"></script>
|
|
@ -0,0 +1,125 @@
|
|||
function urlString({ scheme = "https",
|
||||
username = "username",
|
||||
password = "password",
|
||||
host = "host",
|
||||
port = "8000",
|
||||
pathname = "path",
|
||||
search = "query",
|
||||
hash = "fragment" }) {
|
||||
return `${scheme}://${username}:${password}@${host}:${port}/${pathname}?${search}#${hash}`;
|
||||
}
|
||||
|
||||
function urlRecord(scheme) {
|
||||
return new URL(urlString({ scheme }));
|
||||
}
|
||||
|
||||
for(const scheme of ["https", "wpt++"]) {
|
||||
for(let i = 0; i < 0x20; i++) {
|
||||
const stripped = i === 0x09 || i === 0x0A || i === 0x0D;
|
||||
|
||||
// It turns out that user agents are surprisingly similar for these ranges so generate fewer
|
||||
// tests. If this is changed also change the logic for host below.
|
||||
if (i !== 0 && i !== 0x1F && !stripped) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const cpString = String.fromCodePoint(i);
|
||||
const cpReference = "U+" + i.toString(16).toUpperCase().padStart(4, "0");
|
||||
|
||||
test(() => {
|
||||
const expected = scheme === "https" ? (stripped ? "http" : "https") : (stripped ? "wpt--" : "wpt++");
|
||||
const url = urlRecord(scheme);
|
||||
url.protocol = String.fromCodePoint(i) + (scheme === "https" ? "http" : "wpt--");
|
||||
assert_equals(url.protocol, expected + ":", "property");
|
||||
assert_equals(url.href, urlString({ scheme: expected }), "href");
|
||||
}, `Setting protocol with leading ${cpReference} (${scheme}:)`);
|
||||
|
||||
test(() => {
|
||||
const expected = scheme === "https" ? (stripped ? "http" : "https") : (stripped ? "wpt--" : "wpt++");
|
||||
const url = urlRecord(scheme);
|
||||
url.protocol = (scheme === "https" ? "http" : "wpt--") + String.fromCodePoint(i);
|
||||
assert_equals(url.protocol, expected + ":", "property");
|
||||
assert_equals(url.href, urlString({ scheme: expected }), "href");
|
||||
}, `Setting protocol with ${cpReference} before inserted colon (${scheme}:)`);
|
||||
|
||||
// Cannot test protocol with trailing as the algorithm inserts a colon before proceeding
|
||||
|
||||
// These do no stripping
|
||||
for (const property of ["username", "password"]) {
|
||||
for (const [type, expected, input] of [
|
||||
["leading", encodeURIComponent(cpString) + "test", String.fromCodePoint(i) + "test"],
|
||||
["middle", "te" + encodeURIComponent(cpString) + "st", "te" + String.fromCodePoint(i) + "st"],
|
||||
["trailing", "test" + encodeURIComponent(cpString), "test" + String.fromCodePoint(i)]
|
||||
]) {
|
||||
test(() => {
|
||||
const url = urlRecord(scheme);
|
||||
url[property] = input;
|
||||
assert_equals(url[property], expected, "property");
|
||||
assert_equals(url.href, urlString({ scheme, [property]: expected }), "href");
|
||||
}, `Setting ${property} with ${type} ${cpReference} (${scheme}:)`);
|
||||
}
|
||||
}
|
||||
|
||||
for (const [type, expectedPart, input] of [
|
||||
["leading", (scheme === "https" ? cpString : encodeURIComponent(cpString)) + "test", String.fromCodePoint(i) + "test"],
|
||||
["middle", "te" + (scheme === "https" ? cpString : encodeURIComponent(cpString)) + "st", "te" + String.fromCodePoint(i) + "st"],
|
||||
["trailing", "test" + (scheme === "https" ? cpString : encodeURIComponent(cpString)), "test" + String.fromCodePoint(i)]
|
||||
]) {
|
||||
test(() => {
|
||||
const expected = i === 0x00 || (scheme === "https" && i === 0x1F) ? "host" : stripped ? "test" : expectedPart;
|
||||
const url = urlRecord(scheme);
|
||||
url.host = input;
|
||||
assert_equals(url.host, expected + ":8000", "property");
|
||||
assert_equals(url.href, urlString({ scheme, host: expected }), "href");
|
||||
}, `Setting host with ${type} ${cpReference} (${scheme}:)`);
|
||||
|
||||
test(() => {
|
||||
const expected = i === 0x00 || (scheme === "https" && i === 0x1F) ? "host" : stripped ? "test" : expectedPart;
|
||||
const url = urlRecord(scheme);
|
||||
url.hostname = input;
|
||||
assert_equals(url.hostname, expected, "property");
|
||||
assert_equals(url.href, urlString({ scheme, host: expected }), "href");
|
||||
}, `Setting hostname with ${type} ${cpReference} (${scheme}:)`);
|
||||
}
|
||||
|
||||
test(() => {
|
||||
const expected = stripped ? "9000" : "8000";
|
||||
const url = urlRecord(scheme);
|
||||
url.port = String.fromCodePoint(i) + "9000";
|
||||
assert_equals(url.port, expected, "property");
|
||||
assert_equals(url.href, urlString({ scheme, port: expected }), "href");
|
||||
}, `Setting port with leading ${cpReference} (${scheme}:)`);
|
||||
|
||||
test(() => {
|
||||
const expected = stripped ? "9000" : "90";
|
||||
const url = urlRecord(scheme);
|
||||
url.port = "90" + String.fromCodePoint(i) + "00";
|
||||
assert_equals(url.port, expected, "property");
|
||||
assert_equals(url.href, urlString({ scheme, port: expected }), "href");
|
||||
}, `Setting port with middle ${cpReference} (${scheme}:)`);
|
||||
|
||||
test(() => {
|
||||
const expected = "9000";
|
||||
const url = urlRecord(scheme);
|
||||
url.port = "9000" + String.fromCodePoint(i);
|
||||
assert_equals(url.port, expected, "property");
|
||||
assert_equals(url.href, urlString({ scheme, port: expected }), "href");
|
||||
}, `Setting port with trailing ${cpReference} (${scheme}:)`);
|
||||
|
||||
for (const [property, separator] of [["pathname", "/"], ["search", "?"], ["hash", "#"]]) {
|
||||
for (const [type, expectedPart, input] of [
|
||||
["leading", encodeURIComponent(cpString) + "test", String.fromCodePoint(i) + "test"],
|
||||
["middle", "te" + encodeURIComponent(cpString) + "st", "te" + String.fromCodePoint(i) + "st"],
|
||||
["trailing", "test" + encodeURIComponent(cpString), "test" + String.fromCodePoint(i)]
|
||||
]) {
|
||||
test(() => {
|
||||
const expected = stripped ? "test" : expectedPart;
|
||||
const url = urlRecord(scheme);
|
||||
url[property] = input;
|
||||
assert_equals(url[property], separator + expected, "property");
|
||||
assert_equals(url.href, urlString({ scheme, [property]: expected }), "href");
|
||||
}, `Setting ${property} with ${type} ${cpReference} (${scheme}:)`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
Tests/LibWeb/Text/input/wpt-import/url/url-setters.any.html
Normal file
15
Tests/LibWeb/Text/input/wpt-import/url/url-setters.any.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
<script src="../common/subset-tests-by-key.js"></script>
|
||||
<div id=log></div>
|
||||
<script src="../url/url-setters.any.js"></script>
|
34
Tests/LibWeb/Text/input/wpt-import/url/url-setters.any.js
Normal file
34
Tests/LibWeb/Text/input/wpt-import/url/url-setters.any.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
// META: script=/common/subset-tests-by-key.js
|
||||
// META: variant=?include=file
|
||||
// META: variant=?include=javascript
|
||||
// META: variant=?include=mailto
|
||||
// META: variant=?exclude=(file|javascript|mailto)
|
||||
|
||||
// Keep this file in sync with url-setters-a-area.window.js.
|
||||
|
||||
promise_test(() => fetch("resources/setters_tests.json").then(res => res.json()).then(runURLSettersTests), "Loading data…");
|
||||
|
||||
function runURLSettersTests(all_test_cases) {
|
||||
for (var attribute_to_be_set in all_test_cases) {
|
||||
if (attribute_to_be_set == "comment") {
|
||||
continue;
|
||||
}
|
||||
var test_cases = all_test_cases[attribute_to_be_set];
|
||||
for(var i = 0, l = test_cases.length; i < l; i++) {
|
||||
var test_case = test_cases[i];
|
||||
var name = "Setting <" + test_case.href + ">." + attribute_to_be_set +
|
||||
" = '" + test_case.new_value + "'";
|
||||
if ("comment" in test_case) {
|
||||
name += " " + test_case.comment;
|
||||
}
|
||||
const key = test_case.href.split(":")[0];
|
||||
subsetTestByKey(key, test, function() {
|
||||
var url = new URL(test_case.href);
|
||||
url[attribute_to_be_set] = test_case.new_value;
|
||||
for (var attribute in test_case.expected) {
|
||||
assert_equals(url[attribute], test_case.expected[attribute])
|
||||
}
|
||||
}, "URL: " + name)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
|
||||
<div id=log></div>
|
||||
<script src="../url/url-statics-parse.any.js"></script>
|
|
@ -0,0 +1,50 @@
|
|||
// This intentionally does not use resources/urltestdata.json to preserve resources.
|
||||
[
|
||||
{
|
||||
"url": undefined,
|
||||
"base": undefined,
|
||||
"expected": false
|
||||
},
|
||||
{
|
||||
"url": "aaa:b",
|
||||
"base": undefined,
|
||||
"expected": true
|
||||
},
|
||||
{
|
||||
"url": undefined,
|
||||
"base": "aaa:b",
|
||||
"expected": false
|
||||
},
|
||||
{
|
||||
"url": "aaa:/b",
|
||||
"base": undefined,
|
||||
"expected": true
|
||||
},
|
||||
{
|
||||
"url": undefined,
|
||||
"base": "aaa:/b",
|
||||
"expected": true
|
||||
},
|
||||
{
|
||||
"url": "https://test:test",
|
||||
"base": undefined,
|
||||
"expected": false
|
||||
},
|
||||
{
|
||||
"url": "a",
|
||||
"base": "https://b/",
|
||||
"expected": true
|
||||
}
|
||||
].forEach(({ url, base, expected }) => {
|
||||
test(() => {
|
||||
if (expected == false) {
|
||||
assert_equals(URL.parse(url, base), null);
|
||||
} else {
|
||||
assert_equals(URL.parse(url, base).href, new URL(url, base).href);
|
||||
}
|
||||
}, `URL.parse(${url}, ${base})`);
|
||||
});
|
||||
|
||||
test(() => {
|
||||
assert_not_equals(URL.parse("https://example/"), URL.parse("https://example/"));
|
||||
}, `URL.parse() should return a unique object`);
|
15
Tests/LibWeb/Text/input/wpt-import/url/url-tojson.any.html
Normal file
15
Tests/LibWeb/Text/input/wpt-import/url/url-tojson.any.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
|
||||
<div id=log></div>
|
||||
<script src="../url/url-tojson.any.js"></script>
|
4
Tests/LibWeb/Text/input/wpt-import/url/url-tojson.any.js
Normal file
4
Tests/LibWeb/Text/input/wpt-import/url/url-tojson.any.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
test(() => {
|
||||
const a = new URL("https://example.com/")
|
||||
assert_equals(JSON.stringify(a), "\"https://example.com/\"")
|
||||
})
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
|
||||
<div id=log></div>
|
||||
<script src="../url/urlencoded-parser.any.js"></script>
|
|
@ -0,0 +1,68 @@
|
|||
[
|
||||
{ "input": "test", "output": [["test", ""]] },
|
||||
{ "input": "\uFEFFtest=\uFEFF", "output": [["\uFEFFtest", "\uFEFF"]] },
|
||||
{ "input": "%EF%BB%BFtest=%EF%BB%BF", "output": [["\uFEFFtest", "\uFEFF"]] },
|
||||
{ "input": "%EF%BF%BF=%EF%BF%BF", "output": [["\uFFFF", "\uFFFF"]] },
|
||||
{ "input": "%FE%FF", "output": [["\uFFFD\uFFFD", ""]] },
|
||||
{ "input": "%FF%FE", "output": [["\uFFFD\uFFFD", ""]] },
|
||||
{ "input": "†&†=x", "output": [["†", ""], ["†", "x"]] },
|
||||
{ "input": "%C2", "output": [["\uFFFD", ""]] },
|
||||
{ "input": "%C2x", "output": [["\uFFFDx", ""]] },
|
||||
{ "input": "_charset_=windows-1252&test=%C2x", "output": [["_charset_", "windows-1252"], ["test", "\uFFFDx"]] },
|
||||
{ "input": '', "output": [] },
|
||||
{ "input": 'a', "output": [['a', '']] },
|
||||
{ "input": 'a=b', "output": [['a', 'b']] },
|
||||
{ "input": 'a=', "output": [['a', '']] },
|
||||
{ "input": '=b', "output": [['', 'b']] },
|
||||
{ "input": '&', "output": [] },
|
||||
{ "input": '&a', "output": [['a', '']] },
|
||||
{ "input": 'a&', "output": [['a', '']] },
|
||||
{ "input": 'a&a', "output": [['a', ''], ['a', '']] },
|
||||
{ "input": 'a&b&c', "output": [['a', ''], ['b', ''], ['c', '']] },
|
||||
{ "input": 'a=b&c=d', "output": [['a', 'b'], ['c', 'd']] },
|
||||
{ "input": 'a=b&c=d&', "output": [['a', 'b'], ['c', 'd']] },
|
||||
{ "input": '&&&a=b&&&&c=d&', "output": [['a', 'b'], ['c', 'd']] },
|
||||
{ "input": 'a=a&a=b&a=c', "output": [['a', 'a'], ['a', 'b'], ['a', 'c']] },
|
||||
{ "input": 'a==a', "output": [['a', '=a']] },
|
||||
{ "input": 'a=a+b+c+d', "output": [['a', 'a b c d']] },
|
||||
{ "input": '%=a', "output": [['%', 'a']] },
|
||||
{ "input": '%a=a', "output": [['%a', 'a']] },
|
||||
{ "input": '%a_=a', "output": [['%a_', 'a']] },
|
||||
{ "input": '%61=a', "output": [['a', 'a']] },
|
||||
{ "input": '%61+%4d%4D=', "output": [['a MM', '']] },
|
||||
{ "input": "id=0&value=%", "output": [['id', '0'], ['value', '%']] },
|
||||
{ "input": "b=%2sf%2a", "output": [['b', '%2sf*']]},
|
||||
{ "input": "b=%2%2af%2a", "output": [['b', '%2*f*']]},
|
||||
{ "input": "b=%%2a", "output": [['b', '%*']]}
|
||||
].forEach((val) => {
|
||||
test(() => {
|
||||
let sp = new URLSearchParams(val.input),
|
||||
i = 0
|
||||
for (let item of sp) {
|
||||
assert_array_equals(item, val.output[i])
|
||||
i++
|
||||
}
|
||||
}, "URLSearchParams constructed with: " + val.input)
|
||||
|
||||
promise_test(() => {
|
||||
let init = new Request("about:blank", { body: val.input, method: "LADIDA", headers: {"Content-Type": "application/x-www-form-urlencoded;charset=windows-1252"} }).formData()
|
||||
return init.then((fd) => {
|
||||
let i = 0
|
||||
for (let item of fd) {
|
||||
assert_array_equals(item, val.output[i])
|
||||
i++
|
||||
}
|
||||
})
|
||||
}, "request.formData() with input: " + val.input)
|
||||
|
||||
promise_test(() => {
|
||||
let init = new Response(val.input, { headers: {"Content-Type": "application/x-www-form-urlencoded;charset=shift_jis"} }).formData()
|
||||
return init.then((fd) => {
|
||||
let i = 0
|
||||
for (let item of fd) {
|
||||
assert_array_equals(item, val.output[i])
|
||||
i++
|
||||
}
|
||||
})
|
||||
}, "response.formData() with input: " + val.input)
|
||||
});
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
|
||||
<div id=log></div>
|
||||
<script src="../url/urlsearchparams-delete.any.js"></script>
|
|
@ -0,0 +1,83 @@
|
|||
test(function() {
|
||||
var params = new URLSearchParams('a=b&c=d');
|
||||
params.delete('a');
|
||||
assert_equals(params + '', 'c=d');
|
||||
params = new URLSearchParams('a=a&b=b&a=a&c=c');
|
||||
params.delete('a');
|
||||
assert_equals(params + '', 'b=b&c=c');
|
||||
params = new URLSearchParams('a=a&=&b=b&c=c');
|
||||
params.delete('');
|
||||
assert_equals(params + '', 'a=a&b=b&c=c');
|
||||
params = new URLSearchParams('a=a&null=null&b=b');
|
||||
params.delete(null);
|
||||
assert_equals(params + '', 'a=a&b=b');
|
||||
params = new URLSearchParams('a=a&undefined=undefined&b=b');
|
||||
params.delete(undefined);
|
||||
assert_equals(params + '', 'a=a&b=b');
|
||||
}, 'Delete basics');
|
||||
|
||||
test(function() {
|
||||
var params = new URLSearchParams();
|
||||
params.append('first', 1);
|
||||
assert_true(params.has('first'), 'Search params object has name "first"');
|
||||
assert_equals(params.get('first'), '1', 'Search params object has name "first" with value "1"');
|
||||
params.delete('first');
|
||||
assert_false(params.has('first'), 'Search params object has no "first" name');
|
||||
params.append('first', 1);
|
||||
params.append('first', 10);
|
||||
params.delete('first');
|
||||
assert_false(params.has('first'), 'Search params object has no "first" name');
|
||||
}, 'Deleting appended multiple');
|
||||
|
||||
test(function() {
|
||||
var url = new URL('http://example.com/?param1¶m2');
|
||||
url.searchParams.delete('param1');
|
||||
url.searchParams.delete('param2');
|
||||
assert_equals(url.href, 'http://example.com/', 'url.href does not have ?');
|
||||
assert_equals(url.search, '', 'url.search does not have ?');
|
||||
}, 'Deleting all params removes ? from URL');
|
||||
|
||||
test(function() {
|
||||
var url = new URL('http://example.com/?');
|
||||
url.searchParams.delete('param1');
|
||||
assert_equals(url.href, 'http://example.com/', 'url.href does not have ?');
|
||||
assert_equals(url.search, '', 'url.search does not have ?');
|
||||
}, 'Removing non-existent param removes ? from URL');
|
||||
|
||||
test(() => {
|
||||
const url = new URL('data:space ?test');
|
||||
assert_true(url.searchParams.has('test'));
|
||||
url.searchParams.delete('test');
|
||||
assert_false(url.searchParams.has('test'));
|
||||
assert_equals(url.search, '');
|
||||
assert_equals(url.pathname, 'space');
|
||||
assert_equals(url.href, 'data:space');
|
||||
}, 'Changing the query of a URL with an opaque path can impact the path');
|
||||
|
||||
test(() => {
|
||||
const url = new URL('data:space ?test#test');
|
||||
url.searchParams.delete('test');
|
||||
assert_equals(url.search, '');
|
||||
assert_equals(url.pathname, 'space ');
|
||||
assert_equals(url.href, 'data:space #test');
|
||||
}, 'Changing the query of a URL with an opaque path can impact the path if the URL has no fragment');
|
||||
|
||||
test(() => {
|
||||
const params = new URLSearchParams();
|
||||
params.append('a', 'b');
|
||||
params.append('a', 'c');
|
||||
params.append('a', 'd');
|
||||
params.delete('a', 'c');
|
||||
assert_equals(params.toString(), 'a=b&a=d');
|
||||
}, "Two-argument delete()");
|
||||
|
||||
test(() => {
|
||||
const params = new URLSearchParams();
|
||||
params.append('a', 'b');
|
||||
params.append('a', 'c');
|
||||
params.append('b', 'c');
|
||||
params.append('b', 'd');
|
||||
params.delete('b', 'c');
|
||||
params.delete('a', undefined);
|
||||
assert_equals(params.toString(), 'b=d');
|
||||
}, "Two-argument delete() respects undefined as second arg");
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
|
||||
<div id=log></div>
|
||||
<script src="../url/urlsearchparams-foreach.any.js"></script>
|
|
@ -0,0 +1,76 @@
|
|||
test(function() {
|
||||
var params = new URLSearchParams('a=1&b=2&c=3');
|
||||
var keys = [];
|
||||
var values = [];
|
||||
params.forEach(function(value, key) {
|
||||
keys.push(key);
|
||||
values.push(value);
|
||||
});
|
||||
assert_array_equals(keys, ['a', 'b', 'c']);
|
||||
assert_array_equals(values, ['1', '2', '3']);
|
||||
}, "ForEach Check");
|
||||
|
||||
test(function() {
|
||||
let a = new URL("http://a.b/c?a=1&b=2&c=3&d=4");
|
||||
let b = a.searchParams;
|
||||
var c = [];
|
||||
for (const i of b) {
|
||||
a.search = "x=1&y=2&z=3";
|
||||
c.push(i);
|
||||
}
|
||||
assert_array_equals(c[0], ["a","1"]);
|
||||
assert_array_equals(c[1], ["y","2"]);
|
||||
assert_array_equals(c[2], ["z","3"]);
|
||||
}, "For-of Check");
|
||||
|
||||
test(function() {
|
||||
let a = new URL("http://a.b/c");
|
||||
let b = a.searchParams;
|
||||
for (const i of b) {
|
||||
assert_unreached(i);
|
||||
}
|
||||
}, "empty");
|
||||
|
||||
test(function() {
|
||||
const url = new URL("http://localhost/query?param0=0¶m1=1¶m2=2");
|
||||
const searchParams = url.searchParams;
|
||||
const seen = [];
|
||||
for (const param of searchParams) {
|
||||
if (param[0] === 'param0') {
|
||||
searchParams.delete('param1');
|
||||
}
|
||||
seen.push(param);
|
||||
}
|
||||
|
||||
assert_array_equals(seen[0], ["param0", "0"]);
|
||||
assert_array_equals(seen[1], ["param2", "2"]);
|
||||
}, "delete next param during iteration");
|
||||
|
||||
test(function() {
|
||||
const url = new URL("http://localhost/query?param0=0¶m1=1¶m2=2");
|
||||
const searchParams = url.searchParams;
|
||||
const seen = [];
|
||||
for (const param of searchParams) {
|
||||
if (param[0] === 'param0') {
|
||||
searchParams.delete('param0');
|
||||
// 'param1=1' is now in the first slot, so the next iteration will see 'param2=2'.
|
||||
} else {
|
||||
seen.push(param);
|
||||
}
|
||||
}
|
||||
|
||||
assert_array_equals(seen[0], ["param2", "2"]);
|
||||
}, "delete current param during iteration");
|
||||
|
||||
test(function() {
|
||||
const url = new URL("http://localhost/query?param0=0¶m1=1¶m2=2");
|
||||
const searchParams = url.searchParams;
|
||||
const seen = [];
|
||||
for (const param of searchParams) {
|
||||
seen.push(param[0]);
|
||||
searchParams.delete(param[0]);
|
||||
}
|
||||
|
||||
assert_array_equals(seen, ["param0", "param2"], "param1 should not have been seen by the loop");
|
||||
assert_equals(String(searchParams), "param1=1", "param1 should remain");
|
||||
}, "delete every param seen during iteration");
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
|
||||
<div id=log></div>
|
||||
<script src="../url/urlsearchparams-get.any.js"></script>
|
|
@ -0,0 +1,21 @@
|
|||
test(function() {
|
||||
var params = new URLSearchParams('a=b&c=d');
|
||||
assert_equals(params.get('a'), 'b');
|
||||
assert_equals(params.get('c'), 'd');
|
||||
assert_equals(params.get('e'), null);
|
||||
params = new URLSearchParams('a=b&c=d&a=e');
|
||||
assert_equals(params.get('a'), 'b');
|
||||
params = new URLSearchParams('=b&c=d');
|
||||
assert_equals(params.get(''), 'b');
|
||||
params = new URLSearchParams('a=&c=d&a=e');
|
||||
assert_equals(params.get('a'), '');
|
||||
}, 'Get basics');
|
||||
|
||||
test(function() {
|
||||
var params = new URLSearchParams('first=second&third&&');
|
||||
assert_true(params != null, 'constructor returned non-null value.');
|
||||
assert_true(params.has('first'), 'Search params object has name "first"');
|
||||
assert_equals(params.get('first'), 'second', 'Search params object has name "first" with value "second"');
|
||||
assert_equals(params.get('third'), '', 'Search params object has name "third" with the empty value.');
|
||||
assert_equals(params.get('fourth'), null, 'Search params object has no "fourth" name and value.');
|
||||
}, 'More get() basics');
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
|
||||
<div id=log></div>
|
||||
<script src="../url/urlsearchparams-getall.any.js"></script>
|
|
@ -0,0 +1,25 @@
|
|||
test(function() {
|
||||
var params = new URLSearchParams('a=b&c=d');
|
||||
assert_array_equals(params.getAll('a'), ['b']);
|
||||
assert_array_equals(params.getAll('c'), ['d']);
|
||||
assert_array_equals(params.getAll('e'), []);
|
||||
params = new URLSearchParams('a=b&c=d&a=e');
|
||||
assert_array_equals(params.getAll('a'), ['b', 'e']);
|
||||
params = new URLSearchParams('=b&c=d');
|
||||
assert_array_equals(params.getAll(''), ['b']);
|
||||
params = new URLSearchParams('a=&c=d&a=e');
|
||||
assert_array_equals(params.getAll('a'), ['', 'e']);
|
||||
}, 'getAll() basics');
|
||||
|
||||
test(function() {
|
||||
var params = new URLSearchParams('a=1&a=2&a=3&a');
|
||||
assert_true(params.has('a'), 'Search params object has name "a"');
|
||||
var matches = params.getAll('a');
|
||||
assert_true(matches && matches.length == 4, 'Search params object has values for name "a"');
|
||||
assert_array_equals(matches, ['1', '2', '3', ''], 'Search params object has expected name "a" values');
|
||||
params.set('a', 'one');
|
||||
assert_equals(params.get('a'), 'one', 'Search params object has name "a" with value "one"');
|
||||
var matches = params.getAll('a');
|
||||
assert_true(matches && matches.length == 1, 'Search params object has values for name "a"');
|
||||
assert_array_equals(matches, ['one'], 'Search params object has expected name "a" values');
|
||||
}, 'getAll() multiples');
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
|
||||
<div id=log></div>
|
||||
<script src="../url/urlsearchparams-has.any.js"></script>
|
|
@ -0,0 +1,45 @@
|
|||
test(function() {
|
||||
var params = new URLSearchParams('a=b&c=d');
|
||||
assert_true(params.has('a'));
|
||||
assert_true(params.has('c'));
|
||||
assert_false(params.has('e'));
|
||||
params = new URLSearchParams('a=b&c=d&a=e');
|
||||
assert_true(params.has('a'));
|
||||
params = new URLSearchParams('=b&c=d');
|
||||
assert_true(params.has(''));
|
||||
params = new URLSearchParams('null=a');
|
||||
assert_true(params.has(null));
|
||||
}, 'Has basics');
|
||||
|
||||
test(function() {
|
||||
var params = new URLSearchParams('a=b&c=d&&');
|
||||
params.append('first', 1);
|
||||
params.append('first', 2);
|
||||
assert_true(params.has('a'), 'Search params object has name "a"');
|
||||
assert_true(params.has('c'), 'Search params object has name "c"');
|
||||
assert_true(params.has('first'), 'Search params object has name "first"');
|
||||
assert_false(params.has('d'), 'Search params object has no name "d"');
|
||||
params.delete('first');
|
||||
assert_false(params.has('first'), 'Search params object has no name "first"');
|
||||
}, 'has() following delete()');
|
||||
|
||||
test(() => {
|
||||
const params = new URLSearchParams("a=b&a=d&c&e&");
|
||||
assert_true(params.has('a', 'b'));
|
||||
assert_false(params.has('a', 'c'));
|
||||
assert_true(params.has('a', 'd'));
|
||||
assert_true(params.has('e', ''));
|
||||
params.append('first', null);
|
||||
assert_false(params.has('first', ''));
|
||||
assert_true(params.has('first', 'null'));
|
||||
params.delete('a', 'b');
|
||||
assert_true(params.has('a', 'd'));
|
||||
}, "Two-argument has()");
|
||||
|
||||
test(() => {
|
||||
const params = new URLSearchParams("a=b&a=d&c&e&");
|
||||
assert_true(params.has('a', 'b'));
|
||||
assert_false(params.has('a', 'c'));
|
||||
assert_true(params.has('a', 'd'));
|
||||
assert_true(params.has('a', undefined));
|
||||
}, "Two-argument has() respects undefined as second arg");
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
|
||||
<div id=log></div>
|
||||
<script src="../url/urlsearchparams-set.any.js"></script>
|
|
@ -0,0 +1,22 @@
|
|||
test(function() {
|
||||
var params = new URLSearchParams('a=b&c=d');
|
||||
params.set('a', 'B');
|
||||
assert_equals(params + '', 'a=B&c=d');
|
||||
params = new URLSearchParams('a=b&c=d&a=e');
|
||||
params.set('a', 'B');
|
||||
assert_equals(params + '', 'a=B&c=d')
|
||||
params.set('e', 'f');
|
||||
assert_equals(params + '', 'a=B&c=d&e=f')
|
||||
}, 'Set basics');
|
||||
|
||||
test(function() {
|
||||
var params = new URLSearchParams('a=1&a=2&a=3');
|
||||
assert_true(params.has('a'), 'Search params object has name "a"');
|
||||
assert_equals(params.get('a'), '1', 'Search params object has name "a" with value "1"');
|
||||
params.set('first', 4);
|
||||
assert_true(params.has('a'), 'Search params object has name "a"');
|
||||
assert_equals(params.get('a'), '1', 'Search params object has name "a" with value "1"');
|
||||
params.set('a', 4);
|
||||
assert_true(params.has('a'), 'Search params object has name "a"');
|
||||
assert_equals(params.get('a'), '4', 'Search params object has name "a" with value "4"');
|
||||
}, 'URLSearchParams.set');
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
|
||||
<div id=log></div>
|
||||
<script src="../url/urlsearchparams-sort.any.js"></script>
|
|
@ -0,0 +1,62 @@
|
|||
[
|
||||
{
|
||||
"input": "z=b&a=b&z=a&a=a",
|
||||
"output": [["a", "b"], ["a", "a"], ["z", "b"], ["z", "a"]]
|
||||
},
|
||||
{
|
||||
"input": "\uFFFD=x&\uFFFC&\uFFFD=a",
|
||||
"output": [["\uFFFC", ""], ["\uFFFD", "x"], ["\uFFFD", "a"]]
|
||||
},
|
||||
{
|
||||
"input": "ffi&🌈", // 🌈 > code point, but < code unit because two code units
|
||||
"output": [["🌈", ""], ["ffi", ""]]
|
||||
},
|
||||
{
|
||||
"input": "é&e\uFFFD&e\u0301",
|
||||
"output": [["e\u0301", ""], ["e\uFFFD", ""], ["é", ""]]
|
||||
},
|
||||
{
|
||||
"input": "z=z&a=a&z=y&a=b&z=x&a=c&z=w&a=d&z=v&a=e&z=u&a=f&z=t&a=g",
|
||||
"output": [["a", "a"], ["a", "b"], ["a", "c"], ["a", "d"], ["a", "e"], ["a", "f"], ["a", "g"], ["z", "z"], ["z", "y"], ["z", "x"], ["z", "w"], ["z", "v"], ["z", "u"], ["z", "t"]]
|
||||
},
|
||||
{
|
||||
"input": "bbb&bb&aaa&aa=x&aa=y",
|
||||
"output": [["aa", "x"], ["aa", "y"], ["aaa", ""], ["bb", ""], ["bbb", ""]]
|
||||
},
|
||||
{
|
||||
"input": "z=z&=f&=t&=x",
|
||||
"output": [["", "f"], ["", "t"], ["", "x"], ["z", "z"]]
|
||||
},
|
||||
{
|
||||
"input": "a🌈&a💩",
|
||||
"output": [["a🌈", ""], ["a💩", ""]]
|
||||
}
|
||||
].forEach((val) => {
|
||||
test(() => {
|
||||
let params = new URLSearchParams(val.input),
|
||||
i = 0
|
||||
params.sort()
|
||||
for(let param of params) {
|
||||
assert_array_equals(param, val.output[i])
|
||||
i++
|
||||
}
|
||||
}, "Parse and sort: " + val.input)
|
||||
|
||||
test(() => {
|
||||
let url = new URL("?" + val.input, "https://example/")
|
||||
url.searchParams.sort()
|
||||
let params = new URLSearchParams(url.search),
|
||||
i = 0
|
||||
for(let param of params) {
|
||||
assert_array_equals(param, val.output[i])
|
||||
i++
|
||||
}
|
||||
}, "URL parse and sort: " + val.input)
|
||||
})
|
||||
|
||||
test(function() {
|
||||
const url = new URL("http://example.com/?")
|
||||
url.searchParams.sort()
|
||||
assert_equals(url.href, "http://example.com/")
|
||||
assert_equals(url.search, "")
|
||||
}, "Sorting non-existent params removes ? from URL")
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../resources/testharness.js"></script>
|
||||
<script src="../resources/testharnessreport.js"></script>
|
||||
|
||||
<div id=log></div>
|
||||
<script src="../url/urlsearchparams-stringifier.any.js"></script>
|
|
@ -0,0 +1,145 @@
|
|||
test(function() {
|
||||
var params = new URLSearchParams();
|
||||
params.append('a', 'b c');
|
||||
assert_equals(params + '', 'a=b+c');
|
||||
params.delete('a');
|
||||
params.append('a b', 'c');
|
||||
assert_equals(params + '', 'a+b=c');
|
||||
}, 'Serialize space');
|
||||
|
||||
test(function() {
|
||||
var params = new URLSearchParams();
|
||||
params.append('a', '');
|
||||
assert_equals(params + '', 'a=');
|
||||
params.append('a', '');
|
||||
assert_equals(params + '', 'a=&a=');
|
||||
params.append('', 'b');
|
||||
assert_equals(params + '', 'a=&a=&=b');
|
||||
params.append('', '');
|
||||
assert_equals(params + '', 'a=&a=&=b&=');
|
||||
params.append('', '');
|
||||
assert_equals(params + '', 'a=&a=&=b&=&=');
|
||||
}, 'Serialize empty value');
|
||||
|
||||
test(function() {
|
||||
var params = new URLSearchParams();
|
||||
params.append('', 'b');
|
||||
assert_equals(params + '', '=b');
|
||||
params.append('', 'b');
|
||||
assert_equals(params + '', '=b&=b');
|
||||
}, 'Serialize empty name');
|
||||
|
||||
test(function() {
|
||||
var params = new URLSearchParams();
|
||||
params.append('', '');
|
||||
assert_equals(params + '', '=');
|
||||
params.append('', '');
|
||||
assert_equals(params + '', '=&=');
|
||||
}, 'Serialize empty name and value');
|
||||
|
||||
test(function() {
|
||||
var params = new URLSearchParams();
|
||||
params.append('a', 'b+c');
|
||||
assert_equals(params + '', 'a=b%2Bc');
|
||||
params.delete('a');
|
||||
params.append('a+b', 'c');
|
||||
assert_equals(params + '', 'a%2Bb=c');
|
||||
}, 'Serialize +');
|
||||
|
||||
test(function() {
|
||||
var params = new URLSearchParams();
|
||||
params.append('=', 'a');
|
||||
assert_equals(params + '', '%3D=a');
|
||||
params.append('b', '=');
|
||||
assert_equals(params + '', '%3D=a&b=%3D');
|
||||
}, 'Serialize =');
|
||||
|
||||
test(function() {
|
||||
var params = new URLSearchParams();
|
||||
params.append('&', 'a');
|
||||
assert_equals(params + '', '%26=a');
|
||||
params.append('b', '&');
|
||||
assert_equals(params + '', '%26=a&b=%26');
|
||||
}, 'Serialize &');
|
||||
|
||||
test(function() {
|
||||
var params = new URLSearchParams();
|
||||
params.append('a', '*-._');
|
||||
assert_equals(params + '', 'a=*-._');
|
||||
params.delete('a');
|
||||
params.append('*-._', 'c');
|
||||
assert_equals(params + '', '*-._=c');
|
||||
}, 'Serialize *-._');
|
||||
|
||||
test(function() {
|
||||
var params = new URLSearchParams();
|
||||
params.append('a', 'b%c');
|
||||
assert_equals(params + '', 'a=b%25c');
|
||||
params.delete('a');
|
||||
params.append('a%b', 'c');
|
||||
assert_equals(params + '', 'a%25b=c');
|
||||
|
||||
params = new URLSearchParams('id=0&value=%')
|
||||
assert_equals(params + '', 'id=0&value=%25')
|
||||
}, 'Serialize %');
|
||||
|
||||
test(function() {
|
||||
var params = new URLSearchParams();
|
||||
params.append('a', 'b\0c');
|
||||
assert_equals(params + '', 'a=b%00c');
|
||||
params.delete('a');
|
||||
params.append('a\0b', 'c');
|
||||
assert_equals(params + '', 'a%00b=c');
|
||||
}, 'Serialize \\0');
|
||||
|
||||
test(function() {
|
||||
var params = new URLSearchParams();
|
||||
params.append('a', 'b\uD83D\uDCA9c');
|
||||
assert_equals(params + '', 'a=b%F0%9F%92%A9c');
|
||||
params.delete('a');
|
||||
params.append('a\uD83D\uDCA9b', 'c');
|
||||
assert_equals(params + '', 'a%F0%9F%92%A9b=c');
|
||||
}, 'Serialize \uD83D\uDCA9'); // Unicode Character 'PILE OF POO' (U+1F4A9)
|
||||
|
||||
test(function() {
|
||||
var params;
|
||||
params = new URLSearchParams('a=b&c=d&&e&&');
|
||||
assert_equals(params.toString(), 'a=b&c=d&e=');
|
||||
params = new URLSearchParams('a = b &a=b&c=d%20');
|
||||
assert_equals(params.toString(), 'a+=+b+&a=b&c=d+');
|
||||
// The lone '=' _does_ survive the roundtrip.
|
||||
params = new URLSearchParams('a=&a=b');
|
||||
assert_equals(params.toString(), 'a=&a=b');
|
||||
|
||||
params = new URLSearchParams('b=%2sf%2a');
|
||||
assert_equals(params.toString(), 'b=%252sf*');
|
||||
|
||||
params = new URLSearchParams('b=%2%2af%2a');
|
||||
assert_equals(params.toString(), 'b=%252*f*');
|
||||
|
||||
params = new URLSearchParams('b=%%2a');
|
||||
assert_equals(params.toString(), 'b=%25*');
|
||||
}, 'URLSearchParams.toString');
|
||||
|
||||
test(() => {
|
||||
const url = new URL('http://www.example.com/?a=b,c');
|
||||
const params = url.searchParams;
|
||||
|
||||
assert_equals(url.toString(), 'http://www.example.com/?a=b,c');
|
||||
assert_equals(params.toString(), 'a=b%2Cc');
|
||||
|
||||
params.append('x', 'y');
|
||||
|
||||
assert_equals(url.toString(), 'http://www.example.com/?a=b%2Cc&x=y');
|
||||
assert_equals(params.toString(), 'a=b%2Cc&x=y');
|
||||
}, 'URLSearchParams connected to URL');
|
||||
|
||||
test(() => {
|
||||
const url = new URL('http://www.example.com/');
|
||||
const params = url.searchParams;
|
||||
|
||||
params.append('a\nb', 'c\rd');
|
||||
params.append('e\n\rf', 'g\r\nh');
|
||||
|
||||
assert_equals(params.toString(), "a%0Ab=c%0Dd&e%0A%0Df=g%0D%0Ah");
|
||||
}, 'URLSearchParams must not do newline normalization');
|
Loading…
Add table
Add a link
Reference in a new issue