Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Bug 791577: Support "test addons" #575

Merged
merged 6 commits into from

2 participants

ochameau Erik Vold
ochameau
Owner

More detail in bugzilla:
https://bugzilla.mozilla.org/show_bug.cgi?id=791577

Note that this pull request is splitted in mutliple meaningfull commits in order to help the review.

Erik Vold
Owner

@ochameau the test l10n addon just hangs on Fennec. I made another add-on simple add-on for simple-prefs and that one works tho.

ochameau
Owner

The original l10n tests wasn't working on Fennec, because of PageWorker usage:
https://github.com/erikvold/jetpack-sdk/blob/8c57bacb22e7f42b514bee5d26f503cdb395dec0/test-addons/l10n/main.js#L97

ochameau
Owner

Would you mind addressing this in a followup patch, as it isn't related to this feature?

Erik Vold
Owner

sure
r+

ochameau ochameau merged commit 57ca4fe into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
15 packages/api-utils/lib/test/assert.js
View
@@ -63,7 +63,20 @@ function Assert(logger) {
}
Assert.prototype = {
fail: function fail(e) {
- this._log.fail(e.message);
+ if (!e || typeof(e) !== 'object') {
+ this._log.fail(e);
+ return;
+ }
+ let message = e.message;
+ if ('operator' in e) {
+ message += [
+ " -",
+ source(e.expected),
+ e.operator,
+ source(e.actual)
+ ].join(" ");
+ }
+ this._log.fail(message);
},
pass: function pass(message) {
this._log.pass(message);
10 packages/api-utils/lib/unit-test-finder.js
View
@@ -23,14 +23,6 @@ var TestFinder = exports.TestFinder = function TestFinder(options) {
};
TestFinder.prototype = {
- _makeTest: function _makeTest(suite, name, test) {
- function runTest(runner) {
- console.info("executing '" + suite + "." + name + "'");
- test(runner);
- }
- return runTest;
- },
-
findTests: function findTests(cb) {
var self = this;
var tests = [];
@@ -67,7 +59,7 @@ TestFinder.prototype = {
tests.push({
setup: module.setup,
teardown: module.teardown,
- testFunction: self._makeTest(suite, name, module[name]),
+ testFunction: module[name],
name: suite + "." + name
});
}
2  packages/api-utils/lib/unit-test.js
View
@@ -436,6 +436,8 @@ TestRunner.prototype = {
this.testFailureLogged = false;
try {
+ this.console.info("executing '" + this.test.name + "'");
+
if(this.test.setup) {
this.test.setup(this);
}
3  packages/api-utils/tests/test-unit-test.js
View
@@ -139,6 +139,9 @@ exports.testWaitUntilTimeoutInCallback = function(test) {
" assertion callback: '" + arguments[1] + "'");
}
},
+ info: function (msg) {
+ test.assertEqual(msg, "executing 'wait4ever'");
+ },
trace: function () {}
}
});
26 packages/test-harness/lib/harness.js
View
@@ -23,15 +23,15 @@ var print;
// How many more times to run all tests.
var iterationsLeft;
-// Only tests in files whose names match this regexp filter will be run.
-var filter;
-
// Whether to report memory profiling information.
var profileMemory;
// Whether we should stop as soon as a test reports a failure.
var stopOnError;
+// Function to call to retrieve a list of tests to execute
+var findAndRunTests;
+
// Combined information from all test runs.
var results = {
passed: 0,
@@ -163,9 +163,6 @@ function showResults() {
);
}
- print("\n");
- var total = results.passed + results.failed;
- print(results.passed + " of " + total + " tests passed.\n");
onDone(results);
}
@@ -231,14 +228,10 @@ function nextIteration(tests) {
}
if (iterationsLeft && (!stopOnError || results.failed == 0)) {
- let require = loader.require;
- require("api-utils/unit-test").findAndRunTests({
- testOutOfProcess: false,
- testInProcess: true,
- stopOnError: stopOnError,
- filter: filter,
- onDone: nextIteration
- });
+ // Pass the loader which has a hooked console that doesn't dispatch
+ // errors to the JS console and avoid firing false alarm in our
+ // console listener
+ findAndRunTests(loader, nextIteration);
}
else {
require("api-utils/timer").setTimeout(cleanup, 0);
@@ -288,11 +281,11 @@ function TestRunnerConsole(base, options) {
var runTests = exports.runTests = function runTests(options) {
iterationsLeft = options.iterations;
- filter = options.filter;
profileMemory = options.profileMemory;
stopOnError = options.stopOnError;
onDone = options.onDone;
print = options.print;
+ findAndRunTests = options.findAndRunTests;
try {
cService.registerListener(consoleListener);
@@ -300,7 +293,8 @@ var runTests = exports.runTests = function runTests(options) {
var ptc = require("api-utils/plain-text-console");
var url = require("api-utils/url");
var system = require("api-utils/system");
-
+ require("api-utils/unit-test");
+ require("api-utils/test");
print("Running tests on " + system.name + " " + system.version +
"/Gecko " + system.platformVersion + " (" +
system.id + ") under " +
72 packages/test-harness/lib/run-tests.js
View
@@ -9,7 +9,7 @@ var { exit, stdout } = require("api-utils/system");
var cfxArgs = require("@test/options");
var { Cc, Ci} = require("chrome");
-function runTests(iterations, filter, profileMemory, stopOnError, verbose, exit, print) {
+function runTests(findAndRunTests) {
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Ci.nsIWindowWatcher);
@@ -25,13 +25,17 @@ function runTests(iterations, filter, profileMemory, stopOnError, verbose, exit,
var harness = require("./harness");
function onDone(tests) {
+ stdout.write("\n");
+ var total = tests.passed + tests.failed;
+ stdout.write(tests.passed + " of " + total + " tests passed.\n");
+
window.close();
if (tests.failed == 0) {
if (tests.passed === 0)
- print("No tests were run\n");
+ stdout.write("No tests were run\n");
exit(0);
} else {
- printFailedTests(tests, verbose, print);
+ printFailedTests(tests, cfxArgs.verbose, stdout.write);
exit(1);
}
};
@@ -50,13 +54,16 @@ function runTests(iterations, filter, profileMemory, stopOnError, verbose, exit,
// For ex: nsIFocusManager.getFocusedElementForWindow may throw
// NS_ERROR_ILLEGAL_VALUE exception.
require("timer").setTimeout(function () {
- harness.runTests({iterations: iterations,
- filter: filter,
- profileMemory: profileMemory,
- stopOnError: stopOnError,
- verbose: verbose,
- print: print,
- onDone: onDone});
+ harness.runTests({
+ findAndRunTests: findAndRunTests,
+ iterations: cfxArgs.iterations || 1,
+ filter: cfxArgs.filter,
+ profileMemory: cfxArgs.profileMemory,
+ stopOnError: cfxArgs.stopOnError,
+ verbose: cfxArgs.verbose,
+ print: stdout.write,
+ onDone: onDone
+ });
}, 0);
}, true);
window.focus();
@@ -93,10 +100,51 @@ function main() {
if (!testsStarted) {
testsStarted = true;
- runTests(cfxArgs.iterations, cfxArgs.filter, cfxArgs.profileMemory,
- cfxArgs.stopOnError, cfxArgs.verbose, exit, stdout.write);
+ runTests(function findAndRunTests(loader, nextIteration) {
+ loader.require("api-utils/unit-test").findAndRunTests({
+ testOutOfProcess: false,
+ testInProcess: true,
+ stopOnError: cfxArgs.stopOnError,
+ filter: cfxArgs.filter,
+ onDone: nextIteration
+ });
+ });
}
};
if (require.main === module)
main();
+
+exports.runTestsFromModule = function runTestsFromModule(module) {
+ let id = module.id;
+ // Make a copy of exports as it may already be frozen by module loader
+ let exports = {};
+ Object.keys(module.exports).forEach(function(key) {
+ exports[key] = module.exports[key];
+ });
+
+ runTests(function findAndRunTests(loader, nextIteration) {
+ // Consider that all these tests are CommonJS ones
+ loader.require('api-utils/test').run(exports);
+
+ // Reproduce what is done in unit-test-finder.findTests()
+ let tests = [];
+ for each (let name in Object.keys(exports).sort()) {
+ tests.push({
+ setup: exports.setup,
+ teardown: exports.teardown,
+ testFunction: exports[name],
+ name: id + "." + name
+ });
+ }
+
+ // Reproduce what is done by unit-test.findAndRunTests()
+ var { TestRunner } = loader.require("api-utils/unit-test");
+ var runner = new TestRunner();
+ runner.startMany({
+ tests: tests,
+ stopOnError: cfxArgs.stopOnError,
+ onDone: nextIteration
+ });
+ });
+}
36 python-lib/cuddlefish/__init__.py
View
@@ -339,6 +339,15 @@ def test_all(env_root, defaults):
fail = (e.code != 0) or fail
if not fail or not defaults.get("stopOnError"):
+ print >>sys.stderr, "Testing all unit-test addons..."
+ sys.stderr.flush()
+
+ try:
+ test_all_testaddons(env_root, defaults)
+ except SystemExit, e:
+ fail = (e.code != 0) or fail
+
+ if not fail or not defaults.get("stopOnError"):
print >>sys.stderr, "Testing all packages..."
sys.stderr.flush()
try:
@@ -365,6 +374,30 @@ def test_cfx(env_root, verbose):
sys.stdout.flush(); sys.stderr.flush()
return retval
+def test_all_testaddons(env_root, defaults):
+ addons_dir = os.path.join(env_root, "test", "addons")
+ addons = [dirname for dirname in os.listdir(addons_dir)
+ if os.path.isdir(os.path.join(addons_dir, dirname))]
+ addons.sort()
+ fail = False
+ for dirname in addons:
+ print >>sys.stderr, "Testing %s..." % dirname
+ sys.stderr.flush()
+ try:
+ run(arguments=["run",
+ "--pkgdir",
+ os.path.join(addons_dir, dirname)],
+ defaults=defaults,
+ env_root=env_root)
+ except SystemExit, e:
+ fail = (e.code != 0) or fail
+ if fail and defaults.get("stopOnError"):
+ break
+
+ if fail:
+ print >>sys.stderr, "Some test addons tests were unsuccessful."
+ sys.exit(-1)
+
def test_all_examples(env_root, defaults):
examples_dir = os.path.join(env_root, "examples")
examples = [dirname for dirname in os.listdir(examples_dir)
@@ -521,6 +554,9 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None,
if command == "testpkgs":
test_all_packages(env_root, defaults=options.__dict__)
return
+ elif command == "testaddons":
+ test_all_testaddons(env_root, defaults=options.__dict__)
+ return
elif command == "testex":
test_all_examples(env_root, defaults=options.__dict__)
return
0  packages/addon-kit/data/test-localization.html → test/addons/l10n/data/test-localization.html
View
File renamed without changes
0  packages/addon-kit/locale/en-GB.properties → test/addons/l10n/locale/en-GB.properties
View
File renamed without changes
0  packages/addon-kit/locale/eo.properties → test/addons/l10n/locale/eo.properties
View
File renamed without changes
0  packages/addon-kit/locale/fr-FR.properties → test/addons/l10n/locale/fr-FR.properties
View
File renamed without changes
93 packages/addon-kit/tests/test-l10n.js → test/addons/l10n/main.js
View
@@ -1,6 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
const prefs = require("preferences-service");
const { Loader } = require('test-harness/loader');
@@ -26,8 +27,7 @@ function definePseudo(loader, id, exports) {
}
function createTest(locale, testFunction) {
- return function (test) {
- test.waitUntilDone();
+ return function (assert, done) {
let loader = Loader(module);
// Change the locale before loading new l10n modules in order to load
// the right .json file
@@ -38,49 +38,54 @@ function createTest(locale, testFunction) {
then(function success(data) {
definePseudo(loader, '@l10n/data', data);
// Execute the given test function
- testFunction(test, loader, function onDone() {
- loader.unload();
- resetLocale();
- test.done();
- });
+ try {
+ testFunction(assert, loader, function onDone() {
+ loader.unload();
+ resetLocale();
+ done();
+ });
+ }
+ catch(e) {
+ console.exception(e);
+ }
},
function failure(error) {
- test.fail("Unable to load locales: " + error);
+ assert.fail("Unable to load locales: " + error);
});
};
}
-exports.testExactMatching = createTest("fr-FR", function(test, loader, done) {
- let _ = loader.require("l10n").get;
- test.assertEqual(_("Not translated"), "Not translated",
+exports.testExactMatching = createTest("fr-FR", function(assert, loader, done) {
+ let _ = loader.require("addon-kit/l10n").get;
+ assert.equal(_("Not translated"), "Not translated",
"Key not translated");
- test.assertEqual(_("Translated"), "Oui",
+ assert.equal(_("Translated"), "Oui",
"Simple key translated");
// Placeholders
- test.assertEqual(_("placeholderString", "works"), "Placeholder works",
+ assert.equal(_("placeholderString", "works"), "Placeholder works",
"Value with placeholder");
- test.assertEqual(_("Placeholder %s", "works"), "Placeholder works",
+ assert.equal(_("Placeholder %s", "works"), "Placeholder works",
"Key without value but with placeholder");
- test.assertEqual(_("Placeholders %2s %1s %s.", "working", "are", "correctly"),
+ assert.equal(_("Placeholders %2s %1s %s.", "working", "are", "correctly"),
"Placeholders are working correctly.",
"Multiple placeholders");
// Plurals
- test.assertEqual(_("downloadsCount", 0),
+ assert.equal(_("downloadsCount", 0),
"0 téléchargement",
"PluralForm form 'one' for 0 in french");
- test.assertEqual(_("downloadsCount", 1),
+ assert.equal(_("downloadsCount", 1),
"1 téléchargement",
"PluralForm form 'one' for 1 in french");
- test.assertEqual(_("downloadsCount", 2),
+ assert.equal(_("downloadsCount", 2),
"2 téléchargements",
"PluralForm form 'other' for n > 1 in french");
done();
});
-exports.testHtmlLocalization = createTest("en-GB", function(test, loader, done) {
+exports.testHtmlLocalization = createTest("en-GB", function(assert, loader, done) {
// Ensure initing html component that watch document creations
// Note that this module is automatically initialized in
@@ -99,18 +104,18 @@ exports.testHtmlLocalization = createTest("en-GB", function(test, loader, done)
nodes[3].innerHTML]);
},
onMessage: function (data) {
- test.assertEqual(
+ assert.equal(
data[0],
"Kept as-is",
"Nodes with unknown id in .properties are kept 'as-is'"
);
- test.assertEqual(data[1], "Yes", "HTML is translated");
- test.assertEqual(
+ assert.equal(data[1], "Yes", "HTML is translated");
+ assert.equal(
data[2],
"no <b>HTML</b> injection",
"Content from .properties is text content; HTML can't be injected."
);
- test.assertEqual(data[3], "Yes", "Multiple elements with same data-l10n-id are accepted.");
+ assert.equal(data[3], "Yes", "Multiple elements with same data-l10n-id are accepted.");
done();
}
@@ -118,47 +123,59 @@ exports.testHtmlLocalization = createTest("en-GB", function(test, loader, done)
});
-exports.testEnUsLocaleName = createTest("en-US", function(test, loader, done) {
- let _ = loader.require("l10n").get;
- test.assertEqual(_("Not translated"), "Not translated");
- test.assertEqual(_("Translated"), "Yes");
+exports.testEnUsLocaleName = createTest("en-US", function(assert, loader, done) {
+ let _ = loader.require("addon-kit/l10n").get;
+
+ assert.equal(_("Not translated"), "Not translated",
+ "String w/o translation is kept as-is");
+ assert.equal(_("Translated"), "Yes",
+ "String with translation is correctly translated");
// Check plural forms regular matching
- test.assertEqual(_("downloadsCount", 0),
+ assert.equal(_("downloadsCount", 0),
"0 downloads",
"PluralForm form 'other' for 0 in english");
- test.assertEqual(_("downloadsCount", 1),
+ assert.equal(_("downloadsCount", 1),
"one download",
"PluralForm form 'one' for 1 in english");
- test.assertEqual(_("downloadsCount", 2),
+ assert.equal(_("downloadsCount", 2),
"2 downloads",
"PluralForm form 'other' for n != 1 in english");
// Check optional plural forms
- test.assertEqual(_("pluralTest", 0),
+ assert.equal(_("pluralTest", 0),
"optional zero form",
"PluralForm form 'zero' can be optionaly specified. (Isn't mandatory in english)");
- test.assertEqual(_("pluralTest", 1),
+ assert.equal(_("pluralTest", 1),
"fallback to other",
"If the specific plural form is missing, we fallback to 'other'");
// Ensure that we can omit specifying the generic key without [other]
// key[one] = ...
// key[other] = ... # Instead of `key = ...`
- test.assertEqual(_("explicitPlural", 1),
+ assert.equal(_("explicitPlural", 1),
"one",
"PluralForm form can be omitting generic key [i.e. without ...[other] at end of key)");
- test.assertEqual(_("explicitPlural", 10),
+ assert.equal(_("explicitPlural", 10),
"other",
"PluralForm form can be omitting generic key [i.e. without ...[other] at end of key)");
done();
});
-exports.testShortLocaleName = createTest("eo", function(test, loader, done) {
- let _ = loader.require("l10n").get;
- test.assertEqual(_("Not translated"), "Not translated");
- test.assertEqual(_("Translated"), "jes");
+exports.testShortLocaleName = createTest("eo", function(assert, loader, done) {
+ let _ = loader.require("addon-kit/l10n").get;
+ assert.equal(_("Not translated"), "Not translated",
+ "String w/o translation is kept as-is");
+ assert.equal(_("Translated"), "jes",
+ "String with translation is correctly translated");
done();
});
+
+
+// Before running tests, disable HTML service which is automatially enabled
+// in api-utils/addon/runner.js
+require('api-utils/l10n/html').disable();
+
+require("test-harness/run-tests").runTestsFromModule(module);
3  test/addons/l10n/package.json
View
@@ -0,0 +1,3 @@
+{
+ "id": "test-l10n"
+}
Something went wrong with that request. Please try again.