tor-browser

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

test_import_es6_modules.js (7853B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 add_task(async function() {
      5  // Test basic import.
      6  let ns = ChromeUtils.importESModule("resource://test/es6module.js");
      7  Assert.equal(ns.loadCount, 1);
      8  Assert.equal(ns.value, 2);
      9 
     10  // Test re-import of the same module.
     11  let ns2 = ChromeUtils.importESModule("resource://test/es6module.js");
     12  Assert.equal(ns.loadCount, 1);
     13  Assert.equal(ns, ns2);
     14 
     15  // Test imports with absolute and relative URIs return the same thing.
     16  let ns3 = ChromeUtils.importESModule("resource://test/es6module_absolute.js");
     17  let ns4 = ChromeUtils.importESModule("resource://test/es6module_absolute2.js");
     18  Assert.ok(ns3.absoluteX === ns3.relativeX);
     19  Assert.ok(ns3.absoluteX === ns4.x);
     20 
     21  // Test load failure.
     22  testFailure("resource://test/es6module_not_found.js", {
     23    type: "Error",
     24    message: "Failed to load resource://test/es6module_not_found.js",
     25    fileName: "test_import_es6_modules.js",
     26    stack: "testFailure",
     27    lineNumber: "*",
     28    columnNumber: "*",
     29    result: Cr.NS_ERROR_FILE_NOT_FOUND,
     30  });
     31 
     32  // Test load failure in import.
     33  testFailure("resource://test/es6module_missing_import.js", {
     34    type: "Error",
     35    message: "Failed to load resource://test/es6module_not_found2.js",
     36    fileName: "test_import_es6_modules.js",
     37    stack: "testFailure",
     38    lineNumber: "*",
     39    columnNumber: "*",
     40    result: Cr.NS_ERROR_FILE_NOT_FOUND,
     41  });
     42 
     43  // Test parse error.
     44  testFailure("resource://test/es6module_parse_error.js", {
     45    type: "SyntaxError",
     46    fileName: "resource://test/es6module_parse_error.js",
     47    stack: "testFailure",
     48    lineNumber: 1,
     49    columnNumber: 6,
     50  });
     51 
     52  // Test parse error in import.
     53  testFailure("resource://test/es6module_parse_error_in_import.js", {
     54    type: "SyntaxError",
     55    fileName: "resource://test/es6module_parse_error.js",
     56    stack: "testFailure",
     57    lineNumber: 1,
     58    columnNumber: 6,
     59  });
     60 
     61  // Test import error.
     62  testFailure("resource://test/es6module_import_error.js", {
     63    type: "SyntaxError",
     64    fileName: "resource://test/es6module_import_error.js",
     65    lineNumber: 1,
     66    columnNumber: 10,
     67  });
     68 
     69  // Test execution failure.
     70  let exception1 = testFailure("resource://test/es6module_throws.js", {
     71    type: "Error",
     72    message: "foobar",
     73    stack: "throwFunction",
     74    fileName: "resource://test/es6module_throws.js",
     75    lineNumber: 2,
     76    columnNumber: 9,
     77  });
     78 
     79  // Test re-import throws the same exception.
     80  let exception2 = testFailure("resource://test/es6module_throws.js", {
     81    type: "Error",
     82    message: "foobar",
     83    stack: "throwFunction",
     84    fileName: "resource://test/es6module_throws.js",
     85    lineNumber: 2,
     86    columnNumber: 9,
     87  });
     88  Assert.ok(exception1 === exception2);
     89 
     90  // Test loading cyclic module graph.
     91  ns = ChromeUtils.importESModule("resource://test/es6module_cycle_a.js");
     92  Assert.ok(ns.loaded);
     93  Assert.equal(ns.getValueFromB(), "b");
     94  ns = ChromeUtils.importESModule("resource://test/es6module_cycle_b.js");
     95  Assert.ok(ns.loaded);
     96  Assert.equal(ns.getValueFromC(), "c");
     97  ns = ChromeUtils.importESModule("resource://test/es6module_cycle_c.js");
     98  Assert.ok(ns.loaded);
     99  Assert.equal(ns.getValueFromA(), "a");
    100 
    101  // Test top-level await is not supported.
    102  testFailure("resource://test/es6module_top_level_await.js", {
    103    type: "SyntaxError",
    104    message: "not supported",
    105    stack: "testFailure",
    106    fileName: "resource://test/es6module_top_level_await.js",
    107    lineNumber: 1,
    108    columnNumber: 1,
    109  });
    110 });
    111 
    112 add_task(async function testDynamicImport() {
    113  // Dynamic import while and after evaluating top-level script.
    114  let ns = ChromeUtils.importESModule("resource://test/es6module_dynamic_import.js");
    115  let ns2 = await ns.result;
    116  Assert.equal(ns2.x, 10);
    117 
    118  ns2 = await ns.doImport();
    119  Assert.equal(ns2.y, 20);
    120 
    121  // Dynamic import for statically imported module.
    122  Assert.equal(ns.callGetCounter(), 1);
    123  ns.callSetCounter(5);
    124  Assert.equal(ns.callGetCounter(), 5);
    125 
    126  const { getCounter, setCounter } = await ns.doImportStatic();
    127  Assert.equal(getCounter(), 5);
    128  setCounter(8);
    129  Assert.equal(getCounter(), 8);
    130  Assert.equal(ns.callGetCounter(), 8);
    131 
    132  // Dynamic import for missing file.
    133  ns = ChromeUtils.importESModule("resource://test/es6module_dynamic_import_missing.js");
    134  let e = await ns.result;
    135  checkException(e, {
    136    type: "TypeError",
    137    message: "error loading dynamically imported",
    138    fileName: "resource://test/es6module_dynamic_import_missing.js",
    139    lineNumber: 5,
    140    columnNumber: 1,
    141  });
    142 
    143  e = await ns.doImport();
    144  checkException(e, {
    145    type: "TypeError",
    146    message: "error loading dynamically imported",
    147    fileName: "resource://test/es6module_dynamic_import_missing.js",
    148    lineNumber: 11,
    149    columnNumber: 5,
    150  });
    151 
    152  // Syntax error in dynamic import.
    153  ns = ChromeUtils.importESModule("resource://test/es6module_dynamic_import_syntax_error.js");
    154  e = await ns.result;
    155  checkException(e, {
    156    type: "SyntaxError",
    157    message: "unexpected token",
    158    fileName: "resource://test/es6module_dynamic_import_syntax_error2.js",
    159    lineNumber: 1,
    160    columnNumber: 3,
    161  });
    162 
    163  e = await ns.doImport();
    164  checkException(e, {
    165    type: "SyntaxError",
    166    message: "unexpected token",
    167    fileName: "resource://test/es6module_dynamic_import_syntax_error3.js",
    168    lineNumber: 1,
    169    columnNumber: 4,
    170  });
    171 
    172  // Runtime error in dynamic import.
    173  ns = ChromeUtils.importESModule("resource://test/es6module_dynamic_import_runtime_error.js");
    174  e = await ns.result;
    175  checkException(e, {
    176    type: "ReferenceError",
    177    message: "foo is not defined",
    178    fileName: "resource://test/es6module_dynamic_import_runtime_error2.js",
    179    lineNumber: 2,
    180    columnNumber: 1,
    181  });
    182 
    183  e = await ns.doImport();
    184  checkException(e, {
    185    type: "ReferenceError",
    186    message: "bar is not defined",
    187    fileName: "resource://test/es6module_dynamic_import_runtime_error3.js",
    188    lineNumber: 2,
    189    columnNumber: 1,
    190  });
    191 });
    192 
    193 function testFailure(url, expected) {
    194  let threw = false;
    195  let exception;
    196  let importLine, importColumn;
    197  try {
    198    // Get the line/column for ChromeUtils.importESModule.
    199    // lineNumber/columnNumber value with "*" in `expected` points the
    200    // line/column.
    201    let e = new Error();
    202    importLine = e.lineNumber + 3;
    203    importColumn = 17;
    204    ChromeUtils.importESModule(url);
    205  } catch (e) {
    206    threw = true;
    207    exception = e;
    208  }
    209 
    210  Assert.ok(threw, "Error should be thrown");
    211 
    212  checkException(exception, expected, importLine, importColumn);
    213 
    214  return exception;
    215 }
    216 
    217 function checkException(exception, expected, importLine, importColumn) {
    218  if ("type" in expected) {
    219    Assert.equal(exception.constructor.name, expected.type, "error type");
    220  }
    221  if ("message" in expected) {
    222    Assert.ok(exception.message.includes(expected.message),
    223              `Message "${exception.message}" should contain "${expected.message}"`);
    224  }
    225  if ("stack" in expected) {
    226    Assert.ok(exception.stack.includes(expected.stack),
    227              `Stack "${exception.stack}" should contain "${expected.stack}"`);
    228  }
    229  if ("fileName" in expected) {
    230    Assert.ok(exception.fileName.includes(expected.fileName),
    231              `fileName "${exception.fileName}" should contain "${expected.fileName}"`);
    232  }
    233  if ("lineNumber" in expected) {
    234    let expectedLine = expected.lineNumber;
    235    if (expectedLine === "*") {
    236      expectedLine = importLine;
    237    }
    238    Assert.equal(exception.lineNumber, expectedLine, "lineNumber");
    239  }
    240  if ("columnNumber" in expected) {
    241    let expectedColumn = expected.columnNumber;
    242    if (expectedColumn === "*") {
    243      expectedColumn = importColumn;
    244    }
    245    Assert.equal(exception.columnNumber, expectedColumn, "columnNumber");
    246  }
    247  if ("result" in expected) {
    248    Assert.equal(exception.result, expected.result, "result");
    249  }
    250 }