From c4b97191fc5eaa2c94506bebd3ac16050ea2c16d Mon Sep 17 00:00:00 2001 From: Erik Vold Date: Tue, 24 Jun 2014 10:36:52 -0700 Subject: [PATCH] Bug 1029207 - Uplift Add-on SDK to Firefox r=me --- addon-sdk/source/app-extension/bootstrap.js | 1 - addon-sdk/source/lib/sdk/addon/installer.js | 4 +- addon-sdk/source/lib/sdk/addon/window.js | 2 - .../lib/sdk/deprecated/unit-test-finder.js | 162 +++++++++++++----- .../source/lib/sdk/deprecated/unit-test.js | 74 ++++---- addon-sdk/source/lib/sdk/test/harness.js | 5 +- addon-sdk/source/lib/sdk/test/runner.js | 30 ++-- addon-sdk/source/lib/sdk/zip/utils.js | 22 +++ addon-sdk/source/package.json | 3 +- .../source/python-lib/cuddlefish/__init__.py | 6 - .../source/python-lib/cuddlefish/manifest.py | 3 - .../source/python-lib/cuddlefish/runner.py | 5 +- .../python-lib/cuddlefish/tests/test_init.py | 3 +- .../python-lib/cuddlefish/tests/test_xpi.py | 85 --------- addon-sdk/source/python-lib/cuddlefish/xpi.py | 5 +- .../test/addons/tab-close-on-startup/main.js | 1 - addon-sdk/source/test/test-unit-test.js | 90 +++++----- 17 files changed, 247 insertions(+), 254 deletions(-) create mode 100644 addon-sdk/source/lib/sdk/zip/utils.js diff --git a/addon-sdk/source/app-extension/bootstrap.js b/addon-sdk/source/app-extension/bootstrap.js index 840103a0fbd9..b16cbbfc72cf 100644 --- a/addon-sdk/source/app-extension/bootstrap.js +++ b/addon-sdk/source/app-extension/bootstrap.js @@ -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, diff --git a/addon-sdk/source/lib/sdk/addon/installer.js b/addon-sdk/source/lib/sdk/addon/installer.js index 8ee7a3eac975..25079c79393a 100644 --- a/addon-sdk/source/lib/sdk/addon/installer.js +++ b/addon-sdk/source/lib/sdk/addon/installer.js @@ -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; diff --git a/addon-sdk/source/lib/sdk/addon/window.js b/addon-sdk/source/lib/sdk/addon/window.js index 00faec76450e..03db16db4e0d 100644 --- a/addon-sdk/source/lib/sdk/addon/window.js +++ b/addon-sdk/source/lib/sdk/addon/window.js @@ -56,8 +56,6 @@ eventTarget.addEventListener("DOMContentLoaded", function handler(event) { resolve(); }, false); - - exports.ready = promise; exports.window = window; diff --git a/addon-sdk/source/lib/sdk/deprecated/unit-test-finder.js b/addon-sdk/source/lib/sdk/deprecated/unit-test-finder.js index 7002525924bc..368efdcc6d3f 100644 --- a/addon-sdk/source/lib/sdk/deprecated/unit-test-finder.js +++ b/addon-sdk/source/lib/sdk/deprecated/unit-test-finder.js @@ -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; + }); } }; diff --git a/addon-sdk/source/lib/sdk/deprecated/unit-test.js b/addon-sdk/source/lib/sdk/deprecated/unit-test.js index dec9d31b0aaf..fb615653e7df 100644 --- a/addon-sdk/source/lib/sdk/deprecated/unit-test.js +++ b/addon-sdk/source/lib/sdk/deprecated/unit-test.js @@ -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; diff --git a/addon-sdk/source/lib/sdk/test/harness.js b/addon-sdk/source/lib/sdk/test/harness.js index ac2985ecc1b8..f981da08fbf9 100644 --- a/addon-sdk/source/lib/sdk/test/harness.js +++ b/addon-sdk/source/lib/sdk/test/harness.js @@ -621,7 +621,4 @@ var runTests = exports.runTests = function runTests(options) { } }; -unload(function() { - cService.unregisterListener(consoleListener); -}); - +unload(_ => cService.unregisterListener(consoleListener)); diff --git a/addon-sdk/source/lib/sdk/test/runner.js b/addon-sdk/source/lib/sdk/test/runner.js index 4e6779524b45..d0b3d7fda58d 100644 --- a/addon-sdk/source/lib/sdk/test/runner.js +++ b/addon-sdk/source/lib/sdk/test/runner.js @@ -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({ diff --git a/addon-sdk/source/lib/sdk/zip/utils.js b/addon-sdk/source/lib/sdk/zip/utils.js new file mode 100644 index 000000000000..bc1e0b610b7e --- /dev/null +++ b/addon-sdk/source/lib/sdk/zip/utils.js @@ -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; diff --git a/addon-sdk/source/package.json b/addon-sdk/source/package.json index 7519eb603a97..5f960a521abb 100644 --- a/addon-sdk/source/package.json +++ b/addon-sdk/source/package.json @@ -6,5 +6,6 @@ "xulrunner", "firefox", "browser" ], "loader": "lib/sdk/loader/cuddlefish.js", - "license": "MPL 2.0" + "license": "MPL 2.0", + "unpack": true } diff --git a/addon-sdk/source/python-lib/cuddlefish/__init__.py b/addon-sdk/source/python-lib/cuddlefish/__init__.py index e6f556d94498..6e86615ccbc3 100644 --- a/addon-sdk/source/python-lib/cuddlefish/__init__.py +++ b/addon-sdk/source/python-lib/cuddlefish/__init__.py @@ -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, diff --git a/addon-sdk/source/python-lib/cuddlefish/manifest.py b/addon-sdk/source/python-lib/cuddlefish/manifest.py index e2714f0c2a19..b3639079d46d 100644 --- a/addon-sdk/source/python-lib/cuddlefish/manifest.py +++ b/addon-sdk/source/python-lib/cuddlefish/manifest.py @@ -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(): diff --git a/addon-sdk/source/python-lib/cuddlefish/runner.py b/addon-sdk/source/python-lib/cuddlefish/runner.py index f6dad1071656..189d219cfa34 100644 --- a/addon-sdk/source/python-lib/cuddlefish/runner.py +++ b/addon-sdk/source/python-lib/cuddlefish/runner.py @@ -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} diff --git a/addon-sdk/source/python-lib/cuddlefish/tests/test_init.py b/addon-sdk/source/python-lib/cuddlefish/tests/test_init.py index ac8d6f9bce83..f331b09cbea9 100644 --- a/addon-sdk/source/python-lib/cuddlefish/tests/test_init.py +++ b/addon-sdk/source/python-lib/cuddlefish/tests/test_init.py @@ -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) diff --git a/addon-sdk/source/python-lib/cuddlefish/tests/test_xpi.py b/addon-sdk/source/python-lib/cuddlefish/tests/test_xpi.py index 0b822a55f0c5..bbefee3b2f36 100644 --- a/addon-sdk/source/python-lib/cuddlefish/tests/test_xpi.py +++ b/addon-sdk/source/python-lib/cuddlefish/tests/test_xpi.py @@ -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']: diff --git a/addon-sdk/source/python-lib/cuddlefish/xpi.py b/addon-sdk/source/python-lib/cuddlefish/xpi.py index 6fa7251653bb..e0b811556da2 100644 --- a/addon-sdk/source/python-lib/cuddlefish/xpi.py +++ b/addon-sdk/source/python-lib/cuddlefish/xpi.py @@ -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: diff --git a/addon-sdk/source/test/addons/tab-close-on-startup/main.js b/addon-sdk/source/test/addons/tab-close-on-startup/main.js index 6e093f14bd71..9af2f4de7ca9 100644 --- a/addon-sdk/source/test/addons/tab-close-on-startup/main.js +++ b/addon-sdk/source/test/addons/tab-close-on-startup/main.js @@ -21,7 +21,6 @@ exports.testNoTabCloseOnStartup = function(assert, done) { }); } - exports.main = function() { tabs.on('close', closeEventDetector); diff --git a/addon-sdk/source/test/test-unit-test.js b/addon-sdk/source/test/test-unit-test.js index 156d47fe716e..67692961143d 100644 --- a/addon-sdk/source/test/test-unit-test.js +++ b/addon-sdk/source/test/test-unit-test.js @@ -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 - 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 - 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) {