diff --git a/addon-sdk/moz.build b/addon-sdk/moz.build index 7ae13484ec31..2186e00d2587 100644 --- a/addon-sdk/moz.build +++ b/addon-sdk/moz.build @@ -29,6 +29,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != "gonk": EXTRA_JS_MODULES.commonjs.sdk.deprecated += [ 'source/lib/sdk/deprecated/api-utils.js', + 'source/lib/sdk/deprecated/memory.js', 'source/lib/sdk/deprecated/sync-worker.js', 'source/lib/sdk/deprecated/unit-test-finder.js', 'source/lib/sdk/deprecated/unit-test.js', @@ -257,10 +258,6 @@ EXTRA_JS_MODULES.commonjs.sdk.content += [ 'source/lib/sdk/content/worker.js', ] -EXTRA_JS_MODULES.commonjs.sdk.content.sandbox += [ - 'source/lib/sdk/content/sandbox/events.js', -] - EXTRA_JS_MODULES.commonjs.sdk['context-menu'] += [ 'source/lib/sdk/context-menu/context.js', 'source/lib/sdk/context-menu/core.js', @@ -456,6 +453,7 @@ EXTRA_JS_MODULES.commonjs.sdk.url += [ EXTRA_JS_MODULES.commonjs.sdk.util += [ 'source/lib/sdk/util/array.js', + 'source/lib/sdk/util/bond.js', 'source/lib/sdk/util/collection.js', 'source/lib/sdk/util/contract.js', 'source/lib/sdk/util/deprecate.js', diff --git a/addon-sdk/source/.travis.yml b/addon-sdk/source/.travis.yml index 287b62a4f8b6..d74bec240146 100644 --- a/addon-sdk/source/.travis.yml +++ b/addon-sdk/source/.travis.yml @@ -1,7 +1,7 @@ sudo: false language: node_js node_js: - - "0.12" + - "0.10" env: - JPM_FX_DEBUG=0 diff --git a/addon-sdk/source/bin/jpm-test.js b/addon-sdk/source/bin/jpm-test.js index f22a552ea7ba..cc06e8c32172 100644 --- a/addon-sdk/source/bin/jpm-test.js +++ b/addon-sdk/source/bin/jpm-test.js @@ -17,13 +17,12 @@ exports.run = function(type) { return new Promise(function(resolve) { type = type || ""; [ - (!isDebug && /^(firefox-bin)?$/.test(type)) && require.resolve("../bin/node-scripts/test.firefox-bin"), + (!isDebug && /^(modules)?$/.test(type)) && require.resolve("../bin/node-scripts/test.modules"), + (!isDebug && /^(addons)?$/.test(type)) && require.resolve("../bin/node-scripts/test.addons"), + (/^(examples)?$/.test(type)) && require.resolve("../bin/node-scripts/test.examples"), (!isDebug && /^(docs)?$/.test(type)) && require.resolve("../bin/node-scripts/test.docs"), (!isDebug && /^(ini)?$/.test(type)) && require.resolve("../bin/node-scripts/test.ini"), - (/^(examples)?$/.test(type)) && require.resolve("../bin/node-scripts/test.examples"), - (!isDebug && /^(addons)?$/.test(type)) && require.resolve("../bin/node-scripts/test.addons"), - (!isDebug && /^(modules)?$/.test(type)) && require.resolve("../bin/node-scripts/test.modules"), - ].forEach(function(filepath) { + ].sort().forEach(function(filepath) { filepath && mocha.addFile(filepath); }) diff --git a/addon-sdk/source/bin/node-scripts/test.firefox-bin.js b/addon-sdk/source/bin/node-scripts/test.firefox-bin.js deleted file mode 100644 index 2570dae20f89..000000000000 --- a/addon-sdk/source/bin/node-scripts/test.firefox-bin.js +++ /dev/null @@ -1,37 +0,0 @@ -/* 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"; - -var fs = require("fs"); -var Promise = require("promise"); -var chai = require("chai"); -var expect = chai.expect; -var normalizeBinary = require("fx-runner/lib/utils").normalizeBinary; - -//var firefox_binary = process.env["JPM_FIREFOX_BINARY"] || normalizeBinary("nightly"); - -describe("Checking Firefox binary", function () { - - it("using matching fx-runner version with jpm", function () { - var sdkPackageJSON = require("../../package.json"); - var jpmPackageINI = require("jpm/package.json"); - expect(sdkPackageJSON.devDependencies["fx-runner"]).to.be.equal(jpmPackageINI.dependencies["fx-runner"]); - }); - - it("exists", function (done) { - var useEnvVar = new Promise(function(resolve) { - resolve(process.env["JPM_FIREFOX_BINARY"]); - }); - - var firefox_binary = process.env["JPM_FIREFOX_BINARY"] ? useEnvVar : normalizeBinary("nightly"); - firefox_binary.then(function(path) { - expect(path).to.be.ok; - fs.exists(path, function (exists) { - expect(exists).to.be.ok; - done(); - }); - }) - }); - -}); diff --git a/addon-sdk/source/bin/node-scripts/test.ini.js b/addon-sdk/source/bin/node-scripts/test.ini.js index 07bd15d1fde5..5b8f76e7af88 100644 --- a/addon-sdk/source/bin/node-scripts/test.ini.js +++ b/addon-sdk/source/bin/node-scripts/test.ini.js @@ -11,7 +11,6 @@ var expect = chai.expect; var ini = require("./update-ini"); var addonINI = path.resolve("./test/addons/jetpack-addon.ini"); -var packageINI = path.resolve("./test/jetpack-package.ini"); describe("Checking ini files", function () { @@ -21,10 +20,7 @@ describe("Checking ini files", function () { if (err) { throw err; } - // filter comments - var text = data.toString().split("\n").filter(function(line) { - return !/^\s*#/.test(line); - }).join("\n"); + var text = data.toString(); var expected = ""; ini.makeAddonIniContent() @@ -32,32 +28,7 @@ describe("Checking ini files", function () { expected = contents; setTimeout(function end() { - expect(text.trim()).to.be.equal(expected.trim()); - done(); - }); - }); - }); - - }); - - it("Check test/jetpack-package.ini", function (done) { - - fs.readFile(packageINI, function (err, data) { - if (err) { - throw err; - } - // filter comments - var text = data.toString().split("\n").filter(function(line) { - return !/^\s*#/.test(line); - }).join("\n"); - var expected = ""; - - ini.makePackageIniContent() - .then(function(contents) { - expected = contents; - - setTimeout(function end() { - expect(text.trim()).to.be.equal(expected.trim()); + expect(expected.trim()).to.be.equal(text.trim()); done(); }); }); diff --git a/addon-sdk/source/bin/node-scripts/update-ini.js b/addon-sdk/source/bin/node-scripts/update-ini.js index a433615b45dd..250d7da01ddf 100644 --- a/addon-sdk/source/bin/node-scripts/update-ini.js +++ b/addon-sdk/source/bin/node-scripts/update-ini.js @@ -11,15 +11,6 @@ var parser = require("ini-parser"); var addonINI = path.resolve("./test/addons/jetpack-addon.ini"); var addonsDir = path.resolve("./test/addons/"); -var packageINI = path.resolve("./test/jetpack-package.ini"); -var packageDir = path.resolve("./test/"); -var packageIgnorables = [ "addons", "preferences" ]; -var packageSupportFiles = [ - "fixtures.js", - "pagemod-test-helpers.js", - "test-context-menu.html", - "util.js" -] function updateAddonINI() { return new Promise(function(resolve) { @@ -41,18 +32,16 @@ function makeAddonIniContent() { var result = {}; fs.readdir(addonsDir, function(err, files) { - // get a list of folders var folders = files.filter(function(file) { return fs.statSync(path.resolve(addonsDir, file)).isDirectory(); }).sort(); - // copy any related data from the existing ini folders.forEach(function(folder) { var oldData = data[folder + ".xpi"]; result[folder] = oldData ? oldData : {}; }); - // build a new ini file + // build ini file var contents = []; Object.keys(result).sort().forEach(function(key) { contents.push("[" + key + ".xpi]"); @@ -67,76 +56,3 @@ function makeAddonIniContent() { }); } exports.makeAddonIniContent = makeAddonIniContent; - -function makePackageIniContent() { - return new Promise(function(resolve) { - var data = parser.parse(fs.readFileSync(packageINI, { encoding: "utf8" }).toString()); - var result = {}; - - fs.readdir(packageDir, function(err, files) { - // get a list of folders - var folders = files.filter(function(file) { - var ignore = (packageIgnorables.indexOf(file) >= 0); - var isDir = fs.statSync(path.resolve(packageDir, file)).isDirectory(); - return (isDir && !ignore); - }).sort(); - - // get a list of "test-"" files - var files = files.filter(function(file) { - var ignore = !/^test\-.*\.js$/i.test(file); - var isDir = fs.statSync(path.resolve(packageDir, file)).isDirectory(); - return (!isDir && !ignore); - }).sort(); - - // get a list of the support files - var support_files = packageSupportFiles.map(function(file) { - return " " + file; - }); - folders.forEach(function(folder) { - support_files.push(" " + folder + "/**"); - }); - support_files = support_files.sort(); - - // copy any related data from the existing ini - files.forEach(function(file) { - var oldData = data[file]; - result[file] = oldData ? oldData : {}; - }); - - // build a new ini file - var contents = [ - "[DEFAULT]", - "support-files =" - ]; - support_files.forEach(function(support_file) { - contents.push(support_file); - }); - contents.push(""); - - Object.keys(result).sort().forEach(function(key) { - contents.push("[" + key + "]"); - Object.keys(result[key]).forEach(function(dataKey) { - contents.push(dataKey + " = " + result[key][dataKey]); - }); - }); - contents = contents.join("\n") + "\n"; - - return resolve(contents); - }); - }); -} -exports.makePackageIniContent = makePackageIniContent; - -function updatePackageINI() { - return new Promise(function(resolve) { - console.log("Start updating " + packageINI); - - makeAddonIniContent(). - then(function(contents) { - fs.writeFileSync(packageINI, contents, { encoding: "utf8" }); - console.log("Done updating " + packageINI); - resolve(); - }); - }) -} -exports.updatePackageINI = updatePackageINI; diff --git a/addon-sdk/source/bin/node-scripts/utils.js b/addon-sdk/source/bin/node-scripts/utils.js index 1d7f94474cf9..9cb47d04e235 100644 --- a/addon-sdk/source/bin/node-scripts/utils.js +++ b/addon-sdk/source/bin/node-scripts/utils.js @@ -65,9 +65,6 @@ function run (cmd, options, p) { if (p) { proc.stdout.pipe(p.stdout); } - else if (!isDebug) { - proc.stdout.pipe(DEFAULT_PROCESS.stdout); - } else { proc.stdout.on("data", function (data) { data = (data || "") + ""; diff --git a/addon-sdk/source/gulpfile.js b/addon-sdk/source/gulpfile.js index 4020dd9d49eb..362ef11c362f 100644 --- a/addon-sdk/source/gulpfile.js +++ b/addon-sdk/source/gulpfile.js @@ -28,11 +28,7 @@ gulp.task('test:modules', function(done) { }); gulp.task('test:ini', function(done) { - require("./bin/jpm-test").run("ini").catch(console.error).then(done); -}); - -gulp.task('test:firefox-bin', function(done) { - require("./bin/jpm-test").run("firefox-bin").catch(console.error).then(done); + test("ini").catch(console.error).then(done); }); gulp.task('patch:clean', function(done) { @@ -42,3 +38,7 @@ gulp.task('patch:clean', function(done) { gulp.task('patch:apply', function(done) { patch.apply().catch(console.error).then(done); }); + +gulp.task('update:ini', function(done) { + ini.updateAddonINI().catch(console.error).then(done); +}); diff --git a/addon-sdk/source/lib/sdk/console/traceback.js b/addon-sdk/source/lib/sdk/console/traceback.js index be0fb7b94ff6..93e387b2585a 100644 --- a/addon-sdk/source/lib/sdk/console/traceback.js +++ b/addon-sdk/source/lib/sdk/console/traceback.js @@ -1,16 +1,19 @@ /* 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 = { "stability": "experimental" }; -const { Ci, components } = require("chrome"); +const { Cc, Ci, components } = require("chrome"); const { parseStack, sourceURI } = require("toolkit/loader"); const { readURISync } = require("../net/url"); +exports.sourceURI = sourceURI + function safeGetFileLine(path, line) { try { var scheme = require("../url").URL(path).scheme; diff --git a/addon-sdk/source/lib/sdk/content/sandbox.js b/addon-sdk/source/lib/sdk/content/sandbox.js index 4a66eab53b9e..503c48c67c1b 100644 --- a/addon-sdk/source/lib/sdk/content/sandbox.js +++ b/addon-sdk/source/lib/sdk/content/sandbox.js @@ -10,7 +10,6 @@ module.metadata = { const { Class } = require('../core/heritage'); const { EventTarget } = require('../event/target'); const { on, off, emit } = require('../event/core'); -const { events } = require('./sandbox/events'); const { requiresAddonGlobal } = require('./utils'); const { delay: async } = require('../lang/functional'); const { Ci, Cu, Cc } = require('chrome'); @@ -21,7 +20,8 @@ const { merge } = require('../util/object'); const { getTabForContentWindow } = require('../tabs/utils'); const { getInnerId } = require('../window/utils'); const { PlainTextConsole } = require('../console/plain-text'); -const { data } = require('../self');const { isChildLoader } = require('../remote/core'); +const { data } = require('../self'); +const { isChildLoader } = require('../remote/core'); // WeakMap of sandboxes so we can access private values const sandboxes = new WeakMap(); @@ -166,7 +166,6 @@ const WorkerSandbox = Class({ get top() top, get parent() parent }); - // Use the Greasemonkey naming convention to provide access to the // unwrapped window object so the content script can access document // JavaScript values. @@ -262,11 +261,6 @@ const WorkerSandbox = Class({ win.console = con; }; - emit(events, "content-script-before-inserted", { - window: window, - worker: worker - }); - // The order of `contentScriptFile` and `contentScript` evaluation is // intentional, so programs can load libraries like jQuery from script URLs // and use them in scripts. @@ -279,7 +273,6 @@ const WorkerSandbox = Class({ if (contentScriptFile) importScripts.apply(null, [this].concat(contentScriptFile)); - if (contentScript) { evaluateIn( this, diff --git a/addon-sdk/source/lib/sdk/deprecated/memory.js b/addon-sdk/source/lib/sdk/deprecated/memory.js new file mode 100644 index 000000000000..b2aa48e888e4 --- /dev/null +++ b/addon-sdk/source/lib/sdk/deprecated/memory.js @@ -0,0 +1,129 @@ +/* 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 = { + "stability": "deprecated" +}; + +const { Cc, Ci, Cu, components } = require("chrome"); +const { when: unload } = require("../system/unload") + +var trackedObjects = {}; +const Compacter = { + notify: function() { + var newTrackedObjects = {}; + + for (let name in trackedObjects) { + let oldBin = trackedObjects[name]; + let newBin = []; + let strongRefs = []; + + for (let i = 0, l = oldBin.length; i < l; i++) { + let strongRef = oldBin[i].weakref.get(); + + if (strongRef && strongRefs.indexOf(strongRef) == -1) { + strongRefs.push(strongRef); + newBin.push(oldBin[i]); + } + } + + if (newBin.length) + newTrackedObjects[name] = newBin; + } + + trackedObjects = newTrackedObjects; + } +}; + +var timer = Cc["@mozilla.org/timer;1"] + .createInstance(Ci.nsITimer); +timer.initWithCallback(Compacter, + 5000, + Ci.nsITimer.TYPE_REPEATING_SLACK); + +function track(object, bin, stackFrameNumber) { + var frame = components.stack.caller; + var weakref = Cu.getWeakReference(object); + + if (!bin && 'constructor' in object) + bin = object.constructor.name; + if (bin == "Object") + bin = frame.name; + if (!bin) + bin = "generic"; + if (!(bin in trackedObjects)) + trackedObjects[bin] = []; + + if (stackFrameNumber > 0) + for (var i = 0; i < stackFrameNumber; i++) + frame = frame.caller; + + trackedObjects[bin].push({weakref: weakref, + created: new Date(), + filename: frame.filename, + lineNo: frame.lineNumber, + bin: bin}); +} +exports.track = track; + +var getBins = exports.getBins = function getBins() { + var names = []; + for (let name in trackedObjects) + names.push(name); + return names; +}; + +function getObjects(bin) { + var results = []; + + function getLiveObjectsInBin(bin) { + for (let i = 0, l = bin.length; i < l; i++) { + let object = bin[i].weakref.get(); + + if (object) { + results.push(bin[i]); + } + } + } + + if (bin) { + if (bin in trackedObjects) + getLiveObjectsInBin(trackedObjects[bin]); + } + else { + for (let name in trackedObjects) + getLiveObjectsInBin(trackedObjects[name]); + } + + return results; +} +exports.getObjects = getObjects; + +function gc() { + // Components.utils.forceGC() doesn't currently perform + // cycle collection, which means that e.g. DOM elements + // won't be collected by it. Fortunately, there are + // other ways... + var test_utils = Cc["@mozilla.org/appshell/appShellService;1"] + .getService(Ci.nsIAppShellService) + .hiddenDOMWindow + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils); + test_utils.garbageCollect(); + // Clean metadata for dead objects + Compacter.notify(); + // Not sure why, but sometimes it appears that we don't get + // them all with just one CC, so let's do it again. + test_utils.garbageCollect(); +}; +exports.gc = gc; + +unload(_ => { + trackedObjects = {}; + if (timer) { + timer.cancel(); + timer = null; + } +}); 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 518d813df4dc..2f062b5b3574 100644 --- a/addon-sdk/source/lib/sdk/deprecated/unit-test-finder.js +++ b/addon-sdk/source/lib/sdk/deprecated/unit-test-finder.js @@ -8,6 +8,7 @@ module.metadata = { }; const file = require("../io/file"); +const memory = require('./memory'); const { Loader } = require("../test/loader"); const { isNative } = require('@loader/options'); @@ -131,6 +132,7 @@ let loader = Loader(module); const NOT_TESTS = ['setup', 'teardown']; var TestFinder = exports.TestFinder = function TestFinder(options) { + memory.track(this); this.filter = options.filter; this.testInProcess = options.testInProcess === false ? false : true; this.testOutOfProcess = options.testOutOfProcess === true ? true : false; diff --git a/addon-sdk/source/lib/sdk/deprecated/unit-test.js b/addon-sdk/source/lib/sdk/deprecated/unit-test.js index b93001971ced..976472f5a824 100644 --- a/addon-sdk/source/lib/sdk/deprecated/unit-test.js +++ b/addon-sdk/source/lib/sdk/deprecated/unit-test.js @@ -7,6 +7,7 @@ module.metadata = { "stability": "deprecated" }; +const memory = require("./memory"); const timer = require("../timers"); const cfxArgs = require("../test/options"); const { getTabs, closeTab, getURI, getTabId, getSelectedTab } = require("../tabs/utils"); @@ -46,6 +47,7 @@ const TestRunner = function TestRunner(options) { this.fs = options.fs; this.console = options.console || console; + memory.track(this); this.passed = 0; this.failed = 0; this.testRunSummary = []; @@ -281,46 +283,40 @@ TestRunner.prototype = { } this.isDone = true; - this.pass("This test is done."); - if (this.test.teardown) { this.test.teardown(this); } - if (this.waitTimeout !== null) { timer.clearTimeout(this.waitTimeout); this.waitTimeout = null; } - // Do not leave any callback set when calling to `waitUntil` this.waitUntilCallback = null; if (this.test.passed == 0 && this.test.failed == 0) { this._logTestFailed("empty test"); - if ("testMessage" in this.console) { this.console.testMessage(false, false, this.test.name, "Empty test"); } else { this.console.error("fail:", "Empty test") } - this.failed++; this.test.failed++; } let wins = windows(null, { includePrivate: true }); - let winPromises = wins.map(win => { - return new Promise(resolve => { - if (["interactive", "complete"].indexOf(win.document.readyState) >= 0) { - resolve() - } - else { - win.addEventListener("DOMContentLoaded", function onLoad() { - win.removeEventListener("DOMContentLoaded", onLoad, false); - resolve(); - }, false); - } - }); + let winPromises = wins.map(win => { + let { promise, resolve } = defer(); + if (["interactive", "complete"].indexOf(win.document.readyState) >= 0) { + resolve() + } + else { + win.addEventListener("DOMContentLoaded", function onLoad() { + win.removeEventListener("DOMContentLoaded", onLoad, false); + resolve(); + }, false); + } + return promise; }); PromiseDebugging.flushUncaughtErrors(); @@ -362,17 +358,9 @@ TestRunner.prototype = { } } - return failure; - }). - then(failure => { - if (!failure) { - this.pass("There was a clean UI."); - return null; - } - return cleanUI().then(() => { - this.pass("There is a clean UI."); - }); + return null; }). + then(cleanUI). then(() => { this.testRunSummary.push({ name: this.test.name, diff --git a/addon-sdk/source/lib/sdk/io/text-streams.js b/addon-sdk/source/lib/sdk/io/text-streams.js index ed4ec4972b29..7a385cf03c49 100644 --- a/addon-sdk/source/lib/sdk/io/text-streams.js +++ b/addon-sdk/source/lib/sdk/io/text-streams.js @@ -1,15 +1,17 @@ /* 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 = { "stability": "experimental" }; -const { Cc, Ci, Cu, components } = require("chrome"); -const { ensure } = require("../system/unload"); -const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {}); +const {Cc,Ci,Cu,components} = require("chrome"); +var NetUtil = {}; +Cu.import("resource://gre/modules/NetUtil.jsm", NetUtil); +NetUtil = NetUtil.NetUtil; // NetUtil.asyncCopy() uses this buffer length, and since we call it, for best // performance we use it, too. @@ -17,6 +19,8 @@ const BUFFER_BYTE_LEN = 0x8000; const PR_UINT32_MAX = 0xffffffff; const DEFAULT_CHARSET = "UTF-8"; +exports.TextReader = TextReader; +exports.TextWriter = TextWriter; /** * An input stream that reads text from a backing stream using a given text @@ -31,6 +35,7 @@ const DEFAULT_CHARSET = "UTF-8"; * documentation on how to determine other valid values for this. */ function TextReader(inputStream, charset) { + const self = this; charset = checkCharset(charset); let stream = Cc["@mozilla.org/intl/converter-input-stream;1"]. @@ -84,7 +89,6 @@ function TextReader(inputStream, charset) { return str; }; } -exports.TextReader = TextReader; /** * A buffered output stream that writes text to a backing stream using a given @@ -99,6 +103,7 @@ exports.TextReader = TextReader; * for documentation on how to determine other valid values for this. */ function TextWriter(outputStream, charset) { + const self = this; charset = checkCharset(charset); let stream = outputStream; @@ -164,7 +169,7 @@ function TextWriter(outputStream, charset) { this.writeAsync = function TextWriter_writeAsync(str, callback) { manager.ensureOpened(); let istream = uconv.convertToInputStream(str); - NetUtil.asyncCopy(istream, stream, (result) => { + NetUtil.asyncCopy(istream, stream, function (result) { let err = components.isSuccessCode(result) ? undefined : new Error("An error occured while writing to the stream: " + result); if (err) @@ -175,7 +180,7 @@ function TextWriter(outputStream, charset) { if (typeof(callback) === "function") { try { - callback.call(this, err); + callback.call(self, err); } catch (exc) { console.exception(exc); @@ -184,32 +189,34 @@ function TextWriter(outputStream, charset) { }); }; } -exports.TextWriter = TextWriter; // This manages the lifetime of stream, a TextReader or TextWriter. It defines // closed and close() on stream and registers an unload listener that closes // rawStream if it's still opened. It also provides ensureOpened(), which // throws an exception if the stream is closed. function StreamManager(stream, rawStream) { + const self = this; this.rawStream = rawStream; this.opened = true; /** * True iff the stream is closed. */ - stream.__defineGetter__("closed", () => !this.opened); + stream.__defineGetter__("closed", function stream_closed() { + return !self.opened; + }); /** * Closes both the stream and its backing stream. If the stream is already * closed, an exception is thrown. For TextWriters, this first flushes the * backing stream's buffer. */ - stream.close = () => { - this.ensureOpened(); - this.unload(); + stream.close = function stream_close() { + self.ensureOpened(); + self.unload(); }; - ensure(this); + require("../system/unload").ensure(this); } StreamManager.prototype = { diff --git a/addon-sdk/source/lib/sdk/places/host/host-query.js b/addon-sdk/source/lib/sdk/places/host/host-query.js index 6ce12c231c95..12ba203afcd6 100644 --- a/addon-sdk/source/lib/sdk/places/host/host-query.js +++ b/addon-sdk/source/lib/sdk/places/host/host-query.js @@ -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"; module.metadata = { @@ -12,7 +13,7 @@ module.metadata = { }; const { Cc, Ci } = require('chrome'); -const { all } = require('../../core/promise'); +const { defer, all, resolve } = require('../../core/promise'); const { safeMerge, omit } = require('../../util/object'); const historyService = Cc['@mozilla.org/browser/nav-history-service;1'] .getService(Ci.nsINavHistoryService); @@ -44,11 +45,13 @@ const PLACES_PROPERTIES = [ ]; function execute (queries, options) { - return new Promise(resolve => { - let root = historyService - .executeQueries(queries, queries.length, options).root; - resolve(collect([], root)); - }); + let deferred = defer(); + let root = historyService + .executeQueries(queries, queries.length, options).root; + + let items = collect([], root); + deferred.resolve(items); + return deferred.promise; } function collect (acc, node) { @@ -66,35 +69,40 @@ function collect (acc, node) { } function query (queries, options) { - return new Promise((resolve, reject) => { - queries = queries || []; - options = options || {}; - let optionsObj, queryObjs; + queries = queries || []; + options = options || {}; + let deferred = defer(); + let optionsObj, queryObjs; + try { optionsObj = historyService.getNewQueryOptions(); queryObjs = [].concat(queries).map(createQuery); if (!queryObjs.length) { queryObjs = [historyService.getNewQuery()]; } safeMerge(optionsObj, options); + } catch (e) { + deferred.reject(e); + return deferred.promise; + } - /* - * Currently `places:` queries are not supported - */ - optionsObj.excludeQueries = true; + /* + * Currently `places:` queries are not supported + */ + optionsObj.excludeQueries = true; - execute(queryObjs, optionsObj).then((results) => { - if (optionsObj.queryType === 0) { - return results.map(normalize); - } - else if (optionsObj.queryType === 1) { - // Formats query results into more standard - // data structures for returning - return all(results.map(({itemId}) => - send('sdk-places-bookmarks-get', { id: itemId }))); - } - }).then(resolve, reject); - }); + execute(queryObjs, optionsObj).then(function (results) { + if (optionsObj.queryType === 0) { + return results.map(normalize); + } else if (optionsObj.queryType === 1) { + // Formats query results into more standard + // data structures for returning + return all(results.map(({itemId}) => + send('sdk-places-bookmarks-get', { id: itemId }))); + } + }).then(deferred.resolve, deferred.reject); + + return deferred.promise; } exports.query = query; @@ -132,7 +140,7 @@ function queryReceiver (message) { /* * Converts a nsINavHistoryResultNode into a plain object - * + * * https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsINavHistoryResultNode */ function normalize (historyObj) { @@ -142,8 +150,7 @@ function normalize (historyObj) { else if (prop === 'time') { // Cast from microseconds to milliseconds obj.time = Math.floor(historyObj.time / 1000) - } - else if (prop === 'accessCount') + } else if (prop === 'accessCount') obj.visitCount = historyObj[prop]; else obj[prop] = historyObj[prop]; diff --git a/addon-sdk/source/lib/sdk/places/utils.js b/addon-sdk/source/lib/sdk/places/utils.js index f03a8f6a75a5..e016a1452532 100644 --- a/addon-sdk/source/lib/sdk/places/utils.js +++ b/addon-sdk/source/lib/sdk/places/utils.js @@ -51,14 +51,14 @@ exports.TreeNode = TreeNode; /* * Descends down from `node` applying `fn` to each in order. * `fn` can return values or promises -- if promise returned, - * children are not processed until resolved. `fn` is passed + * children are not processed until resolved. `fn` is passed * one argument, the current node, `curr`. */ function walk (curr, fn) { return promised(fn)(curr).then(val => { return all(curr.children.map(child => walk(child, fn))); }); -} +} /* * Descends from the TreeNode `node`, returning @@ -122,7 +122,7 @@ exports.isRootGroup = isRootGroup; /* * Merges appropriate options into query based off of url * 4 scenarios: - * + * * 'moz.com' // domain: moz.com, domainIsHost: true * --> 'http://moz.com', 'http://moz.com/thunderbird' * '*.moz.com' // domain: moz.com, domainIsHost: false @@ -177,9 +177,9 @@ function createQuery (type, query) { let qObj = { searchTerms: query.query }; - + urlQueryParser(qObj, query.url); - + // 0 === history if (type === 0) { // PRTime used by query is in microseconds, not milliseconds @@ -194,7 +194,7 @@ function createQuery (type, query) { else if (type === 1) { qObj.tags = query.tags; qObj.folder = query.group && query.group.id; - } + } // 2 === unified (not implemented on platform) else if (type === 2) { diff --git a/addon-sdk/source/lib/sdk/test/harness.js b/addon-sdk/source/lib/sdk/test/harness.js index c5e3f09d4930..b32cf54f7ef1 100644 --- a/addon-sdk/source/lib/sdk/test/harness.js +++ b/addon-sdk/source/lib/sdk/test/harness.js @@ -15,6 +15,7 @@ const { PlainTextConsole } = require("../console/plain-text"); const { when: unload } = require("../system/unload"); const { format, fromException } = require("../console/traceback"); const system = require("../system"); +const memory = require('../deprecated/memory'); const { gc: gcPromise } = require('./memory'); const { defer } = require('../core/promise'); const { extend } = require('../core/heritage'); @@ -149,7 +150,7 @@ function reportMemoryUsage() { return emptyPromise(); } - return gcPromise().then((() => { + return gcPromise().then((function () { var mgr = Cc["@mozilla.org/memory-reporter-manager;1"] .getService(Ci.nsIMemoryReporterManager); let count = 0; @@ -157,6 +158,11 @@ function reportMemoryUsage() { print(((++count == 1) ? "\n" : "") + description + ": " + amount + "\n"); } mgr.getReportsForThisProcess(logReporter, null, /* anonymize = */ false); + + var weakrefs = [info.weakref.get() + for (info of memory.getObjects())]; + weakrefs = [weakref for (weakref of weakrefs) if (weakref)]; + print("Tracked memory objects in testing sandbox: " + weakrefs.length + "\n"); })); } @@ -210,6 +216,16 @@ function showResults() { function cleanup() { let coverObject = {}; try { + for (let name in loader.modules) + memory.track(loader.modules[name], + "module global scope: " + name); + memory.track(loader, "Cuddlefish Loader"); + + if (profileMemory) { + gWeakrefInfo = [{ weakref: info.weakref, bin: info.bin } + for (info of memory.getObjects())]; + } + loader.unload(); if (loader.globals.console.errorsLogged && !results.failed) { @@ -235,7 +251,7 @@ function cleanup() { consoleListener.unregister(); - Cu.forceGC(); + memory.gc(); } catch (e) { results.failed++; @@ -262,7 +278,7 @@ function cleanup() { } function getPotentialLeaks() { - Cu.forceGC(); + memory.gc(); // Things we can assume are part of the platform and so aren't leaks let GOOD_BASE_URLS = [ diff --git a/addon-sdk/source/lib/sdk/test/memory.js b/addon-sdk/source/lib/sdk/test/memory.js index bd1198bfe52d..1c564331266f 100644 --- a/addon-sdk/source/lib/sdk/test/memory.js +++ b/addon-sdk/source/lib/sdk/test/memory.js @@ -4,8 +4,17 @@ 'use strict'; const { Cu } = require("chrome"); +const memory = require('../deprecated/memory'); +const { defer } = require('../core/promise'); function gc() { - return new Promise(resolve => Cu.schedulePreciseGC(resolve)); + let { promise, resolve } = defer(); + + Cu.forceGC(); + memory.gc(); + + Cu.schedulePreciseGC(_ => resolve()); + + return promise; } exports.gc = gc; diff --git a/addon-sdk/source/lib/sdk/util/bond.js b/addon-sdk/source/lib/sdk/util/bond.js new file mode 100644 index 000000000000..422f57737e17 --- /dev/null +++ b/addon-sdk/source/lib/sdk/util/bond.js @@ -0,0 +1,36 @@ +/* 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 = { + "stability": "experimental" +}; + +const makeDescriptor = (name, method) => ({ + get() { + if (!Object.hasOwnProperty.call(this, name)) { + Object.defineProperty(this, name, {value: method.bind(this)}); + return this[name]; + } else { + return method; + } + } +}); + +const Bond = function(methods) { + let descriptor = {}; + let members = [...Object.getOwnPropertyNames(methods), + ...Object.getOwnPropertySymbols(methods)]; + + for (let name of members) { + let method = methods[name]; + if (typeof(method) !== "function") { + throw new TypeError(`Property named "${name}" passed to Bond must be a function`); + } + descriptor[name] = makeDescriptor(name, method); + } + + return Object.create(Bond.prototype, descriptor); +} +exports.Bond = Bond; diff --git a/addon-sdk/source/lib/sdk/zip/utils.js b/addon-sdk/source/lib/sdk/zip/utils.js index e600380cbea6..bc1e0b610b7e 100644 --- a/addon-sdk/source/lib/sdk/zip/utils.js +++ b/addon-sdk/source/lib/sdk/zip/utils.js @@ -1,16 +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"; +'use strict'; -const { Cc, Ci } = require("chrome"); +const { Cc, Ci, Cu } = require("chrome"); +const { defer } = require("../core/promise"); -function getZipReader(aFile) { - return new Promise(resolve => { - let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"]. - createInstance(Ci.nsIZipReader); +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); - resolve(zipReader); - }); + } + catch(e){ + reject(e); + } + resolve(zipReader); + return promise; }; exports.getZipReader = getZipReader; diff --git a/addon-sdk/source/mapping.json b/addon-sdk/source/mapping.json index d8f497a26fc7..18b78b979a1f 100644 --- a/addon-sdk/source/mapping.json +++ b/addon-sdk/source/mapping.json @@ -13,6 +13,7 @@ "l10n/prefs": "sdk/l10n/prefs", "list": "sdk/util/list", "loader": "sdk/loader/loader", + "memory": "sdk/deprecated/memory", "namespace": "sdk/core/namespace", "preferences-service": "sdk/preferences/service", "promise": "sdk/core/promise", diff --git a/addon-sdk/source/package.json b/addon-sdk/source/package.json index 5a9707afb838..35a4e9c9034e 100644 --- a/addon-sdk/source/package.json +++ b/addon-sdk/source/package.json @@ -22,7 +22,6 @@ "async": "0.9.0", "chai": "2.1.1", "fs-extra": "0.18.2", - "fx-runner": "0.0.7", "glob": "4.4.2", "gulp": "3.8.11", "ini-parser": "0.0.2", diff --git a/addon-sdk/source/python-lib/cuddlefish/__init__.py b/addon-sdk/source/python-lib/cuddlefish/__init__.py index 365d96c5ef4d..7fafe14689b1 100644 --- a/addon-sdk/source/python-lib/cuddlefish/__init__.py +++ b/addon-sdk/source/python-lib/cuddlefish/__init__.py @@ -236,6 +236,10 @@ parser_groups = ( help="Where to put the finished .xpi", default=None, cmds=['xpi'])), + (("", "--manifest-overload",), dict(dest="manifest_overload", + help="JSON file to overload package.json properties", + default=None, + cmds=['xpi'])), (("", "--abort-on-missing-module",), dict(dest="abort_on_missing", help="Abort if required module is missing", action="store_true", @@ -657,6 +661,10 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None, target_cfg_json = os.path.join(options.pkgdir, 'package.json') target_cfg = packaging.get_config_in_dir(options.pkgdir) + if options.manifest_overload: + for k, v in packaging.load_json_file(options.manifest_overload).items(): + target_cfg[k] = v + # At this point, we're either building an XPI or running Jetpack code in # a Mozilla application (which includes running tests). diff --git a/addon-sdk/source/python-lib/cuddlefish/tests/addons/simplest-test/main.js b/addon-sdk/source/python-lib/cuddlefish/tests/addons/simplest-test/main.js new file mode 100644 index 000000000000..22018c2a2eb0 --- /dev/null +++ b/addon-sdk/source/python-lib/cuddlefish/tests/addons/simplest-test/main.js @@ -0,0 +1,17 @@ +/* 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/. */ + +const { Cc, Ci } = require("chrome"); + +exports.main = function(options, callbacks) { + // Close Firefox window. Firefox should quit. + require("sdk/deprecated/window-utils").activeBrowserWindow.close(); + + // But not on Mac where it stay alive! We have to request application quit. + if (require("sdk/system/runtime").OS == "Darwin") { + let appStartup = Cc['@mozilla.org/toolkit/app-startup;1']. + getService(Ci.nsIAppStartup); + appStartup.quit(appStartup.eAttemptQuit); + } +} diff --git a/addon-sdk/source/python-lib/cuddlefish/tests/addons/simplest-test/manifest-overload.json b/addon-sdk/source/python-lib/cuddlefish/tests/addons/simplest-test/manifest-overload.json new file mode 100644 index 000000000000..a446378b0cfb --- /dev/null +++ b/addon-sdk/source/python-lib/cuddlefish/tests/addons/simplest-test/manifest-overload.json @@ -0,0 +1,3 @@ +{ + "version": "1.0-nightly" +} diff --git a/addon-sdk/source/python-lib/cuddlefish/tests/addons/simplest-test/package.json b/addon-sdk/source/python-lib/cuddlefish/tests/addons/simplest-test/package.json new file mode 100644 index 000000000000..afbc15803daa --- /dev/null +++ b/addon-sdk/source/python-lib/cuddlefish/tests/addons/simplest-test/package.json @@ -0,0 +1,6 @@ +{ + "id": "simplest-test", + "directories": { + "lib": "." + } +} diff --git a/addon-sdk/source/lib/sdk/content/sandbox/events.js b/addon-sdk/source/python-lib/cuddlefish/tests/addons/simplest-test/tests/test-minimal.js similarity index 65% rename from addon-sdk/source/lib/sdk/content/sandbox/events.js rename to addon-sdk/source/python-lib/cuddlefish/tests/addons/simplest-test/tests/test-minimal.js index d6f7eb004063..533cd34e6fba 100644 --- a/addon-sdk/source/lib/sdk/content/sandbox/events.js +++ b/addon-sdk/source/python-lib/cuddlefish/tests/addons/simplest-test/tests/test-minimal.js @@ -2,11 +2,6 @@ * 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 = { - "stability": "experimental" +exports.minimalTest = function(test) { + test.assert(true); }; - -const events = {}; -exports.events = events; 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 5ececfea6020..f331b09cbea9 100644 --- a/addon-sdk/source/python-lib/cuddlefish/tests/test_init.py +++ b/addon-sdk/source/python-lib/cuddlefish/tests/test_init.py @@ -182,6 +182,35 @@ class TestCfxQuits(unittest.TestCase): container) self.fail(standardMsg) + def test_cfx_run(self): + addon_path = os.path.join(tests_path, + "addons", "simplest-test") + rc, out, err = self.run_cfx(addon_path, ["run"]) + self.assertEqual(rc, 0) + self.assertIn("Program terminated successfully.", err) + + def test_cfx_test(self): + 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) + self.assertIn("Program terminated successfully.", err) + + def test_cfx_xpi(self): + addon_path = os.path.join(tests_path, + "addons", "simplest-test") + rc, out, err = self.run_cfx(addon_path, \ + ["xpi", "--manifest-overload", "manifest-overload.json"]) + self.assertEqual(rc, 0) + # Ensure that the addon version from our manifest overload is used + # in install.rdf + xpi_path = os.path.join(addon_path, "simplest-test.xpi") + xpi = zipfile.ZipFile(xpi_path, "r") + manifest = xpi.read("install.rdf") + self.assertIn("1.0-nightly", manifest) + xpi.close() + os.remove(xpi_path) + def test_cfx_init(self): # Create an empty test directory addon_path = os.path.abspath(os.path.join(".test_tmp", "test-cfx-init")) @@ -203,7 +232,7 @@ class TestCfxQuits(unittest.TestCase): # run cfx test rc, out, err = self.run_cfx(addon_path, ["test"]) self.assertEqual(rc, 0) - self.assertIn("6 of 6 tests passed.", err) + self.assertIn("2 of 2 tests passed.", err) self.assertIn("Program terminated successfully.", err) diff --git a/addon-sdk/source/test/addons/chrome/data/panel.js b/addon-sdk/source/test/addons/chrome/data/panel.js index c38eca85227d..ae728ed898b6 100644 --- a/addon-sdk/source/test/addons/chrome/data/panel.js +++ b/addon-sdk/source/test/addons/chrome/data/panel.js @@ -6,5 +6,3 @@ self.port.on('echo', _ => { self.port.emit('echo', ''); }); - -self.port.emit('start', ''); diff --git a/addon-sdk/source/test/addons/chrome/main.js b/addon-sdk/source/test/addons/chrome/main.js index 84b82245842d..62e2d691056b 100644 --- a/addon-sdk/source/test/addons/chrome/main.js +++ b/addon-sdk/source/test/addons/chrome/main.js @@ -67,31 +67,23 @@ exports.testChromeLocale = function(assert) { 'locales en-US folder was copied correctly'); } -exports.testChromeInPanel = function*(assert) { +exports.testChromeInPanel = function(assert, done) { let panel = Panel({ contentURL: 'chrome://test/content/panel.html', - contentScriptWhen: 'end', + contentScriptWhen: 'start', contentScriptFile: data.url('panel.js') }); - - yield new Promise(resolve => panel.port.once('start', resolve)); - assert.pass('start was emitted'); - - yield new Promise(resolve => { - panel.once('show', resolve); - panel.show(); - }); - assert.pass('panel shown'); - - yield new Promise(resolve => { - panel.port.once('echo', resolve); + panel.once('show', _ => { + assert.pass('panel shown'); + panel.port.once('echo', _ => { + assert.pass('got echo'); + panel.destroy(); + assert.pass('panel is destroyed'); + done(); + }); panel.port.emit('echo'); }); - - assert.pass('got echo'); - - panel.destroy(); - assert.pass('panel is destroyed'); + panel.show(); } require('sdk/test/runner').runTestsFromModule(module); diff --git a/addon-sdk/source/test/addons/layout-change/lib/test-cuddlefish-loader.js b/addon-sdk/source/test/addons/layout-change/lib/test-cuddlefish-loader.js index f4d7c0edf39f..e1cbddf7c2b9 100644 --- a/addon-sdk/source/test/addons/layout-change/lib/test-cuddlefish-loader.js +++ b/addon-sdk/source/test/addons/layout-change/lib/test-cuddlefish-loader.js @@ -147,6 +147,9 @@ exports["test compatibility"] = function(assert) { assert.equal(require("tabs/tab.js"), require("sdk/tabs/tab"), "sdk/tabs/tab -> tabs/tab.js"); + assert.equal(require("memory"), + require("sdk/deprecated/memory"), "sdk/deprecated/memory -> memory"); + assert.equal(require("environment"), require("sdk/system/environment"), "sdk/system/environment -> environment"); diff --git a/addon-sdk/source/test/addons/places/lib/places-helper.js b/addon-sdk/source/test/addons/places/lib/places-helper.js index 5a20db42cd70..fb6cc6313289 100644 --- a/addon-sdk/source/test/addons/places/lib/places-helper.js +++ b/addon-sdk/source/test/addons/places/lib/places-helper.js @@ -33,6 +33,13 @@ function invalidResolve (assert) { } exports.invalidResolve = invalidResolve; +function invalidReject (assert) { + return function (e) { + assert.fail('Reject state should not be called: ' + e); + }; +} +exports.invalidReject = invalidReject; + // Removes all children of group function clearBookmarks (group) { group diff --git a/addon-sdk/source/test/addons/places/lib/test-places-bookmarks.js b/addon-sdk/source/test/addons/places/lib/test-places-bookmarks.js index d04334714ea6..f329e91ab400 100644 --- a/addon-sdk/source/test/addons/places/lib/test-places-bookmarks.js +++ b/addon-sdk/source/test/addons/places/lib/test-places-bookmarks.js @@ -24,7 +24,7 @@ const { MENU, TOOLBAR, UNSORTED } = require('sdk/places/bookmarks'); const { - invalidResolve, createTree, + invalidResolve, invalidReject, createTree, compareWithHost, createBookmark, createBookmarkItem, createBookmarkTree, addVisits, resetPlaces } = require('./places-helper'); @@ -369,27 +369,28 @@ exports.testPromisedSave = function (assert, done) { }).then(done).catch(assert.fail); }; -exports.testPromisedErrorSave = function*(assert) { +exports.testPromisedErrorSave = function (assert, done) { let bookmarks = [ { title: 'moz1', url: 'http://moz1.com', type: 'bookmark'}, { title: 'moz2', url: 'invalidurl', type: 'bookmark'}, { title: 'moz3', url: 'http://moz3.com', type: 'bookmark'} ]; - yield saveP(bookmarks).then(() => { - assert.fail("should not resolve"); - }, reason => { + saveP(bookmarks).then(invalidResolve, reason => { assert.ok( /The `url` property must be a valid URL/.test(reason), 'Error event called with correct reason'); - }); - bookmarks[1].url = 'http://moz2.com'; - yield saveP(bookmarks); - - let res = yield searchP({ query: 'moz' }); - assert.equal(res.length, 3, 'all 3 should be saved upon retry'); - res.map(item => assert.ok(/moz\d\.com/.test(item.url), 'correct item')); + bookmarks[1].url = 'http://moz2.com'; + return saveP(bookmarks); + }). + then(res => searchP({ query: 'moz' })). + then(res => { + assert.equal(res.length, 3, 'all 3 should be saved upon retry'); + res.map(item => assert.ok(/moz\d\.com/.test(item.url), 'correct item')); + done(); + }, invalidReject). + catch(assert.fail); }; exports.testMovingChildren = function (assert, done) { @@ -691,63 +692,61 @@ exports.testSearchTags = function (assert, done) { * 'http://mozilla.com/' * 'http://mozilla.com/*' */ -exports.testSearchURLForBookmarks = function*(assert) { - yield createBookmarkTree() - let data = yield searchP({ url: 'mozilla.org' }); - - assert.equal(data.length, 2, 'only URLs with host domain'); - assert.equal(data[0].url, 'http://mozilla.org/'); - assert.equal(data[1].url, 'http://mozilla.org/thunderbird/'); - - data = yield searchP({ url: '*.mozilla.org' }); - - assert.equal(data.length, 3, 'returns domain and when host is other than domain'); - assert.equal(data[0].url, 'http://mozilla.org/'); - assert.equal(data[1].url, 'http://mozilla.org/thunderbird/'); - assert.equal(data[2].url, 'http://developer.mozilla.org/en-US/'); - - data = yield searchP({ url: 'http://mozilla.org' }); - - assert.equal(data.length, 1, 'only exact URL match'); - assert.equal(data[0].url, 'http://mozilla.org/'); - - data = yield searchP({ url: 'http://mozilla.org/*' }); - - assert.equal(data.length, 2, 'only URLs that begin with query'); - assert.equal(data[0].url, 'http://mozilla.org/'); - assert.equal(data[1].url, 'http://mozilla.org/thunderbird/'); - - data = yield searchP([{ url: 'mozilla.org' }, { url: 'component.fm' }]); - - assert.equal(data.length, 3, 'returns URLs that match EITHER query'); - assert.equal(data[0].url, 'http://mozilla.org/'); - assert.equal(data[1].url, 'http://mozilla.org/thunderbird/'); - assert.equal(data[2].url, 'http://component.fm/'); +exports.testSearchURL = function (assert, done) { + createBookmarkTree().then(() => { + return searchP({ url: 'mozilla.org' }); + }).then(data => { + assert.equal(data.length, 2, 'only URLs with host domain'); + assert.equal(data[0].url, 'http://mozilla.org/'); + assert.equal(data[1].url, 'http://mozilla.org/thunderbird/'); + return searchP({ url: '*.mozilla.org' }); + }).then(data => { + assert.equal(data.length, 3, 'returns domain and when host is other than domain'); + assert.equal(data[0].url, 'http://mozilla.org/'); + assert.equal(data[1].url, 'http://mozilla.org/thunderbird/'); + assert.equal(data[2].url, 'http://developer.mozilla.org/en-US/'); + return searchP({ url: 'http://mozilla.org' }); + }).then(data => { + assert.equal(data.length, 1, 'only exact URL match'); + assert.equal(data[0].url, 'http://mozilla.org/'); + return searchP({ url: 'http://mozilla.org/*' }); + }).then(data => { + assert.equal(data.length, 2, 'only URLs that begin with query'); + assert.equal(data[0].url, 'http://mozilla.org/'); + assert.equal(data[1].url, 'http://mozilla.org/thunderbird/'); + return searchP([{ url: 'mozilla.org' }, { url: 'component.fm' }]); + }).then(data => { + assert.equal(data.length, 3, 'returns URLs that match EITHER query'); + assert.equal(data[0].url, 'http://mozilla.org/'); + assert.equal(data[1].url, 'http://mozilla.org/thunderbird/'); + assert.equal(data[2].url, 'http://component.fm/'); + }).then(done).catch(assert.fail); }; /* * Searches url, title, tags */ -exports.testSearchQueryForBookmarks = function*(assert) { - yield createBookmarkTree(); - - let data = yield searchP({ query: 'thunder' }); - assert.equal(data.length, 3); - assert.equal(data[0].title, 'mozilla.com', 'query matches tag, url, or title'); - assert.equal(data[1].title, 'mozilla.org', 'query matches tag, url, or title'); - assert.equal(data[2].title, 'thunderbird', 'query matches tag, url, or title'); - - data = yield searchP([{ query: 'rust' }, { query: 'component' }]); - // rust OR component - assert.equal(data.length, 3); - assert.equal(data[0].title, 'mozilla.com', 'query matches tag, url, or title'); - assert.equal(data[1].title, 'mozilla.org', 'query matches tag, url, or title'); - assert.equal(data[2].title, 'web audio components', 'query matches tag, url, or title'); - - data = yield searchP([{ query: 'moz', tags: ['javascript']}]); - assert.equal(data.length, 1); - assert.equal(data[0].title, 'mdn', - 'only one item matches moz query AND has a javascript tag'); +exports.testSearchQuery = function (assert, done) { + createBookmarkTree().then(() => { + return searchP({ query: 'thunder' }); + }).then(data => { + assert.equal(data.length, 3); + assert.equal(data[0].title, 'mozilla.com', 'query matches tag, url, or title'); + assert.equal(data[1].title, 'mozilla.org', 'query matches tag, url, or title'); + assert.equal(data[2].title, 'thunderbird', 'query matches tag, url, or title'); + return searchP([{ query: 'rust' }, { query: 'component' }]); + }).then(data => { + // rust OR component + assert.equal(data.length, 3); + assert.equal(data[0].title, 'mozilla.com', 'query matches tag, url, or title'); + assert.equal(data[1].title, 'mozilla.org', 'query matches tag, url, or title'); + assert.equal(data[2].title, 'web audio components', 'query matches tag, url, or title'); + return searchP([{ query: 'moz', tags: ['javascript']}]); + }).then(data => { + assert.equal(data.length, 1); + assert.equal(data[0].title, 'mdn', + 'only one item matches moz query AND has a javascript tag'); + }).then(done).catch(assert.fail); }; /* @@ -828,7 +827,7 @@ exports.testSearchCount = function (assert, done) { } }; -exports.testSearchSortForBookmarks = function (assert, done) { +exports.testSearchSort = function (assert, done) { let urls = [ 'http://mozilla.com/', 'http://webaud.io/', 'http://mozilla.com/webfwd/', 'http://developer.mozilla.com/', 'http://bandcamp.com/' diff --git a/addon-sdk/source/test/addons/places/lib/test-places-events.js b/addon-sdk/source/test/addons/places/lib/test-places-events.js index dc033f6a8814..e31385238ffe 100644 --- a/addon-sdk/source/test/addons/places/lib/test-places-events.js +++ b/addon-sdk/source/test/addons/places/lib/test-places-events.js @@ -27,7 +27,7 @@ const isOSX10_6 = (() => { const { search } = require('sdk/places/history'); const { - invalidResolve, createTree, createBookmark, + invalidResolve, invalidReject, createTree, createBookmark, compareWithHost, addVisits, resetPlaces, createBookmarkItem, removeVisits, historyBatch } = require('./places-helper'); diff --git a/addon-sdk/source/test/addons/places/lib/test-places-history.js b/addon-sdk/source/test/addons/places/lib/test-places-history.js index 8aed2999b933..e53f26ba1cf0 100644 --- a/addon-sdk/source/test/addons/places/lib/test-places-history.js +++ b/addon-sdk/source/test/addons/places/lib/test-places-history.js @@ -19,44 +19,45 @@ const { search } = require('sdk/places/history'); const { - invalidResolve, createTree, + invalidResolve, invalidReject, createTree, compareWithHost, addVisits, resetPlaces } = require('./places-helper'); const { promisedEmitter } = require('sdk/places/utils'); -exports.testEmptyQuery = function*(assert) { +exports.testEmptyQuery = function (assert, done) { let within = toBeWithin(); - yield addVisits([ + addVisits([ 'http://simplequery-1.com', 'http://simplequery-2.com' - ]); - - let results = yield searchP(); - assert.equal(results.length, 2, 'Correct number of entries returned'); - assert.equal(results[0].url, 'http://simplequery-1.com/', - 'matches url'); - assert.equal(results[1].url, 'http://simplequery-2.com/', - 'matches url'); - assert.equal(results[0].title, 'Test visit for ' + results[0].url, - 'title matches'); - assert.equal(results[1].title, 'Test visit for ' + results[1].url, - 'title matches'); - assert.equal(results[0].visitCount, 1, 'matches access'); - assert.equal(results[1].visitCount, 1, 'matches access'); - assert.ok(within(results[0].time), 'accurate access time'); - assert.ok(within(results[1].time), 'accurate access time'); - assert.equal(Object.keys(results[0]).length, 4, - 'no addition exposed properties on history result'); + ]).then(searchP).then(results => { + assert.equal(results.length, 2, 'Correct number of entries returned'); + assert.equal(results[0].url, 'http://simplequery-1.com/', + 'matches url'); + assert.equal(results[1].url, 'http://simplequery-2.com/', + 'matches url'); + assert.equal(results[0].title, 'Test visit for ' + results[0].url, + 'title matches'); + assert.equal(results[1].title, 'Test visit for ' + results[1].url, + 'title matches'); + assert.equal(results[0].visitCount, 1, 'matches access'); + assert.equal(results[1].visitCount, 1, 'matches access'); + assert.ok(within(results[0].time), 'accurate access time'); + assert.ok(within(results[1].time), 'accurate access time'); + assert.equal(Object.keys(results[0]).length, 4, + 'no addition exposed properties on history result'); + done(); + }, invalidReject); }; -exports.testVisitCount = function*(assert) { - yield addVisits([ +exports.testVisitCount = function (assert, done) { + addVisits([ 'http://simplequery-1.com', 'http://simplequery-1.com', 'http://simplequery-1.com', 'http://simplequery-1.com' - ]); - let results = yield searchP(); - assert.equal(results.length, 1, 'Correct number of entries returned'); - assert.equal(results[0].url, 'http://simplequery-1.com/', 'correct url'); - assert.equal(results[0].visitCount, 4, 'matches access count'); + ]).then(searchP).then(results => { + assert.equal(results.length, 1, 'Correct number of entries returned'); + assert.equal(results[0].url, 'http://simplequery-1.com/', 'correct url'); + assert.equal(results[0].visitCount, 4, 'matches access count'); + done(); + }, invalidReject); }; /* @@ -66,23 +67,24 @@ exports.testVisitCount = function*(assert) { * 'http://mozilla.org/' * 'http://mozilla.org/*' */ -exports.testSearchURLForHistory = function*(assert) { - yield addVisits([ +exports.testSearchURL = function (assert, done) { + addVisits([ 'http://developer.mozilla.org', 'http://mozilla.org', 'http://mozilla.org/index', 'https://mozilla.org' - ]); - - let results = yield searchP({ url: 'http://mozilla.org/' }); - assert.equal(results.length, 1, 'should just be an exact match'); - - results = yield searchP({ url: '*.mozilla.org' }); - assert.equal(results.length, 4, 'returns all entries'); - - results = yield searchP({ url: 'mozilla.org' }); - assert.equal(results.length, 3, 'returns entries where mozilla.org is host'); - - results = yield searchP({ url: 'http://mozilla.org/*' }); - assert.equal(results.length, 2, 'should match anything starting with substring'); + ]).then(() => searchP({ url: '*.mozilla.org' })) + .then(results => { + assert.equal(results.length, 4, 'returns all entries'); + return searchP({ url: 'mozilla.org' }); + }).then(results => { + assert.equal(results.length, 3, 'returns entries where mozilla.org is host'); + return searchP({ url: 'http://mozilla.org/' }); + }).then(results => { + assert.equal(results.length, 1, 'should just be an exact match'); + return searchP({ url: 'http://mozilla.org/*' }); + }).then(results => { + assert.equal(results.length, 2, 'should match anything starting with substring'); + done(); + }); }; // Disabling due to intermittent Bug 892619 @@ -122,21 +124,23 @@ exports.testSearchTimeRange = function (assert, done) { }); }; */ -exports.testSearchQueryForHistory = function*(assert) { - yield addVisits([ +exports.testSearchQuery = function (assert, done) { + addVisits([ 'http://mozilla.com', 'http://webaud.io', 'http://mozilla.com/webfwd' - ]); - - let results = yield searchP({ query: 'moz' }); - assert.equal(results.length, 2, 'should return urls that match substring'); - results.map(({url}) => { - assert.ok(/moz/.test(url), 'correct item'); - }); - - results = yield searchP([{ query: 'webfwd' }, { query: 'aud.io' }]); - assert.equal(results.length, 2, 'should OR separate queries'); - results.map(({url}) => { - assert.ok(/webfwd|aud\.io/.test(url), 'correct item'); + ]).then(() => { + return searchP({ query: 'moz' }); + }).then(results => { + assert.equal(results.length, 2, 'should return urls that match substring'); + results.map(({url}) => { + assert.ok(/moz/.test(url), 'correct item'); + }); + return searchP([{ query: 'webfwd' }, { query: 'aud.io' }]); + }).then(results => { + assert.equal(results.length, 2, 'should OR separate queries'); + results.map(({url}) => { + assert.ok(/webfwd|aud\.io/.test(url), 'correct item'); + }); + done(); }); }; @@ -164,50 +168,51 @@ exports.testSearchCount = function (assert, done) { } }; -exports.testSearchSortForHistory = function*(assert) { +exports.testSearchSort = function (assert, done) { + let places = [ + 'http://mozilla.com/', 'http://webaud.io/', 'http://mozilla.com/webfwd/', + 'http://developer.mozilla.com/', 'http://bandcamp.com/' + ]; + addVisits(places).then(() => { + return searchP({}, { sort: 'title' }); + }).then(results => { + checkOrder(results, [4,3,0,2,1]); + return searchP({}, { sort: 'title', descending: true }); + }).then(results => { + checkOrder(results, [1,2,0,3,4]); + return searchP({}, { sort: 'url' }); + }).then(results => { + checkOrder(results, [4,3,0,2,1]); + return searchP({}, { sort: 'url', descending: true }); + }).then(results => { + checkOrder(results, [1,2,0,3,4]); + return addVisits('http://mozilla.com') // for visit conut + .then(() => addVisits('http://github.com')); // for checking date + }).then(() => { + return searchP({}, { sort: 'visitCount' }); + }).then(results => { + assert.equal(results[5].url, 'http://mozilla.com/', + 'last entry is the highest visit count'); + return searchP({}, { sort: 'visitCount', descending: true }); + }).then(results => { + assert.equal(results[0].url, 'http://mozilla.com/', + 'first entry is the highest visit count'); + return searchP({}, { sort: 'date' }); + }).then(results => { + assert.equal(results[5].url, 'http://github.com/', + 'latest visited should be first'); + return searchP({}, { sort: 'date', descending: true }); + }).then(results => { + assert.equal(results[0].url, 'http://github.com/', + 'latest visited should be at the end'); + }).then(done); + function checkOrder (results, nums) { assert.equal(results.length, nums.length, 'expected return count'); for (let i = 0; i < nums.length; i++) { assert.equal(results[i].url, places[nums[i]], 'successful order'); } } - - let places = [ - 'http://mozilla.com/', 'http://webaud.io/', 'http://mozilla.com/webfwd/', - 'http://developer.mozilla.com/', 'http://bandcamp.com/' - ]; - yield addVisits(places); - - let results = yield searchP({}, { sort: 'title' }); - checkOrder(results, [4,3,0,2,1]); - - results = yield searchP({}, { sort: 'title', descending: true }); - checkOrder(results, [1,2,0,3,4]); - - results = yield searchP({}, { sort: 'url' }); - checkOrder(results, [4,3,0,2,1]); - - results = yield searchP({}, { sort: 'url', descending: true }); - checkOrder(results, [1,2,0,3,4]); - - yield addVisits('http://mozilla.com'); // for visit conut - yield addVisits('http://github.com'); // for checking date - - results = yield searchP({}, { sort: 'visitCount' }); - assert.equal(results[5].url, 'http://mozilla.com/', - 'last entry is the highest visit count'); - - results = yield searchP({}, { sort: 'visitCount', descending: true }); - assert.equal(results[0].url, 'http://mozilla.com/', - 'first entry is the highest visit count'); - - results = yield searchP({}, { sort: 'date' }); - assert.equal(results[5].url, 'http://github.com/', - 'latest visited should be first'); - - results = yield searchP({}, { sort: 'date', descending: true }); - assert.equal(results[0].url, 'http://github.com/', - 'latest visited should be at the end'); }; exports.testEmitters = function (assert, done) { diff --git a/addon-sdk/source/test/addons/places/lib/test-places-host.js b/addon-sdk/source/test/addons/places/lib/test-places-host.js index 3d0b2b3f43a0..ec9addc49dd4 100644 --- a/addon-sdk/source/test/addons/places/lib/test-places-host.js +++ b/addon-sdk/source/test/addons/places/lib/test-places-host.js @@ -21,7 +21,7 @@ require('sdk/places/host/host-bookmarks'); require('sdk/places/host/host-tags'); require('sdk/places/host/host-query'); const { - invalidResolve, createTree, + invalidResolve, invalidReject, createTree, compareWithHost, createBookmark, createBookmarkTree, resetPlaces } = require('./places-helper'); @@ -32,7 +32,7 @@ const hsrv = Cc['@mozilla.org/browser/nav-history-service;1']. const tagsrv = Cc['@mozilla.org/browser/tagging-service;1']. getService(Ci.nsITaggingService); -exports.testBookmarksCreate = function*(assert) { +exports.testBookmarksCreate = function (assert, done) { let items = [{ title: 'my title', url: 'http://test-places-host.com/testBookmarksCreate/', @@ -47,11 +47,13 @@ exports.testBookmarksCreate = function*(assert) { group: bmsrv.unfiledBookmarksFolder }]; - yield all(items.map((item) => { - return send('sdk-places-bookmarks-create', item).then((data) => { + all(items.map(function (item) { + return send('sdk-places-bookmarks-create', item).then(function (data) { compareWithHost(assert, data); - }); - })); + }, invalidReject(assert)); + })).then(function () { + done(); + }, invalidReject(assert)); }; exports.testBookmarksCreateFail = function (assert, done) { diff --git a/addon-sdk/source/test/addons/require/main.js b/addon-sdk/source/test/addons/require/main.js index 53391f08b675..d7dd2ae76ff6 100644 --- a/addon-sdk/source/test/addons/require/main.js +++ b/addon-sdk/source/test/addons/require/main.js @@ -6,10 +6,10 @@ var { isNative } = require("@loader/options"); exports["test local vs sdk module"] = function (assert) { - assert.notEqual(require("list"), - require("sdk/util/list"), + assert.notEqual(require("memory"), + require("sdk/deprecated/memory"), "Local module takes the priority over sdk modules"); - assert.ok(require("list").local, + assert.ok(require("memory").local, "this module is really the local one"); } diff --git a/addon-sdk/source/test/addons/require/list.js b/addon-sdk/source/test/addons/require/memory.js similarity index 94% rename from addon-sdk/source/test/addons/require/list.js rename to addon-sdk/source/test/addons/require/memory.js index 9d2566a87173..f8b0c0f255da 100644 --- a/addon-sdk/source/test/addons/require/list.js +++ b/addon-sdk/source/test/addons/require/memory.js @@ -1,6 +1,5 @@ /* 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"; exports.local = true; diff --git a/addon-sdk/source/test/fixtures/index.html b/addon-sdk/source/test/fixtures/index.html index ba77c6a26fb1..e5b5859cb693 100644 --- a/addon-sdk/source/test/fixtures/index.html +++ b/addon-sdk/source/test/fixtures/index.html @@ -9,10 +9,5 @@

This is an add-on page test!

- diff --git a/addon-sdk/source/test/fixtures/test-addon-extras-window.html b/addon-sdk/source/test/fixtures/test-addon-extras-window.html deleted file mode 100644 index 76ce98cd3f21..000000000000 --- a/addon-sdk/source/test/fixtures/test-addon-extras-window.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - Worker test - - -

Lorem ipsum dolor sit amet.

- - - diff --git a/addon-sdk/source/test/fixtures/test-addon-extras.html b/addon-sdk/source/test/fixtures/test-addon-extras.html deleted file mode 100644 index 9864495e82fe..000000000000 --- a/addon-sdk/source/test/fixtures/test-addon-extras.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - Worker test - - -

Lorem ipsum dolor sit amet.

- - - diff --git a/addon-sdk/source/test/fixtures/test.html b/addon-sdk/source/test/fixtures/test.html index 54fce932c93c..181e85f9b1d9 100644 --- a/addon-sdk/source/test/fixtures/test.html +++ b/addon-sdk/source/test/fixtures/test.html @@ -9,10 +9,5 @@

bar

- diff --git a/addon-sdk/source/test/jetpack-package.ini b/addon-sdk/source/test/jetpack-package.ini index 2bfb5e5b490c..a9e7fc7a28e8 100644 --- a/addon-sdk/source/test/jetpack-package.ini +++ b/addon-sdk/source/test/jetpack-package.ini @@ -4,27 +4,26 @@ support-files = commonjs-test-adapter/** context-menu/** event/** - fixtures.js fixtures/** framescript-manager/** framescript-util/** - lib/** loader/** + lib/** modules/** - pagemod-test-helpers.js path/** private-browsing/** querystring/** sidebar/** tabs/** - test-context-menu.html traits/** - util.js windows/** zip/** + fixtures.js + pagemod-test-helpers.js + test-context-menu.html + util.js [test-addon-bootstrap.js] -[test-addon-extras.js] [test-addon-installer.js] [test-addon-window.js] [test-api-utils.js] @@ -34,6 +33,7 @@ support-files = [test-browser-events.js] [test-buffer.js] [test-byte-streams.js] +[test-bond.js] [test-child_process.js] [test-chrome.js] [test-clipboard.js] @@ -72,20 +72,19 @@ skip-if = true [test-hotkeys.js] [test-httpd.js] [test-indexed-db.js] -[test-jetpack-id.js] [test-keyboard-observer.js] [test-keyboard-utils.js] +[test-lang-type.js] [test-l10n-locale.js] [test-l10n-plural-rules.js] -[test-lang-type.js] [test-libxul.js] [test-list.js] [test-loader.js] [test-match-pattern.js] +[test-memory.js] [test-method.js] [test-module.js] [test-modules.js] -[test-mozilla-toolkit-versioning.js] [test-mpl2-license-header.js] skip-if = true [test-namespace.js] @@ -117,7 +116,6 @@ skip-if = true [test-self.js] [test-sequence.js] [test-set-exports.js] -[test-shared-require.js] [test-simple-prefs.js] [test-simple-storage.js] [test-system-events.js] diff --git a/addon-sdk/source/test/loader/user-global.js b/addon-sdk/source/test/loader/user-global.js deleted file mode 100644 index 34b233f429fb..000000000000 --- a/addon-sdk/source/test/loader/user-global.js +++ /dev/null @@ -1,11 +0,0 @@ -/* 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"; - -// Test module to check presense of user defined globals. -// Related to bug 827792. - -exports.getCom = function() { - return com; -}; diff --git a/addon-sdk/source/test/private-browsing/windows.js b/addon-sdk/source/test/private-browsing/windows.js index 5427d17cf2b5..439ef53a486c 100644 --- a/addon-sdk/source/test/private-browsing/windows.js +++ b/addon-sdk/source/test/private-browsing/windows.js @@ -11,7 +11,6 @@ const { browserWindows: windows } = require('sdk/windows'); const { defer } = require('sdk/core/promise'); const tabs = require('sdk/tabs'); const { getMostRecentBrowserWindow } = require('sdk/window/utils'); -const { cleanUI } = require("sdk/test/utils"); // test openDialog() from window/utils with private option // test isActive state in pwpb case @@ -43,18 +42,15 @@ exports.testPerWindowPrivateBrowsingGetter = function*(assert) { yield close(win) } -exports.testIsPrivateOnWindowOpen = function*(assert) { - let window = yield new Promise(resolve => { - windows.open({ - isPrivate: true, - onOpen: resolve - }); +exports.testIsPrivateOnWindowOpen = function(assert, done) { + windows.open({ + isPrivate: true, + onOpen: function(window) { + assert.equal(isPrivate(window), false, 'isPrivate for a window is true when it should be'); + assert.equal(isPrivate(window.tabs[0]), false, 'isPrivate for a tab is false when it should be'); + window.close(done); + } }); - - assert.equal(isPrivate(window), false, 'isPrivate for a window is true when it should be'); - assert.equal(isPrivate(window.tabs[0]), false, 'isPrivate for a tab is false when it should be'); - - yield cleanUI(); } exports.testIsPrivateOnWindowOpenFromPrivate = function(assert, done) { diff --git a/addon-sdk/source/test/tabs/test-firefox-tabs.js b/addon-sdk/source/test/tabs/test-firefox-tabs.js index 12874444b06a..3e73edc7924a 100644 --- a/addon-sdk/source/test/tabs/test-firefox-tabs.js +++ b/addon-sdk/source/test/tabs/test-firefox-tabs.js @@ -18,7 +18,6 @@ const { set: setPref } = require("sdk/preferences/service"); const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings"; const fixtures = require("../fixtures"); const { base64jpeg } = fixtures; -const { cleanUI, after } = require("sdk/test/utils"); // Bug 682681 - tab.title should never be empty exports.testBug682681_aboutURI = function(assert, done) { @@ -373,28 +372,31 @@ exports.testTabMove = function(assert, done) { }).then(null, assert.fail); }; -exports.testIgnoreClosing = function*(assert) { - let url = "data:text/html;charset=utf-8,foobar"; - let originalWindow = getMostRecentBrowserWindow(); +exports.testIgnoreClosing = function(assert, done) { + let originalWindow = viewFor(browserWindows.activeWindow); + openBrowserWindow(function(window, browser) { + onFocus(window).then(() => { + let url = "data:text/html;charset=utf-8,foobar"; - let window = yield open().then(focus); + assert.equal(tabs.length, 2, "should be two windows open each with one tab"); - assert.equal(tabs.length, 2, "should be two windows open each with one tab"); + tabs.on('ready', function onReady(tab) { + tabs.removeListener('ready', onReady); - yield new Promise(resolve => { - tabs.once("ready", (tab) => { - let win = tab.window; - assert.equal(win.tabs.length, 2, "should be two tabs in the new window"); - assert.equal(tabs.length, 3, "should be three tabs in total"); + let win = tab.window; + assert.equal(win.tabs.length, 2, "should be two tabs in the new window"); + assert.equal(tabs.length, 3, "should be three tabs in total"); - tab.close(() => { - assert.equal(win.tabs.length, 1, "should be one tab in the new window"); - assert.equal(tabs.length, 2, "should be two tabs in total"); - resolve(); + tab.close(function() { + assert.equal(win.tabs.length, 1, "should be one tab in the new window"); + assert.equal(tabs.length, 2, "should be two tabs in total"); + + close(window).then(onFocus(originalWindow)).then(done).then(null, assert.fail); + }); }); - }); - tabs.open(url); + tabs.open(url); + }); }); }; @@ -535,23 +537,23 @@ exports.testTabsEvent_onOpen = function(assert, done) { }; // TEST: onClose event handler -exports.testTabsEvent_onClose = function*(assert) { - let window = yield open().then(focus); - let url = "data:text/html;charset=utf-8,onclose"; - let eventCount = 0; +exports.testTabsEvent_onClose = function(assert, done) { + open().then(focus).then(window => { + let url = "data:text/html;charset=utf-8,onclose"; + let eventCount = 0; - // add listener via property assignment - function listener1(tab) { - eventCount++; - } - tabs.on("close", listener1); + // add listener via property assignment + function listener1(tab) { + eventCount++; + } + tabs.on('close', listener1); - yield new Promise(resolve => { // add listener via collection add - tabs.on("close", function listener2(tab) { + tabs.on('close', function listener2(tab) { assert.equal(++eventCount, 2, "both listeners notified"); - tabs.removeListener("close", listener2); - resolve(); + tabs.removeListener('close', listener1); + tabs.removeListener('close', listener2); + close(window).then(done).then(null, assert.fail); }); tabs.on('ready', function onReady(tab) { @@ -560,13 +562,7 @@ exports.testTabsEvent_onClose = function*(assert) { }); tabs.open(url); - }); - - tabs.removeListener("close", listener1); - assert.pass("done test!"); - - yield close(window); - assert.pass("window was closed!"); + }).then(null, assert.fail); }; // TEST: onClose event handler when a window is closed @@ -675,38 +671,32 @@ exports.testTabsEvent_onActivate = function(assert, done) { }; // onDeactivate event handler -exports.testTabsEvent_onDeactivate = function*(assert) { - let window = yield open().then(focus); +exports.testTabsEvent_onDeactivate = function(assert, done) { + open().then(focus).then(window => { + let url = "data:text/html;charset=utf-8,ondeactivate"; + let eventCount = 0; - let url = "data:text/html;charset=utf-8,ondeactivate"; - let eventCount = 0; + // add listener via property assignment + function listener1(tab) { + eventCount++; + }; + tabs.on('deactivate', listener1); - // add listener via property assignment - function listener1(tab) { - eventCount++; - assert.pass("listener1 was called " + eventCount); - }; - tabs.on('deactivate', listener1); - - yield new Promise(resolve => { // add listener via collection add tabs.on('deactivate', function listener2(tab) { assert.equal(++eventCount, 2, "both listeners notified"); + tabs.removeListener('deactivate', listener1); tabs.removeListener('deactivate', listener2); - resolve(); + close(window).then(done).then(null, assert.fail); }); tabs.on('open', function onOpen(tab) { - assert.pass("tab opened"); tabs.removeListener('open', onOpen); tabs.open("data:text/html;charset=utf-8,foo"); }); tabs.open(url); - }); - - tabs.removeListener('deactivate', listener1); - assert.pass("listeners were removed"); + }).then(null, assert.fail); }; // pinning @@ -736,16 +726,13 @@ exports.testTabsEvent_pinning = function(assert, done) { }; // TEST: per-tab event handlers -exports.testPerTabEvents = function*(assert) { - let window = yield open().then(focus); - let eventCount = 0; +exports.testPerTabEvents = function(assert, done) { + open().then(focus).then(window => { + let eventCount = 0; - let tab = yield new Promise(resolve => { tabs.open({ url: "data:text/html;charset=utf-8,foo", - onOpen: (tab) => { - assert.pass("the tab was opened"); - + onOpen: function(tab) { // add listener via property assignment function listener1() { eventCount++; @@ -754,18 +741,14 @@ exports.testPerTabEvents = function*(assert) { // add listener via collection add tab.on('ready', function listener2() { - assert.equal(eventCount, 1, "listener1 called before listener2"); + assert.equal(eventCount, 1, "both listeners notified"); tab.removeListener('ready', listener1); tab.removeListener('ready', listener2); - assert.pass("removed listeners"); - eventCount++; - resolve(); + close(window).then(done).then(null, assert.fail); }); } }); - }); - - assert.equal(eventCount, 2, "both listeners were notified."); + }).then(null, assert.fail); }; exports.testAttachOnOpen = function (assert, done) { @@ -1220,10 +1203,6 @@ exports.testTabDestroy = function(assert, done) { }) }; -after(exports, function*(name, assert) { - yield cleanUI(); -}); - /******************* helpers *********************/ // Utility function to open a new browser window. diff --git a/addon-sdk/source/test/test-addon-extras.js b/addon-sdk/source/test/test-addon-extras.js deleted file mode 100644 index 55e57c2e4537..000000000000 --- a/addon-sdk/source/test/test-addon-extras.js +++ /dev/null @@ -1,171 +0,0 @@ -/* 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 { Ci, Cu, Cc, components } = require("chrome"); -const self = require("sdk/self"); -const { before, after } = require("sdk/test/utils"); -const fixtures = require("./fixtures"); -const { Loader } = require("sdk/test/loader"); -const { merge } = require("sdk/util/object"); - -exports["test changing result from addon extras in panel"] = function(assert, done) { - let loader = Loader(module, null, null, { - modules: { - "sdk/self": merge({}, self, { - data: merge({}, self.data, {url: fixtures.url}) - }) - } - }); - - const { Panel } = loader.require("sdk/panel"); - const { events } = loader.require("sdk/content/sandbox/events"); - const { on } = loader.require("sdk/event/core"); - const { isAddonContent } = loader.require("sdk/content/utils"); - - var result = 1; - var extrasVal = { - test: function() { - return result; - } - }; - - on(events, "content-script-before-inserted", ({ window, worker }) => { - assert.pass("content-script-before-inserted"); - - if (isAddonContent({ contentURL: window.location.href })) { - let extraStuff = Cu.cloneInto(extrasVal, window, { - cloneFunctions: true - }); - getUnsafeWindow(window).extras = extraStuff; - - assert.pass("content-script-before-inserted done!"); - } - }); - - let panel = Panel({ - contentURL: "./test-addon-extras.html" - }); - - panel.port.once("result1", (result) => { - assert.equal(result, 1, "result is a number"); - result = true; - panel.port.emit("get-result"); - }); - - panel.port.once("result2", (result) => { - assert.equal(result, true, "result is a boolean"); - loader.unload(); - done(); - }); - - panel.port.emit("get-result"); -} - -exports["test window result from addon extras in panel"] = function*(assert) { - let loader = Loader(module, null, null, { - modules: { - "sdk/self": merge({}, self, { - data: merge({}, self.data, {url: fixtures.url}) - }) - } - }); - - const { Panel } = loader.require('sdk/panel'); - const { Page } = loader.require('sdk/page-worker'); - const { getActiveView } = loader.require("sdk/view/core"); - const { getDocShell } = loader.require('sdk/frame/utils'); - const { events } = loader.require("sdk/content/sandbox/events"); - const { on } = loader.require("sdk/event/core"); - const { isAddonContent } = loader.require("sdk/content/utils"); - - // make a page worker and wait for it to load - var page = yield new Promise(resolve => { - assert.pass("Creating the background page"); - - let page = Page({ - contentURL: "./test.html", - contentScriptWhen: "end", - contentScript: "self.port.emit('end', unsafeWindow.getTestURL() + '')" - }); - - page.port.once("end", (url) => { - assert.equal(url, fixtures.url("./test.html"), "url is correct"); - resolve(page); - }); - }); - assert.pass("Created the background page"); - - var extrasVal = { - test: function() { - assert.pass("start test function"); - let frame = getActiveView(page); - let window = getUnsafeWindow(frame.contentWindow); - assert.equal(typeof window.getTestURL, "function", "window.getTestURL is a function"); - return window; - } - }; - - on(events, "content-script-before-inserted", ({ window, worker }) => { - let url = window.location.href; - assert.pass("content-script-before-inserted " + url); - - if (isAddonContent({ contentURL: url })) { - let extraStuff = Cu.cloneInto(extrasVal, window, { - cloneFunctions: true - }); - getUnsafeWindow(window).extras = extraStuff; - - assert.pass("content-script-before-inserted done!"); - } - }); - - let panel = Panel({ - contentURL: "./test-addon-extras-window.html" - }); - - - yield new Promise(resolve => { - panel.port.once("result1", (result) => { - assert.equal(result, fixtures.url("./test.html"), "result1 is a window"); - resolve(); - }); - - assert.pass("emit get-result"); - panel.port.emit("get-result"); - }); - - page.destroy(); - - - page = yield new Promise(resolve => { - let page = Page({ - contentURL: "./index.html", - contentScriptWhen: "end", - contentScript: "self.port.emit('end')" - }); - page.port.once("end", () => resolve(page)); - }); - - - yield new Promise(resolve => { - panel.port.once("result2", (result) => { - assert.equal(result, fixtures.url("./index.html"), "result2 is a window"); - resolve(); - }); - - assert.pass("emit get-result"); - panel.port.emit("get-result"); - }); - - loader.unload(); -} - - - -function getUnsafeWindow (win) { - return win.wrappedJSObject || win; -} - -require("sdk/test").run(exports); diff --git a/addon-sdk/source/test/test-bond.js b/addon-sdk/source/test/test-bond.js new file mode 100644 index 000000000000..4a33a8ca0258 --- /dev/null +++ b/addon-sdk/source/test/test-bond.js @@ -0,0 +1,169 @@ +/* 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 { Bond } = require("sdk/util/bond"); +const { Class } = require("sdk/core/heritage"); + +exports["test bonds on constructors"] = assert => { + const MyClass = function(name) { + this.name = name; + } + MyClass.prototype = Bond({ + hello() { + return `Hello my name is ${this.name}` + } + }) + Object.assign(MyClass.prototype, { + constructor: MyClass, + readName() { + return this.name + } + }); + + const i1 = new MyClass("James Bond"); + + assert.equal(i1.hello(), "Hello my name is James Bond"); + assert.equal(i1.hello.call({name: "Hack"}), "Hello my name is James Bond"); + assert.equal(i1.readName(), "James Bond"); + assert.equal(i1.readName.call({name: "Hack"}), "Hack"); + + const hello = i1.hello + assert.equal(hello(), "Hello my name is James Bond"); +}; + +exports["test subclassing"] = assert => { + const MyClass = function(name) { + this.name = name; + } + MyClass.prototype = Bond({ + hello() { + return `Hello my name is ${this.name}` + } + }); + + const i1 = new MyClass("James Bond"); + + assert.equal(i1.hello(), "Hello my name is James Bond"); + assert.equal(i1.hello.call({name: "Hack"}), "Hello my name is James Bond"); + const i1Hello = i1.hello + assert.equal(i1Hello(), "Hello my name is James Bond"); + + const MySubClass = function(...args) { + MyClass.call(this, ...args) + } + MySubClass.prototype = Object.create(MyClass.prototype) + + const i2 = new MySubClass("Your father"); + + assert.equal(i2.hello(), "Hello my name is Your father"); + assert.equal(i2.hello.call({name: "Hack"}), "Hello my name is Your father"); + const i2Hello = i2.hello + assert.equal(i2Hello(), "Hello my name is Your father"); +}; + +exports["test access on prototype"] = assert => { + const MyClass = function(name) { + this.name = name; + } + MyClass.prototype = Bond({ + hello() { + return `Hello my name is ${this.name}` + } + }); + + assert.equal(MyClass.prototype.hello(), "Hello my name is undefined"); + assert.ok(Object.getOwnPropertyDescriptor(MyClass.prototype, "hello").get, + "hello is still a getter"); + assert.equal(MyClass.prototype.hello.call({name: "this"}), + "Hello my name is this", + "passing `this` on prototype methods work"); + + const i1 = new MyClass("James Bond"); + assert.equal(i1.hello(), "Hello my name is James Bond"); + + assert.ok(!Object.getOwnPropertyDescriptor(i1, "hello").get, + "hello is not a getter on instance"); + + assert.equal(i1.hello.call({name: "Hack"}), "Hello my name is James Bond"); + const i1Hello = i1.hello + assert.equal(i1Hello(), "Hello my name is James Bond"); +}; + + +exports["test bonds with Class"] = assert => { + const MyClass = Class({ + extends: Bond({ + hello() { + return `Hello my name is ${this.name}` + } + }), + initialize(name) { + this.name = name; + } + }); + + const i1 = new MyClass("James Bond"); + + assert.equal(i1.hello(), "Hello my name is James Bond"); + assert.equal(i1.hello.call({name: "Hack"}), "Hello my name is James Bond"); + + const hello = i1.hello + assert.equal(hello(), "Hello my name is James Bond"); +}; + + +exports["test with mixin"] = assert => { + const MyClass = Class({ + implements: [ + Bond({ + hello() { + return `Hello my name is ${this.name}` + } + }) + ], + initialize(name) { + this.name = name; + } + }); + + const i1 = new MyClass("James Bond"); + + assert.equal(i1.hello(), "Hello my name is James Bond"); + assert.equal(i1.hello.call({name: "Hack"}), "Hello my name is James Bond"); + + const hello = i1.hello + assert.equal(hello(), "Hello my name is James Bond"); + + const MyComposedClass = Class({ + implements: [ + MyClass, + Bond({ + bye() { + return `Bye ${this.name}` + } + }) + ], + initialize(name) { + this.name = name; + } + }); + + const i2 = new MyComposedClass("Major Tom"); + + assert.equal(i2.hello(), "Hello my name is Major Tom"); + assert.equal(i2.hello.call({name: "Hack"}), "Hello my name is Major Tom"); + + const i2Hello = i2.hello + assert.equal(i2Hello(), "Hello my name is Major Tom"); + + assert.equal(i2.bye(), "Bye Major Tom"); + assert.equal(i2.bye.call({name: "Hack"}), "Bye Major Tom"); + + const i2Bye = i2.bye + assert.equal(i2Bye(), "Bye Major Tom"); +}; + + +require("sdk/test").run(exports); diff --git a/addon-sdk/source/test/test-file.js b/addon-sdk/source/test/test-file.js index 3c4a7d014af2..2e4aa9e71c88 100644 --- a/addon-sdk/source/test/test-file.js +++ b/addon-sdk/source/test/test-file.js @@ -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 { pathFor } = require('sdk/system'); diff --git a/addon-sdk/source/test/test-loader.js b/addon-sdk/source/test/test-loader.js index 4599b18ff567..09dd4395eddf 100644 --- a/addon-sdk/source/test/test-loader.js +++ b/addon-sdk/source/test/test-loader.js @@ -524,22 +524,4 @@ exports['test lazy globals'] = function (assert) { assert.ok(gotFoo, "foo has been accessed only when we first try to use it"); }; -exports['test user global'] = function(assert) { - // Test case for bug 827792 - let com = {}; - let loader = require('toolkit/loader'); - let loadOptions = require('@loader/options'); - let options = loader.override(loadOptions, - {globals: loader.override(loadOptions.globals, - {com: com, - console: console, - dump: dump})}); - let subloader = loader.Loader(options); - let userRequire = loader.Require(subloader, module); - let userModule = userRequire("./loader/user-global"); - - assert.equal(userModule.getCom(), com, - "user module returns expected `com` global"); -}; - require('sdk/test').run(exports); diff --git a/addon-sdk/source/test/test-memory.js b/addon-sdk/source/test/test-memory.js new file mode 100644 index 000000000000..694172d07b6b --- /dev/null +++ b/addon-sdk/source/test/test-memory.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 memory = require("sdk/deprecated/memory"); +const { gc } = require("sdk/test/memory"); + +exports.testMemory = function(assert) { + var obj = {}; + memory.track(obj, "testMemory.testObj"); + + var objs = memory.getObjects("testMemory.testObj"); + assert.equal(objs[0].weakref.get(), obj); + obj = null; + + gc().then(function() { + assert.equal(objs[0].weakref.get(), null); + }); +}; + +require('sdk/test').run(exports); diff --git a/addon-sdk/source/test/test-mpl2-license-header.js b/addon-sdk/source/test/test-mpl2-license-header.js index 22a2cf0eab71..b14ba087b895 100644 --- a/addon-sdk/source/test/test-mpl2-license-header.js +++ b/addon-sdk/source/test/test-mpl2-license-header.js @@ -10,8 +10,6 @@ const { id } = require("sdk/self"); const { getAddonByID } = require("sdk/addon/manager"); const { mapcat, map, filter, fromEnumerator } = require("sdk/util/sequence"); const { readURISync } = require('sdk/net/url'); -const { Request } = require('sdk/request'); -const { defer } = require("sdk/core/promise"); const ios = Cc['@mozilla.org/network/io-service;1']. getService(Ci.nsIIOService); @@ -59,42 +57,26 @@ const getEntries = directory => mapcat(entry => { return []; }, filter(() => true, getDirectoryEntries(directory))); -function readURL(url) { - let { promise, resolve } = defer(); - - Request({ - url: url, - overrideMimeType: "text/plain", - onComplete: (response) => resolve(response.text) - }).get(); - - return promise; -} exports["test MPL2 license header"] = function*(assert) { let addon = yield getAddonByID(id); let xpiURI = addon.getResourceURI(); let rootURL = xpiURI.spec; - assert.ok(rootURL, rootURL); let files = [...getEntries(xpiURI.QueryInterface(Ci.nsIFileURL).file)]; assert.ok(files.length > 1, files.length + " files found."); let failures = []; let success = 0; - for (let i = 0, len = files.length; i < len; i++) { - let file = files[i]; - assert.ok(file.path, "Trying " + file.path); - + files.forEach(file => { const URI = ios.newFileURI(file); - let leafName = URI.spec.replace(rootURL, ""); + let contents = readURISync(URI); - let contents = yield readURL(URI.spec); if (!MPL2_LICENSE_TEST.test(contents)) { failures.push(leafName); } - } + }); assert.equal(1, failures.length, "we expect one failure"); assert.ok(/test-mpl2-license-header\.js$/.test(failures[0]), "the only failure is this file"); diff --git a/addon-sdk/source/test/test-unit-test.js b/addon-sdk/source/test/test-unit-test.js index a64bd874e382..da1e305de5e2 100644 --- a/addon-sdk/source/test/test-unit-test.js +++ b/addon-sdk/source/test/test-unit-test.js @@ -123,6 +123,7 @@ exports.testWaitUntilTimeoutInCallback = function(test) { expected.push(["print", "TEST-START | wait4ever\n"]); expected.push(["error", "fail:", "Timed out (after: START)"]); expected.push(["error", "test assertion never became true:\n", "assertion failed, value is false\n"]); + expected.push(["print", "TEST-END | wait4ever\n"]); } else { expected.push(["info", "executing 'wait4ever'"]); @@ -131,19 +132,17 @@ exports.testWaitUntilTimeoutInCallback = function(test) { } function checkExpected(name, args) { - var index = message; - if (message++ >= expected.length) { + if (expected.length == 0 || expected[0][0] != name) { + test.fail("Saw an unexpected console." + name + "() call " + args); return; } - let expectedArgs = expected[index].slice(1); - for (let i = 0; i < expectedArgs.length; i++) { + message++; + let expectedArgs = expected.shift().slice(1); + for (let i = 0; i < expectedArgs.length; i++) test.assertEqual(args[i], expectedArgs[i], "Should have seen the right message in argument " + i + " of message " + message); - } - - if (message >= expected.length) { + if (expected.length == 0) test.done(); - } } let runner = new (require("sdk/deprecated/unit-test").TestRunner)({ diff --git a/addon-sdk/source/test/test-weak-set.js b/addon-sdk/source/test/test-weak-set.js index f7cc19e04432..e482a356ed54 100644 --- a/addon-sdk/source/test/test-weak-set.js +++ b/addon-sdk/source/test/test-weak-set.js @@ -1,81 +1,118 @@ /* 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"; +'use strict'; -const { Cu } = require("chrome"); -const memory = require("sdk/test/memory"); -const { add, remove, has, clear, iterator } = require("sdk/lang/weak-set"); -const { setInterval, clearInterval } = require("sdk/timers"); +const { Cu } = require('chrome'); +const { Loader } = require('sdk/test/loader'); +const { gc } = require("sdk/test/memory"); -function gc(assert) { - let wait = 1; - let interval = setInterval(function() { - assert.pass("waited " + (wait++ * 0.250) + "secs for gc().."); - }, 250); - - return memory.gc().then(() => { - assert.pass("gc completed!"); - clearInterval(interval); - }); -} - -exports['test add/remove/iterate/clear item'] = function*(assert) { - let addItems = {}; - let removeItems = {}; - let iterateItems = {}; - let clearItems = {}; - let nonReferencedItems = {}; +exports['test adding item'] = function*(assert) { + let loader = Loader(module); + let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set'); + let items = {}; let item = {}; + + add(items, item); + + yield gc(); + + assert.ok(has(items, item), 'the item is in the weak set'); + + loader.unload(); +}; + +exports['test remove item'] = function*(assert) { + let loader = Loader(module); + let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set'); + + let items = {}; + let item = {}; + + add(items, item); + + remove(items, item); + + yield gc(); + + assert.ok(!has(items, item), 'the item is not in weak set'); + + loader.unload(); +}; + +exports['test iterate'] = function*(assert) { + let loader = Loader(module); + let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set'); + + let items = {}; let addedItems = [{}, {}]; - assert.pass("adding things to items"); - add(addItems, item); - add(removeItems, item); - add(iterateItems, addedItems[0]); - add(iterateItems, addedItems[1]); - add(iterateItems, addedItems[0]); // weak set shouldn't add this twice - add(clearItems, addedItems[0]); - add(clearItems, addedItems[1]); - add(nonReferencedItems, {}); + add(items, addedItems[0]); + add(items, addedItems[1]); + add(items, addedItems[0]); // weak set shouldn't add this twice - assert.pass("removing things from removeItems"); - remove(removeItems, item); - - assert.pass("clear things from clearItems"); - clear(clearItems); - - assert.pass("starting gc.."); - yield gc(assert); + yield gc(); let count = 0; - assert.equal(has(addItems, item), true, 'the addItems is in the weak set'); - assert.equal(has(removeItems, item), false, 'the removeItems is not in weak set'); + for (let item of iterator(items)) { + assert.equal(item, addedItems[count], + 'item in the expected order'); - assert.pass("iterating iterateItems.."); - for (let item of iterator(iterateItems)) { - assert.equal(item, addedItems[count], "item in the expected order"); count++; } assert.equal(count, 2, 'items in the expected number'); + loader.unload(); +}; - assert.pass("iterating clearItems.."); - for (let item of iterator(clearItems)) { - assert.fail("the loop should not be executed"); - count++ +exports['test clear'] = function*(assert) { + let loader = Loader(module); + let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set'); + + let items = {}; + let addedItems = [{}, {}]; + + add(items, addedItems[0]); + add(items, addedItems[1]); + + clear(items) + + yield gc(); + let count = 0; + + for (let item of iterator(items)) { + assert.fail('the loop should not be executed'); } - for (let item of iterator(nonReferencedItems)) { - assert.fail("the loop should not be executed"); - count++ + assert.equal(count, 0, 'no items in the weak set'); + loader.unload(); +}; + +exports['test adding item without reference'] = function*(assert) { + let loader = Loader(module); + let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set'); + + let items = {}; + + add(items, {}); + + yield gc(); + let count = 0; + + for (let item of iterator(items)) { + assert.fail('the loop should not be executed'); } - assert.equal(count, 2, 'items in the expected number'); + assert.equal(count, 0, 'no items in the weak set'); + + loader.unload(); }; exports['test adding non object or null item'] = function(assert) { + let loader = Loader(module); + let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set'); + let items = {}; assert.throws(() => { @@ -110,6 +147,9 @@ exports['test adding non object or null item'] = function(assert) { }; exports['test adding to non object or null item'] = function(assert) { + let loader = Loader(module); + let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set'); + let item = {}; assert.throws(() => { @@ -143,4 +183,4 @@ exports['test adding to non object or null item'] = function(assert) { 'only non-null object are allowed'); }; -require("sdk/test").run(exports); +require('sdk/test').run(exports); diff --git a/addon-sdk/source/test/test-windows-common.js b/addon-sdk/source/test/test-windows-common.js index a4ca6e1a4edd..c27dd4661f72 100644 --- a/addon-sdk/source/test/test-windows-common.js +++ b/addon-sdk/source/test/test-windows-common.js @@ -10,7 +10,6 @@ const { viewFor } = require('sdk/view/core'); const { modelFor } = require('sdk/model/core'); const { Ci } = require("chrome"); const { isBrowser, getWindowTitle } = require("sdk/window/utils"); -const { after, cleanUI } = require("sdk/test/utils"); // TEST: browserWindows Iterator exports.testBrowserWindowsIterator = function(assert) { @@ -66,18 +65,20 @@ exports.testWindowActivateMethod_simple = function(assert) { }; -exports["test getView(window)"] = function*(assert) { - let window = yield new Promise(resolve => { - browserWindows.once("open", resolve); - browserWindows.open({ url: "data:text/html;charset=utf-8,yo" }); +exports["test getView(window)"] = function(assert, done) { + browserWindows.once("open", window => { + const view = viewFor(window); + + assert.ok(view instanceof Ci.nsIDOMWindow, "view is a window"); + assert.ok(isBrowser(view), "view is a browser window"); + assert.equal(getWindowTitle(view), window.title, + "window has a right title"); + + window.close(done); }); - const view = viewFor(window); - assert.ok(view instanceof Ci.nsIDOMWindow, "view is a window"); - assert.ok(isBrowser(view), "view is a browser window"); - assert.equal(getWindowTitle(view), window.title, - "window has a right title"); + browserWindows.open({ url: "data:text/html;charset=utf-8,yo" }); }; @@ -96,9 +97,4 @@ exports["test modelFor(window)"] = function(assert, done) { browserWindows.open({ url: "data:text/html;charset=utf-8,yo" }); }; -after(exports, function*(name, assert) { - assert.pass("cleaning the ui."); - yield cleanUI(); -}); - require('sdk/test').run(exports); diff --git a/addon-sdk/source/test/test-xul-app.js b/addon-sdk/source/test/test-xul-app.js index a57d425d276d..2f9349193b4a 100644 --- a/addon-sdk/source/test/test-xul-app.js +++ b/addon-sdk/source/test/test-xul-app.js @@ -1,11 +1,10 @@ /* 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"; var xulApp = require("sdk/system/xul-app"); -exports["test xulapp"] = function (assert) { +exports["test xulapp"] = function(assert) { assert.equal(typeof(xulApp.ID), "string", "ID is a string"); assert.equal(typeof(xulApp.name), "string", @@ -15,26 +14,26 @@ exports["test xulapp"] = function (assert) { assert.equal(typeof(xulApp.platformVersion), "string", "platformVersion is a string"); - assert.throws(() => xulApp.is("blargy"), - /Unkown Mozilla Application: blargy/, - "is() throws error on bad app name"); - - assert.throws(() => xulApp.isOneOf(["blargy"]), - /Unkown Mozilla Application: blargy/, - "isOneOf() throws error on bad app name"); + assert.throws(function() { xulApp.is("blargy"); }, + /Unkown Mozilla Application: blargy/, + "is() throws error on bad app name"); + assert.throws(function() { xulApp.isOneOf(["blargy"]); }, + /Unkown Mozilla Application: blargy/, + "isOneOf() throws error on bad app name"); function testSupport(name) { var item = xulApp.is(name); assert.ok(item === true || item === false, - "is('" + name + "') is true or false."); + "is('" + name + "') is true or false."); } var apps = ["Firefox", "Mozilla", "SeaMonkey", "Fennec", "Thunderbird"]; apps.forEach(testSupport); - assert.ok(xulApp.isOneOf(apps) == true || xulApp.isOneOf(apps) == false, - "isOneOf() returns true or false."); + assert.ok(xulApp.isOneOf(apps) == true || + xulApp.isOneOf(apps) == false, + "isOneOf() returns true or false."); assert.equal(xulApp.versionInRange(xulApp.platformVersion, "1.9", "*"), true, "platformVersion in range [1.9, *)"); diff --git a/addon-sdk/source/test/windows/test-firefox-windows.js b/addon-sdk/source/test/windows/test-firefox-windows.js index a2ffccabe6de..977698ddfd6e 100644 --- a/addon-sdk/source/test/windows/test-firefox-windows.js +++ b/addon-sdk/source/test/windows/test-firefox-windows.js @@ -327,6 +327,7 @@ exports.testTrackWindows = function(assert, done) { // listen to global deactivate events browserWindows.on("deactivate", windowsDeactivation); + function openWindow() { windows.push(browserWindows.open({ url: "data:text/html;charset=utf-8,testTrackWindows", @@ -349,10 +350,8 @@ exports.testTrackWindows = function(assert, done) { else { (function closeWindows(windows) { if (!windows.length) { - assert.pass('the last window was closed'); browserWindows.removeListener("activate", windowsActivation); browserWindows.removeListener("deactivate", windowsDeactivation); - assert.pass('removed listeners'); return done(); }