summaryrefslogtreecommitdiffstats
path: root/js/xpconnect/tests/unit/test_import_shim.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/xpconnect/tests/unit/test_import_shim.js377
1 files changed, 377 insertions, 0 deletions
diff --git a/js/xpconnect/tests/unit/test_import_shim.js b/js/xpconnect/tests/unit/test_import_shim.js
new file mode 100644
index 0000000000..3e265414f8
--- /dev/null
+++ b/js/xpconnect/tests/unit/test_import_shim.js
@@ -0,0 +1,377 @@
+add_task(function test_Cu_import_shim_first() {
+ // Load and cache with shim.
+
+ const exports = {};
+ const global = Components.utils.import(
+ "resource://test/esmified-1.jsm",
+ exports
+ );
+ Assert.equal(global.loadCount, 1);
+ Assert.equal(global.obj.value, 10);
+ Assert.equal(exports.loadCount, 1);
+ Assert.equal(exports.obj.value, 10);
+ Assert.ok(exports.obj === global.obj);
+
+ const ns = ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs");
+ Assert.equal(ns.loadCount, 1);
+ Assert.equal(ns.obj.value, 10);
+ Assert.ok(ns.obj === global.obj);
+
+ const exports2 = {};
+ const global2 = Components.utils.import(
+ "resource://test/esmified-1.jsm", exports2
+ );
+ Assert.equal(global2.loadCount, 1);
+ Assert.equal(global2.obj.value, 10);
+ Assert.equal(exports2.loadCount, 1);
+ Assert.equal(exports2.obj.value, 10);
+ Assert.ok(exports2.obj === global2.obj);
+ Assert.ok(exports2.obj === global.obj);
+
+ // Also test with *.js extension.
+ const exports3 = {};
+ const global3 = Components.utils.import(
+ "resource://test/esmified-1.js", exports3
+ );
+ Assert.equal(global3.loadCount, 1);
+ Assert.equal(global3.obj.value, 10);
+ Assert.equal(exports3.loadCount, 1);
+ Assert.equal(exports3.obj.value, 10);
+ Assert.ok(exports3.obj === global3.obj);
+ Assert.ok(exports3.obj === global.obj);
+
+ // Also test with *.jsm.js extension.
+ const exports4 = {};
+ const global4 = Components.utils.import(
+ "resource://test/esmified-1.js", exports4
+ );
+ Assert.equal(global4.loadCount, 1);
+ Assert.equal(global4.obj.value, 10);
+ Assert.equal(exports4.loadCount, 1);
+ Assert.equal(exports4.obj.value, 10);
+ Assert.ok(exports4.obj === global4.obj);
+ Assert.ok(exports4.obj === global.obj);
+});
+
+add_task(function test_Cu_import_no_shim_first() {
+ // Load and cache with importESModule.
+
+ const ns = ChromeUtils.importESModule("resource://test/esmified-2.sys.mjs");
+ Assert.equal(ns.loadCount, 1);
+ Assert.equal(ns.obj.value, 10);
+
+ const exports = {};
+ const global = Components.utils.import(
+ "resource://test/esmified-2.jsm", exports
+ );
+ Assert.equal(global.loadCount, 1);
+ Assert.equal(global.obj.value, 10);
+ Assert.equal(exports.loadCount, 1);
+ Assert.equal(exports.obj.value, 10);
+ Assert.ok(exports.obj === global.obj);
+ Assert.ok(ns.obj === global.obj);
+
+ const ns2 = ChromeUtils.importESModule("resource://test/esmified-2.sys.mjs");
+ Assert.equal(ns2.loadCount, 1);
+ Assert.equal(ns2.obj.value, 10);
+});
+
+add_task(function test_ChromeUtils_import_shim_first() {
+ // Load and cache with shim.
+
+ const exports = {};
+ const global = ChromeUtils.import(
+ "resource://test/esmified-3.jsm", exports
+ );
+ Assert.equal(global.loadCount, 1);
+ Assert.equal(global.obj.value, 10);
+ Assert.equal(exports.loadCount, 1);
+ Assert.equal(exports.obj.value, 10);
+ Assert.ok(exports.obj === global.obj);
+
+ const ns = ChromeUtils.importESModule("resource://test/esmified-3.sys.mjs");
+ Assert.equal(ns.loadCount, 1);
+ Assert.equal(ns.obj.value, 10);
+ Assert.ok(ns.obj === global.obj);
+
+ const exports2 = {};
+ const global2 = ChromeUtils.import(
+ "resource://test/esmified-3.jsm", exports2
+ );
+ Assert.equal(global2.loadCount, 1);
+ Assert.equal(global2.obj.value, 10);
+ Assert.equal(exports2.loadCount, 1);
+ Assert.equal(exports2.obj.value, 10);
+ Assert.ok(exports2.obj === global2.obj);
+ Assert.ok(exports2.obj === global.obj);
+});
+
+add_task(function test_ChromeUtils_import_no_shim_first() {
+ // Load and cache with importESModule.
+
+ const ns = ChromeUtils.importESModule("resource://test/esmified-4.sys.mjs");
+ Assert.equal(ns.loadCount, 1);
+ Assert.equal(ns.obj.value, 10);
+
+ const exports = {};
+ const global = ChromeUtils.import(
+ "resource://test/esmified-4.jsm", exports
+ );
+ Assert.equal(global.loadCount, 1);
+ Assert.equal(global.obj.value, 10);
+ Assert.equal(exports.loadCount, 1);
+ Assert.equal(exports.obj.value, 10);
+ Assert.ok(exports.obj === global.obj);
+ Assert.ok(ns.obj === global.obj);
+
+ const ns2 = ChromeUtils.importESModule("resource://test/esmified-4.sys.mjs");
+ Assert.equal(ns2.loadCount, 1);
+ Assert.equal(ns2.obj.value, 10);
+});
+
+add_task(function test_ChromeUtils_import_not_exported_no_shim_JSM() {
+ // `exports` properties for not-ESM-ified case.
+
+ const exports = ChromeUtils.import(
+ "resource://test/not-esmified-not-exported.jsm"
+ );
+
+ Assert.equal(exports.exportedVar, "exported var");
+ Assert.equal(exports.exportedFunction(), "exported function");
+ Assert.equal(exports.exportedLet, "exported let");
+ Assert.equal(exports.exportedConst, "exported const");
+ Assert.equal(exports.notExportedVar, undefined);
+ Assert.equal(exports.notExportedFunction, undefined);
+ Assert.equal(exports.notExportedLet, undefined);
+ Assert.equal(exports.notExportedConst, undefined);
+});
+
+add_task(function test_ChromeUtils_import_not_exported_shim() {
+ // `exports` properties for shim case.
+
+ const exports = ChromeUtils.import(
+ "resource://test/esmified-not-exported.jsm"
+ );
+
+ Assert.equal(exports.exportedVar, "exported var");
+ Assert.equal(exports.exportedFunction(), "exported function");
+ Assert.equal(exports.exportedLet, "exported let");
+ Assert.equal(exports.exportedConst, "exported const");
+ Assert.equal(exports.notExportedVar, undefined);
+ Assert.equal(exports.notExportedFunction, undefined);
+ Assert.equal(exports.notExportedLet, undefined);
+ Assert.equal(exports.notExportedConst, undefined);
+});
+
+add_task(function test_ChromeUtils_import_not_exported_no_shim_ESM() {
+ // `exports` properties for ESM-ified case.
+
+ const exports = ChromeUtils.importESModule(
+ "resource://test/esmified-not-exported.sys.mjs"
+ );
+
+ Assert.equal(exports.exportedVar, "exported var");
+ Assert.equal(exports.exportedFunction(), "exported function");
+ Assert.equal(exports.exportedLet, "exported let");
+ Assert.equal(exports.exportedConst, "exported const");
+ Assert.equal(exports.notExportedVar, undefined);
+ Assert.equal(exports.notExportedFunction, undefined);
+ Assert.equal(exports.notExportedLet, undefined);
+ Assert.equal(exports.notExportedConst, undefined);
+});
+
+function testReadProxyOps(global, expectedNames, expectedDesc) {
+ expectedNames.sort();
+
+ // enumerate
+ const names = Object.keys(global).sort();
+ Assert.equal(JSON.stringify(names), JSON.stringify(expectedNames),
+ `enumerate`);
+
+ // has
+ for (const name of expectedNames) {
+ Assert.ok(name in global, `has for ${name}`);
+ }
+
+ // getOwnPropertyDescriptor
+ for (const name of expectedNames) {
+ const desc = Object.getOwnPropertyDescriptor(global, name);
+ Assert.equal(desc.value, global[name]);
+ Assert.equal(desc.writable, expectedDesc.writable,
+ `writable for ${name}`);
+ Assert.equal(desc.enumerable, expectedDesc.enumerable,
+ `enumerable for ${name}`);
+ Assert.equal(desc.configurable, expectedDesc.configurable,
+ `configurable for ${name}`);
+ }
+}
+
+function testWriteProxyOps(global, expectedNames) {
+ // set: no-op
+ for (const name of expectedNames) {
+ const before = global[name];
+ global[name] = -1;
+ Assert.equal(global[name], before, `value after set for ${name}`);
+ }
+
+ // delete: no-op
+ for (const name of expectedNames) {
+ const before = global[name];
+ Assert.ok(!(delete global[name]), `delete result for ${name}`);
+ Assert.equal(global[name], before, `value after delete for ${name}`);
+ }
+}
+
+add_task(function test_Cu_import_not_exported_no_shim_JSM() {
+ // `exports` and `global` properties for not-ESM-ified case.
+ // Not-exported variables should be visible in `global`.
+
+ const exports = {};
+ const global = Components.utils.import(
+ "resource://test/not-esmified-not-exported.jsm",
+ exports
+ );
+
+ Assert.equal(global.exportedVar, "exported var");
+ Assert.equal(global.exportedFunction(), "exported function");
+ Assert.equal(global.exportedLet, "exported let");
+ Assert.equal(global.exportedConst, "exported const");
+ Assert.equal(global.notExportedVar, "not exported var");
+ Assert.equal(global.notExportedFunction(), "not exported function");
+ Assert.equal(global.notExportedLet, "not exported let");
+ Assert.equal(global.notExportedConst, "not exported const");
+
+ const expectedNames = [
+ "EXPORTED_SYMBOLS",
+ "exportedVar",
+ "exportedFunction",
+ "exportedLet",
+ "exportedConst",
+ "notExportedVar",
+ "notExportedFunction",
+ "notExportedLet",
+ "notExportedConst",
+ ];
+
+ testReadProxyOps(global, expectedNames, {
+ writable: false,
+ enumerable: true,
+ configurable: false,
+ });
+ testWriteProxyOps(global, expectedNames);
+
+ Assert.equal(exports.exportedVar, "exported var");
+ Assert.equal(exports.exportedFunction(), "exported function");
+ Assert.equal(exports.exportedLet, "exported let");
+ Assert.equal(exports.exportedConst, "exported const");
+ Assert.equal(exports.notExportedVar, undefined);
+ Assert.equal(exports.notExportedFunction, undefined);
+ Assert.equal(exports.notExportedLet, undefined);
+ Assert.equal(exports.notExportedConst, undefined);
+});
+
+add_task(function test_Cu_import_not_exported_shim() {
+ // `exports` and `global` properties for shim case.
+ // Not-exported variables should be visible in global.
+
+ const exports = {};
+ const global = Components.utils.import(
+ "resource://test/esmified-not-exported.jsm",
+ exports
+ );
+
+ Assert.equal(global.exportedVar, "exported var");
+ Assert.equal(global.exportedFunction(), "exported function");
+ Assert.equal(global.exportedLet, "exported let");
+ Assert.equal(global.exportedConst, "exported const");
+
+ Assert.equal(global.notExportedVar, "not exported var");
+ Assert.equal(global.notExportedFunction(), "not exported function");
+ Assert.equal(global.notExportedLet, "not exported let");
+ Assert.equal(global.notExportedConst, "not exported const");
+
+ const expectedNames = [
+ "exportedVar",
+ "exportedFunction",
+ "exportedLet",
+ "exportedConst",
+ "notExportedVar",
+ "notExportedFunction",
+ "notExportedLet",
+ "notExportedConst",
+ ];
+
+ testReadProxyOps(global, expectedNames, {
+ writable: false,
+ enumerable: true,
+ configurable: false,
+ });
+ testWriteProxyOps(global, expectedNames);
+
+ Assert.equal(exports.exportedVar, "exported var");
+ Assert.equal(exports.exportedFunction(), "exported function");
+ Assert.equal(exports.exportedLet, "exported let");
+ Assert.equal(exports.exportedConst, "exported const");
+ Assert.equal(exports.notExportedVar, undefined);
+ Assert.equal(exports.notExportedFunction, undefined);
+ Assert.equal(exports.notExportedLet, undefined);
+ Assert.equal(exports.notExportedConst, undefined);
+
+ const desc = Object.getOwnPropertyDescriptor(global, "*namespace*");
+ Assert.ok(!desc, `*namespace* special binding should not be exposed`);
+ Assert.equal("*namespace*" in global, false,
+ `*namespace* special binding should not be exposed`);
+ Assert.equal(global["*namespace*"], undefined,
+ `*namespace* special binding should not be exposed`);
+});
+
+add_task(function test_Cu_isModuleLoaded_shim() {
+ Assert.equal(Cu.isModuleLoaded("resource://test/esmified-5.jsm"), false);
+ Assert.equal(Cu.isModuleLoaded("resource://test/esmified-5.js"), false);
+ Assert.equal(Cu.isModuleLoaded("resource://test/esmified-5.jsm.js"), false);
+ Assert.equal(Cu.loadedModules.includes("resource://test/esmified-5.jsm"), false);
+ Assert.equal(Cu.isModuleLoaded("resource://test/esmified-5.sys.mjs"), false);
+ Assert.equal(Cu.loadedModules.includes("resource://test/esmified-5.sys.mjs"), false);
+
+ Cu.import("resource://test/esmified-5.jsm", {});
+
+ Assert.equal(Cu.isModuleLoaded("resource://test/esmified-5.jsm"), true);
+ Assert.equal(Cu.isModuleLoaded("resource://test/esmified-5.js"), true);
+ Assert.equal(Cu.isModuleLoaded("resource://test/esmified-5.jsm.js"), true);
+ Assert.equal(Cu.loadedModules.includes("resource://test/esmified-5.jsm"), true);
+
+ // This is false because Cu.isModuleLoaded does not support ESM directly
+ // (bug 1768819)
+ Assert.equal(Cu.isModuleLoaded("resource://test/esmified-5.sys.mjs"), false);
+ Assert.equal(Cu.loadedModules.includes("resource://test/esmified-5.sys.mjs"), false);
+});
+
+add_task(function test_Cu_isModuleLoaded_no_shim() {
+ Assert.equal(Cu.isModuleLoaded("resource://test/esmified-6.jsm"), false);
+ Assert.equal(Cu.isModuleLoaded("resource://test/esmified-6.js"), false);
+ Assert.equal(Cu.isModuleLoaded("resource://test/esmified-6.jsm.js"), false);
+ Assert.equal(Cu.loadedModules.includes("resource://test/esmified-6.jsm"), false);
+ Assert.equal(Cu.loadedModules.includes("resource://test/esmified-6.js"), false);
+ Assert.equal(Cu.loadedModules.includes("resource://test/esmified-6.jsm.js"), false);
+ Assert.equal(Cu.isModuleLoaded("resource://test/esmified-6.sys.mjs"), false);
+ Assert.equal(Cu.loadedModules.includes("resource://test/esmified-6.sys.mjs"), false);
+
+ ChromeUtils.importESModule("resource://test/esmified-6.sys.mjs");
+
+ // Regardless of whether the ESM is loaded by shim or not,
+ // query that accesses the ESM-ified module returns the existence of
+ // ESM.
+ Assert.equal(Cu.isModuleLoaded("resource://test/esmified-6.jsm"), true);
+ Assert.equal(Cu.isModuleLoaded("resource://test/esmified-6.js"), true);
+ Assert.equal(Cu.isModuleLoaded("resource://test/esmified-6.jsm.js"), true);
+ Assert.equal(Cu.loadedModules.includes("resource://test/esmified-6.jsm"), true);
+
+ // This is false because shim always use *.jsm.
+ Assert.equal(Cu.loadedModules.includes("resource://test/esmified-6.js"), false);
+ Assert.equal(Cu.loadedModules.includes("resource://test/esmified-6.jsm.js"), false);
+
+ // This is false because Cu.isModuleLoaded does not support ESM directly
+ // (bug 1768819)
+ Assert.equal(Cu.isModuleLoaded("resource://test/esmified-6.sys.mjs"), false);
+ Assert.equal(Cu.loadedModules.includes("resource://test/esmified-6.sys.mjs"), false);
+});