mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 1029207 - Uplift Add-on SDK to Firefox r=me
This commit is contained in:
parent
1f7e252160
commit
c4b97191fc
1
addon-sdk/source/app-extension/bootstrap.js
vendored
1
addon-sdk/source/app-extension/bootstrap.js
vendored
@ -233,7 +233,6 @@ function startup(data, reasonCode) {
|
||||
// Arguments related to test runner.
|
||||
modules: {
|
||||
'@test/options': {
|
||||
allTestModules: options.allTestModules,
|
||||
iterations: options.iterations,
|
||||
filter: options.filter,
|
||||
profileMemory: options.profileMemory,
|
||||
|
@ -54,7 +54,6 @@ exports.install = function install(xpiPath) {
|
||||
setTimeout(resolve, 0, aAddon.id);
|
||||
},
|
||||
onInstallFailed: function (aInstall) {
|
||||
console.log("failed");
|
||||
aInstall.removeListener(listener);
|
||||
reject(aInstall.error);
|
||||
},
|
||||
@ -114,8 +113,9 @@ exports.isActive = function isActive(addonId) {
|
||||
return getAddon(addonId).then(addon => addon.isActive && !addon.appDisabled);
|
||||
};
|
||||
|
||||
function getAddon (id) {
|
||||
const getAddon = function getAddon (id) {
|
||||
let { promise, resolve, reject } = defer();
|
||||
AddonManager.getAddonByID(id, addon => addon ? resolve(addon) : reject());
|
||||
return promise;
|
||||
}
|
||||
exports.getAddon = getAddon;
|
||||
|
@ -56,8 +56,6 @@ eventTarget.addEventListener("DOMContentLoaded", function handler(event) {
|
||||
resolve();
|
||||
}, false);
|
||||
|
||||
|
||||
|
||||
exports.ready = promise;
|
||||
exports.window = window;
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
/* 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";
|
||||
|
||||
module.metadata = {
|
||||
@ -10,9 +9,109 @@ module.metadata = {
|
||||
|
||||
const file = require("../io/file");
|
||||
const memory = require('./memory');
|
||||
const suites = require('@test/options').allTestModules;
|
||||
const { Loader } = require("sdk/test/loader");
|
||||
const cuddlefish = require("sdk/loader/cuddlefish");
|
||||
const { Loader } = require("../test/loader");
|
||||
const cuddlefish = require("../loader/cuddlefish");
|
||||
const { defer, resolve } = require("../core/promise");
|
||||
const { getAddon } = require("../addon/installer");
|
||||
const { id } = require("sdk/self");
|
||||
const { newURI } = require('sdk/url/utils');
|
||||
const { getZipReader } = require("../zip/utils");
|
||||
|
||||
const { Cc, Ci, Cu } = require("chrome");
|
||||
const { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
|
||||
var ios = Cc['@mozilla.org/network/io-service;1']
|
||||
.getService(Ci.nsIIOService);
|
||||
|
||||
const TEST_REGEX = /(([^\/]+\/)(?:lib\/)?)(tests?\/test-[^\.\/]+)\.js$/;
|
||||
|
||||
const { mapcat, map, filter, fromEnumerator } = require("sdk/util/sequence");
|
||||
|
||||
const toFile = x => x.QueryInterface(Ci.nsIFile);
|
||||
const isTestFile = ({leafName}) => leafName.substr(0, 5) == "test-" && leafName.substr(-3, 3) == ".js";
|
||||
const getFileURI = x => ios.newFileURI(x).spec;
|
||||
|
||||
const getDirectoryEntries = file => map(toFile, fromEnumerator(_ => file.directoryEntries));
|
||||
const getTestFiles = directory => filter(isTestFile, getDirectoryEntries(directory));
|
||||
const getTestURIs = directory => map(getFileURI, getTestFiles(directory));
|
||||
|
||||
const isDirectory = x => x.isDirectory();
|
||||
const getTestEntries = directory => mapcat(entry =>
|
||||
/^tests?$/.test(entry.leafName) ? getTestURIs(entry) : getTestEntries(entry),
|
||||
filter(isDirectory, getDirectoryEntries(directory)));
|
||||
|
||||
const removeDups = (array) => array.reduce((result, value) => {
|
||||
if (value != result[result.length - 1]) {
|
||||
result.push(value);
|
||||
}
|
||||
return result;
|
||||
}, []);
|
||||
|
||||
const getSuites = function getSuites({ id }) {
|
||||
return getAddon(id).then(addon => {
|
||||
let fileURI = addon.getResourceURI("tests/");
|
||||
let isPacked = fileURI.scheme == "jar";
|
||||
let xpiURI = addon.getResourceURI();
|
||||
let file = xpiURI.QueryInterface(Ci.nsIFileURL).file;
|
||||
let suites = [];
|
||||
let addEntry = (entry) => {
|
||||
if (TEST_REGEX.test(entry)) {
|
||||
let suite = RegExp.$2 + RegExp.$3;
|
||||
suites.push(suite);
|
||||
}
|
||||
}
|
||||
|
||||
if (isPacked) {
|
||||
return getZipReader(file).then(zip => {
|
||||
let entries = zip.findEntries(null);
|
||||
while (entries.hasMore()) {
|
||||
let entry = entries.getNext();
|
||||
addEntry(entry);
|
||||
}
|
||||
zip.close();
|
||||
|
||||
// sort and remove dups
|
||||
suites = removeDups(suites.sort());
|
||||
return suites;
|
||||
})
|
||||
} else {
|
||||
let tests = getTestEntries(file);
|
||||
[...tests].forEach(addEntry);
|
||||
}
|
||||
|
||||
// sort and remove dups
|
||||
suites = removeDups(suites.sort());
|
||||
return suites;
|
||||
});
|
||||
}
|
||||
exports.getSuites = getSuites;
|
||||
|
||||
const makeFilter = function makeFilter(options) {
|
||||
// A filter string is {fileNameRegex}[:{testNameRegex}] - ie, a colon
|
||||
// optionally separates a regex for the test fileName from a regex for the
|
||||
// testName.
|
||||
if (options.filter) {
|
||||
let colonPos = options.filter.indexOf(':');
|
||||
let filterFileRegex, filterNameRegex;
|
||||
|
||||
if (colonPos === -1) {
|
||||
filterFileRegex = new RegExp(options.filter);
|
||||
} else {
|
||||
filterFileRegex = new RegExp(options.filter.substr(0, colonPos));
|
||||
filterNameRegex = new RegExp(options.filter.substr(colonPos + 1));
|
||||
}
|
||||
// This function will first be called with just the filename; if
|
||||
// it returns true the module will be loaded then the function
|
||||
// called again with both the filename and the testname.
|
||||
return (filename, testname) => {
|
||||
return filterFileRegex.test(filename) &&
|
||||
((testname && filterNameRegex) ? filterNameRegex.test(testname)
|
||||
: true);
|
||||
};
|
||||
}
|
||||
|
||||
return () => true;
|
||||
}
|
||||
exports.makeFilter = makeFilter;
|
||||
|
||||
let loader = Loader(module);
|
||||
const NOT_TESTS = ['setup', 'teardown'];
|
||||
@ -25,45 +124,20 @@ var TestFinder = exports.TestFinder = function TestFinder(options) {
|
||||
};
|
||||
|
||||
TestFinder.prototype = {
|
||||
findTests: function findTests(cb) {
|
||||
var self = this;
|
||||
var tests = [];
|
||||
var filter;
|
||||
// A filter string is {fileNameRegex}[:{testNameRegex}] - ie, a colon
|
||||
// optionally separates a regex for the test fileName from a regex for the
|
||||
// testName.
|
||||
if (this.filter) {
|
||||
var colonPos = this.filter.indexOf(':');
|
||||
var filterFileRegex, filterNameRegex;
|
||||
if (colonPos === -1) {
|
||||
filterFileRegex = new RegExp(self.filter);
|
||||
} else {
|
||||
filterFileRegex = new RegExp(self.filter.substr(0, colonPos));
|
||||
filterNameRegex = new RegExp(self.filter.substr(colonPos + 1));
|
||||
}
|
||||
// This function will first be called with just the filename; if
|
||||
// it returns true the module will be loaded then the function
|
||||
// called again with both the filename and the testname.
|
||||
filter = function(filename, testname) {
|
||||
return filterFileRegex.test(filename) &&
|
||||
((testname && filterNameRegex) ? filterNameRegex.test(testname)
|
||||
: true);
|
||||
};
|
||||
} else
|
||||
filter = function() {return true};
|
||||
findTests: function findTests() {
|
||||
return getSuites({ id: id }).then(suites => {
|
||||
let filter = makeFilter({ filter: this.filter });
|
||||
let tests = [];
|
||||
|
||||
suites.forEach(function(suite) {
|
||||
suites.forEach(suite => {
|
||||
// Load each test file as a main module in its own loader instance
|
||||
// `suite` is defined by cuddlefish/manifest.py:ManifestBuilder.build
|
||||
|
||||
let suiteModule;
|
||||
|
||||
try {
|
||||
suiteModule = cuddlefish.main(loader, suite);
|
||||
}
|
||||
catch (e) {
|
||||
if (!/^Unsupported Application/.test(e.message))
|
||||
throw e;
|
||||
// If `Unsupported Application` error thrown during test,
|
||||
// skip the test suite
|
||||
suiteModule = {
|
||||
@ -71,19 +145,21 @@ TestFinder.prototype = {
|
||||
};
|
||||
}
|
||||
|
||||
if (self.testInProcess)
|
||||
if (this.testInProcess) {
|
||||
for each (let name in Object.keys(suiteModule).sort()) {
|
||||
if(NOT_TESTS.indexOf(name) === -1 && filter(suite, name)) {
|
||||
if (NOT_TESTS.indexOf(name) === -1 && filter(suite, name)) {
|
||||
tests.push({
|
||||
setup: suiteModule.setup,
|
||||
teardown: suiteModule.teardown,
|
||||
testFunction: suiteModule[name],
|
||||
name: suite + "." + name
|
||||
});
|
||||
setup: suiteModule.setup,
|
||||
teardown: suiteModule.teardown,
|
||||
testFunction: suiteModule[name],
|
||||
name: suite + "." + name
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
cb(tests);
|
||||
return tests;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -1,7 +1,6 @@
|
||||
/* 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";
|
||||
|
||||
module.metadata = {
|
||||
@ -9,12 +8,13 @@ module.metadata = {
|
||||
};
|
||||
|
||||
const memory = require('./memory');
|
||||
var timer = require("../timers");
|
||||
const timer = require("../timers");
|
||||
var cfxArgs = require("@test/options");
|
||||
const { getTabs, getURI } = require("../tabs/utils");
|
||||
const { windows, isBrowser } = require("../window/utils");
|
||||
const { defer } = require("../core/promise");
|
||||
|
||||
exports.findAndRunTests = function findAndRunTests(options) {
|
||||
const findAndRunTests = function findAndRunTests(options) {
|
||||
var TestFinder = require("./unit-test-finder").TestFinder;
|
||||
var finder = new TestFinder({
|
||||
filter: options.filter,
|
||||
@ -22,15 +22,17 @@ exports.findAndRunTests = function findAndRunTests(options) {
|
||||
testOutOfProcess: options.testOutOfProcess
|
||||
});
|
||||
var runner = new TestRunner({fs: options.fs});
|
||||
finder.findTests(
|
||||
function (tests) {
|
||||
runner.startMany({tests: tests,
|
||||
stopOnError: options.stopOnError,
|
||||
onDone: options.onDone});
|
||||
finder.findTests().then(tests => {
|
||||
runner.startMany({
|
||||
tests: tests,
|
||||
stopOnError: options.stopOnError,
|
||||
onDone: options.onDone
|
||||
});
|
||||
});
|
||||
};
|
||||
exports.findAndRunTests = findAndRunTests;
|
||||
|
||||
var TestRunner = exports.TestRunner = function TestRunner(options) {
|
||||
const TestRunner = function TestRunner(options) {
|
||||
if (options) {
|
||||
this.fs = options.fs;
|
||||
}
|
||||
@ -40,6 +42,7 @@ var TestRunner = exports.TestRunner = function TestRunner(options) {
|
||||
this.failed = 0;
|
||||
this.testRunSummary = [];
|
||||
this.expectFailNesting = 0;
|
||||
this.done = TestRunner.prototype.done.bind(this);
|
||||
};
|
||||
|
||||
TestRunner.prototype = {
|
||||
@ -252,9 +255,9 @@ TestRunner.prototype = {
|
||||
assertArray: function(a, message) {
|
||||
this.assertStrictEqual('[object Array]', Object.prototype.toString.apply(a), message);
|
||||
},
|
||||
|
||||
|
||||
assertNumber: function(a, message) {
|
||||
this.assertStrictEqual('[object Number]', Object.prototype.toString.apply(a), message);
|
||||
this.assertStrictEqual('[object Number]', Object.prototype.toString.apply(a), message);
|
||||
},
|
||||
|
||||
done: function done() {
|
||||
@ -321,36 +324,37 @@ TestRunner.prototype = {
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// Set of assertion functions to wait for an assertion to become true
|
||||
// These functions take the same arguments as the TestRunner.assert* methods.
|
||||
waitUntil: function waitUntil() {
|
||||
return this._waitUntil(this.assert, arguments);
|
||||
},
|
||||
|
||||
|
||||
waitUntilNotEqual: function waitUntilNotEqual() {
|
||||
return this._waitUntil(this.assertNotEqual, arguments);
|
||||
},
|
||||
|
||||
|
||||
waitUntilEqual: function waitUntilEqual() {
|
||||
return this._waitUntil(this.assertEqual, arguments);
|
||||
},
|
||||
|
||||
|
||||
waitUntilMatches: function waitUntilMatches() {
|
||||
return this._waitUntil(this.assertMatches, arguments);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Internal function that waits for an assertion to become true.
|
||||
* @param {Function} assertionMethod
|
||||
* Reference to a TestRunner assertion method like test.assert,
|
||||
* Reference to a TestRunner assertion method like test.assert,
|
||||
* test.assertEqual, ...
|
||||
* @param {Array} args
|
||||
* List of arguments to give to the previous assertion method.
|
||||
* List of arguments to give to the previous assertion method.
|
||||
* All functions in this list are going to be called to retrieve current
|
||||
* assertion values.
|
||||
*/
|
||||
_waitUntil: function waitUntil(assertionMethod, args) {
|
||||
let { promise, resolve } = defer();
|
||||
let count = 0;
|
||||
let maxCount = this.DEFAULT_PAUSE_TIMEOUT / this.PAUSE_DELAY;
|
||||
|
||||
@ -358,9 +362,7 @@ TestRunner.prototype = {
|
||||
if (!this.waitTimeout)
|
||||
this.waitUntilDone(this.DEFAULT_PAUSE_TIMEOUT);
|
||||
|
||||
let callback = null;
|
||||
let finished = false;
|
||||
|
||||
let test = this;
|
||||
|
||||
// capture a traceback before we go async.
|
||||
@ -380,9 +382,8 @@ TestRunner.prototype = {
|
||||
pass: function (msg) {
|
||||
test.pass(msg);
|
||||
test.waitUntilCallback = null;
|
||||
if (callback && !stopIt)
|
||||
callback();
|
||||
finished = true;
|
||||
if (!stopIt)
|
||||
resolve();
|
||||
},
|
||||
fail: function (msg) {
|
||||
// If we are called on test timeout, we stop the loop
|
||||
@ -398,8 +399,8 @@ TestRunner.prototype = {
|
||||
timeout = timer.setTimeout(loop, test.PAUSE_DELAY);
|
||||
}
|
||||
};
|
||||
|
||||
// Automatically call args closures in order to build arguments for
|
||||
|
||||
// Automatically call args closures in order to build arguments for
|
||||
// assertion function
|
||||
let appliedArgs = [];
|
||||
for (let i = 0, l = args.length; i < l; i++) {
|
||||
@ -411,33 +412,21 @@ TestRunner.prototype = {
|
||||
catch(e) {
|
||||
test.fail("Exception when calling asynchronous assertion: " + e +
|
||||
"\n" + e.stack);
|
||||
finished = true;
|
||||
return;
|
||||
return resolve();
|
||||
}
|
||||
}
|
||||
appliedArgs.push(a);
|
||||
}
|
||||
|
||||
|
||||
// Finally call assertion function with current assertion values
|
||||
assertionMethod.apply(mock, appliedArgs);
|
||||
}
|
||||
loop();
|
||||
this.waitUntilCallback = loop;
|
||||
|
||||
// Return an object with `then` method, to offer a way to execute
|
||||
// some code when the assertion passed or failed
|
||||
return {
|
||||
then: function (c) {
|
||||
callback = c;
|
||||
|
||||
// In case of immediate positive result, we need to execute callback
|
||||
// immediately here:
|
||||
if (finished)
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
return promise;
|
||||
},
|
||||
|
||||
|
||||
waitUntilDone: function waitUntilDone(ms) {
|
||||
if (ms === undefined)
|
||||
ms = this.DEFAULT_PAUSE_TIMEOUT;
|
||||
@ -514,3 +503,4 @@ TestRunner.prototype = {
|
||||
this.done();
|
||||
}
|
||||
};
|
||||
exports.TestRunner = TestRunner;
|
||||
|
@ -621,7 +621,4 @@ var runTests = exports.runTests = function runTests(options) {
|
||||
}
|
||||
};
|
||||
|
||||
unload(function() {
|
||||
cService.unregisterListener(consoleListener);
|
||||
});
|
||||
|
||||
unload(_ => cService.unregisterListener(consoleListener));
|
||||
|
@ -33,24 +33,22 @@ function runTests(findAndRunTests) {
|
||||
// are not correctly updated.
|
||||
// For ex: nsIFocusManager.getFocusedElementForWindow may throw
|
||||
// NS_ERROR_ILLEGAL_VALUE exception.
|
||||
require("../timers").setTimeout(function () {
|
||||
harness.runTests({
|
||||
findAndRunTests: findAndRunTests,
|
||||
iterations: cfxArgs.iterations || 1,
|
||||
filter: cfxArgs.filter,
|
||||
profileMemory: cfxArgs.profileMemory,
|
||||
stopOnError: cfxArgs.stopOnError,
|
||||
verbose: cfxArgs.verbose,
|
||||
parseable: cfxArgs.parseable,
|
||||
print: stdout.write,
|
||||
onDone: onDone
|
||||
});
|
||||
}, 0);
|
||||
require("../timers").setTimeout(_ => harness.runTests({
|
||||
findAndRunTests: findAndRunTests,
|
||||
iterations: cfxArgs.iterations || 1,
|
||||
filter: cfxArgs.filter,
|
||||
profileMemory: cfxArgs.profileMemory,
|
||||
stopOnError: cfxArgs.stopOnError,
|
||||
verbose: cfxArgs.verbose,
|
||||
parseable: cfxArgs.parseable,
|
||||
print: stdout.write,
|
||||
onDone: onDone
|
||||
}));
|
||||
}
|
||||
|
||||
function printFailedTests(tests, print) {
|
||||
let iterationNumber = 0;
|
||||
let singleIteration = tests.testRuns.length == 1;
|
||||
let singleIteration = (tests.testRuns || []).length == 1;
|
||||
let padding = singleIteration ? "" : " ";
|
||||
|
||||
print("\nThe following tests failed:\n");
|
||||
@ -94,7 +92,7 @@ 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) {
|
||||
Object.keys(module.exports).forEach(key => {
|
||||
exports[key] = module.exports[key];
|
||||
});
|
||||
|
||||
@ -102,7 +100,7 @@ exports.runTestsFromModule = function runTestsFromModule(module) {
|
||||
// Consider that all these tests are CommonJS ones
|
||||
loader.require('../../test').run(exports);
|
||||
|
||||
// Reproduce what is done in unit-test-finder.findTests()
|
||||
// Reproduce what is done in sdk/deprecated/unit-test-finder.findTests()
|
||||
let tests = [];
|
||||
for each (let name in Object.keys(exports).sort()) {
|
||||
tests.push({
|
||||
|
22
addon-sdk/source/lib/sdk/zip/utils.js
Normal file
22
addon-sdk/source/lib/sdk/zip/utils.js
Normal file
@ -0,0 +1,22 @@
|
||||
/* 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 { Cc, Ci, Cu } = require("chrome");
|
||||
const { defer } = require("../core/promise");
|
||||
|
||||
const getZipReader = function getZipReader(aFile) {
|
||||
let { promise, resolve, reject } = defer();
|
||||
let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"].
|
||||
createInstance(Ci.nsIZipReader);
|
||||
try {
|
||||
zipReader.open(aFile);
|
||||
}
|
||||
catch(e){
|
||||
reject(e);
|
||||
}
|
||||
resolve(zipReader);
|
||||
return promise;
|
||||
};
|
||||
exports.getZipReader = getZipReader;
|
@ -6,5 +6,6 @@
|
||||
"xulrunner", "firefox", "browser"
|
||||
],
|
||||
"loader": "lib/sdk/loader/cuddlefish.js",
|
||||
"license": "MPL 2.0"
|
||||
"license": "MPL 2.0",
|
||||
"unpack": true
|
||||
}
|
||||
|
@ -836,12 +836,6 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None,
|
||||
# Pass a flag in order to force using sdk modules shipped in the xpi
|
||||
harness_options['force-use-bundled-sdk'] = True
|
||||
|
||||
# Pass the list of absolute path for all test modules
|
||||
if command == "test":
|
||||
harness_options['allTestModules'] = manifest.get_all_test_modules()
|
||||
if len(harness_options['allTestModules']) == 0:
|
||||
sys.exit(0)
|
||||
|
||||
from cuddlefish.rdf import gen_manifest, RDFUpdate
|
||||
|
||||
manifest_rdf = gen_manifest(template_root_dir=app_extension_dir,
|
||||
|
@ -278,9 +278,6 @@ class ManifestBuilder:
|
||||
if me.packageName != "addon-sdk" or bundle_sdk_modules:
|
||||
yield me.js_filename
|
||||
|
||||
def get_all_test_modules(self):
|
||||
return self.test_modules
|
||||
|
||||
def get_harness_options_manifest(self, bundle_sdk_modules):
|
||||
manifest = {}
|
||||
for me in self.get_module_entries():
|
||||
|
@ -539,7 +539,10 @@ def run_app(harness_root_dir, manifest_rdf, harness_options,
|
||||
outfile_tail = follow_file(outfile)
|
||||
def maybe_remove_outfile():
|
||||
if os.path.exists(outfile):
|
||||
os.remove(outfile)
|
||||
try:
|
||||
os.remove(outfile)
|
||||
except Exception, e:
|
||||
print "Error Cleaning up: " + str(e)
|
||||
atexit.register(maybe_remove_outfile)
|
||||
outf = open(outfile, "w")
|
||||
popen_kwargs = { 'stdout': outf, 'stderr': outf}
|
||||
|
@ -190,8 +190,7 @@ class TestCfxQuits(unittest.TestCase):
|
||||
self.assertIn("Program terminated successfully.", err)
|
||||
|
||||
def test_cfx_test(self):
|
||||
addon_path = os.path.join(tests_path,
|
||||
"addons", "simplest-test")
|
||||
addon_path = os.path.join(tests_path, "addons", "simplest-test")
|
||||
rc, out, err = self.run_cfx(addon_path, ["test"])
|
||||
self.assertEqual(rc, 0)
|
||||
self.assertIn("1 of 1 tests passed.", err)
|
||||
|
@ -244,91 +244,6 @@ class SmallXPI(unittest.TestCase):
|
||||
"uft8_value": "\u00e9"
|
||||
}'''))
|
||||
|
||||
def test_scantests(self):
|
||||
target_cfg = self.get_pkg("three")
|
||||
package_path = [self.get_linker_files_dir("three-deps")]
|
||||
pkg_cfg = packaging.build_config(self.root, target_cfg,
|
||||
packagepath=package_path)
|
||||
|
||||
deps = packaging.get_deps_for_targets(pkg_cfg,
|
||||
[target_cfg.name, "addon-sdk"])
|
||||
m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=True)
|
||||
self.failUnlessEqual(sorted(m.get_all_test_modules()),
|
||||
sorted(["three/tests/test-one", "three/tests/test-two"]))
|
||||
# the current __init__.py code omits limit_to=used_files for 'cfx
|
||||
# test', so all test files are included in the XPI. But the test
|
||||
# runner will only execute the tests that m.get_all_test_modules()
|
||||
# tells us about (which are put into the .allTestModules property of
|
||||
# harness-options.json).
|
||||
used_deps = m.get_used_packages()
|
||||
|
||||
build = packaging.generate_build_for_target(pkg_cfg, target_cfg.name,
|
||||
used_deps,
|
||||
include_tests=True)
|
||||
options = {'main': target_cfg.main}
|
||||
options.update(build)
|
||||
basedir = self.make_basedir()
|
||||
xpi_name = os.path.join(basedir, "contents.xpi")
|
||||
xpi.build_xpi(template_root_dir=xpi_template_path,
|
||||
manifest=fake_manifest,
|
||||
xpi_path=xpi_name,
|
||||
harness_options=options,
|
||||
limit_to=None)
|
||||
x = zipfile.ZipFile(xpi_name, "r")
|
||||
names = x.namelist()
|
||||
self.failUnless("resources/addon-sdk/lib/sdk/deprecated/unit-test.js" in names, names)
|
||||
self.failUnless("resources/addon-sdk/lib/sdk/deprecated/unit-test-finder.js" in names, names)
|
||||
self.failUnless("resources/addon-sdk/lib/sdk/test/harness.js" in names, names)
|
||||
self.failUnless("resources/addon-sdk/lib/sdk/test/runner.js" in names, names)
|
||||
# all files are copied into the XPI, even the things that don't look
|
||||
# like tests.
|
||||
self.failUnless("resources/three/tests/test-one.js" in names, names)
|
||||
self.failUnless("resources/three/tests/test-two.js" in names, names)
|
||||
self.failUnless("resources/three/tests/nontest.js" in names, names)
|
||||
|
||||
def test_scantests_filter(self):
|
||||
target_cfg = self.get_pkg("three")
|
||||
package_path = [self.get_linker_files_dir("three-deps")]
|
||||
pkg_cfg = packaging.build_config(self.root, target_cfg,
|
||||
packagepath=package_path)
|
||||
deps = packaging.get_deps_for_targets(pkg_cfg,
|
||||
[target_cfg.name, "addon-sdk"])
|
||||
FILTER = ".*one.*"
|
||||
m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=True,
|
||||
test_filter_re=FILTER)
|
||||
self.failUnlessEqual(sorted(m.get_all_test_modules()),
|
||||
sorted(["three/tests/test-one"]))
|
||||
# the current __init__.py code omits limit_to=used_files for 'cfx
|
||||
# test', so all test files are included in the XPI. But the test
|
||||
# runner will only execute the tests that m.get_all_test_modules()
|
||||
# tells us about (which are put into the .allTestModules property of
|
||||
# harness-options.json).
|
||||
used_deps = m.get_used_packages()
|
||||
|
||||
build = packaging.generate_build_for_target(pkg_cfg, target_cfg.name,
|
||||
used_deps,
|
||||
include_tests=True)
|
||||
options = {'main': target_cfg.main}
|
||||
options.update(build)
|
||||
basedir = self.make_basedir()
|
||||
xpi_name = os.path.join(basedir, "contents.xpi")
|
||||
xpi.build_xpi(template_root_dir=xpi_template_path,
|
||||
manifest=fake_manifest,
|
||||
xpi_path=xpi_name,
|
||||
harness_options=options,
|
||||
limit_to=None)
|
||||
x = zipfile.ZipFile(xpi_name, "r")
|
||||
names = x.namelist()
|
||||
self.failUnless("resources/addon-sdk/lib/sdk/deprecated/unit-test.js" in names, names)
|
||||
self.failUnless("resources/addon-sdk/lib/sdk/deprecated/unit-test-finder.js" in names, names)
|
||||
self.failUnless("resources/addon-sdk/lib/sdk/test/harness.js" in names, names)
|
||||
self.failUnless("resources/addon-sdk/lib/sdk/test/runner.js" in names, names)
|
||||
# get_all_test_modules() respects the filter. But all files are still
|
||||
# copied into the XPI.
|
||||
self.failUnless("resources/three/tests/test-one.js" in names, names)
|
||||
self.failUnless("resources/three/tests/test-two.js" in names, names)
|
||||
self.failUnless("resources/three/tests/nontest.js" in names, names)
|
||||
|
||||
|
||||
def document_dir(name):
|
||||
if name in ['packages', 'xpi-template']:
|
||||
|
@ -24,8 +24,9 @@ def mkzipdir(zf, path):
|
||||
def build_xpi(template_root_dir, manifest, xpi_path,
|
||||
harness_options, limit_to=None, extra_harness_options={},
|
||||
bundle_sdk=True, pkgdir=""):
|
||||
IGNORED_FILES = [".hgignore", ".DS_Store", "install.rdf",
|
||||
IGNORED_FILES = [".hgignore", ".DS_Store",
|
||||
"application.ini", xpi_path]
|
||||
IGNORED_TOP_LVL_FILES = ["install.rdf"]
|
||||
|
||||
files_to_copy = {} # maps zipfile path to local-disk abspath
|
||||
dirs_to_create = set() # zipfile paths, no trailing slash
|
||||
@ -71,6 +72,8 @@ def build_xpi(template_root_dir, manifest, xpi_path,
|
||||
files_to_copy[str(arcpath)] = str(abspath)
|
||||
|
||||
for dirpath, dirnames, filenames in os.walk(template_root_dir):
|
||||
if template_root_dir == dirpath:
|
||||
filenames = list(filter_filenames(filenames, IGNORED_TOP_LVL_FILES))
|
||||
filenames = list(filter_filenames(filenames, IGNORED_FILES))
|
||||
dirnames[:] = filter_dirnames(dirnames)
|
||||
for dirname in dirnames:
|
||||
|
@ -21,7 +21,6 @@ exports.testNoTabCloseOnStartup = function(assert, done) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
exports.main = function() {
|
||||
tabs.on('close', closeEventDetector);
|
||||
|
||||
|
@ -8,7 +8,7 @@ const { Loader } = require("sdk/test/loader");
|
||||
var setupCalled = false, teardownCalled = false;
|
||||
|
||||
exports.setup = function() {
|
||||
setupCalled = true;
|
||||
setupCalled = true;
|
||||
};
|
||||
|
||||
exports.teardown = function() {
|
||||
@ -16,10 +16,10 @@ exports.teardown = function() {
|
||||
setupCalled = false;
|
||||
};
|
||||
|
||||
// Important note - unit tests are run in alphabetical order. The following
|
||||
// unit tests for setup/teardown are order dependent, sometimes the result of
|
||||
// one test is checked in the next test (testing for teardown does this). When
|
||||
// tests are cohesively a single unit, they are named <test_name> - partN where
|
||||
// Important note - unit tests are run in alphabetical order. The following
|
||||
// unit tests for setup/teardown are order dependent, sometimes the result of
|
||||
// one test is checked in the next test (testing for teardown does this). When
|
||||
// tests are cohesively a single unit, they are named <test_name> - partN where
|
||||
// N is their order in the sequence. Secondly, because these tests should be
|
||||
// run before all others, they start with an A.
|
||||
exports.testASetupTeardownSyncTestPart1 = function(test) {
|
||||
@ -34,11 +34,10 @@ exports.testASetupTeardownSyncTestPart2 = function(test) {
|
||||
|
||||
exports.testATeardownAsyncTestPart1 = function(test) {
|
||||
teardownCalled = false;
|
||||
|
||||
timer.setTimeout(function() {
|
||||
timer.setTimeout(_ => {
|
||||
test.assertEqual(false, teardownCalled, "teardown not called until done");
|
||||
test.done();
|
||||
}, 200);
|
||||
}, 20);
|
||||
test.waitUntilDone();
|
||||
};
|
||||
|
||||
@ -48,7 +47,7 @@ exports.testATeardownAsyncTestPart2 = function(test) {
|
||||
|
||||
exports.testWaitUntilInstant = function(test) {
|
||||
test.waitUntilDone();
|
||||
|
||||
|
||||
test.waitUntil(function () true, "waitUntil with instant true pass")
|
||||
.then(function () test.done());
|
||||
}
|
||||
@ -56,60 +55,63 @@ exports.testWaitUntilInstant = function(test) {
|
||||
exports.testWaitUntil = function(test) {
|
||||
test.waitUntilDone();
|
||||
let succeed = false;
|
||||
|
||||
test.waitUntil(function () succeed, "waitUntil pass")
|
||||
.then(function () test.done());
|
||||
|
||||
timer.setTimeout(function () {
|
||||
|
||||
test.waitUntil(_ => succeed, "waitUntil pass")
|
||||
.then(test.done);
|
||||
|
||||
timer.setTimeout(_ => {
|
||||
test.pass("succeed");
|
||||
succeed = true;
|
||||
}, 200);
|
||||
}, 20);
|
||||
}
|
||||
|
||||
exports.testWaitUntilEqual = function(test) {
|
||||
test.waitUntilDone();
|
||||
let succeed = false;
|
||||
|
||||
test.waitUntilEqual("foo", function () succeed ? "foo" : "bar",
|
||||
|
||||
test.waitUntilEqual("foo", _ => succeed ? "foo" : "bar",
|
||||
"waitUntilEqual pass")
|
||||
.then(function () test.done());
|
||||
|
||||
timer.setTimeout(function () {
|
||||
.then(test.done);
|
||||
|
||||
timer.setTimeout(_ => {
|
||||
test.pass("succeed");
|
||||
succeed = true;
|
||||
}, 200);
|
||||
}, 20);
|
||||
}
|
||||
|
||||
exports.testWaitUntilNotEqual = function(test) {
|
||||
test.waitUntilDone();
|
||||
let succeed = false;
|
||||
|
||||
test.waitUntilNotEqual("foo", function () succeed ? "bar" : "foo",
|
||||
|
||||
test.waitUntilNotEqual("foo", _ => succeed ? "bar" : "foo",
|
||||
"waitUntilNotEqual pass")
|
||||
.then(function () test.done());
|
||||
|
||||
timer.setTimeout(function () {
|
||||
.then(test.done);
|
||||
|
||||
timer.setTimeout(_ => {
|
||||
test.pass("succeed");
|
||||
succeed = true;
|
||||
}, 200);
|
||||
}, 20);
|
||||
}
|
||||
|
||||
exports.testWaitUntilMatches = function(test) {
|
||||
test.waitUntilDone();
|
||||
let succeed = false;
|
||||
|
||||
test.waitUntilMatches(function () succeed ? "foo" : "bar",
|
||||
|
||||
test.waitUntilMatches(_ => succeed ? "foo" : "bar",
|
||||
/foo/, "waitUntilEqual pass")
|
||||
.then(function () test.done());
|
||||
|
||||
timer.setTimeout(function () {
|
||||
.then(test.done);
|
||||
|
||||
timer.setTimeout(_ => {
|
||||
test.pass("succeed");
|
||||
succeed = true;
|
||||
}, 200);
|
||||
}, 20);
|
||||
}
|
||||
|
||||
exports.testWaitUntilErrorInCallback = function(test) {
|
||||
test.waitUntilDone();
|
||||
|
||||
test.expectFail(function() {
|
||||
test.waitUntil(function () {throw "oops"}, "waitUntil pass")
|
||||
.then(function () test.done());
|
||||
test.expectFail(_ => {
|
||||
test.waitUntil(_ => { throw "oops"; }, "waitUntil pass")
|
||||
.then(test.done);
|
||||
});
|
||||
}
|
||||
|
||||
@ -195,26 +197,26 @@ exports.testAssertFunction = function(test) {
|
||||
test.assertFunction(function() {}, 'assertFunction with function');
|
||||
test.expectFail(function() {
|
||||
test.assertFunction(null, 'assertFunction with non-function');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.testAssertUndefined = function(test) {
|
||||
test.assertUndefined(undefined, 'assertUndefined with undefined');
|
||||
test.expectFail(function() {
|
||||
test.assertUndefined(null, 'assertUndefined with null');
|
||||
});
|
||||
});
|
||||
test.expectFail(function() {
|
||||
test.assertUndefined(false, 'assertUndefined with false');
|
||||
});
|
||||
});
|
||||
test.expectFail(function() {
|
||||
test.assertUndefined(0, 'assertUndefined with 0');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.testAssertNotUndefined = function(test) {
|
||||
test.expectFail(function() {
|
||||
test.assertNotUndefined(undefined, 'assertNotUndefined with undefined');
|
||||
});
|
||||
});
|
||||
test.assertNotUndefined(null, 'assertNotUndefined with null');
|
||||
test.assertNotUndefined(false, 'assertNotUndefined with false');
|
||||
test.assertNotUndefined(0, 'assertNotUndefined with 0');
|
||||
@ -224,7 +226,7 @@ exports.testAssertNull = function(test) {
|
||||
test.assertNull(null, 'assertNull with null');
|
||||
test.expectFail(function() {
|
||||
test.assertNull(undefined, 'assertNull with undefined');
|
||||
});
|
||||
});
|
||||
test.expectFail(function() {
|
||||
test.assertNull(false, 'assertNull with false');
|
||||
});
|
||||
@ -240,7 +242,7 @@ exports.testAssertNotNull = function(test) {
|
||||
|
||||
test.expectFail(function() {
|
||||
test.assertNotNull(null, 'testAssertNotNull with null');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.testAssertObject = function(test) {
|
||||
|
Loading…
Reference in New Issue
Block a user