summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS/Tests/modules
diff options
context:
space:
mode:
authordavidot <davidot@serenityos.org>2022-01-27 01:54:47 +0100
committerLinus Groh <mail@linusgroh.de>2022-01-30 17:40:20 +0000
commite0e4ead2c829ce5af822624fa57ff6eddb3657dd (patch)
treef1c09f60c7f6e0e2aabdad3edf1e4703fac37ac6 /Userland/Libraries/LibJS/Tests/modules
parent8473f6caeec29513d870cf6475d02807d5135379 (diff)
downloadserenity-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')
-rw-r--r--Userland/Libraries/LibJS/Tests/modules/basic-modules.js62
-rw-r--r--Userland/Libraries/LibJS/Tests/modules/default-and-star-export-indirect.mjs2
-rw-r--r--Userland/Libraries/LibJS/Tests/modules/default-and-star-export.mjs6
-rw-r--r--Userland/Libraries/LibJS/Tests/modules/indirect-export-without-default.mjs3
-rw-r--r--Userland/Libraries/LibJS/Tests/modules/string-import-names.mjs12
-rw-r--r--Userland/Libraries/LibJS/Tests/modules/string-import-namespace-indirect.mjs6
-rw-r--r--Userland/Libraries/LibJS/Tests/modules/string-import-namespace.mjs8
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";