Bug 923719: Uplift Addon SDK to Firefox. r=me

bece20a...24471bc
This commit is contained in:
Dave Townsend 2013-10-04 16:48:52 -07:00
Родитель 4425695a30
Коммит df0f3d49de
61 изменённых файлов: 2202 добавлений и 1741 удалений

Просмотреть файл

@ -25,11 +25,9 @@ deactivate () {
unset _OLD_VIRTUAL_PS1 unset _OLD_VIRTUAL_PS1
fi fi
if [ -n "$_OLD_PYTHONPATH" ] ; then PYTHONPATH="$_OLD_PYTHONPATH"
PYTHONPATH="$_OLD_PYTHONPATH" export PYTHONPATH
export PYTHONPATH unset _OLD_PYTHONPATH
unset _OLD_PYTHONPATH
fi
unset CUDDLEFISH_ROOT unset CUDDLEFISH_ROOT

Просмотреть файл

@ -88,3 +88,24 @@ finished:
</api> </api>
<api name="waitUntil">
@function
`waitUntil` returns a promise that resolves upon the
`predicate` returning a truthy value, which is called every
`interval` milliseconds.
@param predicate {Function}
A function that gets called every `interval` milliseconds
to determine if the promise should be resolved.
@param [interval] {Number}
The frequency in milliseconds to execute `predicate`.
Defaults to `10`.
@returns {Promise}
`waitUntil` returns a promise that becomes resolved once
the `predicate` returns a truthy value. The promise cannot
be rejected.
</api>

Просмотреть файл

@ -0,0 +1,42 @@
<!-- 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/. -->
The `ui/id` module provides the `identify` helper method for creating
and defining UI component IDs.
<api name="identify">
@function
Makes and/or gets a unique ID for the input.
Making an ID
const { identify } = require('sdk/ui/id');
const Thingy = Class({
initialize: function(details) {
let id = identify(this);
}
});
Getting an ID
const { identify } = require('sdk/ui/id');
const { Thingy } = require('./thingy');
let thing = Thingy(/* ... */);
let thingID = identify(thing);
Defining ID generator
const { identify } = require('sdk/ui/id');
const Thingy = Class(/* ... */);
identify.define(Thingy, thing => thing.guid);
@param object {Object}
Object to create an ID for.
@returns {String}
Returns a UUID by default (or domain specific ID based on a provided definition).
</api>

Просмотреть файл

@ -57,6 +57,8 @@ find the modules it is asked to load. **Mandatory**.
* [`globals`](modules/toolkit/loader.html#globals): provides a set of globals shared across modules loaded * [`globals`](modules/toolkit/loader.html#globals): provides a set of globals shared across modules loaded
via this loader. **Optional**. via this loader. **Optional**.
* [`resolve`](modules/toolkit/loader.html#resolve): provide customized module resolution logic. **Optional**. * [`resolve`](modules/toolkit/loader.html#resolve): provide customized module resolution logic. **Optional**.
* [`id`](modules/toolkit/loader.html#id): provide add-on id to attach to loaded
modules. **Optional**.
### paths ### paths
@ -232,6 +234,12 @@ the function assigned to `resolve`
does not return a string value, an exception will still be thrown as does not return a string value, an exception will still be thrown as
the loader will be unable to resolve the required module's location. the loader will be unable to resolve the required module's location.
### id
Add-on debugging requires knowing which objects belong to which add-on.
When created with this option, Loader will transparently mark all new global
objects with the provided value.
### All Together ### All Together
All of these options can be combined to configure the loader for All of these options can be combined to configure the loader for

Просмотреть файл

@ -99,6 +99,13 @@ exports.disable = function disable(addonId) {
}); });
}; };
exports.enable = function enabled(addonId) {
return getAddon(addonId).then(addon => {
addon.userDisabled = false;
return addonId;
});
};
exports.isActive = function isActive(addonId) { exports.isActive = function isActive(addonId) {
return getAddon(addonId).then(addon => addon.isActive && !addon.appDisabled); return getAddon(addonId).then(addon => addon.isActive && !addon.appDisabled);
}; };

Просмотреть файл

@ -112,6 +112,7 @@ function startup(reason, options) {
}).then(function() { }).then(function() {
run(options); run(options);
}).then(null, console.exception); }).then(null, console.exception);
return void 0; // otherwise we raise a warning, see bug 910304
} }
function run(options) { function run(options) {

Просмотреть файл

@ -150,7 +150,8 @@ const WorkerSandbox = EventEmitter.compose({
sandboxPrototype: proto, sandboxPrototype: proto,
wantXrays: true, wantXrays: true,
wantGlobalProperties: wantGlobalProperties, wantGlobalProperties: wantGlobalProperties,
sameZoneAs: window sameZoneAs: window,
metadata: { SDKContentScript: true }
}); });
// We have to ensure that window.top and window.parent are the exact same // We have to ensure that window.top and window.parent are the exact same
// object than window object, i.e. the sandbox global object. But not // object than window object, i.e. the sandbox global object. But not
@ -554,6 +555,7 @@ const Worker = EventEmitter.compose({
*/ */
destroy: function destroy() { destroy: function destroy() {
this._workerCleanup(); this._workerCleanup();
this._inited = true;
this._removeAllListeners(); this._removeAllListeners();
}, },
@ -580,6 +582,7 @@ const Worker = EventEmitter.compose({
this._earlyEvents.length = 0; this._earlyEvents.length = 0;
this._emit("detach"); this._emit("detach");
} }
this._inited = false;
}, },
/** /**

Просмотреть файл

@ -108,8 +108,14 @@ function remove(path, recursive) {
} }
} }
/**
* Utility function to convert either an octal number or string
* into an octal number
* 0777 => 0777
* "0644" => 0644
*/
function Mode(mode, fallback) { function Mode(mode, fallback) {
return isString(mode) ? parseInt(mode) : mode || fallback; return isString(mode) ? parseInt(mode, 8) : mode || fallback;
} }
function Flags(flag) { function Flags(flag) {
return !isString(flag) ? flag : return !isString(flag) ? flag :
@ -394,8 +400,15 @@ exports.lchown = lchown;
* Synchronous chmod(2). * Synchronous chmod(2).
*/ */
function chmodSync (path, mode) { function chmodSync (path, mode) {
throw Error("Not implemented yet!!"); let file;
}; try {
file = new nsILocalFile(path);
} catch(e) {
throw FSError("chmod", "ENOENT", 34, path);
}
file.permissions = Mode(mode);
}
exports.chmodSync = chmodSync; exports.chmodSync = chmodSync;
/** /**
* Asynchronous chmod(2). No arguments other than a possible exception are * Asynchronous chmod(2). No arguments other than a possible exception are
@ -416,7 +429,7 @@ exports.fchmodSync = fchmodSync;
* given to the completion callback. * given to the completion callback.
*/ */
let fchmod = Async(fchmodSync); let fchmod = Async(fchmodSync);
exports.chmod = fchmod; exports.fchmod = fchmod;
/** /**
@ -844,6 +857,9 @@ exports.readFileSync = readFileSync;
* exists. data can be a string or a buffer. * exists. data can be a string or a buffer.
*/ */
function writeFile(path, content, encoding, callback) { function writeFile(path, content, encoding, callback) {
if (!isString(path))
throw new TypeError('path must be a string');
try { try {
if (isFunction(encoding)) { if (isFunction(encoding)) {
callback = encoding callback = encoding

Просмотреть файл

@ -11,15 +11,21 @@ const { Cc, Ci, CC, Cu } = require('chrome');
const systemPrincipal = CC('@mozilla.org/systemprincipal;1', 'nsIPrincipal')(); const systemPrincipal = CC('@mozilla.org/systemprincipal;1', 'nsIPrincipal')();
const scriptLoader = Cc['@mozilla.org/moz/jssubscript-loader;1']. const scriptLoader = Cc['@mozilla.org/moz/jssubscript-loader;1'].
getService(Ci.mozIJSSubScriptLoader); getService(Ci.mozIJSSubScriptLoader);
const self = require('sdk/self');
/** /**
* Make a new sandbox that inherits given `source`'s principals. Source can be * Make a new sandbox that inherits given `source`'s principals. Source can be
* URI string, DOMWindow or `null` for system principals. * URI string, DOMWindow or `null` for system principals.
*/ */
function sandbox(target, options) { function sandbox(target, options) {
return Cu.Sandbox(target || systemPrincipal, options || {}); options = options || {};
options.metadata = options.metadata ? options.metadata : {};
options.metadata.addonID = options.metadata.addonID ?
options.metadata.addonID : self.id;
return Cu.Sandbox(target || systemPrincipal, options);
} }
exports.sandbox = sandbox exports.sandbox = sandbox;
/** /**
* Evaluates given `source` in a given `sandbox` and returns result. * Evaluates given `source` in a given `sandbox` and returns result.

Просмотреть файл

@ -10,7 +10,7 @@ module.metadata = {
const { Class } = require('./core/heritage'); const { Class } = require('./core/heritage');
const { on, emit, off, setListeners } = require('./event/core'); const { on, emit, off, setListeners } = require('./event/core');
const { filter, pipe, map, merge: streamMerge } = require('./event/utils'); const { filter, pipe, map, merge: streamMerge } = require('./event/utils');
const { WorkerHost, Worker, detach, attach } = require('./worker/utils'); const { WorkerHost, Worker, detach, attach, destroy } = require('./worker/utils');
const { Disposable } = require('./core/disposable'); const { Disposable } = require('./core/disposable');
const { EventTarget } = require('./event/target'); const { EventTarget } = require('./event/target');
const { unload } = require('./system/unload'); const { unload } = require('./system/unload');
@ -131,7 +131,7 @@ const Page = Class({
let view = viewFor(this); let view = viewFor(this);
if (view.parentNode) view.parentNode.removeChild(view); if (view.parentNode) view.parentNode.removeChild(view);
views.delete(this); views.delete(this);
detach(workers.get(this)); destroy(workers.get(this));
}, },
toString: function () '[object Page]' toString: function () '[object Page]'
}); });

Просмотреть файл

@ -19,7 +19,7 @@ const { isPrivateBrowsingSupported } = require('./self');
const { isWindowPBSupported } = require('./private-browsing/utils'); const { isWindowPBSupported } = require('./private-browsing/utils');
const { Class } = require("./core/heritage"); const { Class } = require("./core/heritage");
const { merge } = require("./util/object"); const { merge } = require("./util/object");
const { WorkerHost, Worker, detach, attach, const { WorkerHost, Worker, detach, attach, destroy,
requiresAddonGlobal } = require("./worker/utils"); requiresAddonGlobal } = require("./worker/utils");
const { Disposable } = require("./core/disposable"); const { Disposable } = require("./core/disposable");
const { contract: loaderContract } = require("./content/loader"); const { contract: loaderContract } = require("./content/loader");
@ -140,7 +140,7 @@ const Panel = Class({
this.hide(); this.hide();
off(this); off(this);
detach(workerFor(this)); destroy(workerFor(this));
domPanel.dispose(viewFor(this)); domPanel.dispose(viewFor(this));
@ -167,6 +167,9 @@ const Panel = Class({
let model = modelFor(this); let model = modelFor(this);
model.contentURL = panelContract({ contentURL: value }).contentURL; model.contentURL = panelContract({ contentURL: value }).contentURL;
domPanel.setURL(viewFor(this), model.contentURL); domPanel.setURL(viewFor(this), model.contentURL);
// Detach worker so that messages send will be queued until it's
// reatached once panel content is ready.
detach(workerFor(this));
}, },
/* Public API: Panel.isShowing */ /* Public API: Panel.isShowing */
@ -251,10 +254,6 @@ let hides = filter(panelEvents, function({type}) type === "popuphidden");
let ready = filter(panelEvents, function({type, target}) let ready = filter(panelEvents, function({type, target})
getAttachEventType(modelFor(panelFor(target))) === type); getAttachEventType(modelFor(panelFor(target))) === type);
// Panel events emitted after content document in the panel has changed.
let change = filter(panelEvents, function({type})
type === "document-element-inserted");
// Forward panel show / hide events to panel's own event listeners. // Forward panel show / hide events to panel's own event listeners.
on(shows, "data", function({target}) emit(panelFor(target), "show")); on(shows, "data", function({target}) emit(panelFor(target), "show"));
on(hides, "data", function({target}) emit(panelFor(target), "hide")); on(hides, "data", function({target}) emit(panelFor(target), "hide"));

Просмотреть файл

@ -81,6 +81,10 @@ function isOpen(panel) {
} }
exports.isOpen = isOpen; exports.isOpen = isOpen;
function isOpening(panel) {
return panel.state === "showing"
}
exports.isOpening = isOpening
function close(panel) { function close(panel) {
// Sometimes "TypeError: panel.hidePopup is not a function" is thrown // Sometimes "TypeError: panel.hidePopup is not a function" is thrown
@ -363,8 +367,10 @@ function style(panel) {
} }
exports.style = style; exports.style = style;
function getContentFrame(panel) isOpen(panel) ? panel.firstChild : let getContentFrame = panel =>
panel.backgroundFrame (isOpen(panel) || isOpening(panel)) ?
panel.firstChild :
panel.backgroundFrame
exports.getContentFrame = getContentFrame; exports.getContentFrame = getContentFrame;
function getContentDocument(panel) getContentFrame(panel).contentDocument function getContentDocument(panel) getContentFrame(panel).contentDocument

Просмотреть файл

@ -8,6 +8,9 @@ module.metadata = {
'stability': 'unstable' 'stability': 'unstable'
}; };
const { defer } = require('../core/promise');
const { setInterval, clearInterval } = require('../timers');
function getTestNames (exports) function getTestNames (exports)
Object.keys(exports).filter(name => /^test/.test(name)) Object.keys(exports).filter(name => /^test/.test(name))
@ -93,3 +96,14 @@ function after (exports, afterFn) {
}); });
} }
exports.after = after; exports.after = after;
function waitUntil (predicate, delay) {
let { promise, resolve } = defer();
let interval = setInterval(() => {
if (!predicate()) return;
clearInterval(interval);
resolve();
}, delay || 10);
return promise;
}
exports.waitUntil = waitUntil;

Просмотреть файл

@ -0,0 +1,27 @@
/* 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 method = require('method/core');
const { uuid } = require('../util/uuid');
// NOTE: use lang/functional memoize when it is updated to use WeakMap
function memoize(f) {
const memo = new WeakMap();
return function memoizer(o) {
let key = o;
if (!memo.has(key))
memo.set(key, f.apply(this, arguments));
return memo.get(key);
};
}
let identify = method('identify');
identify.define(Object, memoize(function() { return uuid(); }));
exports.identify = identify;

Просмотреть файл

@ -98,3 +98,9 @@ function attach(worker, window) {
trait.attach(window); trait.attach(window);
} }
exports.attach = attach; exports.attach = attach;
function destroy(worker) {
let trait = traitFor(worker);
if (trait) trait.destroy();
}
exports.destroy = destroy;

Просмотреть файл

@ -170,6 +170,8 @@ exports.serializeStack = serializeStack
// to `true`. // to `true`.
// - `sandbox`: A sandbox to share JS compartment with. If omitted new // - `sandbox`: A sandbox to share JS compartment with. If omitted new
// compartment will be created. // compartment will be created.
// - `metadata`: A metadata object associated with the sandbox. It should
// be JSON-serializable.
// For more details see: // For more details see:
// https://developer.mozilla.org/en/Components.utils.Sandbox // https://developer.mozilla.org/en/Components.utils.Sandbox
const Sandbox = iced(function Sandbox(options) { const Sandbox = iced(function Sandbox(options) {
@ -184,7 +186,8 @@ const Sandbox = iced(function Sandbox(options) {
wantGlobalProperties: 'wantGlobalProperties' in options ? wantGlobalProperties: 'wantGlobalProperties' in options ?
options.wantGlobalProperties : [], options.wantGlobalProperties : [],
sandboxPrototype: 'prototype' in options ? options.prototype : {}, sandboxPrototype: 'prototype' in options ? options.prototype : {},
sameGroupAs: 'sandbox' in options ? options.sandbox : null sameGroupAs: 'sandbox' in options ? options.sandbox : null,
metadata: 'metadata' in options ? options.metadata : {}
}; };
// Make `options.sameGroupAs` only if `sandbox` property is passed, // Make `options.sameGroupAs` only if `sandbox` property is passed,
@ -253,7 +256,11 @@ const load = iced(function load(loader, module) {
sandbox: sandboxes[keys(sandboxes).shift()], sandbox: sandboxes[keys(sandboxes).shift()],
prototype: create(globals, descriptors), prototype: create(globals, descriptors),
wantXrays: false, wantXrays: false,
wantGlobalProperties: module.id == "sdk/indexed-db" ? ["indexedDB"] : [] wantGlobalProperties: module.id == "sdk/indexed-db" ? ["indexedDB"] : [],
metadata: {
addonID: loader.id,
URI: module.uri
}
}); });
try { try {
@ -333,6 +340,7 @@ const resolveURI = iced(function resolveURI(id, mapping) {
if (id.indexOf(path) === 0) if (id.indexOf(path) === 0)
return normalize(id.replace(path, uri)); return normalize(id.replace(path, uri));
} }
return void 0; // otherwise we raise a warning, see bug 910304
}); });
exports.resolveURI = resolveURI; exports.resolveURI = resolveURI;
@ -478,6 +486,8 @@ const Loader = iced(function Loader(options) {
// Map of module sandboxes indexed by module URIs. // Map of module sandboxes indexed by module URIs.
sandboxes: { enumerable: false, value: {} }, sandboxes: { enumerable: false, value: {} },
resolve: { enumerable: false, value: resolve }, resolve: { enumerable: false, value: resolve },
// ID of the addon, if provided.
id: { enumerable: false, value: options.id },
load: { enumerable: false, value: options.load || load }, load: { enumerable: false, value: options.load || load },
// Main (entry point) module, it can be set only once, since loader // Main (entry point) module, it can be set only once, since loader
// instance can have only one main module. // instance can have only one main module.

Просмотреть файл

@ -3,6 +3,7 @@
const { open, focus, close } = require('sdk/window/helpers'); const { open, focus, close } = require('sdk/window/helpers');
const { isPrivate } = require('sdk/private-browsing'); const { isPrivate } = require('sdk/private-browsing');
const { defer } = require('sdk/core/promise'); const { defer } = require('sdk/core/promise');
const { browserWindows: windows } = require('sdk/windows');
const BROWSER = 'chrome://browser/content/browser.xul'; const BROWSER = 'chrome://browser/content/browser.xul';
@ -16,6 +17,11 @@ exports.testShowPanelInPrivateWindow = function(assert, done) {
contentURL: "data:text/html;charset=utf-8," contentURL: "data:text/html;charset=utf-8,"
}); });
assert.ok(windows.length > 0, 'there is at least one open window');
for (let window of windows) {
assert.equal(isPrivate(window), false, 'open window is private');
}
testShowPanel(assert, panel). testShowPanel(assert, panel).
then(makeEmptyPrivateBrowserWindow). then(makeEmptyPrivateBrowserWindow).
then(focus). then(focus).
@ -63,20 +69,25 @@ function makeEmptyPrivateBrowserWindow(options) {
function testShowPanel(assert, panel) { function testShowPanel(assert, panel) {
let { promise, resolve } = defer(); let { promise, resolve } = defer();
let shown = false;
assert.ok(!panel.isShowing, 'the panel is not showing [1]'); assert.ok(!panel.isShowing, 'the panel is not showing [1]');
panel.once('hide', function() {
assert.ok(!panel.isShowing, 'the panel is not showing [2]');
assert.ok(shown, 'the panel was shown')
resolve(null);
});
panel.once('show', function() { panel.once('show', function() {
shown = true;
assert.ok(panel.isShowing, 'the panel is showing'); assert.ok(panel.isShowing, 'the panel is showing');
panel.once('hide', function() {
assert.ok(!panel.isShowing, 'the panel is not showing [2]');
resolve(null);
});
panel.hide(); panel.hide();
}) });
panel.show(); panel.show();
return promise; return promise;

Просмотреть файл

@ -14,11 +14,11 @@ const { openTab, getBrowserForTab, closeTab } = require("sdk/tabs/utils");
* A helper function that creates a PageMod, then opens the specified URL * A helper function that creates a PageMod, then opens the specified URL
* and checks the effect of the page mod on 'onload' event via testCallback. * and checks the effect of the page mod on 'onload' event via testCallback.
*/ */
exports.testPageMod = function testPageMod(test, testURL, pageModOptions, exports.testPageMod = function testPageMod(assert, done, testURL, pageModOptions,
testCallback, timeout) { testCallback, timeout) {
if (!xulApp.versionInRange(xulApp.platformVersion, "1.9.3a3", "*") && if (!xulApp.versionInRange(xulApp.platformVersion, "1.9.3a3", "*") &&
!xulApp.versionInRange(xulApp.platformVersion, "1.9.2.7", "1.9.2.*")) { !xulApp.versionInRange(xulApp.platformVersion, "1.9.2.7", "1.9.2.*")) {
test.pass("Note: not testing PageMod, as it doesn't work on this platform version"); assert.pass("Note: not testing PageMod, as it doesn't work on this platform version");
return null; return null;
} }
@ -26,16 +26,11 @@ exports.testPageMod = function testPageMod(test, testURL, pageModOptions,
.getService(Ci.nsIWindowMediator); .getService(Ci.nsIWindowMediator);
var browserWindow = wm.getMostRecentWindow("navigator:browser"); var browserWindow = wm.getMostRecentWindow("navigator:browser");
if (!browserWindow) { if (!browserWindow) {
test.pass("page-mod tests: could not find the browser window, so " + assert.pass("page-mod tests: could not find the browser window, so " +
"will not run. Use -a firefox to run the pagemod tests.") "will not run. Use -a firefox to run the pagemod tests.")
return null; return null;
} }
if (timeout !== undefined)
test.waitUntilDone(timeout);
else
test.waitUntilDone();
let loader = Loader(module); let loader = Loader(module);
let pageMod = loader.require("sdk/page-mod"); let pageMod = loader.require("sdk/page-mod");
@ -54,12 +49,12 @@ exports.testPageMod = function testPageMod(test, testURL, pageModOptions,
// this code again. // this code again.
timer.setTimeout(testCallback, 0, timer.setTimeout(testCallback, 0,
b.contentWindow.wrappedJSObject, b.contentWindow.wrappedJSObject,
function done() { function () {
pageMods.forEach(function(mod) mod.destroy()); pageMods.forEach(function(mod) mod.destroy());
// XXX leaks reported if we don't close the tab? // XXX leaks reported if we don't close the tab?
closeTab(newTab); closeTab(newTab);
loader.unload(); loader.unload();
test.done(); done();
} }
); );
} }

Просмотреть файл

@ -10,9 +10,7 @@ const { getMostRecentBrowserWindow, isWindowPrivate } = require('sdk/window/util
const { set: setPref } = require("sdk/preferences/service"); const { set: setPref } = require("sdk/preferences/service");
const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings"; const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings";
exports["test activate private mode via handler"] = function(test) { exports["test activate private mode via handler"] = function(assert, done) {
test.waitUntilDone();
function onReady(tab) { function onReady(tab) {
if (tab.url == "about:robots") if (tab.url == "about:robots")
tab.close(function() pb.activate()); tab.close(function() pb.activate());
@ -21,18 +19,18 @@ exports["test activate private mode via handler"] = function(test) {
if (tab.url == "about:") { if (tab.url == "about:") {
tabs.removeListener("ready", cleanup); tabs.removeListener("ready", cleanup);
tab.close(function onClose() { tab.close(function onClose() {
test.done(); done();
}); });
} }
} }
tabs.on("ready", onReady); tabs.on("ready", onReady);
pb.once("start", function onStart() { pb.once("start", function onStart() {
test.pass("private mode was activated"); assert.pass("private mode was activated");
pb.deactivate(); pb.deactivate();
}); });
pb.once("stop", function onStop() { pb.once("stop", function onStop() {
test.pass("private mode was deactivated"); assert.pass("private mode was deactivated");
tabs.removeListener("ready", onReady); tabs.removeListener("ready", onReady);
tabs.on("ready", cleanup); tabs.on("ready", cleanup);
}); });
@ -44,18 +42,16 @@ exports["test activate private mode via handler"] = function(test) {
// tests that isActive has the same value as the private browsing service // tests that isActive has the same value as the private browsing service
// expects // expects
exports.testGetIsActive = function (test) { exports.testGetIsActive = function (assert) {
test.waitUntilDone(); assert.equal(pb.isActive, false,
test.assertEqual(pb.isActive, false,
"private-browsing.isActive is correct without modifying PB service"); "private-browsing.isActive is correct without modifying PB service");
test.assertEqual(pb.isPrivate(), false, assert.equal(pb.isPrivate(), false,
"private-browsing.sPrivate() is correct without modifying PB service"); "private-browsing.sPrivate() is correct without modifying PB service");
pb.once("start", function() { pb.once("start", function() {
test.assert(pb.isActive, assert.ok(pb.isActive,
"private-browsing.isActive is correct after modifying PB service"); "private-browsing.isActive is correct after modifying PB service");
test.assert(pb.isPrivate(), assert.ok(pb.isPrivate(),
"private-browsing.sPrivate() is correct after modifying PB service"); "private-browsing.sPrivate() is correct after modifying PB service");
// Switch back to normal mode. // Switch back to normal mode.
pb.deactivate(); pb.deactivate();
@ -63,42 +59,39 @@ exports.testGetIsActive = function (test) {
pb.activate(); pb.activate();
pb.once("stop", function() { pb.once("stop", function() {
test.assert(!pb.isActive, assert.ok(!pb.isActive,
"private-browsing.isActive is correct after modifying PB service"); "private-browsing.isActive is correct after modifying PB service");
test.assert(!pb.isPrivate(), assert.ok(!pb.isPrivate(),
"private-browsing.sPrivate() is correct after modifying PB service"); "private-browsing.sPrivate() is correct after modifying PB service");
test.done(); test.done();
}); });
}; };
exports.testStart = function(test) { exports.testStart = function(assert, done) {
test.waitUntilDone();
pb.on("start", function onStart() { pb.on("start", function onStart() {
test.assertEqual(this, pb, "`this` should be private-browsing module"); assert.equal(this, pb, "`this` should be private-browsing module");
test.assert(pbUtils.getMode(), assert.ok(pbUtils.getMode(),
'private mode is active when "start" event is emitted'); 'private mode is active when "start" event is emitted');
test.assert(pb.isActive, assert.ok(pb.isActive,
'`isActive` is `true` when "start" event is emitted'); '`isActive` is `true` when "start" event is emitted');
test.assert(pb.isPrivate(), assert.ok(pb.isPrivate(),
'`isPrivate` is `true` when "start" event is emitted'); '`isPrivate` is `true` when "start" event is emitted');
pb.removeListener("start", onStart); pb.removeListener("start", onStart);
deactivate(function() test.done()); deactivate(done);
}); });
pb.activate(); pb.activate();
}; };
exports.testStop = function(test) { exports.testStop = function(assert, done) {
test.waitUntilDone();
pb.once("stop", function onStop() { pb.once("stop", function onStop() {
test.assertEqual(this, pb, "`this` should be private-browsing module"); assert.equal(this, pb, "`this` should be private-browsing module");
test.assertEqual(pbUtils.getMode(), false, assert.equal(pbUtils.getMode(), false,
"private mode is disabled when stop event is emitted"); "private mode is disabled when stop event is emitted");
test.assertEqual(pb.isActive, false, assert.equal(pb.isActive, false,
"`isActive` is `false` when stop event is emitted"); "`isActive` is `false` when stop event is emitted");
test.assertEqual(pb.isPrivate(), false, assert.equal(pb.isPrivate(), false,
"`isPrivate()` is `false` when stop event is emitted"); "`isPrivate()` is `false` when stop event is emitted");
test.done(); done();
}); });
pb.activate(); pb.activate();
pb.once("start", function() { pb.once("start", function() {
@ -106,19 +99,18 @@ exports.testStop = function(test) {
}); });
}; };
exports.testBothListeners = function(test) { exports.testBothListeners = function(assert, done) {
test.waitUntilDone();
let stop = false; let stop = false;
let start = false; let start = false;
function onStop() { function onStop() {
test.assertEqual(stop, false, assert.equal(stop, false,
"stop callback must be called only once"); "stop callback must be called only once");
test.assertEqual(pbUtils.getMode(), false, assert.equal(pbUtils.getMode(), false,
"private mode is disabled when stop event is emitted"); "private mode is disabled when stop event is emitted");
test.assertEqual(pb.isActive, false, assert.equal(pb.isActive, false,
"`isActive` is `false` when stop event is emitted"); "`isActive` is `false` when stop event is emitted");
test.assertEqual(pb.isPrivate(), false, assert.equal(pb.isPrivate(), false,
"`isPrivate()` is `false` when stop event is emitted"); "`isPrivate()` is `false` when stop event is emitted");
pb.on("start", finish); pb.on("start", finish);
@ -129,13 +121,13 @@ exports.testBothListeners = function(test) {
} }
function onStart() { function onStart() {
test.assertEqual(false, start, assert.equal(false, start,
"stop callback must be called only once"); "stop callback must be called only once");
test.assert(pbUtils.getMode(), assert.ok(pbUtils.getMode(),
"private mode is active when start event is emitted"); "private mode is active when start event is emitted");
test.assert(pb.isActive, assert.ok(pb.isActive,
"`isActive` is `true` when start event is emitted"); "`isActive` is `true` when start event is emitted");
test.assert(pb.isPrivate(), assert.ok(pb.isPrivate(),
"`isPrivate()` is `true` when start event is emitted"); "`isPrivate()` is `true` when start event is emitted");
pb.on("stop", onStop); pb.on("stop", onStop);
@ -144,16 +136,16 @@ exports.testBothListeners = function(test) {
} }
function onStart2() { function onStart2() {
test.assert(start, "start listener must be called already"); assert.ok(start, "start listener must be called already");
test.assertEqual(false, stop, "stop callback must not be called yet"); assert.equal(false, stop, "stop callback must not be called yet");
} }
function finish() { function finish() {
test.assert(pbUtils.getMode(), true, assert.ok(pbUtils.getMode(), true,
"private mode is active when start event is emitted"); "private mode is active when start event is emitted");
test.assert(pb.isActive, assert.ok(pb.isActive,
"`isActive` is `true` when start event is emitted"); "`isActive` is `true` when start event is emitted");
test.assert(pb.isPrivate(), assert.ok(pb.isPrivate(),
"`isPrivate()` is `true` when start event is emitted"); "`isPrivate()` is `true` when start event is emitted");
pb.removeListener("start", finish); pb.removeListener("start", finish);
@ -161,11 +153,11 @@ exports.testBothListeners = function(test) {
pb.deactivate(); pb.deactivate();
pb.once("stop", function () { pb.once("stop", function () {
test.assertEqual(pbUtils.getMode(), false); assert.equal(pbUtils.getMode(), false);
test.assertEqual(pb.isActive, false); assert.equal(pb.isActive, false);
test.assertEqual(pb.isPrivate(), false); assert.equal(pb.isPrivate(), false);
test.done(); done();
}); });
} }
@ -174,8 +166,7 @@ exports.testBothListeners = function(test) {
pb.activate(); pb.activate();
}; };
exports.testAutomaticUnload = function(test) { exports.testAutomaticUnload = function(assert, done) {
test.waitUntilDone();
setPref(DEPRECATE_PREF, true); setPref(DEPRECATE_PREF, true);
// Create another private browsing instance and unload it // Create another private browsing instance and unload it
@ -184,7 +175,7 @@ exports.testAutomaticUnload = function(test) {
let called = false; let called = false;
pb2.on("start", function onStart() { pb2.on("start", function onStart() {
called = true; called = true;
test.fail("should not be called:x"); assert.fail("should not be called:x");
}); });
loader.unload(); loader.unload();
@ -192,12 +183,12 @@ exports.testAutomaticUnload = function(test) {
// is correctly destroyed // is correctly destroyed
pb.once("start", function onStart() { pb.once("start", function onStart() {
timer.setTimeout(function () { timer.setTimeout(function () {
test.assert(!called, assert.ok(!called,
"First private browsing instance is destroyed and inactive"); "First private browsing instance is destroyed and inactive");
// Must reset to normal mode, so that next test starts with it. // Must reset to normal mode, so that next test starts with it.
deactivate(function() { deactivate(function() {
test.assert(errors.length, 0, "should have been 1 deprecation error"); assert.ok(errors.length, 0, "should have been 1 deprecation error");
test.done(); done();
}); });
}, 0); }, 0);
}); });
@ -205,9 +196,7 @@ exports.testAutomaticUnload = function(test) {
pb.activate(); pb.activate();
}; };
exports.testUnloadWhileActive = function(test) { exports.testUnloadWhileActive = function(assert, done) {
test.waitUntilDone();
let called = false; let called = false;
let { loader, errors } = LoaderWithHookedConsole(module); let { loader, errors } = LoaderWithHookedConsole(module);
let pb2 = loader.require("sdk/private-browsing"); let pb2 = loader.require("sdk/private-browsing");
@ -225,28 +214,25 @@ exports.testUnloadWhileActive = function(test) {
}); });
pb2.once("stop", function() { pb2.once("stop", function() {
called = true; called = true;
test.assert(unloadHappened, "the unload event should have already occurred."); assert.ok(unloadHappened, "the unload event should have already occurred.");
test.fail("stop should not have been fired"); assert.fail("stop should not have been fired");
}); });
pb.once("stop", function() { pb.once("stop", function() {
test.assert(!called, "stop was not called on unload"); assert.ok(!called, "stop was not called on unload");
test.assert(errors.length, 2, "should have been 2 deprecation errors"); assert.ok(errors.length, 2, "should have been 2 deprecation errors");
test.done(); done();
}); });
pb.activate(); pb.activate();
}; };
exports.testIgnoreWindow = function(test) { exports.testIgnoreWindow = function(assert, done) {
test.waitUntilDone();
let window = getMostRecentBrowserWindow(); let window = getMostRecentBrowserWindow();
pb.once('start', function() { pb.once('start', function() {
test.assert(isWindowPrivate(window), 'window is private'); assert.ok(isWindowPrivate(window), 'window is private');
test.assert(!pbUtils.ignoreWindow(window), 'window is not ignored'); assert.ok(!pbUtils.ignoreWindow(window), 'window is not ignored');
pb.once('stop', function() { pb.once('stop', done);
test.done();
});
pb.deactivate(); pb.deactivate();
}); });
pb.activate(); pb.activate();

Просмотреть файл

@ -6,22 +6,22 @@ const { browserWindows } = require('sdk/windows');
const { getOwnerWindow } = require('sdk/private-browsing/window/utils'); const { getOwnerWindow } = require('sdk/private-browsing/window/utils');
const { isPrivate } = require('sdk/private-browsing'); const { isPrivate } = require('sdk/private-browsing');
exports.testIsPrivateOnTab = function(test) { exports.testIsPrivateOnTab = function(assert) {
let window = browserWindows.activeWindow; let window = browserWindows.activeWindow;
let chromeWindow = getOwnerWindow(window); let chromeWindow = getOwnerWindow(window);
test.assert(chromeWindow instanceof Ci.nsIDOMWindow, 'associated window is found'); assert.ok(chromeWindow instanceof Ci.nsIDOMWindow, 'associated window is found');
test.assert(!isPrivate(chromeWindow), 'the top level window is not private'); assert.ok(!isPrivate(chromeWindow), 'the top level window is not private');
let rawTab = openTab(chromeWindow, 'data:text/html,<h1>Hi!</h1>', { let rawTab = openTab(chromeWindow, 'data:text/html,<h1>Hi!</h1>', {
isPrivate: true isPrivate: true
}); });
// test that the tab is private // test that the tab is private
test.assert(rawTab.browser.docShell.QueryInterface(Ci.nsILoadContext).usePrivateBrowsing); assert.ok(rawTab.browser.docShell.QueryInterface(Ci.nsILoadContext).usePrivateBrowsing);
test.assert(isPrivate(rawTab.browser.contentWindow)); assert.ok(isPrivate(rawTab.browser.contentWindow));
test.assert(isPrivate(rawTab.browser)); assert.ok(isPrivate(rawTab.browser));
closeTab(rawTab); closeTab(rawTab);
} };

Просмотреть файл

@ -137,5 +137,3 @@ exports.testIsPrivateOnWindowOff = function(assert, done) {
} }
}) })
} }
require("test").run(exports);

Просмотреть файл

@ -140,7 +140,7 @@ exports['test Uninstall failure'] = function (assert, done) {
).then(done, assert.fail); ).then(done, assert.fail);
}; };
exports['test Addon Disable'] = function (assert, done) { exports['test Addon Disable and Enable'] = function (assert, done) {
let ensureActive = (addonId) => AddonInstaller.isActive(addonId).then(state => { let ensureActive = (addonId) => AddonInstaller.isActive(addonId).then(state => {
assert.equal(state, true, 'Addon should be enabled by default'); assert.equal(state, true, 'Addon should be enabled by default');
return addonId; return addonId;
@ -151,9 +151,15 @@ exports['test Addon Disable'] = function (assert, done) {
}); });
AddonInstaller.install(ADDON_PATH) AddonInstaller.install(ADDON_PATH)
.then(ensureActive)
.then(AddonInstaller.enable) // should do nothing, yet not fail
.then(ensureActive) .then(ensureActive)
.then(AddonInstaller.disable) .then(AddonInstaller.disable)
.then(ensureInactive) .then(ensureInactive)
.then(AddonInstaller.disable) // should do nothing, yet not fail
.then(ensureInactive)
.then(AddonInstaller.enable)
.then(ensureActive)
.then(AddonInstaller.uninstall) .then(AddonInstaller.uninstall)
.then(done, assert.fail); .then(done, assert.fail);
}; };
@ -165,4 +171,11 @@ exports['test Disable failure'] = function (assert, done) {
).then(done, assert.fail); ).then(done, assert.fail);
}; };
exports['test Enable failure'] = function (assert, done) {
AddonInstaller.enable('not-an-id').then(
() => assert.fail('Addon enable should not resolve successfully'),
() => assert.pass('Addon correctly rejected invalid enable')
).then(done, assert.fail);
};
require("test").run(exports); require("test").run(exports);

Просмотреть файл

@ -1,16 +1,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Cc,Ci } = require("chrome"); const { Cc, Ci } = require("chrome");
const { StringBundle } = require("sdk/deprecated/app-strings");
let StringBundle = require("sdk/deprecated/app-strings").StringBundle; exports.testStringBundle = function(assert) {
exports.testStringBundle = function(test) {
let url = "chrome://global/locale/security/caps.properties"; let url = "chrome://global/locale/security/caps.properties";
let strings = StringBundle(url); let strings = StringBundle(url);
test.assertEqual(strings.url, url, assert.equal(strings.url, url,
"'url' property contains correct URL of string bundle"); "'url' property contains correct URL of string bundle");
let appLocale = Cc["@mozilla.org/intl/nslocaleservice;1"]. let appLocale = Cc["@mozilla.org/intl/nslocaleservice;1"].
@ -22,20 +23,20 @@ exports.testStringBundle = function(test) {
createBundle(url, appLocale); createBundle(url, appLocale);
let (name = "CheckMessage") { let (name = "CheckMessage") {
test.assertEqual(strings.get(name), stringBundle.GetStringFromName(name), assert.equal(strings.get(name), stringBundle.GetStringFromName(name),
"getting a string returns the string"); "getting a string returns the string");
} }
let (name = "CreateWrapperDenied", args = ["foo"]) { let (name = "CreateWrapperDenied", args = ["foo"]) {
test.assertEqual(strings.get(name, args), assert.equal(strings.get(name, args),
stringBundle.formatStringFromName(name, args, args.length), stringBundle.formatStringFromName(name, args, args.length),
"getting a formatted string returns the formatted string"); "getting a formatted string returns the formatted string");
} }
test.assertRaises(function () strings.get("nonexistentString"), assert.throws(function () strings.get("nonexistentString"),
"String 'nonexistentString' could not be retrieved from " + RegExp("String 'nonexistentString' could not be retrieved from " +
"the bundle due to an unknown error (it doesn't exist?).", "the bundle due to an unknown error \\(it doesn't exist\\?\\)\\."),
"retrieving a nonexistent string throws an exception"); "retrieving a nonexistent string throws an exception");
let a = [], b = []; let a = [], b = [];
let enumerator = stringBundle.getSimpleEnumeration(); let enumerator = stringBundle.getSimpleEnumeration();
@ -43,8 +44,10 @@ exports.testStringBundle = function(test) {
let elem = enumerator.getNext().QueryInterface(Ci.nsIPropertyElement); let elem = enumerator.getNext().QueryInterface(Ci.nsIPropertyElement);
a.push([elem.key, elem.value]); a.push([elem.key, elem.value]);
} }
for (let key in strings)
for (let key in strings) {
b.push([ key, strings.get(key) ]); b.push([ key, strings.get(key) ]);
}
// Sort the arrays, because we don't assume enumeration has a set order. // Sort the arrays, because we don't assume enumeration has a set order.
// Sort compares [key, val] as string "key,val", which sorts the way we want // Sort compares [key, val] as string "key,val", which sorts the way we want
@ -52,11 +55,14 @@ exports.testStringBundle = function(test) {
a.sort(); a.sort();
b.sort(); b.sort();
test.assertEqual(a.length, b.length, assert.equal(a.length, b.length,
"the iterator returns the correct number of items"); "the iterator returns the correct number of items");
for (let i = 0; i < a.length; i++) { for (let i = 0; i < a.length; i++) {
test.assertEqual(a[i][0], b[i][0], "the iterated string's name is correct"); assert.equal(a[i][0], b[i][0], "the iterated string's name is correct");
test.assertEqual(a[i][1], b[i][1], assert.equal(a[i][1], b[i][1],
"the iterated string's value is correct"); "the iterated string's value is correct");
} }
}; };
require("sdk/test").run(exports);

Просмотреть файл

@ -0,0 +1,90 @@
/* 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 { Buffer, TextEncoder, TextDecoder } = require('sdk/io/buffer');
exports.testIsEncoding = function (assert) {
Object.keys(ENCODINGS).forEach(encoding => {
assert.ok(Buffer.isEncoding(encoding),
'Buffer.isEncoding ' + encoding + ' truthy');
});
['not-encoding', undefined, null, 100, {}].forEach(encoding => {
assert.ok(!Buffer.isEncoding(encoding),
'Buffer.isEncoding ' + encoding + ' falsy');
});
};
exports.testIsBuffer = function (assert) {
let buffer = new Buffer('content', 'utf8');
assert.ok(Buffer.isBuffer(buffer), 'isBuffer truthy on buffers');
assert.ok(!Buffer.isBuffer({}), 'isBuffer falsy on objects');
assert.ok(!Buffer.isBuffer(new Uint8Array()),
'isBuffer falsy on Uint8Array');
};
exports.testBufferByteLength = function (assert) {
let str = '\u00bd + \u00bc = \u00be';
assert.equal(Buffer.byteLength(str), 12,
'correct byteLength of string');
};
exports.testTextEncoderDecoder = function (assert) {
assert.ok(TextEncoder, 'TextEncoder exists');
assert.ok(TextDecoder, 'TextDecoder exists');
};
// List of supported encodings taken from:
// http://mxr.mozilla.org/mozilla-central/source/dom/encoding/labelsencodings.properties
const ENCODINGS = { "unicode-1-1-utf-8": 1, "utf-8": 1, "utf8": 1,
"866": 1, "cp866": 1, "csibm866": 1, "ibm866": 1, "csisolatin2": 1,
"iso-8859-2": 1, "iso-ir-101": 1, "iso8859-2": 1, "iso88592": 1,
"iso_8859-2": 1, "iso_8859-2:1987": 1, "l2": 1, "latin2": 1, "csisolatin3": 1,
"iso-8859-3": 1, "iso-ir-109": 1, "iso8859-3": 1, "iso88593": 1,
"iso_8859-3": 1, "iso_8859-3:1988": 1, "l3": 1, "latin3": 1, "csisolatin4": 1,
"iso-8859-4": 1, "iso-ir-110": 1, "iso8859-4": 1, "iso88594": 1,
"iso_8859-4": 1, "iso_8859-4:1988": 1, "l4": 1, "latin4": 1,
"csisolatincyrillic": 1, "cyrillic": 1, "iso-8859-5": 1, "iso-ir-144": 1,
"iso8859-5": 1, "iso88595": 1, "iso_8859-5": 1, "iso_8859-5:1988": 1,
"arabic": 1, "asmo-708": 1, "csiso88596e": 1, "csiso88596i": 1,
"csisolatinarabic": 1, "ecma-114": 1, "iso-8859-6": 1, "iso-8859-6-e": 1,
"iso-8859-6-i": 1, "iso-ir-127": 1, "iso8859-6": 1, "iso88596": 1,
"iso_8859-6": 1, "iso_8859-6:1987": 1, "csisolatingreek": 1, "ecma-118": 1,
"elot_928": 1, "greek": 1, "greek8": 1, "iso-8859-7": 1, "iso-ir-126": 1,
"iso8859-7": 1, "iso88597": 1, "iso_8859-7": 1, "iso_8859-7:1987": 1,
"sun_eu_greek": 1, "csiso88598e": 1, "csisolatinhebrew": 1, "hebrew": 1,
"iso-8859-8": 1, "iso-8859-8-e": 1, "iso-ir-138": 1, "iso8859-8": 1,
"iso88598": 1, "iso_8859-8": 1, "iso_8859-8:1988": 1, "visual": 1,
"csiso88598i": 1, "iso-8859-8-i": 1, "logical": 1, "csisolatin6": 1,
"iso-8859-10": 1, "iso-ir-157": 1, "iso8859-10": 1, "iso885910": 1,
"l6": 1, "latin6": 1, "iso-8859-13": 1, "iso8859-13": 1, "iso885913": 1,
"iso-8859-14": 1, "iso8859-14": 1, "iso885914": 1, "csisolatin9": 1,
"iso-8859-15": 1, "iso8859-15": 1, "iso885915": 1, "iso_8859-15": 1,
"l9": 1, "iso-8859-16": 1, "cskoi8r": 1, "koi": 1, "koi8": 1, "koi8-r": 1,
"koi8_r": 1, "koi8-u": 1, "csmacintosh": 1, "mac": 1, "macintosh": 1,
"x-mac-roman": 1, "dos-874": 1, "iso-8859-11": 1, "iso8859-11": 1,
"iso885911": 1, "tis-620": 1, "windows-874": 1, "cp1250": 1,
"windows-1250": 1, "x-cp1250": 1, "cp1251": 1, "windows-1251": 1,
"x-cp1251": 1, "ansi_x3.4-1968": 1, "ascii": 1, "cp1252": 1, "cp819": 1,
"csisolatin1": 1, "ibm819": 1, "iso-8859-1": 1, "iso-ir-100": 1,
"iso8859-1": 1, "iso88591": 1, "iso_8859-1": 1, "iso_8859-1:1987": 1,
"l1": 1, "latin1": 1, "us-ascii": 1, "windows-1252": 1, "x-cp1252": 1,
"cp1253": 1, "windows-1253": 1, "x-cp1253": 1, "cp1254": 1, "csisolatin5": 1,
"iso-8859-9": 1, "iso-ir-148": 1, "iso8859-9": 1, "iso88599": 1,
"iso_8859-9": 1, "iso_8859-9:1989": 1, "l5": 1, "latin5": 1,
"windows-1254": 1, "x-cp1254": 1, "cp1255": 1, "windows-1255": 1,
"x-cp1255": 1, "cp1256": 1, "windows-1256": 1, "x-cp1256": 1, "cp1257": 1,
"windows-1257": 1, "x-cp1257": 1, "cp1258": 1, "windows-1258": 1,
"x-cp1258": 1, "x-mac-cyrillic": 1, "x-mac-ukrainian": 1, "chinese": 1,
"csgb2312": 1, "csiso58gb231280": 1, "gb2312": 1, "gb_2312": 1,
"gb_2312-80": 1, "gbk": 1, "iso-ir-58": 1, "x-gbk": 1, "gb18030": 1,
"hz-gb-2312": 1, "big5": 1, "big5-hkscs": 1, "cn-big5": 1, "csbig5": 1,
"x-x-big5": 1, "cseucpkdfmtjapanese": 1, "euc-jp": 1, "x-euc-jp": 1,
"csiso2022jp": 1, "iso-2022-jp": 1, "csshiftjis": 1, "ms_kanji": 1,
"shift-jis": 1, "shift_jis": 1, "sjis": 1, "windows-31j": 1, "x-sjis": 1,
"cseuckr": 1, "csksc56011987": 1, "euc-kr": 1, "iso-ir-149": 1, "korean": 1,
"ks_c_5601-1987": 1, "ks_c_5601-1989": 1, "ksc5601": 1, "ksc_5601": 1,
"windows-949": 1, "csiso2022kr": 1, "iso-2022-kr": 1, "utf-16": 1,
"utf-16le": 1, "utf-16be": 1, "x-user-defined": 1 };
require('sdk/test').run(exports);

Просмотреть файл

@ -7,67 +7,67 @@ const file = require("sdk/io/file");
const { pathFor } = require("sdk/system"); const { pathFor } = require("sdk/system");
const { Loader } = require("sdk/test/loader"); const { Loader } = require("sdk/test/loader");
const STREAM_CLOSED_ERROR = "The stream is closed and cannot be used."; const STREAM_CLOSED_ERROR = new RegExp("The stream is closed and cannot be used.");
// This should match the constant of the same name in byte-streams.js. // This should match the constant of the same name in byte-streams.js.
const BUFFER_BYTE_LEN = 0x8000; const BUFFER_BYTE_LEN = 0x8000;
exports.testWriteRead = function (test) { exports.testWriteRead = function (assert) {
let fname = dataFileFilename(); let fname = dataFileFilename();
// Write a small string less than the stream's buffer size... // Write a small string less than the stream's buffer size...
let str = "exports.testWriteRead data!"; let str = "exports.testWriteRead data!";
let stream = open(test, fname, true); let stream = open(assert, fname, true);
test.assert(!stream.closed, "stream.closed after open should be false"); assert.ok(!stream.closed, "stream.closed after open should be false");
stream.write(str); stream.write(str);
stream.close(); stream.close();
test.assert(stream.closed, "Stream should be closed after stream.close"); assert.ok(stream.closed, "Stream should be closed after stream.close");
test.assertRaises(function () stream.write("This shouldn't be written!"), assert.throws(function () stream.write("This shouldn't be written!"),
STREAM_CLOSED_ERROR, STREAM_CLOSED_ERROR,
"stream.write after close should raise error"); "stream.write after close should raise error");
// ... and read it. // ... and read it.
stream = open(test, fname); stream = open(assert, fname);
test.assertEqual(stream.read(), str, assert.equal(stream.read(), str,
"stream.read should return string written"); "stream.read should return string written");
test.assertEqual(stream.read(), "", assert.equal(stream.read(), "",
"stream.read at EOS should return empty string"); "stream.read at EOS should return empty string");
stream.close(); stream.close();
test.assert(stream.closed, "Stream should be closed after stream.close"); assert.ok(stream.closed, "Stream should be closed after stream.close");
test.assertRaises(function () stream.read(), assert.throws(function () stream.read(),
STREAM_CLOSED_ERROR, STREAM_CLOSED_ERROR,
"stream.read after close should raise error"); "stream.read after close should raise error");
file.remove(fname); file.remove(fname);
}; };
// Write a big string many times the size of the stream's buffer and read it. // Write a big string many times the size of the stream's buffer and read it.
exports.testWriteReadBig = function (test) { exports.testWriteReadBig = function (assert) {
let str = ""; let str = "";
let bufLen = BUFFER_BYTE_LEN; let bufLen = BUFFER_BYTE_LEN;
let fileSize = bufLen * 10; let fileSize = bufLen * 10;
for (let i = 0; i < fileSize; i++) for (let i = 0; i < fileSize; i++)
str += i % 10; str += i % 10;
let fname = dataFileFilename(); let fname = dataFileFilename();
let stream = open(test, fname, true); let stream = open(assert, fname, true);
stream.write(str); stream.write(str);
stream.close(); stream.close();
stream = open(test, fname); stream = open(assert, fname);
test.assertEqual(stream.read(), str, assert.equal(stream.read(), str,
"stream.read should return string written"); "stream.read should return string written");
stream.close(); stream.close();
file.remove(fname); file.remove(fname);
}; };
// The same, but write and read in chunks. // The same, but write and read in chunks.
exports.testWriteReadChunks = function (test) { exports.testWriteReadChunks = function (assert) {
let str = ""; let str = "";
let bufLen = BUFFER_BYTE_LEN; let bufLen = BUFFER_BYTE_LEN;
let fileSize = bufLen * 10; let fileSize = bufLen * 10;
for (let i = 0; i < fileSize; i++) for (let i = 0; i < fileSize; i++)
str += i % 10; str += i % 10;
let fname = dataFileFilename(); let fname = dataFileFilename();
let stream = open(test, fname, true); let stream = open(assert, fname, true);
let i = 0; let i = 0;
while (i < str.length) { while (i < str.length) {
// Use a chunk length that spans buffers. // Use a chunk length that spans buffers.
@ -76,7 +76,7 @@ exports.testWriteReadChunks = function (test) {
i += bufLen + 1; i += bufLen + 1;
} }
stream.close(); stream.close();
stream = open(test, fname); stream = open(assert, fname);
let readStr = ""; let readStr = "";
bufLen = BUFFER_BYTE_LEN; bufLen = BUFFER_BYTE_LEN;
let readLen = bufLen + 1; let readLen = bufLen + 1;
@ -85,63 +85,63 @@ exports.testWriteReadChunks = function (test) {
readStr += frag; readStr += frag;
} while (frag); } while (frag);
stream.close(); stream.close();
test.assertEqual(readStr, str, assert.equal(readStr, str,
"stream.write and read in chunks should work as expected"); "stream.write and read in chunks should work as expected");
file.remove(fname); file.remove(fname);
}; };
exports.testReadLengths = function (test) { exports.testReadLengths = function (assert) {
let fname = dataFileFilename(); let fname = dataFileFilename();
let str = "exports.testReadLengths data!"; let str = "exports.testReadLengths data!";
let stream = open(test, fname, true); let stream = open(assert, fname, true);
stream.write(str); stream.write(str);
stream.close(); stream.close();
stream = open(test, fname); stream = open(assert, fname);
test.assertEqual(stream.read(str.length * 1000), str, assert.equal(stream.read(str.length * 1000), str,
"stream.read with big byte length should return string " + "stream.read with big byte length should return string " +
"written"); "written");
stream.close(); stream.close();
stream = open(test, fname); stream = open(assert, fname);
test.assertEqual(stream.read(0), "", assert.equal(stream.read(0), "",
"string.read with zero byte length should return empty " + "string.read with zero byte length should return empty " +
"string"); "string");
stream.close(); stream.close();
stream = open(test, fname); stream = open(assert, fname);
test.assertEqual(stream.read(-1), "", assert.equal(stream.read(-1), "",
"string.read with negative byte length should return " + "string.read with negative byte length should return " +
"empty string"); "empty string");
stream.close(); stream.close();
file.remove(fname); file.remove(fname);
}; };
exports.testTruncate = function (test) { exports.testTruncate = function (assert) {
let fname = dataFileFilename(); let fname = dataFileFilename();
let str = "exports.testReadLengths data!"; let str = "exports.testReadLengths data!";
let stream = open(test, fname, true); let stream = open(assert, fname, true);
stream.write(str); stream.write(str);
stream.close(); stream.close();
stream = open(test, fname); stream = open(assert, fname);
test.assertEqual(stream.read(), str, assert.equal(stream.read(), str,
"stream.read should return string written"); "stream.read should return string written");
stream.close(); stream.close();
stream = open(test, fname, true); stream = open(assert, fname, true);
stream.close(); stream.close();
stream = open(test, fname); stream = open(assert, fname);
test.assertEqual(stream.read(), "", assert.equal(stream.read(), "",
"stream.read after truncate should be empty"); "stream.read after truncate should be empty");
stream.close(); stream.close();
file.remove(fname); file.remove(fname);
}; };
exports.testUnload = function (test) { exports.testUnload = function (assert) {
let loader = Loader(module); let loader = Loader(module);
let file = loader.require("sdk/io/file"); let file = loader.require("sdk/io/file");
@ -149,7 +149,7 @@ exports.testUnload = function (test) {
let stream = file.open(filename, "wb"); let stream = file.open(filename, "wb");
loader.unload(); loader.unload();
test.assert(stream.closed, "Stream should be closed after module unload"); assert.ok(stream.closed, "Stream should be closed after module unload");
}; };
// Returns the name of a file that should be used to test writing and reading. // Returns the name of a file that should be used to test writing and reading.
@ -158,10 +158,12 @@ function dataFileFilename() {
} }
// Opens and returns the given file and ensures it's of the correct class. // Opens and returns the given file and ensures it's of the correct class.
function open(test, filename, forWriting) { function open(assert, filename, forWriting) {
let stream = file.open(filename, forWriting ? "wb" : "b"); let stream = file.open(filename, forWriting ? "wb" : "b");
let klass = forWriting ? "ByteWriter" : "ByteReader"; let klass = forWriting ? "ByteWriter" : "ByteReader";
test.assert(stream instanceof byteStreams[klass], assert.ok(stream instanceof byteStreams[klass],
"Opened stream should be a " + klass); "Opened stream should be a " + klass);
return stream; return stream;
} }
require('sdk/test').run(exports);

Просмотреть файл

@ -6,28 +6,28 @@
const { Loader } = require('sdk/content/loader'); const { Loader } = require('sdk/content/loader');
const self = require("sdk/self"); const self = require("sdk/self");
exports['test:contentURL'] = function(test) { exports['test:contentURL'] = function(assert) {
let loader = Loader(), let loader = Loader(),
value, emitted = 0, changes = 0; value, emitted = 0, changes = 0;
test.assertRaises( assert.throws(
function() loader.contentURL = 4, function() loader.contentURL = 4,
'The `contentURL` option must be a valid URL.', /The `contentURL` option must be a valid URL./,
'Must throw an exception if `contentURL` is not URL.' 'Must throw an exception if `contentURL` is not URL.'
); );
test.assertRaises( assert.throws(
function() loader.contentURL = { toString: function() 'Oops' }, function() loader.contentURL = { toString: function() 'Oops' },
'The `contentURL` option must be a valid URL.', /The `contentURL` option must be a valid URL./,
'Must throw an exception if `contentURL` is not URL.' 'Must throw an exception if `contentURL` is not URL.'
); );
function listener(e) { function listener(e) {
emitted ++; emitted ++;
test.assert( assert.ok(
'contentURL' in e, 'contentURL' in e,
'emitted event must contain "content" property' 'emitted event must contain "content" property'
); );
test.assert( assert.ok(
value, value,
'' + e.contentURL, '' + e.contentURL,
'content property of an event must match value' 'content property of an event must match value'
@ -35,42 +35,42 @@ exports['test:contentURL'] = function(test) {
} }
loader.on('propertyChange', listener); loader.on('propertyChange', listener);
test.assertEqual( assert.equal(
null, null,
loader.contentURL, loader.contentURL,
'default value is `null`' 'default value is `null`'
); );
loader.contentURL = value = 'data:text/html,<html><body>Hi</body><html>'; loader.contentURL = value = 'data:text/html,<html><body>Hi</body><html>';
test.assertEqual( assert.equal(
value, value,
'' + loader.contentURL, '' + loader.contentURL,
'data uri is ok' 'data uri is ok'
); );
test.assertEqual( assert.equal(
++changes, ++changes,
emitted, emitted,
'had to emit `propertyChange`' 'had to emit `propertyChange`'
); );
loader.contentURL = value; loader.contentURL = value;
test.assertEqual( assert.equal(
changes, changes,
emitted, emitted,
'must not emit `propertyChange` if same value is set' 'must not emit `propertyChange` if same value is set'
); );
loader.contentURL = value = 'http://google.com/'; loader.contentURL = value = 'http://google.com/';
test.assertEqual( assert.equal(
value, value,
'' + loader.contentURL, '' + loader.contentURL,
'value must be set' 'value must be set'
); );
test.assertEqual( assert.equal(
++ changes, ++ changes,
emitted, emitted,
'had to emit `propertyChange`' 'had to emit `propertyChange`'
); );
loader.contentURL = value; loader.contentURL = value;
test.assertEqual( assert.equal(
changes, changes,
emitted, emitted,
'must not emit `propertyChange` if same value is set' 'must not emit `propertyChange` if same value is set'
@ -78,27 +78,27 @@ exports['test:contentURL'] = function(test) {
loader.removeListener('propertyChange', listener); loader.removeListener('propertyChange', listener);
loader.contentURL = value = 'about:blank'; loader.contentURL = value = 'about:blank';
test.assertEqual( assert.equal(
value, value,
'' + loader.contentURL, '' + loader.contentURL,
'contentURL must be an actual value' 'contentURL must be an actual value'
); );
test.assertEqual( assert.equal(
changes, changes,
emitted, emitted,
'listener had to be romeved' 'listener had to be romeved'
); );
}; };
exports['test:contentScriptWhen'] = function(test) { exports['test:contentScriptWhen'] = function(assert) {
let loader = Loader(); let loader = Loader();
test.assertEqual( assert.equal(
'end', 'end',
loader.contentScriptWhen, loader.contentScriptWhen,
'`contentScriptWhen` defaults to "end"' '`contentScriptWhen` defaults to "end"'
); );
loader.contentScriptWhen = "end"; loader.contentScriptWhen = "end";
test.assertEqual( assert.equal(
"end", "end",
loader.contentScriptWhen loader.contentScriptWhen
); );
@ -106,38 +106,38 @@ exports['test:contentScriptWhen'] = function(test) {
loader.contentScriptWhen = 'boom'; loader.contentScriptWhen = 'boom';
test.fail('must throw when wrong value is set'); test.fail('must throw when wrong value is set');
} catch(e) { } catch(e) {
test.assertEqual( assert.equal(
'The `contentScriptWhen` option must be either "start", "ready" or "end".', 'The `contentScriptWhen` option must be either "start", "ready" or "end".',
e.message e.message
); );
} }
loader.contentScriptWhen = null; loader.contentScriptWhen = null;
test.assertEqual( assert.equal(
'end', 'end',
loader.contentScriptWhen, loader.contentScriptWhen,
'`contentScriptWhen` defaults to "end"' '`contentScriptWhen` defaults to "end"'
); );
loader.contentScriptWhen = "ready"; loader.contentScriptWhen = "ready";
test.assertEqual( assert.equal(
"ready", "ready",
loader.contentScriptWhen loader.contentScriptWhen
); );
loader.contentScriptWhen = "start"; loader.contentScriptWhen = "start";
test.assertEqual( assert.equal(
'start', 'start',
loader.contentScriptWhen loader.contentScriptWhen
); );
}; };
exports['test:contentScript'] = function(test) { exports['test:contentScript'] = function(assert) {
let loader = Loader(), value; let loader = Loader(), value;
test.assertEqual( assert.equal(
null, null,
loader.contentScript, loader.contentScript,
'`contentScript` defaults to `null`' '`contentScript` defaults to `null`'
); );
loader.contentScript = value = 'let test = {};'; loader.contentScript = value = 'let test = {};';
test.assertEqual( assert.equal(
value, value,
loader.contentScript loader.contentScript
); );
@ -145,7 +145,7 @@ exports['test:contentScript'] = function(test) {
loader.contentScript = { 1: value } loader.contentScript = { 1: value }
test.fail('must throw when wrong value is set'); test.fail('must throw when wrong value is set');
} catch(e) { } catch(e) {
test.assertEqual( assert.equal(
'The `contentScript` option must be a string or an array of strings.', 'The `contentScript` option must be a string or an array of strings.',
e.message e.message
); );
@ -154,32 +154,32 @@ exports['test:contentScript'] = function(test) {
loader.contentScript = ['oue', 2] loader.contentScript = ['oue', 2]
test.fail('must throw when wrong value is set'); test.fail('must throw when wrong value is set');
} catch(e) { } catch(e) {
test.assertEqual( assert.equal(
'The `contentScript` option must be a string or an array of strings.', 'The `contentScript` option must be a string or an array of strings.',
e.message e.message
); );
} }
loader.contentScript = undefined; loader.contentScript = undefined;
test.assertEqual( assert.equal(
null, null,
loader.contentScript loader.contentScript
); );
loader.contentScript = value = ["1;", "2;"]; loader.contentScript = value = ["1;", "2;"];
test.assertEqual( assert.equal(
value, value,
loader.contentScript loader.contentScript
); );
}; };
exports['test:contentScriptFile'] = function(test) { exports['test:contentScriptFile'] = function(assert) {
let loader = Loader(), value, uri = self.data.url("test-content-loader.js"); let loader = Loader(), value, uri = self.data.url("test-content-loader.js");
test.assertEqual( assert.equal(
null, null,
loader.contentScriptFile, loader.contentScriptFile,
'`contentScriptFile` defaults to `null`' '`contentScriptFile` defaults to `null`'
); );
loader.contentScriptFile = value = uri; loader.contentScriptFile = value = uri;
test.assertEqual( assert.equal(
value, value,
loader.contentScriptFile loader.contentScriptFile
); );
@ -187,7 +187,7 @@ exports['test:contentScriptFile'] = function(test) {
loader.contentScriptFile = { 1: uri } loader.contentScriptFile = { 1: uri }
test.fail('must throw when wrong value is set'); test.fail('must throw when wrong value is set');
} catch(e) { } catch(e) {
test.assertEqual( assert.equal(
'The `contentScriptFile` option must be a local URL or an array of URLs.', 'The `contentScriptFile` option must be a local URL or an array of URLs.',
e.message e.message
); );
@ -197,20 +197,22 @@ exports['test:contentScriptFile'] = function(test) {
loader.contentScriptFile = [ 'oue', uri ] loader.contentScriptFile = [ 'oue', uri ]
test.fail('must throw when wrong value is set'); test.fail('must throw when wrong value is set');
} catch(e) { } catch(e) {
test.assertEqual( assert.equal(
'The `contentScriptFile` option must be a local URL or an array of URLs.', 'The `contentScriptFile` option must be a local URL or an array of URLs.',
e.message e.message
); );
} }
loader.contentScriptFile = undefined; loader.contentScriptFile = undefined;
test.assertEqual( assert.equal(
null, null,
loader.contentScriptFile loader.contentScriptFile
); );
loader.contentScriptFile = value = [uri]; loader.contentScriptFile = value = [uri];
test.assertEqual( assert.equal(
value, value,
loader.contentScriptFile loader.contentScriptFile
); );
}; };
require('sdk/test').run(exports);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -24,22 +24,22 @@ const dirNameInProfile = 'extensions';
const filePathInProfile = file.join(profilePath, fileNameInProfile); const filePathInProfile = file.join(profilePath, fileNameInProfile);
const dirPathInProfile = file.join(profilePath, dirNameInProfile); const dirPathInProfile = file.join(profilePath, dirNameInProfile);
exports.testDirName = function(test) { exports.testDirName = function(assert) {
test.assertEqual(file.dirname(dirPathInProfile), profilePath, assert.equal(file.dirname(dirPathInProfile), profilePath,
"file.dirname() of dir should return parent dir"); "file.dirname() of dir should return parent dir");
test.assertEqual(file.dirname(filePathInProfile), profilePath, assert.equal(file.dirname(filePathInProfile), profilePath,
"file.dirname() of file should return its dir"); "file.dirname() of file should return its dir");
let dir = profilePath; let dir = profilePath;
while (dir) while (dir)
dir = file.dirname(dir); dir = file.dirname(dir);
test.assertEqual(dir, "", assert.equal(dir, "",
"dirname should return empty string when dir has no parent"); "dirname should return empty string when dir has no parent");
}; };
exports.testBasename = function(test) { exports.testBasename = function(assert) {
// Get the top-most path -- the path with no basename. E.g., on Unix-like // Get the top-most path -- the path with no basename. E.g., on Unix-like
// systems this will be /. We'll use it below to build up some test paths. // systems this will be /. We'll use it below to build up some test paths.
// We have to go to this trouble because file.join() needs a legal path as a // We have to go to this trouble because file.join() needs a legal path as a
@ -52,144 +52,144 @@ exports.testBasename = function(test) {
} }
let path = topPath; let path = topPath;
test.assertEqual(file.basename(path), "", assert.equal(file.basename(path), "",
"basename should work on paths with no components"); "basename should work on paths with no components");
path = file.join(path, "foo"); path = file.join(path, "foo");
test.assertEqual(file.basename(path), "foo", assert.equal(file.basename(path), "foo",
"basename should work on paths with a single component"); "basename should work on paths with a single component");
path = file.join(path, "bar"); path = file.join(path, "bar");
test.assertEqual(file.basename(path), "bar", assert.equal(file.basename(path), "bar",
"basename should work on paths with multiple components"); "basename should work on paths with multiple components");
}; };
exports.testList = function(test) { exports.testList = function(assert) {
let list = file.list(profilePath); let list = file.list(profilePath);
let found = [ true for each (name in list) let found = [ true for each (name in list)
if (name === fileNameInProfile) ]; if (name === fileNameInProfile) ];
if (found.length > 1) if (found.length > 1)
test.fail("a dir can't contain two files of the same name!"); assert.fail("a dir can't contain two files of the same name!");
test.assertEqual(found[0], true, "file.list() should work"); assert.equal(found[0], true, "file.list() should work");
test.assertRaises(function() { assert.throws(function() {
file.list(filePathInProfile); file.list(filePathInProfile);
}, ERRORS.NOT_A_DIRECTORY, "file.list() on non-dir should raise error"); }, ERRORS.NOT_A_DIRECTORY, "file.list() on non-dir should raise error");
test.assertRaises(function() { assert.throws(function() {
file.list(file.join(dirPathInProfile, "does-not-exist")); file.list(file.join(dirPathInProfile, "does-not-exist"));
}, ERRORS.FILE_NOT_FOUND, "file.list() on nonexistent should raise error"); }, ERRORS.FILE_NOT_FOUND, "file.list() on nonexistent should raise error");
}; };
exports.testRead = function(test) { exports.testRead = function(assert) {
let contents = file.read(filePathInProfile); let contents = file.read(filePathInProfile);
test.assertMatches(contents, /Compatibility/, assert.ok(/Compatibility/.test(contents),
"file.read() should work"); "file.read() should work");
test.assertRaises(function() { assert.throws(function() {
file.read(file.join(dirPathInProfile, "does-not-exists")); file.read(file.join(dirPathInProfile, "does-not-exists"));
}, ERRORS.FILE_NOT_FOUND, "file.read() on nonexistent file should throw"); }, ERRORS.FILE_NOT_FOUND, "file.read() on nonexistent file should throw");
test.assertRaises(function() { assert.throws(function() {
file.read(dirPathInProfile); file.read(dirPathInProfile);
}, ERRORS.NOT_A_FILE, "file.read() on dir should throw"); }, ERRORS.NOT_A_FILE, "file.read() on dir should throw");
}; };
exports.testJoin = function(test) { exports.testJoin = function(assert) {
let baseDir = file.dirname(filePathInProfile); let baseDir = file.dirname(filePathInProfile);
test.assertEqual(file.join(baseDir, fileNameInProfile), assert.equal(file.join(baseDir, fileNameInProfile),
filePathInProfile, "file.join() should work"); filePathInProfile, "file.join() should work");
}; };
exports.testOpenNonexistentForRead = function (test) { exports.testOpenNonexistentForRead = function (assert) {
var filename = file.join(profilePath, 'does-not-exists'); var filename = file.join(profilePath, 'does-not-exists');
test.assertRaises(function() { assert.throws(function() {
file.open(filename); file.open(filename);
}, ERRORS.FILE_NOT_FOUND, "file.open() on nonexistent file should throw"); }, ERRORS.FILE_NOT_FOUND, "file.open() on nonexistent file should throw");
test.assertRaises(function() { assert.throws(function() {
file.open(filename, "r"); file.open(filename, "r");
}, ERRORS.FILE_NOT_FOUND, "file.open('r') on nonexistent file should throw"); }, ERRORS.FILE_NOT_FOUND, "file.open('r') on nonexistent file should throw");
test.assertRaises(function() { assert.throws(function() {
file.open(filename, "zz"); file.open(filename, "zz");
}, ERRORS.FILE_NOT_FOUND, "file.open('zz') on nonexistent file should throw"); }, ERRORS.FILE_NOT_FOUND, "file.open('zz') on nonexistent file should throw");
}; };
exports.testOpenNonexistentForWrite = function (test) { exports.testOpenNonexistentForWrite = function (assert) {
let filename = file.join(profilePath, 'open.txt'); let filename = file.join(profilePath, 'open.txt');
let stream = file.open(filename, "w"); let stream = file.open(filename, "w");
stream.close(); stream.close();
test.assert(file.exists(filename), assert.ok(file.exists(filename),
"file.exists() should return true after file.open('w')"); "file.exists() should return true after file.open('w')");
file.remove(filename); file.remove(filename);
test.assert(!file.exists(filename), assert.ok(!file.exists(filename),
"file.exists() should return false after file.remove()"); "file.exists() should return false after file.remove()");
stream = file.open(filename, "rw"); stream = file.open(filename, "rw");
stream.close(); stream.close();
test.assert(file.exists(filename), assert.ok(file.exists(filename),
"file.exists() should return true after file.open('rw')"); "file.exists() should return true after file.open('rw')");
file.remove(filename); file.remove(filename);
test.assert(!file.exists(filename), assert.ok(!file.exists(filename),
"file.exists() should return false after file.remove()"); "file.exists() should return false after file.remove()");
}; };
exports.testOpenDirectory = function (test) { exports.testOpenDirectory = function (assert) {
let dir = dirPathInProfile; let dir = dirPathInProfile;
test.assertRaises(function() { assert.throws(function() {
file.open(dir); file.open(dir);
}, ERRORS.NOT_A_FILE, "file.open() on directory should throw"); }, ERRORS.NOT_A_FILE, "file.open() on directory should throw");
test.assertRaises(function() { assert.throws(function() {
file.open(dir, "w"); file.open(dir, "w");
}, ERRORS.NOT_A_FILE, "file.open('w') on directory should throw"); }, ERRORS.NOT_A_FILE, "file.open('w') on directory should throw");
}; };
exports.testOpenTypes = function (test) { exports.testOpenTypes = function (assert) {
let filename = file.join(profilePath, 'open-types.txt'); let filename = file.join(profilePath, 'open-types.txt');
// Do the opens first to create the data file. // Do the opens first to create the data file.
var stream = file.open(filename, "w"); var stream = file.open(filename, "w");
test.assert(stream instanceof textStreams.TextWriter, assert.ok(stream instanceof textStreams.TextWriter,
"open(w) should return a TextWriter"); "open(w) should return a TextWriter");
stream.close(); stream.close();
stream = file.open(filename, "wb"); stream = file.open(filename, "wb");
test.assert(stream instanceof byteStreams.ByteWriter, assert.ok(stream instanceof byteStreams.ByteWriter,
"open(wb) should return a ByteWriter"); "open(wb) should return a ByteWriter");
stream.close(); stream.close();
stream = file.open(filename); stream = file.open(filename);
test.assert(stream instanceof textStreams.TextReader, assert.ok(stream instanceof textStreams.TextReader,
"open() should return a TextReader"); "open() should return a TextReader");
stream.close(); stream.close();
stream = file.open(filename, "r"); stream = file.open(filename, "r");
test.assert(stream instanceof textStreams.TextReader, assert.ok(stream instanceof textStreams.TextReader,
"open(r) should return a TextReader"); "open(r) should return a TextReader");
stream.close(); stream.close();
stream = file.open(filename, "b"); stream = file.open(filename, "b");
test.assert(stream instanceof byteStreams.ByteReader, assert.ok(stream instanceof byteStreams.ByteReader,
"open(b) should return a ByteReader"); "open(b) should return a ByteReader");
stream.close(); stream.close();
stream = file.open(filename, "rb"); stream = file.open(filename, "rb");
test.assert(stream instanceof byteStreams.ByteReader, assert.ok(stream instanceof byteStreams.ByteReader,
"open(rb) should return a ByteReader"); "open(rb) should return a ByteReader");
stream.close(); stream.close();
file.remove(filename); file.remove(filename);
}; };
exports.testMkpathRmdir = function (test) { exports.testMkpathRmdir = function (assert) {
let basePath = profilePath; let basePath = profilePath;
let dirs = []; let dirs = [];
for (let i = 0; i < 3; i++) for (let i = 0; i < 3; i++)
@ -202,72 +202,74 @@ exports.testMkpathRmdir = function (test) {
} }
for (let i = 0; i < paths.length; i++) { for (let i = 0; i < paths.length; i++) {
test.assert(!file.exists(paths[i]), assert.ok(!file.exists(paths[i]),
"Sanity check: path should not exist: " + paths[i]); "Sanity check: path should not exist: " + paths[i]);
} }
file.mkpath(paths[0]); file.mkpath(paths[0]);
test.assert(file.exists(paths[0]), "mkpath should create path: " + paths[0]); assert.ok(file.exists(paths[0]), "mkpath should create path: " + paths[0]);
for (let i = 0; i < paths.length; i++) { for (let i = 0; i < paths.length; i++) {
file.rmdir(paths[i]); file.rmdir(paths[i]);
test.assert(!file.exists(paths[i]), assert.ok(!file.exists(paths[i]),
"rmdir should remove path: " + paths[i]); "rmdir should remove path: " + paths[i]);
} }
}; };
exports.testMkpathTwice = function (test) { exports.testMkpathTwice = function (assert) {
let dir = profilePath; let dir = profilePath;
let path = file.join(dir, "test-file-dir"); let path = file.join(dir, "test-file-dir");
test.assert(!file.exists(path), assert.ok(!file.exists(path),
"Sanity check: path should not exist: " + path); "Sanity check: path should not exist: " + path);
file.mkpath(path); file.mkpath(path);
test.assert(file.exists(path), "mkpath should create path: " + path); assert.ok(file.exists(path), "mkpath should create path: " + path);
file.mkpath(path); file.mkpath(path);
test.assert(file.exists(path), assert.ok(file.exists(path),
"After second mkpath, path should still exist: " + path); "After second mkpath, path should still exist: " + path);
file.rmdir(path); file.rmdir(path);
test.assert(!file.exists(path), "rmdir should remove path: " + path); assert.ok(!file.exists(path), "rmdir should remove path: " + path);
}; };
exports.testMkpathExistingNondirectory = function (test) { exports.testMkpathExistingNondirectory = function (assert) {
var fname = file.join(profilePath, 'conflict.txt'); var fname = file.join(profilePath, 'conflict.txt');
file.open(fname, "w").close(); file.open(fname, "w").close();
test.assert(file.exists(fname), "File should exist"); assert.ok(file.exists(fname), "File should exist");
test.assertRaises(function() file.mkpath(fname), assert.throws(function() file.mkpath(fname),
/^The path already exists and is not a directory: .+$/, /^The path already exists and is not a directory: .+$/,
"mkpath on file should raise error"); "mkpath on file should raise error");
file.remove(fname); file.remove(fname);
}; };
exports.testRmdirNondirectory = function (test) { exports.testRmdirNondirectory = function (assert) {
var fname = file.join(profilePath, 'not-a-dir') var fname = file.join(profilePath, 'not-a-dir')
file.open(fname, "w").close(); file.open(fname, "w").close();
test.assert(file.exists(fname), "File should exist"); assert.ok(file.exists(fname), "File should exist");
test.assertRaises(function() { assert.throws(function() {
file.rmdir(fname); file.rmdir(fname);
}, ERRORS.NOT_A_DIRECTORY, "rmdir on file should raise error"); }, ERRORS.NOT_A_DIRECTORY, "rmdir on file should raise error");
file.remove(fname); file.remove(fname);
test.assert(!file.exists(fname), "File should not exist"); assert.ok(!file.exists(fname), "File should not exist");
test.assertRaises(function () file.rmdir(fname), assert.throws(function () file.rmdir(fname),
ERRORS.FILE_NOT_FOUND, ERRORS.FILE_NOT_FOUND,
"rmdir on non-existing file should raise error"); "rmdir on non-existing file should raise error");
}; };
exports.testRmdirNonempty = function (test) { exports.testRmdirNonempty = function (assert) {
let dir = profilePath; let dir = profilePath;
let path = file.join(dir, "test-file-dir"); let path = file.join(dir, "test-file-dir");
test.assert(!file.exists(path), assert.ok(!file.exists(path),
"Sanity check: path should not exist: " + path); "Sanity check: path should not exist: " + path);
file.mkpath(path); file.mkpath(path);
let filePath = file.join(path, "file"); let filePath = file.join(path, "file");
file.open(filePath, "w").close(); file.open(filePath, "w").close();
test.assert(file.exists(filePath), assert.ok(file.exists(filePath),
"Sanity check: path should exist: " + filePath); "Sanity check: path should exist: " + filePath);
test.assertRaises(function () file.rmdir(path), assert.throws(function () file.rmdir(path),
/^The directory is not empty: .+$/, /^The directory is not empty: .+$/,
"rmdir on non-empty directory should raise error"); "rmdir on non-empty directory should raise error");
file.remove(filePath); file.remove(filePath);
file.rmdir(path); file.rmdir(path);
test.assert(!file.exists(path), "Path should not exist"); assert.ok(!file.exists(path), "Path should not exist");
}; };
require('sdk/test').run(exports);

Просмотреть файл

@ -4,10 +4,11 @@
"use strict"; "use strict";
const { pathFor } = require("sdk/system"); const { pathFor, platform } = require("sdk/system");
const fs = require("sdk/io/fs"); const fs = require("sdk/io/fs");
const url = require("sdk/url"); const url = require("sdk/url");
const path = require("sdk/fs/path"); const path = require("sdk/fs/path");
const { defer } = require("sdk/core/promise");
const { Buffer } = require("sdk/io/buffer"); const { Buffer } = require("sdk/io/buffer");
const { is } = require("sdk/system/xul-app"); const { is } = require("sdk/system/xul-app");
@ -23,15 +24,18 @@ const unlinkPath = path.join(profilePath, "sdk-fixture-unlink");
const truncatePath = path.join(profilePath, "sdk-fixture-truncate"); const truncatePath = path.join(profilePath, "sdk-fixture-truncate");
const renameFromPath = path.join(profilePath, "sdk-fixture-rename-from"); const renameFromPath = path.join(profilePath, "sdk-fixture-rename-from");
const renameToPath = path.join(profilePath, "sdk-fixture-rename-to"); const renameToPath = path.join(profilePath, "sdk-fixture-rename-to");
const chmodPath = path.join(profilePath, "sdk-fixture-chmod");
const profileEntries = [ const profileEntries = [
"compatibility.ini", "compatibility.ini",
"extensions", "extensions",
"prefs.js" "prefs.js"
// There are likely to be a lot more files but we can't really // There are likely to be a lot more files but we can"t really
// on consistent list so we limit to this. // on consistent list so we limit to this.
]; ];
const isWindows = platform.indexOf('win') === 0;
exports["test readdir"] = function(assert, end) { exports["test readdir"] = function(assert, end) {
var async = false; var async = false;
fs.readdir(profilePath, function(error, entries) { fs.readdir(profilePath, function(error, entries) {
@ -483,4 +487,135 @@ exports["test fs.writeFile (with large files)"] = function(assert, end) {
async = true; async = true;
}; };
exports["test fs.writeFile error"] = function (assert, done) {
try {
fs.writeFile({}, 'content', function (err) {
assert.fail('Error thrown from TypeError should not be caught');
});
} catch (e) {
assert.ok(e,
'writeFile with a non-string error should not be caught');
assert.equal(e.name, 'TypeError', 'error should be TypeError');
}
fs.writeFile('not/a/valid/path', 'content', function (err) {
assert.ok(err, 'error caught and handled in callback');
done();
});
};
exports["test fs.chmod"] = function (assert, done) {
let content = ["hej från sverige"];
fs.writeFile(chmodPath, content, function (err) {
testPerm("0755")()
.then(testPerm("0777"))
.then(testPerm("0666"))
.then(testPerm(parseInt("0511", 8)))
.then(testPerm(parseInt("0200", 8)))
.then(testPerm("0040"))
.then(testPerm("0000"))
.then(testPermSync(parseInt("0777", 8)))
.then(testPermSync(parseInt("0666", 8)))
.then(testPermSync("0511"))
.then(testPermSync("0200"))
.then(testPermSync("0040"))
.then(testPermSync("0000"))
.then(() => {
assert.pass("Successful chmod passes");
}, assert.fail)
// Test invalid paths
.then(() => chmod("not-a-valid-file", parseInt("0755", 8)))
.then(assert.fail, (err) => {
checkPermError(err, "not-a-valid-file");
})
.then(() => chmod("not-a-valid-file", parseInt("0755", 8), "sync"))
.then(assert.fail, (err) => {
checkPermError(err, "not-a-valid-file");
})
// Test invalid files
.then(() => chmod("resource://not-a-real-file", parseInt("0755", 8)))
.then(assert.fail, (err) => {
checkPermError(err, "resource://not-a-real-file");
})
.then(() => chmod("resource://not-a-real-file", parseInt("0755", 8), 'sync'))
.then(assert.fail, (err) => {
checkPermError(err, "resource://not-a-real-file");
})
.then(done, assert.fail);
});
function checkPermError (err, path) {
assert.equal(err.message, "ENOENT, chmod " + path);
assert.equal(err.code, "ENOENT", "error has a code");
assert.equal(err.path, path, "error has a path");
assert.equal(err.errno, 34, "error has a errno");
}
function chmod (path, mode, sync) {
let { promise, resolve, reject } = defer();
if (!sync) {
fs.chmod(path, mode, (err) => {
if (err) reject(err);
else resolve();
});
} else {
fs.chmodSync(path, mode);
resolve();
}
return promise;
}
function testPerm (mode, sync) {
return function () {
return chmod(chmodPath, mode, sync)
.then(() => getPerm(chmodPath))
.then(perm => {
let nMode = normalizeMode(mode);
if (isWindows)
assert.equal(perm, nMode,
"mode correctly set to " + mode + " (" + nMode + " on windows)");
else
assert.equal(perm, nMode, "mode correctly set to " + nMode);
});
};
}
function testPermSync (mode) {
return testPerm(mode, true);
}
function getPerm (path) {
let { promise, resolve, reject } = defer();
fs.stat(path, function (err, stat) {
if (err) reject(err);
else resolve(stat.mode);
});
return promise;
}
/*
* Converts a unix mode `0755` into a Windows version of unix permissions
*/
function normalizeMode (mode) {
if (typeof mode === "string")
mode = parseInt(mode, 8);
if (!isWindows)
return mode;
var ANY_READ = parseInt("0444", 8);
var ANY_WRITE = parseInt("0222", 8);
var winMode = 0;
// On Windows, if WRITE is true, then READ is also true
if (mode & ANY_WRITE)
winMode |= ANY_WRITE | ANY_READ;
// Minimum permissions are READ for Windows
else
winMode |= ANY_READ;
return winMode;
}
};
require("test").run(exports); require("test").run(exports);

Просмотреть файл

@ -180,6 +180,21 @@ exports['test once'] = function(assert) {
assert.equal(target.state, 1, 'this was passed in and called only once'); assert.equal(target.state, 1, 'this was passed in and called only once');
}; };
exports['test once with argument'] = function(assert) {
let n = 0;
let increment = once(function(a) n++);
increment();
increment('foo');
assert.equal(n, 1, 'only incremented once');
increment();
increment('foo');
assert.equal(n, 1, 'only incremented once');
};
exports['test chain'] = function (assert) { exports['test chain'] = function (assert) {
let Player = function () { this.volume = 5; }; let Player = function () { this.volume = 5; };
Player.prototype = { Player.prototype = {

Просмотреть файл

@ -13,7 +13,7 @@ const httpd = loader.require("sdk/test/httpd");
if (options.parseable || options.verbose) if (options.parseable || options.verbose)
loader.sandbox("sdk/test/httpd").DEBUG = true; loader.sandbox("sdk/test/httpd").DEBUG = true;
exports.testBasicHTTPServer = function(test) { exports.testBasicHTTPServer = function(assert, done) {
// Use the profile directory for the temporary file as that will be deleted // Use the profile directory for the temporary file as that will be deleted
// when tests are complete // when tests are complete
let basePath = pathFor("ProfD"); let basePath = pathFor("ProfD");
@ -25,26 +25,18 @@ exports.testBasicHTTPServer = function(test) {
let srv = httpd.startServerAsync(port, basePath); let srv = httpd.startServerAsync(port, basePath);
test.waitUntilDone();
// Request this very file. // Request this very file.
let Request = require('sdk/request').Request; let Request = require('sdk/request').Request;
Request({ Request({
url: "http://localhost:" + port + "/test-httpd.txt", url: "http://localhost:" + port + "/test-httpd.txt",
onComplete: function (response) { onComplete: function (response) {
test.assertEqual(response.text, content); assert.equal(response.text, content);
done(); srv.stop(done);
} }
}).get(); }).get();
function done() {
srv.stop(function() {
test.done();
});
}
}; };
exports.testDynamicServer = function (test) { exports.testDynamicServer = function (assert, done) {
let content = "This is the HTTPD test file.\n"; let content = "This is the HTTPD test file.\n";
let srv = httpd.startServerAsync(port); let srv = httpd.startServerAsync(port);
@ -58,35 +50,24 @@ exports.testDynamicServer = function (test) {
response.write(content); response.write(content);
}); });
test.waitUntilDone();
// Request this very file. // Request this very file.
let Request = require('sdk/request').Request; let Request = require('sdk/request').Request;
Request({ Request({
url: "http://localhost:" + port + "/test-httpd.txt", url: "http://localhost:" + port + "/test-httpd.txt",
onComplete: function (response) { onComplete: function (response) {
test.assertEqual(response.text, content); assert.equal(response.text, content);
done(); srv.stop(done);
} }
}).get(); }).get();
};
function done() { exports.testAutomaticPortSelection = function (assert, done) {
srv.stop(function() {
test.done();
});
}
}
exports.testAutomaticPortSelection = function (test) {
const srv = httpd.startServerAsync(-1); const srv = httpd.startServerAsync(-1);
test.waitUntilDone();
const port = srv.identity.primaryPort; const port = srv.identity.primaryPort;
test.assert(0 <= port && port <= 65535); assert.ok(0 <= port && port <= 65535);
srv.stop(function() { srv.stop(done);
test.done(); };
});
} require('sdk/test').run(exports);

Просмотреть файл

@ -12,31 +12,31 @@ const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
const PREF_SELECTED_LOCALE = "general.useragent.locale"; const PREF_SELECTED_LOCALE = "general.useragent.locale";
const PREF_ACCEPT_LANGUAGES = "intl.accept_languages"; const PREF_ACCEPT_LANGUAGES = "intl.accept_languages";
function assertPrefered(test, expected, msg) { function assertPrefered(assert, expected, msg) {
test.assertEqual(JSON.stringify(getPreferedLocales()), JSON.stringify(expected), assert.equal(JSON.stringify(getPreferedLocales()), JSON.stringify(expected),
msg); msg);
} }
exports.testGetPreferedLocales = function(test) { exports.testGetPreferedLocales = function(assert) {
prefs.set(PREF_MATCH_OS_LOCALE, false); prefs.set(PREF_MATCH_OS_LOCALE, false);
prefs.set(PREF_SELECTED_LOCALE, ""); prefs.set(PREF_SELECTED_LOCALE, "");
prefs.set(PREF_ACCEPT_LANGUAGES, ""); prefs.set(PREF_ACCEPT_LANGUAGES, "");
assertPrefered(test, ["en-us"], assertPrefered(assert, ["en-us"],
"When all preferences are empty, we only have en-us"); "When all preferences are empty, we only have en-us");
prefs.set(PREF_SELECTED_LOCALE, "fr"); prefs.set(PREF_SELECTED_LOCALE, "fr");
prefs.set(PREF_ACCEPT_LANGUAGES, "jp"); prefs.set(PREF_ACCEPT_LANGUAGES, "jp");
assertPrefered(test, ["fr", "jp", "en-us"], assertPrefered(assert, ["fr", "jp", "en-us"],
"We first have useragent locale, then web one and finally en-US"); "We first have useragent locale, then web one and finally en-US");
prefs.set(PREF_SELECTED_LOCALE, "en-US"); prefs.set(PREF_SELECTED_LOCALE, "en-US");
prefs.set(PREF_ACCEPT_LANGUAGES, "en-US"); prefs.set(PREF_ACCEPT_LANGUAGES, "en-US");
assertPrefered(test, ["en-us"], assertPrefered(assert, ["en-us"],
"We do not have duplicates"); "We do not have duplicates");
prefs.set(PREF_SELECTED_LOCALE, "en-US"); prefs.set(PREF_SELECTED_LOCALE, "en-US");
prefs.set(PREF_ACCEPT_LANGUAGES, "fr"); prefs.set(PREF_ACCEPT_LANGUAGES, "fr");
assertPrefered(test, ["en-us", "fr"], assertPrefered(assert, ["en-us", "fr"],
"en-US can be first if specified by higher priority preference"); "en-US can be first if specified by higher priority preference");
// Reset what we changed // Reset what we changed
@ -48,7 +48,7 @@ exports.testGetPreferedLocales = function(test) {
// In some cases, mainly on Fennec and on Linux version, // In some cases, mainly on Fennec and on Linux version,
// `general.useragent.locale` is a special 'localized' value, like: // `general.useragent.locale` is a special 'localized' value, like:
// "chrome://global/locale/intl.properties" // "chrome://global/locale/intl.properties"
exports.testPreferedLocalizedLocale = function(test) { exports.testPreferedLocalizedLocale = function(assert) {
prefs.set(PREF_MATCH_OS_LOCALE, false); prefs.set(PREF_MATCH_OS_LOCALE, false);
let bundleURL = "chrome://global/locale/intl.properties"; let bundleURL = "chrome://global/locale/intl.properties";
prefs.setLocalized(PREF_SELECTED_LOCALE, bundleURL); prefs.setLocalized(PREF_SELECTED_LOCALE, bundleURL);
@ -71,7 +71,7 @@ exports.testPreferedLocalizedLocale = function(test) {
if (expectedLocaleList.indexOf("en-us") == -1) if (expectedLocaleList.indexOf("en-us") == -1)
expectedLocaleList.push("en-us"); expectedLocaleList.push("en-us");
assertPrefered(test, expectedLocaleList, "test localized pref value"); assertPrefered(assert, expectedLocaleList, "test localized pref value");
// Reset what we have changed // Reset what we have changed
prefs.reset(PREF_MATCH_OS_LOCALE); prefs.reset(PREF_MATCH_OS_LOCALE);
@ -79,7 +79,7 @@ exports.testPreferedLocalizedLocale = function(test) {
prefs.reset(PREF_ACCEPT_LANGUAGES); prefs.reset(PREF_ACCEPT_LANGUAGES);
} }
exports.testPreferedOsLocale = function(test) { exports.testPreferedOsLocale = function(assert) {
prefs.set(PREF_MATCH_OS_LOCALE, true); prefs.set(PREF_MATCH_OS_LOCALE, true);
prefs.set(PREF_SELECTED_LOCALE, ""); prefs.set(PREF_SELECTED_LOCALE, "");
prefs.set(PREF_ACCEPT_LANGUAGES, ""); prefs.set(PREF_ACCEPT_LANGUAGES, "");
@ -92,7 +92,7 @@ exports.testPreferedOsLocale = function(test) {
if (expectedLocale != "en-us") if (expectedLocale != "en-us")
expectedLocaleList.push("en-us"); expectedLocaleList.push("en-us");
assertPrefered(test, expectedLocaleList, "Ensure that we select OS locale when related preference is set"); assertPrefered(assert, expectedLocaleList, "Ensure that we select OS locale when related preference is set");
// Reset what we have changed // Reset what we have changed
prefs.reset(PREF_MATCH_OS_LOCALE); prefs.reset(PREF_MATCH_OS_LOCALE);
@ -100,42 +100,44 @@ exports.testPreferedOsLocale = function(test) {
prefs.reset(PREF_ACCEPT_LANGUAGES); prefs.reset(PREF_ACCEPT_LANGUAGES);
} }
exports.testFindClosestLocale = function(test) { exports.testFindClosestLocale = function(assert) {
// Second param of findClosestLocale (aMatchLocales) have to be in lowercase // Second param of findClosestLocale (aMatchLocales) have to be in lowercase
test.assertEqual(findClosestLocale([], []), null, assert.equal(findClosestLocale([], []), null,
"When everything is empty we get null"); "When everything is empty we get null");
test.assertEqual(findClosestLocale(["en", "en-US"], ["en"]), assert.equal(findClosestLocale(["en", "en-US"], ["en"]),
"en", "We always accept exact match first 1/5"); "en", "We always accept exact match first 1/5");
test.assertEqual(findClosestLocale(["en-US", "en"], ["en"]), assert.equal(findClosestLocale(["en-US", "en"], ["en"]),
"en", "We always accept exact match first 2/5"); "en", "We always accept exact match first 2/5");
test.assertEqual(findClosestLocale(["en", "en-US"], ["en-us"]), assert.equal(findClosestLocale(["en", "en-US"], ["en-us"]),
"en-US", "We always accept exact match first 3/5"); "en-US", "We always accept exact match first 3/5");
test.assertEqual(findClosestLocale(["ja-JP-mac", "ja", "ja-JP"], ["ja-jp"]), assert.equal(findClosestLocale(["ja-JP-mac", "ja", "ja-JP"], ["ja-jp"]),
"ja-JP", "We always accept exact match first 4/5"); "ja-JP", "We always accept exact match first 4/5");
test.assertEqual(findClosestLocale(["ja-JP-mac", "ja", "ja-JP"], ["ja-jp-mac"]), assert.equal(findClosestLocale(["ja-JP-mac", "ja", "ja-JP"], ["ja-jp-mac"]),
"ja-JP-mac", "We always accept exact match first 5/5"); "ja-JP-mac", "We always accept exact match first 5/5");
test.assertEqual(findClosestLocale(["en", "en-GB"], ["en-us"]), assert.equal(findClosestLocale(["en", "en-GB"], ["en-us"]),
"en", "We accept more generic locale, when there is no exact match 1/2"); "en", "We accept more generic locale, when there is no exact match 1/2");
test.assertEqual(findClosestLocale(["en-ZA", "en"], ["en-gb"]), assert.equal(findClosestLocale(["en-ZA", "en"], ["en-gb"]),
"en", "We accept more generic locale, when there is no exact match 2/2"); "en", "We accept more generic locale, when there is no exact match 2/2");
test.assertEqual(findClosestLocale(["ja-JP"], ["ja"]), assert.equal(findClosestLocale(["ja-JP"], ["ja"]),
"ja-JP", "We accept more specialized locale, when there is no exact match 1/2"); "ja-JP", "We accept more specialized locale, when there is no exact match 1/2");
// Better to select "ja" in this case but behave same as current AddonManager // Better to select "ja" in this case but behave same as current AddonManager
test.assertEqual(findClosestLocale(["ja-JP-mac", "ja"], ["ja-jp"]), assert.equal(findClosestLocale(["ja-JP-mac", "ja"], ["ja-jp"]),
"ja-JP-mac", "We accept more specialized locale, when there is no exact match 2/2"); "ja-JP-mac", "We accept more specialized locale, when there is no exact match 2/2");
test.assertEqual(findClosestLocale(["en-US"], ["en-us"]), assert.equal(findClosestLocale(["en-US"], ["en-us"]),
"en-US", "We keep the original one as result 1/2"); "en-US", "We keep the original one as result 1/2");
test.assertEqual(findClosestLocale(["en-us"], ["en-us"]), assert.equal(findClosestLocale(["en-us"], ["en-us"]),
"en-us", "We keep the original one as result 2/2"); "en-us", "We keep the original one as result 2/2");
test.assertEqual(findClosestLocale(["ja-JP-mac"], ["ja-jp-mac"]), assert.equal(findClosestLocale(["ja-JP-mac"], ["ja-jp-mac"]),
"ja-JP-mac", "We accept locale with 3 parts"); "ja-JP-mac", "We accept locale with 3 parts");
test.assertEqual(findClosestLocale(["ja-JP"], ["ja-jp-mac"]), assert.equal(findClosestLocale(["ja-JP"], ["ja-jp-mac"]),
"ja-JP", "We accept locale with 2 parts from locale with 3 parts"); "ja-JP", "We accept locale with 2 parts from locale with 3 parts");
test.assertEqual(findClosestLocale(["ja"], ["ja-jp-mac"]), assert.equal(findClosestLocale(["ja"], ["ja-jp-mac"]),
"ja", "We accept locale with 1 part from locale with 3 parts"); "ja", "We accept locale with 1 part from locale with 3 parts");
} };
require('sdk/test').run(exports);

Просмотреть файл

@ -7,76 +7,78 @@ const { getRulesForLocale } = require("sdk/l10n/plural-rules");
// For more information, please visit unicode website: // For more information, please visit unicode website:
// http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html // http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
function map(test, f, n, form) { function map(assert, f, n, form) {
test.assertEqual(f(n), form, n + " maps to '" + form + "'"); assert.equal(f(n), form, n + " maps to '" + form + "'");
} }
exports.testFrench = function(test) { exports.testFrench = function(assert) {
let f = getRulesForLocale("fr"); let f = getRulesForLocale("fr");
map(test, f, -1, "other"); map(assert, f, -1, "other");
map(test, f, 0, "one"); map(assert, f, 0, "one");
map(test, f, 1, "one"); map(assert, f, 1, "one");
map(test, f, 1.5, "one"); map(assert, f, 1.5, "one");
map(test, f, 2, "other"); map(assert, f, 2, "other");
map(test, f, 100, "other"); map(assert, f, 100, "other");
} }
exports.testEnglish = function(test) { exports.testEnglish = function(assert) {
let f = getRulesForLocale("en"); let f = getRulesForLocale("en");
map(test, f, -1, "other"); map(assert, f, -1, "other");
map(test, f, 0, "other"); map(assert, f, 0, "other");
map(test, f, 1, "one"); map(assert, f, 1, "one");
map(test, f, 1.5, "other"); map(assert, f, 1.5, "other");
map(test, f, 2, "other"); map(assert, f, 2, "other");
map(test, f, 100, "other"); map(assert, f, 100, "other");
} }
exports.testArabic = function(test) { exports.testArabic = function(assert) {
let f = getRulesForLocale("ar"); let f = getRulesForLocale("ar");
map(test, f, -1, "other"); map(assert, f, -1, "other");
map(test, f, 0, "zero"); map(assert, f, 0, "zero");
map(test, f, 0.5, "other"); map(assert, f, 0.5, "other");
map(test, f, 1, "one"); map(assert, f, 1, "one");
map(test, f, 1.5, "other"); map(assert, f, 1.5, "other");
map(test, f, 2, "two"); map(assert, f, 2, "two");
map(test, f, 2.5, "other"); map(assert, f, 2.5, "other");
map(test, f, 3, "few"); map(assert, f, 3, "few");
map(test, f, 3.5, "few"); // I'd expect it to be 'other', but the unicode.org map(assert, f, 3.5, "few"); // I'd expect it to be 'other', but the unicode.org
// algorithm computes 'few'. // algorithm computes 'few'.
map(test, f, 5, "few"); map(assert, f, 5, "few");
map(test, f, 10, "few"); map(assert, f, 10, "few");
map(test, f, 103, "few"); map(assert, f, 103, "few");
map(test, f, 105, "few"); map(assert, f, 105, "few");
map(test, f, 110, "few"); map(assert, f, 110, "few");
map(test, f, 203, "few"); map(assert, f, 203, "few");
map(test, f, 205, "few"); map(assert, f, 205, "few");
map(test, f, 210, "few"); map(assert, f, 210, "few");
map(test, f, 11, "many"); map(assert, f, 11, "many");
map(test, f, 50, "many"); map(assert, f, 50, "many");
map(test, f, 99, "many"); map(assert, f, 99, "many");
map(test, f, 111, "many"); map(assert, f, 111, "many");
map(test, f, 150, "many"); map(assert, f, 150, "many");
map(test, f, 199, "many"); map(assert, f, 199, "many");
map(test, f, 100, "other"); map(assert, f, 100, "other");
map(test, f, 101, "other"); map(assert, f, 101, "other");
map(test, f, 102, "other"); map(assert, f, 102, "other");
map(test, f, 200, "other"); map(assert, f, 200, "other");
map(test, f, 201, "other"); map(assert, f, 201, "other");
map(test, f, 202, "other"); map(assert, f, 202, "other");
} }
exports.testJapanese = function(test) { exports.testJapanese = function(assert) {
// Japanese doesn't have plural forms. // Japanese doesn't have plural forms.
let f = getRulesForLocale("ja"); let f = getRulesForLocale("ja");
map(test, f, -1, "other"); map(assert, f, -1, "other");
map(test, f, 0, "other"); map(assert, f, 0, "other");
map(test, f, 1, "other"); map(assert, f, 1, "other");
map(test, f, 1.5, "other"); map(assert, f, 1.5, "other");
map(test, f, 2, "other"); map(assert, f, 2, "other");
map(test, f, 100, "other"); map(assert, f, 100, "other");
} }
require('sdk/test').run(exports);

Просмотреть файл

@ -8,6 +8,11 @@ let { Loader, main, unload, parseStack } = require('toolkit/loader');
let root = module.uri.substr(0, module.uri.lastIndexOf('/')) let root = module.uri.substr(0, module.uri.lastIndexOf('/'))
// The following adds Debugger constructor to the global namespace.
const { Cu } = require('chrome');
const { addDebuggerToGlobal } = Cu.import('resource://gre/modules/jsdebugger.jsm', {});
addDebuggerToGlobal(this);
exports['test dependency cycles'] = function(assert) { exports['test dependency cycles'] = function(assert) {
let uri = root + '/fixtures/loader/cycles/'; let uri = root + '/fixtures/loader/cycles/';
let loader = Loader({ paths: { '': uri } }); let loader = Loader({ paths: { '': uri } });
@ -144,4 +149,22 @@ exports['test early errors in module'] = function(assert) {
} }
} }
exports['test setting metadata for newly created sandboxes'] = function(assert) {
let addonID = 'random-addon-id';
let uri = root + '/fixtures/loader/cycles/';
let loader = Loader({ paths: { '': uri }, id: addonID });
let dbg = new Debugger();
dbg.onNewGlobalObject = function(global) {
dbg.onNewGlobalObject = undefined;
let metadata = Cu.getSandboxMetadata(global.unsafeDereference());
assert.ok(metadata, 'this global has attached metadata');
assert.equal(metadata.URI, uri + 'main.js', 'URI is set properly');
assert.equal(metadata.addonID, addonID, 'addon ID is set');
}
let program = main(loader, 'main');
}
require('test').run(exports); require('test').run(exports);

Просмотреть файл

@ -5,10 +5,10 @@
const { MatchPattern } = require("sdk/util/match-pattern"); const { MatchPattern } = require("sdk/util/match-pattern");
exports.testMatchPatternTestTrue = function(test) { exports.testMatchPatternTestTrue = function(assert) {
function ok(pattern, url) { function ok(pattern, url) {
let mp = new MatchPattern(pattern); let mp = new MatchPattern(pattern);
test.assert(mp.test(url), pattern + " should match " + url); assert.ok(mp.test(url), pattern + " should match " + url);
} }
ok("*", "http://example.com"); ok("*", "http://example.com");
@ -37,10 +37,10 @@ exports.testMatchPatternTestTrue = function(test) {
ok('data:*', 'data:text/html;charset=utf-8,'); ok('data:*', 'data:text/html;charset=utf-8,');
}; };
exports.testMatchPatternTestFalse = function(test) { exports.testMatchPatternTestFalse = function(assert) {
function ok(pattern, url) { function ok(pattern, url) {
let mp = new MatchPattern(pattern); let mp = new MatchPattern(pattern);
test.assert(!mp.test(url), pattern + " should not match " + url); assert.ok(!mp.test(url), pattern + " should not match " + url);
} }
ok("*", null); ok("*", null);
@ -82,58 +82,60 @@ exports.testMatchPatternTestFalse = function(test) {
ok('*.amp.le.com', 'http://examp.le.com'); ok('*.amp.le.com', 'http://examp.le.com');
}; };
exports.testMatchPatternErrors = function(test) { exports.testMatchPatternErrors = function(assert) {
test.assertRaises( assert.throws(
function() new MatchPattern("*.google.com/*"), function() new MatchPattern("*.google.com/*"),
/There can be at most one/, /There can be at most one/,
"MatchPattern throws when supplied multiple '*'" "MatchPattern throws when supplied multiple '*'"
); );
test.assertRaises( assert.throws(
function() new MatchPattern("google.com"), function() new MatchPattern("google.com"),
/expected to be either an exact URL/, /expected to be either an exact URL/,
"MatchPattern throws when the wildcard doesn't use '*' and doesn't " + "MatchPattern throws when the wildcard doesn't use '*' and doesn't " +
"look like a URL" "look like a URL"
); );
test.assertRaises( assert.throws(
function() new MatchPattern("http://google*.com"), function() new MatchPattern("http://google*.com"),
/expected to be the first or the last/, /expected to be the first or the last/,
"MatchPattern throws when a '*' is in the middle of the wildcard" "MatchPattern throws when a '*' is in the middle of the wildcard"
); );
test.assertRaises( assert.throws(
function() new MatchPattern(/ /g), function() new MatchPattern(/ /g),
/^A RegExp match pattern cannot be set to `global` \(i\.e\. \/\/g\)\.$/, /^A RegExp match pattern cannot be set to `global` \(i\.e\. \/\/g\)\.$/,
"MatchPattern throws on a RegExp set to `global` (i.e. //g)." "MatchPattern throws on a RegExp set to `global` (i.e. //g)."
); );
test.assertRaises( assert.throws(
function() new MatchPattern(/ /i), function() new MatchPattern(/ /i),
/^A RegExp match pattern cannot be set to `ignoreCase` \(i\.e\. \/\/i\)\.$/, /^A RegExp match pattern cannot be set to `ignoreCase` \(i\.e\. \/\/i\)\.$/,
"MatchPattern throws on a RegExp set to `ignoreCase` (i.e. //i)." "MatchPattern throws on a RegExp set to `ignoreCase` (i.e. //i)."
); );
test.assertRaises( assert.throws(
function() new MatchPattern( / /m ), function() new MatchPattern( / /m ),
/^A RegExp match pattern cannot be set to `multiline` \(i\.e\. \/\/m\)\.$/, /^A RegExp match pattern cannot be set to `multiline` \(i\.e\. \/\/m\)\.$/,
"MatchPattern throws on a RegExp set to `multiline` (i.e. //m)." "MatchPattern throws on a RegExp set to `multiline` (i.e. //m)."
); );
}; };
exports.testMatchPatternInternals = function(test) { exports.testMatchPatternInternals = function(assert) {
test.assertEqual( assert.equal(
new MatchPattern("http://google.com/test").exactURL, new MatchPattern("http://google.com/test").exactURL,
"http://google.com/test" "http://google.com/test"
); );
test.assertEqual( assert.equal(
new MatchPattern("http://google.com/test/*").urlPrefix, new MatchPattern("http://google.com/test/*").urlPrefix,
"http://google.com/test/" "http://google.com/test/"
); );
test.assertEqual( assert.equal(
new MatchPattern("*.example.com").domain, new MatchPattern("*.example.com").domain,
"example.com" "example.com"
); );
}; };
require('sdk/test').run(exports);

Просмотреть файл

@ -4,16 +4,18 @@
var memory = require("sdk/deprecated/memory"); var memory = require("sdk/deprecated/memory");
exports.testMemory = function(test) { exports.testMemory = function(assert) {
test.pass("Skipping this test until Gecko memory debugging issues " + assert.pass("Skipping this test until Gecko memory debugging issues " +
"are resolved (see bug 592774)."); "are resolved (see bug 592774).");
return; return;
var obj = {}; var obj = {};
memory.track(obj, "testMemory.testObj"); memory.track(obj, "testMemory.testObj");
var objs = memory.getObjects("testMemory.testObj"); var objs = memory.getObjects("testMemory.testObj");
test.assertEqual(objs[0].weakref.get(), obj); assert.equal(objs[0].weakref.get(), obj);
obj = null; obj = null;
memory.gc(); memory.gc();
test.assertEqual(objs[0].weakref.get(), null); assert.equal(objs[0].weakref.get(), null);
}; };
require('sdk/test').run(exports);

Просмотреть файл

@ -2,58 +2,58 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
exports.testDefine = function(test) { exports.testDefine = function(assert) {
let tiger = require('./modules/tiger'); let tiger = require('./modules/tiger');
test.assertEqual(tiger.name, 'tiger', 'name proprety was exported properly'); assert.equal(tiger.name, 'tiger', 'name proprety was exported properly');
test.assertEqual(tiger.type, 'cat', 'property form other module exported'); assert.equal(tiger.type, 'cat', 'property form other module exported');
}; };
exports.testDefineInoresNonFactory = function(test) { exports.testDefineInoresNonFactory = function(assert) {
let mod = require('./modules/async2'); let mod = require('./modules/async2');
test.assertEqual(mod.name, 'async2', 'name proprety was exported properly'); assert.equal(mod.name, 'async2', 'name proprety was exported properly');
test.assertNotEqual(mod.traditional2Name, 'traditional2', '1st is ignored'); assert.ok(mod.traditional2Name !== 'traditional2', '1st is ignored');
}; };
/* Disable test that require AMD specific functionality: /* Disable test that require AMD specific functionality:
// define() that exports a function as the module value, // define() that exports a function as the module value,
// specifying a module name. // specifying a module name.
exports.testDefExport = function(test) { exports.testDefExport = function(assert) {
var add = require('modules/add'); var add = require('modules/add');
test.assertEqual(add(1, 1), 2, 'Named define() exporting a function'); assert.equal(add(1, 1), 2, 'Named define() exporting a function');
}; };
// define() that exports function as a value, but is anonymous // define() that exports function as a value, but is anonymous
exports.testAnonDefExport = function (test) { exports.testAnonDefExport = function (assert) {
var subtract = require('modules/subtract'); var subtract = require('modules/subtract');
test.assertEqual(subtract(4, 2), 2, assert.equal(subtract(4, 2), 2,
'Anonymous define() exporting a function'); 'Anonymous define() exporting a function');
} }
// using require([], function () {}) to load modules. // using require([], function () {}) to load modules.
exports.testSimpleRequire = function (test) { exports.testSimpleRequire = function (assert) {
require(['modules/blue', 'modules/orange'], function (blue, orange) { require(['modules/blue', 'modules/orange'], function (blue, orange) {
test.assertEqual(blue.name, 'blue', 'Simple require for blue'); assert.equal(blue.name, 'blue', 'Simple require for blue');
test.assertEqual(orange.name, 'orange', 'Simple require for orange'); assert.equal(orange.name, 'orange', 'Simple require for orange');
test.assertEqual(orange.parentType, 'color', assert.equal(orange.parentType, 'color',
'Simple require dependency check for orange'); 'Simple require dependency check for orange');
}); });
} }
// using nested require([]) calls. // using nested require([]) calls.
exports.testSimpleRequireNested = function (test) { exports.testSimpleRequireNested = function (assert) {
require(['modules/blue', 'modules/orange', 'modules/green'], require(['modules/blue', 'modules/orange', 'modules/green'],
function (blue, orange, green) { function (blue, orange, green) {
require(['modules/orange', 'modules/red'], function (orange, red) { require(['modules/orange', 'modules/red'], function (orange, red) {
test.assertEqual(red.name, 'red', 'Simple require for red'); assert.equal(red.name, 'red', 'Simple require for red');
test.assertEqual(red.parentType, 'color', assert.equal(red.parentType, 'color',
'Simple require dependency check for red'); 'Simple require dependency check for red');
test.assertEqual(blue.name, 'blue', 'Simple require for blue'); assert.equal(blue.name, 'blue', 'Simple require for blue');
test.assertEqual(orange.name, 'orange', 'Simple require for orange'); assert.equal(orange.name, 'orange', 'Simple require for orange');
test.assertEqual(orange.parentType, 'color', assert.equal(orange.parentType, 'color',
'Simple require dependency check for orange'); 'Simple require dependency check for orange');
test.assertEqual(green.name, 'green', 'Simple require for green'); assert.equal(green.name, 'green', 'Simple require for green');
test.assertEqual(green.parentType, 'color', assert.equal(green.parentType, 'color',
'Simple require dependency check for green'); 'Simple require dependency check for green');
}); });
@ -62,57 +62,57 @@ exports.testSimpleRequireNested = function (test) {
// requiring a traditional module, that uses async, that use traditional and // requiring a traditional module, that uses async, that use traditional and
// async, with a circular reference // async, with a circular reference
exports.testMixedCircular = function (test) { exports.testMixedCircular = function (assert) {
var t = require('modules/traditional1'); var t = require('modules/traditional1');
test.assertEqual(t.name, 'traditional1', 'Testing name'); assert.equal(t.name, 'traditional1', 'Testing name');
test.assertEqual(t.traditional2Name, 'traditional2', assert.equal(t.traditional2Name, 'traditional2',
'Testing dependent name'); 'Testing dependent name');
test.assertEqual(t.traditional1Name, 'traditional1', 'Testing circular name'); assert.equal(t.traditional1Name, 'traditional1', 'Testing circular name');
test.assertEqual(t.async2Name, 'async2', 'Testing async2 name'); assert.equal(t.async2Name, 'async2', 'Testing async2 name');
test.assertEqual(t.async2Traditional2Name, 'traditional2', assert.equal(t.async2Traditional2Name, 'traditional2',
'Testing nested traditional2 name'); 'Testing nested traditional2 name');
} }
// Testing define()(function(require) {}) with some that use exports, // Testing define()(function(require) {}) with some that use exports,
// some that use return. // some that use return.
exports.testAnonExportsReturn = function (test) { exports.testAnonExportsReturn = function (assert) {
var lion = require('modules/lion'); var lion = require('modules/lion');
require(['modules/tiger', 'modules/cheetah'], function (tiger, cheetah) { require(['modules/tiger', 'modules/cheetah'], function (tiger, cheetah) {
test.assertEqual('lion', lion, 'Check lion name'); assert.equal('lion', lion, 'Check lion name');
test.assertEqual('tiger', tiger.name, 'Check tiger name'); assert.equal('tiger', tiger.name, 'Check tiger name');
test.assertEqual('cat', tiger.type, 'Check tiger type'); assert.equal('cat', tiger.type, 'Check tiger type');
test.assertEqual('cheetah', cheetah(), 'Check cheetah name'); assert.equal('cheetah', cheetah(), 'Check cheetah name');
}); });
} }
// circular dependency // circular dependency
exports.testCircular = function (test) { exports.testCircular = function (assert) {
var pollux = require('modules/pollux'), var pollux = require('modules/pollux'),
castor = require('modules/castor'); castor = require('modules/castor');
test.assertEqual(pollux.name, 'pollux', 'Pollux\'s name'); assert.equal(pollux.name, 'pollux', 'Pollux\'s name');
test.assertEqual(pollux.getCastorName(), assert.equal(pollux.getCastorName(),
'castor', 'Castor\'s name from Pollux.'); 'castor', 'Castor\'s name from Pollux.');
test.assertEqual(castor.name, 'castor', 'Castor\'s name'); assert.equal(castor.name, 'castor', 'Castor\'s name');
test.assertEqual(castor.getPolluxName(), 'pollux', assert.equal(castor.getPolluxName(), 'pollux',
'Pollux\'s name from Castor.'); 'Pollux\'s name from Castor.');
} }
// test a bad module that asks for exports but also does a define() return // test a bad module that asks for exports but also does a define() return
exports.testBadExportAndReturn = function (test) { exports.testBadExportAndReturn = function (assert) {
var passed = false; var passed = false;
try { try {
var bad = require('modules/badExportAndReturn'); var bad = require('modules/badExportAndReturn');
} catch(e) { } catch(e) {
passed = /cannot use exports and also return/.test(e.toString()); passed = /cannot use exports and also return/.test(e.toString());
} }
test.assertEqual(passed, true, 'Make sure exports and return fail'); assert.equal(passed, true, 'Make sure exports and return fail');
} }
// test a bad circular dependency, where an exported value is needed, but // test a bad circular dependency, where an exported value is needed, but
// the return value happens too late, a module already asked for the exported // the return value happens too late, a module already asked for the exported
// value. // value.
exports.testBadExportAndReturnCircular = function (test) { exports.testBadExportAndReturnCircular = function (assert) {
var passed = false; var passed = false;
try { try {
var bad = require('modules/badFirst'); var bad = require('modules/badFirst');
@ -120,29 +120,31 @@ exports.testBadExportAndReturnCircular = function (test) {
passed = /after another module has referenced its exported value/ passed = /after another module has referenced its exported value/
.test(e.toString()); .test(e.toString());
} }
test.assertEqual(passed, true, 'Make sure return after an exported ' + assert.equal(passed, true, 'Make sure return after an exported ' +
'value is grabbed by another module fails.'); 'value is grabbed by another module fails.');
} }
// only allow one define call per file. // only allow one define call per file.
exports.testOneDefine = function (test) { exports.testOneDefine = function (assert) {
var passed = false; var passed = false;
try { try {
var dupe = require('modules/dupe'); var dupe = require('modules/dupe');
} catch(e) { } catch(e) {
passed = /Only one call to define/.test(e.toString()); passed = /Only one call to define/.test(e.toString());
} }
test.assertEqual(passed, true, 'Only allow one define call per module'); assert.equal(passed, true, 'Only allow one define call per module');
} }
// only allow one define call per file, testing a bad nested define call. // only allow one define call per file, testing a bad nested define call.
exports.testOneDefineNested = function (test) { exports.testOneDefineNested = function (assert) {
var passed = false; var passed = false;
try { try {
var dupe = require('modules/dupeNested'); var dupe = require('modules/dupeNested');
} catch(e) { } catch(e) {
passed = /Only one call to define/.test(e.toString()); passed = /Only one call to define/.test(e.toString());
} }
test.assertEqual(passed, true, 'Only allow one define call per module'); assert.equal(passed, true, 'Only allow one define call per module');
} }
*/ */
require('sdk/test').run(exports);

Просмотреть файл

@ -4,14 +4,14 @@
const { Loader } = require('sdk/test/loader'); const { Loader } = require('sdk/test/loader');
exports.testOnClick = function (test) { exports.testOnClick = function (assert) {
let [loader, mockAlertServ] = makeLoader(module); let [loader, mockAlertServ] = makeLoader(module);
let notifs = loader.require("sdk/notifications"); let notifs = loader.require("sdk/notifications");
let data = "test data"; let data = "test data";
let opts = { let opts = {
onClick: function (clickedData) { onClick: function (clickedData) {
test.assertEqual(this, notifs, "|this| should be notifications module"); assert.equal(this, notifs, "|this| should be notifications module");
test.assertEqual(clickedData, data, assert.equal(clickedData, data,
"data passed to onClick should be correct"); "data passed to onClick should be correct");
}, },
data: data, data: data,
@ -25,7 +25,7 @@ exports.testOnClick = function (test) {
}; };
// Returns [loader, mockAlertService]. // Returns [loader, mockAlertService].
function makeLoader(test) { function makeLoader(module) {
let loader = Loader(module); let loader = Loader(module);
let mockAlertServ = { let mockAlertServ = {
showAlertNotification: function (imageUrl, title, text, textClickable, showAlertNotification: function (imageUrl, title, text, textClickable,
@ -41,4 +41,6 @@ function makeLoader(test) {
let scope = loader.sandbox("sdk/notifications"); let scope = loader.sandbox("sdk/notifications");
scope.notify = mockAlertServ.showAlertNotification.bind(mockAlertServ); scope.notify = mockAlertServ.showAlertNotification.bind(mockAlertServ);
return [loader, mockAlertServ]; return [loader, mockAlertServ];
}; }
require('sdk/test').run(exports);

Просмотреть файл

@ -9,27 +9,28 @@ let o = {
'paper': 0, 'paper': 0,
'rock': 1, 'rock': 1,
'scissors': 2 'scissors': 2
}
//exports.testMerge = function(test) {}
//exports.testExtend = function(test) {}
exports.testHas = function(test) {
test.assertEqual(has(o, 'paper'), true, 'has correctly finds key');
test.assertEqual(has(o, 'rock'), true, 'has correctly finds key');
test.assertEqual(has(o, 'scissors'), true, 'has correctly finds key');
test.assertEqual(has(o, 'nope'), false, 'has correctly does not find key');
test.assertEqual(has(o, '__proto__'), false, 'has correctly does not find key');
test.assertEqual(has(o, 'isPrototypeOf'), false, 'has correctly does not find key');
}; };
exports.testEach = function(test) { //exports.testMerge = function(assert) {}
var count = 0; //exports.testExtend = function(assert) {}
exports.testHas = function(assert) {
assert.equal(has(o, 'paper'), true, 'has correctly finds key');
assert.equal(has(o, 'rock'), true, 'has correctly finds key');
assert.equal(has(o, 'scissors'), true, 'has correctly finds key');
assert.equal(has(o, 'nope'), false, 'has correctly does not find key');
assert.equal(has(o, '__proto__'), false, 'has correctly does not find key');
assert.equal(has(o, 'isPrototypeOf'), false, 'has correctly does not find key');
};
exports.testEach = function(assert) {
var keys = new Set(); var keys = new Set();
each(o, function (value, key, object) { each(o, function (value, key, object) {
keys.add(key); keys.add(key);
test.assertEqual(o[key], value, 'Key and value pairs passed in'); assert.equal(o[key], value, 'Key and value pairs passed in');
test.assertEqual(o, object, 'Object passed in'); assert.equal(o, object, 'Object passed in');
}); });
test.assertEqual(keys.size, 3, 'All keys have been iterated upon'); assert.equal(keys.size, 3, 'All keys have been iterated upon');
} };
require('sdk/test').run(exports);

Просмотреть файл

@ -6,7 +6,7 @@ const observers = require("sdk/deprecated/observer-service");
const { Cc, Ci } = require("chrome"); const { Cc, Ci } = require("chrome");
const { LoaderWithHookedConsole2 } = require("sdk/test/loader"); const { LoaderWithHookedConsole2 } = require("sdk/test/loader");
exports.testUnloadAndErrorLogging = function(test) { exports.testUnloadAndErrorLogging = function(assert) {
let { loader, messages } = LoaderWithHookedConsole2(module); let { loader, messages } = LoaderWithHookedConsole2(module);
var sbobsvc = loader.require("sdk/deprecated/observer-service"); var sbobsvc = loader.require("sdk/deprecated/observer-service");
@ -19,23 +19,23 @@ exports.testUnloadAndErrorLogging = function(test) {
}; };
sbobsvc.add("blarg", cb); sbobsvc.add("blarg", cb);
observers.notify("blarg", "yo yo"); observers.notify("blarg", "yo yo");
test.assertEqual(timesCalled, 1); assert.equal(timesCalled, 1);
sbobsvc.add("narg", badCb); sbobsvc.add("narg", badCb);
observers.notify("narg", "yo yo"); observers.notify("narg", "yo yo");
test.assertEqual(messages[0], "console.error: " + require("sdk/self").name + ": \n"); assert.equal(messages[0], "console.error: " + require("sdk/self").name + ": \n");
var lines = messages[1].split("\n"); var lines = messages[1].split("\n");
test.assertEqual(lines[0], " Message: Error: foo"); assert.equal(lines[0], " Message: Error: foo");
test.assertEqual(lines[1], " Stack:"); assert.equal(lines[1], " Stack:");
// Keep in mind to update "18" to the line of "throw new Error("foo")" // Keep in mind to update "18" to the line of "throw new Error("foo")"
test.assert(lines[2].indexOf(module.uri + ":18") != -1); assert.ok(lines[2].indexOf(module.uri + ":18") != -1);
loader.unload(); loader.unload();
observers.notify("blarg", "yo yo"); observers.notify("blarg", "yo yo");
test.assertEqual(timesCalled, 1); assert.equal(timesCalled, 1);
}; };
exports.testObserverService = function(test) { exports.testObserverService = function(assert) {
var ios = Cc['@mozilla.org/network/io-service;1'] var ios = Cc['@mozilla.org/network/io-service;1']
.getService(Ci.nsIIOService); .getService(Ci.nsIIOService);
var service = Cc["@mozilla.org/observer-service;1"]. var service = Cc["@mozilla.org/observer-service;1"].
@ -53,25 +53,27 @@ exports.testObserverService = function(test) {
observers.add("blarg", cb); observers.add("blarg", cb);
service.notifyObservers(uri, "blarg", "some data"); service.notifyObservers(uri, "blarg", "some data");
test.assertEqual(timesCalled, 1, assert.equal(timesCalled, 1,
"observer-service.add() should call callback"); "observer-service.add() should call callback");
test.assertEqual(lastSubject, uri, assert.equal(lastSubject, uri,
"observer-service.add() should pass subject"); "observer-service.add() should pass subject");
test.assertEqual(lastData, "some data", assert.equal(lastData, "some data",
"observer-service.add() should pass data"); "observer-service.add() should pass data");
function customSubject() {} function customSubject() {}
function customData() {} function customData() {}
observers.notify("blarg", customSubject, customData); observers.notify("blarg", customSubject, customData);
test.assertEqual(timesCalled, 2, assert.equal(timesCalled, 2,
"observer-service.notify() should work"); "observer-service.notify() should work");
test.assertEqual(lastSubject, customSubject, assert.equal(lastSubject, customSubject,
"observer-service.notify() should pass+wrap subject"); "observer-service.notify() should pass+wrap subject");
test.assertEqual(lastData, customData, assert.equal(lastData, customData,
"observer-service.notify() should pass data"); "observer-service.notify() should pass data");
observers.remove("blarg", cb); observers.remove("blarg", cb);
service.notifyObservers(null, "blarg", "some data"); service.notifyObservers(null, "blarg", "some data");
test.assertEqual(timesCalled, 2, assert.equal(timesCalled, 2,
"observer-service.remove() should work"); "observer-service.remove() should work");
}; };
require('sdk/test').run(exports);

Просмотреть файл

@ -5,40 +5,42 @@
var options = require("@loader/options"); var options = require("@loader/options");
exports.testPackaging = function(test) { exports.testPackaging = function(assert) {
test.assertEqual(options.metadata.description, assert.equal(options.metadata.description,
"Add-on development made easy.", "Add-on development made easy.",
"packaging metadata should be available"); "packaging metadata should be available");
try { try {
options.metadata.description = 'new description'; options.metadata.description = 'new description';
test.fail('should not have been able to set options.metadata property'); assert.fail('should not have been able to set options.metadata property');
} }
catch (e) {} catch (e) {}
test.assertEqual(options.metadata.description, assert.equal(options.metadata.description,
"Add-on development made easy.", "Add-on development made easy.",
"packaging metadata should be frozen"); "packaging metadata should be frozen");
test.assertEqual(options.metadata.permissions['private-browsing'], undefined, assert.equal(options.metadata.permissions['private-browsing'], undefined,
"private browsing metadata should be undefined"); "private browsing metadata should be undefined");
test.assertEqual(options.metadata['private-browsing'], undefined, assert.equal(options.metadata['private-browsing'], undefined,
"private browsing metadata should be be frozen"); "private browsing metadata should be be frozen");
test.assertEqual(options['private-browsing'], undefined, assert.equal(options['private-browsing'], undefined,
"private browsing metadata should be be frozen"); "private browsing metadata should be be frozen");
try { try {
options.metadata['private-browsing'] = true; options.metadata['private-browsing'] = true;
test.fail('should not have been able to set options.metadata property'); assert.fail('should not have been able to set options.metadata property');
} }
catch(e) {} catch(e) {}
test.assertEqual(options.metadata['private-browsing'], undefined, assert.equal(options.metadata['private-browsing'], undefined,
"private browsing metadata should be be frozen"); "private browsing metadata should be be frozen");
try { try {
options.metadata.permissions['private-browsing'] = true; options.metadata.permissions['private-browsing'] = true;
test.fail('should not have been able to set options.metadata.permissions property'); assert.fail('should not have been able to set options.metadata.permissions property');
} }
catch (e) {} catch (e) {}
test.assertEqual(options.metadata.permissions['private-browsing'], undefined, assert.equal(options.metadata.permissions['private-browsing'], undefined,
"private browsing metadata should be be frozen"); "private browsing metadata should be be frozen");
}; };
require('sdk/test').run(exports);

Просмотреть файл

@ -8,7 +8,7 @@ const testPageMod = require("./pagemod-test-helpers").testPageMod;
const { Loader } = require('sdk/test/loader'); const { Loader } = require('sdk/test/loader');
const tabs = require("sdk/tabs"); const tabs = require("sdk/tabs");
const timer = require("sdk/timers"); const timer = require("sdk/timers");
const { Cc, Ci } = require("chrome"); const { Cc, Ci, Cu } = require("chrome");
const { open, getFrames, getMostRecentBrowserWindow } = require('sdk/window/utils'); const { open, getFrames, getMostRecentBrowserWindow } = require('sdk/window/utils');
const windowUtils = require('sdk/deprecated/window-utils'); const windowUtils = require('sdk/deprecated/window-utils');
const { getTabContentWindow, getActiveTab, setTabURL, openTab, closeTab } = require('sdk/tabs/utils'); const { getTabContentWindow, getActiveTab, setTabURL, openTab, closeTab } = require('sdk/tabs/utils');
@ -21,19 +21,12 @@ const promise = require("sdk/core/promise");
const { pb } = require('./private-browsing/helper'); const { pb } = require('./private-browsing/helper');
const { URL } = require("sdk/url"); const { URL } = require("sdk/url");
const testPageURI = require("sdk/self").data.url("test.html"); const testPageURI = require("sdk/self").data.url("test.html");
const { waitUntil } = require("sdk/test/utils");
/* XXX This can be used to delay closing the test Firefox instance for interactive // The following adds Debugger constructor to the global namespace.
* testing or visual inspection. This test is registered first so that it runs const { addDebuggerToGlobal } =
* the last. */ Cu.import('resource://gre/modules/jsdebugger.jsm', {});
exports.delay = function(test) { addDebuggerToGlobal(this);
if (false) {
test.waitUntilDone(60000);
timer.setTimeout(function() {test.done();}, 4000);
}
else {
test.pass();
}
}
function Isolate(worker) { function Isolate(worker) {
return "(" + worker + ")()"; return "(" + worker + ")()";
@ -41,19 +34,19 @@ function Isolate(worker) {
/* Tests for the PageMod APIs */ /* Tests for the PageMod APIs */
exports.testPageMod1 = function(test) { exports.testPageMod1 = function(assert, done) {
let mods = testPageMod(test, "about:", [{ let mods = testPageMod(assert, done, "about:", [{
include: /about:/, include: /about:/,
contentScriptWhen: 'end', contentScriptWhen: 'end',
contentScript: 'new ' + function WorkerScope() { contentScript: 'new ' + function WorkerScope() {
window.document.body.setAttribute("JEP-107", "worked"); window.document.body.setAttribute("JEP-107", "worked");
}, },
onAttach: function() { onAttach: function() {
test.assertEqual(this, mods[0], "The 'this' object is the page mod."); assert.equal(this, mods[0], "The 'this' object is the page mod.");
} }
}], }],
function(win, done) { function(win, done) {
test.assertEqual( assert.equal(
win.document.body.getAttribute("JEP-107"), win.document.body.getAttribute("JEP-107"),
"worked", "worked",
"PageMod.onReady test" "PageMod.onReady test"
@ -63,8 +56,8 @@ exports.testPageMod1 = function(test) {
); );
}; };
exports.testPageMod2 = function(test) { exports.testPageMod2 = function(assert, done) {
testPageMod(test, "about:", [{ testPageMod(assert, done, "about:", [{
include: "about:*", include: "about:*",
contentScript: [ contentScript: [
'new ' + function contentScript() { 'new ' + function contentScript() {
@ -82,25 +75,25 @@ exports.testPageMod2 = function(test) {
} }
] ]
}], function(win, done) { }], function(win, done) {
test.assertEqual(win.document.documentElement.getAttribute("first"), assert.equal(win.document.documentElement.getAttribute("first"),
"true", "true",
"PageMod test #2: first script has run"); "PageMod test #2: first script has run");
test.assertEqual(win.document.documentElement.getAttribute("second"), assert.equal(win.document.documentElement.getAttribute("second"),
"true", "true",
"PageMod test #2: second script has run"); "PageMod test #2: second script has run");
test.assertEqual("AUQLUE" in win, false, assert.equal("AUQLUE" in win, false,
"PageMod test #2: scripts get a wrapped window"); "PageMod test #2: scripts get a wrapped window");
done(); done();
}); });
}; };
exports.testPageModIncludes = function(test) { exports.testPageModIncludes = function(assert, done) {
var asserts = []; var asserts = [];
function createPageModTest(include, expectedMatch) { function createPageModTest(include, expectedMatch) {
// Create an 'onload' test function... // Create an 'onload' test function...
asserts.push(function(test, win) { asserts.push(function(test, win) {
var matches = include in win.localStorage; var matches = include in win.localStorage;
test.assert(expectedMatch ? matches : !matches, assert.ok(expectedMatch ? matches : !matches,
"'" + include + "' match test, expected: " + expectedMatch); "'" + include + "' match test, expected: " + expectedMatch);
}); });
// ...and corresponding PageMod options // ...and corresponding PageMod options
@ -121,7 +114,7 @@ exports.testPageModIncludes = function(test) {
}; };
} }
testPageMod(test, testPageURI, [ testPageMod(assert, done, testPageURI, [
createPageModTest("*", false), createPageModTest("*", false),
createPageModTest("*.google.com", false), createPageModTest("*.google.com", false),
createPageModTest("resource:*", true), createPageModTest("resource:*", true),
@ -129,11 +122,11 @@ exports.testPageModIncludes = function(test) {
createPageModTest(testPageURI, true) createPageModTest(testPageURI, true)
], ],
function (win, done) { function (win, done) {
test.waitUntil(function () win.localStorage[testPageURI], waitUntil(function () win.localStorage[testPageURI],
testPageURI + " page-mod to be executed") testPageURI + " page-mod to be executed")
.then(function () { .then(function () {
asserts.forEach(function(fn) { asserts.forEach(function(fn) {
fn(test, win); fn(assert, win);
}); });
done(); done();
}); });
@ -141,20 +134,20 @@ exports.testPageModIncludes = function(test) {
); );
}; };
exports.testPageModErrorHandling = function(test) { exports.testPageModErrorHandling = function(assert) {
test.assertRaises(function() { assert.throws(function() {
new PageMod(); new PageMod();
}, },
'The `include` option must always contain atleast one rule', /The `include` option must always contain atleast one rule/,
"PageMod() throws when 'include' option is not specified."); "PageMod() throws when 'include' option is not specified.");
}; };
/* Tests for internal functions. */ /* Tests for internal functions. */
exports.testCommunication1 = function(test) { exports.testCommunication1 = function(assert, done) {
let workerDone = false, let workerDone = false,
callbackDone = null; callbackDone = null;
testPageMod(test, "about:", [{ testPageMod(assert, done, "about:", [{
include: "about:*", include: "about:*",
contentScriptWhen: 'end', contentScriptWhen: 'end',
contentScript: 'new ' + function WorkerScope() { contentScript: 'new ' + function WorkerScope() {
@ -165,10 +158,10 @@ exports.testCommunication1 = function(test) {
}, },
onAttach: function(worker) { onAttach: function(worker) {
worker.on('error', function(e) { worker.on('error', function(e) {
test.fail('Errors where reported'); assert.fail('Errors where reported');
}); });
worker.on('message', function(value) { worker.on('message', function(value) {
test.assertEqual( assert.equal(
"worked", "worked",
value, value,
"test comunication" "test comunication"
@ -183,7 +176,7 @@ exports.testCommunication1 = function(test) {
function(win, done) { function(win, done) {
(callbackDone = function() { (callbackDone = function() {
if (workerDone) { if (workerDone) {
test.assertEqual( assert.equal(
'worked', 'worked',
win.document.body.getAttribute('JEP-107'), win.document.body.getAttribute('JEP-107'),
'attribute should be modified' 'attribute should be modified'
@ -195,11 +188,11 @@ exports.testCommunication1 = function(test) {
); );
}; };
exports.testCommunication2 = function(test) { exports.testCommunication2 = function(assert, done) {
let callbackDone = null, let callbackDone = null,
window; window;
testPageMod(test, "about:license", [{ testPageMod(assert, done, "about:license", [{
include: "about:*", include: "about:*",
contentScriptWhen: 'start', contentScriptWhen: 'start',
contentScript: 'new ' + function WorkerScope() { contentScript: 'new ' + function WorkerScope() {
@ -213,11 +206,11 @@ exports.testCommunication2 = function(test) {
}, },
onAttach: function(worker) { onAttach: function(worker) {
worker.on('error', function(e) { worker.on('error', function(e) {
test.fail('Errors where reported'); assert.fail('Errors where reported');
}); });
worker.on('message', function(msg) { worker.on('message', function(msg) {
if ('onload' == msg) { if ('onload' == msg) {
test.assertEqual( assert.equal(
'42', '42',
window.document.documentElement.getAttribute('AUQLUE'), window.document.documentElement.getAttribute('AUQLUE'),
'PageMod scripts executed in order' 'PageMod scripts executed in order'
@ -225,7 +218,7 @@ exports.testCommunication2 = function(test) {
window.document.documentElement.setAttribute('test', 'changes in window'); window.document.documentElement.setAttribute('test', 'changes in window');
worker.postMessage('get window.test') worker.postMessage('get window.test')
} else { } else {
test.assertEqual( assert.equal(
'changes in window', 'changes in window',
msg, msg,
'PageMod test #2: second script has run' 'PageMod test #2: second script has run'
@ -242,11 +235,11 @@ exports.testCommunication2 = function(test) {
); );
}; };
exports.testEventEmitter = function(test) { exports.testEventEmitter = function(assert, done) {
let workerDone = false, let workerDone = false,
callbackDone = null; callbackDone = null;
testPageMod(test, "about:", [{ testPageMod(assert, done, "about:", [{
include: "about:*", include: "about:*",
contentScript: 'new ' + function WorkerScope() { contentScript: 'new ' + function WorkerScope() {
self.port.on('addon-to-content', function(data) { self.port.on('addon-to-content', function(data) {
@ -255,10 +248,10 @@ exports.testEventEmitter = function(test) {
}, },
onAttach: function(worker) { onAttach: function(worker) {
worker.on('error', function(e) { worker.on('error', function(e) {
test.fail('Errors were reported : '+e); assert.fail('Errors were reported : '+e);
}); });
worker.port.on('content-to-addon', function(value) { worker.port.on('content-to-addon', function(value) {
test.assertEqual( assert.equal(
"worked", "worked",
value, value,
"EventEmitter API works!" "EventEmitter API works!"
@ -282,7 +275,7 @@ exports.testEventEmitter = function(test) {
// Execute two concurrent page mods on same document to ensure that their // Execute two concurrent page mods on same document to ensure that their
// JS contexts are different // JS contexts are different
exports.testMixedContext = function(test) { exports.testMixedContext = function(assert, done) {
let doneCallback = null; let doneCallback = null;
let messages = 0; let messages = 0;
let modObject = { let modObject = {
@ -297,30 +290,30 @@ exports.testMixedContext = function(test) {
onAttach: function(w) { onAttach: function(w) {
w.on("message", function (isContextShared) { w.on("message", function (isContextShared) {
if (isContextShared) { if (isContextShared) {
test.fail("Page mod contexts are mixed."); assert.fail("Page mod contexts are mixed.");
doneCallback(); doneCallback();
} }
else if (++messages == 2) { else if (++messages == 2) {
test.pass("Page mod contexts are different."); assert.pass("Page mod contexts are different.");
doneCallback(); doneCallback();
} }
}); });
} }
}; };
testPageMod(test, "data:text/html;charset=utf-8,", [modObject, modObject], testPageMod(assert, done, "data:text/html;charset=utf-8,", [modObject, modObject],
function(win, done) { function(win, done) {
doneCallback = done; doneCallback = done;
} }
); );
}; };
exports.testHistory = function(test) { exports.testHistory = function(assert, done) {
// We need a valid url in order to have a working History API. // We need a valid url in order to have a working History API.
// (i.e do not work on data: or about: pages) // (i.e do not work on data: or about: pages)
// Test bug 679054. // Test bug 679054.
let url = require("sdk/self").data.url("test-page-mod.html"); let url = require("sdk/self").data.url("test-page-mod.html");
let callbackDone = null; let callbackDone = null;
testPageMod(test, url, [{ testPageMod(assert, done, url, [{
include: url, include: url,
contentScriptWhen: 'end', contentScriptWhen: 'end',
contentScript: 'new ' + function WorkerScope() { contentScript: 'new ' + function WorkerScope() {
@ -330,7 +323,7 @@ exports.testHistory = function(test) {
}, },
onAttach: function(worker) { onAttach: function(worker) {
worker.on('message', function (data) { worker.on('message', function (data) {
test.assertEqual(JSON.stringify(data), JSON.stringify({foo: "bar"}), assert.equal(JSON.stringify(data), JSON.stringify({foo: "bar"}),
"History API works!"); "History API works!");
callbackDone(); callbackDone();
}); });
@ -342,19 +335,15 @@ exports.testHistory = function(test) {
); );
}; };
exports.testRelatedTab = function(test) { exports.testRelatedTab = function(assert, done) {
test.waitUntilDone();
let tab; let tab;
let pageMod = new PageMod({ let pageMod = new PageMod({
include: "about:*", include: "about:*",
onAttach: function(worker) { onAttach: function(worker) {
test.assert(!!worker.tab, "Worker.tab exists"); assert.ok(!!worker.tab, "Worker.tab exists");
test.assertEqual(tab, worker.tab, "Worker.tab is valid"); assert.equal(tab, worker.tab, "Worker.tab is valid");
pageMod.destroy(); pageMod.destroy();
tab.close(function() { tab.close(done);
test.done();
});
} }
}); });
@ -366,9 +355,7 @@ exports.testRelatedTab = function(test) {
}); });
}; };
exports.testRelatedTabNoRequireTab = function(test) { exports.testRelatedTabNoRequireTab = function(assert, done) {
test.waitUntilDone();
let loader = Loader(module); let loader = Loader(module);
let tab; let tab;
let url = "data:text/html;charset=utf-8," + encodeURI("Test related worker tab 2"); let url = "data:text/html;charset=utf-8," + encodeURI("Test related worker tab 2");
@ -376,11 +363,11 @@ exports.testRelatedTabNoRequireTab = function(test) {
let pageMod = new PageMod({ let pageMod = new PageMod({
include: url, include: url,
onAttach: function(worker) { onAttach: function(worker) {
test.assertEqual(worker.tab.url, url, "Worker.tab.url is valid"); assert.equal(worker.tab.url, url, "Worker.tab.url is valid");
worker.tab.close(function() { worker.tab.close(function() {
pageMod.destroy(); pageMod.destroy();
loader.unload(); loader.unload();
test.done(); done();
}); });
} }
}); });
@ -388,20 +375,18 @@ exports.testRelatedTabNoRequireTab = function(test) {
tabs.open(url); tabs.open(url);
}; };
exports.testRelatedTabNoOtherReqs = function(test) { exports.testRelatedTabNoOtherReqs = function(assert, done) {
test.waitUntilDone();
let loader = Loader(module); let loader = Loader(module);
let { PageMod } = loader.require("sdk/page-mod"); let { PageMod } = loader.require("sdk/page-mod");
let pageMod = new PageMod({ let pageMod = new PageMod({
include: "about:blank?testRelatedTabNoOtherReqs", include: "about:blank?testRelatedTabNoOtherReqs",
onAttach: function(worker) { onAttach: function(worker) {
test.assert(!!worker.tab, "Worker.tab exists"); assert.ok(!!worker.tab, "Worker.tab exists");
pageMod.destroy(); pageMod.destroy();
worker.tab.close(function() { worker.tab.close(function() {
worker.destroy(); worker.destroy();
loader.unload(); loader.unload();
test.done(); done();
}); });
} }
}); });
@ -411,9 +396,7 @@ exports.testRelatedTabNoOtherReqs = function(test) {
}); });
}; };
exports.testWorksWithExistingTabs = function(test) { exports.testWorksWithExistingTabs = function(assert, done) {
test.waitUntilDone();
let url = "data:text/html;charset=utf-8," + encodeURI("Test unique document"); let url = "data:text/html;charset=utf-8," + encodeURI("Test unique document");
let { PageMod } = require("sdk/page-mod"); let { PageMod } = require("sdk/page-mod");
tabs.open({ tabs.open({
@ -423,13 +406,13 @@ exports.testWorksWithExistingTabs = function(test) {
include: url, include: url,
attachTo: ["existing", "top", "frame"], attachTo: ["existing", "top", "frame"],
onAttach: function(worker) { onAttach: function(worker) {
test.assert(!!worker.tab, "Worker.tab exists"); assert.ok(!!worker.tab, "Worker.tab exists");
test.assertEqual(tab, worker.tab, "A worker has been created on this existing tab"); assert.equal(tab, worker.tab, "A worker has been created on this existing tab");
timer.setTimeout(function() { timer.setTimeout(function() {
pageModOnExisting.destroy(); pageModOnExisting.destroy();
pageModOffExisting.destroy(); pageModOffExisting.destroy();
tab.close(test.done.bind(test)); tab.close(done);
}, 0); }, 0);
} }
}); });
@ -437,16 +420,14 @@ exports.testWorksWithExistingTabs = function(test) {
let pageModOffExisting = new PageMod({ let pageModOffExisting = new PageMod({
include: url, include: url,
onAttach: function(worker) { onAttach: function(worker) {
test.fail("pageModOffExisting page-mod should not have attached to anything"); assert.fail("pageModOffExisting page-mod should not have attached to anything");
} }
}); });
} }
}); });
}; };
exports.testTabWorkerOnMessage = function(test) { exports.testTabWorkerOnMessage = function(assert, done) {
test.waitUntilDone();
let { browserWindows } = require("sdk/windows"); let { browserWindows } = require("sdk/windows");
let tabs = require("sdk/tabs"); let tabs = require("sdk/tabs");
let { PageMod } = require("sdk/page-mod"); let { PageMod } = require("sdk/page-mod");
@ -465,8 +446,8 @@ exports.testTabWorkerOnMessage = function(test) {
contentScriptWhen: "ready", contentScriptWhen: "ready",
contentScript: "self.postMessage({ url: window.location.href, title: document.title });", contentScript: "self.postMessage({ url: window.location.href, title: document.title });",
onMessage: function onMessage(data) { onMessage: function onMessage(data) {
test.assertEqual(this.tab.url, data.url, "location is correct"); assert.equal(this.tab.url, data.url, "location is correct");
test.assertEqual(this.tab.title, data.title, "title is correct"); assert.equal(this.tab.title, data.title, "title is correct");
if (this.tab.url === url1) { if (this.tab.url === url1) {
worker1 = this; worker1 = this;
tabs.open({ url: url2, inBackground: true }); tabs.open({ url: url2, inBackground: true });
@ -477,7 +458,7 @@ exports.testTabWorkerOnMessage = function(test) {
worker1.destroy(); worker1.destroy();
worker.tab.close(function() { worker.tab.close(function() {
worker.destroy(); worker.destroy();
test.done(); done();
}); });
}); });
} }
@ -490,15 +471,14 @@ exports.testTabWorkerOnMessage = function(test) {
tabs.open(url1); tabs.open(url1);
}; };
exports.testAutomaticDestroy = function(test) { exports.testAutomaticDestroy = function(assert, done) {
test.waitUntilDone();
let loader = Loader(module); let loader = Loader(module);
let pageMod = loader.require("sdk/page-mod").PageMod({ let pageMod = loader.require("sdk/page-mod").PageMod({
include: "about:*", include: "about:*",
contentScriptWhen: "start", contentScriptWhen: "start",
onAttach: function(w) { onAttach: function(w) {
test.fail("Page-mod should have been detroyed during module unload"); assert.fail("Page-mod should have been detroyed during module unload");
} }
}); });
@ -510,14 +490,13 @@ exports.testAutomaticDestroy = function(test) {
tabs.open({ tabs.open({
url: "about:", url: "about:",
onReady: function onReady(tab) { onReady: function onReady(tab) {
test.pass("check automatic destroy"); assert.pass("check automatic destroy");
tab.close(test.done.bind(test)); tab.close(done);
} }
}); });
} };
exports.testAttachToTabsOnly = function(test) { exports.testAttachToTabsOnly = function(assert, done) {
test.waitUntilDone();
let { PageMod } = require('sdk/page-mod'); let { PageMod } = require('sdk/page-mod');
let openedTab = null; // Tab opened in openTabWithIframe() let openedTab = null; // Tab opened in openTabWithIframe()
@ -530,16 +509,14 @@ exports.testAttachToTabsOnly = function(test) {
onAttach: function onAttach(worker) { onAttach: function onAttach(worker) {
if (worker.tab === openedTab) { if (worker.tab === openedTab) {
if (++workerCount == 3) { if (++workerCount == 3) {
test.pass('Succesfully applied to tab documents and its iframe'); assert.pass('Succesfully applied to tab documents and its iframe');
worker.destroy(); worker.destroy();
mod.destroy(); mod.destroy();
openedTab.close(function() { openedTab.close(done);
test.done();
});
} }
} }
else { else {
test.fail('page-mod attached to a non-tab document'); assert.fail('page-mod attached to a non-tab document');
} }
} }
}); });
@ -608,9 +585,7 @@ exports.testAttachToTabsOnly = function(test) {
openHiddenFrame(); openHiddenFrame();
}; };
exports['test111 attachTo [top]'] = function(test) { exports['test111 attachTo [top]'] = function(assert, done) {
test.waitUntilDone();
let { PageMod } = require('sdk/page-mod'); let { PageMod } = require('sdk/page-mod');
let subContent = '<iframe src="data:text/html;charset=utf-8,sub frame" />' let subContent = '<iframe src="data:text/html;charset=utf-8,sub frame" />'
@ -628,18 +603,16 @@ exports['test111 attachTo [top]'] = function(test) {
onAttach: function onAttach(worker) { onAttach: function onAttach(worker) {
if (++workerCount == 1) { if (++workerCount == 1) {
worker.on('message', function (href) { worker.on('message', function (href) {
test.assertEqual(href, topDocumentURL, assert.equal(href, topDocumentURL,
"worker on top level document only"); "worker on top level document only");
let tab = worker.tab; let tab = worker.tab;
worker.destroy(); worker.destroy();
mod.destroy(); mod.destroy();
tab.close(function() { tab.close(done);
test.done();
});
}); });
} }
else { else {
test.fail('page-mod attached to a non-top document'); assert.fail('page-mod attached to a non-top document');
} }
} }
}); });
@ -647,9 +620,7 @@ exports['test111 attachTo [top]'] = function(test) {
require('sdk/tabs').open(topDocumentURL); require('sdk/tabs').open(topDocumentURL);
}; };
exports['test111 attachTo [frame]'] = function(test) { exports['test111 attachTo [frame]'] = function(assert, done) {
test.waitUntilDone();
let { PageMod } = require('sdk/page-mod'); let { PageMod } = require('sdk/page-mod');
let subFrameURL = 'data:text/html;charset=utf-8,subframe'; let subFrameURL = 'data:text/html;charset=utf-8,subframe';
@ -662,17 +633,15 @@ exports['test111 attachTo [frame]'] = function(test) {
function onMessage(href) { function onMessage(href) {
if (href == frameURL) if (href == frameURL)
test.pass("worker on first frame"); assert.pass("worker on first frame");
else if (href == subFrameURL) else if (href == subFrameURL)
test.pass("worker on second frame"); assert.pass("worker on second frame");
else else
test.fail("worker on unexpected document: " + href); assert.fail("worker on unexpected document: " + href);
this.destroy(); this.destroy();
if (++messageCount == 2) { if (++messageCount == 2) {
mod.destroy(); mod.destroy();
require('sdk/tabs').activeTab.close(function() { require('sdk/tabs').activeTab.close(done);
test.done();
});
} }
} }
let mod = PageMod({ let mod = PageMod({
@ -685,7 +654,7 @@ exports['test111 attachTo [frame]'] = function(test) {
worker.on('message', onMessage); worker.on('message', onMessage);
} }
else { else {
test.fail('page-mod attached to a non-frame document'); assert.fail('page-mod attached to a non-frame document');
} }
} }
}); });
@ -693,22 +662,20 @@ exports['test111 attachTo [frame]'] = function(test) {
require('sdk/tabs').open(topDocumentURL); require('sdk/tabs').open(topDocumentURL);
}; };
exports.testContentScriptOptionsOption = function(test) { exports.testContentScriptOptionsOption = function(assert, done) {
test.waitUntilDone();
let callbackDone = null; let callbackDone = null;
testPageMod(test, "about:", [{ testPageMod(assert, done, "about:", [{
include: "about:*", include: "about:*",
contentScript: "self.postMessage( [typeof self.options.d, self.options] );", contentScript: "self.postMessage( [typeof self.options.d, self.options] );",
contentScriptWhen: "end", contentScriptWhen: "end",
contentScriptOptions: {a: true, b: [1,2,3], c: "string", d: function(){ return 'test'}}, contentScriptOptions: {a: true, b: [1,2,3], c: "string", d: function(){ return 'test'}},
onAttach: function(worker) { onAttach: function(worker) {
worker.on('message', function(msg) { worker.on('message', function(msg) {
test.assertEqual( msg[0], 'undefined', 'functions are stripped from contentScriptOptions' ); assert.equal( msg[0], 'undefined', 'functions are stripped from contentScriptOptions' );
test.assertEqual( typeof msg[1], 'object', 'object as contentScriptOptions' ); assert.equal( typeof msg[1], 'object', 'object as contentScriptOptions' );
test.assertEqual( msg[1].a, true, 'boolean in contentScriptOptions' ); assert.equal( msg[1].a, true, 'boolean in contentScriptOptions' );
test.assertEqual( msg[1].b.join(), '1,2,3', 'array and numbers in contentScriptOptions' ); assert.equal( msg[1].b.join(), '1,2,3', 'array and numbers in contentScriptOptions' );
test.assertEqual( msg[1].c, 'string', 'string in contentScriptOptions' ); assert.equal( msg[1].c, 'string', 'string in contentScriptOptions' );
callbackDone(); callbackDone();
}); });
} }
@ -719,8 +686,8 @@ exports.testContentScriptOptionsOption = function(test) {
); );
}; };
exports.testPageModCss = function(test) { exports.testPageModCss = function(assert, done) {
let [pageMod] = testPageMod(test, let [pageMod] = testPageMod(assert, done,
'data:text/html;charset=utf-8,<div style="background: silver">css test</div>', [{ 'data:text/html;charset=utf-8,<div style="background: silver">css test</div>', [{
include: ["*", "data:*"], include: ["*", "data:*"],
contentStyle: "div { height: 100px; }", contentStyle: "div { height: 100px; }",
@ -729,12 +696,12 @@ exports.testPageModCss = function(test) {
}], }],
function(win, done) { function(win, done) {
let div = win.document.querySelector("div"); let div = win.document.querySelector("div");
test.assertEqual( assert.equal(
div.clientHeight, div.clientHeight,
100, 100,
"PageMod contentStyle worked" "PageMod contentStyle worked"
); );
test.assertEqual( assert.equal(
div.offsetHeight, div.offsetHeight,
120, 120,
"PageMod contentStyleFile worked" "PageMod contentStyleFile worked"
@ -744,8 +711,8 @@ exports.testPageModCss = function(test) {
); );
}; };
exports.testPageModCssList = function(test) { exports.testPageModCssList = function(assert, done) {
let [pageMod] = testPageMod(test, let [pageMod] = testPageMod(assert, done,
'data:text/html;charset=utf-8,<div style="width:320px; max-width: 480px!important">css test</div>', [{ 'data:text/html;charset=utf-8,<div style="width:320px; max-width: 480px!important">css test</div>', [{
include: "data:*", include: "data:*",
contentStyleFile: [ contentStyleFile: [
@ -766,25 +733,25 @@ exports.testPageModCssList = function(test) {
let div = win.document.querySelector("div"), let div = win.document.querySelector("div"),
style = win.getComputedStyle(div); style = win.getComputedStyle(div);
test.assertEqual( assert.equal(
div.clientHeight, div.clientHeight,
100, 100,
"PageMod contentStyle list works and is evaluated after contentStyleFile" "PageMod contentStyle list works and is evaluated after contentStyleFile"
); );
test.assertEqual( assert.equal(
div.offsetHeight, div.offsetHeight,
120, 120,
"PageMod contentStyleFile list works" "PageMod contentStyleFile list works"
); );
test.assertEqual( assert.equal(
style.width, style.width,
"320px", "320px",
"PageMod add-on author/page author style sheet precedence works" "PageMod add-on author/page author style sheet precedence works"
); );
test.assertEqual( assert.equal(
style.maxWidth, style.maxWidth,
"480px", "480px",
"PageMod add-on author/page author style sheet precedence with !important works" "PageMod add-on author/page author style sheet precedence with !important works"
@ -795,8 +762,8 @@ exports.testPageModCssList = function(test) {
); );
}; };
exports.testPageModCssDestroy = function(test) { exports.testPageModCssDestroy = function(assert, done) {
let [pageMod] = testPageMod(test, let [pageMod] = testPageMod(assert, done,
'data:text/html;charset=utf-8,<div style="width:200px">css test</div>', [{ 'data:text/html;charset=utf-8,<div style="width:200px">css test</div>', [{
include: "data:*", include: "data:*",
contentStyle: "div { width: 100px!important; }" contentStyle: "div { width: 100px!important; }"
@ -806,14 +773,14 @@ exports.testPageModCssDestroy = function(test) {
let div = win.document.querySelector("div"), let div = win.document.querySelector("div"),
style = win.getComputedStyle(div); style = win.getComputedStyle(div);
test.assertEqual( assert.equal(
style.width, style.width,
"100px", "100px",
"PageMod contentStyle worked" "PageMod contentStyle worked"
); );
pageMod.destroy(); pageMod.destroy();
test.assertEqual( assert.equal(
style.width, style.width,
"200px", "200px",
"PageMod contentStyle is removed after destroy" "PageMod contentStyle is removed after destroy"
@ -825,8 +792,7 @@ exports.testPageModCssDestroy = function(test) {
); );
}; };
exports.testPageModCssAutomaticDestroy = function(test) { exports.testPageModCssAutomaticDestroy = function(assert, done) {
test.waitUntilDone();
let loader = Loader(module); let loader = Loader(module);
let pageMod = loader.require("sdk/page-mod").PageMod({ let pageMod = loader.require("sdk/page-mod").PageMod({
@ -844,7 +810,7 @@ exports.testPageModCssAutomaticDestroy = function(test) {
let div = win.document.querySelector("div"); let div = win.document.querySelector("div");
let style = win.getComputedStyle(div); let style = win.getComputedStyle(div);
test.assertEqual( assert.equal(
style.width, style.width,
"100px", "100px",
"PageMod contentStyle worked" "PageMod contentStyle worked"
@ -852,20 +818,19 @@ exports.testPageModCssAutomaticDestroy = function(test) {
loader.unload(); loader.unload();
test.assertEqual( assert.equal(
style.width, style.width,
"200px", "200px",
"PageMod contentStyle is removed after loader's unload" "PageMod contentStyle is removed after loader's unload"
); );
tab.close(test.done.bind(test)); tab.close(done);
} }
}); });
}; };
exports.testPageModTimeout = function(test) { exports.testPageModTimeout = function(assert, done) {
test.waitUntilDone();
let tab = null let tab = null
let loader = Loader(module); let loader = Loader(module);
let { PageMod } = loader.require("sdk/page-mod"); let { PageMod } = loader.require("sdk/page-mod");
@ -880,13 +845,13 @@ exports.testPageModTimeout = function(test) {
}), }),
onAttach: function(worker) { onAttach: function(worker) {
worker.port.on("scheduled", function(id) { worker.port.on("scheduled", function(id) {
test.pass("timer was scheduled") assert.pass("timer was scheduled")
worker.port.on("fired", function(data) { worker.port.on("fired", function(data) {
test.assertEqual(id, data, "timer was fired") assert.equal(id, data, "timer was fired")
tab.close(function() { tab.close(function() {
worker.destroy() worker.destroy()
loader.unload() loader.unload()
test.done() done()
}); });
}) })
}) })
@ -900,8 +865,7 @@ exports.testPageModTimeout = function(test) {
} }
exports.testPageModcancelTimeout = function(test) { exports.testPageModcancelTimeout = function(assert, done) {
test.waitUntilDone();
let tab = null let tab = null
let loader = Loader(module); let loader = Loader(module);
let { PageMod } = loader.require("sdk/page-mod"); let { PageMod } = loader.require("sdk/page-mod");
@ -919,15 +883,15 @@ exports.testPageModcancelTimeout = function(test) {
}), }),
onAttach: function(worker) { onAttach: function(worker) {
worker.port.on("failed", function() { worker.port.on("failed", function() {
test.fail("cancelled timeout fired") assert.fail("cancelled timeout fired")
}) })
worker.port.on("timeout", function(id) { worker.port.on("timeout", function(id) {
test.pass("timer was scheduled") assert.pass("timer was scheduled")
tab.close(function() { tab.close(function() {
worker.destroy(); worker.destroy();
mod.destroy(); mod.destroy();
loader.unload(); loader.unload();
test.done(); done();
}); });
}) })
} }
@ -939,9 +903,7 @@ exports.testPageModcancelTimeout = function(test) {
}) })
} }
exports.testExistingOnFrames = function(test) { exports.testExistingOnFrames = function(assert, done) {
test.waitUntilDone();
let subFrameURL = 'data:text/html;charset=utf-8,testExistingOnFrames-sub-frame'; let subFrameURL = 'data:text/html;charset=utf-8,testExistingOnFrames-sub-frame';
let subIFrame = '<iframe src="' + subFrameURL + '" />' let subIFrame = '<iframe src="' + subFrameURL + '" />'
let iFrameURL = 'data:text/html;charset=utf-8,' + encodeURIComponent(subIFrame) let iFrameURL = 'data:text/html;charset=utf-8,' + encodeURIComponent(subIFrame)
@ -972,26 +934,26 @@ exports.testExistingOnFrames = function(test) {
if (urls.indexOf(worker.url) == -1) if (urls.indexOf(worker.url) == -1)
return; return;
test.assertNotEqual(url, assert.notEqual(url,
worker.url, worker.url,
'worker should not be attached to the top window'); 'worker should not be attached to the top window');
if (++counter < 2) { if (++counter < 2) {
// we can rely on this order in this case because we are sure that // we can rely on this order in this case because we are sure that
// the frames being tested have completely loaded // the frames being tested have completely loaded
test.assertEqual(iFrameURL, worker.url, '1st attach is for top frame'); assert.equal(iFrameURL, worker.url, '1st attach is for top frame');
} }
else if (counter > 2) { else if (counter > 2) {
test.fail('applied page mod too many times'); assert.fail('applied page mod too many times');
} }
else { else {
test.assertEqual(subFrameURL, worker.url, '2nd attach is for sub frame'); assert.equal(subFrameURL, worker.url, '2nd attach is for sub frame');
// need timeout because onAttach is called before the constructor returns // need timeout because onAttach is called before the constructor returns
timer.setTimeout(function() { timer.setTimeout(function() {
pagemodOnExisting.destroy(); pagemodOnExisting.destroy();
pagemodOffExisting.destroy(); pagemodOffExisting.destroy();
closeTab(tab); closeTab(tab);
test.done(); done();
}, 0); }, 0);
} }
} }
@ -1002,7 +964,7 @@ exports.testExistingOnFrames = function(test) {
attachTo: ["frame"], attachTo: ["frame"],
contentScriptWhen: 'ready', contentScriptWhen: 'ready',
onAttach: function(mod) { onAttach: function(mod) {
test.fail('pagemodOffExisting page-mod should not have been attached'); assert.fail('pagemodOffExisting page-mod should not have been attached');
} }
}); });
} }
@ -1010,8 +972,7 @@ exports.testExistingOnFrames = function(test) {
window.addEventListener("load", wait4Iframes, false); window.addEventListener("load", wait4Iframes, false);
}; };
exports.testIFramePostMessage = function(test) { exports.testIFramePostMessage = function(assert, done) {
test.waitUntilDone();
let count = 0; let count = 0;
tabs.open({ tabs.open({
@ -1021,27 +982,27 @@ exports.testIFramePostMessage = function(test) {
contentScriptFile: data.url('test-iframe.js'), contentScriptFile: data.url('test-iframe.js'),
contentScript: 'var iframePath = \'' + data.url('test-iframe-postmessage.html') + '\'', contentScript: 'var iframePath = \'' + data.url('test-iframe-postmessage.html') + '\'',
onMessage: function(msg) { onMessage: function(msg) {
test.assertEqual(++count, 1); assert.equal(++count, 1);
test.assertEqual(msg.first, 'a string'); assert.equal(msg.first, 'a string');
test.assert(msg.second[1], "array"); assert.ok(msg.second[1], "array");
test.assertEqual(typeof msg.third, 'object'); assert.equal(typeof msg.third, 'object');
worker.destroy(); worker.destroy();
tab.close(function() test.done()); tab.close(done);
} }
}); });
} }
}); });
}; };
exports.testEvents = function(test) { exports.testEvents = function(assert, done) {
let content = "<script>\n new " + function DocumentScope() { let content = "<script>\n new " + function DocumentScope() {
window.addEventListener("ContentScriptEvent", function () { window.addEventListener("ContentScriptEvent", function () {
window.receivedEvent = true; window.receivedEvent = true;
}, false); }, false);
} + "\n</script>"; } + "\n</script>";
let url = "data:text/html;charset=utf-8," + encodeURIComponent(content); let url = "data:text/html;charset=utf-8," + encodeURIComponent(content);
testPageMod(test, url, [{ testPageMod(assert, done, url, [{
include: "data:*", include: "data:*",
contentScript: 'new ' + function WorkerScope() { contentScript: 'new ' + function WorkerScope() {
let evt = document.createEvent("Event"); let evt = document.createEvent("Event");
@ -1050,7 +1011,7 @@ exports.testEvents = function(test) {
} }
}], }],
function(win, done) { function(win, done) {
test.assert( assert.ok(
win.receivedEvent, win.receivedEvent,
"Content script sent an event and document received it" "Content script sent an event and document received it"
); );
@ -1059,9 +1020,8 @@ exports.testEvents = function(test) {
); );
}; };
exports["test page-mod on private tab"] = function (test) { exports["test page-mod on private tab"] = function (assert, done) {
test.waitUntilDone(); let fail = assert.fail.bind(assert);
let fail = test.fail.bind(test);
let privateUri = "data:text/html;charset=utf-8," + let privateUri = "data:text/html;charset=utf-8," +
"<iframe src=\"data:text/html;charset=utf-8,frame\" />"; "<iframe src=\"data:text/html;charset=utf-8,frame\" />";
@ -1073,20 +1033,20 @@ exports["test page-mod on private tab"] = function (test) {
if (isTabPBSupported || isWindowPBSupported) { if (isTabPBSupported || isWindowPBSupported) {
// When PB isn't supported, the page-mod will apply to all document // When PB isn't supported, the page-mod will apply to all document
// as all of them will be non-private // as all of them will be non-private
test.assertEqual(worker.tab.url, assert.equal(worker.tab.url,
nonPrivateUri, nonPrivateUri,
"page-mod should only attach to the non-private tab"); "page-mod should only attach to the non-private tab");
} }
test.assert(!isPrivate(worker), assert.ok(!isPrivate(worker),
"The worker is really non-private"); "The worker is really non-private");
test.assert(!isPrivate(worker.tab), assert.ok(!isPrivate(worker.tab),
"The document is really non-private"); "The document is really non-private");
pageMod.destroy(); pageMod.destroy();
page1.close(). page1.close().
then(page2.close). then(page2.close).
then(test.done.bind(test), fail); then(done, fail);
} }
}); });
@ -1097,11 +1057,10 @@ exports["test page-mod on private tab"] = function (test) {
}, fail); }, fail);
} }
exports["test page-mod on private tab in global pb"] = function (test) { exports["test page-mod on private tab in global pb"] = function (assert, done) {
test.waitUntilDone();
if (!isGlobalPBSupported) { if (!isGlobalPBSupported) {
test.pass(); assert.pass();
return test.done(); return done();
} }
let privateUri = "data:text/html;charset=utf-8," + let privateUri = "data:text/html;charset=utf-8," +
@ -1110,22 +1069,22 @@ exports["test page-mod on private tab in global pb"] = function (test) {
let pageMod = new PageMod({ let pageMod = new PageMod({
include: privateUri, include: privateUri,
onAttach: function(worker) { onAttach: function(worker) {
test.assertEqual(worker.tab.url, assert.equal(worker.tab.url,
privateUri, privateUri,
"page-mod should attach"); "page-mod should attach");
test.assertEqual(isPrivateBrowsingSupported, assert.equal(isPrivateBrowsingSupported,
false, false,
"private browsing is not supported"); "private browsing is not supported");
test.assert(isPrivate(worker), assert.ok(isPrivate(worker),
"The worker is really non-private"); "The worker is really non-private");
test.assert(isPrivate(worker.tab), assert.ok(isPrivate(worker.tab),
"The document is really non-private"); "The document is really non-private");
pageMod.destroy(); pageMod.destroy();
worker.tab.close(function() { worker.tab.close(function() {
pb.once('stop', function() { pb.once('stop', function() {
test.pass('global pb stop'); assert.pass('global pb stop');
test.done(); done();
}); });
pb.deactivate(); pb.deactivate();
}); });
@ -1134,16 +1093,16 @@ exports["test page-mod on private tab in global pb"] = function (test) {
let page1; let page1;
pb.once('start', function() { pb.once('start', function() {
test.pass('global pb start'); assert.pass('global pb start');
tabs.open({ url: privateUri }); tabs.open({ url: privateUri });
}); });
pb.activate(); pb.activate();
} }
// Bug 699450: Calling worker.tab.close() should not lead to exception // Bug 699450: Calling worker.tab.close() should not lead to exception
exports.testWorkerTabClose = function(test) { exports.testWorkerTabClose = function(assert, done) {
let callbackDone; let callbackDone;
testPageMod(test, "about:", [{ testPageMod(assert, done, "about:", [{
include: "about:", include: "about:",
contentScript: '', contentScript: '',
onAttach: function(worker) { onAttach: function(worker) {
@ -1153,7 +1112,7 @@ exports.testWorkerTabClose = function(test) {
// dispatch, so we need to wait for the next event loop cycle to // dispatch, so we need to wait for the next event loop cycle to
// check for tab nulliness. // check for tab nulliness.
timer.setTimeout(function () { timer.setTimeout(function () {
test.assert(!worker.tab, assert.ok(!worker.tab,
"worker.tab should be null right after tab.close()"); "worker.tab should be null right after tab.close()");
callbackDone(); callbackDone();
}, 0); }, 0);
@ -1165,3 +1124,33 @@ exports.testWorkerTabClose = function(test) {
} }
); );
}; };
exports.testDebugMetadata = function(assert, done) {
let dbg = new Debugger;
let globalDebuggees = [];
dbg.onNewGlobalObject = function(global) {
globalDebuggees.push(global);
}
let mods = testPageMod(assert, done, "about:", [{
include: "about:",
contentScriptWhen: "start",
contentScript: "null;",
}],
function(win, done) {
assert.ok(globalDebuggees.some(function(global) {
try {
let metadata = Cu.getSandboxMetadata(global.unsafeDereference());
return metadata && metadata.addonID && metadata.SDKContentScript;
} catch(e) {
// Some of the globals might not be Sandbox instances and thus
// will cause getSandboxMetadata to fail.
return false;
}
}), "one of the globals is a content script");
done();
}
);
};
require('sdk/test').run(exports);

Просмотреть файл

@ -560,11 +560,9 @@ exports["test Automatic Destroy"] = function(assert) {
loader.unload(); loader.unload();
panel.port.on("event-back", function () { assert.throws(() => {
assert.fail("Panel should have been destroyed on module unload"); panel.port.emit("event");
}); }, /already have been unloaded/, "check automatic destroy");
panel.port.emit("event");
assert.pass("check automatic destroy");
}; };
exports["test Show Then Destroy"] = makeEventOrderTest({ exports["test Show Then Destroy"] = makeEventOrderTest({
@ -942,6 +940,30 @@ exports['test nested popups'] = function (assert, done) {
panel.show(); panel.show();
}; };
exports['test emits on url changes'] = function (assert, done) {
let loader = Loader(module);
let { Panel } = loader.require('sdk/panel');
let uriA = 'data:text/html;charset=utf-8,A';
let uriB = 'data:text/html;charset=utf-8,B';
let panel = Panel({
contentURL: uriA,
contentScript: 'new ' + function() {
self.port.on('hi', function() {
self.port.emit('bye', document.URL);
});
}
});
panel.contentURL = uriB;
panel.port.emit('hi', 'hi')
panel.port.on('bye', function(uri) {
assert.equal(uri, uriB, 'message was delivered to new uri');
loader.unload();
done();
});
};
if (isWindowPBSupported) { if (isWindowPBSupported) {
exports.testGetWindow = function(assert, done) { exports.testGetWindow = function(assert, done) {
let activeWindow = getMostRecentBrowserWindow(); let activeWindow = getMostRecentBrowserWindow();

Просмотреть файл

@ -10,107 +10,107 @@ const BundleService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsISt
const specialChars = "!@#$%^&*()_-=+[]{}~`\'\"<>,./?;:"; const specialChars = "!@#$%^&*()_-=+[]{}~`\'\"<>,./?;:";
exports.testReset = function(test) { exports.testReset = function(assert) {
prefs.reset("test_reset_pref"); prefs.reset("test_reset_pref");
test.assertEqual(prefs.has("test_reset_pref"), false); assert.equal(prefs.has("test_reset_pref"), false);
test.assertEqual(prefs.isSet("test_reset_pref"), false); assert.equal(prefs.isSet("test_reset_pref"), false);
prefs.set("test_reset_pref", 5); prefs.set("test_reset_pref", 5);
test.assertEqual(prefs.has("test_reset_pref"), true); assert.equal(prefs.has("test_reset_pref"), true);
test.assertEqual(prefs.isSet("test_reset_pref"), true); assert.equal(prefs.isSet("test_reset_pref"), true);
test.assertEqual(prefs.keys("test_reset_pref").toString(), "test_reset_pref"); assert.equal(prefs.keys("test_reset_pref").toString(), "test_reset_pref");
}; };
exports.testGetAndSet = function(test) { exports.testGetAndSet = function(assert) {
let svc = Cc["@mozilla.org/preferences-service;1"]. let svc = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefService). getService(Ci.nsIPrefService).
getBranch(null); getBranch(null);
svc.setCharPref("test_set_get_pref", "a normal string"); svc.setCharPref("test_set_get_pref", "a normal string");
test.assertEqual(prefs.get("test_set_get_pref"), "a normal string", assert.equal(prefs.get("test_set_get_pref"), "a normal string",
"preferences-service should read from " + "preferences-service should read from " +
"application-wide preferences service"); "application-wide preferences service");
prefs.set("test_set_get_pref.integer", 1); prefs.set("test_set_get_pref.integer", 1);
test.assertEqual(prefs.get("test_set_get_pref.integer"), 1, assert.equal(prefs.get("test_set_get_pref.integer"), 1,
"set/get integer preference should work"); "set/get integer preference should work");
test.assertEqual( assert.equal(
prefs.keys("test_set_get_pref").sort().toString(), prefs.keys("test_set_get_pref").sort().toString(),
["test_set_get_pref.integer","test_set_get_pref"].sort().toString()); ["test_set_get_pref.integer","test_set_get_pref"].sort().toString());
prefs.set("test_set_get_number_pref", 42); prefs.set("test_set_get_number_pref", 42);
test.assertRaises( assert.throws(
function() { prefs.set("test_set_get_number_pref", 3.14159); }, function() { prefs.set("test_set_get_number_pref", 3.14159); },
"cannot store non-integer number: 3.14159", /cannot store non-integer number: 3.14159/,
"setting a float preference should raise an error" "setting a float preference should raise an error"
); );
test.assertEqual(prefs.get("test_set_get_number_pref"), 42, assert.equal(prefs.get("test_set_get_number_pref"), 42,
"bad-type write attempt should not overwrite"); "bad-type write attempt should not overwrite");
// 0x80000000 (no), 0x7fffffff (yes), -0x80000000 (yes), -0x80000001 (no) // 0x80000000 (no), 0x7fffffff (yes), -0x80000000 (yes), -0x80000001 (no)
test.assertRaises( assert.throws(
function() { prefs.set("test_set_get_number_pref", Math.pow(2, 31)); }, function() { prefs.set("test_set_get_number_pref", Math.pow(2, 31)); },
("you cannot set the test_set_get_number_pref pref to the number " + new RegExp("you cannot set the test_set_get_number_pref pref to the number " +
"2147483648, as number pref values must be in the signed 32-bit " + "2147483648, as number pref values must be in the signed 32\\-bit " +
"integer range -(2^31) to 2^31-1. To store numbers outside that " + "integer range \\-\\(2\\^31\\) to 2\\^31\\-1. To store numbers outside that " +
"range, store them as strings."), "range, store them as strings."),
"setting an int pref outside the range -(2^31) to 2^31-1 shouldn't work" "setting an int pref outside the range -(2^31) to 2^31-1 shouldn't work"
); );
test.assertEqual(prefs.get("test_set_get_number_pref"), 42, assert.equal(prefs.get("test_set_get_number_pref"), 42,
"out-of-range write attempt should not overwrite 1"); "out-of-range write attempt should not overwrite 1");
prefs.set("test_set_get_number_pref", Math.pow(2, 31)-1); prefs.set("test_set_get_number_pref", Math.pow(2, 31)-1);
test.assertEqual(prefs.get("test_set_get_number_pref"), 0x7fffffff, assert.equal(prefs.get("test_set_get_number_pref"), 0x7fffffff,
"in-range write attempt should work 1"); "in-range write attempt should work 1");
prefs.set("test_set_get_number_pref", -Math.pow(2, 31)); prefs.set("test_set_get_number_pref", -Math.pow(2, 31));
test.assertEqual(prefs.get("test_set_get_number_pref"), -0x80000000, assert.equal(prefs.get("test_set_get_number_pref"), -0x80000000,
"in-range write attempt should work 2"); "in-range write attempt should work 2");
test.assertRaises( assert.throws(
function() { prefs.set("test_set_get_number_pref", -0x80000001); }, function() { prefs.set("test_set_get_number_pref", -0x80000001); },
("you cannot set the test_set_get_number_pref pref to the number " + new RegExp("you cannot set the test_set_get_number_pref pref to the number " +
"-2147483649, as number pref values must be in the signed 32-bit " + "\\-2147483649, as number pref values must be in the signed 32-bit " +
"integer range -(2^31) to 2^31-1. To store numbers outside that " + "integer range \\-\\(2\\^31\\) to 2\\^31\\-1. To store numbers outside that " +
"range, store them as strings."), "range, store them as strings."),
"setting an int pref outside the range -(2^31) to 2^31-1 shouldn't work" "setting an int pref outside the range -(2^31) to 2^31-1 shouldn't work"
); );
test.assertEqual(prefs.get("test_set_get_number_pref"), -0x80000000, assert.equal(prefs.get("test_set_get_number_pref"), -0x80000000,
"out-of-range write attempt should not overwrite 2"); "out-of-range write attempt should not overwrite 2");
prefs.set("test_set_get_pref.string", "foo"); prefs.set("test_set_get_pref.string", "foo");
test.assertEqual(prefs.get("test_set_get_pref.string"), "foo", assert.equal(prefs.get("test_set_get_pref.string"), "foo",
"set/get string preference should work"); "set/get string preference should work");
prefs.set("test_set_get_pref.boolean", true); prefs.set("test_set_get_pref.boolean", true);
test.assertEqual(prefs.get("test_set_get_pref.boolean"), true, assert.equal(prefs.get("test_set_get_pref.boolean"), true,
"set/get boolean preference should work"); "set/get boolean preference should work");
prefs.set("test_set_get_unicode_pref", String.fromCharCode(960)); prefs.set("test_set_get_unicode_pref", String.fromCharCode(960));
test.assertEqual(prefs.get("test_set_get_unicode_pref"), assert.equal(prefs.get("test_set_get_unicode_pref"),
String.fromCharCode(960), String.fromCharCode(960),
"set/get unicode preference should work"); "set/get unicode preference should work");
var unsupportedValues = [null, [], undefined]; var unsupportedValues = [null, [], undefined];
unsupportedValues.forEach( unsupportedValues.forEach(
function(value) { function(value) {
test.assertRaises( assert.throws(
function() { prefs.set("test_set_pref", value); }, function() { prefs.set("test_set_pref", value); },
("can't set pref test_set_pref to value '" + value + "'; " + new RegExp("can't set pref test_set_pref to value '" + value + "'; " +
"it isn't a string, integer, or boolean"), "it isn't a string, integer, or boolean"),
"Setting a pref to " + uneval(value) + " should raise error" "Setting a pref to " + uneval(value) + " should raise error"
); );
}); });
}; };
exports.testPrefClass = function(test) { exports.testPrefClass = function(assert) {
var branch = Branch("test_foo"); var branch = Branch("test_foo");
test.assertEqual(branch.test, undefined, "test_foo.test is undefined"); assert.equal(branch.test, undefined, "test_foo.test is undefined");
branch.test = true; branch.test = true;
test.assertEqual(branch.test, true, "test_foo.test is true"); assert.equal(branch.test, true, "test_foo.test is true");
delete branch.test; delete branch.test;
test.assertEqual(branch.test, undefined, "test_foo.test is undefined"); assert.equal(branch.test, undefined, "test_foo.test is undefined");
}; };
exports.testGetSetLocalized = function(test) { exports.testGetSetLocalized = function(assert) {
let prefName = "general.useragent.locale"; let prefName = "general.useragent.locale";
// Ensure that "general.useragent.locale" is a 'localized' pref // Ensure that "general.useragent.locale" is a 'localized' pref
@ -122,7 +122,7 @@ exports.testGetSetLocalized = function(test) {
GetStringFromName(prefName). GetStringFromName(prefName).
toLowerCase(); toLowerCase();
test.assertEqual(prefs.getLocalized(prefName).toLowerCase(), assert.equal(prefs.getLocalized(prefName).toLowerCase(),
expectedValue, expectedValue,
"get localized preference"); "get localized preference");
@ -131,13 +131,15 @@ exports.testGetSetLocalized = function(test) {
} }
// TEST: setting and getting preferences with special characters work // TEST: setting and getting preferences with special characters work
exports.testSpecialChars = function(test) { exports.testSpecialChars = function(assert) {
let chars = specialChars.split(''); let chars = specialChars.split('');
const ROOT = "test."; const ROOT = "test.";
chars.forEach(function(char) { chars.forEach(function(char) {
let rand = Math.random() + ""; let rand = Math.random() + "";
prefs.set(ROOT+char, rand); prefs.set(ROOT+char, rand);
test.assertEqual(prefs.get(ROOT+char), rand, "setting pref with a name that is a special char, " + char + ", worked!"); assert.equal(prefs.get(ROOT+char), rand, "setting pref with a name that is a special char, " + char + ", worked!");
}); });
}; };
require('sdk/test').run(exports);

Просмотреть файл

@ -10,33 +10,33 @@ const { setTimeout } = require('sdk/timers');
const root = PrefsTarget(); const root = PrefsTarget();
exports.testPrefsTarget = function(test) { exports.testPrefsTarget = function(assert, done) {
test.waitUntilDone();
let loader = Loader(module); let loader = Loader(module);
let pt = loader.require('sdk/preferences/event-target').PrefsTarget({}); let pt = loader.require('sdk/preferences/event-target').PrefsTarget({});
let name = 'test'; let name = 'test';
test.assertEqual(get(name, ''), '', 'test pref is blank'); assert.equal(get(name, ''), '', 'test pref is blank');
pt.once(name, function() { pt.once(name, function() {
test.assertEqual(pt.prefs[name], 2, 'test pref is 2'); assert.equal(pt.prefs[name], 2, 'test pref is 2');
pt.once(name, function() { pt.once(name, function() {
test.fail('should not have heard a pref change'); assert.fail('should not have heard a pref change');
}); });
loader.unload(); loader.unload();
root.once(name, function() { root.once(name, function() {
test.pass('test pref was changed'); assert.pass('test pref was changed');
reset(name); reset(name);
// NOTE: using setTimeout to make sure that the other listener had // NOTE: using setTimeout to make sure that the other listener had
// a chance to fail // a chance to fail
// end test // end test
setTimeout(function() test.done()); setTimeout(done);
}); });
set(name, 3); set(name, 3);
}); });
pt.prefs[name] = 2; pt.prefs[name] = 2;
}; };
require('sdk/test').run(exports);

Просмотреть файл

@ -4,7 +4,7 @@
'use strict'; 'use strict';
const { Ci } = require('chrome'); const { Ci } = require('chrome');
const { merge } = require('sdk/util/object'); const { safeMerge } = require('sdk/util/object');
const windows = require('sdk/windows').browserWindows; const windows = require('sdk/windows').browserWindows;
const tabs = require('sdk/tabs'); const tabs = require('sdk/tabs');
const winUtils = require('sdk/window/utils'); const winUtils = require('sdk/window/utils');
@ -25,69 +25,67 @@ const kAutoStartPref = "browser.privatebrowsing.autostart";
// is global pb is enabled? // is global pb is enabled?
if (isGlobalPBSupported) { if (isGlobalPBSupported) {
merge(module.exports, require('./private-browsing/global')); safeMerge(module.exports, require('./private-browsing/global'));
exports.testGlobalOnlyOnFirefox = function(test) { exports.testGlobalOnlyOnFirefox = function(assert) {
test.assert(is("Firefox"), "isGlobalPBSupported is only true on Firefox"); assert.ok(is("Firefox"), "isGlobalPBSupported is only true on Firefox");
} }
} }
else if (isWindowPBSupported) { else if (isWindowPBSupported) {
merge(module.exports, require('./private-browsing/windows')); safeMerge(module.exports, require('./private-browsing/windows'));
exports.testPWOnlyOnFirefox = function(test) { exports.testPWOnlyOnFirefox = function(assert) {
test.assert(is("Firefox"), "isWindowPBSupported is only true on Firefox"); assert.ok(is("Firefox"), "isWindowPBSupported is only true on Firefox");
} }
} }
// only on Fennec // only on Fennec
else if (isTabPBSupported) { else if (isTabPBSupported) {
merge(module.exports, require('./private-browsing/tabs')); safeMerge(module.exports, require('./private-browsing/tabs'));
exports.testPTOnlyOnFennec = function(test) { exports.testPTOnlyOnFennec = function(assert) {
test.assert(is("Fennec"), "isTabPBSupported is only true on Fennec"); assert.ok(is("Fennec"), "isTabPBSupported is only true on Fennec");
} }
} }
exports.testIsPrivateDefaults = function(test) { exports.testIsPrivateDefaults = function(assert) {
test.assertEqual(isPrivate(), false, 'undefined is not private'); assert.equal(isPrivate(), false, 'undefined is not private');
test.assertEqual(isPrivate('test'), false, 'strings are not private'); assert.equal(isPrivate('test'), false, 'strings are not private');
test.assertEqual(isPrivate({}), false, 'random objects are not private'); assert.equal(isPrivate({}), false, 'random objects are not private');
test.assertEqual(isPrivate(4), false, 'numbers are not private'); assert.equal(isPrivate(4), false, 'numbers are not private');
test.assertEqual(isPrivate(/abc/), false, 'regex are not private'); assert.equal(isPrivate(/abc/), false, 'regex are not private');
test.assertEqual(isPrivate(function() {}), false, 'functions are not private'); assert.equal(isPrivate(function() {}), false, 'functions are not private');
}; };
exports.testWindowDefaults = function(test) { exports.testWindowDefaults = function(assert) {
setPref(DEPRECATE_PREF, true); setPref(DEPRECATE_PREF, true);
// Ensure that browserWindow still works while being deprecated // Ensure that browserWindow still works while being deprecated
let { loader, messages } = LoaderWithHookedConsole(module); let { loader, messages } = LoaderWithHookedConsole(module);
let windows = loader.require("sdk/windows").browserWindows; let windows = loader.require("sdk/windows").browserWindows;
test.assertEqual(windows.activeWindow.isPrivateBrowsing, false, assert.equal(windows.activeWindow.isPrivateBrowsing, false,
'window is not private browsing by default'); 'window is not private browsing by default');
test.assertMatches(messages[0].msg, /DEPRECATED.+isPrivateBrowsing/, assert.ok(/DEPRECATED.+isPrivateBrowsing/.test(messages[0].msg),
'isPrivateBrowsing is deprecated'); 'isPrivateBrowsing is deprecated');
let chromeWin = winUtils.getMostRecentBrowserWindow(); let chromeWin = winUtils.getMostRecentBrowserWindow();
test.assertEqual(getMode(chromeWin), false); assert.equal(getMode(chromeWin), false);
test.assertEqual(isWindowPrivate(chromeWin), false); assert.equal(isWindowPrivate(chromeWin), false);
} };
// tests for the case where private browsing doesn't exist // tests for the case where private browsing doesn't exist
exports.testIsActiveDefault = function(test) { exports.testIsActiveDefault = function(assert) {
test.assertEqual(pb.isActive, false, assert.equal(pb.isActive, false,
'pb.isActive returns false when private browsing isn\'t supported'); 'pb.isActive returns false when private browsing isn\'t supported');
}; };
exports.testIsPrivateBrowsingFalseDefault = function(test) { exports.testIsPrivateBrowsingFalseDefault = function(assert) {
test.assertEqual(isPrivateBrowsingSupported, false, assert.equal(isPrivateBrowsingSupported, false,
'isPrivateBrowsingSupported property is false by default'); 'isPrivateBrowsingSupported property is false by default');
}; };
exports.testGetOwnerWindow = function(test) { exports.testGetOwnerWindow = function(assert, done) {
test.waitUntilDone();
let window = windows.activeWindow; let window = windows.activeWindow;
let chromeWindow = getOwnerWindow(window); let chromeWindow = getOwnerWindow(window);
test.assert(chromeWindow instanceof Ci.nsIDOMWindow, 'associated window is found'); assert.ok(chromeWindow instanceof Ci.nsIDOMWindow, 'associated window is found');
tabs.open({ tabs.open({
url: 'about:blank', url: 'about:blank',
@ -95,28 +93,30 @@ exports.testGetOwnerWindow = function(test) {
onOpen: function(tab) { onOpen: function(tab) {
// test that getOwnerWindow works as expected // test that getOwnerWindow works as expected
if (is('Fennec')) { if (is('Fennec')) {
test.assertNotStrictEqual(chromeWindow, getOwnerWindow(tab)); assert.notStrictEqual(chromeWindow, getOwnerWindow(tab));
test.assert(getOwnerWindow(tab) instanceof Ci.nsIDOMWindow); assert.ok(getOwnerWindow(tab) instanceof Ci.nsIDOMWindow);
} }
else { else {
test.assertStrictEqual(chromeWindow, getOwnerWindow(tab), 'associated window is the same for window and window\'s tab'); assert.strictEqual(chromeWindow, getOwnerWindow(tab), 'associated window is the same for window and window\'s tab');
} }
// test that the tab is not private // test that the tab is not private
// private flag should be ignored by default // private flag should be ignored by default
test.assert(!isPrivate(tab)); assert.ok(!isPrivate(tab));
test.assert(!isPrivate(getOwnerWindow(tab))); assert.ok(!isPrivate(getOwnerWindow(tab)));
tab.close(function() test.done()); tab.close(done);
} }
}); });
}; };
exports.testNewGlobalPBService = function(test) { exports.testNewGlobalPBService = function(assert) {
test.assertEqual(isPrivate(), false, 'isPrivate() is false by default'); assert.equal(isPrivate(), false, 'isPrivate() is false by default');
prefs.set(kAutoStartPref, true); prefs.set(kAutoStartPref, true);
test.assertEqual(prefs.get(kAutoStartPref, false), true, kAutoStartPref + ' is true now'); assert.equal(prefs.get(kAutoStartPref, false), true, kAutoStartPref + ' is true now');
test.assertEqual(isPrivate(), true, 'isPrivate() is true now'); assert.equal(isPrivate(), true, 'isPrivate() is true now');
prefs.set(kAutoStartPref, false); prefs.set(kAutoStartPref, false);
test.assertEqual(isPrivate(), false, 'isPrivate() is false again'); assert.equal(isPrivate(), false, 'isPrivate() is false again');
} };
require('sdk/test').run(exports);

Просмотреть файл

@ -4,20 +4,20 @@
'use strict'; 'use strict';
exports['test:add'] = function(test) { exports['test:add'] = function(assert) {
function Class() {} function Class() {}
let fixture = require('sdk/util/registry').Registry(Class); let fixture = require('sdk/util/registry').Registry(Class);
let isAddEmitted = false; let isAddEmitted = false;
fixture.on('add', function(item) { fixture.on('add', function(item) {
test.assert( assert.ok(
item instanceof Class, item instanceof Class,
'if object added is not an instance should construct instance from it' 'if object added is not an instance should construct instance from it'
); );
test.assert( assert.ok(
fixture.has(item), fixture.has(item),
'callback is called after instance is added' 'callback is called after instance is added'
); );
test.assert( assert.ok(
!isAddEmitted, !isAddEmitted,
'callback should be called for the same item only once' 'callback should be called for the same item only once'
); );
@ -28,19 +28,19 @@ exports['test:add'] = function(test) {
fixture.add(object); fixture.add(object);
}; };
exports['test:remove'] = function(test) { exports['test:remove'] = function(assert) {
function Class() {} function Class() {}
let fixture = require('sdk/util/registry').Registry(Class); let fixture = require('sdk/util/registry').Registry(Class);
fixture.on('remove', function(item) { fixture.on('remove', function(item) {
test.assert( assert.ok(
item instanceof Class, item instanceof Class,
'if object removed can be only instance of Class' 'if object removed can be only instance of Class'
); );
test.assert( assert.ok(
fixture.has(item), fixture.has(item),
'callback is called before instance is removed' 'callback is called before instance is removed'
); );
test.assert( assert.ok(
!isRemoveEmitted, !isRemoveEmitted,
'callback should be called for the same item only once' 'callback should be called for the same item only once'
); );
@ -53,7 +53,7 @@ exports['test:remove'] = function(test) {
fixture.remove(object); fixture.remove(object);
}; };
exports['test:items'] = function(test) { exports['test:items'] = function(assert) {
function Class() {} function Class() {}
let fixture = require('sdk/util/registry').Registry(Class), let fixture = require('sdk/util/registry').Registry(Class),
actual, actual,
@ -61,7 +61,7 @@ exports['test:items'] = function(test) {
function testItem(item) { function testItem(item) {
times ++; times ++;
test.assertEqual( assert.equal(
actual, actual,
item, item,
'item should match actual item being added/removed' 'item should match actual item being added/removed'
@ -75,6 +75,8 @@ exports['test:items'] = function(test) {
fixture.remove(actual); fixture.remove(actual);
fixture.remove(fixture.add(actual = new Class())); fixture.remove(fixture.add(actual = new Class()));
test.assertEqual(3, times, 'should notify listeners on each call'); assert.equal(3, times, 'should notify listeners on each call');
} };
require('sdk/test').run(exports);

Просмотреть файл

@ -21,79 +21,76 @@ const { Services } = Cu.import("resource://gre/modules/Services.jsm");
// Use the profile directory for the temporary files as that will be deleted // Use the profile directory for the temporary files as that will be deleted
// when tests are complete // when tests are complete
const basePath = pathFor("ProfD") const basePath = pathFor("ProfD");
const port = 8099; const port = 8099;
exports.testOptionsValidator = function(test) { exports.testOptionsValidator = function(assert) {
// First, a simple test to make sure we didn't break normal functionality. // First, a simple test to make sure we didn't break normal functionality.
test.assertRaises(function () { assert.throws(function () {
Request({ Request({
url: null url: null
}); });
}, 'The option "url" is invalid.'); }, /The option "url" is invalid./);
// Next we'll have a Request that doesn't throw from c'tor, but from a setter. // Next we'll have a Request that doesn't throw from c'tor, but from a setter.
let req = Request({ let req = Request({
url: "http://playground.zpao.com/jetpack/request/text.php", url: "http://playground.zpao.com/jetpack/request/text.php",
onComplete: function () {} onComplete: function () {}
}); });
test.assertRaises(function () { assert.throws(function () {
req.url = 'www.mozilla.org'; req.url = 'www.mozilla.org';
}, 'The option "url" is invalid.'); }, /The option "url" is invalid/);
// The url shouldn't have changed, so check that // The url shouldn't have changed, so check that
test.assertEqual(req.url, "http://playground.zpao.com/jetpack/request/text.php"); assert.equal(req.url, "http://playground.zpao.com/jetpack/request/text.php");
} };
exports.testContentValidator = function(test) { exports.testContentValidator = function(assert, done) {
test.waitUntilDone(); runMultipleURLs(null, assert, done, {
runMultipleURLs(null, test, {
url: "data:text/html;charset=utf-8,response", url: "data:text/html;charset=utf-8,response",
content: { 'key1' : null, 'key2' : 'some value' }, content: { 'key1' : null, 'key2' : 'some value' },
onComplete: function(response) { onComplete: function(response) {
test.assertEqual(response.text, "response?key1=null&key2=some+value"); assert.equal(response.text, "response?key1=null&key2=some+value");
} }
}); });
}; };
// This is a request to a file that exists. // This is a request to a file that exists.
exports.testStatus200 = function (test) { exports.testStatus200 = function (assert, done) {
let srv = startServerAsync(port, basePath); let srv = startServerAsync(port, basePath);
let content = "Look ma, no hands!\n"; let content = "Look ma, no hands!\n";
let basename = "test-request.txt" let basename = "test-request.txt"
prepareFile(basename, content); prepareFile(basename, content);
test.waitUntilDone();
var req = Request({ var req = Request({
url: "http://localhost:" + port + "/" + basename, url: "http://localhost:" + port + "/" + basename,
onComplete: function (response) { onComplete: function (response) {
test.assertEqual(this, req, "`this` should be request"); assert.equal(this, req, "`this` should be request");
test.assertEqual(response.status, 200); assert.equal(response.status, 200);
test.assertEqual(response.statusText, "OK"); assert.equal(response.statusText, "OK");
test.assertEqual(response.headers["Content-Type"], "text/plain"); assert.equal(response.headers["Content-Type"], "text/plain");
test.assertEqual(response.text, content); assert.equal(response.text, content);
srv.stop(function() test.done()); srv.stop(done);
} }
}).get(); }).get();
} };
// This tries to get a file that doesn't exist // This tries to get a file that doesn't exist
exports.testStatus404 = function (test) { exports.testStatus404 = function (assert, done) {
var srv = startServerAsync(port, basePath); var srv = startServerAsync(port, basePath);
test.waitUntilDone(); runMultipleURLs(srv, assert, done, {
runMultipleURLs(srv, test, {
// the following URL doesn't exist // the following URL doesn't exist
url: "http://localhost:" + port + "/test-request-404.txt", url: "http://localhost:" + port + "/test-request-404.txt",
onComplete: function (response) { onComplete: function (response) {
test.assertEqual(response.status, 404); assert.equal(response.status, 404);
test.assertEqual(response.statusText, "Not Found"); assert.equal(response.statusText, "Not Found");
} }
}); });
} };
// a simple file with a known header // a simple file with a known header
exports.testKnownHeader = function (test) { exports.testKnownHeader = function (assert, done) {
var srv = startServerAsync(port, basePath); var srv = startServerAsync(port, basePath);
// Create the file that will be requested with the associated headers file // Create the file that will be requested with the associated headers file
@ -104,17 +101,16 @@ exports.testKnownHeader = function (test) {
prepareFile(basename, content); prepareFile(basename, content);
prepareFile(headerBasename, headerContent); prepareFile(headerBasename, headerContent);
test.waitUntilDone(); runMultipleURLs(srv, assert, done, {
runMultipleURLs(srv, test, {
url: "http://localhost:" + port + "/test-request-headers.txt", url: "http://localhost:" + port + "/test-request-headers.txt",
onComplete: function (response) { onComplete: function (response) {
test.assertEqual(response.headers["x-jetpack-header"], "Jamba Juice"); assert.equal(response.headers["x-jetpack-header"], "Jamba Juice");
} }
}); });
} };
// complex headers // complex headers
exports.testComplexHeader = function (test) { exports.testComplexHeader = function (assert, done) {
let srv = startServerAsync(port, basePath); let srv = startServerAsync(port, basePath);
let basename = "test-request-complex-headers.sjs"; let basename = "test-request-complex-headers.sjs";
@ -127,21 +123,20 @@ exports.testComplexHeader = function (test) {
"x-jetpack-header-3": "sup dawg, i heard you like x, so we put a x in " + "x-jetpack-header-3": "sup dawg, i heard you like x, so we put a x in " +
"yo x so you can y while you y", "yo x so you can y while you y",
"Set-Cookie": "foo=bar\nbaz=foo" "Set-Cookie": "foo=bar\nbaz=foo"
} };
test.waitUntilDone(); runMultipleURLs(srv, assert, done, {
runMultipleURLs(srv, test, {
url: "http://localhost:" + port + "/test-request-complex-headers.sjs", url: "http://localhost:" + port + "/test-request-complex-headers.sjs",
onComplete: function (response) { onComplete: function (response) {
for (k in headers) { for (k in headers) {
test.assertEqual(response.headers[k], headers[k]); assert.equal(response.headers[k], headers[k]);
} }
} }
}); });
} };
// Force Allow Third Party cookies // Force Allow Third Party cookies
exports.test3rdPartyCookies = function (test) { exports.test3rdPartyCookies = function (assert, done) {
let srv = startServerAsync(port, basePath); let srv = startServerAsync(port, basePath);
let basename = "test-request-3rd-party-cookies.sjs"; let basename = "test-request-3rd-party-cookies.sjs";
@ -159,66 +154,63 @@ exports.test3rdPartyCookies = function (test) {
} }
response.write("<html><body>This tests 3rd party cookies.</body></html>"); response.write("<html><body>This tests 3rd party cookies.</body></html>");
}.toString() }.toString();
prepareFile(basename, content); prepareFile(basename, content);
// Disable the 3rd party cookies // Disable the 3rd party cookies
Services.prefs.setIntPref("network.cookie.cookieBehavior", 1); Services.prefs.setIntPref("network.cookie.cookieBehavior", 1);
test.waitUntilDone();
Request({ Request({
url: "http://localhost:" + port + "/test-request-3rd-party-cookies.sjs", url: "http://localhost:" + port + "/test-request-3rd-party-cookies.sjs",
onComplete: function (response) { onComplete: function (response) {
// Check that the server created the cookie // Check that the server created the cookie
test.assertEqual(response.headers['Set-Cookie'], 'cookie=monster;'); assert.equal(response.headers['Set-Cookie'], 'cookie=monster;');
// Check it wasn't there before // Check it wasn't there before
test.assertEqual(response.headers['x-jetpack-3rd-party'], 'false'); assert.equal(response.headers['x-jetpack-3rd-party'], 'false');
// Make a second request, and check that the server this time // Make a second request, and check that the server this time
// got the cookie // got the cookie
Request({ Request({
url: "http://localhost:" + port + "/test-request-3rd-party-cookies.sjs", url: "http://localhost:" + port + "/test-request-3rd-party-cookies.sjs",
onComplete: function (response) { onComplete: function (response) {
test.assertEqual(response.headers['x-jetpack-3rd-party'], 'true'); assert.equal(response.headers['x-jetpack-3rd-party'], 'true');
srv.stop(function() test.done()); srv.stop(done);
} }
}).get(); }).get();
} }
}).get(); }).get();
} };
exports.testSimpleJSON = function (test) { exports.testSimpleJSON = function (assert, done) {
let srv = startServerAsync(port, basePath); let srv = startServerAsync(port, basePath);
let json = { foo: "bar" }; let json = { foo: "bar" };
let basename = "test-request.json"; let basename = "test-request.json";
prepareFile(basename, JSON.stringify(json)); prepareFile(basename, JSON.stringify(json));
test.waitUntilDone(); runMultipleURLs(srv, assert, done, {
runMultipleURLs(srv, test, {
url: "http://localhost:" + port + "/" + basename, url: "http://localhost:" + port + "/" + basename,
onComplete: function (response) { onComplete: function (response) {
assertDeepEqual(test, response.json, json); assert.deepEqual(response.json, json);
} }
}); });
} };
exports.testInvalidJSON = function (test) { exports.testInvalidJSON = function (assert, done) {
let srv = startServerAsync(port, basePath); let srv = startServerAsync(port, basePath);
let basename = "test-request-invalid.json"; let basename = "test-request-invalid.json";
prepareFile(basename, '"this": "isn\'t JSON"'); prepareFile(basename, '"this": "isn\'t JSON"');
test.waitUntilDone(); runMultipleURLs(srv, assert, done, {
runMultipleURLs(srv, test, {
url: "http://localhost:" + port + "/" + basename, url: "http://localhost:" + port + "/" + basename,
onComplete: function (response) { onComplete: function (response) {
test.assertEqual(response.json, null); assert.equal(response.json, null);
} }
}); });
} };
exports.testHead = function (test) { exports.testHead = function (assert, done) {
let srv = startServerAsync(port, basePath); let srv = startServerAsync(port, basePath);
srv.registerPathHandler("/test-head", srv.registerPathHandler("/test-head",
@ -226,27 +218,26 @@ exports.testHead = function (test) {
response.setHeader("Content-Type", "text/plain", false); response.setHeader("Content-Type", "text/plain", false);
}); });
test.waitUntilDone();
Request({ Request({
url: "http://localhost:" + port + "/test-head", url: "http://localhost:" + port + "/test-head",
onComplete: function (response) { onComplete: function (response) {
test.assertEqual(response.text, ""); assert.equal(response.text, "");
test.assertEqual(response.statusText, "OK"); assert.equal(response.statusText, "OK");
test.assertEqual(response.headers["Content-Type"], "text/plain"); assert.equal(response.headers["Content-Type"], "text/plain");
srv.stop(function() test.done()); srv.stop(done);
} }
}).head(); }).head();
} };
function runMultipleURLs (srv, test, options) { function runMultipleURLs (srv, assert, done, options) {
let urls = [options.url, URL(options.url)]; let urls = [options.url, URL(options.url)];
let cb = options.onComplete; let cb = options.onComplete;
let ran = 0; let ran = 0;
let onComplete = function (res) { let onComplete = function (res) {
cb(res); cb(res);
if (++ran === urls.length) if (++ran === urls.length)
srv ? srv.stop(function () test.done()) : test.done(); srv ? srv.stop(done) : done();
} };
urls.forEach(function (url) { urls.forEach(function (url) {
Request(extend(options, { url: url, onComplete: onComplete })).get(); Request(extend(options, { url: url, onComplete: onComplete })).get();
}); });
@ -259,8 +250,7 @@ function runMultipleURLs (srv, test, options) {
// require an external server nor a network connection. // require an external server nor a network connection.
/* /*
exports.testGetWithParamsNotContent = function (test) { exports.testGetWithParamsNotContent = function (assert, done) {
test.waitUntilDone();
Request({ Request({
url: "http://playground.zpao.com/jetpack/request/getpost.php?foo=bar", url: "http://playground.zpao.com/jetpack/request/getpost.php?foo=bar",
onComplete: function (response) { onComplete: function (response) {
@ -268,14 +258,13 @@ exports.testGetWithParamsNotContent = function (test) {
"POST": [], "POST": [],
"GET" : { foo: "bar" } "GET" : { foo: "bar" }
}; };
assertDeepEqual(test, response.json, expected); assert.deepEqual(response.json, expected);
test.done(); done();
} }
}).get(); }).get();
} }
exports.testGetWithContent = function (test) { exports.testGetWithContent = function (assert, done) {
test.waitUntilDone();
Request({ Request({
url: "http://playground.zpao.com/jetpack/request/getpost.php", url: "http://playground.zpao.com/jetpack/request/getpost.php",
content: { foo: "bar" }, content: { foo: "bar" },
@ -284,14 +273,13 @@ exports.testGetWithContent = function (test) {
"POST": [], "POST": [],
"GET" : { foo: "bar" } "GET" : { foo: "bar" }
}; };
assertDeepEqual(test, response.json, expected); assert.deepEqual(response.json, expected);
test.done(); done();
} }
}).get(); }).get();
} }
exports.testGetWithParamsAndContent = function (test) { exports.testGetWithParamsAndContent = function (assert, done) {
test.waitUntilDone();
Request({ Request({
url: "http://playground.zpao.com/jetpack/request/getpost.php?foo=bar", url: "http://playground.zpao.com/jetpack/request/getpost.php?foo=bar",
content: { baz: "foo" }, content: { baz: "foo" },
@ -300,14 +288,13 @@ exports.testGetWithParamsAndContent = function (test) {
"POST": [], "POST": [],
"GET" : { foo: "bar", baz: "foo" } "GET" : { foo: "bar", baz: "foo" }
}; };
assertDeepEqual(test, response.json, expected); assert.deepEqual(response.json, expected);
test.done(); done();
} }
}).get(); }).get();
} }
exports.testSimplePost = function (test) { exports.testSimplePost = function (assert, done) {
test.waitUntilDone();
Request({ Request({
url: "http://playground.zpao.com/jetpack/request/getpost.php", url: "http://playground.zpao.com/jetpack/request/getpost.php",
content: { foo: "bar" }, content: { foo: "bar" },
@ -316,14 +303,13 @@ exports.testSimplePost = function (test) {
"POST": { foo: "bar" }, "POST": { foo: "bar" },
"GET" : [] "GET" : []
}; };
assertDeepEqual(test, response.json, expected); assert.deepEqual(response.json, expected);
test.done(); done();
} }
}).post(); }).post();
} }
exports.testEncodedContent = function (test) { exports.testEncodedContent = function (assert, done) {
test.waitUntilDone();
Request({ Request({
url: "http://playground.zpao.com/jetpack/request/getpost.php", url: "http://playground.zpao.com/jetpack/request/getpost.php",
content: "foo=bar&baz=foo", content: "foo=bar&baz=foo",
@ -332,14 +318,13 @@ exports.testEncodedContent = function (test) {
"POST": [], "POST": [],
"GET" : { foo: "bar", baz: "foo" } "GET" : { foo: "bar", baz: "foo" }
}; };
assertDeepEqual(test, response.json, expected); assert.deepEqual(response.json, expected);
test.done(); done();
} }
}).get(); }).get();
} }
exports.testEncodedContentWithSpaces = function (test) { exports.testEncodedContentWithSpaces = function (assert, done) {
test.waitUntilDone();
Request({ Request({
url: "http://playground.zpao.com/jetpack/request/getpost.php", url: "http://playground.zpao.com/jetpack/request/getpost.php",
content: "foo=bar+hop!&baz=foo", content: "foo=bar+hop!&baz=foo",
@ -348,14 +333,13 @@ exports.testEncodedContentWithSpaces = function (test) {
"POST": [], "POST": [],
"GET" : { foo: "bar hop!", baz: "foo" } "GET" : { foo: "bar hop!", baz: "foo" }
}; };
assertDeepEqual(test, response.json, expected); assert.deepEqual(response.json, expected);
test.done(); done();
} }
}).get(); }).get();
} }
exports.testGetWithArray = function (test) { exports.testGetWithArray = function (assert, done) {
test.waitUntilDone();
Request({ Request({
url: "http://playground.zpao.com/jetpack/request/getpost.php", url: "http://playground.zpao.com/jetpack/request/getpost.php",
content: { foo: [1, 2], baz: "foo" }, content: { foo: [1, 2], baz: "foo" },
@ -364,14 +348,13 @@ exports.testGetWithArray = function (test) {
"POST": [], "POST": [],
"GET" : { foo: [1, 2], baz: "foo" } "GET" : { foo: [1, 2], baz: "foo" }
}; };
assertDeepEqual(test, response.json, expected); assert.deepEqual(response.json, expected);
test.done(); done();
} }
}).get(); }).get();
} }
exports.testGetWithNestedArray = function (test) { exports.testGetWithNestedArray = function (assert, done) {
test.waitUntilDone();
Request({ Request({
url: "http://playground.zpao.com/jetpack/request/getpost.php", url: "http://playground.zpao.com/jetpack/request/getpost.php",
content: { foo: [1, 2, [3, 4]], bar: "baz" }, content: { foo: [1, 2, [3, 4]], bar: "baz" },
@ -380,14 +363,13 @@ exports.testGetWithNestedArray = function (test) {
"POST": [], "POST": [],
"GET" : this.content "GET" : this.content
}; };
assertDeepEqual(test, response.json, expected); assert.deepEqual(response.json, expected);
test.done(); done();
} }
}).get(); }).get();
} }
exports.testGetWithNestedArray = function (test) { exports.testGetWithNestedArray = function (assert, done) {
test.waitUntilDone();
let request = Request({ let request = Request({
url: "http://playground.zpao.com/jetpack/request/getpost.php", url: "http://playground.zpao.com/jetpack/request/getpost.php",
content: { content: {
@ -402,46 +384,13 @@ exports.testGetWithNestedArray = function (test) {
"POST": [], "POST": [],
"GET" : request.content "GET" : request.content
}; };
assertDeepEqual(test, response.json, expected); assert.deepEqual(response.json, expected);
test.done(); done();
} }
}).get(); }).get();
} }
*/ */
// This is not a proper testing for deep equal, but it's good enough for my uses
// here. It will do type coercion to check equality, but that's good here. Data
// coming from the server will be stringified and so "0" should be equal to 0.
function assertDeepEqual(test, obj1, obj2, msg) {
function equal(o1, o2) {
// cover our non-object cases well enough
if (o1 == o2)
return true;
if (typeof(o1) != typeof(o2))
return false;
if (typeof(o1) != "object")
return o1 == o2;
let e = true;
for (let key in o1) {
let val = o1[key];
e = e && key in o2 && equal(o2[key], val);
if (!e)
break;
}
for (let key in o2) {
let val = o2[key]
e = e && key in o1 && equal(o1[key], val);
if (!e)
break;
}
return e;
}
msg = msg || "objects not equal - " + JSON.stringify(obj1) + " != " +
JSON.stringify(obj2);
test.assert(equal(obj1, obj2), msg);
}
function prepareFile(basename, content) { function prepareFile(basename, content) {
let filePath = file.join(basePath, basename); let filePath = file.join(basePath, basename);
let fileStream = file.open(filePath, 'w'); let fileStream = file.open(filePath, 'w');
@ -469,3 +418,4 @@ function handleRequest(request, response) {
response.write("<html><body>This file tests more complex headers.</body></html>"); response.write("<html><body>This file tests more complex headers.</body></html>");
} }
require('sdk/test').run(exports);

Просмотреть файл

@ -6,6 +6,11 @@ const { sandbox, load, evaluate } = require('sdk/loader/sandbox');
const xulApp = require("sdk/system/xul-app"); const xulApp = require("sdk/system/xul-app");
const fixturesURI = module.uri.split('test-sandbox.js')[0] + 'fixtures/'; const fixturesURI = module.uri.split('test-sandbox.js')[0] + 'fixtures/';
// The following adds Debugger constructor to the global namespace.
const { Cu } = require('chrome');
const { addDebuggerToGlobal } =
Cu.import('resource://gre/modules/jsdebugger.jsm', {});
addDebuggerToGlobal(this);
exports['test basics'] = function(assert) { exports['test basics'] = function(assert) {
let fixture = sandbox('http://example.com'); let fixture = sandbox('http://example.com');
@ -118,4 +123,18 @@ exports['test load script with data: URL and complex char'] = function(assert) {
assert.equal(fixture.chars, 'გამარჯობა', 'complex chars were loaded correctly'); assert.equal(fixture.chars, 'გამარჯობა', 'complex chars were loaded correctly');
}; };
exports['test metadata'] = function(assert) {
let dbg = new Debugger();
dbg.onNewGlobalObject = function(global) {
let metadata = Cu.getSandboxMetadata(global.unsafeDereference());
assert.ok(metadata, 'this global has attached metadata');
assert.equal(metadata.addonID, self.id, 'addon ID is set');
dbg.onNewGlobalObject = undefined;
}
let fixture = sandbox();
let self = require('sdk/self');
}
require('test').run(exports); require('test').run(exports);

Просмотреть файл

@ -3,33 +3,35 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
let four = require("./modules/exportsEquals"); let four = require("./modules/exportsEquals");
exports.testExportsEquals = function(test) { exports.testExportsEquals = function(assert) {
test.assertEqual(four, 4); assert.equal(four, 4);
} };
/* TODO: Discuss idea of dropping support for this feature that was alternative /* TODO: Discuss idea of dropping support for this feature that was alternative
to `module.exports = ..` that failed. to `module.exports = ..` that failed.
let five = require("./modules/setExports"); let five = require("./modules/setExports");
exports.testSetExports = function(test) { exports.testSetExports = function(assert) {
test.assertEqual(five, 5); assert.equal(five, 5);
} }
exports.testDupeSetExports = function(test) { exports.testDupeSetExports = function(assert) {
var passed = false; var passed = false;
try { try {
var dupe = require('./modules/dupeSetExports'); var dupe = require('./modules/dupeSetExports');
} catch(e) { } catch(e) {
passed = /define\(\) was used, so module\.exports= and module\.setExports\(\) may not be used/.test(e.toString()); passed = /define\(\) was used, so module\.exports= and module\.setExports\(\) may not be used/.test(e.toString());
} }
test.assertEqual(passed, true, 'define() or setExports(), not both'); assert.equal(passed, true, 'define() or setExports(), not both');
} }
*/ */
exports.testModule = function(test) { exports.testModule = function(assert) {
// module.id is not cast in stone yet. In the future, it may include the // module.id is not cast in stone yet. In the future, it may include the
// package name, or may possibly be a/ URL of some sort. For now, it's a // package name, or may possibly be a/ URL of some sort. For now, it's a
// URL that starts with resource: and ends with this module name, but the // URL that starts with resource: and ends with this module name, but the
// part in between varies depending upon how the test is run. // part in between varies depending upon how the test is run.
var found = /test-set-exports$/.test(module.id); var found = /test-set-exports$/.test(module.id);
test.assertEqual(found, true, module.id+" ends with test-set-exports.js"); assert.equal(found, true, module.id+" ends with test-set-exports.js");
} };
require('sdk/test').run(exports);

Просмотреть файл

@ -12,18 +12,18 @@ const { prefs: sp } = simplePrefs;
const specialChars = "!@#$%^&*()_-=+[]{}~`\'\"<>,./?;:"; const specialChars = "!@#$%^&*()_-=+[]{}~`\'\"<>,./?;:";
exports.testIterations = function(test) { exports.testIterations = function(assert) {
sp["test"] = true; sp["test"] = true;
sp["test.test"] = true; sp["test.test"] = true;
let prefAry = []; let prefAry = [];
for (var name in sp ) { for (var name in sp ) {
prefAry.push(name); prefAry.push(name);
} }
test.assert("test" in sp); assert.ok("test" in sp);
test.assert(!sp.getPropertyDescriptor); assert.ok(!sp.getPropertyDescriptor);
test.assert(Object.prototype.hasOwnProperty.call(sp, "test")); assert.ok(Object.prototype.hasOwnProperty.call(sp, "test"));
test.assertEqual(["test", "test.test"].toString(), prefAry.sort().toString(), "for (x in y) part 1/2 works"); assert.equal(["test", "test.test"].toString(), prefAry.sort().toString(), "for (x in y) part 1/2 works");
test.assertEqual(["test", "test.test"].toString(), Object.keys(sp).sort().toString(), "Object.keys works"); assert.equal(["test", "test.test"].toString(), Object.keys(sp).sort().toString(), "Object.keys works");
delete sp["test"]; delete sp["test"];
delete sp["test.test"]; delete sp["test.test"];
@ -31,17 +31,17 @@ exports.testIterations = function(test) {
for (var name in sp ) { for (var name in sp ) {
prefAry.push(name); prefAry.push(name);
} }
test.assertEqual([].toString(), prefAry.toString(), "for (x in y) part 2/2 works"); assert.equal([].toString(), prefAry.toString(), "for (x in y) part 2/2 works");
} }
exports.testSetGetBool = function(test) { exports.testSetGetBool = function(assert) {
test.assertEqual(sp.test, undefined, "Value should not exist"); assert.equal(sp.test, undefined, "Value should not exist");
sp.test = true; sp.test = true;
test.assert(sp.test, "Value read should be the value previously set"); assert.ok(sp.test, "Value read should be the value previously set");
}; };
// TEST: setting and getting preferences with special characters work // TEST: setting and getting preferences with special characters work
exports.testSpecialChars = function(test) { exports.testSpecialChars = function(assert) {
let chars = specialChars.split(""); let chars = specialChars.split("");
let len = chars.length; let len = chars.length;
@ -50,7 +50,7 @@ exports.testSpecialChars = function(test) {
let rand = Math.random() + ""; let rand = Math.random() + "";
simplePrefs.on(char, function onPrefChanged() { simplePrefs.on(char, function onPrefChanged() {
simplePrefs.removeListener(char, onPrefChanged); simplePrefs.removeListener(char, onPrefChanged);
test.assertEqual(sp[char], rand, "setting pref with a name that is a special char, " + char + ", worked!"); assert.equal(sp[char], rand, "setting pref with a name that is a special char, " + char + ", worked!");
// end test // end test
if (++count == len) if (++count == len)
@ -60,42 +60,40 @@ exports.testSpecialChars = function(test) {
}); });
}; };
exports.testSetGetInt = function(test) { exports.testSetGetInt = function(assert) {
test.assertEqual(sp["test-int"], undefined, "Value should not exist"); assert.equal(sp["test-int"], undefined, "Value should not exist");
sp["test-int"] = 1; sp["test-int"] = 1;
test.assertEqual(sp["test-int"], 1, "Value read should be the value previously set"); assert.equal(sp["test-int"], 1, "Value read should be the value previously set");
}; };
exports.testSetComplex = function(test) { exports.testSetComplex = function(assert) {
try { try {
sp["test-complex"] = {test: true}; sp["test-complex"] = {test: true};
test.fail("Complex values are not allowed"); assert.fail("Complex values are not allowed");
} }
catch (e) { catch (e) {
test.pass("Complex values are not allowed"); assert.pass("Complex values are not allowed");
} }
}; };
exports.testSetGetString = function(test) { exports.testSetGetString = function(assert) {
test.assertEqual(sp["test-string"], undefined, "Value should not exist"); assert.equal(sp["test-string"], undefined, "Value should not exist");
sp["test-string"] = "test"; sp["test-string"] = "test";
test.assertEqual(sp["test-string"], "test", "Value read should be the value previously set"); assert.equal(sp["test-string"], "test", "Value read should be the value previously set");
}; };
exports.testHasAndRemove = function(test) { exports.testHasAndRemove = function(assert) {
sp.test = true; sp.test = true;
test.assert(("test" in sp), "Value exists"); assert.ok(("test" in sp), "Value exists");
delete sp.test; delete sp.test;
test.assertEqual(sp.test, undefined, "Value should be undefined"); assert.equal(sp.test, undefined, "Value should be undefined");
}; };
exports.testPrefListener = function(test) { exports.testPrefListener = function(assert, done) {
test.waitUntilDone();
let listener = function(prefName) { let listener = function(prefName) {
simplePrefs.removeListener('test-listener', listener); simplePrefs.removeListener('test-listener', listener);
test.assertEqual(prefName, "test-listen", "The prefs listener heard the right event"); assert.equal(prefName, "test-listen", "The prefs listener heard the right event");
test.done(); done();
}; };
simplePrefs.on("test-listen", listener); simplePrefs.on("test-listen", listener);
@ -116,47 +114,43 @@ exports.testPrefListener = function(test) {
sp[pref] = true; sp[pref] = true;
}); });
test.assert((observed.length == 3 && toSet.length == 3), assert.ok((observed.length == 3 && toSet.length == 3),
"Wildcard lengths inconsistent" + JSON.stringify([observed.length, toSet.length])); "Wildcard lengths inconsistent" + JSON.stringify([observed.length, toSet.length]));
toSet.forEach(function(pref,ii) { toSet.forEach(function(pref,ii) {
test.assertEqual(observed[ii], pref, "Wildcard observed " + pref); assert.equal(observed[ii], pref, "Wildcard observed " + pref);
}); });
simplePrefs.removeListener('',wildlistener); simplePrefs.removeListener('',wildlistener);
}; };
exports.testBtnListener = function(test) { exports.testBtnListener = function(assert, done) {
test.waitUntilDone();
let name = "test-btn-listen"; let name = "test-btn-listen";
simplePrefs.on(name, function listener() { simplePrefs.on(name, function listener() {
simplePrefs.removeListener(name, listener); simplePrefs.removeListener(name, listener);
test.pass("Button press event was heard"); assert.pass("Button press event was heard");
test.done(); done();
}); });
notify((id + "-cmdPressed"), "", name); notify((id + "-cmdPressed"), "", name);
}; };
exports.testPrefRemoveListener = function(test) { exports.testPrefRemoveListener = function(assert, done) {
test.waitUntilDone();
let counter = 0; let counter = 0;
let listener = function() { let listener = function() {
test.pass("The prefs listener was not removed yet"); assert.pass("The prefs listener was not removed yet");
if (++counter > 1) if (++counter > 1)
test.fail("The prefs listener was not removed"); assert.fail("The prefs listener was not removed");
simplePrefs.removeListener("test-listen2", listener); simplePrefs.removeListener("test-listen2", listener);
sp["test-listen2"] = false; sp["test-listen2"] = false;
setTimeout(function() { setTimeout(function() {
test.pass("The prefs listener was removed"); assert.pass("The prefs listener was removed");
test.done(); done();
}, 250); }, 250);
}; };
@ -167,15 +161,13 @@ exports.testPrefRemoveListener = function(test) {
}; };
// Bug 710117: Test that simple-pref listeners are removed on unload // Bug 710117: Test that simple-pref listeners are removed on unload
exports.testPrefUnloadListener = function(test) { exports.testPrefUnloadListener = function(assert, done) {
test.waitUntilDone();
let loader = Loader(module); let loader = Loader(module);
let sp = loader.require("sdk/simple-prefs"); let sp = loader.require("sdk/simple-prefs");
let counter = 0; let counter = 0;
let listener = function() { let listener = function() {
test.assertEqual(++counter, 1, "This listener should only be called once"); assert.equal(++counter, 1, "This listener should only be called once");
loader.unload(); loader.unload();
@ -184,7 +176,7 @@ exports.testPrefUnloadListener = function(test) {
// this should execute, but also definitely shouldn't fire listener // this should execute, but also definitely shouldn't fire listener
require("sdk/simple-prefs").prefs["test-listen3"] = false; require("sdk/simple-prefs").prefs["test-listen3"] = false;
test.done(); done();
}; };
sp.on("test-listen3", listener); sp.on("test-listen3", listener);
@ -195,15 +187,14 @@ exports.testPrefUnloadListener = function(test) {
// Bug 710117: Test that simple-pref listeners are removed on unload // Bug 710117: Test that simple-pref listeners are removed on unload
exports.testPrefUnloadWildcardListener = function(test) { exports.testPrefUnloadWildcardListener = function(assert, done) {
test.waitUntilDone();
let testpref = "test-wildcard-unload-listener"; let testpref = "test-wildcard-unload-listener";
let loader = Loader(module); let loader = Loader(module);
let sp = loader.require("sdk/simple-prefs"); let sp = loader.require("sdk/simple-prefs");
let counter = 0; let counter = 0;
let listener = function() { let listener = function() {
test.assertEqual(++counter, 1, "This listener should only be called once"); assert.equal(++counter, 1, "This listener should only be called once");
loader.unload(); loader.unload();
@ -212,7 +203,7 @@ exports.testPrefUnloadWildcardListener = function(test) {
// this should execute, but also definitely shouldn't fire listener // this should execute, but also definitely shouldn't fire listener
require("sdk/simple-prefs").prefs[testpref] = false; require("sdk/simple-prefs").prefs[testpref] = false;
test.done(); done();
}; };
sp.on("", listener); sp.on("", listener);
@ -222,10 +213,12 @@ exports.testPrefUnloadWildcardListener = function(test) {
// Bug 732919 - JSON.stringify() fails on simple-prefs.prefs // Bug 732919 - JSON.stringify() fails on simple-prefs.prefs
exports.testPrefJSONStringification = function(test) { exports.testPrefJSONStringification = function(assert) {
var sp = require("sdk/simple-prefs").prefs; var sp = require("sdk/simple-prefs").prefs;
test.assertEqual( assert.equal(
Object.keys(sp).join(), Object.keys(sp).join(),
Object.keys(JSON.parse(JSON.stringify(sp))).join(), Object.keys(JSON.parse(JSON.stringify(sp))).join(),
"JSON stringification should work."); "JSON stringification should work.");
}; };
require('sdk/test').run(exports);

Просмотреть файл

@ -23,33 +23,31 @@ let storeFilename = storeFile.path;
function manager(loader) loader.sandbox("sdk/simple-storage").manager; function manager(loader) loader.sandbox("sdk/simple-storage").manager;
exports.testSetGet = function (test) { exports.testSetGet = function (assert, done) {
test.waitUntilDone();
// Load the module once, set a value. // Load the module once, set a value.
let loader = Loader(module); let loader = Loader(module);
let ss = loader.require("sdk/simple-storage"); let ss = loader.require("sdk/simple-storage");
manager(loader).jsonStore.onWrite = function (storage) { manager(loader).jsonStore.onWrite = function (storage) {
test.assert(file.exists(storeFilename), "Store file should exist"); assert.ok(file.exists(storeFilename), "Store file should exist");
// Load the module again and make sure the value stuck. // Load the module again and make sure the value stuck.
loader = Loader(module); loader = Loader(module);
ss = loader.require("sdk/simple-storage"); ss = loader.require("sdk/simple-storage");
manager(loader).jsonStore.onWrite = function (storage) { manager(loader).jsonStore.onWrite = function (storage) {
file.remove(storeFilename); file.remove(storeFilename);
test.done(); done();
}; };
test.assertEqual(ss.storage.foo, val, "Value should persist"); assert.equal(ss.storage.foo, val, "Value should persist");
loader.unload(); loader.unload();
}; };
let val = "foo"; let val = "foo";
ss.storage.foo = val; ss.storage.foo = val;
test.assertEqual(ss.storage.foo, val, "Value read should be value set"); assert.equal(ss.storage.foo, val, "Value read should be value set");
loader.unload(); loader.unload();
}; };
exports.testSetGetRootArray = function (test) { exports.testSetGetRootArray = function (assert, done) {
setGetRoot(test, [1, 2, 3], function (arr1, arr2) { setGetRoot(assert, done, [1, 2, 3], function (arr1, arr2) {
if (arr1.length !== arr2.length) if (arr1.length !== arr2.length)
return false; return false;
for (let i = 0; i < arr1.length; i++) { for (let i = 0; i < arr1.length; i++) {
@ -60,25 +58,25 @@ exports.testSetGetRootArray = function (test) {
}); });
}; };
exports.testSetGetRootBool = function (test) { exports.testSetGetRootBool = function (assert, done) {
setGetRoot(test, true); setGetRoot(assert, done, true);
}; };
exports.testSetGetRootFunction = function (test) { exports.testSetGetRootFunction = function (assert, done) {
setGetRootError(test, function () {}, setGetRootError(assert, done, function () {},
"Setting storage to a function should fail"); "Setting storage to a function should fail");
}; };
exports.testSetGetRootNull = function (test) { exports.testSetGetRootNull = function (assert, done) {
setGetRoot(test, null); setGetRoot(assert, done, null);
}; };
exports.testSetGetRootNumber = function (test) { exports.testSetGetRootNumber = function (assert, done) {
setGetRoot(test, 3.14); setGetRoot(assert, done, 3.14);
}; };
exports.testSetGetRootObject = function (test) { exports.testSetGetRootObject = function (assert, done) {
setGetRoot(test, { foo: 1, bar: 2 }, function (obj1, obj2) { setGetRoot(assert, done, { foo: 1, bar: 2 }, function (obj1, obj2) {
for (let prop in obj1) { for (let prop in obj1) {
if (!(prop in obj2) || obj2[prop] !== obj1[prop]) if (!(prop in obj2) || obj2[prop] !== obj1[prop])
return false; return false;
@ -91,22 +89,22 @@ exports.testSetGetRootObject = function (test) {
}); });
}; };
exports.testSetGetRootString = function (test) { exports.testSetGetRootString = function (assert, done) {
setGetRoot(test, "sho' 'nuff"); setGetRoot(assert, done, "sho' 'nuff");
}; };
exports.testSetGetRootUndefined = function (test) { exports.testSetGetRootUndefined = function (assert, done) {
setGetRootError(test, undefined, "Setting storage to undefined should fail"); setGetRootError(assert, done, undefined, "Setting storage to undefined should fail");
}; };
exports.testEmpty = function (test) { exports.testEmpty = function (assert) {
let loader = Loader(module); let loader = Loader(module);
let ss = loader.require("sdk/simple-storage"); let ss = loader.require("sdk/simple-storage");
loader.unload(); loader.unload();
test.assert(!file.exists(storeFilename), "Store file should not exist"); assert.ok(!file.exists(storeFilename), "Store file should not exist");
}; };
exports.testMalformed = function (test) { exports.testMalformed = function (assert) {
let stream = file.open(storeFilename, "w"); let stream = file.open(storeFilename, "w");
stream.write("i'm not json"); stream.write("i'm not json");
stream.close(); stream.close();
@ -117,20 +115,19 @@ exports.testMalformed = function (test) {
empty = false; empty = false;
break; break;
} }
test.assert(empty, "Malformed storage should cause root to be empty"); assert.ok(empty, "Malformed storage should cause root to be empty");
loader.unload(); loader.unload();
}; };
// Go over quota and handle it by listener. // Go over quota and handle it by listener.
exports.testQuotaExceededHandle = function (test) { exports.testQuotaExceededHandle = function (assert, done) {
test.waitUntilDone();
prefs.set(QUOTA_PREF, 18); prefs.set(QUOTA_PREF, 18);
let loader = Loader(module); let loader = Loader(module);
let ss = loader.require("sdk/simple-storage"); let ss = loader.require("sdk/simple-storage");
ss.on("OverQuota", function () { ss.on("OverQuota", function () {
test.pass("OverQuota was emitted as expected"); assert.pass("OverQuota was emitted as expected");
test.assertEqual(this, ss, "`this` should be simple storage"); assert.equal(this, ss, "`this` should be simple storage");
ss.storage = { x: 4, y: 5 }; ss.storage = { x: 4, y: 5 };
manager(loader).jsonStore.onWrite = function () { manager(loader).jsonStore.onWrite = function () {
@ -139,13 +136,13 @@ exports.testQuotaExceededHandle = function (test) {
let numProps = 0; let numProps = 0;
for (let prop in ss.storage) for (let prop in ss.storage)
numProps++; numProps++;
test.assert(numProps, 2, assert.ok(numProps, 2,
"Store should contain 2 values: " + ss.storage.toSource()); "Store should contain 2 values: " + ss.storage.toSource());
test.assertEqual(ss.storage.x, 4, "x value should be correct"); assert.equal(ss.storage.x, 4, "x value should be correct");
test.assertEqual(ss.storage.y, 5, "y value should be correct"); assert.equal(ss.storage.y, 5, "y value should be correct");
manager(loader).jsonStore.onWrite = function (storage) { manager(loader).jsonStore.onWrite = function (storage) {
prefs.reset(QUOTA_PREF); prefs.reset(QUOTA_PREF);
test.done(); done();
}; };
loader.unload(); loader.unload();
}; };
@ -157,8 +154,7 @@ exports.testQuotaExceededHandle = function (test) {
}; };
// Go over quota but don't handle it. The last good state should still persist. // Go over quota but don't handle it. The last good state should still persist.
exports.testQuotaExceededNoHandle = function (test) { exports.testQuotaExceededNoHandle = function (assert, done) {
test.waitUntilDone();
prefs.set(QUOTA_PREF, 5); prefs.set(QUOTA_PREF, 5);
let loader = Loader(module); let loader = Loader(module);
@ -167,24 +163,24 @@ exports.testQuotaExceededNoHandle = function (test) {
manager(loader).jsonStore.onWrite = function (storage) { manager(loader).jsonStore.onWrite = function (storage) {
loader = Loader(module); loader = Loader(module);
ss = loader.require("sdk/simple-storage"); ss = loader.require("sdk/simple-storage");
test.assertEqual(ss.storage, val, assert.equal(ss.storage, val,
"Value should have persisted: " + ss.storage); "Value should have persisted: " + ss.storage);
ss.storage = "some very long string that is very long"; ss.storage = "some very long string that is very long";
ss.on("OverQuota", function () { ss.on("OverQuota", function () {
test.pass("OverQuota emitted as expected"); assert.pass("OverQuota emitted as expected");
manager(loader).jsonStore.onWrite = function () { manager(loader).jsonStore.onWrite = function () {
test.fail("Over-quota value should not have been written"); assert.fail("Over-quota value should not have been written");
}; };
loader.unload(); loader.unload();
loader = Loader(module); loader = Loader(module);
ss = loader.require("sdk/simple-storage"); ss = loader.require("sdk/simple-storage");
test.assertEqual(ss.storage, val, assert.equal(ss.storage, val,
"Over-quota value should not have been written, " + "Over-quota value should not have been written, " +
"old value should have persisted: " + ss.storage); "old value should have persisted: " + ss.storage);
loader.unload(); loader.unload();
prefs.reset(QUOTA_PREF); prefs.reset(QUOTA_PREF);
test.done(); done();
}); });
manager(loader).jsonStore.write(); manager(loader).jsonStore.write();
}; };
@ -194,9 +190,7 @@ exports.testQuotaExceededNoHandle = function (test) {
loader.unload(); loader.unload();
}; };
exports.testQuotaUsage = function (test) { exports.testQuotaUsage = function (assert, done) {
test.waitUntilDone();
let quota = 21; let quota = 21;
prefs.set(QUOTA_PREF, quota); prefs.set(QUOTA_PREF, quota);
@ -205,54 +199,51 @@ exports.testQuotaUsage = function (test) {
// {"a":1} (7 bytes) // {"a":1} (7 bytes)
ss.storage = { a: 1 }; ss.storage = { a: 1 };
test.assertEqual(ss.quotaUsage, 7 / quota, "quotaUsage should be correct"); assert.equal(ss.quotaUsage, 7 / quota, "quotaUsage should be correct");
// {"a":1,"bb":2} (14 bytes) // {"a":1,"bb":2} (14 bytes)
ss.storage = { a: 1, bb: 2 }; ss.storage = { a: 1, bb: 2 };
test.assertEqual(ss.quotaUsage, 14 / quota, "quotaUsage should be correct"); assert.equal(ss.quotaUsage, 14 / quota, "quotaUsage should be correct");
// {"a":1,"bb":2,"cc":3} (21 bytes) // {"a":1,"bb":2,"cc":3} (21 bytes)
ss.storage = { a: 1, bb: 2, cc: 3 }; ss.storage = { a: 1, bb: 2, cc: 3 };
test.assertEqual(ss.quotaUsage, 21 / quota, "quotaUsage should be correct"); assert.equal(ss.quotaUsage, 21 / quota, "quotaUsage should be correct");
manager(loader).jsonStore.onWrite = function () { manager(loader).jsonStore.onWrite = function () {
prefs.reset(QUOTA_PREF); prefs.reset(QUOTA_PREF);
test.done(); done();
}; };
loader.unload(); loader.unload();
}; };
exports.testUninstall = function (test) { exports.testUninstall = function (assert, done) {
test.waitUntilDone();
let loader = Loader(module); let loader = Loader(module);
let ss = loader.require("sdk/simple-storage"); let ss = loader.require("sdk/simple-storage");
manager(loader).jsonStore.onWrite = function () { manager(loader).jsonStore.onWrite = function () {
test.assert(file.exists(storeFilename), "Store file should exist"); assert.ok(file.exists(storeFilename), "Store file should exist");
loader = Loader(module); loader = Loader(module);
ss = loader.require("sdk/simple-storage"); ss = loader.require("sdk/simple-storage");
loader.unload("uninstall"); loader.unload("uninstall");
test.assert(!file.exists(storeFilename), "Store file should be removed"); assert.ok(!file.exists(storeFilename), "Store file should be removed");
test.done(); done();
}; };
ss.storage.foo = "foo"; ss.storage.foo = "foo";
loader.unload(); loader.unload();
}; };
exports.testSetNoSetRead = function (test) { exports.testSetNoSetRead = function (assert, done) {
test.waitUntilDone();
// Load the module, set a value. // Load the module, set a value.
let loader = Loader(module); let loader = Loader(module);
let ss = loader.require("sdk/simple-storage"); let ss = loader.require("sdk/simple-storage");
manager(loader).jsonStore.onWrite = function (storage) { manager(loader).jsonStore.onWrite = function (storage) {
test.assert(file.exists(storeFilename), "Store file should exist"); assert.ok(file.exists(storeFilename), "Store file should exist");
// Load the module again but don't access ss.storage. // Load the module again but don't access ss.storage.
loader = Loader(module); loader = Loader(module);
ss = loader.require("sdk/simple-storage"); ss = loader.require("sdk/simple-storage");
manager(loader).jsonStore.onWrite = function (storage) { manager(loader).jsonStore.onWrite = function (storage) {
test.fail("Nothing should be written since `storage` was not accessed."); assert.fail("Nothing should be written since `storage` was not accessed.");
}; };
loader.unload(); loader.unload();
@ -261,49 +252,50 @@ exports.testSetNoSetRead = function (test) {
ss = loader.require("sdk/simple-storage"); ss = loader.require("sdk/simple-storage");
manager(loader).jsonStore.onWrite = function (storage) { manager(loader).jsonStore.onWrite = function (storage) {
file.remove(storeFilename); file.remove(storeFilename);
test.done(); done();
}; };
test.assertEqual(ss.storage.foo, val, "Value should persist"); assert.equal(ss.storage.foo, val, "Value should persist");
loader.unload(); loader.unload();
}; };
let val = "foo"; let val = "foo";
ss.storage.foo = val; ss.storage.foo = val;
test.assertEqual(ss.storage.foo, val, "Value read should be value set"); assert.equal(ss.storage.foo, val, "Value read should be value set");
loader.unload(); loader.unload();
}; };
function setGetRoot(test, val, compare) { function setGetRoot(assert, done, val, compare) {
test.waitUntilDone();
compare = compare || function (a, b) a === b; compare = compare || function (a, b) a === b;
// Load the module once, set a value. // Load the module once, set a value.
let loader = Loader(module); let loader = Loader(module);
let ss = loader.require("sdk/simple-storage"); let ss = loader.require("sdk/simple-storage");
manager(loader).jsonStore.onWrite = function () { manager(loader).jsonStore.onWrite = function () {
test.assert(file.exists(storeFilename), "Store file should exist"); assert.ok(file.exists(storeFilename), "Store file should exist");
// Load the module again and make sure the value stuck. // Load the module again and make sure the value stuck.
loader = Loader(module); loader = Loader(module);
ss = loader.require("sdk/simple-storage"); ss = loader.require("sdk/simple-storage");
manager(loader).jsonStore.onWrite = function () { manager(loader).jsonStore.onWrite = function () {
file.remove(storeFilename); file.remove(storeFilename);
test.done(); done();
}; };
test.assert(compare(ss.storage, val), "Value should persist"); assert.ok(compare(ss.storage, val), "Value should persist");
loader.unload(); loader.unload();
}; };
ss.storage = val; ss.storage = val;
test.assert(compare(ss.storage, val), "Value read should be value set"); assert.ok(compare(ss.storage, val), "Value read should be value set");
loader.unload(); loader.unload();
} }
function setGetRootError(test, val, msg) { function setGetRootError(assert, done, val, msg) {
let pred = "storage must be one of the following types: " + let pred = new RegExp("storage must be one of the following types: " +
"array, boolean, null, number, object, string"; "array, boolean, null, number, object, string");
let loader = Loader(module); let loader = Loader(module);
let ss = loader.require("sdk/simple-storage"); let ss = loader.require("sdk/simple-storage");
test.assertRaises(function () ss.storage = val, pred, msg); assert.throws(function () ss.storage = val, pred, msg);
done();
loader.unload(); loader.unload();
} }
require('sdk/test').run(exports);

Просмотреть файл

@ -65,8 +65,7 @@ function closeTwoWindows(window1, window2, callback) {
}); });
} }
exports.testAddTab = function(test) { exports.testAddTab = function(assert, done) {
test.waitUntilDone();
openBrowserWindow(function(window, browser) { openBrowserWindow(function(window, browser) {
const tabBrowser = require("sdk/deprecated/tab-browser"); const tabBrowser = require("sdk/deprecated/tab-browser");
@ -87,24 +86,22 @@ exports.testAddTab = function(test) {
tabBrowser.addTab(firstUrl, { tabBrowser.addTab(firstUrl, {
onLoad: function(e) { onLoad: function(e) {
let win1 = cache[startWindowCount - 1]; let win1 = cache[startWindowCount - 1];
test.assertEqual(win1.content.location, firstUrl, "URL of new tab in first window matches"); assert.equal(win1.content.location, firstUrl, "URL of new tab in first window matches");
// Test 2: add a tab in a new window // Test 2: add a tab in a new window
let secondUrl = "data:text/html;charset=utf-8,two"; let secondUrl = "data:text/html;charset=utf-8,two";
tabBrowser.addTab(secondUrl, { tabBrowser.addTab(secondUrl, {
inNewWindow: true, inNewWindow: true,
onLoad: function(e) { onLoad: function(e) {
test.assertEqual(cache.length, startWindowCount + 1, "a new window was opened"); assert.equal(cache.length, startWindowCount + 1, "a new window was opened");
let win2 = cache[startWindowCount]; let win2 = cache[startWindowCount];
let gBrowser = win2.gBrowser; let gBrowser = win2.gBrowser;
gBrowser.addEventListener("DOMContentLoaded", function onLoad(e) { gBrowser.addEventListener("DOMContentLoaded", function onLoad(e) {
gBrowser.removeEventListener("DOMContentLoaded", onLoad, false); gBrowser.removeEventListener("DOMContentLoaded", onLoad, false);
test.assertEqual(win2.content.location, secondUrl, "URL of new tab in the new window matches"); assert.equal(win2.content.location, secondUrl, "URL of new tab in the new window matches");
closeBrowserWindow(win2, function() { closeBrowserWindow(win2, function() {
closeBrowserWindow(win1, function() { closeBrowserWindow(win1, done);
test.done();
});
}); });
}, false); }, false);
} }
@ -114,8 +111,7 @@ exports.testAddTab = function(test) {
}); });
}; };
exports.testTrackerWithDelegate = function(test) { exports.testTrackerWithDelegate = function(assert, done) {
test.waitUntilDone();
const tabBrowser = require("sdk/deprecated/tab-browser"); const tabBrowser = require("sdk/deprecated/tab-browser");
var delegate = { var delegate = {
@ -128,22 +124,22 @@ exports.testTrackerWithDelegate = function(test) {
this.state = "waiting for browser window to close"; this.state = "waiting for browser window to close";
timer.setTimeout(function() { timer.setTimeout(function() {
closeBrowserWindow(browser.ownerDocument.defaultView, function() { closeBrowserWindow(browser.ownerDocument.defaultView, function() {
test.assertEqual(delegate.state, "deinitializing"); assert.equal(delegate.state, "deinitializing");
tb.unload(); tb.unload();
test.done(); done();
}); });
}, 0); }, 0);
} }
else else
test.fail("invalid state"); assert.fail("invalid state");
}, },
onUntrack: function onUntrack(browser) { onUntrack: function onUntrack(browser) {
if (this.state == "waiting for browser window to close") { if (this.state == "waiting for browser window to close") {
test.pass("proper state in onUntrack"); assert.pass("proper state in onUntrack");
this.state = "deinitializing"; this.state = "deinitializing";
} }
else if (this.state != "deinitializing") else if (this.state != "deinitializing")
test.fail("invalid state"); assert.fail("invalid state");
} }
}; };
var tb = new tabBrowser.Tracker(delegate); var tb = new tabBrowser.Tracker(delegate);
@ -153,19 +149,16 @@ exports.testTrackerWithDelegate = function(test) {
openBrowserWindow(); openBrowserWindow();
}; };
exports.testWhenContentLoaded = function(test) { exports.testWhenContentLoaded = function(assert, done) {
test.waitUntilDone();
const tabBrowser = require("sdk/deprecated/tab-browser"); const tabBrowser = require("sdk/deprecated/tab-browser");
var tracker = tabBrowser.whenContentLoaded( var tracker = tabBrowser.whenContentLoaded(
function(window) { function(window) {
var item = window.document.getElementById("foo"); var item = window.document.getElementById("foo");
test.assertEqual(item.textContent, "bar", assert.equal(item.textContent, "bar",
"whenContentLoaded() works."); "whenContentLoaded() works.");
tracker.unload(); tracker.unload();
closeBrowserWindow(activeWindow(), function() { closeBrowserWindow(activeWindow(), done);
test.done();
});
}); });
openBrowserWindow(function(browserWindow, browser) { openBrowserWindow(function(browserWindow, browser) {
@ -174,8 +167,7 @@ exports.testWhenContentLoaded = function(test) {
}); });
}; };
exports.testTrackerWithoutDelegate = function(test) { exports.testTrackerWithoutDelegate = function(assert, done) {
test.waitUntilDone();
const tabBrowser = require("sdk/deprecated/tab-browser"); const tabBrowser = require("sdk/deprecated/tab-browser");
openBrowserWindow(function(browserWindow, browser) { openBrowserWindow(function(browserWindow, browser) {
@ -185,26 +177,23 @@ exports.testTrackerWithoutDelegate = function(test) {
test.fail("expect at least one tab browser to exist."); test.fail("expect at least one tab browser to exist.");
for (var i = 0; i < tb.length; i++) for (var i = 0; i < tb.length; i++)
test.assertEqual(tb.get(i).nodeName, "tabbrowser", assert.equal(tb.get(i).nodeName, "tabbrowser",
"get() method and length prop should work"); "get() method and length prop should work");
for (var b in tb) for (var b in tb)
test.assertEqual(b.nodeName, "tabbrowser", assert.equal(b.nodeName, "tabbrowser",
"iterator should work"); "iterator should work");
var matches = [b for (b in tb) var matches = [b for (b in tb)
if (b == browser)]; if (b == browser)];
test.assertEqual(matches.length, 1, assert.equal(matches.length, 1,
"New browser should be in tracker."); "New browser should be in tracker.");
tb.unload(); tb.unload();
closeBrowserWindow(browserWindow, function() { closeBrowserWindow(browserWindow, done);
test.done();
});
}); });
}; };
exports.testTabTracker = function(test) { exports.testTabTracker = function(assert, done) {
test.waitUntilDone();
const tabBrowser = require("sdk/deprecated/tab-browser"); const tabBrowser = require("sdk/deprecated/tab-browser");
openBrowserWindow(function(browserWindow, browser) { openBrowserWindow(function(browserWindow, browser) {
@ -236,10 +225,10 @@ exports.testTabTracker = function(test) {
tabCount++; tabCount++;
if (tabCount == 3) { if (tabCount == 3) {
test.assertEqual(delegate.tracked, tracked + 3, "delegate tracked tabs matched count"); assert.equal(delegate.tracked, tracked + 3, "delegate tracked tabs matched count");
tabTracker.unload(); tabTracker.unload();
closeBrowserWindow(browserWindow, function() { closeBrowserWindow(browserWindow, function() {
timer.setTimeout(function() test.done(), 0); timer.setTimeout(done, 0);
}); });
} }
} }
@ -256,13 +245,12 @@ exports.testTabTracker = function(test) {
}); });
}; };
exports.testActiveTab = function(test) { exports.testActiveTab = function(assert, done) {
test.waitUntilDone();
openBrowserWindow(function(browserWindow, browser) { openBrowserWindow(function(browserWindow, browser) {
const tabBrowser = require("sdk/deprecated/tab-browser"); const tabBrowser = require("sdk/deprecated/tab-browser");
const TabModule = require("sdk/deprecated/tab-browser").TabModule; const TabModule = require("sdk/deprecated/tab-browser").TabModule;
let tm = new TabModule(browserWindow); let tm = new TabModule(browserWindow);
test.assertEqual(tm.length, 1); assert.equal(tm.length, 1);
let url1 = "data:text/html;charset=utf-8,foo"; let url1 = "data:text/html;charset=utf-8,foo";
let url2 = "data:text/html;charset=utf-8,bar"; let url2 = "data:text/html;charset=utf-8,bar";
@ -271,23 +259,21 @@ exports.testActiveTab = function(test) {
tabBrowser.addTab(url1, { tabBrowser.addTab(url1, {
onLoad: function(e) { onLoad: function(e) {
// make sure we're running in the right window. // make sure we're running in the right window.
test.assertEqual(tabBrowser.activeTab.ownerDocument.defaultView, browserWindow, "active window matches"); assert.equal(tabBrowser.activeTab.ownerDocument.defaultView, browserWindow, "active window matches");
browserWindow.focus(); browserWindow.focus();
test.assertEqual(tabURL(tabBrowser.activeTab), url1, "url1 matches"); assert.equal(tabURL(tabBrowser.activeTab), url1, "url1 matches");
let tabIndex = browser.getBrowserIndexForDocument(e.target); let tabIndex = browser.getBrowserIndexForDocument(e.target);
let tabAtIndex = browser.tabContainer.getItemAtIndex(tabIndex); let tabAtIndex = browser.tabContainer.getItemAtIndex(tabIndex);
test.assertEqual(tabAtIndex, tabBrowser.activeTab, "activeTab element matches"); assert.equal(tabAtIndex, tabBrowser.activeTab, "activeTab element matches");
tabBrowser.addTab(url2, { tabBrowser.addTab(url2, {
inBackground: true, inBackground: true,
onLoad: function() { onLoad: function() {
test.assertEqual(tabURL(tabBrowser.activeTab), url1, "url1 still matches"); assert.equal(tabURL(tabBrowser.activeTab), url1, "url1 still matches");
let tabAtIndex = browser.tabContainer.getItemAtIndex(tabIndex); let tabAtIndex = browser.tabContainer.getItemAtIndex(tabIndex);
test.assertEqual(tabAtIndex, tabBrowser.activeTab, "activeTab element matches"); assert.equal(tabAtIndex, tabBrowser.activeTab, "activeTab element matches");
closeBrowserWindow(browserWindow, function() { closeBrowserWindow(browserWindow, done);
test.done()
});
} }
}); });
} }
@ -296,8 +282,7 @@ exports.testActiveTab = function(test) {
}; };
// TabModule tests // TabModule tests
exports.testEventsAndLengthStayInModule = function(test) { exports.testEventsAndLengthStayInModule = function(assert, done) {
test.waitUntilDone();
let TabModule = require("sdk/deprecated/tab-browser").TabModule; let TabModule = require("sdk/deprecated/tab-browser").TabModule;
openTwoWindows(function(window1, window2) { openTwoWindows(function(window1, window2) {
@ -311,12 +296,12 @@ exports.testEventsAndLengthStayInModule = function(test) {
++counterTabs; ++counterTabs;
if (counterTabs < 5) if (counterTabs < 5)
return; return;
test.assertEqual(counter1, 2, "Correct number of events fired from window 1"); assert.equal(counter1, 2, "Correct number of events fired from window 1");
test.assertEqual(counter2, 3, "Correct number of events fired from window 2"); assert.equal(counter2, 3, "Correct number of events fired from window 2");
test.assertEqual(counterTabs, 5, "Correct number of events fired from all windows"); assert.equal(counterTabs, 5, "Correct number of events fired from all windows");
test.assertEqual(tm1.length, 3, "Correct number of tabs in window 1"); assert.equal(tm1.length, 3, "Correct number of tabs in window 1");
test.assertEqual(tm2.length, 4, "Correct number of tabs in window 2"); assert.equal(tm2.length, 4, "Correct number of tabs in window 2");
closeTwoWindows(window1, window2, function() test.done()); closeTwoWindows(window1, window2, done);
} }
tm1.onOpen = function() ++counter1 && onOpenListener(); tm1.onOpen = function() ++counter1 && onOpenListener();
@ -332,8 +317,7 @@ exports.testEventsAndLengthStayInModule = function(test) {
}); });
} }
exports.testTabModuleActiveTab_getterAndSetter = function(test) { exports.testTabModuleActiveTab_getterAndSetter = function(assert, done) {
test.waitUntilDone();
let TabModule = require("sdk/deprecated/tab-browser").TabModule; let TabModule = require("sdk/deprecated/tab-browser").TabModule;
openTwoWindows(function(window1, window2) { openTwoWindows(function(window1, window2) {
@ -366,19 +350,19 @@ exports.testTabModuleActiveTab_getterAndSetter = function(test) {
// Then try to activate tabs, but wait for all of them to be activated after // Then try to activate tabs, but wait for all of them to be activated after
// being opened // being opened
function onTabsOpened(tab1, tab2, tab3, tab4) { function onTabsOpened(tab1, tab2, tab3, tab4) {
test.assertEqual(tm1.activeTab.title, "window1,tab2", assert.equal(tm1.activeTab.title, "window1,tab2",
"Correct active tab on window 1"); "Correct active tab on window 1");
test.assertEqual(tm2.activeTab.title, "window2,tab2", assert.equal(tm2.activeTab.title, "window2,tab2",
"Correct active tab on window 2"); "Correct active tab on window 2");
tm1.onActivate = function onActivate() { tm1.onActivate = function onActivate() {
tm1.onActivate.remove(onActivate); tm1.onActivate.remove(onActivate);
timer.setTimeout(function() { timer.setTimeout(function() {
test.assertEqual(tm1.activeTab.title, "window1,tab1", assert.equal(tm1.activeTab.title, "window1,tab1",
"activeTab setter works (window 1)"); "activeTab setter works (window 1)");
test.assertEqual(tm2.activeTab.title, "window2,tab2", assert.equal(tm2.activeTab.title, "window2,tab2",
"activeTab is ignored with tabs from another window"); "activeTab is ignored with tabs from another window");
closeTwoWindows(window1, window2, function() test.done()); closeTwoWindows(window1, window2, done);
}, 1000); }, 1000);
} }
@ -391,8 +375,7 @@ exports.testTabModuleActiveTab_getterAndSetter = function(test) {
} }
// test tabs iterator // test tabs iterator
exports.testTabModuleTabsIterator = function(test) { exports.testTabModuleTabsIterator = function(assert, done) {
test.waitUntilDone();
let TabModule = require("sdk/deprecated/tab-browser").TabModule; let TabModule = require("sdk/deprecated/tab-browser").TabModule;
openBrowserWindow(function(window) { openBrowserWindow(function(window) {
@ -405,17 +388,16 @@ exports.testTabModuleTabsIterator = function(test) {
onOpen: function(tab) { onOpen: function(tab) {
let count = 0; let count = 0;
for each (let t in tm1) count++; for each (let t in tm1) count++;
test.assertEqual(count, 4, "iterated tab count matches"); assert.equal(count, 4, "iterated tab count matches");
test.assertEqual(count, tm1.length, "length tab count matches"); assert.equal(count, tm1.length, "length tab count matches");
closeBrowserWindow(window, function() test.done()); closeBrowserWindow(window, done);
} }
}); });
}); });
}; };
// inNewWindow parameter is ignored on single-window modules // inNewWindow parameter is ignored on single-window modules
exports.testTabModuleCantOpenInNewWindow = function(test) { exports.testTabModuleCantOpenInNewWindow = function(assert, done) {
test.waitUntilDone();
let TabModule = require("sdk/deprecated/tab-browser").TabModule; let TabModule = require("sdk/deprecated/tab-browser").TabModule;
openBrowserWindow(function(window) { openBrowserWindow(function(window) {
@ -425,8 +407,8 @@ exports.testTabModuleCantOpenInNewWindow = function(test) {
url: url, url: url,
inNewWindow: true, inNewWindow: true,
onOpen: function() { onOpen: function() {
test.assertEqual(tm.length, 2, "Tab was open on same window"); assert.equal(tm.length, 2, "Tab was open on same window");
closeBrowserWindow(window, function() test.done()); closeBrowserWindow(window, done);
} }
}); });
}); });
@ -434,10 +416,9 @@ exports.testTabModuleCantOpenInNewWindow = function(test) {
// Test that having two modules attached to the same // Test that having two modules attached to the same
// window won't duplicate events fired on each module // window won't duplicate events fired on each module
exports.testModuleListenersDontInteract = function(test) { exports.testModuleListenersDontInteract = function(assert, done) {
test.waitUntilDone();
let TabModule = require("sdk/deprecated/tab-browser").TabModule; let TabModule = require("sdk/deprecated/tab-browser").TabModule;
let onOpenTab;
openBrowserWindow(function(window) { openBrowserWindow(function(window) {
let tm1 = new TabModule(window); let tm1 = new TabModule(window);
let tm2 = new TabModule(window); let tm2 = new TabModule(window);
@ -451,43 +432,49 @@ exports.testModuleListenersDontInteract = function(test) {
// the url location is changed // the url location is changed
eventCount++; eventCount++;
eventModule1++; eventModule1++;
check();
} }
tm1.onReady = listener1; tm1.onReady = listener1;
tm2.open({ tm2.open({
url: "about:blank", url: "about:blank",
onOpen: function(tab) { onOpen: function(tab) {
onOpenTab = tab;
// add listener via property assignment // add listener via property assignment
let listener2 = function() {
eventCount++;
eventModule2++;
};
tab.onReady = listener2; tab.onReady = listener2;
// add listener via collection add // add listener via collection add
let listener3 = function() {
eventCount++;
eventModule2++;
};
tab.onReady.add(listener3); tab.onReady.add(listener3);
tab.location = url; tab.location = url;
test.waitUntilEqual(function () eventCount, 4,
"Correct global number of events")
.then(function () {
test.assertEqual(eventModule1, 2,
"Correct number of events on module 1");
test.assertEqual(eventModule2, 2,
"Correct number of events on module 2");
tm1.onReady.remove(listener1);
tab.onReady.remove(listener2);
tab.onReady.remove(listener3);
closeBrowserWindow(window, function() test.done());
});
} }
}); });
function listener2 () {
eventCount++;
eventModule2++;
check();
}
function listener3 () {
eventCount++;
eventModule2++;
check();
}
function check () {
if (eventCount !== 4) return;
assert.equal(eventModule1, 2,
"Correct number of events on module 1");
assert.equal(eventModule2, 2,
"Correct number of events on module 2");
tm1.onReady.remove(listener1);
onOpenTab.onReady.remove(listener2);
onOpenTab.onReady.remove(listener3);
closeBrowserWindow(window, done);
}
}); });
}; };
@ -499,3 +486,5 @@ function activeWindow() {
getService(Ci.nsIWindowMediator). getService(Ci.nsIWindowMediator).
getMostRecentWindow("navigator:browser"); getMostRecentWindow("navigator:browser");
} }
require('sdk/test').run(exports);

Просмотреть файл

@ -17,9 +17,7 @@ const app = require("sdk/system/xul-app");
const URL = 'data:text/html;charset=utf-8,<html><head><title>#title#</title></head></html>'; const URL = 'data:text/html;charset=utf-8,<html><head><title>#title#</title></head></html>';
// TEST: tab count // TEST: tab count
exports.testTabCounts = function(test) { exports.testTabCounts = function(assert, done) {
test.waitUntilDone();
tabs.open({ tabs.open({
url: 'about:blank', url: 'about:blank',
onReady: function(tab) { onReady: function(tab) {
@ -32,42 +30,38 @@ exports.testTabCounts = function(test) {
} }
} }
test.assert(tabs.length > 1, 'tab count is > 1'); assert.ok(tabs.length > 1, 'tab count is > 1');
test.assertEqual(count1, tabs.length, 'tab count by length is correct'); assert.equal(count1, tabs.length, 'tab count by length is correct');
test.assertEqual(count2, tabs.length, 'tab count by iteration is correct'); assert.equal(count2, tabs.length, 'tab count by iteration is correct');
// end test // end test
tab.close(function() test.done()); tab.close(done);
} }
}); });
}; };
// TEST: tabs.activeTab getter // TEST: tabs.activeTab getter
exports.testActiveTab_getter = function(test) { exports.testActiveTab_getter = function(assert, done) {
test.waitUntilDone();
let evtCount = 0; let evtCount = 0;
let activeTab = null; let activeTab = null;
function endTest(type, tab) { function endTest(type, tab) {
if (type == 'activate') { if (type == 'activate') {
test.assertStrictEqual(tabs.activeTab, tab, 'the active tab is the opened tab'); assert.strictEqual(tabs.activeTab, tab, 'the active tab is the opened tab');
activeTab = tabs.activeTab; activeTab = tabs.activeTab;
} }
else { else {
test.assertEqual(tab.url, url, 'the opened tab has the correct url'); assert.equal(tab.url, url, 'the opened tab has the correct url');
} }
if (++evtCount != 2) if (++evtCount != 2)
return; return;
test.assertStrictEqual(activeTab, tab, 'the active tab is the ready tab'); assert.strictEqual(activeTab, tab, 'the active tab is the ready tab');
test.assertStrictEqual(tabs.activeTab, tab, 'the active tab is the ready tab'); assert.strictEqual(tabs.activeTab, tab, 'the active tab is the ready tab');
tab.close(function() { tab.close(done);
// end test
test.done();
});
} }
let url = URL.replace("#title#", "testActiveTab_getter"); let url = URL.replace("#title#", "testActiveTab_getter");
@ -79,9 +73,7 @@ exports.testActiveTab_getter = function(test) {
}; };
// TEST: tab.activate() // TEST: tab.activate()
exports.testActiveTab_setter = function(test) { exports.testActiveTab_setter = function(assert, done) {
test.waitUntilDone();
let url = URL.replace("#title#", "testActiveTab_setter"); let url = URL.replace("#title#", "testActiveTab_setter");
let tab1URL = URL.replace("#title#", "tab1"); let tab1URL = URL.replace("#title#", "tab1");
@ -94,19 +86,16 @@ exports.testActiveTab_setter = function(test) {
url: url, url: url,
inBackground: true, inBackground: true,
onReady: function onReady(tab) { onReady: function onReady(tab) {
test.assertEqual(tabs.activeTab.url, activeTabURL, "activeTab url has not changed"); assert.equal(tabs.activeTab.url, activeTabURL, "activeTab url has not changed");
test.assertEqual(tab.url, url, "url of new background tab matches"); assert.equal(tab.url, url, "url of new background tab matches");
tab.once('activate', function onActivate(eventTab) { tab.once('activate', function onActivate(eventTab) {
test.assertEqual(tabs.activeTab.url, url, "url after activeTab setter matches"); assert.equal(tabs.activeTab.url, url, "url after activeTab setter matches");
test.assertEqual(eventTab, tab, "event argument is the activated tab"); assert.equal(eventTab, tab, "event argument is the activated tab");
test.assertEqual(eventTab, tabs.activeTab, "the tab is the active one"); assert.equal(eventTab, tabs.activeTab, "the tab is the active one");
activeTab.close(function() { activeTab.close(function() {
tab.close(function() { tab.close(done);
// end test
test.done();
});
}); });
}); });
@ -118,9 +107,7 @@ exports.testActiveTab_setter = function(test) {
}; };
// TEST: tab.close() // TEST: tab.close()
exports.testTabClose_alt = function(test) { exports.testTabClose_alt = function(assert, done) {
test.waitUntilDone();
let url = URL.replace('#title#', 'TabClose_alt'); let url = URL.replace('#title#', 'TabClose_alt');
let tab1URL = URL.replace('#title#', 'tab1'); let tab1URL = URL.replace('#title#', 'tab1');
@ -128,20 +115,20 @@ exports.testTabClose_alt = function(test) {
url: tab1URL, url: tab1URL,
onReady: function(tab1) { onReady: function(tab1) {
// make sure that our tab is not active first // make sure that our tab is not active first
test.assertNotEqual(tabs.activeTab.url, url, "tab is not the active tab"); assert.notEqual(tabs.activeTab.url, url, "tab is not the active tab");
tabs.open({ tabs.open({
url: url, url: url,
onReady: function(tab) { onReady: function(tab) {
test.assertEqual(tab.url, url, "tab is now the active tab"); assert.equal(tab.url, url, "tab is now the active tab");
test.assertEqual(tabs.activeTab.url, url, "tab is now the active tab"); assert.equal(tabs.activeTab.url, url, "tab is now the active tab");
// another tab should be activated on close // another tab should be activated on close
tabs.once('activate', function() { tabs.once('activate', function() {
test.assertNotEqual(tabs.activeTab.url, url, "tab is no longer the active tab"); assert.notEqual(tabs.activeTab.url, url, "tab is no longer the active tab");
// end test // end test
tab1.close(function() test.done()); tab1.close(done);
}); });
tab.close(); tab.close();
@ -151,30 +138,26 @@ exports.testTabClose_alt = function(test) {
}); });
}; };
exports.testAttachOnOpen_alt = function (test) { exports.testAttachOnOpen_alt = function (assert, done) {
// Take care that attach has to be called on tab ready and not on tab open. // Take care that attach has to be called on tab ready and not on tab open.
test.waitUntilDone();
tabs.open({ tabs.open({
url: "data:text/html;charset=utf-8,foobar", url: "data:text/html;charset=utf-8,foobar",
onOpen: function (tab) { onOpen: function (tab) {
let worker = tab.attach({ let worker = tab.attach({
contentScript: 'self.postMessage(document.location.href); ', contentScript: 'self.postMessage(document.location.href); ',
onMessage: function (msg) { onMessage: function (msg) {
test.assertEqual(msg, "about:blank", assert.equal(msg, "about:blank",
"Worker document url is about:blank on open"); "Worker document url is about:blank on open");
worker.destroy(); worker.destroy();
tab.close(function() test.done()); tab.close(done);
} }
}); });
} }
}); });
}; };
exports.testAttachOnMultipleDocuments_alt = function (test) { exports.testAttachOnMultipleDocuments_alt = function (assert, done) {
// Example of attach that process multiple tab documents // Example of attach that process multiple tab documents
test.waitUntilDone();
let firstLocation = "data:text/html;charset=utf-8,foobar"; let firstLocation = "data:text/html;charset=utf-8,foobar";
let secondLocation = "data:text/html;charset=utf-8,bar"; let secondLocation = "data:text/html;charset=utf-8,bar";
let thirdLocation = "data:text/html;charset=utf-8,fox"; let thirdLocation = "data:text/html;charset=utf-8,fox";
@ -193,14 +176,14 @@ exports.testAttachOnMultipleDocuments_alt = function (test) {
' function () self.postMessage(document.location.href)' + ' function () self.postMessage(document.location.href)' +
');', ');',
onMessage: function (msg) { onMessage: function (msg) {
test.assertEqual(msg, firstLocation, assert.equal(msg, firstLocation,
"Worker url is equal to the 1st document"); "Worker url is equal to the 1st document");
tab.url = secondLocation; tab.url = secondLocation;
}, },
onDetach: function () { onDetach: function () {
detachEventCount++; detachEventCount++;
test.pass("Got worker1 detach event"); assert.pass("Got worker1 detach event");
test.assertRaises(function () { assert.throws(function () {
worker1.postMessage("ex-1"); worker1.postMessage("ex-1");
}, },
/Couldn't find the worker/, /Couldn't find the worker/,
@ -216,14 +199,14 @@ exports.testAttachOnMultipleDocuments_alt = function (test) {
' function () self.postMessage(document.location.href)' + ' function () self.postMessage(document.location.href)' +
');', ');',
onMessage: function (msg) { onMessage: function (msg) {
test.assertEqual(msg, secondLocation, assert.equal(msg, secondLocation,
"Worker url is equal to the 2nd document"); "Worker url is equal to the 2nd document");
tab.url = thirdLocation; tab.url = thirdLocation;
}, },
onDetach: function () { onDetach: function () {
detachEventCount++; detachEventCount++;
test.pass("Got worker2 detach event"); assert.pass("Got worker2 detach event");
test.assertRaises(function () { assert.throws(function () {
worker2.postMessage("ex-2"); worker2.postMessage("ex-2");
}, },
/Couldn't find the worker/, /Couldn't find the worker/,
@ -243,16 +226,14 @@ exports.testAttachOnMultipleDocuments_alt = function (test) {
if (detachEventCount != 2) if (detachEventCount != 2)
return; return;
test.pass("Got all detach events"); assert.pass("Got all detach events");
// end test done();
test.done();
} }
}; };
exports.testAttachWrappers_alt = function (test) { exports.testAttachWrappers_alt = function (assert, done) {
// Check that content script has access to wrapped values by default // Check that content script has access to wrapped values by default
test.waitUntilDone();
let document = "data:text/html;charset=utf-8,<script>var globalJSVar = true; " + let document = "data:text/html;charset=utf-8,<script>var globalJSVar = true; " +
" document.getElementById = 3;</script>"; " document.getElementById = 3;</script>";
@ -269,9 +250,9 @@ exports.testAttachWrappers_alt = function (test) {
' self.postMessage(e.message);' + ' self.postMessage(e.message);' +
'}', '}',
onMessage: function (msg) { onMessage: function (msg) {
test.assertEqual(msg, true, "Worker has wrapped objects ("+count+")"); assert.equal(msg, true, "Worker has wrapped objects ("+count+")");
if (count++ == 1) if (count++ == 1)
tab.close(function() test.done()); tab.close(function() done());
} }
}); });
} }
@ -279,15 +260,14 @@ exports.testAttachWrappers_alt = function (test) {
}; };
// TEST: activeWindow getter and activeTab getter on tab 'activate' event // TEST: activeWindow getter and activeTab getter on tab 'activate' event
exports.testActiveWindowActiveTabOnActivate_alt = function(test) { exports.testActiveWindowActiveTabOnActivate_alt = function(assert, done) {
test.waitUntilDone();
let activateCount = 0; let activateCount = 0;
let newTabs = []; let newTabs = [];
let tabs = browserWindows.activeWindow.tabs; let tabs = browserWindows.activeWindow.tabs;
tabs.on('activate', function onActivate(tab) { tabs.on('activate', function onActivate(tab) {
test.assertEqual(tabs.activeTab, tab, assert.equal(tabs.activeTab, tab,
"the active window's active tab is the tab provided"); "the active window's active tab is the tab provided");
if (++activateCount == 2) { if (++activateCount == 2) {
@ -296,14 +276,13 @@ exports.testActiveWindowActiveTabOnActivate_alt = function(test) {
newTabs.forEach(function(tab) { newTabs.forEach(function(tab) {
tab.close(function() { tab.close(function() {
if (--activateCount == 0) { if (--activateCount == 0) {
// end test done();
test.done();
} }
}); });
}); });
} }
else if (activateCount > 2) { else if (activateCount > 2) {
test.fail("activateCount is greater than 2 for some reason.."); assert.fail("activateCount is greater than 2 for some reason..");
} }
}); });
@ -318,8 +297,7 @@ exports.testActiveWindowActiveTabOnActivate_alt = function(test) {
}; };
// TEST: tab properties // TEST: tab properties
exports.testTabContentTypeAndReload = function(test) { exports.testTabContentTypeAndReload = function(assert, done) {
test.waitUntilDone();
let url = "data:text/html;charset=utf-8,<html><head><title>foo</title></head><body>foo</body></html>"; let url = "data:text/html;charset=utf-8,<html><head><title>foo</title></head><body>foo</body></html>";
let urlXML = "data:text/xml;charset=utf-8,<foo>bar</foo>"; let urlXML = "data:text/xml;charset=utf-8,<foo>bar</foo>";
@ -327,61 +305,55 @@ exports.testTabContentTypeAndReload = function(test) {
url: url, url: url,
onReady: function(tab) { onReady: function(tab) {
if (tab.url === url) { if (tab.url === url) {
test.assertEqual(tab.contentType, "text/html"); assert.equal(tab.contentType, "text/html");
tab.url = urlXML; tab.url = urlXML;
} }
else { else {
test.assertEqual(tab.contentType, "text/xml"); assert.equal(tab.contentType, "text/xml");
tab.close(function() { tab.close(done);
test.done();
});
} }
} }
}); });
}; };
// test that it isn't possible to open a private tab without the private permission // test that it isn't possible to open a private tab without the private permission
exports.testTabOpenPrivate = function(test) { exports.testTabOpenPrivate = function(assert, done) {
test.waitUntilDone();
let url = 'about:blank'; let url = 'about:blank';
tabs.open({ tabs.open({
url: url, url: url,
isPrivate: true, isPrivate: true,
onReady: function(tab) { onReady: function(tab) {
test.assertEqual(tab.url, url, 'opened correct tab'); assert.equal(tab.url, url, 'opened correct tab');
test.assertEqual(isPrivate(tab), false, 'private tabs are not supported by default'); assert.equal(isPrivate(tab), false, 'private tabs are not supported by default');
tab.close(function() { tab.close(done);
test.done();
});
} }
}); });
} }
// We need permission flag in order to see private window's tabs // We need permission flag in order to see private window's tabs
exports.testPrivateAreNotListed = function (test) { exports.testPrivateAreNotListed = function (assert, done) {
let originalTabCount = tabs.length; let originalTabCount = tabs.length;
let page = openWebpage("about:blank", true); let page = openWebpage("about:blank", true);
if (!page) { if (!page) {
test.pass("Private browsing isn't supported in this release"); assert.pass("Private browsing isn't supported in this release");
return; return;
} }
test.waitUntilDone();
page.ready.then(function (win) { page.ready.then(function (win) {
if (isTabPBSupported || isWindowPBSupported) { if (isTabPBSupported || isWindowPBSupported) {
test.assert(isWindowPrivate(win), "the window is private"); assert.ok(isWindowPrivate(win), "the window is private");
test.assertEqual(tabs.length, originalTabCount, assert.equal(tabs.length, originalTabCount,
'but the tab is *not* visible in tabs list'); 'but the tab is *not* visible in tabs list');
} }
else { else {
test.assert(!isWindowPrivate(win), "the window isn't private"); assert.ok(!isWindowPrivate(win), "the window isn't private");
test.assertEqual(tabs.length, originalTabCount + 1, assert.equal(tabs.length, originalTabCount + 1,
'so that the tab is visible is tabs list'); 'so that the tab is visible is tabs list');
} }
page.close().then(test.done.bind(test)); page.close().then(done);
}); });
} }
@ -389,9 +361,7 @@ exports.testPrivateAreNotListed = function (test) {
// we end up synchronously consuming TabOpen, closing the tab and still // we end up synchronously consuming TabOpen, closing the tab and still
// synchronously consuming the related TabClose event before the second // synchronously consuming the related TabClose event before the second
// loader have a change to process the first TabOpen event! // loader have a change to process the first TabOpen event!
exports.testImmediateClosing = function (test) { exports.testImmediateClosing = function (assert, done) {
test.waitUntilDone();
let tabURL = 'data:text/html,foo'; let tabURL = 'data:text/html,foo';
let { loader, messages } = LoaderWithHookedConsole(module, onMessage); let { loader, messages } = LoaderWithHookedConsole(module, onMessage);
@ -401,30 +371,30 @@ exports.testImmediateClosing = function (test) {
// open and destroy the tab without giving a chance to other loader to even // open and destroy the tab without giving a chance to other loader to even
// know about the existance of this tab. // know about the existance of this tab.
if (app.is("Firefox")) { if (app.is("Firefox")) {
test.fail("Concurrent loader received a tabs `open` event"); assert.fail("Concurrent loader received a tabs `open` event");
} }
else { else {
// On mobile, we can still receive an open event, // On mobile, we can still receive an open event,
// but not the related ready event // but not the related ready event
tab.on("ready", function () { tab.on("ready", function () {
test.fail("Concurrent loader received a tabs `ready` event"); assert.fail("Concurrent loader received a tabs `ready` event");
}); });
} }
}); });
function onMessage(type, msg) { function onMessage(type, msg) {
test.fail("Unexpected mesage on concurrent loader: " + msg); assert.fail("Unexpected mesage on concurrent loader: " + msg);
} }
tabs.open({ tabs.open({
url: tabURL, url: tabURL,
onOpen: function(tab) { onOpen: function(tab) {
tab.close(function () { tab.close(function () {
test.pass("Tab succesfully removed"); assert.pass("Tab succesfully removed");
// Let a chance to the concurrent loader to receive a TabOpen event // Let a chance to the concurrent loader to receive a TabOpen event
// on the next event loop turn // on the next event loop turn
setTimeout(function () { setTimeout(function () {
loader.unload(); loader.unload();
test.done(); done();
}, 0); }, 0);
}); });
} }
@ -432,8 +402,7 @@ exports.testImmediateClosing = function (test) {
} }
// TEST: tab.reload() // TEST: tab.reload()
exports.testTabReload = function(test) { exports.testTabReload = function(assert, done) {
test.waitUntilDone();
let url = "data:text/html;charset=utf-8,<!doctype%20html><title></title>"; let url = "data:text/html;charset=utf-8,<!doctype%20html><title></title>";
@ -445,11 +414,10 @@ exports.testTabReload = function(test) {
tab.once( tab.once(
'ready', 'ready',
function onReload() { function onReload() {
test.pass("the tab was loaded again"); assert.pass("the tab was loaded again");
test.assertEqual(tab.url, url, "the tab has the same URL"); assert.equal(tab.url, url, "the tab has the same URL");
// end test tab.close(function() done());
tab.close(function() test.done());
} }
); );
@ -458,9 +426,7 @@ exports.testTabReload = function(test) {
}); });
}; };
exports.testOnPageShowEvent = function (test) { exports.testOnPageShowEvent = function (assert, done) {
test.waitUntilDone();
let events = []; let events = [];
let firstUrl = 'data:text/html;charset=utf-8,First'; let firstUrl = 'data:text/html;charset=utf-8,First';
let secondUrl = 'data:text/html;charset=utf-8,Second'; let secondUrl = 'data:text/html;charset=utf-8,Second';
@ -470,17 +436,17 @@ exports.testOnPageShowEvent = function (test) {
events.push('pageshow'); events.push('pageshow');
counter++; counter++;
if (counter === 1) { if (counter === 1) {
test.assertEqual(persisted, false, 'page should not be cached on initial load'); assert.equal(persisted, false, 'page should not be cached on initial load');
tab.url = secondUrl; tab.url = secondUrl;
} }
else if (counter === 2) { else if (counter === 2) {
test.assertEqual(persisted, false, 'second test page should not be cached either'); assert.equal(persisted, false, 'second test page should not be cached either');
tab.attach({ tab.attach({
contentScript: 'setTimeout(function () { window.history.back(); }, 0)' contentScript: 'setTimeout(function () { window.history.back(); }, 0)'
}); });
} }
else { else {
test.assertEqual(persisted, true, 'when we get back to the fist page, it has to' + assert.equal(persisted, true, 'when we get back to the fist page, it has to' +
'come from cache'); 'come from cache');
tabs.removeListener('pageshow', onPageShow); tabs.removeListener('pageshow', onPageShow);
tabs.removeListener('open', onOpen); tabs.removeListener('open', onOpen);
@ -488,9 +454,9 @@ exports.testOnPageShowEvent = function (test) {
tab.close(() => { tab.close(() => {
['open', 'ready', 'pageshow', 'ready', ['open', 'ready', 'pageshow', 'ready',
'pageshow', 'pageshow'].map((type, i) => { 'pageshow', 'pageshow'].map((type, i) => {
test.assertEqual(type, events[i], 'correct ordering of events'); assert.equal(type, events[i], 'correct ordering of events');
}); });
test.done() done()
}); });
} }
} }
@ -506,9 +472,7 @@ exports.testOnPageShowEvent = function (test) {
}); });
}; };
exports.testOnPageShowEventDeclarative = function (test) { exports.testOnPageShowEventDeclarative = function (assert, done) {
test.waitUntilDone();
let events = []; let events = [];
let firstUrl = 'data:text/html;charset=utf-8,First'; let firstUrl = 'data:text/html;charset=utf-8,First';
let secondUrl = 'data:text/html;charset=utf-8,Second'; let secondUrl = 'data:text/html;charset=utf-8,Second';
@ -518,17 +482,17 @@ exports.testOnPageShowEventDeclarative = function (test) {
events.push('pageshow'); events.push('pageshow');
counter++; counter++;
if (counter === 1) { if (counter === 1) {
test.assertEqual(persisted, false, 'page should not be cached on initial load'); assert.equal(persisted, false, 'page should not be cached on initial load');
tab.url = secondUrl; tab.url = secondUrl;
} }
else if (counter === 2) { else if (counter === 2) {
test.assertEqual(persisted, false, 'second test page should not be cached either'); assert.equal(persisted, false, 'second test page should not be cached either');
tab.attach({ tab.attach({
contentScript: 'setTimeout(function () { window.history.back(); }, 0)' contentScript: 'setTimeout(function () { window.history.back(); }, 0)'
}); });
} }
else { else {
test.assertEqual(persisted, true, 'when we get back to the fist page, it has to' + assert.equal(persisted, true, 'when we get back to the fist page, it has to' +
'come from cache'); 'come from cache');
tabs.removeListener('pageshow', onPageShow); tabs.removeListener('pageshow', onPageShow);
tabs.removeListener('open', onOpen); tabs.removeListener('open', onOpen);
@ -536,9 +500,9 @@ exports.testOnPageShowEventDeclarative = function (test) {
tab.close(() => { tab.close(() => {
['open', 'ready', 'pageshow', 'ready', ['open', 'ready', 'pageshow', 'ready',
'pageshow', 'pageshow'].map((type, i) => { 'pageshow', 'pageshow'].map((type, i) => {
test.assertEqual(type, events[i], 'correct ordering of events'); assert.equal(type, events[i], 'correct ordering of events');
}); });
test.done() done()
}); });
} }
} }
@ -554,3 +518,4 @@ exports.testOnPageShowEventDeclarative = function (test) {
}); });
}; };
require('sdk/test').run(exports);

Просмотреть файл

@ -0,0 +1,46 @@
/* 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 { setTimeout } = require('sdk/timers');
const { waitUntil } = require('sdk/test/utils');
exports.testWaitUntil = function (assert, done) {
let bool = false;
let finished = false;
waitUntil(() => {
if (finished)
assert.fail('interval should be cleared after predicate is truthy');
return bool;
}).then(function () {
assert.ok(bool,
'waitUntil shouldn\'t call until predicate is truthy');
finished = true;
done();
});
setTimeout(() => { bool = true; }, 20);
};
exports.testWaitUntilInterval = function (assert, done) {
let bool = false;
let finished = false;
let counter = 0;
waitUntil(() => {
if (finished)
assert.fail('interval should be cleared after predicate is truthy');
counter++;
return bool;
}, 50).then(function () {
assert.ok(bool,
'waitUntil shouldn\'t call until predicate is truthy');
assert.equal(counter, 1,
'predicate should only be called once with a higher interval');
finished = true;
done();
});
setTimeout(() => { bool = true; }, 10);
};
require('sdk/test').run(exports);

Просмотреть файл

@ -6,41 +6,41 @@ const file = require("sdk/io/file");
const { pathFor } = require("sdk/system"); const { pathFor } = require("sdk/system");
const { Loader } = require("sdk/test/loader"); const { Loader } = require("sdk/test/loader");
const STREAM_CLOSED_ERROR = "The stream is closed and cannot be used."; const STREAM_CLOSED_ERROR = new RegExp("The stream is closed and cannot be used.");
// This should match the constant of the same name in text-streams.js. // This should match the constant of the same name in text-streams.js.
const BUFFER_BYTE_LEN = 0x8000; const BUFFER_BYTE_LEN = 0x8000;
exports.testWriteRead = function (test) { exports.testWriteRead = function (assert) {
let fname = dataFileFilename(); let fname = dataFileFilename();
// Write a small string less than the stream's buffer size... // Write a small string less than the stream's buffer size...
let str = "exports.testWriteRead data!"; let str = "exports.testWriteRead data!";
let stream = file.open(fname, "w"); let stream = file.open(fname, "w");
test.assert(!stream.closed, "stream.closed after open should be false"); assert.ok(!stream.closed, "stream.closed after open should be false");
stream.write(str); stream.write(str);
stream.close(); stream.close();
test.assert(stream.closed, "stream.closed after close should be true"); assert.ok(stream.closed, "stream.closed after close should be true");
test.assertRaises(function () stream.close(), assert.throws(function () stream.close(),
STREAM_CLOSED_ERROR, STREAM_CLOSED_ERROR,
"stream.close after already closed should raise error"); "stream.close after already closed should raise error");
test.assertRaises(function () stream.write("This shouldn't be written!"), assert.throws(function () stream.write("This shouldn't be written!"),
STREAM_CLOSED_ERROR, STREAM_CLOSED_ERROR,
"stream.write after close should raise error"); "stream.write after close should raise error");
// ... and read it. // ... and read it.
stream = file.open(fname); stream = file.open(fname);
test.assert(!stream.closed, "stream.closed after open should be false"); assert.ok(!stream.closed, "stream.closed after open should be false");
test.assertEqual(stream.read(), str, assert.equal(stream.read(), str,
"stream.read should return string written"); "stream.read should return string written");
test.assertEqual(stream.read(), "", assert.equal(stream.read(), "",
"stream.read at EOS should return empty string"); "stream.read at EOS should return empty string");
stream.close(); stream.close();
test.assert(stream.closed, "stream.closed after close should be true"); assert.ok(stream.closed, "stream.closed after close should be true");
test.assertRaises(function () stream.close(), assert.throws(function () stream.close(),
STREAM_CLOSED_ERROR, STREAM_CLOSED_ERROR,
"stream.close after already closed should raise error"); "stream.close after already closed should raise error");
test.assertRaises(function () stream.read(), assert.throws(function () stream.read(),
STREAM_CLOSED_ERROR, STREAM_CLOSED_ERROR,
"stream.read after close should raise error"); "stream.read after close should raise error");
@ -56,7 +56,7 @@ exports.testWriteRead = function (test) {
stream.write(str); stream.write(str);
stream.close(); stream.close();
stream = file.open(fname); stream = file.open(fname);
test.assertEqual(stream.read(), str, assert.equal(stream.read(), str,
"stream.read should return string written"); "stream.read should return string written");
stream.close(); stream.close();
@ -79,24 +79,24 @@ exports.testWriteRead = function (test) {
readStr += frag; readStr += frag;
} while (frag); } while (frag);
stream.close(); stream.close();
test.assertEqual(readStr, str, assert.equal(readStr, str,
"stream.write and read in chunks should work as expected"); "stream.write and read in chunks should work as expected");
// Read the same file, passing in strange numbers of bytes to read. // Read the same file, passing in strange numbers of bytes to read.
stream = file.open(fname); stream = file.open(fname);
test.assertEqual(stream.read(fileSize * 100), str, assert.equal(stream.read(fileSize * 100), str,
"stream.read with big byte length should return string " + "stream.read with big byte length should return string " +
"written"); "written");
stream.close(); stream.close();
stream = file.open(fname); stream = file.open(fname);
test.assertEqual(stream.read(0), "", assert.equal(stream.read(0), "",
"string.read with zero byte length should return empty " + "string.read with zero byte length should return empty " +
"string"); "string");
stream.close(); stream.close();
stream = file.open(fname); stream = file.open(fname);
test.assertEqual(stream.read(-1), "", assert.equal(stream.read(-1), "",
"string.read with negative byte length should return " + "string.read with negative byte length should return " +
"empty string"); "empty string");
stream.close(); stream.close();
@ -104,40 +104,38 @@ exports.testWriteRead = function (test) {
file.remove(fname); file.remove(fname);
}; };
exports.testWriteAsync = function (test) { exports.testWriteAsync = function (assert, done) {
test.waitUntilDone();
let fname = dataFileFilename(); let fname = dataFileFilename();
let str = "exports.testWriteAsync data!"; let str = "exports.testWriteAsync data!";
let stream = file.open(fname, "w"); let stream = file.open(fname, "w");
test.assert(!stream.closed, "stream.closed after open should be false"); assert.ok(!stream.closed, "stream.closed after open should be false");
// Write. // Write.
stream.writeAsync(str, function (err) { stream.writeAsync(str, function (err) {
test.assertEqual(this, stream, "|this| should be the stream object"); assert.equal(this, stream, "|this| should be the stream object");
test.assertEqual(err, undefined, assert.equal(err, undefined,
"stream.writeAsync should not cause error"); "stream.writeAsync should not cause error");
test.assert(stream.closed, "stream.closed after write should be true"); assert.ok(stream.closed, "stream.closed after write should be true");
test.assertRaises(function () stream.close(), assert.throws(function () stream.close(),
STREAM_CLOSED_ERROR, STREAM_CLOSED_ERROR,
"stream.close after already closed should raise error"); "stream.close after already closed should raise error");
test.assertRaises(function () stream.writeAsync("This shouldn't work!"), assert.throws(function () stream.writeAsync("This shouldn't work!"),
STREAM_CLOSED_ERROR, STREAM_CLOSED_ERROR,
"stream.writeAsync after close should raise error"); "stream.writeAsync after close should raise error");
// Read. // Read.
stream = file.open(fname, "r"); stream = file.open(fname, "r");
test.assert(!stream.closed, "stream.closed after open should be false"); assert.ok(!stream.closed, "stream.closed after open should be false");
let readStr = stream.read(); let readStr = stream.read();
test.assertEqual(readStr, str, assert.equal(readStr, str,
"string.read should yield string written"); "string.read should yield string written");
stream.close(); stream.close();
file.remove(fname); file.remove(fname);
test.done(); done();
}); });
}; };
exports.testUnload = function (test) { exports.testUnload = function (assert) {
let loader = Loader(module); let loader = Loader(module);
let file = loader.require("sdk/io/file"); let file = loader.require("sdk/io/file");
@ -145,10 +143,12 @@ exports.testUnload = function (test) {
let stream = file.open(filename, "w"); let stream = file.open(filename, "w");
loader.unload(); loader.unload();
test.assert(stream.closed, "stream should be closed after module unload"); assert.ok(stream.closed, "stream should be closed after module unload");
}; };
// Returns the name of a file that should be used to test writing and reading. // Returns the name of a file that should be used to test writing and reading.
function dataFileFilename() { function dataFileFilename() {
return file.join(pathFor("ProfD"), "test-text-streams-data"); return file.join(pathFor("ProfD"), "test-text-streams-data");
} }
require('sdk/test').run(exports);

Просмотреть файл

@ -15,7 +15,7 @@ function throwError() {
throw new Error("foob"); throw new Error("foob");
} }
exports.testFormatDoesNotFetchRemoteFiles = function(test) { exports.testFormatDoesNotFetchRemoteFiles = function(assert) {
var observers = require("sdk/deprecated/observer-service"); var observers = require("sdk/deprecated/observer-service");
["http", "https"].forEach( ["http", "https"].forEach(
function(scheme) { function(scheme) {
@ -32,75 +32,75 @@ exports.testFormatDoesNotFetchRemoteFiles = function(test) {
name: "blah"}]; name: "blah"}];
traceback.format(tb); traceback.format(tb);
} catch (e) { } catch (e) {
test.exception(e); assert.fail(e);
} }
observers.remove("http-on-modify-request", onHttp); observers.remove("http-on-modify-request", onHttp);
test.assertEqual(httpRequests, 0, assert.equal(httpRequests, 0,
"traceback.format() does not make " + "traceback.format() does not make " +
scheme + " request"); scheme + " request");
}); });
}; };
exports.testFromExceptionWithString = function(test) { exports.testFromExceptionWithString = function(assert) {
try { try {
throw "foob"; throw "foob";
test.fail("an exception should've been thrown"); assert.fail("an exception should've been thrown");
} catch (e if e == "foob") { } catch (e if e == "foob") {
var tb = traceback.fromException(e); var tb = traceback.fromException(e);
test.assertEqual(tb.length, 0); assert.equal(tb.length, 0);
} }
}; };
exports.testFormatWithString = function(test) { exports.testFormatWithString = function(assert) {
// This can happen if e.g. a thrown exception was // This can happen if e.g. a thrown exception was
// a string instead of an Error instance. // a string instead of an Error instance.
test.assertEqual(traceback.format("blah"), assert.equal(traceback.format("blah"),
"Traceback (most recent call last):"); "Traceback (most recent call last):");
}; };
exports.testFromExceptionWithError = function(test) { exports.testFromExceptionWithError = function(assert) {
try { try {
throwError(); throwError();
test.fail("an exception should've been thrown"); assert.fail("an exception should've been thrown");
} catch (e if e instanceof Error) { } catch (e if e instanceof Error) {
var tb = traceback.fromException(e); var tb = traceback.fromException(e);
var xulApp = require("sdk/system/xul-app"); var xulApp = require("sdk/system/xul-app");
test.assertEqual(tb.slice(-1)[0].name, "throwError"); assert.equal(tb.slice(-1)[0].name, "throwError");
} }
}; };
exports.testFromExceptionWithNsIException = function(test) { exports.testFromExceptionWithNsIException = function(assert) {
try { try {
throwNsIException(); throwNsIException();
test.fail("an exception should've been thrown"); assert.fail("an exception should've been thrown");
} catch (e if e.result == Cr.NS_ERROR_MALFORMED_URI) { } catch (e if e.result == Cr.NS_ERROR_MALFORMED_URI) {
var tb = traceback.fromException(e); var tb = traceback.fromException(e);
test.assertEqual(tb[tb.length - 1].name, "throwNsIException"); assert.equal(tb[tb.length - 1].name, "throwNsIException");
} }
}; };
exports.testFormat = function(test) { exports.testFormat = function(assert) {
function getTraceback() { function getTraceback() {
return traceback.format(); return traceback.format();
} }
var formatted = getTraceback(); var formatted = getTraceback();
test.assertEqual(typeof(formatted), "string"); assert.equal(typeof(formatted), "string");
var lines = formatted.split("\n"); var lines = formatted.split("\n");
test.assertEqual(lines[lines.length - 2].indexOf("getTraceback") > 0, assert.equal(lines[lines.length - 2].indexOf("getTraceback") > 0,
true, true,
"formatted traceback should include function name"); "formatted traceback should include function name");
test.assertEqual(lines[lines.length - 1].trim(), assert.equal(lines[lines.length - 1].trim(),
"return traceback.format();", "return traceback.format();",
"formatted traceback should include source code"); "formatted traceback should include source code");
}; };
exports.testExceptionsWithEmptyStacksAreLogged = function(test) { exports.testExceptionsWithEmptyStacksAreLogged = function(assert) {
// Ensures that our fix to bug 550368 works. // Ensures that our fix to bug 550368 works.
var sandbox = Cu.Sandbox("http://www.foo.com"); var sandbox = Cu.Sandbox("http://www.foo.com");
var excRaised = false; var excRaised = false;
@ -110,12 +110,14 @@ exports.testExceptionsWithEmptyStacksAreLogged = function(test) {
} catch (e) { } catch (e) {
excRaised = true; excRaised = true;
var stack = traceback.fromException(e); var stack = traceback.fromException(e);
test.assertEqual(stack.length, 1, "stack should have one frame"); assert.equal(stack.length, 1, "stack should have one frame");
test.assert(stack[0].fileName, "blah.js", "frame should have filename"); assert.ok(stack[0].fileName, "blah.js", "frame should have filename");
test.assert(stack[0].lineNumber, 25, "frame should have line no"); assert.ok(stack[0].lineNumber, 25, "frame should have line no");
test.assertEqual(stack[0].name, null, "frame should have null function name"); assert.equal(stack[0].name, null, "frame should have null function name");
} }
if (!excRaised) if (!excRaised)
test.fail("Exception should have been raised."); assert.fail("Exception should have been raised.");
}; };
require('sdk/test').run(exports);

Просмотреть файл

@ -6,7 +6,7 @@
const { Trait } = require('sdk/deprecated/traits'); const { Trait } = require('sdk/deprecated/traits');
exports['test:simple compose'] = function(test) { exports['test:simple compose'] = function(assert) {
let List = Trait.compose({ let List = Trait.compose({
_list: null, _list: null,
constructor: function List() { constructor: function List() {
@ -21,35 +21,35 @@ exports['test:simple compose'] = function(test) {
} }
}); });
test.assertNotEqual(undefined, List, 'should not be undefined'); assert.notEqual(undefined, List, 'should not be undefined');
test.assertEqual('function', typeof List, 'type should be function'); assert.equal('function', typeof List, 'type should be function');
test.assertEqual( assert.equal(
Trait.compose, Trait.compose,
List.compose, List.compose,
'should inherit static compose' 'should inherit static compose'
); );
test.assertEqual( assert.equal(
Trait.override, Trait.override,
List.override, List.override,
'should inherit static override' 'should inherit static override'
); );
test.assertEqual( assert.equal(
Trait.required, Trait.required,
List.required, List.required,
'should inherit static required' 'should inherit static required'
); );
test.assertEqual( assert.equal(
Trait.resolve, Trait.resolve,
List.resolve, List.resolve,
'should inherit static resolve' 'should inherit static resolve'
); );
test.assert( assert.ok(
!('_list' in List.prototype), !('_list' in List.prototype),
'should not expose private API' 'should not expose private API'
); );
} }
exports['test: compose trait instance and create instance'] = function(test) { exports['test: compose trait instance and create instance'] = function(assert) {
let List = Trait.compose({ let List = Trait.compose({
constructor: function List(options) { constructor: function List(options) {
this._list = []; this._list = [];
@ -67,20 +67,20 @@ exports['test: compose trait instance and create instance'] = function(test) {
}); });
let list = List({ publicMember: true }); let list = List({ publicMember: true });
test.assertEqual('object', typeof list, 'should return an object') assert.equal('object', typeof list, 'should return an object')
test.assertEqual( assert.equal(
true, true,
list instanceof List, list instanceof List,
'should be instance of a List' 'should be instance of a List'
); );
test.assertEqual( assert.equal(
undefined, undefined,
list._privateMember, list._privateMember,
'instance should not expose private API' 'instance should not expose private API'
); );
test.assertEqual( assert.equal(
true, true,
list.privateMember, list.privateMember,
'privates are accessible by public API' 'privates are accessible by public API'
@ -88,35 +88,35 @@ exports['test: compose trait instance and create instance'] = function(test) {
list._privateMember = false; list._privateMember = false;
test.assertEqual( assert.equal(
true, true,
list.privateMember, list.privateMember,
'property changes on instance must not affect privates' 'property changes on instance must not affect privates'
); );
test.assert( assert.ok(
!('_list' in list), !('_list' in list),
'instance should not expose private members' 'instance should not expose private members'
); );
test.assertEqual( assert.equal(
true, true,
list.publicMember, list.publicMember,
'public members are exposed' 'public members are exposed'
) )
test.assertEqual( assert.equal(
'function', 'function',
typeof list.add, typeof list.add,
'should be function' 'should be function'
) )
test.assertEqual( assert.equal(
'function', 'function',
typeof list.remove, typeof list.remove,
'should be function' 'should be function'
); );
list.add(1); list.add(1);
test.assertEqual( assert.equal(
1, 1,
list.list[0], list.list[0],
'exposed public API should be able of modifying privates' 'exposed public API should be able of modifying privates'
@ -124,7 +124,7 @@ exports['test: compose trait instance and create instance'] = function(test) {
}; };
exports['test:instances must not be hackable'] = function(test) { exports['test:instances must not be hackable'] = function(assert) {
let SECRET = 'There is no secret!', let SECRET = 'There is no secret!',
secret = null; secret = null;
@ -136,7 +136,7 @@ exports['test:instances must not be hackable'] = function(test) {
let i1 = Class(); let i1 = Class();
i1.protect(SECRET); i1.protect(SECRET);
test.assertEqual( assert.equal(
undefined, undefined,
(function() this._secret).call(i1), (function() this._secret).call(i1),
'call / apply can\'t access private state' 'call / apply can\'t access private state'
@ -147,7 +147,7 @@ exports['test:instances must not be hackable'] = function(test) {
proto.reveal = function() this._secret; proto.reveal = function() this._secret;
secret = i1.reveal(); secret = i1.reveal();
} catch(e) {} } catch(e) {}
test.assertNotEqual( assert.notEqual(
SECRET, SECRET,
secret, secret,
'public __proto__ changes should not affect privates' 'public __proto__ changes should not affect privates'
@ -164,14 +164,14 @@ exports['test:instances must not be hackable'] = function(test) {
Object.prototype.reveal = function() this._secret; Object.prototype.reveal = function() this._secret;
secret = i2.reveal(); secret = i2.reveal();
} catch(e) {} } catch(e) {}
test.assertNotEqual( assert.notEqual(
SECRET, SECRET,
secret, secret,
'Object.prototype changes must not affect instances' 'Object.prototype changes must not affect instances'
); );
} }
exports['test:instanceof'] = function(test) { exports['test:instanceof'] = function(assert) {
const List = Trait.compose({ const List = Trait.compose({
// private API: // private API:
_list: null, _list: null,
@ -188,11 +188,11 @@ exports['test:instanceof'] = function(test) {
} }
}); });
test.assert(List() instanceof List, 'Must be instance of List'); assert.ok(List() instanceof List, 'Must be instance of List');
test.assert(new List() instanceof List, 'Must be instance of List'); assert.ok(new List() instanceof List, 'Must be instance of List');
}; };
exports['test:privates are unaccessible'] = function(test) { exports['test:privates are unaccessible'] = function(assert) {
const List = Trait.compose({ const List = Trait.compose({
// private API: // private API:
_list: null, _list: null,
@ -210,14 +210,14 @@ exports['test:privates are unaccessible'] = function(test) {
}); });
let list = List(); let list = List();
test.assert(!('_list' in list), 'no privates on instance'); assert.ok(!('_list' in list), 'no privates on instance');
test.assert( assert.ok(
!('_list' in List.prototype), !('_list' in List.prototype),
'no privates on prototype' 'no privates on prototype'
); );
}; };
exports['test:public API can access private API'] = function(test) { exports['test:public API can access private API'] = function(assert) {
const List = Trait.compose({ const List = Trait.compose({
// private API: // private API:
_list: null, _list: null,
@ -237,14 +237,14 @@ exports['test:public API can access private API'] = function(test) {
list.add('test'); list.add('test');
test.assertEqual( assert.equal(
1, 1,
list.length, list.length,
'should be able to add element and access it from public getter' 'should be able to add element and access it from public getter'
); );
}; };
exports['test:required'] = function(test) { exports['test:required'] = function(assert) {
const Enumerable = Trait.compose({ const Enumerable = Trait.compose({
list: Trait.required, list: Trait.required,
forEach: function forEach(consumer) { forEach: function forEach(consumer) {
@ -254,9 +254,9 @@ exports['test:required'] = function(test) {
try { try {
let i = Enumerable(); let i = Enumerable();
test.fail('should throw when creating instance with required properties'); assert.fail('should throw when creating instance with required properties');
} catch(e) { } catch(e) {
test.assertEqual( assert.equal(
'Error: Missing required property: list', 'Error: Missing required property: list',
e.toString(), e.toString(),
'required prop error' 'required prop error'
@ -264,7 +264,7 @@ exports['test:required'] = function(test) {
} }
}; };
exports['test:compose with required'] = function(test) { exports['test:compose with required'] = function(assert) {
const List = Trait.compose({ const List = Trait.compose({
// private API: // private API:
_list: null, _list: null,
@ -298,16 +298,16 @@ exports['test:compose with required'] = function(test) {
let number = 0; let number = 0;
l.forEach(function(element, index) { l.forEach(function(element, index) {
number ++; number ++;
test.assertEqual(array[index], element, 'should mach array element') assert.equal(array[index], element, 'should mach array element')
}); });
test.assertEqual( assert.equal(
array.length, array.length,
number, number,
'should perform as many asserts as elements in array' 'should perform as many asserts as elements in array'
); );
}; };
exports['test:resolve'] = function(test) { exports['test:resolve'] = function(assert) {
const List = Trait.compose({ const List = Trait.compose({
// private API: // private API:
_list: null, _list: null,
@ -344,18 +344,18 @@ exports['test:resolve'] = function(test) {
let r = Range(0, 10); let r = Range(0, 10);
test.assertEqual( assert.equal(
0, 0,
r.min, r.min,
'constructor must have set min' 'constructor must have set min'
); );
test.assertEqual( assert.equal(
10, 10,
r.max, r.max,
'constructor must have set max' 'constructor must have set max'
); );
test.assertEqual( assert.equal(
0, 0,
r.length, r.length,
'should not contain any elements' 'should not contain any elements'
@ -363,7 +363,7 @@ exports['test:resolve'] = function(test) {
r.add(5); r.add(5);
test.assertEqual( assert.equal(
1, 1,
r.length, r.length,
'should add `5` to list' 'should add `5` to list'
@ -371,14 +371,14 @@ exports['test:resolve'] = function(test) {
r.add(12); r.add(12);
test.assertEqual( assert.equal(
1, 1,
r.length, r.length,
'should not add `12` to list' 'should not add `12` to list'
); );
}; };
exports['test:custom iterator'] = function(test) { exports['test:custom iterator'] = function(assert) {
let Sub = Trait.compose({ let Sub = Trait.compose({
foo: "foo", foo: "foo",
bar: "bar", bar: "bar",
@ -392,7 +392,8 @@ exports['test:custom iterator'] = function(test) {
let (i = 0, sub = Sub()) { let (i = 0, sub = Sub()) {
for (let item in sub) for (let item in sub)
test.assertEqual(++i, item, "iterated item has the right value"); assert.equal(++i, item, "iterated item has the right value");
}; };
}; };
require('sdk/test').run(exports);

Просмотреть файл

@ -0,0 +1,43 @@
/* 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 { identify } = require('sdk/ui/id');
const { Class } = require('sdk/core/heritage');
const signature = /{[0-9a-f\-]+}/;
exports['test generate id'] = function(assert) {
let first = identify({});
let second = identify({});
assert.ok(signature.test(first), 'first id has a correct signature');
assert.ok(signature.test(second), 'second id has a correct signature');
assert.notEqual(first, identify({}), 'identify generated new uuid [1]');
assert.notEqual(first, second, 'identify generated new uuid [2]');
};
exports['test get id'] = function(assert) {
let thing = {};
let thingID = identify(thing);
assert.equal(thingID, identify(thing), 'ids for things are cached by default');
assert.notEqual(identify(thing), identify({}), 'new ids for new things');
};
exports['test custom id definition for classes'] = function(assert) {
let Thing = Class({});
let thing = Thing();
let counter = 0;
identify.define(Thing, function(thing) {
return ++counter;
});
assert.equal(identify(thing), counter, 'it is possible to define custom identifications');
assert.ok(signature.test(identify({})), 'defining a custom identification does not affect the default behavior');
}
require('sdk/test').run(exports);

Просмотреть файл

@ -49,8 +49,8 @@ exports.testSideBarIsNotInNewPrivateWindows = function(assert, done) {
}) })
} }
/*
exports.testSidebarIsNotOpenInNewPrivateWindow = function(assert, done) { exports.testSidebarIsNotOpenInNewPrivateWindow = function(assert, done) {
const { Sidebar } = require('sdk/ui/sidebar');
let testName = 'testSidebarIsNotOpenInNewPrivateWindow'; let testName = 'testSidebarIsNotOpenInNewPrivateWindow';
let window = getMostRecentBrowserWindow(); let window = getMostRecentBrowserWindow();
@ -73,15 +73,15 @@ exports.testSidebarIsNotOpenInNewPrivateWindow = function(assert, done) {
assert.equal(isSidebarShowing(window), true, 'the sidebar is showing in old window still'); assert.equal(isSidebarShowing(window), true, 'the sidebar is showing in old window still');
assert.equal(isSidebarShowing(window2), false, 'the sidebar is not showing in the new private window'); assert.equal(isSidebarShowing(window2), false, 'the sidebar is not showing in the new private window');
assert.equal(isShowing(sidebar), false, 'the sidebar is not showing'); assert.equal(isShowing(sidebar), false, 'the sidebar is not showing');
sidebar.destroy(); sidebar.destroy();
close(window2).then(done); close(window2).then(done);
}, 500) }, 500);
}) })
}); });
sidebar.show(); sidebar.show();
} }
*/
// TEST: edge case where web panel is destroyed while loading // TEST: edge case where web panel is destroyed while loading
exports.testDestroyEdgeCaseBugWithPrivateWindow = function(assert, done) { exports.testDestroyEdgeCaseBugWithPrivateWindow = function(assert, done) {

Просмотреть файл

@ -13,34 +13,36 @@ const { browserWindows } = require('sdk/windows');
const ERR_MSG = 'This method is not yet supported by Fennec, consider using require("sdk/tabs") instead'; const ERR_MSG = 'This method is not yet supported by Fennec, consider using require("sdk/tabs") instead';
// TEST: browserWindows.length for Fennec // TEST: browserWindows.length for Fennec
exports.testBrowserWindowsLength = function(test) { exports.testBrowserWindowsLength = function(assert) {
test.assertEqual(browserWindows.length, 1, "Only one window open"); assert.equal(browserWindows.length, 1, "Only one window open");
}; };
// TEST: open & close window // TEST: open & close window
exports.testOpenWindow = function(test) { exports.testOpenWindow = function(assert) {
let tabCount = browserWindows.activeWindow.tabs.length; let tabCount = browserWindows.activeWindow.tabs.length;
let url = "data:text/html;charset=utf-8,<title>windows%20API%20test</title>"; let url = "data:text/html;charset=utf-8,<title>windows%20API%20test</title>";
try { try {
browserWindows.open({url: url}); browserWindows.open({url: url});
test.fail('Error was not thrown'); assert.fail('Error was not thrown');
} }
catch(e) { catch(e) {
test.assertEqual(e.message, ERR_MSG, 'Error is thrown on windows.open'); assert.equal(e.message, ERR_MSG, 'Error is thrown on windows.open');
test.assertEqual(browserWindows.length, 1, "Only one window open"); assert.equal(browserWindows.length, 1, "Only one window open");
} }
}; };
exports.testCloseWindow = function(test) { exports.testCloseWindow = function(assert) {
let window = browserWindows.activeWindow; let window = browserWindows.activeWindow;
try { try {
window.close(); window.close();
test.fail('Error was not thrown'); assert.fail('Error was not thrown');
} }
catch(e) { catch(e) {
test.assertEqual(e.message, ERR_MSG, 'Error is thrown on windows.close'); assert.equal(e.message, ERR_MSG, 'Error is thrown on windows.close');
test.assertEqual(browserWindows.length, 1, "Only one window open"); assert.equal(browserWindows.length, 1, "Only one window open");
} }
}; };
require('sdk/test').run(exports);