Backed out changeset b117a76d0a25 (bug 1171638) for making Windows M(JP) basically permafail.

This commit is contained in:
Ryan VanderMeulen 2015-06-05 11:49:54 -04:00
parent 0f0eb9d111
commit 2b6330f5bd
57 changed files with 959 additions and 938 deletions

View File

@ -29,6 +29,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != "gonk":
EXTRA_JS_MODULES.commonjs.sdk.deprecated += [
'source/lib/sdk/deprecated/api-utils.js',
'source/lib/sdk/deprecated/memory.js',
'source/lib/sdk/deprecated/sync-worker.js',
'source/lib/sdk/deprecated/unit-test-finder.js',
'source/lib/sdk/deprecated/unit-test.js',
@ -257,10 +258,6 @@ EXTRA_JS_MODULES.commonjs.sdk.content += [
'source/lib/sdk/content/worker.js',
]
EXTRA_JS_MODULES.commonjs.sdk.content.sandbox += [
'source/lib/sdk/content/sandbox/events.js',
]
EXTRA_JS_MODULES.commonjs.sdk['context-menu'] += [
'source/lib/sdk/context-menu/context.js',
'source/lib/sdk/context-menu/core.js',
@ -456,6 +453,7 @@ EXTRA_JS_MODULES.commonjs.sdk.url += [
EXTRA_JS_MODULES.commonjs.sdk.util += [
'source/lib/sdk/util/array.js',
'source/lib/sdk/util/bond.js',
'source/lib/sdk/util/collection.js',
'source/lib/sdk/util/contract.js',
'source/lib/sdk/util/deprecate.js',

View File

@ -1,7 +1,7 @@
sudo: false
language: node_js
node_js:
- "0.12"
- "0.10"
env:
- JPM_FX_DEBUG=0

View File

@ -17,13 +17,12 @@ exports.run = function(type) {
return new Promise(function(resolve) {
type = type || "";
[
(!isDebug && /^(firefox-bin)?$/.test(type)) && require.resolve("../bin/node-scripts/test.firefox-bin"),
(!isDebug && /^(modules)?$/.test(type)) && require.resolve("../bin/node-scripts/test.modules"),
(!isDebug && /^(addons)?$/.test(type)) && require.resolve("../bin/node-scripts/test.addons"),
(/^(examples)?$/.test(type)) && require.resolve("../bin/node-scripts/test.examples"),
(!isDebug && /^(docs)?$/.test(type)) && require.resolve("../bin/node-scripts/test.docs"),
(!isDebug && /^(ini)?$/.test(type)) && require.resolve("../bin/node-scripts/test.ini"),
(/^(examples)?$/.test(type)) && require.resolve("../bin/node-scripts/test.examples"),
(!isDebug && /^(addons)?$/.test(type)) && require.resolve("../bin/node-scripts/test.addons"),
(!isDebug && /^(modules)?$/.test(type)) && require.resolve("../bin/node-scripts/test.modules"),
].forEach(function(filepath) {
].sort().forEach(function(filepath) {
filepath && mocha.addFile(filepath);
})

View File

@ -1,37 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var fs = require("fs");
var Promise = require("promise");
var chai = require("chai");
var expect = chai.expect;
var normalizeBinary = require("fx-runner/lib/utils").normalizeBinary;
//var firefox_binary = process.env["JPM_FIREFOX_BINARY"] || normalizeBinary("nightly");
describe("Checking Firefox binary", function () {
it("using matching fx-runner version with jpm", function () {
var sdkPackageJSON = require("../../package.json");
var jpmPackageINI = require("jpm/package.json");
expect(sdkPackageJSON.devDependencies["fx-runner"]).to.be.equal(jpmPackageINI.dependencies["fx-runner"]);
});
it("exists", function (done) {
var useEnvVar = new Promise(function(resolve) {
resolve(process.env["JPM_FIREFOX_BINARY"]);
});
var firefox_binary = process.env["JPM_FIREFOX_BINARY"] ? useEnvVar : normalizeBinary("nightly");
firefox_binary.then(function(path) {
expect(path).to.be.ok;
fs.exists(path, function (exists) {
expect(exists).to.be.ok;
done();
});
})
});
});

View File

@ -11,7 +11,6 @@ var expect = chai.expect;
var ini = require("./update-ini");
var addonINI = path.resolve("./test/addons/jetpack-addon.ini");
var packageINI = path.resolve("./test/jetpack-package.ini");
describe("Checking ini files", function () {
@ -21,10 +20,7 @@ describe("Checking ini files", function () {
if (err) {
throw err;
}
// filter comments
var text = data.toString().split("\n").filter(function(line) {
return !/^\s*#/.test(line);
}).join("\n");
var text = data.toString();
var expected = "";
ini.makeAddonIniContent()
@ -32,32 +28,7 @@ describe("Checking ini files", function () {
expected = contents;
setTimeout(function end() {
expect(text.trim()).to.be.equal(expected.trim());
done();
});
});
});
});
it("Check test/jetpack-package.ini", function (done) {
fs.readFile(packageINI, function (err, data) {
if (err) {
throw err;
}
// filter comments
var text = data.toString().split("\n").filter(function(line) {
return !/^\s*#/.test(line);
}).join("\n");
var expected = "";
ini.makePackageIniContent()
.then(function(contents) {
expected = contents;
setTimeout(function end() {
expect(text.trim()).to.be.equal(expected.trim());
expect(expected.trim()).to.be.equal(text.trim());
done();
});
});

View File

@ -11,15 +11,6 @@ var parser = require("ini-parser");
var addonINI = path.resolve("./test/addons/jetpack-addon.ini");
var addonsDir = path.resolve("./test/addons/");
var packageINI = path.resolve("./test/jetpack-package.ini");
var packageDir = path.resolve("./test/");
var packageIgnorables = [ "addons", "preferences" ];
var packageSupportFiles = [
"fixtures.js",
"pagemod-test-helpers.js",
"test-context-menu.html",
"util.js"
]
function updateAddonINI() {
return new Promise(function(resolve) {
@ -41,18 +32,16 @@ function makeAddonIniContent() {
var result = {};
fs.readdir(addonsDir, function(err, files) {
// get a list of folders
var folders = files.filter(function(file) {
return fs.statSync(path.resolve(addonsDir, file)).isDirectory();
}).sort();
// copy any related data from the existing ini
folders.forEach(function(folder) {
var oldData = data[folder + ".xpi"];
result[folder] = oldData ? oldData : {};
});
// build a new ini file
// build ini file
var contents = [];
Object.keys(result).sort().forEach(function(key) {
contents.push("[" + key + ".xpi]");
@ -67,76 +56,3 @@ function makeAddonIniContent() {
});
}
exports.makeAddonIniContent = makeAddonIniContent;
function makePackageIniContent() {
return new Promise(function(resolve) {
var data = parser.parse(fs.readFileSync(packageINI, { encoding: "utf8" }).toString());
var result = {};
fs.readdir(packageDir, function(err, files) {
// get a list of folders
var folders = files.filter(function(file) {
var ignore = (packageIgnorables.indexOf(file) >= 0);
var isDir = fs.statSync(path.resolve(packageDir, file)).isDirectory();
return (isDir && !ignore);
}).sort();
// get a list of "test-"" files
var files = files.filter(function(file) {
var ignore = !/^test\-.*\.js$/i.test(file);
var isDir = fs.statSync(path.resolve(packageDir, file)).isDirectory();
return (!isDir && !ignore);
}).sort();
// get a list of the support files
var support_files = packageSupportFiles.map(function(file) {
return " " + file;
});
folders.forEach(function(folder) {
support_files.push(" " + folder + "/**");
});
support_files = support_files.sort();
// copy any related data from the existing ini
files.forEach(function(file) {
var oldData = data[file];
result[file] = oldData ? oldData : {};
});
// build a new ini file
var contents = [
"[DEFAULT]",
"support-files ="
];
support_files.forEach(function(support_file) {
contents.push(support_file);
});
contents.push("");
Object.keys(result).sort().forEach(function(key) {
contents.push("[" + key + "]");
Object.keys(result[key]).forEach(function(dataKey) {
contents.push(dataKey + " = " + result[key][dataKey]);
});
});
contents = contents.join("\n") + "\n";
return resolve(contents);
});
});
}
exports.makePackageIniContent = makePackageIniContent;
function updatePackageINI() {
return new Promise(function(resolve) {
console.log("Start updating " + packageINI);
makeAddonIniContent().
then(function(contents) {
fs.writeFileSync(packageINI, contents, { encoding: "utf8" });
console.log("Done updating " + packageINI);
resolve();
});
})
}
exports.updatePackageINI = updatePackageINI;

View File

@ -65,9 +65,6 @@ function run (cmd, options, p) {
if (p) {
proc.stdout.pipe(p.stdout);
}
else if (!isDebug) {
proc.stdout.pipe(DEFAULT_PROCESS.stdout);
}
else {
proc.stdout.on("data", function (data) {
data = (data || "") + "";

View File

@ -28,11 +28,7 @@ gulp.task('test:modules', function(done) {
});
gulp.task('test:ini', function(done) {
require("./bin/jpm-test").run("ini").catch(console.error).then(done);
});
gulp.task('test:firefox-bin', function(done) {
require("./bin/jpm-test").run("firefox-bin").catch(console.error).then(done);
test("ini").catch(console.error).then(done);
});
gulp.task('patch:clean', function(done) {
@ -42,3 +38,7 @@ gulp.task('patch:clean', function(done) {
gulp.task('patch:apply', function(done) {
patch.apply().catch(console.error).then(done);
});
gulp.task('update:ini', function(done) {
ini.updateAddonINI().catch(console.error).then(done);
});

View File

@ -1,16 +1,19 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
module.metadata = {
"stability": "experimental"
};
const { Ci, components } = require("chrome");
const { Cc, Ci, components } = require("chrome");
const { parseStack, sourceURI } = require("toolkit/loader");
const { readURISync } = require("../net/url");
exports.sourceURI = sourceURI
function safeGetFileLine(path, line) {
try {
var scheme = require("../url").URL(path).scheme;

View File

@ -10,7 +10,6 @@ module.metadata = {
const { Class } = require('../core/heritage');
const { EventTarget } = require('../event/target');
const { on, off, emit } = require('../event/core');
const { events } = require('./sandbox/events');
const { requiresAddonGlobal } = require('./utils');
const { delay: async } = require('../lang/functional');
const { Ci, Cu, Cc } = require('chrome');
@ -21,7 +20,8 @@ const { merge } = require('../util/object');
const { getTabForContentWindow } = require('../tabs/utils');
const { getInnerId } = require('../window/utils');
const { PlainTextConsole } = require('../console/plain-text');
const { data } = require('../self');const { isChildLoader } = require('../remote/core');
const { data } = require('../self');
const { isChildLoader } = require('../remote/core');
// WeakMap of sandboxes so we can access private values
const sandboxes = new WeakMap();
@ -166,7 +166,6 @@ const WorkerSandbox = Class({
get top() top,
get parent() parent
});
// Use the Greasemonkey naming convention to provide access to the
// unwrapped window object so the content script can access document
// JavaScript values.
@ -262,11 +261,6 @@ const WorkerSandbox = Class({
win.console = con;
};
emit(events, "content-script-before-inserted", {
window: window,
worker: worker
});
// The order of `contentScriptFile` and `contentScript` evaluation is
// intentional, so programs can load libraries like jQuery from script URLs
// and use them in scripts.
@ -279,7 +273,6 @@ const WorkerSandbox = Class({
if (contentScriptFile)
importScripts.apply(null, [this].concat(contentScriptFile));
if (contentScript) {
evaluateIn(
this,

View File

@ -0,0 +1,129 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
module.metadata = {
"stability": "deprecated"
};
const { Cc, Ci, Cu, components } = require("chrome");
const { when: unload } = require("../system/unload")
var trackedObjects = {};
const Compacter = {
notify: function() {
var newTrackedObjects = {};
for (let name in trackedObjects) {
let oldBin = trackedObjects[name];
let newBin = [];
let strongRefs = [];
for (let i = 0, l = oldBin.length; i < l; i++) {
let strongRef = oldBin[i].weakref.get();
if (strongRef && strongRefs.indexOf(strongRef) == -1) {
strongRefs.push(strongRef);
newBin.push(oldBin[i]);
}
}
if (newBin.length)
newTrackedObjects[name] = newBin;
}
trackedObjects = newTrackedObjects;
}
};
var timer = Cc["@mozilla.org/timer;1"]
.createInstance(Ci.nsITimer);
timer.initWithCallback(Compacter,
5000,
Ci.nsITimer.TYPE_REPEATING_SLACK);
function track(object, bin, stackFrameNumber) {
var frame = components.stack.caller;
var weakref = Cu.getWeakReference(object);
if (!bin && 'constructor' in object)
bin = object.constructor.name;
if (bin == "Object")
bin = frame.name;
if (!bin)
bin = "generic";
if (!(bin in trackedObjects))
trackedObjects[bin] = [];
if (stackFrameNumber > 0)
for (var i = 0; i < stackFrameNumber; i++)
frame = frame.caller;
trackedObjects[bin].push({weakref: weakref,
created: new Date(),
filename: frame.filename,
lineNo: frame.lineNumber,
bin: bin});
}
exports.track = track;
var getBins = exports.getBins = function getBins() {
var names = [];
for (let name in trackedObjects)
names.push(name);
return names;
};
function getObjects(bin) {
var results = [];
function getLiveObjectsInBin(bin) {
for (let i = 0, l = bin.length; i < l; i++) {
let object = bin[i].weakref.get();
if (object) {
results.push(bin[i]);
}
}
}
if (bin) {
if (bin in trackedObjects)
getLiveObjectsInBin(trackedObjects[bin]);
}
else {
for (let name in trackedObjects)
getLiveObjectsInBin(trackedObjects[name]);
}
return results;
}
exports.getObjects = getObjects;
function gc() {
// Components.utils.forceGC() doesn't currently perform
// cycle collection, which means that e.g. DOM elements
// won't be collected by it. Fortunately, there are
// other ways...
var test_utils = Cc["@mozilla.org/appshell/appShellService;1"]
.getService(Ci.nsIAppShellService)
.hiddenDOMWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
test_utils.garbageCollect();
// Clean metadata for dead objects
Compacter.notify();
// Not sure why, but sometimes it appears that we don't get
// them all with just one CC, so let's do it again.
test_utils.garbageCollect();
};
exports.gc = gc;
unload(_ => {
trackedObjects = {};
if (timer) {
timer.cancel();
timer = null;
}
});

View File

@ -8,6 +8,7 @@ module.metadata = {
};
const file = require("../io/file");
const memory = require('./memory');
const { Loader } = require("../test/loader");
const { isNative } = require('@loader/options');
@ -131,6 +132,7 @@ let loader = Loader(module);
const NOT_TESTS = ['setup', 'teardown'];
var TestFinder = exports.TestFinder = function TestFinder(options) {
memory.track(this);
this.filter = options.filter;
this.testInProcess = options.testInProcess === false ? false : true;
this.testOutOfProcess = options.testOutOfProcess === true ? true : false;

View File

@ -7,6 +7,7 @@ module.metadata = {
"stability": "deprecated"
};
const memory = require("./memory");
const timer = require("../timers");
const cfxArgs = require("../test/options");
const { getTabs, closeTab, getURI, getTabId, getSelectedTab } = require("../tabs/utils");
@ -46,6 +47,7 @@ const TestRunner = function TestRunner(options) {
this.fs = options.fs;
this.console = options.console || console;
memory.track(this);
this.passed = 0;
this.failed = 0;
this.testRunSummary = [];
@ -281,46 +283,40 @@ TestRunner.prototype = {
}
this.isDone = true;
this.pass("This test is done.");
if (this.test.teardown) {
this.test.teardown(this);
}
if (this.waitTimeout !== null) {
timer.clearTimeout(this.waitTimeout);
this.waitTimeout = null;
}
// Do not leave any callback set when calling to `waitUntil`
this.waitUntilCallback = null;
if (this.test.passed == 0 && this.test.failed == 0) {
this._logTestFailed("empty test");
if ("testMessage" in this.console) {
this.console.testMessage(false, false, this.test.name, "Empty test");
}
else {
this.console.error("fail:", "Empty test")
}
this.failed++;
this.test.failed++;
}
let wins = windows(null, { includePrivate: true });
let winPromises = wins.map(win => {
return new Promise(resolve => {
if (["interactive", "complete"].indexOf(win.document.readyState) >= 0) {
resolve()
}
else {
win.addEventListener("DOMContentLoaded", function onLoad() {
win.removeEventListener("DOMContentLoaded", onLoad, false);
resolve();
}, false);
}
});
let winPromises = wins.map(win => {
let { promise, resolve } = defer();
if (["interactive", "complete"].indexOf(win.document.readyState) >= 0) {
resolve()
}
else {
win.addEventListener("DOMContentLoaded", function onLoad() {
win.removeEventListener("DOMContentLoaded", onLoad, false);
resolve();
}, false);
}
return promise;
});
PromiseDebugging.flushUncaughtErrors();
@ -362,17 +358,9 @@ TestRunner.prototype = {
}
}
return failure;
}).
then(failure => {
if (!failure) {
this.pass("There was a clean UI.");
return null;
}
return cleanUI().then(() => {
this.pass("There is a clean UI.");
});
return null;
}).
then(cleanUI).
then(() => {
this.testRunSummary.push({
name: this.test.name,

View File

@ -1,15 +1,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
module.metadata = {
"stability": "experimental"
};
const { Cc, Ci, Cu, components } = require("chrome");
const { ensure } = require("../system/unload");
const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
const {Cc,Ci,Cu,components} = require("chrome");
var NetUtil = {};
Cu.import("resource://gre/modules/NetUtil.jsm", NetUtil);
NetUtil = NetUtil.NetUtil;
// NetUtil.asyncCopy() uses this buffer length, and since we call it, for best
// performance we use it, too.
@ -17,6 +19,8 @@ const BUFFER_BYTE_LEN = 0x8000;
const PR_UINT32_MAX = 0xffffffff;
const DEFAULT_CHARSET = "UTF-8";
exports.TextReader = TextReader;
exports.TextWriter = TextWriter;
/**
* An input stream that reads text from a backing stream using a given text
@ -31,6 +35,7 @@ const DEFAULT_CHARSET = "UTF-8";
* documentation on how to determine other valid values for this.
*/
function TextReader(inputStream, charset) {
const self = this;
charset = checkCharset(charset);
let stream = Cc["@mozilla.org/intl/converter-input-stream;1"].
@ -84,7 +89,6 @@ function TextReader(inputStream, charset) {
return str;
};
}
exports.TextReader = TextReader;
/**
* A buffered output stream that writes text to a backing stream using a given
@ -99,6 +103,7 @@ exports.TextReader = TextReader;
* for documentation on how to determine other valid values for this.
*/
function TextWriter(outputStream, charset) {
const self = this;
charset = checkCharset(charset);
let stream = outputStream;
@ -164,7 +169,7 @@ function TextWriter(outputStream, charset) {
this.writeAsync = function TextWriter_writeAsync(str, callback) {
manager.ensureOpened();
let istream = uconv.convertToInputStream(str);
NetUtil.asyncCopy(istream, stream, (result) => {
NetUtil.asyncCopy(istream, stream, function (result) {
let err = components.isSuccessCode(result) ? undefined :
new Error("An error occured while writing to the stream: " + result);
if (err)
@ -175,7 +180,7 @@ function TextWriter(outputStream, charset) {
if (typeof(callback) === "function") {
try {
callback.call(this, err);
callback.call(self, err);
}
catch (exc) {
console.exception(exc);
@ -184,32 +189,34 @@ function TextWriter(outputStream, charset) {
});
};
}
exports.TextWriter = TextWriter;
// This manages the lifetime of stream, a TextReader or TextWriter. It defines
// closed and close() on stream and registers an unload listener that closes
// rawStream if it's still opened. It also provides ensureOpened(), which
// throws an exception if the stream is closed.
function StreamManager(stream, rawStream) {
const self = this;
this.rawStream = rawStream;
this.opened = true;
/**
* True iff the stream is closed.
*/
stream.__defineGetter__("closed", () => !this.opened);
stream.__defineGetter__("closed", function stream_closed() {
return !self.opened;
});
/**
* Closes both the stream and its backing stream. If the stream is already
* closed, an exception is thrown. For TextWriters, this first flushes the
* backing stream's buffer.
*/
stream.close = () => {
this.ensureOpened();
this.unload();
stream.close = function stream_close() {
self.ensureOpened();
self.unload();
};
ensure(this);
require("../system/unload").ensure(this);
}
StreamManager.prototype = {

View File

@ -1,6 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
module.metadata = {
@ -12,7 +13,7 @@ module.metadata = {
};
const { Cc, Ci } = require('chrome');
const { all } = require('../../core/promise');
const { defer, all, resolve } = require('../../core/promise');
const { safeMerge, omit } = require('../../util/object');
const historyService = Cc['@mozilla.org/browser/nav-history-service;1']
.getService(Ci.nsINavHistoryService);
@ -44,11 +45,13 @@ const PLACES_PROPERTIES = [
];
function execute (queries, options) {
return new Promise(resolve => {
let root = historyService
.executeQueries(queries, queries.length, options).root;
resolve(collect([], root));
});
let deferred = defer();
let root = historyService
.executeQueries(queries, queries.length, options).root;
let items = collect([], root);
deferred.resolve(items);
return deferred.promise;
}
function collect (acc, node) {
@ -66,35 +69,40 @@ function collect (acc, node) {
}
function query (queries, options) {
return new Promise((resolve, reject) => {
queries = queries || [];
options = options || {};
let optionsObj, queryObjs;
queries = queries || [];
options = options || {};
let deferred = defer();
let optionsObj, queryObjs;
try {
optionsObj = historyService.getNewQueryOptions();
queryObjs = [].concat(queries).map(createQuery);
if (!queryObjs.length) {
queryObjs = [historyService.getNewQuery()];
}
safeMerge(optionsObj, options);
} catch (e) {
deferred.reject(e);
return deferred.promise;
}
/*
* Currently `places:` queries are not supported
*/
optionsObj.excludeQueries = true;
/*
* Currently `places:` queries are not supported
*/
optionsObj.excludeQueries = true;
execute(queryObjs, optionsObj).then((results) => {
if (optionsObj.queryType === 0) {
return results.map(normalize);
}
else if (optionsObj.queryType === 1) {
// Formats query results into more standard
// data structures for returning
return all(results.map(({itemId}) =>
send('sdk-places-bookmarks-get', { id: itemId })));
}
}).then(resolve, reject);
});
execute(queryObjs, optionsObj).then(function (results) {
if (optionsObj.queryType === 0) {
return results.map(normalize);
} else if (optionsObj.queryType === 1) {
// Formats query results into more standard
// data structures for returning
return all(results.map(({itemId}) =>
send('sdk-places-bookmarks-get', { id: itemId })));
}
}).then(deferred.resolve, deferred.reject);
return deferred.promise;
}
exports.query = query;
@ -132,7 +140,7 @@ function queryReceiver (message) {
/*
* Converts a nsINavHistoryResultNode into a plain object
*
*
* https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsINavHistoryResultNode
*/
function normalize (historyObj) {
@ -142,8 +150,7 @@ function normalize (historyObj) {
else if (prop === 'time') {
// Cast from microseconds to milliseconds
obj.time = Math.floor(historyObj.time / 1000)
}
else if (prop === 'accessCount')
} else if (prop === 'accessCount')
obj.visitCount = historyObj[prop];
else
obj[prop] = historyObj[prop];

View File

@ -51,14 +51,14 @@ exports.TreeNode = TreeNode;
/*
* Descends down from `node` applying `fn` to each in order.
* `fn` can return values or promises -- if promise returned,
* children are not processed until resolved. `fn` is passed
* children are not processed until resolved. `fn` is passed
* one argument, the current node, `curr`.
*/
function walk (curr, fn) {
return promised(fn)(curr).then(val => {
return all(curr.children.map(child => walk(child, fn)));
});
}
}
/*
* Descends from the TreeNode `node`, returning
@ -122,7 +122,7 @@ exports.isRootGroup = isRootGroup;
/*
* Merges appropriate options into query based off of url
* 4 scenarios:
*
*
* 'moz.com' // domain: moz.com, domainIsHost: true
* --> 'http://moz.com', 'http://moz.com/thunderbird'
* '*.moz.com' // domain: moz.com, domainIsHost: false
@ -177,9 +177,9 @@ function createQuery (type, query) {
let qObj = {
searchTerms: query.query
};
urlQueryParser(qObj, query.url);
// 0 === history
if (type === 0) {
// PRTime used by query is in microseconds, not milliseconds
@ -194,7 +194,7 @@ function createQuery (type, query) {
else if (type === 1) {
qObj.tags = query.tags;
qObj.folder = query.group && query.group.id;
}
}
// 2 === unified (not implemented on platform)
else if (type === 2) {

View File

@ -15,6 +15,7 @@ const { PlainTextConsole } = require("../console/plain-text");
const { when: unload } = require("../system/unload");
const { format, fromException } = require("../console/traceback");
const system = require("../system");
const memory = require('../deprecated/memory');
const { gc: gcPromise } = require('./memory');
const { defer } = require('../core/promise');
const { extend } = require('../core/heritage');
@ -149,7 +150,7 @@ function reportMemoryUsage() {
return emptyPromise();
}
return gcPromise().then((() => {
return gcPromise().then((function () {
var mgr = Cc["@mozilla.org/memory-reporter-manager;1"]
.getService(Ci.nsIMemoryReporterManager);
let count = 0;
@ -157,6 +158,11 @@ function reportMemoryUsage() {
print(((++count == 1) ? "\n" : "") + description + ": " + amount + "\n");
}
mgr.getReportsForThisProcess(logReporter, null, /* anonymize = */ false);
var weakrefs = [info.weakref.get()
for (info of memory.getObjects())];
weakrefs = [weakref for (weakref of weakrefs) if (weakref)];
print("Tracked memory objects in testing sandbox: " + weakrefs.length + "\n");
}));
}
@ -210,6 +216,16 @@ function showResults() {
function cleanup() {
let coverObject = {};
try {
for (let name in loader.modules)
memory.track(loader.modules[name],
"module global scope: " + name);
memory.track(loader, "Cuddlefish Loader");
if (profileMemory) {
gWeakrefInfo = [{ weakref: info.weakref, bin: info.bin }
for (info of memory.getObjects())];
}
loader.unload();
if (loader.globals.console.errorsLogged && !results.failed) {
@ -235,7 +251,7 @@ function cleanup() {
consoleListener.unregister();
Cu.forceGC();
memory.gc();
}
catch (e) {
results.failed++;
@ -262,7 +278,7 @@ function cleanup() {
}
function getPotentialLeaks() {
Cu.forceGC();
memory.gc();
// Things we can assume are part of the platform and so aren't leaks
let GOOD_BASE_URLS = [

View File

@ -4,8 +4,17 @@
'use strict';
const { Cu } = require("chrome");
const memory = require('../deprecated/memory');
const { defer } = require('../core/promise');
function gc() {
return new Promise(resolve => Cu.schedulePreciseGC(resolve));
let { promise, resolve } = defer();
Cu.forceGC();
memory.gc();
Cu.schedulePreciseGC(_ => resolve());
return promise;
}
exports.gc = gc;

View File

@ -0,0 +1,36 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
module.metadata = {
"stability": "experimental"
};
const makeDescriptor = (name, method) => ({
get() {
if (!Object.hasOwnProperty.call(this, name)) {
Object.defineProperty(this, name, {value: method.bind(this)});
return this[name];
} else {
return method;
}
}
});
const Bond = function(methods) {
let descriptor = {};
let members = [...Object.getOwnPropertyNames(methods),
...Object.getOwnPropertySymbols(methods)];
for (let name of members) {
let method = methods[name];
if (typeof(method) !== "function") {
throw new TypeError(`Property named "${name}" passed to Bond must be a function`);
}
descriptor[name] = makeDescriptor(name, method);
}
return Object.create(Bond.prototype, descriptor);
}
exports.Bond = Bond;

View File

@ -1,16 +1,22 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
'use strict';
const { Cc, Ci } = require("chrome");
const { Cc, Ci, Cu } = require("chrome");
const { defer } = require("../core/promise");
function getZipReader(aFile) {
return new Promise(resolve => {
let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"].
createInstance(Ci.nsIZipReader);
const getZipReader = function getZipReader(aFile) {
let { promise, resolve, reject } = defer();
let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"].
createInstance(Ci.nsIZipReader);
try {
zipReader.open(aFile);
resolve(zipReader);
});
}
catch(e){
reject(e);
}
resolve(zipReader);
return promise;
};
exports.getZipReader = getZipReader;

View File

@ -13,6 +13,7 @@
"l10n/prefs": "sdk/l10n/prefs",
"list": "sdk/util/list",
"loader": "sdk/loader/loader",
"memory": "sdk/deprecated/memory",
"namespace": "sdk/core/namespace",
"preferences-service": "sdk/preferences/service",
"promise": "sdk/core/promise",

View File

@ -22,7 +22,6 @@
"async": "0.9.0",
"chai": "2.1.1",
"fs-extra": "0.18.2",
"fx-runner": "0.0.7",
"glob": "4.4.2",
"gulp": "3.8.11",
"ini-parser": "0.0.2",

View File

@ -236,6 +236,10 @@ parser_groups = (
help="Where to put the finished .xpi",
default=None,
cmds=['xpi'])),
(("", "--manifest-overload",), dict(dest="manifest_overload",
help="JSON file to overload package.json properties",
default=None,
cmds=['xpi'])),
(("", "--abort-on-missing-module",), dict(dest="abort_on_missing",
help="Abort if required module is missing",
action="store_true",
@ -657,6 +661,10 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None,
target_cfg_json = os.path.join(options.pkgdir, 'package.json')
target_cfg = packaging.get_config_in_dir(options.pkgdir)
if options.manifest_overload:
for k, v in packaging.load_json_file(options.manifest_overload).items():
target_cfg[k] = v
# At this point, we're either building an XPI or running Jetpack code in
# a Mozilla application (which includes running tests).

View File

@ -0,0 +1,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const { Cc, Ci } = require("chrome");
exports.main = function(options, callbacks) {
// Close Firefox window. Firefox should quit.
require("sdk/deprecated/window-utils").activeBrowserWindow.close();
// But not on Mac where it stay alive! We have to request application quit.
if (require("sdk/system/runtime").OS == "Darwin") {
let appStartup = Cc['@mozilla.org/toolkit/app-startup;1'].
getService(Ci.nsIAppStartup);
appStartup.quit(appStartup.eAttemptQuit);
}
}

View File

@ -0,0 +1,3 @@
{
"version": "1.0-nightly"
}

View File

@ -0,0 +1,6 @@
{
"id": "simplest-test",
"directories": {
"lib": "."
}
}

View File

@ -2,11 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
module.metadata = {
"stability": "experimental"
exports.minimalTest = function(test) {
test.assert(true);
};
const events = {};
exports.events = events;

View File

@ -182,6 +182,35 @@ class TestCfxQuits(unittest.TestCase):
container)
self.fail(standardMsg)
def test_cfx_run(self):
addon_path = os.path.join(tests_path,
"addons", "simplest-test")
rc, out, err = self.run_cfx(addon_path, ["run"])
self.assertEqual(rc, 0)
self.assertIn("Program terminated successfully.", err)
def test_cfx_test(self):
addon_path = os.path.join(tests_path, "addons", "simplest-test")
rc, out, err = self.run_cfx(addon_path, ["test"])
self.assertEqual(rc, 0)
self.assertIn("1 of 1 tests passed.", err)
self.assertIn("Program terminated successfully.", err)
def test_cfx_xpi(self):
addon_path = os.path.join(tests_path,
"addons", "simplest-test")
rc, out, err = self.run_cfx(addon_path, \
["xpi", "--manifest-overload", "manifest-overload.json"])
self.assertEqual(rc, 0)
# Ensure that the addon version from our manifest overload is used
# in install.rdf
xpi_path = os.path.join(addon_path, "simplest-test.xpi")
xpi = zipfile.ZipFile(xpi_path, "r")
manifest = xpi.read("install.rdf")
self.assertIn("<em:version>1.0-nightly</em:version>", manifest)
xpi.close()
os.remove(xpi_path)
def test_cfx_init(self):
# Create an empty test directory
addon_path = os.path.abspath(os.path.join(".test_tmp", "test-cfx-init"))
@ -203,7 +232,7 @@ class TestCfxQuits(unittest.TestCase):
# run cfx test
rc, out, err = self.run_cfx(addon_path, ["test"])
self.assertEqual(rc, 0)
self.assertIn("6 of 6 tests passed.", err)
self.assertIn("2 of 2 tests passed.", err)
self.assertIn("Program terminated successfully.", err)

View File

@ -6,5 +6,3 @@
self.port.on('echo', _ => {
self.port.emit('echo', '');
});
self.port.emit('start', '');

View File

@ -67,31 +67,23 @@ exports.testChromeLocale = function(assert) {
'locales en-US folder was copied correctly');
}
exports.testChromeInPanel = function*(assert) {
exports.testChromeInPanel = function(assert, done) {
let panel = Panel({
contentURL: 'chrome://test/content/panel.html',
contentScriptWhen: 'end',
contentScriptWhen: 'start',
contentScriptFile: data.url('panel.js')
});
yield new Promise(resolve => panel.port.once('start', resolve));
assert.pass('start was emitted');
yield new Promise(resolve => {
panel.once('show', resolve);
panel.show();
});
assert.pass('panel shown');
yield new Promise(resolve => {
panel.port.once('echo', resolve);
panel.once('show', _ => {
assert.pass('panel shown');
panel.port.once('echo', _ => {
assert.pass('got echo');
panel.destroy();
assert.pass('panel is destroyed');
done();
});
panel.port.emit('echo');
});
assert.pass('got echo');
panel.destroy();
assert.pass('panel is destroyed');
panel.show();
}
require('sdk/test/runner').runTestsFromModule(module);

View File

@ -147,6 +147,9 @@ exports["test compatibility"] = function(assert) {
assert.equal(require("tabs/tab.js"),
require("sdk/tabs/tab"), "sdk/tabs/tab -> tabs/tab.js");
assert.equal(require("memory"),
require("sdk/deprecated/memory"), "sdk/deprecated/memory -> memory");
assert.equal(require("environment"),
require("sdk/system/environment"), "sdk/system/environment -> environment");

View File

@ -33,6 +33,13 @@ function invalidResolve (assert) {
}
exports.invalidResolve = invalidResolve;
function invalidReject (assert) {
return function (e) {
assert.fail('Reject state should not be called: ' + e);
};
}
exports.invalidReject = invalidReject;
// Removes all children of group
function clearBookmarks (group) {
group

View File

@ -24,7 +24,7 @@ const {
MENU, TOOLBAR, UNSORTED
} = require('sdk/places/bookmarks');
const {
invalidResolve, createTree,
invalidResolve, invalidReject, createTree,
compareWithHost, createBookmark, createBookmarkItem,
createBookmarkTree, addVisits, resetPlaces
} = require('./places-helper');
@ -369,27 +369,28 @@ exports.testPromisedSave = function (assert, done) {
}).then(done).catch(assert.fail);
};
exports.testPromisedErrorSave = function*(assert) {
exports.testPromisedErrorSave = function (assert, done) {
let bookmarks = [
{ title: 'moz1', url: 'http://moz1.com', type: 'bookmark'},
{ title: 'moz2', url: 'invalidurl', type: 'bookmark'},
{ title: 'moz3', url: 'http://moz3.com', type: 'bookmark'}
];
yield saveP(bookmarks).then(() => {
assert.fail("should not resolve");
}, reason => {
saveP(bookmarks).then(invalidResolve, reason => {
assert.ok(
/The `url` property must be a valid URL/.test(reason),
'Error event called with correct reason');
});
bookmarks[1].url = 'http://moz2.com';
yield saveP(bookmarks);
let res = yield searchP({ query: 'moz' });
assert.equal(res.length, 3, 'all 3 should be saved upon retry');
res.map(item => assert.ok(/moz\d\.com/.test(item.url), 'correct item'));
bookmarks[1].url = 'http://moz2.com';
return saveP(bookmarks);
}).
then(res => searchP({ query: 'moz' })).
then(res => {
assert.equal(res.length, 3, 'all 3 should be saved upon retry');
res.map(item => assert.ok(/moz\d\.com/.test(item.url), 'correct item'));
done();
}, invalidReject).
catch(assert.fail);
};
exports.testMovingChildren = function (assert, done) {
@ -691,63 +692,61 @@ exports.testSearchTags = function (assert, done) {
* 'http://mozilla.com/'
* 'http://mozilla.com/*'
*/
exports.testSearchURLForBookmarks = function*(assert) {
yield createBookmarkTree()
let data = yield searchP({ url: 'mozilla.org' });
assert.equal(data.length, 2, 'only URLs with host domain');
assert.equal(data[0].url, 'http://mozilla.org/');
assert.equal(data[1].url, 'http://mozilla.org/thunderbird/');
data = yield searchP({ url: '*.mozilla.org' });
assert.equal(data.length, 3, 'returns domain and when host is other than domain');
assert.equal(data[0].url, 'http://mozilla.org/');
assert.equal(data[1].url, 'http://mozilla.org/thunderbird/');
assert.equal(data[2].url, 'http://developer.mozilla.org/en-US/');
data = yield searchP({ url: 'http://mozilla.org' });
assert.equal(data.length, 1, 'only exact URL match');
assert.equal(data[0].url, 'http://mozilla.org/');
data = yield searchP({ url: 'http://mozilla.org/*' });
assert.equal(data.length, 2, 'only URLs that begin with query');
assert.equal(data[0].url, 'http://mozilla.org/');
assert.equal(data[1].url, 'http://mozilla.org/thunderbird/');
data = yield searchP([{ url: 'mozilla.org' }, { url: 'component.fm' }]);
assert.equal(data.length, 3, 'returns URLs that match EITHER query');
assert.equal(data[0].url, 'http://mozilla.org/');
assert.equal(data[1].url, 'http://mozilla.org/thunderbird/');
assert.equal(data[2].url, 'http://component.fm/');
exports.testSearchURL = function (assert, done) {
createBookmarkTree().then(() => {
return searchP({ url: 'mozilla.org' });
}).then(data => {
assert.equal(data.length, 2, 'only URLs with host domain');
assert.equal(data[0].url, 'http://mozilla.org/');
assert.equal(data[1].url, 'http://mozilla.org/thunderbird/');
return searchP({ url: '*.mozilla.org' });
}).then(data => {
assert.equal(data.length, 3, 'returns domain and when host is other than domain');
assert.equal(data[0].url, 'http://mozilla.org/');
assert.equal(data[1].url, 'http://mozilla.org/thunderbird/');
assert.equal(data[2].url, 'http://developer.mozilla.org/en-US/');
return searchP({ url: 'http://mozilla.org' });
}).then(data => {
assert.equal(data.length, 1, 'only exact URL match');
assert.equal(data[0].url, 'http://mozilla.org/');
return searchP({ url: 'http://mozilla.org/*' });
}).then(data => {
assert.equal(data.length, 2, 'only URLs that begin with query');
assert.equal(data[0].url, 'http://mozilla.org/');
assert.equal(data[1].url, 'http://mozilla.org/thunderbird/');
return searchP([{ url: 'mozilla.org' }, { url: 'component.fm' }]);
}).then(data => {
assert.equal(data.length, 3, 'returns URLs that match EITHER query');
assert.equal(data[0].url, 'http://mozilla.org/');
assert.equal(data[1].url, 'http://mozilla.org/thunderbird/');
assert.equal(data[2].url, 'http://component.fm/');
}).then(done).catch(assert.fail);
};
/*
* Searches url, title, tags
*/
exports.testSearchQueryForBookmarks = function*(assert) {
yield createBookmarkTree();
let data = yield searchP({ query: 'thunder' });
assert.equal(data.length, 3);
assert.equal(data[0].title, 'mozilla.com', 'query matches tag, url, or title');
assert.equal(data[1].title, 'mozilla.org', 'query matches tag, url, or title');
assert.equal(data[2].title, 'thunderbird', 'query matches tag, url, or title');
data = yield searchP([{ query: 'rust' }, { query: 'component' }]);
// rust OR component
assert.equal(data.length, 3);
assert.equal(data[0].title, 'mozilla.com', 'query matches tag, url, or title');
assert.equal(data[1].title, 'mozilla.org', 'query matches tag, url, or title');
assert.equal(data[2].title, 'web audio components', 'query matches tag, url, or title');
data = yield searchP([{ query: 'moz', tags: ['javascript']}]);
assert.equal(data.length, 1);
assert.equal(data[0].title, 'mdn',
'only one item matches moz query AND has a javascript tag');
exports.testSearchQuery = function (assert, done) {
createBookmarkTree().then(() => {
return searchP({ query: 'thunder' });
}).then(data => {
assert.equal(data.length, 3);
assert.equal(data[0].title, 'mozilla.com', 'query matches tag, url, or title');
assert.equal(data[1].title, 'mozilla.org', 'query matches tag, url, or title');
assert.equal(data[2].title, 'thunderbird', 'query matches tag, url, or title');
return searchP([{ query: 'rust' }, { query: 'component' }]);
}).then(data => {
// rust OR component
assert.equal(data.length, 3);
assert.equal(data[0].title, 'mozilla.com', 'query matches tag, url, or title');
assert.equal(data[1].title, 'mozilla.org', 'query matches tag, url, or title');
assert.equal(data[2].title, 'web audio components', 'query matches tag, url, or title');
return searchP([{ query: 'moz', tags: ['javascript']}]);
}).then(data => {
assert.equal(data.length, 1);
assert.equal(data[0].title, 'mdn',
'only one item matches moz query AND has a javascript tag');
}).then(done).catch(assert.fail);
};
/*
@ -828,7 +827,7 @@ exports.testSearchCount = function (assert, done) {
}
};
exports.testSearchSortForBookmarks = function (assert, done) {
exports.testSearchSort = function (assert, done) {
let urls = [
'http://mozilla.com/', 'http://webaud.io/', 'http://mozilla.com/webfwd/',
'http://developer.mozilla.com/', 'http://bandcamp.com/'

View File

@ -27,7 +27,7 @@ const isOSX10_6 = (() => {
const { search } = require('sdk/places/history');
const {
invalidResolve, createTree, createBookmark,
invalidResolve, invalidReject, createTree, createBookmark,
compareWithHost, addVisits, resetPlaces, createBookmarkItem,
removeVisits, historyBatch
} = require('./places-helper');

View File

@ -19,44 +19,45 @@ const {
search
} = require('sdk/places/history');
const {
invalidResolve, createTree,
invalidResolve, invalidReject, createTree,
compareWithHost, addVisits, resetPlaces
} = require('./places-helper');
const { promisedEmitter } = require('sdk/places/utils');
exports.testEmptyQuery = function*(assert) {
exports.testEmptyQuery = function (assert, done) {
let within = toBeWithin();
yield addVisits([
addVisits([
'http://simplequery-1.com', 'http://simplequery-2.com'
]);
let results = yield searchP();
assert.equal(results.length, 2, 'Correct number of entries returned');
assert.equal(results[0].url, 'http://simplequery-1.com/',
'matches url');
assert.equal(results[1].url, 'http://simplequery-2.com/',
'matches url');
assert.equal(results[0].title, 'Test visit for ' + results[0].url,
'title matches');
assert.equal(results[1].title, 'Test visit for ' + results[1].url,
'title matches');
assert.equal(results[0].visitCount, 1, 'matches access');
assert.equal(results[1].visitCount, 1, 'matches access');
assert.ok(within(results[0].time), 'accurate access time');
assert.ok(within(results[1].time), 'accurate access time');
assert.equal(Object.keys(results[0]).length, 4,
'no addition exposed properties on history result');
]).then(searchP).then(results => {
assert.equal(results.length, 2, 'Correct number of entries returned');
assert.equal(results[0].url, 'http://simplequery-1.com/',
'matches url');
assert.equal(results[1].url, 'http://simplequery-2.com/',
'matches url');
assert.equal(results[0].title, 'Test visit for ' + results[0].url,
'title matches');
assert.equal(results[1].title, 'Test visit for ' + results[1].url,
'title matches');
assert.equal(results[0].visitCount, 1, 'matches access');
assert.equal(results[1].visitCount, 1, 'matches access');
assert.ok(within(results[0].time), 'accurate access time');
assert.ok(within(results[1].time), 'accurate access time');
assert.equal(Object.keys(results[0]).length, 4,
'no addition exposed properties on history result');
done();
}, invalidReject);
};
exports.testVisitCount = function*(assert) {
yield addVisits([
exports.testVisitCount = function (assert, done) {
addVisits([
'http://simplequery-1.com', 'http://simplequery-1.com',
'http://simplequery-1.com', 'http://simplequery-1.com'
]);
let results = yield searchP();
assert.equal(results.length, 1, 'Correct number of entries returned');
assert.equal(results[0].url, 'http://simplequery-1.com/', 'correct url');
assert.equal(results[0].visitCount, 4, 'matches access count');
]).then(searchP).then(results => {
assert.equal(results.length, 1, 'Correct number of entries returned');
assert.equal(results[0].url, 'http://simplequery-1.com/', 'correct url');
assert.equal(results[0].visitCount, 4, 'matches access count');
done();
}, invalidReject);
};
/*
@ -66,23 +67,24 @@ exports.testVisitCount = function*(assert) {
* 'http://mozilla.org/'
* 'http://mozilla.org/*'
*/
exports.testSearchURLForHistory = function*(assert) {
yield addVisits([
exports.testSearchURL = function (assert, done) {
addVisits([
'http://developer.mozilla.org', 'http://mozilla.org',
'http://mozilla.org/index', 'https://mozilla.org'
]);
let results = yield searchP({ url: 'http://mozilla.org/' });
assert.equal(results.length, 1, 'should just be an exact match');
results = yield searchP({ url: '*.mozilla.org' });
assert.equal(results.length, 4, 'returns all entries');
results = yield searchP({ url: 'mozilla.org' });
assert.equal(results.length, 3, 'returns entries where mozilla.org is host');
results = yield searchP({ url: 'http://mozilla.org/*' });
assert.equal(results.length, 2, 'should match anything starting with substring');
]).then(() => searchP({ url: '*.mozilla.org' }))
.then(results => {
assert.equal(results.length, 4, 'returns all entries');
return searchP({ url: 'mozilla.org' });
}).then(results => {
assert.equal(results.length, 3, 'returns entries where mozilla.org is host');
return searchP({ url: 'http://mozilla.org/' });
}).then(results => {
assert.equal(results.length, 1, 'should just be an exact match');
return searchP({ url: 'http://mozilla.org/*' });
}).then(results => {
assert.equal(results.length, 2, 'should match anything starting with substring');
done();
});
};
// Disabling due to intermittent Bug 892619
@ -122,21 +124,23 @@ exports.testSearchTimeRange = function (assert, done) {
});
};
*/
exports.testSearchQueryForHistory = function*(assert) {
yield addVisits([
exports.testSearchQuery = function (assert, done) {
addVisits([
'http://mozilla.com', 'http://webaud.io', 'http://mozilla.com/webfwd'
]);
let results = yield searchP({ query: 'moz' });
assert.equal(results.length, 2, 'should return urls that match substring');
results.map(({url}) => {
assert.ok(/moz/.test(url), 'correct item');
});
results = yield searchP([{ query: 'webfwd' }, { query: 'aud.io' }]);
assert.equal(results.length, 2, 'should OR separate queries');
results.map(({url}) => {
assert.ok(/webfwd|aud\.io/.test(url), 'correct item');
]).then(() => {
return searchP({ query: 'moz' });
}).then(results => {
assert.equal(results.length, 2, 'should return urls that match substring');
results.map(({url}) => {
assert.ok(/moz/.test(url), 'correct item');
});
return searchP([{ query: 'webfwd' }, { query: 'aud.io' }]);
}).then(results => {
assert.equal(results.length, 2, 'should OR separate queries');
results.map(({url}) => {
assert.ok(/webfwd|aud\.io/.test(url), 'correct item');
});
done();
});
};
@ -164,50 +168,51 @@ exports.testSearchCount = function (assert, done) {
}
};
exports.testSearchSortForHistory = function*(assert) {
exports.testSearchSort = function (assert, done) {
let places = [
'http://mozilla.com/', 'http://webaud.io/', 'http://mozilla.com/webfwd/',
'http://developer.mozilla.com/', 'http://bandcamp.com/'
];
addVisits(places).then(() => {
return searchP({}, { sort: 'title' });
}).then(results => {
checkOrder(results, [4,3,0,2,1]);
return searchP({}, { sort: 'title', descending: true });
}).then(results => {
checkOrder(results, [1,2,0,3,4]);
return searchP({}, { sort: 'url' });
}).then(results => {
checkOrder(results, [4,3,0,2,1]);
return searchP({}, { sort: 'url', descending: true });
}).then(results => {
checkOrder(results, [1,2,0,3,4]);
return addVisits('http://mozilla.com') // for visit conut
.then(() => addVisits('http://github.com')); // for checking date
}).then(() => {
return searchP({}, { sort: 'visitCount' });
}).then(results => {
assert.equal(results[5].url, 'http://mozilla.com/',
'last entry is the highest visit count');
return searchP({}, { sort: 'visitCount', descending: true });
}).then(results => {
assert.equal(results[0].url, 'http://mozilla.com/',
'first entry is the highest visit count');
return searchP({}, { sort: 'date' });
}).then(results => {
assert.equal(results[5].url, 'http://github.com/',
'latest visited should be first');
return searchP({}, { sort: 'date', descending: true });
}).then(results => {
assert.equal(results[0].url, 'http://github.com/',
'latest visited should be at the end');
}).then(done);
function checkOrder (results, nums) {
assert.equal(results.length, nums.length, 'expected return count');
for (let i = 0; i < nums.length; i++) {
assert.equal(results[i].url, places[nums[i]], 'successful order');
}
}
let places = [
'http://mozilla.com/', 'http://webaud.io/', 'http://mozilla.com/webfwd/',
'http://developer.mozilla.com/', 'http://bandcamp.com/'
];
yield addVisits(places);
let results = yield searchP({}, { sort: 'title' });
checkOrder(results, [4,3,0,2,1]);
results = yield searchP({}, { sort: 'title', descending: true });
checkOrder(results, [1,2,0,3,4]);
results = yield searchP({}, { sort: 'url' });
checkOrder(results, [4,3,0,2,1]);
results = yield searchP({}, { sort: 'url', descending: true });
checkOrder(results, [1,2,0,3,4]);
yield addVisits('http://mozilla.com'); // for visit conut
yield addVisits('http://github.com'); // for checking date
results = yield searchP({}, { sort: 'visitCount' });
assert.equal(results[5].url, 'http://mozilla.com/',
'last entry is the highest visit count');
results = yield searchP({}, { sort: 'visitCount', descending: true });
assert.equal(results[0].url, 'http://mozilla.com/',
'first entry is the highest visit count');
results = yield searchP({}, { sort: 'date' });
assert.equal(results[5].url, 'http://github.com/',
'latest visited should be first');
results = yield searchP({}, { sort: 'date', descending: true });
assert.equal(results[0].url, 'http://github.com/',
'latest visited should be at the end');
};
exports.testEmitters = function (assert, done) {

View File

@ -21,7 +21,7 @@ require('sdk/places/host/host-bookmarks');
require('sdk/places/host/host-tags');
require('sdk/places/host/host-query');
const {
invalidResolve, createTree,
invalidResolve, invalidReject, createTree,
compareWithHost, createBookmark, createBookmarkTree, resetPlaces
} = require('./places-helper');
@ -32,7 +32,7 @@ const hsrv = Cc['@mozilla.org/browser/nav-history-service;1'].
const tagsrv = Cc['@mozilla.org/browser/tagging-service;1'].
getService(Ci.nsITaggingService);
exports.testBookmarksCreate = function*(assert) {
exports.testBookmarksCreate = function (assert, done) {
let items = [{
title: 'my title',
url: 'http://test-places-host.com/testBookmarksCreate/',
@ -47,11 +47,13 @@ exports.testBookmarksCreate = function*(assert) {
group: bmsrv.unfiledBookmarksFolder
}];
yield all(items.map((item) => {
return send('sdk-places-bookmarks-create', item).then((data) => {
all(items.map(function (item) {
return send('sdk-places-bookmarks-create', item).then(function (data) {
compareWithHost(assert, data);
});
}));
}, invalidReject(assert));
})).then(function () {
done();
}, invalidReject(assert));
};
exports.testBookmarksCreateFail = function (assert, done) {

View File

@ -6,10 +6,10 @@
var { isNative } = require("@loader/options");
exports["test local vs sdk module"] = function (assert) {
assert.notEqual(require("list"),
require("sdk/util/list"),
assert.notEqual(require("memory"),
require("sdk/deprecated/memory"),
"Local module takes the priority over sdk modules");
assert.ok(require("list").local,
assert.ok(require("memory").local,
"this module is really the local one");
}

View File

@ -1,6 +1,5 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
exports.local = true;

View File

@ -9,10 +9,5 @@
</head>
<body>
<p>This is an add-on page test!</p>
<script>
function getTestURL() {
return window.document.documentURI + "";
}
</script>
</body>
</html>

View File

@ -1,21 +0,0 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<html>
<head>
<meta charset="UTF-8">
<title>Worker test</title>
</head>
<body>
<p id="paragraph">Lorem ipsum dolor sit amet.</p>
<script>
if ("addon" in window) {
var count = 1;
addon.port.on("get-result", () => {
addon.port.emit("result" + count++, extras.test().getTestURL())
});
}
</script>
</body>
</html>

View File

@ -1,31 +0,0 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<html>
<head>
<meta charset="UTF-8">
<title>Worker test</title>
</head>
<body>
<p id="paragraph">Lorem ipsum dolor sit amet.</p>
<script>
if ("addon" in window) {
var count = 1;
addon.port.on("get-result", () => {
console.log("get-result recieved");
addon.port.emit("result" + count++, extras && extras.test())
});
}
window.addEventListener("message", function getMessage({ data }) {
if (data.name == "start") {
window.postMessage({
name: "extras",
result: window.extras === undefined
}, '*');
}
}, false);
</script>
</body>
</html>

View File

@ -9,10 +9,5 @@
</head>
<body>
<p>bar</p>
<script>
function getTestURL() {
return window.document.documentURI + "";
}
</script>
</body>
</html>

View File

@ -4,27 +4,26 @@ support-files =
commonjs-test-adapter/**
context-menu/**
event/**
fixtures.js
fixtures/**
framescript-manager/**
framescript-util/**
lib/**
loader/**
lib/**
modules/**
pagemod-test-helpers.js
path/**
private-browsing/**
querystring/**
sidebar/**
tabs/**
test-context-menu.html
traits/**
util.js
windows/**
zip/**
fixtures.js
pagemod-test-helpers.js
test-context-menu.html
util.js
[test-addon-bootstrap.js]
[test-addon-extras.js]
[test-addon-installer.js]
[test-addon-window.js]
[test-api-utils.js]
@ -34,6 +33,7 @@ support-files =
[test-browser-events.js]
[test-buffer.js]
[test-byte-streams.js]
[test-bond.js]
[test-child_process.js]
[test-chrome.js]
[test-clipboard.js]
@ -72,20 +72,19 @@ skip-if = true
[test-hotkeys.js]
[test-httpd.js]
[test-indexed-db.js]
[test-jetpack-id.js]
[test-keyboard-observer.js]
[test-keyboard-utils.js]
[test-lang-type.js]
[test-l10n-locale.js]
[test-l10n-plural-rules.js]
[test-lang-type.js]
[test-libxul.js]
[test-list.js]
[test-loader.js]
[test-match-pattern.js]
[test-memory.js]
[test-method.js]
[test-module.js]
[test-modules.js]
[test-mozilla-toolkit-versioning.js]
[test-mpl2-license-header.js]
skip-if = true
[test-namespace.js]
@ -117,7 +116,6 @@ skip-if = true
[test-self.js]
[test-sequence.js]
[test-set-exports.js]
[test-shared-require.js]
[test-simple-prefs.js]
[test-simple-storage.js]
[test-system-events.js]

View File

@ -1,11 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
// Test module to check presense of user defined globals.
// Related to bug 827792.
exports.getCom = function() {
return com;
};

View File

@ -11,7 +11,6 @@ const { browserWindows: windows } = require('sdk/windows');
const { defer } = require('sdk/core/promise');
const tabs = require('sdk/tabs');
const { getMostRecentBrowserWindow } = require('sdk/window/utils');
const { cleanUI } = require("sdk/test/utils");
// test openDialog() from window/utils with private option
// test isActive state in pwpb case
@ -43,18 +42,15 @@ exports.testPerWindowPrivateBrowsingGetter = function*(assert) {
yield close(win)
}
exports.testIsPrivateOnWindowOpen = function*(assert) {
let window = yield new Promise(resolve => {
windows.open({
isPrivate: true,
onOpen: resolve
});
exports.testIsPrivateOnWindowOpen = function(assert, done) {
windows.open({
isPrivate: true,
onOpen: function(window) {
assert.equal(isPrivate(window), false, 'isPrivate for a window is true when it should be');
assert.equal(isPrivate(window.tabs[0]), false, 'isPrivate for a tab is false when it should be');
window.close(done);
}
});
assert.equal(isPrivate(window), false, 'isPrivate for a window is true when it should be');
assert.equal(isPrivate(window.tabs[0]), false, 'isPrivate for a tab is false when it should be');
yield cleanUI();
}
exports.testIsPrivateOnWindowOpenFromPrivate = function(assert, done) {

View File

@ -18,7 +18,6 @@ const { set: setPref } = require("sdk/preferences/service");
const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings";
const fixtures = require("../fixtures");
const { base64jpeg } = fixtures;
const { cleanUI, after } = require("sdk/test/utils");
// Bug 682681 - tab.title should never be empty
exports.testBug682681_aboutURI = function(assert, done) {
@ -373,28 +372,31 @@ exports.testTabMove = function(assert, done) {
}).then(null, assert.fail);
};
exports.testIgnoreClosing = function*(assert) {
let url = "data:text/html;charset=utf-8,foobar";
let originalWindow = getMostRecentBrowserWindow();
exports.testIgnoreClosing = function(assert, done) {
let originalWindow = viewFor(browserWindows.activeWindow);
openBrowserWindow(function(window, browser) {
onFocus(window).then(() => {
let url = "data:text/html;charset=utf-8,foobar";
let window = yield open().then(focus);
assert.equal(tabs.length, 2, "should be two windows open each with one tab");
assert.equal(tabs.length, 2, "should be two windows open each with one tab");
tabs.on('ready', function onReady(tab) {
tabs.removeListener('ready', onReady);
yield new Promise(resolve => {
tabs.once("ready", (tab) => {
let win = tab.window;
assert.equal(win.tabs.length, 2, "should be two tabs in the new window");
assert.equal(tabs.length, 3, "should be three tabs in total");
let win = tab.window;
assert.equal(win.tabs.length, 2, "should be two tabs in the new window");
assert.equal(tabs.length, 3, "should be three tabs in total");
tab.close(() => {
assert.equal(win.tabs.length, 1, "should be one tab in the new window");
assert.equal(tabs.length, 2, "should be two tabs in total");
resolve();
tab.close(function() {
assert.equal(win.tabs.length, 1, "should be one tab in the new window");
assert.equal(tabs.length, 2, "should be two tabs in total");
close(window).then(onFocus(originalWindow)).then(done).then(null, assert.fail);
});
});
});
tabs.open(url);
tabs.open(url);
});
});
};
@ -535,23 +537,23 @@ exports.testTabsEvent_onOpen = function(assert, done) {
};
// TEST: onClose event handler
exports.testTabsEvent_onClose = function*(assert) {
let window = yield open().then(focus);
let url = "data:text/html;charset=utf-8,onclose";
let eventCount = 0;
exports.testTabsEvent_onClose = function(assert, done) {
open().then(focus).then(window => {
let url = "data:text/html;charset=utf-8,onclose";
let eventCount = 0;
// add listener via property assignment
function listener1(tab) {
eventCount++;
}
tabs.on("close", listener1);
// add listener via property assignment
function listener1(tab) {
eventCount++;
}
tabs.on('close', listener1);
yield new Promise(resolve => {
// add listener via collection add
tabs.on("close", function listener2(tab) {
tabs.on('close', function listener2(tab) {
assert.equal(++eventCount, 2, "both listeners notified");
tabs.removeListener("close", listener2);
resolve();
tabs.removeListener('close', listener1);
tabs.removeListener('close', listener2);
close(window).then(done).then(null, assert.fail);
});
tabs.on('ready', function onReady(tab) {
@ -560,13 +562,7 @@ exports.testTabsEvent_onClose = function*(assert) {
});
tabs.open(url);
});
tabs.removeListener("close", listener1);
assert.pass("done test!");
yield close(window);
assert.pass("window was closed!");
}).then(null, assert.fail);
};
// TEST: onClose event handler when a window is closed
@ -675,38 +671,32 @@ exports.testTabsEvent_onActivate = function(assert, done) {
};
// onDeactivate event handler
exports.testTabsEvent_onDeactivate = function*(assert) {
let window = yield open().then(focus);
exports.testTabsEvent_onDeactivate = function(assert, done) {
open().then(focus).then(window => {
let url = "data:text/html;charset=utf-8,ondeactivate";
let eventCount = 0;
let url = "data:text/html;charset=utf-8,ondeactivate";
let eventCount = 0;
// add listener via property assignment
function listener1(tab) {
eventCount++;
};
tabs.on('deactivate', listener1);
// add listener via property assignment
function listener1(tab) {
eventCount++;
assert.pass("listener1 was called " + eventCount);
};
tabs.on('deactivate', listener1);
yield new Promise(resolve => {
// add listener via collection add
tabs.on('deactivate', function listener2(tab) {
assert.equal(++eventCount, 2, "both listeners notified");
tabs.removeListener('deactivate', listener1);
tabs.removeListener('deactivate', listener2);
resolve();
close(window).then(done).then(null, assert.fail);
});
tabs.on('open', function onOpen(tab) {
assert.pass("tab opened");
tabs.removeListener('open', onOpen);
tabs.open("data:text/html;charset=utf-8,foo");
});
tabs.open(url);
});
tabs.removeListener('deactivate', listener1);
assert.pass("listeners were removed");
}).then(null, assert.fail);
};
// pinning
@ -736,16 +726,13 @@ exports.testTabsEvent_pinning = function(assert, done) {
};
// TEST: per-tab event handlers
exports.testPerTabEvents = function*(assert) {
let window = yield open().then(focus);
let eventCount = 0;
exports.testPerTabEvents = function(assert, done) {
open().then(focus).then(window => {
let eventCount = 0;
let tab = yield new Promise(resolve => {
tabs.open({
url: "data:text/html;charset=utf-8,foo",
onOpen: (tab) => {
assert.pass("the tab was opened");
onOpen: function(tab) {
// add listener via property assignment
function listener1() {
eventCount++;
@ -754,18 +741,14 @@ exports.testPerTabEvents = function*(assert) {
// add listener via collection add
tab.on('ready', function listener2() {
assert.equal(eventCount, 1, "listener1 called before listener2");
assert.equal(eventCount, 1, "both listeners notified");
tab.removeListener('ready', listener1);
tab.removeListener('ready', listener2);
assert.pass("removed listeners");
eventCount++;
resolve();
close(window).then(done).then(null, assert.fail);
});
}
});
});
assert.equal(eventCount, 2, "both listeners were notified.");
}).then(null, assert.fail);
};
exports.testAttachOnOpen = function (assert, done) {
@ -1220,10 +1203,6 @@ exports.testTabDestroy = function(assert, done) {
})
};
after(exports, function*(name, assert) {
yield cleanUI();
});
/******************* helpers *********************/
// Utility function to open a new browser window.

View File

@ -1,171 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Ci, Cu, Cc, components } = require("chrome");
const self = require("sdk/self");
const { before, after } = require("sdk/test/utils");
const fixtures = require("./fixtures");
const { Loader } = require("sdk/test/loader");
const { merge } = require("sdk/util/object");
exports["test changing result from addon extras in panel"] = function(assert, done) {
let loader = Loader(module, null, null, {
modules: {
"sdk/self": merge({}, self, {
data: merge({}, self.data, {url: fixtures.url})
})
}
});
const { Panel } = loader.require("sdk/panel");
const { events } = loader.require("sdk/content/sandbox/events");
const { on } = loader.require("sdk/event/core");
const { isAddonContent } = loader.require("sdk/content/utils");
var result = 1;
var extrasVal = {
test: function() {
return result;
}
};
on(events, "content-script-before-inserted", ({ window, worker }) => {
assert.pass("content-script-before-inserted");
if (isAddonContent({ contentURL: window.location.href })) {
let extraStuff = Cu.cloneInto(extrasVal, window, {
cloneFunctions: true
});
getUnsafeWindow(window).extras = extraStuff;
assert.pass("content-script-before-inserted done!");
}
});
let panel = Panel({
contentURL: "./test-addon-extras.html"
});
panel.port.once("result1", (result) => {
assert.equal(result, 1, "result is a number");
result = true;
panel.port.emit("get-result");
});
panel.port.once("result2", (result) => {
assert.equal(result, true, "result is a boolean");
loader.unload();
done();
});
panel.port.emit("get-result");
}
exports["test window result from addon extras in panel"] = function*(assert) {
let loader = Loader(module, null, null, {
modules: {
"sdk/self": merge({}, self, {
data: merge({}, self.data, {url: fixtures.url})
})
}
});
const { Panel } = loader.require('sdk/panel');
const { Page } = loader.require('sdk/page-worker');
const { getActiveView } = loader.require("sdk/view/core");
const { getDocShell } = loader.require('sdk/frame/utils');
const { events } = loader.require("sdk/content/sandbox/events");
const { on } = loader.require("sdk/event/core");
const { isAddonContent } = loader.require("sdk/content/utils");
// make a page worker and wait for it to load
var page = yield new Promise(resolve => {
assert.pass("Creating the background page");
let page = Page({
contentURL: "./test.html",
contentScriptWhen: "end",
contentScript: "self.port.emit('end', unsafeWindow.getTestURL() + '')"
});
page.port.once("end", (url) => {
assert.equal(url, fixtures.url("./test.html"), "url is correct");
resolve(page);
});
});
assert.pass("Created the background page");
var extrasVal = {
test: function() {
assert.pass("start test function");
let frame = getActiveView(page);
let window = getUnsafeWindow(frame.contentWindow);
assert.equal(typeof window.getTestURL, "function", "window.getTestURL is a function");
return window;
}
};
on(events, "content-script-before-inserted", ({ window, worker }) => {
let url = window.location.href;
assert.pass("content-script-before-inserted " + url);
if (isAddonContent({ contentURL: url })) {
let extraStuff = Cu.cloneInto(extrasVal, window, {
cloneFunctions: true
});
getUnsafeWindow(window).extras = extraStuff;
assert.pass("content-script-before-inserted done!");
}
});
let panel = Panel({
contentURL: "./test-addon-extras-window.html"
});
yield new Promise(resolve => {
panel.port.once("result1", (result) => {
assert.equal(result, fixtures.url("./test.html"), "result1 is a window");
resolve();
});
assert.pass("emit get-result");
panel.port.emit("get-result");
});
page.destroy();
page = yield new Promise(resolve => {
let page = Page({
contentURL: "./index.html",
contentScriptWhen: "end",
contentScript: "self.port.emit('end')"
});
page.port.once("end", () => resolve(page));
});
yield new Promise(resolve => {
panel.port.once("result2", (result) => {
assert.equal(result, fixtures.url("./index.html"), "result2 is a window");
resolve();
});
assert.pass("emit get-result");
panel.port.emit("get-result");
});
loader.unload();
}
function getUnsafeWindow (win) {
return win.wrappedJSObject || win;
}
require("sdk/test").run(exports);

View File

@ -0,0 +1,169 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Bond } = require("sdk/util/bond");
const { Class } = require("sdk/core/heritage");
exports["test bonds on constructors"] = assert => {
const MyClass = function(name) {
this.name = name;
}
MyClass.prototype = Bond({
hello() {
return `Hello my name is ${this.name}`
}
})
Object.assign(MyClass.prototype, {
constructor: MyClass,
readName() {
return this.name
}
});
const i1 = new MyClass("James Bond");
assert.equal(i1.hello(), "Hello my name is James Bond");
assert.equal(i1.hello.call({name: "Hack"}), "Hello my name is James Bond");
assert.equal(i1.readName(), "James Bond");
assert.equal(i1.readName.call({name: "Hack"}), "Hack");
const hello = i1.hello
assert.equal(hello(), "Hello my name is James Bond");
};
exports["test subclassing"] = assert => {
const MyClass = function(name) {
this.name = name;
}
MyClass.prototype = Bond({
hello() {
return `Hello my name is ${this.name}`
}
});
const i1 = new MyClass("James Bond");
assert.equal(i1.hello(), "Hello my name is James Bond");
assert.equal(i1.hello.call({name: "Hack"}), "Hello my name is James Bond");
const i1Hello = i1.hello
assert.equal(i1Hello(), "Hello my name is James Bond");
const MySubClass = function(...args) {
MyClass.call(this, ...args)
}
MySubClass.prototype = Object.create(MyClass.prototype)
const i2 = new MySubClass("Your father");
assert.equal(i2.hello(), "Hello my name is Your father");
assert.equal(i2.hello.call({name: "Hack"}), "Hello my name is Your father");
const i2Hello = i2.hello
assert.equal(i2Hello(), "Hello my name is Your father");
};
exports["test access on prototype"] = assert => {
const MyClass = function(name) {
this.name = name;
}
MyClass.prototype = Bond({
hello() {
return `Hello my name is ${this.name}`
}
});
assert.equal(MyClass.prototype.hello(), "Hello my name is undefined");
assert.ok(Object.getOwnPropertyDescriptor(MyClass.prototype, "hello").get,
"hello is still a getter");
assert.equal(MyClass.prototype.hello.call({name: "this"}),
"Hello my name is this",
"passing `this` on prototype methods work");
const i1 = new MyClass("James Bond");
assert.equal(i1.hello(), "Hello my name is James Bond");
assert.ok(!Object.getOwnPropertyDescriptor(i1, "hello").get,
"hello is not a getter on instance");
assert.equal(i1.hello.call({name: "Hack"}), "Hello my name is James Bond");
const i1Hello = i1.hello
assert.equal(i1Hello(), "Hello my name is James Bond");
};
exports["test bonds with Class"] = assert => {
const MyClass = Class({
extends: Bond({
hello() {
return `Hello my name is ${this.name}`
}
}),
initialize(name) {
this.name = name;
}
});
const i1 = new MyClass("James Bond");
assert.equal(i1.hello(), "Hello my name is James Bond");
assert.equal(i1.hello.call({name: "Hack"}), "Hello my name is James Bond");
const hello = i1.hello
assert.equal(hello(), "Hello my name is James Bond");
};
exports["test with mixin"] = assert => {
const MyClass = Class({
implements: [
Bond({
hello() {
return `Hello my name is ${this.name}`
}
})
],
initialize(name) {
this.name = name;
}
});
const i1 = new MyClass("James Bond");
assert.equal(i1.hello(), "Hello my name is James Bond");
assert.equal(i1.hello.call({name: "Hack"}), "Hello my name is James Bond");
const hello = i1.hello
assert.equal(hello(), "Hello my name is James Bond");
const MyComposedClass = Class({
implements: [
MyClass,
Bond({
bye() {
return `Bye ${this.name}`
}
})
],
initialize(name) {
this.name = name;
}
});
const i2 = new MyComposedClass("Major Tom");
assert.equal(i2.hello(), "Hello my name is Major Tom");
assert.equal(i2.hello.call({name: "Hack"}), "Hello my name is Major Tom");
const i2Hello = i2.hello
assert.equal(i2Hello(), "Hello my name is Major Tom");
assert.equal(i2.bye(), "Bye Major Tom");
assert.equal(i2.bye.call({name: "Hack"}), "Bye Major Tom");
const i2Bye = i2.bye
assert.equal(i2Bye(), "Bye Major Tom");
};
require("sdk/test").run(exports);

View File

@ -1,6 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { pathFor } = require('sdk/system');

View File

@ -524,22 +524,4 @@ exports['test lazy globals'] = function (assert) {
assert.ok(gotFoo, "foo has been accessed only when we first try to use it");
};
exports['test user global'] = function(assert) {
// Test case for bug 827792
let com = {};
let loader = require('toolkit/loader');
let loadOptions = require('@loader/options');
let options = loader.override(loadOptions,
{globals: loader.override(loadOptions.globals,
{com: com,
console: console,
dump: dump})});
let subloader = loader.Loader(options);
let userRequire = loader.Require(subloader, module);
let userModule = userRequire("./loader/user-global");
assert.equal(userModule.getCom(), com,
"user module returns expected `com` global");
};
require('sdk/test').run(exports);

View File

@ -0,0 +1,22 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const memory = require("sdk/deprecated/memory");
const { gc } = require("sdk/test/memory");
exports.testMemory = function(assert) {
var obj = {};
memory.track(obj, "testMemory.testObj");
var objs = memory.getObjects("testMemory.testObj");
assert.equal(objs[0].weakref.get(), obj);
obj = null;
gc().then(function() {
assert.equal(objs[0].weakref.get(), null);
});
};
require('sdk/test').run(exports);

View File

@ -10,8 +10,6 @@ const { id } = require("sdk/self");
const { getAddonByID } = require("sdk/addon/manager");
const { mapcat, map, filter, fromEnumerator } = require("sdk/util/sequence");
const { readURISync } = require('sdk/net/url');
const { Request } = require('sdk/request');
const { defer } = require("sdk/core/promise");
const ios = Cc['@mozilla.org/network/io-service;1'].
getService(Ci.nsIIOService);
@ -59,42 +57,26 @@ const getEntries = directory => mapcat(entry => {
return [];
}, filter(() => true, getDirectoryEntries(directory)));
function readURL(url) {
let { promise, resolve } = defer();
Request({
url: url,
overrideMimeType: "text/plain",
onComplete: (response) => resolve(response.text)
}).get();
return promise;
}
exports["test MPL2 license header"] = function*(assert) {
let addon = yield getAddonByID(id);
let xpiURI = addon.getResourceURI();
let rootURL = xpiURI.spec;
assert.ok(rootURL, rootURL);
let files = [...getEntries(xpiURI.QueryInterface(Ci.nsIFileURL).file)];
assert.ok(files.length > 1, files.length + " files found.");
let failures = [];
let success = 0;
for (let i = 0, len = files.length; i < len; i++) {
let file = files[i];
assert.ok(file.path, "Trying " + file.path);
files.forEach(file => {
const URI = ios.newFileURI(file);
let leafName = URI.spec.replace(rootURL, "");
let contents = readURISync(URI);
let contents = yield readURL(URI.spec);
if (!MPL2_LICENSE_TEST.test(contents)) {
failures.push(leafName);
}
}
});
assert.equal(1, failures.length, "we expect one failure");
assert.ok(/test-mpl2-license-header\.js$/.test(failures[0]), "the only failure is this file");

View File

@ -123,6 +123,7 @@ exports.testWaitUntilTimeoutInCallback = function(test) {
expected.push(["print", "TEST-START | wait4ever\n"]);
expected.push(["error", "fail:", "Timed out (after: START)"]);
expected.push(["error", "test assertion never became true:\n", "assertion failed, value is false\n"]);
expected.push(["print", "TEST-END | wait4ever\n"]);
}
else {
expected.push(["info", "executing 'wait4ever'"]);
@ -131,19 +132,17 @@ exports.testWaitUntilTimeoutInCallback = function(test) {
}
function checkExpected(name, args) {
var index = message;
if (message++ >= expected.length) {
if (expected.length == 0 || expected[0][0] != name) {
test.fail("Saw an unexpected console." + name + "() call " + args);
return;
}
let expectedArgs = expected[index].slice(1);
for (let i = 0; i < expectedArgs.length; i++) {
message++;
let expectedArgs = expected.shift().slice(1);
for (let i = 0; i < expectedArgs.length; i++)
test.assertEqual(args[i], expectedArgs[i], "Should have seen the right message in argument " + i + " of message " + message);
}
if (message >= expected.length) {
if (expected.length == 0)
test.done();
}
}
let runner = new (require("sdk/deprecated/unit-test").TestRunner)({

View File

@ -1,81 +1,118 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
'use strict';
const { Cu } = require("chrome");
const memory = require("sdk/test/memory");
const { add, remove, has, clear, iterator } = require("sdk/lang/weak-set");
const { setInterval, clearInterval } = require("sdk/timers");
const { Cu } = require('chrome');
const { Loader } = require('sdk/test/loader');
const { gc } = require("sdk/test/memory");
function gc(assert) {
let wait = 1;
let interval = setInterval(function() {
assert.pass("waited " + (wait++ * 0.250) + "secs for gc()..");
}, 250);
return memory.gc().then(() => {
assert.pass("gc completed!");
clearInterval(interval);
});
}
exports['test add/remove/iterate/clear item'] = function*(assert) {
let addItems = {};
let removeItems = {};
let iterateItems = {};
let clearItems = {};
let nonReferencedItems = {};
exports['test adding item'] = function*(assert) {
let loader = Loader(module);
let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set');
let items = {};
let item = {};
add(items, item);
yield gc();
assert.ok(has(items, item), 'the item is in the weak set');
loader.unload();
};
exports['test remove item'] = function*(assert) {
let loader = Loader(module);
let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set');
let items = {};
let item = {};
add(items, item);
remove(items, item);
yield gc();
assert.ok(!has(items, item), 'the item is not in weak set');
loader.unload();
};
exports['test iterate'] = function*(assert) {
let loader = Loader(module);
let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set');
let items = {};
let addedItems = [{}, {}];
assert.pass("adding things to items");
add(addItems, item);
add(removeItems, item);
add(iterateItems, addedItems[0]);
add(iterateItems, addedItems[1]);
add(iterateItems, addedItems[0]); // weak set shouldn't add this twice
add(clearItems, addedItems[0]);
add(clearItems, addedItems[1]);
add(nonReferencedItems, {});
add(items, addedItems[0]);
add(items, addedItems[1]);
add(items, addedItems[0]); // weak set shouldn't add this twice
assert.pass("removing things from removeItems");
remove(removeItems, item);
assert.pass("clear things from clearItems");
clear(clearItems);
assert.pass("starting gc..");
yield gc(assert);
yield gc();
let count = 0;
assert.equal(has(addItems, item), true, 'the addItems is in the weak set');
assert.equal(has(removeItems, item), false, 'the removeItems is not in weak set');
for (let item of iterator(items)) {
assert.equal(item, addedItems[count],
'item in the expected order');
assert.pass("iterating iterateItems..");
for (let item of iterator(iterateItems)) {
assert.equal(item, addedItems[count], "item in the expected order");
count++;
}
assert.equal(count, 2, 'items in the expected number');
loader.unload();
};
assert.pass("iterating clearItems..");
for (let item of iterator(clearItems)) {
assert.fail("the loop should not be executed");
count++
exports['test clear'] = function*(assert) {
let loader = Loader(module);
let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set');
let items = {};
let addedItems = [{}, {}];
add(items, addedItems[0]);
add(items, addedItems[1]);
clear(items)
yield gc();
let count = 0;
for (let item of iterator(items)) {
assert.fail('the loop should not be executed');
}
for (let item of iterator(nonReferencedItems)) {
assert.fail("the loop should not be executed");
count++
assert.equal(count, 0, 'no items in the weak set');
loader.unload();
};
exports['test adding item without reference'] = function*(assert) {
let loader = Loader(module);
let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set');
let items = {};
add(items, {});
yield gc();
let count = 0;
for (let item of iterator(items)) {
assert.fail('the loop should not be executed');
}
assert.equal(count, 2, 'items in the expected number');
assert.equal(count, 0, 'no items in the weak set');
loader.unload();
};
exports['test adding non object or null item'] = function(assert) {
let loader = Loader(module);
let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set');
let items = {};
assert.throws(() => {
@ -110,6 +147,9 @@ exports['test adding non object or null item'] = function(assert) {
};
exports['test adding to non object or null item'] = function(assert) {
let loader = Loader(module);
let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set');
let item = {};
assert.throws(() => {
@ -143,4 +183,4 @@ exports['test adding to non object or null item'] = function(assert) {
'only non-null object are allowed');
};
require("sdk/test").run(exports);
require('sdk/test').run(exports);

View File

@ -10,7 +10,6 @@ const { viewFor } = require('sdk/view/core');
const { modelFor } = require('sdk/model/core');
const { Ci } = require("chrome");
const { isBrowser, getWindowTitle } = require("sdk/window/utils");
const { after, cleanUI } = require("sdk/test/utils");
// TEST: browserWindows Iterator
exports.testBrowserWindowsIterator = function(assert) {
@ -66,18 +65,20 @@ exports.testWindowActivateMethod_simple = function(assert) {
};
exports["test getView(window)"] = function*(assert) {
let window = yield new Promise(resolve => {
browserWindows.once("open", resolve);
browserWindows.open({ url: "data:text/html;charset=utf-8,<title>yo</title>" });
exports["test getView(window)"] = function(assert, done) {
browserWindows.once("open", window => {
const view = viewFor(window);
assert.ok(view instanceof Ci.nsIDOMWindow, "view is a window");
assert.ok(isBrowser(view), "view is a browser window");
assert.equal(getWindowTitle(view), window.title,
"window has a right title");
window.close(done);
});
const view = viewFor(window);
assert.ok(view instanceof Ci.nsIDOMWindow, "view is a window");
assert.ok(isBrowser(view), "view is a browser window");
assert.equal(getWindowTitle(view), window.title,
"window has a right title");
browserWindows.open({ url: "data:text/html;charset=utf-8,<title>yo</title>" });
};
@ -96,9 +97,4 @@ exports["test modelFor(window)"] = function(assert, done) {
browserWindows.open({ url: "data:text/html;charset=utf-8,<title>yo</title>" });
};
after(exports, function*(name, assert) {
assert.pass("cleaning the ui.");
yield cleanUI();
});
require('sdk/test').run(exports);

View File

@ -1,11 +1,10 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var xulApp = require("sdk/system/xul-app");
exports["test xulapp"] = function (assert) {
exports["test xulapp"] = function(assert) {
assert.equal(typeof(xulApp.ID), "string",
"ID is a string");
assert.equal(typeof(xulApp.name), "string",
@ -15,26 +14,26 @@ exports["test xulapp"] = function (assert) {
assert.equal(typeof(xulApp.platformVersion), "string",
"platformVersion is a string");
assert.throws(() => xulApp.is("blargy"),
/Unkown Mozilla Application: blargy/,
"is() throws error on bad app name");
assert.throws(() => xulApp.isOneOf(["blargy"]),
/Unkown Mozilla Application: blargy/,
"isOneOf() throws error on bad app name");
assert.throws(function() { xulApp.is("blargy"); },
/Unkown Mozilla Application: blargy/,
"is() throws error on bad app name");
assert.throws(function() { xulApp.isOneOf(["blargy"]); },
/Unkown Mozilla Application: blargy/,
"isOneOf() throws error on bad app name");
function testSupport(name) {
var item = xulApp.is(name);
assert.ok(item === true || item === false,
"is('" + name + "') is true or false.");
"is('" + name + "') is true or false.");
}
var apps = ["Firefox", "Mozilla", "SeaMonkey", "Fennec", "Thunderbird"];
apps.forEach(testSupport);
assert.ok(xulApp.isOneOf(apps) == true || xulApp.isOneOf(apps) == false,
"isOneOf() returns true or false.");
assert.ok(xulApp.isOneOf(apps) == true ||
xulApp.isOneOf(apps) == false,
"isOneOf() returns true or false.");
assert.equal(xulApp.versionInRange(xulApp.platformVersion, "1.9", "*"),
true, "platformVersion in range [1.9, *)");

View File

@ -327,6 +327,7 @@ exports.testTrackWindows = function(assert, done) {
// listen to global deactivate events
browserWindows.on("deactivate", windowsDeactivation);
function openWindow() {
windows.push(browserWindows.open({
url: "data:text/html;charset=utf-8,<i>testTrackWindows</i>",
@ -349,10 +350,8 @@ exports.testTrackWindows = function(assert, done) {
else {
(function closeWindows(windows) {
if (!windows.length) {
assert.pass('the last window was closed');
browserWindows.removeListener("activate", windowsActivation);
browserWindows.removeListener("deactivate", windowsDeactivation);
assert.pass('removed listeners');
return done();
}