blob: 8fa7b65adb5f77d0e5a6282305641c8268948cb4 [file] [log] [blame]
// Hacky glue code to run Jest-based tests as WPT tests.
// TODO(https://github.com/WICG/import-maps/issues/170): Consider better ways
// to write and run tests.
setup({allow_uncaught_exception : true});
const exports = {};
function require(name) {
return Object.assign({
'URL': URL,
'parseFromString': parseFromString,
'resolve': resolve,
'BUILT_IN_MODULE_SCHEME': 'std'
}, exports);
}
// Sort keys and then stringify for comparison.
function stringifyImportMap(importMap) {
function getKeys(m) {
if (typeof m !== 'object')
return [];
let keys = [];
for (const key in m) {
keys.push(key);
keys = keys.concat(getKeys(m[key]));
}
return keys;
}
return JSON.stringify(importMap, getKeys(importMap).sort());
}
function expect(v) {
return {
toMatchURL: expected => assert_equals(v, expected),
toThrow: expected => {
if (expected.test && expected.test('not yet implemented')) {
// We override /not yet implemented/ expectation.
assert_throws(TypeError(), v);
} else {
assert_throws(expected(), v);
}
},
toEqual: expected => {
if (v.localName === 'iframe') {
// `v` is the result of parseFromString(), and thus toEqual() is
// expected to compare parsed import maps.
// We sort keys when stringifying for normalization.
const actualParsedImportMap = JSON.parse(
internals.getParsedImportMap(v.contentDocument));
assert_equals(
stringifyImportMap(actualParsedImportMap),
stringifyImportMap(expected)
);
} else {
assert_object_equals(v, expected);
}
}
};
}
expect.toMatchURL = expected => expected;
const test_harness_test = test;
test = it;
let current_message = '';
function describe(message, f) {
const old = current_message;
if (current_message !== '') {
current_message += ' / ';
}
current_message += message;
f();
current_message = old;
}
function it(message, f) {
const old = current_message;
if (current_message !== '') {
current_message += ' / ';
}
current_message += message;
test_harness_test(t => t.step_func(f)(), current_message);
current_message = old;
}
// Creates a new Document (via <iframe>) and add an inline import map.
// Currently document.write() is used to make everything synchronous, which
// is just needed for running the existing Jest-based tests easily.
function parseFromString(mapString, mapBaseURL) {
// We can't test data: base URLs because <base> rejects data: URLs.
if (new URL(mapBaseURL).protocol === 'data:') {
throw Error('test helper does not support data: base URLs');
}
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
iframe.contentDocument.write(`
<base href="${mapBaseURL}">
<script>
var scriptError;
var windowError;
function onScriptError(event) {
scriptError = event.error;
}
function onWindowError(event) {
windowError = event.error;
return false;
}
window.addEventListener('error', onWindowError);
</sc` + `ript>
<script type="importmap" onerror="onScriptError(event)">
${mapString}
</sc` + `ript>
`);
iframe.contentDocument.close();
// Rethrow window's error event.
if (iframe.contentWindow.windowError) {
throw iframe.contentWindow.windowError;
}
return iframe;
}
// URL resolution is tested using Chromium's `internals`.
// TODO(hiroshige): Remove the Chromium-specific dependency.
function resolve(specifier, map, baseURL) {
return internals.resolveModuleSpecifier(specifier,
baseURL,
map.contentDocument);
}