<!DOCTYPE html>
<meta charset="utf-8">
<meta name="variant" content="?parsing-addresses-absolute.json">
<meta name="variant" content="?parsing-addresses-invalid.json">
<meta name="variant" content="?parsing-addresses.json">
<meta name="variant" content="?parsing-invalid-json.json">
<meta name="variant" content="?parsing-schema-normalization.json">
<meta name="variant" content="?parsing-schema-scope.json">
<meta name="variant" content="?parsing-schema-specifier-map.json">
<meta name="variant" content="?parsing-schema-toplevel.json">
<meta name="variant" content="?parsing-scope-keys.json">
<meta name="variant" content="?parsing-specifier-keys.json">
<meta name="variant" content="?parsing-trailing-slashes.json">
<meta name="variant" content="?parsing-integrity.json">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
const filename = location.search.substring(1);
promise_test(async () => {
const res = await fetch('resources/' + filename);
const json = await res.json();
const tests = await jsonToTests(json);
for (const test of tests) {
promise_test(async t => {
const testHTML = `
<!DOCTYPE html>
<base href="${test.importMapBaseURL}">
<script type="importmap">
${JSON.stringify(test.importMap)}
</scri` + `pt>
<script>
parent.postMessage(internals.getParsedImportMap(document), '*');
</scri` + `pt>
`;
const iframe = document.createElement('iframe');
if (new URL(test.importMapBaseURL).protocol === 'data:') {
iframe.src = 'data:text/html;base64,' + btoa(testHTML);
} else {
iframe.src = '/common/blank.html';
iframe.onload = () => {
iframe.contentDocument.write(testHTML);
iframe.contentDocument.close();
};
}
document.body.append(iframe);
let parsedImportMap = JSON.parse(await new Promise(resolve => {
window.onmessage = t.step_func(e => {
assert_equals(e.source, iframe.contentWindow);
resolve(e.data);
});
}));
// internals.getParsedImportMap() returns an empty object instead of null for parse failures.
// Translate it so the test comparison works as expected.
if (Object.keys(parsedImportMap).length === 0) {
parsedImportMap = null;
}
assert_equals(
stringifyImportMap(parsedImportMap),
stringifyImportMap(test.expectedParsedImportMap)
);
}, test.name);
}
}, 'Data fetching and setup');
function jsonToTests(json, inheritedProps = {}, name = '') {
const baseProps = {
importMap: orFallback(json, inheritedProps, 'importMap'),
importMapBaseURL: orFallback(json, inheritedProps, 'importMapBaseURL'),
expectedParsedImportMap: orFallback(json, inheritedProps, 'expectedParsedImportMap')
};
if (json.tests) {
// Parent node
return Object.entries(json.tests).flatMap(([subName, subJSON]) => {
const fullName = [name, json.name, subName].filter(Boolean).join(': ');
return jsonToTests(subJSON, baseProps, fullName);
});
} else {
// Leaf (test) node
return [{ name: json.name, ...baseProps }];
}
}
function orFallback(obj1, obj2, property) {
return obj1.hasOwnProperty(property) ? obj1[property] : obj2[property];
}
// 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());
}
</script>