mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Update web-platform-tests to revision d4391fedfec67d69f00396873a11f501a97ee3f1
This commit is contained in:
parent
e1f6dfd716
commit
5119e2cbbd
140 changed files with 406 additions and 2522 deletions
File diff suppressed because it is too large
Load diff
|
@ -1,4 +0,0 @@
|
|||
[hit-test-floats-002.html]
|
||||
[Hit test float]
|
||||
expected: FAIL
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[hit-test-floats-003.html]
|
||||
[Miss float below something else]
|
||||
expected: FAIL
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[hit-test-floats-004.html]
|
||||
[Miss float below something else]
|
||||
expected: FAIL
|
||||
|
|
@ -2,3 +2,6 @@
|
|||
[Hit test intersecting scaled box]
|
||||
expected: FAIL
|
||||
|
||||
[Hit test within unscaled box]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -2,3 +2,6 @@
|
|||
[listeners are called when <iframe> is resized]
|
||||
expected: FAIL
|
||||
|
||||
[listeners are called correct number of times]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -2,3 +2,6 @@
|
|||
[elementsFromPoint on the root document for points in iframe elements]
|
||||
expected: FAIL
|
||||
|
||||
[elementsFromPoint on inner documents]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[traverse_the_history_5.html]
|
||||
[traverse_the_history_2.html]
|
||||
[Multiple history traversals, last would be aborted]
|
||||
expected: FAIL
|
||||
|
|
@ -18,3 +18,6 @@
|
|||
[Set HTTP URL frame location.protocol to ftp]
|
||||
expected: FAIL
|
||||
|
||||
[Set data URL frame location.protocol to data]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -13,8 +13,5 @@
|
|||
expected: NOTRUN
|
||||
|
||||
[Host element with delegatesFocus should support autofocus]
|
||||
expected: NOTRUN
|
||||
|
||||
[Non-HTMLElement should not support autofocus]
|
||||
expected: TIMEOUT
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
[017.html]
|
||||
expected: TIMEOUT
|
||||
[origin of the script that invoked the method, about:blank]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -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>
|
|
@ -1 +0,0 @@
|
|||
Feature-Policy: oversized-images (inf)
|
|
@ -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>
|
|
@ -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>
|
|
@ -1 +0,0 @@
|
|||
Feature-Policy: oversized-images (1.5)
|
|
@ -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 |
|
@ -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>
|
||||
|
|
|
@ -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());
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
Cross-Origin-Embedder-Policy: require-corp
|
|
@ -1,3 +0,0 @@
|
|||
spec: https://wicg.github.io/kv-storage/
|
||||
suggested_reviewers:
|
||||
- domenic
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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} ` : "";
|
||||
}
|
|
@ -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>
|
|
@ -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} ` : "";
|
||||
}
|
|
@ -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");
|
||||
}
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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`.
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -1 +0,0 @@
|
|||
export const myExport = "not the real KV storage";
|
|
@ -1 +0,0 @@
|
|||
window.sideEffectsHappened = true;
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
||||
|
|
|
@ -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'] });
|
||||
}
|
||||
}
|
||||
);
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"content_security": {
|
||||
"policies": [
|
||||
"script-src 'self' 'unsafe-inline'"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"ids": [],
|
||||
"content_security": {
|
||||
"policies": [
|
||||
"script-src 'self' 'unsafe-inline'"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"ids": [
|
||||
"this should be overwritten by the subsequent one"
|
||||
],
|
||||
"ids": [],
|
||||
"content_security": {
|
||||
"policies": [
|
||||
"script-src 'self' 'unsafe-inline'"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"ids": "this is not an array",
|
||||
"content_security": {
|
||||
"policies": [
|
||||
"script-src 'self' 'unsafe-inline'"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -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'"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"ids": [
|
||||
"1",
|
||||
"2"
|
||||
],
|
||||
"ids": [
|
||||
"3",
|
||||
"4"
|
||||
],
|
||||
"content_security": {
|
||||
"policies": [
|
||||
"script-src 'self' 'unsafe-inline'",
|
||||
"img-src 'none'"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue