chromium/third_party/blink/web_tests/wpt_internal/import-maps/parsing.html

<!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>