Skip to content

Commit 570d8d3

Browse files
committed
Use IDLHarness to test URL interface
1 parent f70f0b3 commit 570d8d3

File tree

4 files changed

+177
-1
lines changed

4 files changed

+177
-1
lines changed

.eslintrc.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"es6": true
66
},
77
"parserOptions": {
8-
"ecmaVersion": 6
8+
"ecmaVersion": 2019
99
},
1010
"rules": {
1111
// Possible errors

test/.eslintrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"env": { "jest": true }
3+
}

test/harness.test.js

+170
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
"use strict";
2+
3+
const { readFileSync, promises: fs } = require("fs");
4+
const path = require("path");
5+
const vm = require("vm");
6+
7+
process.on("unhandledRejection", e => {
8+
throw e;
9+
});
10+
11+
function createSandbox(setupScripts) {
12+
const sandbox = vm.createContext();
13+
sandbox.self = vm.runInContext("this", sandbox);
14+
for (const script of setupScripts) {
15+
script.runInContext(sandbox);
16+
}
17+
sandbox.require = p => {
18+
if (p[0] !== ".") {
19+
// eslint-disable-next-line global-require
20+
return require(p);
21+
}
22+
if (p.startsWith("../implementations/")) {
23+
return { implementation: class Stub {} };
24+
}
25+
26+
const resolved = path.resolve(__dirname, "./output", p);
27+
const src = readFileSync(resolved, { encoding: "utf8" });
28+
return vm.runInContext(
29+
`(() => {
30+
let exports = {};
31+
const module = { exports };
32+
(() => {${src}})();
33+
return module.exports;
34+
})();`,
35+
sandbox,
36+
{ filename: resolved, lineOffset: 5, columnOffset: 16 }
37+
);
38+
};
39+
return sandbox;
40+
}
41+
42+
async function prepareInterface({ name, content }, idlArray, sandbox) {
43+
const lcName = name[0].toLowerCase() + name.substring(1);
44+
45+
vm.runInContext(
46+
`(() => {
47+
const Wrapper = require("./${name}.js");
48+
Object.defineProperty(self, '${name}', {
49+
value: Wrapper.interface,
50+
enumerable: false,
51+
writable:true,
52+
configurable:true
53+
});
54+
Object.defineProperty(self, '${lcName}', {
55+
value: Wrapper.create([], {}),
56+
enumerable: false,
57+
writable:true,
58+
configurable:true
59+
});
60+
})()
61+
`,
62+
sandbox
63+
);
64+
65+
idlArray.add_idls(content);
66+
idlArray.add_objects({ [name]: [lcName] });
67+
}
68+
69+
describe("IDL Harness", () => {
70+
let setupScripts;
71+
72+
beforeAll(async () => {
73+
const files = await Promise.all(
74+
["testharness.js", "webidl2.js", "idlharness.js"].map(async p => ({
75+
path: path.join(__dirname, "/vendor/", p),
76+
contents: await fs.readFile(path.join(__dirname, "/vendor/", p), {
77+
encoding: "utf8"
78+
})
79+
}))
80+
);
81+
setupScripts = files.map(
82+
file => new vm.Script(file.contents, { filename: file.path })
83+
);
84+
});
85+
86+
const files = [
87+
"DOMImplementation",
88+
"EnumInterface",
89+
"PromiseTypes",
90+
"ReflectAttribute",
91+
"Storage",
92+
"StringifierAttribute",
93+
"StringifierDefaultOperation",
94+
"StringifierNamedOperation",
95+
"StringifierOperation",
96+
"TypedefsAndUnions",
97+
// "UnderscoredProperties",
98+
"Unforgeable",
99+
"UnforgeableMap",
100+
"URL",
101+
"URLList",
102+
"URLSearchParams",
103+
"URLSearchParamsCollection",
104+
// "URLSearchParamsCollection2",
105+
"Variadic",
106+
"ZeroArgConstructor"
107+
];
108+
test(`Interfaces`, async () => {
109+
const idlSources = await Promise.all(
110+
files.map(async f => ({
111+
name: f.replace(/\.webidl$/, ""),
112+
content: await fs.readFile(
113+
path.join(__dirname, `./cases/${f}.webidl`),
114+
{
115+
encoding: "utf8"
116+
}
117+
)
118+
}))
119+
);
120+
const sandbox = createSandbox(setupScripts);
121+
122+
const idlArray = new sandbox.IdlArray();
123+
idlSources.forEach(source => {
124+
prepareInterface(source, idlArray, sandbox);
125+
});
126+
127+
const prom = new Promise((resolve, reject) => {
128+
const errors = [];
129+
130+
sandbox.add_result_callback(test => {
131+
if (test.status === 1) {
132+
errors.push(
133+
`Failed in "${test.name}": \n${test.message}\n\n${test.stack}`
134+
);
135+
} else if (test.status === 2) {
136+
errors.push(
137+
`Timeout in "${test.name}": \n${test.message}\n\n${test.stack}`
138+
);
139+
} else if (test.status === 3) {
140+
errors.push(
141+
`Uncompleted test "${test.name}": \n${test.message}\n\n${
142+
test.stack
143+
}`
144+
);
145+
}
146+
});
147+
148+
sandbox.add_completion_callback((tests, harnessStatus) => {
149+
if (harnessStatus.status === 2) {
150+
errors.push(new Error(`test harness should not timeout`));
151+
}
152+
153+
if (errors.length === 1) {
154+
reject(new Error(errors[0]));
155+
} else if (errors.length) {
156+
reject(
157+
new Error(
158+
`${errors.length} errors in test:\n\n${errors.join("\n")}`
159+
)
160+
);
161+
} else {
162+
resolve();
163+
}
164+
});
165+
});
166+
167+
idlArray.test();
168+
await prom;
169+
});
170+
});

test/implementations/URL.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"use strict";
2+
3+
module.exports = class URL {};

0 commit comments

Comments
 (0)