summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/modules/module-evaluation.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/modules/module-evaluation.js')
-rw-r--r--js/src/jit-test/tests/modules/module-evaluation.js94
1 files changed, 94 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/modules/module-evaluation.js b/js/src/jit-test/tests/modules/module-evaluation.js
new file mode 100644
index 000000000..eec13c040
--- /dev/null
+++ b/js/src/jit-test/tests/modules/module-evaluation.js
@@ -0,0 +1,94 @@
+// Exercise ModuleEvaluation() concrete method.
+
+load(libdir + "asserts.js");
+load(libdir + "dummyModuleResolveHook.js");
+
+function parseAndEvaluate(source) {
+ let m = parseModule(source);
+ m.declarationInstantiation();
+ return m.evaluation();
+}
+
+// Check the evaluation of an empty module succeeds.
+assertEq(typeof parseAndEvaluate(""), "undefined");
+
+// Check evaluation returns evaluation result the first time, then undefined.
+let m = parseModule("1");
+m.declarationInstantiation();
+assertEq(m.evaluation(), 1);
+assertEq(typeof m.evaluation(), "undefined");
+
+// Check top level variables are initialized by evaluation.
+m = parseModule("export var x = 2 + 2;");
+assertEq(typeof getModuleEnvironmentValue(m, "x"), "undefined");
+m.declarationInstantiation();
+m.evaluation();
+assertEq(getModuleEnvironmentValue(m, "x"), 4);
+
+m = parseModule("export let x = 2 * 3;");
+m.declarationInstantiation();
+m.evaluation();
+assertEq(getModuleEnvironmentValue(m, "x"), 6);
+
+// Set up a module to import from.
+let a = moduleRepo['a'] =
+parseModule(`var x = 1;
+ export { x };
+ export default 2;
+ export function f(x) { return x + 1; }`);
+
+// Check we can evaluate top level definitions.
+parseAndEvaluate("var foo = 1;");
+parseAndEvaluate("let foo = 1;");
+parseAndEvaluate("const foo = 1");
+parseAndEvaluate("function foo() {}");
+parseAndEvaluate("class foo { constructor() {} }");
+
+// Check we can evaluate all module-related syntax.
+parseAndEvaluate("export var foo = 1;");
+parseAndEvaluate("export let foo = 1;");
+parseAndEvaluate("export const foo = 1;");
+parseAndEvaluate("var x = 1; export { x };");
+parseAndEvaluate("export default 1");
+parseAndEvaluate("export default function() {};");
+parseAndEvaluate("export default function foo() {};");
+parseAndEvaluate("import a from 'a';");
+parseAndEvaluate("import { x } from 'a';");
+parseAndEvaluate("import * as ns from 'a';");
+parseAndEvaluate("export * from 'a'");
+parseAndEvaluate("export default class { constructor() {} };");
+parseAndEvaluate("export default class foo { constructor() {} };");
+
+// Test default import
+m = parseModule("import a from 'a'; a;")
+m.declarationInstantiation();
+assertEq(m.evaluation(), 2);
+
+// Test named import
+m = parseModule("import { x as y } from 'a'; y;")
+m.declarationInstantiation();
+assertEq(m.evaluation(), 1);
+
+// Call exported function
+m = parseModule("import { f } from 'a'; f(3);")
+m.declarationInstantiation();
+assertEq(m.evaluation(), 4);
+
+// Test importing an indirect export
+moduleRepo['b'] = parseModule("export { x as z } from 'a';");
+assertEq(parseAndEvaluate("import { z } from 'b'; z"), 1);
+
+// Test cyclic dependencies
+moduleRepo['c1'] = parseModule("export var x = 1; export {y} from 'c2'");
+moduleRepo['c2'] = parseModule("export var y = 2; export {x} from 'c1'");
+assertDeepEq(parseAndEvaluate(`import { x as x1, y as y1 } from 'c1';
+ import { x as x2, y as y2 } from 'c2';
+ [x1, y1, x2, y2]`),
+ [1, 2, 1, 2]);
+
+// Import access in functions
+m = parseModule("import { x } from 'a'; function f() { return x; }")
+m.declarationInstantiation();
+m.evaluation();
+let f = getModuleEnvironmentValue(m, "f");
+assertEq(f(), 1);