summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/mime/jsmime/test/unit/head_xpcshell_glue.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mailnews/mime/jsmime/test/unit/head_xpcshell_glue.js')
-rw-r--r--comm/mailnews/mime/jsmime/test/unit/head_xpcshell_glue.js176
1 files changed, 176 insertions, 0 deletions
diff --git a/comm/mailnews/mime/jsmime/test/unit/head_xpcshell_glue.js b/comm/mailnews/mime/jsmime/test/unit/head_xpcshell_glue.js
new file mode 100644
index 0000000000..6f7fca89f1
--- /dev/null
+++ b/comm/mailnews/mime/jsmime/test/unit/head_xpcshell_glue.js
@@ -0,0 +1,176 @@
+// This file needs to contain glue to rephrase the Mocha testsuite framework in
+// a way that the xpcshell test suite can understand.
+
+var { Assert } = ChromeUtils.importESModule(
+ "resource://testing-common/Assert.sys.mjs"
+);
+var requireCache = new Map();
+
+// Preload an assert module
+var assert = new Assert();
+assert.doesNotThrow = function (block, message) {
+ message = message ? " " + message : ".";
+ try {
+ block();
+ } catch (e) {
+ this.report(true, e, null, "Got unwanted exception" + message);
+ }
+};
+requireCache.set("assert", assert);
+
+// Preload an fs module
+var fs = {
+ readFile(filename, options, callback) {
+ if (callback === undefined) {
+ callback = options;
+ options = {};
+ }
+
+ // Convert according to encoding. For the moment, we don't support this
+ // node.js feature in the shim since we don't need to.
+ var translator = contents => contents;
+ if (options !== undefined && "encoding" in options) {
+ translator = function () {
+ throw new Error("I can't do this!");
+ };
+ }
+
+ Promise.resolve(filename)
+ .then(do_get_file)
+ .then(file => IOUtils.read(file.path))
+ .then(translator)
+ .then(contents => callback(undefined, contents), callback);
+ },
+};
+requireCache.set("fs", fs);
+var { jsmime } = ChromeUtils.import("resource:///modules/jsmime.jsm");
+requireCache.set("jsmime", jsmime);
+
+function require(path) {
+ if (requireCache.has(path)) {
+ return requireCache.get(path);
+ }
+
+ let file;
+ if (path.startsWith("test/")) {
+ let name = path.substring("test/".length);
+ file = "resource://testing-common/jsmime/" + name + ".js";
+ } else {
+ file = "resource:///modules/jsmime/" + path + ".js";
+ }
+
+ var globalObject = {
+ define: innerDefine.bind(this, path),
+ };
+ Services.scriptloader.loadSubScript(file, globalObject);
+ return requireCache.get(path);
+}
+
+function innerDefine(moduleName, dfn) {
+ if (typeof dfn !== "function") {
+ throw new Error("What is going on here?");
+ }
+ function resolvingRequire(path) {
+ if (path.startsWith("./")) {
+ path = path.substring(2);
+ }
+ return require(path);
+ }
+ var result = dfn(resolvingRequire);
+ requireCache.set(moduleName, result);
+}
+
+var define = innerDefine.bind(this, "xpcshell-test");
+
+// Mocha TDD UI Bindings
+// ---------------------
+
+/**
+ * A block of tests, from the suite class.
+ */
+function MochaSuite(name) {
+ this.name = name;
+ this.setup = [];
+ this.tests = [];
+ this.teardown = [];
+ this.suites = [];
+}
+
+// The real code for running a suite of tests, written as async function.
+MochaSuite.prototype._runSuite = async function () {
+ info("Running suite " + this.name);
+ for (let setup_ of this.setup) {
+ await runFunction(setup_);
+ }
+ for (let test_ of this.tests) {
+ info("Running test " + test_.name);
+ await runFunction(test_.test);
+ }
+ for (let suite_ of this.suites) {
+ await suite_.runSuite();
+ }
+ for (let fn of this.teardown) {
+ await runFunction(fn);
+ }
+ info("Finished suite " + this.name);
+};
+
+// The outer call to run a test suite, which returns a promise of completion.
+MochaSuite.prototype.runSuite = function () {
+ return this._runSuite();
+};
+
+// Run the given function, returning a promise of when the test will complete.
+function runFunction(fn) {
+ let completed = new Promise(function (resolve, reject) {
+ function onEnd(error) {
+ if (error !== undefined) {
+ reject(error);
+ } else {
+ resolve();
+ }
+ }
+ // If the function is expecting an argument, that argument is the callback
+ // above. If it's not, then it may be returning a promise.
+ if (fn.length == 1) {
+ fn(onEnd);
+ } else {
+ // Promise.resolve nicely handles both promises and not-promise values for
+ // us.
+ resolve(fn());
+ }
+ });
+ return completed;
+}
+
+var currentSuite = new MochaSuite("");
+function suite(name, tests) {
+ name = name.toString();
+ if (/[\x80-]/.exec(name)) {
+ name = "<unprintable name>";
+ }
+ let suiteParent = currentSuite;
+ currentSuite = new MochaSuite(name);
+ suiteParent.suites.push(currentSuite);
+ tests();
+ currentSuite = suiteParent;
+}
+function test(name, block) {
+ name = name.toString();
+ if (/[\x80-]/.exec(name)) {
+ name = "<unprintable name>";
+ }
+ currentSuite.tests.push({ name, test: block });
+}
+function setup(block) {
+ currentSuite.setup.push(block);
+}
+function teardown(block) {
+ currentSuite.teardown.push(block);
+}
+
+// The actual binding xpcshell needs to do its work.
+function run_test() {
+ add_task(() => currentSuite.runSuite());
+ run_next_test();
+}