Skip to content

Commit c65ed0e

Browse files
committed
test: add webidl web-platform tests
1 parent a18f8c1 commit c65ed0e

File tree

47 files changed

+2560
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2560
-0
lines changed

test/fixtures/wpt/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Last update:
3535
- wasm/webapi: https://github.com/web-platform-tests/wpt/tree/fd1b23eeaa/wasm/webapi
3636
- web-locks: https://github.com/web-platform-tests/wpt/tree/10a122a6bc/web-locks
3737
- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/1e4933113d/WebCryptoAPI
38+
- webidl: https://github.com/web-platform-tests/wpt/tree/63ca529a02/webidl
3839
- webidl/ecmascript-binding/es-exceptions: https://github.com/web-platform-tests/wpt/tree/2f96fa1996/webidl/ecmascript-binding/es-exceptions
3940
- webmessaging/broadcastchannel: https://github.com/web-platform-tests/wpt/tree/6495c91853/webmessaging/broadcastchannel
4041
- webstorage: https://github.com/web-platform-tests/wpt/tree/1d2c5fb36a/webstorage

test/fixtures/wpt/versions.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@
9999
"commit": "1e4933113d2028e092d07a9e865db8f606b21026",
100100
"path": "WebCryptoAPI"
101101
},
102+
"webidl": {
103+
"commit": "63ca529a021fec15b2996db82fd7dd04c11abe85",
104+
"path": "webidl"
105+
},
102106
"webidl/ecmascript-binding/es-exceptions": {
103107
"commit": "2f96fa19966d6bc19e979a09479ac8a7aa337c54",
104108
"path": "webidl/ecmascript-binding/es-exceptions"

test/fixtures/wpt/webidl/META.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
spec: https://webidl.spec.whatwg.org/
2+
suggested_reviewers:
3+
- yuki3

test/fixtures/wpt/webidl/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Tests for the [Web IDL Standard](https://webidl.spec.whatwg.org/).
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<!-- This tests the agreed upon outcome for https://www.w3.org/Bugs/Public/show_bug.cgi?id=24652
2+
that has not been reflected in the IDL standard yet due to lack of editing resources.
3+
4+
TODO: https://github.com/w3c/webcrypto/issues/85 -->
5+
<!DOCTYPE html>
6+
<meta charset=utf-8>
7+
<title>Current Realm</title>
8+
<script src="/resources/testharness.js"></script>
9+
<script src="/resources/testharnessreport.js"></script>
10+
<div id="log"></div>
11+
<iframe srcdoc="<body test>"></iframe>
12+
<script>
13+
setup({explicit_done:true})
14+
15+
function isObjectFromGlobal(object, global) {
16+
return object instanceof global.Object;
17+
}
18+
function assert_global(obj) {
19+
assert_false(isObjectFromGlobal(obj, self), obj + " should not be from top-level Realm")
20+
assert_true(isObjectFromGlobal(obj, self[0]), obj + " should be from <iframe> Realm")
21+
}
22+
23+
onload = function() {
24+
[["querySelectorAll", "test"],
25+
["createElement", "x"],
26+
["createElementNS", null, "x"],
27+
["createDocumentFragment"],
28+
["createTextNode", "test"],
29+
["createComment", "test"],
30+
["createProcessingInstruction", "x", "x"],
31+
["createAttribute", "x"],
32+
["createAttributeNS", "x", "x"],
33+
["createEvent", "Event"],
34+
["createRange"],
35+
["createNodeIterator", document.head],
36+
["createTreeWalker", document.head]].forEach(function(val) {
37+
test(function() {
38+
const method = val.shift();
39+
let obj = self[0].document[method](...val);
40+
assert_global(obj)
41+
42+
obj = Document.prototype[method].call(self[0].document, ...val);
43+
assert_global(obj)
44+
}, val[0])
45+
})
46+
47+
;["Request", "Response"].forEach(val => {
48+
test(() => {
49+
const obj = new self[0][val]("about:blank");
50+
assert_global(obj);
51+
52+
const cloneObj = obj.clone();
53+
assert_global(cloneObj);
54+
55+
const involvedCloneObj = self[val].prototype["clone"].call(cloneObj);
56+
assert_global(cloneObj);
57+
}, val)
58+
})
59+
60+
// Note: these are not [NewObject] and can be cached. But across globals?
61+
;[["getElementsByTagName", "x"],
62+
["getElementsByTagNameNS", null, "x"],
63+
["getElementsByClassName", "x"]].forEach(function(val) {
64+
test(function() {
65+
const method = val.shift();
66+
const obj = self[0].document[method](...val);
67+
assert_global(obj)
68+
69+
const obj2 = Document.prototype[method].call(self[0].document, ...val);
70+
assert_global(obj)
71+
72+
assert_equals(obj, obj2) // XXX this might be controversial
73+
}, val[0])
74+
})
75+
76+
;[["createDocumentType", "x", "", ""],
77+
["createDocument", null, "", null],
78+
["createHTMLDocument", "x"]].forEach(function(val) {
79+
test(function() {
80+
const method = val.shift();
81+
let obj = self[0].document.implementation[method](...val);
82+
assert_global(obj)
83+
84+
obj = DOMImplementation.prototype[method].call(self[0].document.implementation, ...val);
85+
assert_global(obj)
86+
}, val[0])
87+
})
88+
89+
;[["item", 0],
90+
["getNamedItem", "test"],
91+
["getNamedItemNS", null, "test"]].forEach(function(val) {
92+
test(function() {
93+
const method = val.shift();
94+
const obj = self[0].document.body.attributes[method](...val);
95+
assert_global(obj)
96+
97+
const obj2 = NamedNodeMap.prototype[method].call(self[0].document.body.attributes, ...val);
98+
assert_global(obj)
99+
100+
assert_equals(obj, obj2)
101+
}, "NamedNodeMap " + val[0])
102+
})
103+
104+
test(function() {
105+
var c = self[0].document.createTextNode(""),
106+
obj = c.splitText(0)
107+
assert_global(obj)
108+
109+
obj = Text.prototype.splitText.call(c, "")
110+
assert_global(obj)
111+
}, "splitText")
112+
113+
;["extractContents",
114+
"cloneContents",
115+
"cloneRange"].forEach(function(val) {
116+
test(function() {
117+
var c = self[0].document.createRange(),
118+
obj = c[val]()
119+
assert_global(obj)
120+
121+
obj = Range.prototype[val].call(c)
122+
assert_global(obj)
123+
}, val)
124+
})
125+
126+
;["2d", "webgl"].forEach(function(val) {
127+
test(function() {
128+
var c = self[0].document.createElement("canvas"),
129+
obj = c.getContext(val)
130+
131+
// WebGL might not be enabled in this environment
132+
if (!obj && val === "webgl") {
133+
return;
134+
}
135+
136+
assert_global(obj)
137+
obj = HTMLCanvasElement.prototype.getContext.call(c, val)
138+
assert_global(obj)
139+
}, "getContext " + val)
140+
})
141+
142+
;[["createImageData", 5, 5],
143+
["getImageData", 5, 5, 5, 5]].forEach(function(val) {
144+
test(function() {
145+
const method = val.shift();
146+
const c = self[0].document.createElement("canvas").getContext("2d");
147+
let obj = c[method](...val);
148+
assert_global(obj)
149+
assert_global(obj.data)
150+
151+
obj = CanvasRenderingContext2D.prototype[method].call(c, ...val);
152+
assert_global(obj)
153+
assert_global(obj.data)
154+
}, val[0])
155+
})
156+
157+
test(function() {
158+
var c = new self[0].FontFace("test", "about:blank"),
159+
obj = c.load()
160+
assert_global(obj)
161+
162+
obj = FontFace.prototype.load.call(c)
163+
assert_global(obj)
164+
}, "FontFace's load()")
165+
166+
done()
167+
}
168+
</script>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<!DOCTYPE html>
2+
<script src="/resources/testharness.js"></script>
3+
<script src="/resources/testharnessreport.js"></script>
4+
<script src="/common/sab.js"></script>
5+
<script type="module">
6+
test(t => {
7+
// Fixed-length ABs should not throw
8+
const ab = new ArrayBuffer(16);
9+
new Response(new Uint8Array(ab));
10+
11+
const rab = new ArrayBuffer(16, { maxByteLength: 1024 });
12+
// Response doesn't have [AllowResizable] or [AllowShared]
13+
assert_throws_js(TypeError, () => {
14+
new Response(new Uint8Array(rab));
15+
});
16+
}, "APIs without [AllowResizable] throw when passed resizable ArrayBuffers");
17+
18+
test(t => {
19+
const enc = new TextEncoder();
20+
21+
// Fixed-length SABs should not throw
22+
const sab = createBuffer('SharedArrayBuffer', 16);
23+
enc.encodeInto("foobar", new Uint8Array(sab));
24+
25+
const gsab = createBuffer('SharedArrayBuffer', 16, { maxByteLength: 1024 });
26+
// TextEncoder.encodeInto doesn't have [AllowResizable] but has [AllowShared]
27+
assert_throws_js(TypeError, () => {
28+
enc.encodeInto("foobar", new Uint8Array(gsab));
29+
});
30+
}, "APIs with [AllowShared] but without [AllowResizable] throw when passed growable SharedArrayBuffers");
31+
</script>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>All attributes accessors are unique function objects</title>
4+
<link rel="help" href="https://webidl.spec.whatwg.org/#idl-interface-mixins">
5+
<script src="/resources/testharness.js"></script>
6+
<script src="/resources/testharnessreport.js"></script>
7+
<script>
8+
"use strict";
9+
10+
test(() => {
11+
const seenPrototypes = new WeakSet([Function.prototype]);
12+
const seenFunctions = new WeakMap();
13+
14+
for (const windowKey of Object.getOwnPropertyNames(window)) {
15+
const windowValue = window[windowKey];
16+
if (typeof windowValue !== "function") continue;
17+
18+
const {prototype} = windowValue;
19+
if (!prototype || seenPrototypes.has(prototype)) continue;
20+
seenPrototypes.add(prototype);
21+
22+
for (const key of Object.getOwnPropertyNames(prototype)) {
23+
const assert_not_seen = (fn, field) => {
24+
const fnInfo = `${windowKey}.${key}.${field}`;
25+
assert_equals(seenFunctions.get(fn), undefined, fnInfo);
26+
seenFunctions.set(fn, fnInfo);
27+
};
28+
29+
const desc = Object.getOwnPropertyDescriptor(prototype, key);
30+
if (desc.get) assert_not_seen(desc.get, "[[Get]]");
31+
if (desc.set) assert_not_seen(desc.set, "[[Set]]");
32+
}
33+
}
34+
}, "For attributes, each copy of the accessor property has distinct built-in function objects for its getters and setters.");
35+
</script>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"use strict";
2+
3+
test(() => {
4+
const ownPropKeys = Reflect.ownKeys(Blob).slice(0, 3);
5+
assert_array_equals(ownPropKeys, ["length", "name", "prototype"]);
6+
}, 'Constructor property enumeration order of "length", "name", and "prototype"');
7+
8+
test(() => {
9+
assert_own_property(Blob.prototype, "slice");
10+
11+
const ownPropKeys = Reflect.ownKeys(Blob.prototype.slice).slice(0, 2);
12+
assert_array_equals(ownPropKeys, ["length", "name"]);
13+
}, 'Method property enumeration order of "length" and "name"');
14+
15+
test(() => {
16+
assert_own_property(Blob.prototype, "size");
17+
18+
const desc = Reflect.getOwnPropertyDescriptor(Blob.prototype, "size");
19+
assert_equals(typeof desc.get, "function");
20+
21+
const ownPropKeys = Reflect.ownKeys(desc.get).slice(0, 2);
22+
assert_array_equals(ownPropKeys, ["length", "name"]);
23+
}, 'Getter property enumeration order of "length" and "name"');
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
"use strict";
2+
3+
test(() => {
4+
assert_own_property(Blob.prototype, Symbol.toStringTag);
5+
6+
const propDesc = Object.getOwnPropertyDescriptor(Blob.prototype, Symbol.toStringTag);
7+
assert_equals(propDesc.value, "Blob", "value");
8+
assert_equals(propDesc.configurable, true, "configurable");
9+
assert_equals(propDesc.enumerable, false, "enumerable");
10+
assert_equals(propDesc.writable, false, "writable");
11+
}, "@@toStringTag exists on the prototype with the appropriate descriptor");
12+
13+
test(() => {
14+
assert_not_own_property(new Blob(), Symbol.toStringTag);
15+
}, "@@toStringTag must not exist on the instance");
16+
17+
test(() => {
18+
assert_equals(Object.prototype.toString.call(Blob.prototype), "[object Blob]");
19+
}, "Object.prototype.toString applied to the prototype");
20+
21+
test(() => {
22+
assert_equals(Object.prototype.toString.call(new Blob()), "[object Blob]");
23+
}, "Object.prototype.toString applied to an instance");
24+
25+
test(t => {
26+
assert_own_property(Blob.prototype, Symbol.toStringTag, "Precondition for this test: @@toStringTag on the prototype");
27+
28+
t.add_cleanup(() => {
29+
Object.defineProperty(Blob.prototype, Symbol.toStringTag, { value: "Blob" });
30+
});
31+
32+
Object.defineProperty(Blob.prototype, Symbol.toStringTag, { value: "NotABlob" });
33+
assert_equals(Object.prototype.toString.call(Blob.prototype), "[object NotABlob]", "prototype");
34+
assert_equals(Object.prototype.toString.call(new Blob()), "[object NotABlob]", "instance");
35+
}, "Object.prototype.toString applied after modifying the prototype's @@toStringTag");
36+
37+
test(t => {
38+
const instance = new Blob();
39+
assert_not_own_property(instance, Symbol.toStringTag, "Precondition for this test: no @@toStringTag on the instance");
40+
41+
Object.defineProperty(instance, Symbol.toStringTag, { value: "NotABlob" });
42+
assert_equals(Object.prototype.toString.call(instance), "[object NotABlob]");
43+
}, "Object.prototype.toString applied to the instance after modifying the instance's @@toStringTag");
44+
45+
// Chrome had a bug (https://bugs.chromium.org/p/chromium/issues/detail?id=793406) where if there
46+
// was no @@toStringTag in the prototype, it would fall back to a magic class string. This tests
47+
// that the bug is fixed.
48+
49+
test(() => {
50+
const instance = new Blob();
51+
Object.setPrototypeOf(instance, null);
52+
53+
assert_equals(Object.prototype.toString.call(instance), "[object Object]");
54+
}, "Object.prototype.toString applied to a null-prototype instance");
55+
56+
// This test must be last.
57+
test(() => {
58+
delete Blob.prototype[Symbol.toStringTag];
59+
60+
assert_equals(Object.prototype.toString.call(Blob.prototype), "[object Object]", "prototype");
61+
assert_equals(Object.prototype.toString.call(new Blob()), "[object Object]", "instance");
62+
}, "Object.prototype.toString applied after deleting @@toStringTag");

0 commit comments

Comments
 (0)