forked from mirrors/gecko-dev
250 lines
7.7 KiB
JavaScript
250 lines
7.7 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
add_task(async function() {
|
|
// Test basic import.
|
|
let ns = ChromeUtils.importESModule("resource://test/es6module.js");
|
|
Assert.equal(ns.loadCount, 1);
|
|
Assert.equal(ns.value, 2);
|
|
|
|
// Test re-import of the same module.
|
|
let ns2 = ChromeUtils.importESModule("resource://test/es6module.js");
|
|
Assert.equal(ns.loadCount, 1);
|
|
Assert.equal(ns, ns2);
|
|
|
|
// Test imports with absolute and relative URIs return the same thing.
|
|
let ns3 = ChromeUtils.importESModule("resource://test/es6module_absolute.js");
|
|
let ns4 = ChromeUtils.importESModule("resource://test/es6module_absolute2.js");
|
|
Assert.ok(ns3.absoluteX === ns3.relativeX);
|
|
Assert.ok(ns3.absoluteX === ns4.x);
|
|
|
|
// Test load failure.
|
|
testFailure("resource://test/es6module_not_found.js", {
|
|
type: "Error",
|
|
message: "Failed to load resource://test/es6module_not_found.js",
|
|
fileName: "test_import_es6_modules.js",
|
|
stack: "testFailure",
|
|
lineNumber: "*",
|
|
columnNumber: "*",
|
|
result: Cr.NS_ERROR_FILE_NOT_FOUND,
|
|
});
|
|
|
|
// Test load failure in import.
|
|
testFailure("resource://test/es6module_missing_import.js", {
|
|
type: "Error",
|
|
message: "Failed to load resource://test/es6module_not_found2.js",
|
|
fileName: "test_import_es6_modules.js",
|
|
stack: "testFailure",
|
|
lineNumber: "*",
|
|
columnNumber: "*",
|
|
result: Cr.NS_ERROR_FILE_NOT_FOUND,
|
|
});
|
|
|
|
// Test parse error.
|
|
testFailure("resource://test/es6module_parse_error.js", {
|
|
type: "SyntaxError",
|
|
fileName: "resource://test/es6module_parse_error.js",
|
|
stack: "testFailure",
|
|
lineNumber: 1,
|
|
columnNumber: 6,
|
|
});
|
|
|
|
// Test parse error in import.
|
|
testFailure("resource://test/es6module_parse_error_in_import.js", {
|
|
type: "SyntaxError",
|
|
fileName: "resource://test/es6module_parse_error.js",
|
|
stack: "testFailure",
|
|
lineNumber: 1,
|
|
columnNumber: 6,
|
|
});
|
|
|
|
// Test import error.
|
|
testFailure("resource://test/es6module_import_error.js", {
|
|
type: "SyntaxError",
|
|
fileName: "resource://test/es6module_import_error.js",
|
|
lineNumber: 1,
|
|
columnNumber: 10,
|
|
});
|
|
|
|
// Test execution failure.
|
|
let exception1 = testFailure("resource://test/es6module_throws.js", {
|
|
type: "Error",
|
|
message: "foobar",
|
|
stack: "throwFunction",
|
|
fileName: "resource://test/es6module_throws.js",
|
|
lineNumber: 2,
|
|
columnNumber: 9,
|
|
});
|
|
|
|
// Test re-import throws the same exception.
|
|
let exception2 = testFailure("resource://test/es6module_throws.js", {
|
|
type: "Error",
|
|
message: "foobar",
|
|
stack: "throwFunction",
|
|
fileName: "resource://test/es6module_throws.js",
|
|
lineNumber: 2,
|
|
columnNumber: 9,
|
|
});
|
|
Assert.ok(exception1 === exception2);
|
|
|
|
// Test loading cyclic module graph.
|
|
ns = ChromeUtils.importESModule("resource://test/es6module_cycle_a.js");
|
|
Assert.ok(ns.loaded);
|
|
Assert.equal(ns.getValueFromB(), "b");
|
|
ns = ChromeUtils.importESModule("resource://test/es6module_cycle_b.js");
|
|
Assert.ok(ns.loaded);
|
|
Assert.equal(ns.getValueFromC(), "c");
|
|
ns = ChromeUtils.importESModule("resource://test/es6module_cycle_c.js");
|
|
Assert.ok(ns.loaded);
|
|
Assert.equal(ns.getValueFromA(), "a");
|
|
|
|
// Test top-level await is not supported.
|
|
testFailure("resource://test/es6module_top_level_await.js", {
|
|
type: "SyntaxError",
|
|
message: "not supported",
|
|
stack: "testFailure",
|
|
fileName: "resource://test/es6module_top_level_await.js",
|
|
lineNumber: 1,
|
|
columnNumber: 1,
|
|
});
|
|
});
|
|
|
|
add_task(async function testDynamicImport() {
|
|
// Dynamic import while and after evaluating top-level script.
|
|
let ns = ChromeUtils.importESModule("resource://test/es6module_dynamic_import.js");
|
|
let ns2 = await ns.result;
|
|
Assert.equal(ns2.x, 10);
|
|
|
|
ns2 = await ns.doImport();
|
|
Assert.equal(ns2.y, 20);
|
|
|
|
// Dynamic import for statically imported module.
|
|
Assert.equal(ns.callGetCounter(), 1);
|
|
ns.callSetCounter(5);
|
|
Assert.equal(ns.callGetCounter(), 5);
|
|
|
|
const { getCounter, setCounter } = await ns.doImportStatic();
|
|
Assert.equal(getCounter(), 5);
|
|
setCounter(8);
|
|
Assert.equal(getCounter(), 8);
|
|
Assert.equal(ns.callGetCounter(), 8);
|
|
|
|
// Dynamic import for missing file.
|
|
ns = ChromeUtils.importESModule("resource://test/es6module_dynamic_import_missing.js");
|
|
let e = await ns.result;
|
|
checkException(e, {
|
|
type: "TypeError",
|
|
message: "error loading dynamically imported",
|
|
fileName: "resource://test/es6module_dynamic_import_missing.js",
|
|
lineNumber: 5,
|
|
columnNumber: 1,
|
|
});
|
|
|
|
e = await ns.doImport();
|
|
checkException(e, {
|
|
type: "TypeError",
|
|
message: "error loading dynamically imported",
|
|
fileName: "resource://test/es6module_dynamic_import_missing.js",
|
|
lineNumber: 11,
|
|
columnNumber: 5,
|
|
});
|
|
|
|
// Syntax error in dynamic import.
|
|
ns = ChromeUtils.importESModule("resource://test/es6module_dynamic_import_syntax_error.js");
|
|
e = await ns.result;
|
|
checkException(e, {
|
|
type: "SyntaxError",
|
|
message: "unexpected token",
|
|
fileName: "resource://test/es6module_dynamic_import_syntax_error2.js",
|
|
lineNumber: 1,
|
|
columnNumber: 3,
|
|
});
|
|
|
|
e = await ns.doImport();
|
|
checkException(e, {
|
|
type: "SyntaxError",
|
|
message: "unexpected token",
|
|
fileName: "resource://test/es6module_dynamic_import_syntax_error3.js",
|
|
lineNumber: 1,
|
|
columnNumber: 4,
|
|
});
|
|
|
|
// Runtime error in dynamic import.
|
|
ns = ChromeUtils.importESModule("resource://test/es6module_dynamic_import_runtime_error.js");
|
|
e = await ns.result;
|
|
checkException(e, {
|
|
type: "ReferenceError",
|
|
message: "foo is not defined",
|
|
fileName: "resource://test/es6module_dynamic_import_runtime_error2.js",
|
|
lineNumber: 2,
|
|
columnNumber: 1,
|
|
});
|
|
|
|
e = await ns.doImport();
|
|
checkException(e, {
|
|
type: "ReferenceError",
|
|
message: "bar is not defined",
|
|
fileName: "resource://test/es6module_dynamic_import_runtime_error3.js",
|
|
lineNumber: 2,
|
|
columnNumber: 1,
|
|
});
|
|
});
|
|
|
|
function testFailure(url, expected) {
|
|
let threw = false;
|
|
let exception;
|
|
let importLine, importColumn;
|
|
try {
|
|
// Get the line/column for ChromeUtils.importESModule.
|
|
// lineNumber/columnNumber value with "*" in `expected` points the
|
|
// line/column.
|
|
let e = new Error();
|
|
importLine = e.lineNumber + 3;
|
|
importColumn = 17;
|
|
ChromeUtils.importESModule(url);
|
|
} catch (e) {
|
|
threw = true;
|
|
exception = e;
|
|
}
|
|
|
|
Assert.ok(threw, "Error should be thrown");
|
|
|
|
checkException(exception, expected, importLine, importColumn);
|
|
|
|
return exception;
|
|
}
|
|
|
|
function checkException(exception, expected, importLine, importColumn) {
|
|
if ("type" in expected) {
|
|
Assert.equal(exception.constructor.name, expected.type, "error type");
|
|
}
|
|
if ("message" in expected) {
|
|
Assert.ok(exception.message.includes(expected.message),
|
|
`Message "${exception.message}" should contain "${expected.message}"`);
|
|
}
|
|
if ("stack" in expected) {
|
|
Assert.ok(exception.stack.includes(expected.stack),
|
|
`Stack "${exception.stack}" should contain "${expected.stack}"`);
|
|
}
|
|
if ("fileName" in expected) {
|
|
Assert.ok(exception.fileName.includes(expected.fileName),
|
|
`fileName "${exception.fileName}" should contain "${expected.fileName}"`);
|
|
}
|
|
if ("lineNumber" in expected) {
|
|
let expectedLine = expected.lineNumber;
|
|
if (expectedLine === "*") {
|
|
expectedLine = importLine;
|
|
}
|
|
Assert.equal(exception.lineNumber, expectedLine, "lineNumber");
|
|
}
|
|
if ("columnNumber" in expected) {
|
|
let expectedColumn = expected.columnNumber;
|
|
if (expectedColumn === "*") {
|
|
expectedColumn = importColumn;
|
|
}
|
|
Assert.equal(exception.columnNumber, expectedColumn, "columnNumber");
|
|
}
|
|
if ("result" in expected) {
|
|
Assert.equal(exception.result, expected.result, "result");
|
|
}
|
|
}
|