Update web-platform-tests to revision d4391fedfec67d69f00396873a11f501a97ee3f1

This commit is contained in:
WPT Sync Bot 2020-03-09 08:20:19 +00:00
parent e1f6dfd716
commit 5119e2cbbd
140 changed files with 406 additions and 2522 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,4 +0,0 @@
[hit-test-floats-002.html]
[Hit test float]
expected: FAIL

View file

@ -1,4 +0,0 @@
[hit-test-floats-003.html]
[Miss float below something else]
expected: FAIL

View file

@ -1,4 +0,0 @@
[hit-test-floats-004.html]
[Miss float below something else]
expected: FAIL

View file

@ -2,3 +2,6 @@
[Hit test intersecting scaled box]
expected: FAIL
[Hit test within unscaled box]
expected: FAIL

View file

@ -2,3 +2,6 @@
[listeners are called when <iframe> is resized]
expected: FAIL
[listeners are called correct number of times]
expected: FAIL

View file

@ -2,3 +2,6 @@
[elementsFromPoint on the root document for points in iframe elements]
expected: FAIL
[elementsFromPoint on inner documents]
expected: FAIL

View file

@ -0,0 +1,4 @@
[elementsFromPoint-invalid-cases.html]
[The root element is the last element returned for otherwise empty queries within the viewport]
expected: FAIL

View file

@ -312,24 +312,12 @@
[fetch(): separate response Content-Type: text/plain ]
expected: NOTRUN
[<iframe>: combined response Content-Type: */* text/html]
expected: FAIL
[<iframe>: separate response Content-Type: text/html */*;charset=gbk]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;charset=gbk text/plain text/html]
expected: FAIL
[<iframe>: combined response Content-Type: text/html */*]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;" \\" text/plain]
[<iframe>: combined response Content-Type: text/html */*;charset=gbk]
expected: FAIL
[<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
expected: FAIL

View file

@ -56,6 +56,9 @@
[separate text/javascript x/x]
expected: FAIL
[separate text/javascript error]
[separate text/javascript;charset=windows-1252 error text/javascript]
expected: FAIL
[separate text/javascript;charset=windows-1252 text/javascript]
expected: FAIL

View file

@ -11,3 +11,6 @@
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
expected: FAIL
[X-Content-Type-Options%3A%20'NosniFF']
expected: FAIL

View file

@ -1,4 +1,4 @@
[traverse_the_history_5.html]
[traverse_the_history_2.html]
[Multiple history traversals, last would be aborted]
expected: FAIL

View file

@ -18,3 +18,6 @@
[Set HTTP URL frame location.protocol to ftp]
expected: FAIL
[Set data URL frame location.protocol to data]
expected: FAIL

View file

@ -13,8 +13,5 @@
expected: NOTRUN
[Host element with delegatesFocus should support autofocus]
expected: NOTRUN
[Non-HTMLElement should not support autofocus]
expected: TIMEOUT

View file

@ -1,5 +1,6 @@
[iframe_sandbox_popups_nonescaping-1.html]
type: testharness
expected: TIMEOUT
[Check that popups from a sandboxed iframe do not escape the sandbox]
expected: FAIL
expected: NOTRUN

View file

@ -44,3 +44,6 @@
[X Rendered audio for channel 5 does not equal [0,0.0626220703125,0.125030517578125,0.18695068359375,0.24810791015625,0.308319091796875,0.3673095703125,0.42486572265625,0.480743408203125,0.53472900390625,0.58660888671875,0.636199951171875,0.68328857421875,0.727691650390625,0.76922607421875,0.8077392578125...\] with an element-wise tolerance of {"absoluteThreshold":0.000030517578125,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[1\]\t3.6732959747314453e-1\t6.2622070312500000e-2\t3.0470752716064453e-1\t4.8658168859649127e+0\t3.0517578125000000e-5\n\t[2\]\t6.8329977989196777e-1\t1.2503051757812500e-1\t5.5826926231384277e-1\t4.4650639949963384e+0\t3.0517578125000000e-5\n\t[3\]\t9.0373212099075317e-1\t1.8695068359375000e-1\t7.1678143739700317e-1\t3.8340669508039502e+0\t3.0517578125000000e-5\n\t[4\]\t9.9780619144439697e-1\t2.4810791015625000e-1\t7.4969828128814697e-1\t3.0216621502152523e+0\t3.0517578125000000e-5\n\t[5\]\t9.5236867666244507e-1\t3.0831909179687500e-1\t6.4404958486557007e-1\t2.0889059484187866e+0\t3.0517578125000000e-5\n\t...and 42290 more errors.\n\tMax AbsError of 1.9986611604690552e+0 at index of 26105.\n\t[26105\]\t-9.9994289875030518e-1\t9.9871826171875000e-1\t1.9986611604690552e+0\t2.0012262087101997e+0\t3.0517578125000000e-5\n\tMax RelError of Infinity at index of 10584.\n\t[10584\]\t-5.8778524398803711e-1\t0.0000000000000000e+0\t5.8778524398803711e-1\tInfinity\t3.0517578125000000e-5\n]
expected: FAIL
[X Rendered audio for channel 5 does not equal [0,0.0626220703125,0.125030517578125,0.18695068359375,0.24810791015625,0.308319091796875,0.3673095703125,0.42486572265625,0.480743408203125,0.53472900390625,0.58660888671875,0.636199951171875,0.68328857421875,0.727691650390625,0.76922607421875,0.8077392578125...\] with an element-wise tolerance of {"absoluteThreshold":0.000030517578125,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[1\]\t3.6732959747314453e-1\t6.2622070312500000e-2\t3.0470752716064453e-1\t4.8658168859649127e+0\t3.0517578125000000e-5\n\t[2\]\t6.8329977989196777e-1\t1.2503051757812500e-1\t5.5826926231384277e-1\t4.4650639949963384e+0\t3.0517578125000000e-5\n\t[3\]\t9.0373212099075317e-1\t1.8695068359375000e-1\t7.1678143739700317e-1\t3.8340669508039502e+0\t3.0517578125000000e-5\n\t[4\]\t9.9780619144439697e-1\t2.4810791015625000e-1\t7.4969828128814697e-1\t3.0216621502152523e+0\t3.0517578125000000e-5\n\t[5\]\t9.5236867666244507e-1\t3.0831909179687500e-1\t6.4404958486557007e-1\t2.0889059484187866e+0\t3.0517578125000000e-5\n\t...and 44051 more errors.\n\tMax AbsError of 1.9986916780471802e+0 at index of 37840.\n\t[37840\]\t9.9994289875030518e-1\t-9.9874877929687500e-1\t1.9986916780471802e+0\t2.0011956154322119e+0\t3.0517578125000000e-5\n\tMax RelError of Infinity at index of 10584.\n\t[10584\]\t-5.8778524398803711e-1\t0.0000000000000000e+0\t5.8778524398803711e-1\tInfinity\t3.0517578125000000e-5\n]
expected: FAIL

View file

@ -197,3 +197,6 @@
[X SNR (45.01863889546195 dB) is not greater than or equal to 85.58. Got 45.01863889546195.]
expected: FAIL
[X Stitched sine-wave buffers at sample rate 44100 does not equal [0,0.06264832615852356,0.12505052983760834,0.18696144223213196,0.24813786149024963,0.308339387178421,0.36732959747314453,0.4248766601085663,0.480754554271698,0.5347436666488647,0.5866320133209229,0.6362156271934509,0.6832997798919678,0.7276994585990906,0.7692402601242065,0.8077589869499207...\] with an element-wise tolerance of {"absoluteThreshold":0.000090957,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[31080\]\t-7.7842698715429952e-27\t5.6332010030746460e-1\t5.6332010030746460e-1\t1.0000000000000000e+0\t9.0957000000000003e-5\n\t[31081\]\t4.5752394860205277e-41\t6.1397600173950195e-1\t6.1397600173950195e-1\t1.0000000000000000e+0\t9.0957000000000003e-5\n\tMax AbsError of 6.1397600173950195e-1 at index of 31081.\n\tMax RelError of 1.0000000000000000e+0 at index of 31080.\n]
expected: FAIL

View file

@ -1,5 +0,0 @@
[017.html]
expected: TIMEOUT
[origin of the script that invoked the method, about:blank]
expected: TIMEOUT

View file

@ -1,21 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test oversized-images policy with threshold 'inf'</title>
</head>
<body>
<!-- The sample image has an intrinsic image size of 200x200px -->
<img src="resources/sample-1.png" width="200" height="200">
<img src="resources/sample-1.png" width="100" height="200">
<img src="resources/sample-1.png" width="50" height="200">
<br>
<img src="resources/sample-1.png" width="200" height="100">
<img src="resources/sample-1.png" width="100" height="100">
<img src="resources/sample-1.png" width="50" height="100">
<br>
<img src="resources/sample-1.png" width="200" height="50">
<img src="resources/sample-1.png" width="100" height="50">
<img src="resources/sample-1.png" width="50" height="50">
</body>
</html>

View file

@ -1 +0,0 @@
Feature-Policy: oversized-images (inf)

View file

@ -1,44 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/feature-policy/resources/featurepolicy.js"></script>
<title>Test oversized-images policy with threshold 1.5</title>
</head>
<body>
<iframe scrolling="no" name="a" style="overflow:hidden" width="380" height="220"></iframe>
<iframe scrolling="no" name="b" style="overflow:hidden" width="380" height="220"></iframe>
<iframe scrolling="no" name="c" style="overflow:hidden" width="380" height="220"></iframe>
<iframe scrolling="no" name="d" style="overflow:hidden" width="380" height="220"></iframe>
<iframe scrolling="no" name="e" style="overflow:hidden" width="380" height="220"></iframe>
<script>
const frame_to_test_map = {};
window.addEventListener('message', ev => {
if (ev.data.type == "finished") {
if (frame_to_test_map.hasOwnProperty(ev.data.name)) {
frame_to_test_map[ev.data.name].done();
}
}
});
const config = {
a: {threshold: 0.0, blocked: 3},
b: {threshold: 1.0, blocked: 2},
c: {threshold: 2.5, blocked: 1},
d: {threshold: 4.0, blocked: 0},
e: {threshold: "inf", blocked: 0}
};
const iframes = document.querySelectorAll('iframe');
const total_iframes = iframes.length;
iframes.forEach(iframe => {
const frame_config = config[iframe.name]
async_test(t => {
frame_to_test_map[iframe.name] = t;
iframe.src = "resources/feature-parameters-frame.html?name="+iframe.name+"&n="+frame_config.blocked+"&pipe=header(Feature-Policy,oversized-images%20("+frame_config.threshold+"\\);)";
}, "Test frame with threshold " + frame_config.threshold + " should block " + frame_config.blocked + " images.");
});
</script>
</body>
</html>

View file

@ -1,28 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/feature-policy/resources/featurepolicy.js"></script>
<title>Test oversized-images policy with threshold 1.5</title>
</head>
<body>
<!-- The sample image has an intrinsic image size of 200x200px -->
<img src="resources/sample-1.png" width="200" height="200">
<img src="resources/sample-1.png" width="100" height="200">
<img src="resources/sample-1.png" width="50" height="200">
<br>
<img src="resources/sample-1.png" width="200" height="100">
<img src="resources/sample-1.png" width="100" height="100">
<img src="resources/sample-1.png" width="50" height="100">
<br>
<img src="resources/sample-1.png" width="200" height="50">
<img src="resources/sample-1.png" width="100" height="50">
<img src="resources/sample-1.png" width="50" height="50">
<script>
expect_reports(8, "oversized-images", "8 images should be blocked by policy");
</script>
</body>
</html>

View file

@ -1 +0,0 @@
Feature-Policy: oversized-images (1.5)

View file

@ -1,50 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/feature-policy/resources/featurepolicy.js"></script>
<title>Test oversized-images policy in subframe</title>
</head>
<body>
<!-- The sample image has an intrinsic image size of 200x200px -->
<img width="200" height="200">
<img width="100" height="200">
<img width="50" height="200">
<script>
const policy_name = "oversized-images";
const params = new URLSearchParams(document.location.search);
const frame_name = params.get('name');
const expected_report_count = +params.get('n');
var num_received_reports = 0;
const images = document.querySelectorAll('img');
const total_images = images.length;
var images_loaded = 0;
const notifyIfDone = () => {
if (num_received_reports >= expected_report_count &&
images_loaded == total_images) {
parent.postMessage({
"type": "finished",
"name": frame_name
},"*");
}
};
images.forEach(image => {
image.addEventListener('load', () => { images_loaded++; notifyIfDone(); });
image.src = "sample-1.png";
});
new ReportingObserver((reports, observer) => {
const relevant_reports = reports.filter(r => (r.body.featureId === policy_name));
num_received_reports += relevant_reports.length;
notifyIfDone();
}, {types: ['feature-policy-violation'], buffered: true}).observe();
</script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 428 B

View file

@ -34,4 +34,20 @@ promise_test(async t => {
worker.postMessage('WithoutCorp');
assert_equals((await p).data, 'TypeError: Failed to fetch');
}, "fetch() to no CORP response should not succeed.");
promise_test(async t => {
const scope = `${SCOPE}-2`;
await service_worker_unregister(t, scope);
const promise = navigator.serviceWorker.register(
'resources/require-corp-sw-import-scripts.js', {scope});
await promise_rejects_js(t, TypeError, promise, 'register() should fail.');
}, 'importScripts() fails for a script with no corp.');
promise_test(async t => {
const scope = `${SCOPE}-3`;
await service_worker_unregister(t, scope);
const registration = await navigator.serviceWorker.register(
'resources/require-corp-sw-import-scripts.js?corp=cross-origin', {scope});
t.add_cleanup(() => registration.unregister());
}, 'importScripts() succeeds for a script with corp: cross-origin.');
</script>

View file

@ -0,0 +1,23 @@
// Service worker with 'COEP: require-corp' response header.
// This service worker issues a network request to import scripts with or
// without CORP response header.
importScripts("/common/get-host-info.sub.js");
function url_for_empty_js(corp) {
const url = new URL(get_host_info().HTTPS_REMOTE_ORIGIN);
url.pathname = '/service-workers/service-worker/resources/empty.js';
if (corp) {
url.searchParams.set(
'pipe', `header(Cross-Origin-Resource-Policy, ${corp})`);
}
return url.href;
}
const params = new URL(location.href).searchParams;
if (params.get('corp') === 'cross-origin') {
importScripts(url_for_empty_js('cross-origin'));
} else {
importScripts(url_for_empty_js());
}

View file

@ -0,0 +1 @@
Cross-Origin-Embedder-Policy: require-corp

View file

@ -1,3 +0,0 @@
spec: https://wicg.github.io/kv-storage/
suggested_reviewers:
- domenic

View file

@ -1,33 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>KV Storage: backingStore getter</title>
<!-- See https://github.com/WICG/kv-storage/issues/45 -->
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script type="module">
import storage from "std:kv-storage";
test(() => {
assert_equals(storage.backingStore, storage.backingStore);
}, "backingStore must return the same object each time");
test(() => {
assert_true(Object.isFrozen(storage.backingStore));
}, "backingStore must be a frozen object");
test(() => {
const { backingStore } = storage;
assert_array_equals(Object.keys(backingStore), ["database", "store", "version"], "property names");
assert_array_equals(Object.getOwnPropertySymbols(backingStore), [], "no symbols")
assert_own_property(backingStore, "database");
assert_own_property(backingStore, "store");
assert_own_property(backingStore, "version");
assert_equals(Object.getPrototypeOf(backingStore), Object.prototype);
assert_equals(backingStore.database, "kv-storage:default");
assert_equals(backingStore.store, "store");
assert_equals(backingStore.version, 1);
}, "backingStore object must have the right shape");
</script>

View file

@ -1,116 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>KV Storage: causing errors by directly manipulating the IDB</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/IndexedDB/support-promises.js"></script>
<script type="module">
import { testWithArea, testWithAreaNoCleanup } from "./helpers/kvs-tests.js";
const mustFail = {
"set()": area => area.set(1, "value 1"),
"get()": area => area.get(1),
"delete()": area => area.delete(1),
"keys()": area => {
const iter = area.keys();
return iter.next();
},
"values()": area => {
const iter = area.values();
return iter.next();
},
"entries()": area => {
const iter = area.entries();
return iter.next();
}
};
for (const [method, testFn] of Object.entries(mustFail)) {
testWithArea(async (area, t) => {
const { database, version } = area.backingStore;
const db = await migrateNamedDatabase(t, database, version + 1, () => {});
const result = testFn(area);
await promise_rejects_dom(t, "VersionError", result);
}, `${method}: upgrading the database must cause a "VersionError" DOMException`);
testWithAreaNoCleanup(async (area, t) => {
const { database } = area.backingStore;
// Set up a new database with that name, but with no object stores!
// NB: this depends on the fact that createNameDatabase sets the initial version to 1, which is
// the same as the database version used/expected by KV Storage.
const db = await createNamedDatabase(t, database, () => {});
const result = testFn(area);
await promise_rejects_dom(t, "InvalidStateError", result);
}, `${method}: creating a same-named database with no object store must cause an "InvalidStateError" DOMException`);
testWithAreaNoCleanup(async (area, t) => {
const { database } = area.backingStore;
const db = await createNamedDatabase(t, database, db => {
db.createObjectStore("wrongName");
});
const result = testFn(area);
await promise_rejects_dom(t, "InvalidStateError", result);
}, `${method}: creating a same-named database with a single object store with the wrong name must cause an "InvalidStateError" DOMException`);
testWithAreaNoCleanup(async (area, t) => {
const { database, store } = area.backingStore;
const db = await createNamedDatabase(t, database, db => {
db.createObjectStore(store);
db.createObjectStore("wrongName");
});
const result = testFn(area);
await promise_rejects_dom(t, "InvalidStateError", result);
}, `${method}: creating a same-named database with more than one object store must cause an "InvalidStateError" DOMException`);
testWithAreaNoCleanup(async (area, t) => {
const { database, store } = area.backingStore;
const db = await createNamedDatabase(t, database, db => {
db.createObjectStore(store, { autoIncrement: true });
});
const result = testFn(area);
await promise_rejects_dom(t, "InvalidStateError", result);
}, `${method}: creating a same-named database the right object store but a bad schema (autoIncrement = true) must cause an "InvalidStateError" DOMException`);
testWithAreaNoCleanup(async (area, t) => {
const { database, store } = area.backingStore;
const db = await createNamedDatabase(t, database, db => {
db.createObjectStore(store, { keyPath: "somekey" });
});
const result = testFn(area);
await promise_rejects_dom(t, "InvalidStateError", result);
}, `${method}: creating a same-named database the right object store but a bad schema (keyPath != null) must cause an "InvalidStateError" DOMException`);
testWithAreaNoCleanup(async (area, t) => {
const { database, store } = area.backingStore;
const db = await createNamedDatabase(t, database, db => {
const s = db.createObjectStore(store);
s.createIndex("index", "indexKey");
});
const result = testFn(area);
await promise_rejects_dom(t, "InvalidStateError", result);
}, `${method}: creating a same-named database the right object store but a bad schema (has indices) must cause an "InvalidStateError" DOMException`);
}
</script>

View file

@ -1,291 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>KV Storage: entries() trickier tests</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script type="module">
import { testWithArea } from "./helpers/kvs-tests.js";
import * as iterAssert from "./helpers/iter-assert.js";
import {
assertAsyncIteratorEquals,
assertAsyncIteratorCustomEquals,
assertArrayCustomEquals,
assertEqualPostKeyRoundtripping
} from "./helpers/equality-asserters.js";
function assertEqualsArrayOrUndefined(actual, expected, label) {
if (expected === undefined) {
return assert_equals(actual, expected, label);
}
return assert_array_equals(actual, expected, label);
}
testWithArea(async area => {
await area.set(1, "value 1");
await area.set(2, "value 2");
await area.set(3, "value 3");
await assertAsyncIteratorCustomEquals(
area.entries(),
[[1, "value 1"], [2, "value 2"], [3, "value 3"]],
assert_array_equals
);
}, "Using for-await-of to collect the results works");
testWithArea(async area => {
// We're not testing every key type since this isn't a test of IndexedDB.
await area.set(1, "value 1");
await area.set(new Date(500), "value date 500");
await area.set(-1, "value -1");
await area.set(new Date(-20), "value date -20");
await area.set("aaa", "value aaa");
await area.set("a", "value a");
await area.set(-Infinity, "value -Infinity");
await assertAsyncIteratorCustomEquals(
area.entries(),
[
[-Infinity, "value -Infinity"],
[-1, "value -1"],
[1, "value 1"],
[new Date(-20), "value date -20"],
[new Date(500), "value date 500"],
["a", "value a"],
["aaa", "value aaa"]
],
(actual, expected, label) => {
return assertArrayCustomEquals(actual, expected, assertEqualPostKeyRoundtripping, label);
}
);
}, "Results are returned in IndexedDB order");
testWithArea(async area => {
await area.set(1, "value 1");
await area.set(2, "value 2");
await area.set(3, "value 3");
const iter = area.entries();
const iterResults = [
await iter.next(),
await iter.next(),
await iter.next(),
await iter.next(),
await iter.next(),
await iter.next()
];
iterAssert.iterResultsCustom(
iterResults,
[
[[1, "value 1"], false],
[[2, "value 2"], false],
[[3, "value 3"], false],
[undefined, true],
[undefined, true],
[undefined, true]
],
assertEqualsArrayOrUndefined
);
}, "Manual testing of .next() calls, with awaiting");
testWithArea(async area => {
area.set(1, "value 1");
area.set(2, "value 2");
area.set(3, "value 3");
const iter = area.entries();
const promises = [
iter.next(),
iter.next(),
iter.next(),
iter.next(),
iter.next(),
iter.next()
];
const iterResults = await Promise.all(promises);
iterAssert.iterResultsCustom(
iterResults,
[
[[1, "value 1"], false],
[[2, "value 2"], false],
[[3, "value 3"], false],
[undefined, true],
[undefined, true],
[undefined, true]
],
assertEqualsArrayOrUndefined
);
}, "Manual testing of .next() calls, no awaiting");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const entry of area.entries()) {
seen.push(entry);
if (entry[0] === 20) {
await area.set(15, "value 15");
}
}
assertArrayCustomEquals(
seen,
[[10, "value 10"], [20, "value 20"], [30, "value 30"], [40, "value 40"]],
assert_array_equals
);
}, "Inserting an entry before the current entry must have no effect on iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const entry of area.entries()) {
seen.push(entry);
if (entry[0] === 20) {
await area.set(25, "value 25");
}
}
assertArrayCustomEquals(
seen,
[[10, "value 10"], [20, "value 20"], [25, "value 25"], [30, "value 30"], [40, "value 40"]],
assert_array_equals
);
}, "Inserting an entry after the current entry must show up in iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const entry of area.entries()) {
seen.push(entry);
if (entry[0] === 20) {
await area.delete(10);
}
}
assertArrayCustomEquals(
seen,
[[10, "value 10"], [20, "value 20"], [30, "value 30"], [40, "value 40"]],
assert_array_equals
);
}, "Deleting an entry before the current entry must have no effect on iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const entry of area.entries()) {
seen.push(entry);
if (entry[0] === 20) {
await area.delete(20);
}
}
assertArrayCustomEquals(
seen,
[[10, "value 10"], [20, "value 20"], [30, "value 30"], [40, "value 40"]],
assert_array_equals
);
}, "Deleting the current entry must have no effect on iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const entry of area.entries()) {
seen.push(entry);
if (entry[0] === 20) {
await area.delete(30);
}
}
assertArrayCustomEquals(
seen,
[[10, "value 10"], [20, "value 20"], [40, "value 40"]],
assert_array_equals
);
}, "Deleting an entry after the current entry must show up in iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const entry of area.entries()) {
seen.push(entry);
if (entry[0] === 20) {
await area.set(10, "value 10, but changed!!");
}
}
assertArrayCustomEquals(
seen,
[[10, "value 10"], [20, "value 20"], [30, "value 30"], [40, "value 40"]],
assert_array_equals
);
}, "Modifying a value before the current entry must have no effect on iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const entry of area.entries()) {
seen.push(entry);
if (entry[0] === 20) {
await area.set(20, "value 20, but changed!!");
}
}
assertArrayCustomEquals(
seen,
[[10, "value 10"], [20, "value 20"], [30, "value 30"], [40, "value 40"]],
assert_array_equals
);
}, "Modifying a value at the current entry must have no effect on iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const entry of area.entries()) {
seen.push(entry);
if (entry[0] === 20) {
await area.set(30, "value 30, but changed!!");
}
}
assertArrayCustomEquals(
seen,
[[10, "value 10"], [20, "value 20"], [30, "value 30, but changed!!"], [40, "value 40"]],
assert_array_equals
);
}, "Modifying a value after the current entry must show up in iteration");
</script>

View file

@ -1,91 +0,0 @@
export function assertEqualDates(actual, expected, label) {
label = formatLabel(label);
assert_equals(expected.constructor, Date,
`${label}assertEqualDates usage check: expected must be a Date`);
assert_equals(actual.constructor, Date, `${label}must be a Date`);
assert_equals(actual.valueOf(), expected.valueOf(), `${label}timestamps must match`);
}
export function assertEqualPostKeyRoundtripping(actual, expected, label) {
label = formatLabel(label);
// Please extend this to support other types as needed!
assert_true(
typeof expected === "number" || typeof expected === "string" || expected.constructor === Date,
`${label}assertEqualPostKeyRoundtripping usage check: currently only supports numbers, strings, and dates`
);
if (expected.constructor === Date) {
assert_equals(actual.constructor, Date, `${label}comparing to Date(${Number(expected)}) (actual = ${actual})`);
actual = Number(actual);
expected = Number(expected);
}
assert_equals(actual, expected, label);
}
export function assertEqualArrayBuffers(actual, expected, label) {
label = formatLabel(label);
assert_equals(expected.constructor, ArrayBuffer,
`${label}assertEqualArrayBuffers usage check: expected must be an ArrayBuffer`);
assert_equals(actual.constructor, ArrayBuffer, `${label}must be an ArrayBuffer`);
assert_array_equals(new Uint8Array(actual), new Uint8Array(expected), `${label}must match`);
}
export function assertArrayBufferEqualsABView(actual, expected, label) {
label = formatLabel(label);
assert_true(ArrayBuffer.isView(expected),
`${label}assertArrayBufferEqualsABView usage check: expected must be an ArrayBuffer view`);
assertEqualArrayBuffers(actual, expected.buffer, label);
}
export function assertAsyncIteratorEquals(actual, expected, label) {
return assertAsyncIteratorCustomEquals(actual, expected, Object.is, label);
}
export function assertArrayCustomEquals(actual, expected, equalityAsserter, label) {
label = formatLabel(label);
assert_true(Array.isArray(expected),
`${label} assertArrayCustomEquals usage check: expected must be an Array`);
assert_true(Array.isArray(actual), `${label}must be an array`);
assert_equals(actual.length, expected.length, `${label}length must be as expected`);
for (let i = 0; i < actual.length; ++i) {
equalityAsserter(actual[i], expected[i], `${label}index ${i}`);
}
}
export async function assertAsyncIteratorCustomEquals(actual, expected, equalityAsserter, label) {
label = formatLabel(label);
assert_true(Array.isArray(expected),
`${label} assertAsyncIteratorCustomEquals usage check: expected must be an Array`);
const collected = await collectAsyncIterator(actual);
assert_equals(collected.length, expected.length, `${label}length must be as expected`);
for (let i = 0; i < collected.length; ++i) {
equalityAsserter(collected[i], expected[i], `${label}index ${i}`);
}
}
async function collectAsyncIterator(asyncIterator) {
const array = [];
for await (const entry of asyncIterator) {
array.push(entry);
}
return array;
}
function formatLabel(label) {
return label !== undefined ? `${label} ` : "";
}

View file

@ -1,8 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Helper file to be loaded in an iframe that exposes a copy of StorageArea as a global</title>
<script type="module">
import { StorageArea } from "std:kv-storage";
window.StorageArea = StorageArea;
</script>

View file

@ -1,42 +0,0 @@
export function iterResultCustom(o, expectedValue, expectedDone, valueAsserter, label) {
label = formatLabel(label);
assert_equals(typeof expectedDone, "boolean",
`${label} iterResult assert usage check: expectedDone must be a boolean`);
propertyKeys(o, ["value", "done"], [], label);
assert_equals(Object.getPrototypeOf(o), Object.prototype, `${label}prototype must be Object.prototype`);
valueAsserter(o.value, expectedValue, `${label}value`);
assert_equals(o.done, expectedDone, `${label}done`);
}
export function iterResult(o, expectedValue, expectedDone, label) {
return iterResultCustom(o, expectedValue, expectedDone, assert_equals, label);
}
export function iterResultsCustom(actualArray, expectedArrayOfArrays, valueAsserter, label) {
label = formatLabel(label);
assert_equals(actualArray.length, expectedArrayOfArrays.length,
`${label} iterResults assert usage check: actual and expected must have the same length`);
for (let i = 0; i < actualArray.length; ++i) {
const [expectedValue, expectedDone] = expectedArrayOfArrays[i];
iterResultCustom(actualArray[i], expectedValue, expectedDone, valueAsserter, `${label}iter result ${i}`);
}
}
export function iterResults(actualArray, expectedArrayOfArrays, label) {
return iterResultsCustom(actualArray, expectedArrayOfArrays, assert_equals, label);
}
function propertyKeys(o, expectedNames, expectedSymbols, label) {
label = formatLabel(label);
assert_array_equals(Object.getOwnPropertyNames(o), expectedNames, `${label}property names`);
assert_array_equals(Object.getOwnPropertySymbols(o), expectedSymbols,
`${label}property symbols`);
}
function formatLabel(label) {
return label !== undefined ? `${label} ` : "";
}

View file

@ -1,82 +0,0 @@
import defaultArea, { StorageArea } from "std:kv-storage";
import { assertAsyncIteratorEquals, assertAsyncIteratorCustomEquals } from "./equality-asserters.js";
// Used when we're manually creating the database, and so the IDB helpers also want to clean it up.
// If we used testWithArea, then the IDB helpers would time out in their cleanup steps when they
// fail to delete the already-deleted database.
export function testWithAreaNoCleanup(testFn, description) {
promise_test(t => {
const area = new StorageArea(description);
return testFn(area, t);
}, description);
}
export function testWithArea(testFn, description) {
promise_test(t => {
const area = new StorageArea(description);
t.add_cleanup(t => area.clear());
return testFn(area, t);
}, description);
}
export function testWithDefaultArea(testFn, description) {
promise_test(t => {
t.add_cleanup(t => defaultArea.clear());
return testFn(defaultArea, t);
}, description);
}
// These two functions take a key/value and use them to test
// set()/get()/delete()/keys()/values()/entries(). The keyEqualityAsserter should be a
// function from ./equality-asserters.js.
export function testVariousMethodsWithDefaultArea(label, key, value, keyEqualityAsserter) {
testWithDefaultArea(testVariousMethodsInner(key, value, keyEqualityAsserter), label);
}
export function testVariousMethods(label, key, value, keyEqualityAsserter) {
testWithArea(testVariousMethodsInner(key, value, keyEqualityAsserter), label);
}
function testVariousMethodsInner(key, value, keyEqualityAsserter) {
return async area => {
await assertPromiseEquals(area.set(key, value), undefined, "set()", "undefined");
await assertPromiseEquals(area.get(key), value, "get()", "the set value");
const keysIter = area.keys();
await assertAsyncIteratorCustomEquals(keysIter, [key], keyEqualityAsserter, "keys() must have the key");
const valuesIter = area.values();
await assertAsyncIteratorEquals(valuesIter, [value], "values() must have the value");
const entriesIter = area.entries();
const entry0 = await entriesIter.next();
assert_false(entry0.done, "entries() 0th iter-result must not be done");
assert_true(Array.isArray(entry0.value), "entries() 0th iter-result value must be an array");
assert_equals(entry0.value.length, 2, "entries() 0th iter-result value must have 2 elements");
keyEqualityAsserter(entry0.value[0], key, "entries() 0th iter-result value's 0th element must be the key");
assert_equals(entry0.value[1], value, "entries() 0th iter-result value's 1st element must be the value");
const entry1 = await entriesIter.next();
assert_true(entry1.done, "entries() 1st iter-result must be done");
assert_equals(entry1.value, undefined, "entries() 1st iter-result must have undefined value");
await assertPromiseEquals(area.delete(key), undefined, "delete()", "undefined");
await assertPromiseEquals(area.get(key), undefined, "get()", "undefined after deleting");
};
}
async function assertPromiseEquals(promise, expected, label, expectedLabel) {
assertIsPromise(promise, label);
assert_equals(await promise, expected, label + " must fulfill with " + expectedLabel);
}
function assertIsPromise(promise, label) {
assert_equals(promise.constructor, Promise, label + " must return a promise");
}

View file

@ -1,176 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>KV Storage: IDL interface tests</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/WebIDLParser.js"></script>
<script src="/resources/idlharness.js"></script>
<script type="module">
import storage, { StorageArea } from "std:kv-storage";
// Web IDL/idlharness.js do not yet have support for the spec's IDL, which uses module {},
// async_iterator, and some new extended attributes. This IDL is a mutated version to work with the
// current idlharness.js to get some coverage.
//
// When the relevant Web IDL PRs land and idlharness.js gets updated, we can replace this file with
// a normal-style idlharness test, with the IDL scraped from the spec.
//
// Other tests in this file are similarly ones that should be generatable from the IDL, in theory.
const idl = `
[Constructor(DOMString name)]
interface StorageArea {
Promise<void> set(any key, any value);
Promise<any> get(any key);
Promise<void> delete(any key);
Promise<void> clear();
// async_iterable<any, any>;
[SameObject] readonly attribute object backingStore;
};
`;
// Define a global property because idlharness.js only understands
// global properties, not modules.
Object.defineProperty(window, "StorageArea", {
configurable: true,
enumerable: false,
writable: true,
value: StorageArea
});
test(t => {
window.testStorageArea = storage;
t.add_cleanup(() => {
delete window.testStorageArea;
});
const idlArray = new IdlArray();
idlArray.add_idls(idl);
idlArray.add_objects({ StorageArea: ["window.testStorageArea"] });
idlArray.test();
}, "idlharness basic interface tests");
test(() => {
assert_equals(storage instanceof StorageArea, true, "instanceof");
assert_equals(storage.constructor, StorageArea, ".constructor property");
assert_equals(Object.getPrototypeOf(storage), StorageArea.prototype, "[[Prototype]]");
}, "Built-in storage export is a StorageArea");
// These should be auto-tested by idlharness eventually, similar to
// https://github.com/web-platform-tests/wpt/blob/3725067ef0328c998be2ba93dbaeb0579586fccd/resources/idlharness.js#L2452
// for sync iterators (although this tests more than that does).
test(() => {
for (const methodName of ["keys", "values", "entries"]) {
const descriptor = Object.getOwnPropertyDescriptor(StorageArea.prototype, methodName);
assert_true(descriptor.writable, `${methodName} property should be writable`);
assert_true(descriptor.configurable, `${methodName} property should be configurable`);
// May need updating if https://github.com/heycam/webidl/issues/738 changes the spec
assert_true(descriptor.enumerable, `${methodName} property should be enumerable`);
assert_equals(typeof descriptor.value, "function",
`${methodName} property should be a function`);
assert_equals(descriptor.value.length, 0, `${methodName} function object length should be 0`);
assert_equals(descriptor.value.name, methodName,
`${methodName} function object should have the right name`);
assert_throws_js(TypeError, () => descriptor.value.call(StorageArea.prototype),
`${methodName} should throw when called on the prototype directly`);
assert_throws_js(TypeError, () => descriptor.value.call({}),
`${methodName} should throw when called on an empty object`);
}
const AsyncIteratorPrototype =
Object.getPrototypeOf(Object.getPrototypeOf(async function*() {}).prototype);
const asyncIteratorProto = Object.getPrototypeOf(storage.keys());
assert_equals(Object.getPrototypeOf(storage.values()), asyncIteratorProto,
"keys() and values() return values must have the same prototype");
assert_equals(Object.getPrototypeOf(storage.entries()), asyncIteratorProto,
"keys() and entries() return values must have the same prototype");
assert_equals(Object.getPrototypeOf(asyncIteratorProto), AsyncIteratorPrototype,
"[[Prototype]] must be the async iterator prototype");
assert_array_equals(Object.getOwnPropertyNames(asyncIteratorProto), ["next"],
`async iterator prototype object must have a next method`);
const nextMethodDescriptor = Object.getOwnPropertyDescriptor(asyncIteratorProto, "next");
assert_true(nextMethodDescriptor.writable, `async iterator next property should be writable`);
assert_true(nextMethodDescriptor.configurable,
`async iterator next property should be configurable`);
// May need updating if https://github.com/heycam/webidl/issues/739 changes the spec
assert_true(nextMethodDescriptor.enumerable,
`async iterator next property should be enumerable`);
assert_equals(typeof nextMethodDescriptor.value, "function",
`async iterator next property should be a function`);
assert_equals(nextMethodDescriptor.value.length, 0,
`async iterator next function object length should be 0`);
assert_equals(nextMethodDescriptor.value.name, "next",
`async iterator next function object should have the right name`);
assert_array_equals(Object.getOwnPropertySymbols(asyncIteratorProto), [Symbol.toStringTag]);
const toStringTagDescriptor = Object.getOwnPropertyDescriptor(
asyncIteratorProto,
Symbol.toStringTag
);
assert_false(toStringTagDescriptor.writable,
`async iterator @@toStringTag property should be non-writable`);
assert_true(toStringTagDescriptor.configurable,
`async iterator @@toStringTag property should be configurable`);
assert_false(toStringTagDescriptor.enumerable,
`async iterator @@toStringTag property should be non-enumerable`);
assert_equals(toStringTagDescriptor.value, "StorageArea AsyncIterator",
`async iterator @@toStringTag property should have the right value`);
assert_equals(StorageArea.prototype[Symbol.asyncIterator], StorageArea.prototype.entries,
"@@asyncIterator method should be the same as entries");
}, "@@asyncIterator tests");
promise_test(async t => {
const iframe = document.createElement("iframe");
iframe.src = "helpers/expose-as-global.html";
document.body.append(iframe);
await frameLoadPromise(iframe);
const OtherStorageArea = iframe.contentWindow.StorageArea;
const TypeError = iframe.contentWindow.TypeError;
await promise_rejects_js(t, TypeError,
OtherStorageArea.prototype.set.call(storage, "testkey", "testvalue"),
`set() must reject cross-realm`);
await promise_rejects_js(t, TypeError,
OtherStorageArea.prototype.get.call(storage, "testkey"),
`get() must reject cross-realm`);
await promise_rejects_js(t, TypeError,
OtherStorageArea.prototype.delete.call(storage, "testkey"),
`delete() must reject cross-realm`);
await promise_rejects_js(t, TypeError, OtherStorageArea.prototype.clear.call(storage),
`clear() must reject cross-realm`);
assert_throws_js(TypeError, () => OtherStorageArea.prototype.keys.call(storage),
`keys() must throw cross-realm`);
assert_throws_js(TypeError, () => OtherStorageArea.prototype.values.call(storage),
`values() must throw cross-realm`);
assert_throws_js(TypeError, () => OtherStorageArea.prototype.entries.call(storage),
`entries() must throw cross-realm`);
const otherBackingStoreGetter =
Object.getOwnPropertyDescriptor(OtherStorageArea.prototype, "backingStore").get;
assert_throws_js(TypeError, () => otherBackingStoreGetter.call(storage),
`backingStore must throw cross-realm`);
}, "Same-realm brand checks");
function frameLoadPromise(frame) {
return new Promise((resolve, reject) => {
frame.onload = resolve;
frame.onerror = () => reject(new Error(`${frame.src} failed to load`));
});
}
</script>

View file

@ -1,67 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>KV Storage: tests against various key types</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script type="module">
import { testWithArea, testVariousMethods } from "./helpers/kvs-tests.js";
import { assertEqualDates, assertEqualArrayBuffers, assertArrayBufferEqualsABView }
from "./helpers/equality-asserters.js";
const invalidKeys = {
"undefined": undefined,
"null": null,
"a boolean": true,
"a symbol": Symbol("a symbol"),
"an object": { an: "object" },
"a function": () => {},
"a regexp": /foo/,
"a Map": new Map(),
"a Set": new Set(),
"an IDBKeyRange": IDBKeyRange.only(5)
};
const validKeys = {
"a number": [5, assert_equals],
"a string": ["a string", assert_equals],
"a Date": [new Date(), assertEqualDates],
"a typed array": [new Uint8Array([1, 2]), assertArrayBufferEqualsABView],
"a DataView": [new DataView(new Uint8Array([3, 4]).buffer), assertArrayBufferEqualsABView],
"an ArrayBuffer": [new Uint8Array([5, 6]).buffer, assertEqualArrayBuffers]
};
const methods = ["delete", "get", "set"];
for (const method of methods) {
testWithArea(async (area, t) => {
for (const [description, key] of Object.entries(invalidKeys)) {
await promise_rejects_dom(t, "DataError", area[method](key), description);
}
}, `${method}: invalid keys`);
testWithArea(async (area, t) => {
for (const [description, key] of Object.entries(invalidKeys)) {
await promise_rejects_dom(t, "DataError", area[method]([key]), description);
}
}, `${method}: invalid keys, nested in arrays`);
testWithArea(async (area, t) => {
for (const [key] of Object.values(validKeys)) {
await area[method](key);
}
}, `${method}: valid keys`);
testWithArea(async (area, t) => {
for (const [key] of Object.values(validKeys)) {
await area[method]([key]);
}
}, `${method}: valid keys, nested in arrays`);
}
for (const [description, [key, equalityAsserter]] of Object.entries(validKeys)) {
testVariousMethods(`Storage methods smoke test: ${description} key`, key, 5, equalityAsserter);
}
</script>

View file

@ -1,78 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>KV Storage: keys()/values()/entries()</title>
<meta name="timeout" content="long">
<!--
This file contains tests that are easy to generalize over all three methods.
See sibling files for more complicated tests which are not worth generalizing.
-->
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/IndexedDB/support-promises.js"></script>
<script type="module">
import { testWithArea } from "./helpers/kvs-tests.js";
import * as iterAssert from "./helpers/iter-assert.js";
import { assertAsyncIteratorEquals } from "./helpers/equality-asserters.js";
// Also uses some global functions included via support-promises.js.
for (const method of ["keys", "values", "entries"]) {
testWithArea(async area => {
const iter = area[method]();
const promise = iter.next();
await area.set(1, "value 1");
const iterResults = [
await promise,
await iter.next()
];
iterAssert.iterResults(iterResults, [
[undefined, true],
[undefined, true]
]);
}, `${method}(): .next() on empty means forever done, even if you set more`);
testWithArea(async area => {
for await (const key of area[method]()) {
assert_unreached("Loop body must not be entered");
}
}, `${method}(): for-await-of loop body never executes`);
testWithArea(async (area, t) => {
await area.set(1, "value 1");
const iter = area[method]();
const { database, store, version } = area.backingStore;
await migrateNamedDatabase(t, database, version + 1, () => {});
const iterResultPromise1 = iter.next();
const iterResultPromise2 = iter.next();
await promise_rejects_dom(t, "VersionError", iterResultPromise1, "first next()");
await promise_rejects_dom(t, "VersionError", iterResultPromise2, "second next()");
const iterResultPromise3 = iter.next();
assert_not_equals(iterResultPromise1, iterResultPromise2,
"Two promises retrieved from synchronous next() calls must be different (1 vs 2)");
assert_not_equals(iterResultPromise1, iterResultPromise3,
"Two promises, one retrieved after waiting for the other, must be different (1 vs 3)");
assert_not_equals(iterResultPromise2, iterResultPromise3,
"Two promises, one retrieved after waiting for the other, must be different (2 vs 3)");
await promise_rejects_dom(t, "VersionError", iterResultPromise2, "third next()");
const reason1 = await iterResultPromise1.catch(r => r);
const reason2 = await iterResultPromise2.catch(r => r);
const reason3 = await iterResultPromise3.catch(r => r);
assert_equals(reason1, reason2, "reasons must be the same (1 vs 2)");
assert_equals(reason2, reason3, "reasons must be the same (2 vs 3)");
}, `${method}(): error path: returns new rejected promises, each with the same reason`);
}
</script>

View file

@ -1,237 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>KV Storage: keys() trickier tests</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script type="module">
import { testWithArea } from "./helpers/kvs-tests.js";
import * as iterAssert from "./helpers/iter-assert.js";
import {
assertAsyncIteratorEquals,
assertAsyncIteratorCustomEquals,
assertEqualPostKeyRoundtripping
} from "./helpers/equality-asserters.js";
testWithArea(async area => {
await area.set(1, "value 1");
await area.set(2, "value 2");
await area.set(3, "value 3");
await assertAsyncIteratorEquals(area.keys(), [1, 2, 3]);
}, "Using for-await-of to collect the results works");
testWithArea(async area => {
// We're not testing every key type since this isn't a test of IndexedDB.
await area.set(1, "value 1");
await area.set(new Date(500), "value date 500");
await area.set(-1, "value -1");
await area.set(new Date(-20), "value date -20");
await area.set("aaa", "value aaa");
await area.set("a", "value a");
await area.set(-Infinity, "value -Infinity");
await assertAsyncIteratorCustomEquals(
area.keys(),
[
-Infinity,
-1,
1,
new Date(-20),
new Date(500),
"a",
"aaa"
],
assertEqualPostKeyRoundtripping
);
}, "Results are returned in IndexedDB order");
testWithArea(async area => {
await area.set(1, "value 1");
await area.set(2, "value 2");
await area.set(3, "value 3");
const iter = area.keys();
const iterResults = [
await iter.next(),
await iter.next(),
await iter.next(),
await iter.next(),
await iter.next(),
await iter.next()
];
iterAssert.iterResults(iterResults, [
[1, false],
[2, false],
[3, false],
[undefined, true],
[undefined, true],
[undefined, true]
]);
}, "Manual testing of .next() calls, with awaiting");
testWithArea(async area => {
area.set(1, "value 1");
area.set(2, "value 2");
area.set(3, "value 3");
const iter = area.keys();
const promises = [
iter.next(),
iter.next(),
iter.next(),
iter.next(),
iter.next(),
iter.next()
];
const iterResults = await Promise.all(promises);
iterAssert.iterResults(iterResults, [
[1, false],
[2, false],
[3, false],
[undefined, true],
[undefined, true],
[undefined, true]
]);
}, "Manual testing of .next() calls, no awaiting");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const key of area.keys()) {
seen.push(key);
if (key === 20) {
await area.set(15, "value 15");
}
}
assert_array_equals(seen, [10, 20, 30, 40]);
}, "Inserting an entry before the current entry must have no effect on iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const key of area.keys()) {
seen.push(key);
if (key === 20) {
await area.set(25, "value 25");
}
}
assert_array_equals(seen, [10, 20, 25, 30, 40]);
}, "Inserting an entry after the current entry must show up in iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const key of area.keys()) {
seen.push(key);
if (key === 20) {
await area.delete(10);
}
}
assert_array_equals(seen, [10, 20, 30, 40]);
}, "Deleting an entry before the current entry must have no effect on iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const key of area.keys()) {
seen.push(key);
if (key === 20) {
await area.delete(20);
}
}
assert_array_equals(seen, [10, 20, 30, 40]);
}, "Deleting the current entry must have no effect on iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const key of area.keys()) {
seen.push(key);
if (key === 20) {
await area.delete(30);
}
}
assert_array_equals(seen, [10, 20, 40]);
}, "Deleting an entry after the current entry must show up in iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const key of area.keys()) {
seen.push(key);
if (key === 20) {
await area.set(10, "value 10, but changed!!");
}
}
assert_array_equals(seen, [10, 20, 30, 40]);
}, "Modifying a value before the current entry must have no effect on iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const key of area.keys()) {
seen.push(key);
if (key === 20) {
await area.set(20, "value 20, but changed!!");
}
}
assert_array_equals(seen, [10, 20, 30, 40]);
}, "Modifying a value at the current entry must have no effect on iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const key of area.keys()) {
seen.push(key);
if (key === 20) {
await area.set(30, "value 30, but changed!!");
}
}
assert_array_equals(seen, [10, 20, 30, 40]);
}, "Modifying a value after the current entry must have no effect on iteration (since we're iterating keys)");
</script>

View file

@ -1,5 +0,0 @@
# KV Storage `[SecureContext]` tests
These tests ensure that KV Storage follows the rules for `[SecureContext]` modules. (As of the time of this writing, they are only proposed rules, in [heycam/webidl#675](https://github.com/heycam/webidl/pull/675).)
Eventually these should probably be generalized and tested as part of `idlharness.js`.

View file

@ -1,18 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>KV Storage: should not work in non-secure contexts when included via import()</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
"use strict";
test(() => {
assert_false(self.isSecureContext, "This test must run in a non-secure context");
}, "Prerequisite check");
promise_test(t => {
return promise_rejects_js(t, TypeError, import("std:kv-storage"));
});
</script>

View file

@ -1,31 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>KV Storage: in non-secure contexts, import map mappings should fall back</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
"use strict";
test(() => {
assert_false(self.isSecureContext, "This test must run in a non-secure context");
}, "Prerequisite check");
</script>
<script type="importmap">
{
"imports": {
"./resources/dummy-module.js": [
"std:kv-storage",
"./resources/dummy-module.js"
]
}
}
</script>
<script type="module">
promise_test(async () => {
const result = await import("./resources/dummy-module.js");
assert_equals(result.myExport, "not the real KV storage");
});
</script>

View file

@ -1,26 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>KV Storage: should not work in non-secure contexts when included via an import statement</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
"use strict";
setup({ allow_uncaught_exception: true });
test(() => {
assert_false(self.isSecureContext, "This test must run in a non-secure context");
}, "Prerequisite check");
const t = async_test('Static import kv-storage in non-secure context');
window.addEventListener("error", t.step_func_done(errorEvent => {
assert_equals(errorEvent.error.constructor, TypeError, "Must trigger a TypeError");
}, { once: true }));
</script>
<script type="module"
onerror="t.unreached_func('script error event should not be fired')()">
import "std:kv-storage";
</script>

View file

@ -1 +0,0 @@
export const myExport = "not the real KV storage";

View file

@ -1 +0,0 @@
window.sideEffectsHappened = true;

View file

@ -1,21 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>KV Storage: should not work in non-secure contexts when included via a script element</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
"use strict";
test(() => {
assert_false(self.isSecureContext, "This test must run in a non-secure context");
}, "Prerequisite check");
window.t = async_test("Check the events");
</script>
<script type="module"
src="std:kv-storage"
onload="t.step(() => { assert_unreached('load event fired'); })"
onerror="t.done()">
</script>

View file

@ -1,28 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>KV Storage: should fail in non-secure contexts in the fetching phase, not evaluation phase</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
"use strict";
setup({ allow_uncaught_exception: true });
window.sideEffectsHappened = false;
test(() => {
assert_false(self.isSecureContext, "This test must run in a non-secure context");
}, "Prerequisite check");
</script>
<script type="module">
import "./resources/test-side-effects.js";
import "std:kv-storage";
</script>
<script type="module">
test(() => {
assert_false(window.sideEffectsHappened, "The side effects module didn't evaluate either");
});
</script>

View file

@ -1,15 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>KV storage: storage export smoke test</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script type="module">
import { testVariousMethodsWithDefaultArea } from "./helpers/kvs-tests.js";
testVariousMethodsWithDefaultArea(
"Storage methods smoke test with string key and value", "key", "value", assert_equals
);
</script>

View file

@ -1,39 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>KV Storage: undefined values</title>
<meta name="timeout" content="long">
<!-- https://github.com/wicg/kv-storage/commit/5bf31109f37d1371f619ea33d0e2391f10e8b8f5 -->
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script type="module">
import { StorageArea } from "std:kv-storage";
import { testWithArea } from "./helpers/kvs-tests.js";
import { assertAsyncIteratorEquals } from "./helpers/equality-asserters.js";
testWithArea(async (area) => {
assert_equals(await area.get("key"), undefined);
}, "Get on a non-existant key returns undefined");
testWithArea(async (area) => {
await area.set("key", undefined);
assert_equals(await area.get("key"), undefined);
await assertAsyncIteratorEquals(area.keys(), [], "keys");
await assertAsyncIteratorEquals(area.values(), [], "values");
await assertAsyncIteratorEquals(area.entries(), [], "entries");
}, "Setting undefined as a value when nothing was present is a no-op");
testWithArea(async (area) => {
await area.set("key", "value");
await area.set("key", undefined);
assert_equals(await area.get("key"), undefined);
await assertAsyncIteratorEquals(area.keys(), [], "keys");
await assertAsyncIteratorEquals(area.values(), [], "values");
await assertAsyncIteratorEquals(area.entries(), [], "entries");
}, "Setting undefined as a value deletes what was previously there");
</script>

View file

@ -1,232 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>KV Storage: values() trickier tests</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script type="module">
import { testWithArea } from "./helpers/kvs-tests.js";
import * as iterAssert from "./helpers/iter-assert.js";
import { assertAsyncIteratorEquals } from "./helpers/equality-asserters.js";
testWithArea(async area => {
await area.set(1, "value 1");
await area.set(2, "value 2");
await area.set(3, "value 3");
await assertAsyncIteratorEquals(area.values(), ["value 1", "value 2", "value 3"]);
}, "Using for-await-of to collect the results works");
testWithArea(async area => {
// We're not testing every key type since this isn't a test of IndexedDB.
await area.set(1, "value 1");
await area.set(new Date(500), "value date 500");
await area.set(-1, "value -1");
await area.set(new Date(-20), "value date -20");
await area.set("aaa", "value aaa");
await area.set("a", "value a");
await area.set(-Infinity, "value -Infinity");
await assertAsyncIteratorEquals(
area.values(),
[
"value -Infinity",
"value -1",
"value 1",
"value date -20",
"value date 500",
"value a",
"value aaa"
]
);
}, "Results are returned in IndexedDB key order");
testWithArea(async area => {
await area.set(1, "value 1");
await area.set(2, "value 2");
await area.set(3, "value 3");
const iter = area.values();
const iterResults = [
await iter.next(),
await iter.next(),
await iter.next(),
await iter.next(),
await iter.next(),
await iter.next()
];
iterAssert.iterResults(iterResults, [
["value 1", false],
["value 2", false],
["value 3", false],
[undefined, true],
[undefined, true],
[undefined, true]
]);
}, "Manual testing of .next() calls, with awaiting");
testWithArea(async area => {
area.set(1, "value 1");
area.set(2, "value 2");
area.set(3, "value 3");
const iter = area.values();
const promises = [
iter.next(),
iter.next(),
iter.next(),
iter.next(),
iter.next(),
iter.next()
];
const iterResults = await Promise.all(promises);
iterAssert.iterResults(iterResults, [
["value 1", false],
["value 2", false],
["value 3", false],
[undefined, true],
[undefined, true],
[undefined, true]
]);
}, "Manual testing of .next() calls, no awaiting");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const value of area.values()) {
seen.push(value);
if (value === "value 20") {
await area.set(15, "value 15");
}
}
assert_array_equals(seen, ["value 10", "value 20", "value 30", "value 40"]);
}, "Inserting an entry before the current entry must have no effect on iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const value of area.values()) {
seen.push(value);
if (value === "value 20") {
await area.set(25, "value 25");
}
}
assert_array_equals(seen, ["value 10", "value 20", "value 25", "value 30", "value 40"]);
}, "Inserting an entry after the current entry must show up in iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const value of area.values()) {
seen.push(value);
if (value === "value 20") {
await area.delete(10);
}
}
assert_array_equals(seen, ["value 10", "value 20", "value 30", "value 40"]);
}, "Deleting an entry before the current entry must have no effect on iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const value of area.values()) {
seen.push(value);
if (value === "value 20") {
await area.delete(20);
}
}
assert_array_equals(seen, ["value 10", "value 20", "value 30", "value 40"]);
}, "Deleting the current entry must have no effect on iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const value of area.values()) {
seen.push(value);
if (value === "value 20") {
await area.delete(30);
}
}
assert_array_equals(seen, ["value 10", "value 20", "value 40"]);
}, "Deleting an entry after the current entry must show up in iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const value of area.values()) {
seen.push(value);
if (value === "value 20") {
await area.set(10, "value 10, but changed!!");
}
}
assert_array_equals(seen, ["value 10", "value 20", "value 30", "value 40"]);
}, "Modifying a value before the current entry must have no effect on iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const value of area.values()) {
seen.push(value);
if (value === "value 20") {
await area.set(20, "value 20, but changed!!");
}
}
assert_array_equals(seen, ["value 10", "value 20", "value 30", "value 40"]);
}, "Modifying a value at the current entry must have no effect on iteration");
testWithArea(async area => {
await area.set(10, "value 10");
await area.set(20, "value 20");
await area.set(30, "value 30");
await area.set(40, "value 40");
let seen = [];
for await (const value of area.values()) {
seen.push(value);
if (value === "value 20") {
await area.set(30, "value 30, but changed!!");
}
}
assert_array_equals(seen, ["value 10", "value 20", "value 30, but changed!!", "value 40"]);
}, "Modifying a value after the current entry must show up in iteration");
</script>

View file

@ -201,8 +201,8 @@ SET TIMEOUT: service-workers/service-worker/resources/resource-timing-worker.js
SET TIMEOUT: shadow-dom/Document-prototype-currentScript.html
SET TIMEOUT: shadow-dom/scroll-to-the-fragment-in-shadow-tree.html
SET TIMEOUT: shadow-dom/slotchange-event.html
SET TIMEOUT: trusted-types/block-string-assignment-to-DOMWindowTimers-setTimeout-setInterval.tentative.html
SET TIMEOUT: trusted-types/DOMWindowTimers-setTimeout-setInterval.tentative.html
SET TIMEOUT: trusted-types/block-string-assignment-to-DOMWindowTimers-setTimeout-setInterval.tentative.https.html
SET TIMEOUT: trusted-types/DOMWindowTimers-setTimeout-setInterval.tentative.https.html
SET TIMEOUT: user-timing/*
SET TIMEOUT: web-animations/timing-model/animations/*
SET TIMEOUT: webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest.html

View file

@ -1,17 +0,0 @@
// META: global=window,worker
// META: script=/resources/WebIDLParser.js
// META: script=/resources/idlharness.js
'use strict';
idl_test(
['origin-policy'],
['html', 'dom'],
idl_array => {
if (self.Window) {
idl_array.add_objects({ Window: ['self'] });
} else {
idl_array.add_objects({ WorkerGlobalScope: ['self'] });
}
}
);

View file

@ -1,17 +0,0 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy with empty-array "ids" member that occurs after a non-empty "ids" member must be ignored</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>
<div id="log"></div>
<script>
"use strict";
runTestsInSubframe({
hostname: "op13",
testJS: "../content-security/resources/allow-unsafe-eval.mjs",
expectedIds: []
});
</script>

View file

@ -1,17 +0,0 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy with empty-array "ids" member must be ignored</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>
<div id="log"></div>
<script>
"use strict";
runTestsInSubframe({
hostname: "op12",
testJS: "../content-security/resources/allow-unsafe-eval.mjs",
expectedIds: []
});
</script>

View file

@ -1,25 +0,0 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy must include valid IDs and exclude non-strings and invalid strings</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>
<div id="log"></div>
<script>
"use strict";
runTestsInSubframe({
hostname: "op15",
testJS: "../content-security/resources/disallow-unsafe-eval-disallow-images.mjs",
expectedIds: [
"my-policy-1",
"my-policy-2",
"~",
" ",
"!\"#$%&'()*+,-./:;<=>?@{|}~",
"azAZ",
"my~policy"
]
});
</script>

View file

@ -1,17 +0,0 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy with no "ids" member must be ignored</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>
<div id="log"></div>
<script>
"use strict";
runTestsInSubframe({
hostname: "op11",
testJS: "../content-security/resources/allow-unsafe-eval.mjs",
expectedIds: []
});
</script>

View file

@ -1,17 +0,0 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy a non-array "ids" member must be ignored</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>
<div id="log"></div>
<script>
"use strict";
runTestsInSubframe({
hostname: "op14",
testJS: "../content-security/resources/allow-unsafe-eval.mjs",
expectedIds: []
});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>originPolicyIds must return the same object each time</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
"use strict";
test(() => {
// Failing this test is a common failure mode for FrozenArray attributes,
// so let's be sure implementations get it right.
assert_equals(window.originPolicyIds, window.originPolicyIds);
});
</script>

View file

@ -1,16 +0,0 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>originPolicyIds must return an empty array in http: pages</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
"use strict";
test(() => {
assert_equals(location.protocol, "http:");
}, "Prerequisite check: running on HTTP, not HTTPS");
test(() => {
assert_array_equals(window.originPolicyIds, []);
}, "The attribute is still present and returns an empty frozen array");
</script>

View file

@ -1,20 +0,0 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy second "ids" member must take precedence</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>
<div id="log"></div>
<script>
"use strict";
runTestsInSubframe({
hostname: "op16",
testJS: "../content-security/resources/disallow-unsafe-eval-disallow-images.mjs",
expectedIds: [
"3",
"4"
]
});
</script>

View file

@ -1,7 +0,0 @@
{
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'"
]
}
}

View file

@ -1,8 +0,0 @@
{
"ids": [],
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'"
]
}
}

View file

@ -1,11 +0,0 @@
{
"ids": [
"this should be overwritten by the subsequent one"
],
"ids": [],
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'"
]
}
}

View file

@ -1,8 +0,0 @@
{
"ids": "this is not an array",
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'"
]
}
}

View file

@ -1,28 +0,0 @@
{
"ids": [
"my-policy-1",
["my-policy-array"],
5,
null,
{ "id": "my-policy-object" },
"my-policy-2",
true,
"~",
" ",
"\u0000",
"\t",
"my\tpolicy",
"!\"#$%&'()*+,-./:;<=>?@{|}~",
"my\u007Fpolicy",
"azAZ",
"my\u0080policy",
"my~policy",
"my\u1234policy"
],
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'",
"img-src 'none'"
]
}
}

View file

@ -1,16 +0,0 @@
{
"ids": [
"1",
"2"
],
"ids": [
"3",
"4"
],
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'",
"img-src 'none'"
]
}
}

View file

@ -1,4 +1,4 @@
window.runTestsInSubframe = ({ hostname, testJS, expectedIds }) => {
window.runTestsInSubframe = ({ hostname, testJS }) => {
test(() => {
assert_equals(location.protocol, "https:");
}, "Prerequisite check: running on HTTPS");
@ -12,8 +12,6 @@ window.runTestsInSubframe = ({ hostname, testJS, expectedIds }) => {
// to themselves.
url.searchParams.append("test", new URL(testJS, document.baseURI).pathname);
url.searchParams.append("expectedIds", JSON.stringify(expectedIds));
const iframe = document.createElement("iframe");
iframe.src = url.href;

View file

@ -9,12 +9,10 @@ def main(request, response):
"""
test_file = request.GET.first("test")
expected_ids = request.GET.first("expectedIds")
response.headers.set("Origin-Policy", "allowed=(latest)")
response.headers.set("Content-Type", "text/html")
ret_val = """
return """
<!DOCTYPE html>
<meta charset="utf-8">
<title>Origin policy subframe</title>
@ -26,14 +24,3 @@ def main(request, response):
<script type="module" src="%s"></script>
""" % test_file
if expected_ids != "undefined":
ret_val += """
<script type="module">
test(() => {
assert_array_equals(originPolicyIds, %s);
}, "Expected originPolicyIDs check");
</script>
""" % expected_ids
return ret_val

View file

@ -21,7 +21,15 @@ function createTestTree(node) {
function attachShadowFromTemplate(template) {
let parent = template.parentNode;
parent.removeChild(template);
let shadowRoot = parent.attachShadow({mode: template.getAttribute('data-mode')});
let shadowRoot;
if (template.getAttribute('data-slot-assignment') === 'manual') {
shadowRoot =
parent.attachShadow({mode: template.getAttribute('data-mode'),
slotAssignment: 'manual'});
} else {
shadowRoot = parent.attachShadow(
{mode: template.getAttribute('data-mode')});
}
let id = template.id;
if (id) {
shadowRoot.id = id;

View file

@ -0,0 +1,229 @@
<!DOCTYPE html>
<title>Shadow DOM: Imperative Slot API</title>
<meta name="author" title="Yu Han" href="mailto:yuzhehan@chromium.org">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/shadow-dom.js"></script>
<div id="test_basic">
<div id="host1"></div>
<div id="host2"></div>
<div id="host3"></div>
</div>
<script>
test(() => {
let tTree = createTestTree(test_basic);
assert_not_equals(tTree.host1.attachShadow({ mode: 'open', slotAssignment: 'manual'}),
null, 'slot assignment manual should work');
assert_not_equals(tTree.host2.attachShadow({ mode: 'open', slotAssignment: 'auto'}),
null, 'slot assignment auto should work');
assert_throws_js(TypeError, () => {
tTree.host3.attachShadow({ mode: 'open', slotAssignment: 'exceptional' })},
'others should throw exception');
}, 'attachShadow can take slotAssignment parameter.');
</script>
<div id="test_errors">
<div id="host1">
<template data-mode="open" data-slot-assignment="auto">
<slot id="s1"></slot>
</template>
</div>
<div id="host2">
<template data-mode="open" data-slot-assignment="manual">
<slot id="s2"></slot>
</template>
</div>
<div id="c1" slot="slot1"></div>
</div>
<script>
test(() => {
let tTree = createTestTree(test_errors);
assert_throws_dom('NotAllowedError', () => { tTree.s1.assign([]); });
}, 'Imperative slot API throws exception when not slotAssignment != \'manual\'.');
test(() => {
let tTree = createTestTree(test_errors);
assert_throws_dom('NotAllowedError', () => { tTree.s2.assign([tTree.c1]); });
assert_throws_dom('NotAllowedError', () => { tTree.s2.assign([tTree.host1]); });
}, 'Imperative slot API throws exception when slotable parentNode != slot\'s host.');
</script>
<div id="test_assign">
<div id="host">
<template id="shadow_root" data-mode="open" data--slot-assignment="manual">
<slot id="s1"></slot>
<slot id="s2"></slot>
<slot id="s3"></slot>
</template>
<div id="c1"></div>
<div id="c2"></div>
<div id="c3"></div>
<div id="nested">
<div id="ns1"></div>
</div>
</div>
<div id="c4"></div>
<div id="host4">
<template id="shadow_root4" data-mode="open" data-slot-assignment="manual">
<slot id="s4" name="s4"></slot>
</template>
</div>
</div>
<script>
test(() => {
let tTree = createTestTree(test_assign);
assert_array_equals(tTree.s2.assignedElements(), []);
assert_equals(tTree.c1.assignedSlot, null);
tTree.s1.assign([tTree.c1]);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1]);
assert_equals(tTree.c1.assignedSlot, tTree.s1);
tTree.s2.assign([tTree.c2, tTree.c3]);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1]);
assert_array_equals(tTree.s2.assignedNodes(), [tTree.c2, tTree.c3]);
}, 'Imperative slot API can assign nodes in manual slot assignment.');
test(() => {
let tTree = createTestTree(test_assign);
tTree.s1.assign([tTree.c2, tTree.c3, tTree.c1]);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c2, tTree.c3, tTree.c1]);
assert_equals(tTree.c1.assignedSlot, tTree.s1);
assert_equals(tTree.c2.assignedSlot, tTree.s1);
assert_equals(tTree.c3.assignedSlot, tTree.s1);
tTree.s1.assign([tTree.c1, tTree.c2]);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1, tTree.c2]);
assert_equals(tTree.c1.assignedSlot, tTree.s1);
assert_equals(tTree.c2.assignedSlot, tTree.s1);
assert_equals(tTree.c3.assignedSlot, null);
tTree.s1.assign([tTree.c3, tTree.c2, tTree.c1]);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c3, tTree.c2, tTree.c1]);
assert_equals(tTree.c1.assignedSlot, tTree.s1);
assert_equals(tTree.c2.assignedSlot, tTree.s1);
assert_equals(tTree.c3.assignedSlot, tTree.s1);
}, 'Order of slotables is preserved in manual slot assignment.');
test(() => {
let tTree = createTestTree(test_assign);
tTree.s1.assign([tTree.c2, tTree.c3, tTree.c1]);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c2, tTree.c3, tTree.c1]);
tTree.s2.assign([tTree.c2]);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c3, tTree.c1]);
assert_array_equals(tTree.s2.assignedNodes(), [tTree.c2]);
assert_equals(tTree.c1.assignedSlot, tTree.s1);
assert_equals(tTree.c2.assignedSlot, tTree.s2);
assert_equals(tTree.c3.assignedSlot, tTree.s1);
tTree.s3.assign([tTree.c3]);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1]);
assert_array_equals(tTree.s2.assignedNodes(), [tTree.c2]);
assert_array_equals(tTree.s3.assignedNodes(), [tTree.c3]);
assert_equals(tTree.c1.assignedSlot, tTree.s1);
assert_equals(tTree.c2.assignedSlot, tTree.s2);
assert_equals(tTree.c3.assignedSlot, tTree.s3);
}, 'Previously assigned slotable is moved to new slot when it\'s reassigned.');
test(() => {
let tTree = createTestTree(test_assign);
// tTree.c4 is invalid for tTree.host slot assignment.
try {
tTree.s1.assign([tTree.c1, tTree.c2, tTree.c4]);
assert_unreached('assign() should have failed) ');
} catch (err) {
assert_equals(err.name, 'NotAllowedError');
}
assert_array_equals(tTree.s1.assignedNodes(), []);
assert_equals(tTree.c1.assignedSlot, null);
assert_equals(tTree.c2.assignedSlot, null);
assert_equals(tTree.c4.assignedSlot, null);
tTree.s1.assign([tTree.c2, tTree.c3, tTree.c1]);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c2, tTree.c3, tTree.c1]);
try {
tTree.s1.assign([tTree.c4]);
assert_unreached('assign() should have failed) ');
} catch (err) {
assert_equals(err.name, 'NotAllowedError');
}
// Previous state is preserved.
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c2, tTree.c3, tTree.c1]);
assert_equals(tTree.c1.assignedSlot, tTree.s1);
assert_equals(tTree.c2.assignedSlot, tTree.s1);
assert_equals(tTree.c3.assignedSlot, tTree.s1);
}, 'Assigning invalid nodes causes exception and slot returns to its previous state.');
test(() => {
let tTree = createTestTree(test_assign);
tTree.s1.assign([tTree.c1, tTree.c2, tTree.c3]);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1, tTree.c2, tTree.c3]);
tTree.host4.append(tTree.s1);
assert_array_equals(tTree.s1.assignedNodes(), []);
}, 'Moving a slot to a new host, the slot loses its previously assigned slotables.');
test(() => {
let tTree = createTestTree(test_assign);
tTree.s1.assign([tTree.c1, tTree.c2, tTree.c3]);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1, tTree.c2, tTree.c3]);
tTree.shadow_root.insertBefore(tTree.s2, tTree.s1);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1, tTree.c2, tTree.c3]);
assert_array_equals(tTree.s2.assignedNodes(), []);
tTree.shadow_root.insertBefore(tTree.s4, tTree.s1);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1, tTree.c2, tTree.c3]);
assert_array_equals(tTree.s4.assignedNodes(), []);
tTree.ns1.append(tTree.s1);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1, tTree.c2, tTree.c3]);
}, 'Moving a slot\'s tree order position within a shadow host has no impact on its assigned slotables.');
test(() => {
let tTree = createTestTree(test_assign);
tTree.s1.assign([tTree.c1, tTree.c2, tTree.c3]);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1, tTree.c2, tTree.c3]);
tTree.host4.append(tTree.c1);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c2, tTree.c3]);
assert_array_equals(tTree.s4.assignedNodes(), []);
tTree.s4.assign(tTree.c1);
assert_array_equals(tTree.s4.assignedNodes(), [tTree.c1]);
assert_equals(tTree.c1.assignedSlot, tTree.s4);
}, 'Appending slotable to different host, it loses slot assignment. It can be re-assigned within a new host.');
test(() => {
let tTree = createTestTree(test_assign);
tTree.s1.assign([tTree.c1, tTree.c1, tTree.c1]);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1]);
tTree.s1.assign([tTree.c1, tTree.c1, tTree.c2, tTree.c2, tTree.c1]);
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c2, tTree.c1]);
}, 'Assignment with the same node in parameters should be ignored, last one wins.');
test(() => {
let tTree = createTestTree(test_assign);
tTree.s1.assign([tTree.c1, tTree.c2, tTree.c3]);
tTree.s1.remove();
assert_equals(tTree.c1.assignedSlot, null);
assert_equals(tTree.c2.assignedSlot, null);
assert_equals(tTree.c3.assignedSlot, null);
}, 'Removing a slot from DOM resets its slotable\'s slot assignment.');
</script>

Some files were not shown because too many files have changed in this diff Show more