tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test-helper.js (4381B)


      1 setup({allow_uncaught_exception : true});
      2 
      3 // Creates a new Document (via <iframe>) and add an inline import map.
      4 function createTestIframe(importMap, importMapBaseURL) {
      5  return new Promise(resolve => {
      6    const iframe = document.createElement('iframe');
      7 
      8    window.addEventListener('message', event => {
      9        // Parsing result is saved here and checked later, rather than
     10        // rejecting the promise on errors.
     11        iframe.parseImportMapResult = event.data.type;
     12        resolve(iframe);
     13      },
     14      {once: true});
     15 
     16    const testHTML = createTestHTML(importMap, importMapBaseURL);
     17 
     18    if (new URL(importMapBaseURL).protocol === 'data:') {
     19      iframe.src = 'data:text/html;base64,' + btoa(testHTML);
     20    } else {
     21      iframe.src = '/common/blank.html';
     22      iframe.addEventListener('load', () => {
     23        iframe.contentDocument.write(testHTML);
     24        iframe.contentDocument.close();
     25      }, {once: true});
     26    }
     27    document.body.appendChild(iframe);
     28  });
     29 }
     30 
     31 function createTestHTML(importMap, importMapBaseURL) {
     32  return `
     33    <!DOCTYPE html>
     34    <script src="${location.origin}/import-maps/data-driven/resources/test-helper-iframe.js"></script>
     35 
     36    <base href="${importMapBaseURL}">
     37    <script type="importmap" onerror="onScriptError(event)">
     38    ${JSON.stringify(importMap)}
     39    </script>
     40 
     41    <script type="module">
     42      if (!window.registrationResult) {
     43        window.registrationResult = {type: 'Success'};
     44      }
     45      window.removeEventListener('error', window.windowErrorHandler);
     46      parent.postMessage(window.registrationResult, '*');
     47    </script>
     48  `;
     49 }
     50 
     51 // Returns a promise that is resolved with the resulting URL, or rejected if
     52 // the resolution fails.
     53 function resolve(specifier, baseURL, iframe) {
     54  return new Promise((resolve, reject) => {
     55    window.addEventListener('message', event => {
     56        if (event.data.type === 'ResolutionSuccess') {
     57          resolve(event.data.result);
     58        } else if (event.data.type === 'Failure') {
     59          if (event.data.result === 'TypeError') {
     60            reject(new TypeError(event.data.message));
     61          } else {
     62            reject(new Error(event.data.message));
     63          }
     64        } else {
     65          assert_unreached('Invalid message: ' + event.data.type);
     66        }
     67      },
     68      {once: true});
     69 
     70    iframe.contentWindow.postMessage(
     71      {action: 'resolve', specifier, baseURL},
     72      '*'
     73    );
     74  });
     75 }
     76 
     77 function assert_no_extra_properties(object, expectedProperties, description) {
     78  for (const actualProperty in object) {
     79    assert_true(expectedProperties.indexOf(actualProperty) !== -1,
     80        description + ': unexpected property ' + actualProperty);
     81  }
     82 }
     83 
     84 async function runTests(j) {
     85  const tests = j.tests;
     86  delete j.tests;
     87 
     88  if (j.hasOwnProperty('importMap')) {
     89    assert_own_property(j, 'importMap');
     90    assert_own_property(j, 'importMapBaseURL');
     91    j.iframe = await createTestIframe(j.importMap, j.importMapBaseURL);
     92    delete j.importMap;
     93    delete j.importMapBaseURL;
     94  }
     95 
     96  assert_no_extra_properties(
     97      j,
     98      ['expectedResults', 'expectedParsedImportMap',
     99      'baseURL', 'name', 'iframe',
    100      'importMap', 'importMapBaseURL',
    101      'link', 'details'],
    102      j.name);
    103 
    104  if (tests) {
    105    // Nested node.
    106    for (const testName in tests) {
    107      let fullTestName = testName;
    108      if (j.name) {
    109        fullTestName = j.name + ': ' + testName;
    110      }
    111      tests[testName].name = fullTestName;
    112      const k = Object.assign({}, j, tests[testName]);
    113      await runTests(k);
    114    }
    115  } else {
    116    // Leaf node.
    117    for (const key of ['iframe', 'name', 'expectedResults']) {
    118      assert_own_property(j, key, j.name);
    119    }
    120 
    121    assert_equals(
    122        j.iframe.parseImportMapResult,
    123        'Success',
    124        'Import map registration should be successful for resolution tests');
    125    for (const [specifier, expected] of Object.entries(j.expectedResults)) {
    126      promise_test(async t => {
    127        if (expected === null) {
    128          return promise_rejects_js(t, TypeError, resolve(specifier, j.baseURL, j.iframe));
    129        } else {
    130          assert_equals(await resolve(specifier, j.baseURL, j.iframe), expected);
    131        }
    132      },
    133      j.name + ': ' + specifier);
    134    }
    135  }
    136 }
    137 
    138 export async function runTestsFromJSON(jsonURL) {
    139  const response = await fetch(jsonURL);
    140  const json = await response.json();
    141  await runTests(json);
    142 }