Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: browsertests.js

Issue 29373596: Issue 4838 - Use nodeunit framework for integration tests running in browser (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore
Patch Set: Isolate module scopes to avoid naming conflicts Created Jan. 25, 2017, 9:53 a.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | package.json » ('j') | package.json » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: browsertests.js
===================================================================
new file mode 100644
--- /dev/null
+++ b/browsertests.js
@@ -0,0 +1,179 @@
+/*
+ * This file is part of Adblock Plus <https://adblockplus.org/>,
+ * Copyright (C) 2006-2016 Eyeo GmbH
Felix Dahlke 2017/01/30 14:37:58 It's 2017 :)
Wladimir Palant 2017/02/24 09:18:55 Yes, but the copyright header hasn't been updated
Felix Dahlke 2017/02/24 10:43:38 :)
+ *
+ * Adblock Plus is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Adblock Plus is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+"use strict";
+
+(function()
+{
+ // TODO: This should use promises once PhantomJS supports them, this will make
Felix Dahlke 2017/01/30 14:37:58 Could you reference issue 4796 here? In the other
Wladimir Palant 2017/02/24 09:18:55 Done.
+ // wrapping all async calls in order to catch errors unnecessary.
+ function safeCall(callback)
Felix Dahlke 2017/01/30 14:37:58 Have you considered using phantom.onError instead?
Wladimir Palant 2017/02/24 09:18:55 I was using that originally, it wasn't catching al
Felix Dahlke 2017/02/24 10:43:38 Acknowledged.
+ {
+ return function()
+ {
+ try
+ {
+ callback.apply(this, arguments);
+ }
+ catch (e)
+ {
+ var message = String(e);
+ if (e.stack)
+ message += "\n" + e.stack;
+ console.log(message);
Felix Dahlke 2017/01/30 14:37:58 Since it's an error message, how about console.err
Wladimir Palant 2017/02/24 09:18:55 nodeunit prints all output via console.log(), incl
Felix Dahlke 2017/02/24 10:43:39 Acknowledged.
+ phantom.exit();
Felix Dahlke 2017/01/30 14:37:58 phantom.exit(1) in this case?
Wladimir Palant 2017/02/24 09:18:55 Done.
+ }
+ }
Felix Dahlke 2017/01/30 14:37:58 Missing semicolon?
Wladimir Palant 2017/02/24 09:18:55 Done.
+ }
+
+ function loadScript(doc, url, callback)
+ {
+ var script = doc.createElement("script");
+ script.src = url;
+ script.async = false;
+ doc.head.appendChild(script);
+ if (callback)
+ window.setTimeout(callback, 0);
+ }
+
+ function run()
Felix Dahlke 2017/01/30 14:37:58 Nit: Move this below runTests() to have the functi
Wladimir Palant 2017/02/24 09:18:55 Done.
+ {
+ var system = require("system");
+ var nodeunitUrl = system.args[1];
+ var urls = system.args.slice(2);
+
+ loadScript(document, nodeunitUrl, safeCall(function()
+ {
+ loadModules(urls, safeCall(function(modules)
+ {
+ runTests(modules, function()
+ {
+ phantom.exit();
+ });
+ }));
+ }));
+ }
+
+ function loadModules(urls, callback)
+ {
+ var modules = {};
+
+ var loadNext = safeCall(function()
+ {
+ if (urls.length)
+ {
+ // Load each module into a new frame so that their scopes don't clash
+ var frame = document.createElement("iframe");
+ document.body.appendChild(frame);
+
+ var wnd = frame.contentWindow;
+ wnd.loadScript = loadScript.bind(null, wnd.document);
+ wnd.console = console;
+ wnd.require = require;
+ wnd.exports = {};
+ wnd.module = {exports: wnd.exports};
+
+ var url = urls.shift();
+ var name = url.split("/").pop();
+ wnd.loadScript(url, safeCall(function()
+ {
+ modules[name] = nodeunit.testCase(wnd.module.exports);
+ loadNext();
+ }));
+ }
+ else
+ callback(modules);
+ });
+
+ loadNext();
+ }
+
+ function runTests(modules, callback)
+ {
+ function bold(str)
+ {
+ return "\u001B[1m" + str + "\u001B[22m";
+ }
+
+ function ok(str)
+ {
+ return "\u001B[32m" + str + "\u001B[39m";
+ }
+
+ function error(str)
+ {
+ return "\u001B[31m" + str + "\u001B[39m";
+ }
+
+ nodeunit.runModules(modules, {
+ moduleStart: function(name)
+ {
+ console.log(bold(name));
+ },
+ testDone: function(name, assertions)
+ {
+ var errors = assertions.filter(function(assertion)
+ {
+ return assertion.failed();
+ }).map(function(assertion)
+ {
+ return assertion.error;
+ });
+
+ if (errors.length == 0)
+ console.log("\u2714 " + name);
+ else
+ {
+ console.log(error("\u2716 " + name) + "\n");
+ errors.forEach(function(error)
+ {
+ console.log(String(error));
+ if (error.stack)
+ console.log(error.stack);
+ console.log("");
+ })
+ }
+ },
+ done: function(assertions)
+ {
+ var failures = assertions.filter(function(assertion)
+ {
+ return assertion.failed();
+ });
+ if (failures.length)
+ {
+ console.log(
+ "\n" +
+ bold(error("FAILURES: ")) +
+ failures.length + "/" + assertions.length + " assertions failed"
+ );
+ }
+ else
+ {
+ console.log(
+ "\n" + bold(ok("OK: ")) +
+ assertions.length + " assertions"
+ );
+ }
+
+ callback();
+ }
+ });
+ }
+
+ safeCall(run)();
+})();
« no previous file with comments | « no previous file | package.json » ('j') | package.json » ('J')

Powered by Google App Engine
This is Rietveld