diff options
author | davidot <davidot@serenityos.org> | 2022-01-27 01:54:47 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-01-30 17:40:20 +0000 |
commit | e0e4ead2c829ce5af822624fa57ff6eddb3657dd (patch) | |
tree | f1c09f60c7f6e0e2aabdad3edf1e4703fac37ac6 /Userland/Libraries/LibJS/Tests/modules | |
parent | 8473f6caeec29513d870cf6475d02807d5135379 (diff) | |
download | serenity-e0e4ead2c829ce5af822624fa57ff6eddb3657dd.zip |
LibJS: Follow the spec with storing im- and export entries
Because we can have arbitrary in- and export names with strings we can
have '*' and '' which means using '*' as an indicating namespace imports
failed / behaved incorrectly for string imports '*'.
We now use more specific types to indicate these special states instead
of these 'magic' string values.
Do note that 'default' is not actually a magic string value but one
specified by the spec. And you can in fact export the default value by
doing: `export { 1 as default }`.
Diffstat (limited to 'Userland/Libraries/LibJS/Tests/modules')
7 files changed, 89 insertions, 10 deletions
diff --git a/Userland/Libraries/LibJS/Tests/modules/basic-modules.js b/Userland/Libraries/LibJS/Tests/modules/basic-modules.js index 7693b1df14..eb927ab63c 100644 --- a/Userland/Libraries/LibJS/Tests/modules/basic-modules.js +++ b/Userland/Libraries/LibJS/Tests/modules/basic-modules.js @@ -1,25 +1,22 @@ // Because you can't easily load modules directly we load them via here and check // if they passed by checking the result -function expectModulePassed(filename) { +function validTestModule(filename) { if (!filename.endsWith(".mjs") || !filename.startsWith("./")) { throw new ExpectationError( - "Expected module name to start with './' " + - "and end with '.mjs' but got '" + - filename + - "'" + `Expected module name to start with './' and end with '.mjs' but got '${filename}'` ); } +} - async function getModule() { - return import(filename); - } +function expectModulePassed(filename) { + validTestModule(filename); let moduleLoaded = false; let moduleResult = null; let thrownError = null; - getModule() + import(filename) .then(result => { moduleLoaded = true; moduleResult = result; @@ -36,10 +33,36 @@ function expectModulePassed(filename) { } expect(moduleLoaded).toBeTrue(); - return moduleResult; } +function expectedModuleToThrowSyntaxError(filename, message) { + validTestModule(filename); + + let moduleLoaded = false; + let thrownError = null; + + import(filename) + .then(() => { + moduleLoaded = true; + }) + .catch(error => { + thrownError = error; + }); + + runQueuedPromiseJobs(); + + if (thrownError) { + expect(() => { + throw thrownError; + }).toThrowWithMessage(SyntaxError, message); + } else { + throw new ExpectationError( + `Expected module: '${filename}' to fail to load with a syntax error but did not throw.` + ); + } +} + describe("testing behavior", () => { // To ensure the other tests are interpreter correctly we first test the underlying // mechanisms so these tests don't use expectModulePassed. @@ -131,6 +154,25 @@ describe("in- and exports", () => { test("declaration exports which can be used in the module it self", () => { expectModulePassed("./declarations-tests.mjs"); }); + + test("string '*' is not a full namespace import", () => { + expectModulePassed("./string-import-names.mjs"); + }); + + test("can combine string and default exports", () => { + expectModulePassed("./string-import-namespace.mjs"); + }); + + test("can re export string names", () => { + expectModulePassed("./string-import-namespace-indirect.mjs"); + }); + + test("re exporting all-but-default does not export a default value", () => { + expectedModuleToThrowSyntaxError( + "./indirect-export-without-default.mjs", + "Invalid or ambiguous export entry 'default'" + ); + }); }); describe("loops", () => { diff --git a/Userland/Libraries/LibJS/Tests/modules/default-and-star-export-indirect.mjs b/Userland/Libraries/LibJS/Tests/modules/default-and-star-export-indirect.mjs new file mode 100644 index 0000000000..658425f847 --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/modules/default-and-star-export-indirect.mjs @@ -0,0 +1,2 @@ +// This is an all-but-default export and should thus only provide '*'. +export * from "./default-and-star-export.mjs"; diff --git a/Userland/Libraries/LibJS/Tests/modules/default-and-star-export.mjs b/Userland/Libraries/LibJS/Tests/modules/default-and-star-export.mjs new file mode 100644 index 0000000000..ffe97ffedb --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/modules/default-and-star-export.mjs @@ -0,0 +1,6 @@ +export default "defaultValue"; + +const star = "starExportValue"; +const empty = "empty"; + +export { star as "*", empty as "" }; diff --git a/Userland/Libraries/LibJS/Tests/modules/indirect-export-without-default.mjs b/Userland/Libraries/LibJS/Tests/modules/indirect-export-without-default.mjs new file mode 100644 index 0000000000..e6aa386731 --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/modules/indirect-export-without-default.mjs @@ -0,0 +1,3 @@ +// Since 'default-and-star-export-indirect.mjs' only contains an all-but-default re export of +// 'default-and-star-export.mjs' it should not have a default value. +import defaultExportIndirect from "./default-and-star-export-indirect.mjs"; diff --git a/Userland/Libraries/LibJS/Tests/modules/string-import-names.mjs b/Userland/Libraries/LibJS/Tests/modules/string-import-names.mjs new file mode 100644 index 0000000000..d61158f85a --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/modules/string-import-names.mjs @@ -0,0 +1,12 @@ +import { "*" as starImport, "" as emptyImport } from "./default-and-star-export.mjs"; + +import { + "*" as starImportIndirect, + "" as emptyImportIndirect, +} from "./default-and-star-export-indirect.mjs"; + +export const passed = + starImport === "starExportValue" && + starImportIndirect === "starExportValue" && + emptyImport === "empty" && + emptyImportIndirect === "empty"; diff --git a/Userland/Libraries/LibJS/Tests/modules/string-import-namespace-indirect.mjs b/Userland/Libraries/LibJS/Tests/modules/string-import-namespace-indirect.mjs new file mode 100644 index 0000000000..f203dd2d07 --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/modules/string-import-namespace-indirect.mjs @@ -0,0 +1,6 @@ +import * as indirectNs from "./default-and-star-export-indirect.mjs"; + +export const passed = + indirectNs["*"] === "starExportValue" && + indirectNs[""] === "empty" && + indirectNs.default === undefined; diff --git a/Userland/Libraries/LibJS/Tests/modules/string-import-namespace.mjs b/Userland/Libraries/LibJS/Tests/modules/string-import-namespace.mjs new file mode 100644 index 0000000000..c06777aae3 --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/modules/string-import-namespace.mjs @@ -0,0 +1,8 @@ +import * as ns from "./default-and-star-export.mjs"; +import defaultExport from "./default-and-star-export.mjs"; + +export const passed = + ns.default === "defaultValue" && + ns["*"] === "starExportValue" && + ns[""] === "empty" && + defaultExport === "defaultValue"; |