mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 15:28:39 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
6
devtools/shared/tests/unit/.eslintrc.js
Normal file
6
devtools/shared/tests/unit/.eslintrc.js
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
// Extend from the common devtools xpcshell eslintrc config.
|
||||
"extends": "../../../.eslintrc.xpcshell.js"
|
||||
};
|
||||
8
devtools/shared/tests/unit/exposeLoader.js
Normal file
8
devtools/shared/tests/unit/exposeLoader.js
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
exports.exerciseLazyRequire = (name, path) => {
|
||||
const o = {};
|
||||
loader.lazyRequireGetter(o, name, path);
|
||||
return o;
|
||||
};
|
||||
60
devtools/shared/tests/unit/head_devtools.js
Normal file
60
devtools/shared/tests/unit/head_devtools.js
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
var Cu = Components.utils;
|
||||
var Cr = Components.results;
|
||||
|
||||
const {require, DevToolsLoader, devtools} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
const flags = require("devtools/shared/flags");
|
||||
|
||||
flags.testing = true;
|
||||
do_register_cleanup(() => {
|
||||
flags.testing = false;
|
||||
});
|
||||
|
||||
// Register a console listener, so console messages don't just disappear
|
||||
// into the ether.
|
||||
|
||||
// If for whatever reason the test needs to post console errors that aren't
|
||||
// failures, set this to true.
|
||||
var ALLOW_CONSOLE_ERRORS = false;
|
||||
|
||||
var errorCount = 0;
|
||||
var listener = {
|
||||
observe: function (aMessage) {
|
||||
errorCount++;
|
||||
try {
|
||||
// If we've been given an nsIScriptError, then we can print out
|
||||
// something nicely formatted, for tools like Emacs to pick up.
|
||||
var scriptError = aMessage.QueryInterface(Ci.nsIScriptError);
|
||||
dump(aMessage.sourceName + ":" + aMessage.lineNumber + ": " +
|
||||
scriptErrorFlagsToKind(aMessage.flags) + ": " +
|
||||
aMessage.errorMessage + "\n");
|
||||
var string = aMessage.errorMessage;
|
||||
} catch (x) {
|
||||
// Be a little paranoid with message, as the whole goal here is to lose
|
||||
// no information.
|
||||
try {
|
||||
var string = "" + aMessage.message;
|
||||
} catch (x) {
|
||||
var string = "<error converting error message to string>";
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we exit all nested event loops so that the test can finish.
|
||||
while (DebuggerServer.xpcInspector.eventLoopNestLevel > 0) {
|
||||
DebuggerServer.xpcInspector.exitNestedEventLoop();
|
||||
}
|
||||
|
||||
if (!ALLOW_CONSOLE_ERRORS) {
|
||||
do_throw("head_devtools.js got console message: " + string + "\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var consoleService = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
|
||||
consoleService.registerListener(listener);
|
||||
36
devtools/shared/tests/unit/test_assert.js
Normal file
36
devtools/shared/tests/unit/test_assert.js
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test DevToolsUtils.assert
|
||||
|
||||
ALLOW_CONSOLE_ERRORS = true;
|
||||
|
||||
function run_test() {
|
||||
// Enable assertions.
|
||||
flags.testing = true;
|
||||
|
||||
const { assert } = DevToolsUtils;
|
||||
equal(typeof assert, "function");
|
||||
|
||||
try {
|
||||
assert(true, "this assertion should not fail");
|
||||
} catch (e) {
|
||||
// If you catch assertion failures in practice, I will hunt you down. I get
|
||||
// email notifications every time it happens.
|
||||
ok(false, "Should not get an error for an assertion that should not fail. Got "
|
||||
+ DevToolsUtils.safeErrorString(e));
|
||||
}
|
||||
|
||||
let assertionFailed = false;
|
||||
try {
|
||||
assert(false, "this assertion should fail");
|
||||
} catch (e) {
|
||||
ok(e.message.startsWith("Assertion failure:"),
|
||||
"Should be an assertion failure error");
|
||||
assertionFailed = true;
|
||||
}
|
||||
|
||||
ok(assertionFailed,
|
||||
"The assertion should have failed, which should throw an error when assertions are enabled.");
|
||||
}
|
||||
157
devtools/shared/tests/unit/test_async-utils.js
Normal file
157
devtools/shared/tests/unit/test_async-utils.js
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test async-utils.js
|
||||
|
||||
const {Task} = require("devtools/shared/task");
|
||||
// |const| will not work because
|
||||
// it will make the Promise object immutable before assigning.
|
||||
// Using Object.defineProperty() instead.
|
||||
Object.defineProperty(this, "Promise", {
|
||||
value: require("promise"),
|
||||
writable: false, configurable: false
|
||||
});
|
||||
const {asyncOnce, promiseInvoke, promiseCall} = require("devtools/shared/async-utils");
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
Task.spawn(function* () {
|
||||
yield test_async_args(asyncOnce);
|
||||
yield test_async_return(asyncOnce);
|
||||
yield test_async_throw(asyncOnce);
|
||||
|
||||
yield test_async_once();
|
||||
yield test_async_invoke();
|
||||
do_test_finished();
|
||||
}).then(null, error => {
|
||||
do_throw(error);
|
||||
});
|
||||
}
|
||||
|
||||
// Test that arguments are correctly passed through to the async function.
|
||||
function test_async_args(async) {
|
||||
let obj = {
|
||||
method: async(function* (a, b) {
|
||||
do_check_eq(this, obj);
|
||||
do_check_eq(a, "foo");
|
||||
do_check_eq(b, "bar");
|
||||
})
|
||||
};
|
||||
|
||||
return obj.method("foo", "bar");
|
||||
}
|
||||
|
||||
// Test that the return value from the async function is resolution value of
|
||||
// the promise.
|
||||
function test_async_return(async) {
|
||||
let obj = {
|
||||
method: async(function* (a, b) {
|
||||
return a + b;
|
||||
})
|
||||
};
|
||||
|
||||
return obj.method("foo", "bar").then(ret => {
|
||||
do_check_eq(ret, "foobar");
|
||||
});
|
||||
}
|
||||
|
||||
// Test that the throwing from an async function rejects the promise.
|
||||
function test_async_throw(async) {
|
||||
let obj = {
|
||||
method: async(function* () {
|
||||
throw "boom";
|
||||
})
|
||||
};
|
||||
|
||||
return obj.method().then(null, error => {
|
||||
do_check_eq(error, "boom");
|
||||
});
|
||||
}
|
||||
|
||||
// Test that asyncOnce only runs the async function once per instance and
|
||||
// returns the same promise for that instance.
|
||||
function test_async_once() {
|
||||
let counter = 0;
|
||||
|
||||
function Foo() {}
|
||||
Foo.prototype = {
|
||||
ran: false,
|
||||
method: asyncOnce(function* () {
|
||||
yield Promise.resolve();
|
||||
if (this.ran) {
|
||||
do_throw("asyncOnce function unexpectedly ran twice on the same object");
|
||||
}
|
||||
this.ran = true;
|
||||
return counter++;
|
||||
})
|
||||
};
|
||||
|
||||
let foo1 = new Foo();
|
||||
let foo2 = new Foo();
|
||||
let p1 = foo1.method();
|
||||
let p2 = foo2.method();
|
||||
|
||||
do_check_neq(p1, p2);
|
||||
|
||||
let p3 = foo1.method();
|
||||
do_check_eq(p1, p3);
|
||||
do_check_false(foo1.ran);
|
||||
|
||||
let p4 = foo2.method();
|
||||
do_check_eq(p2, p4);
|
||||
do_check_false(foo2.ran);
|
||||
|
||||
return p1.then(ret => {
|
||||
do_check_true(foo1.ran);
|
||||
do_check_eq(ret, 0);
|
||||
return p2;
|
||||
}).then(ret => {
|
||||
do_check_true(foo2.ran);
|
||||
do_check_eq(ret, 1);
|
||||
});
|
||||
}
|
||||
|
||||
// Test invoke and call.
|
||||
function test_async_invoke() {
|
||||
return Task.spawn(function* () {
|
||||
function func(a, b, expectedThis, callback) {
|
||||
"use strict";
|
||||
do_check_eq(a, "foo");
|
||||
do_check_eq(b, "bar");
|
||||
do_check_eq(this, expectedThis);
|
||||
callback(a + b);
|
||||
}
|
||||
|
||||
// Test call.
|
||||
let callResult = yield promiseCall(func, "foo", "bar", undefined);
|
||||
do_check_eq(callResult, "foobar");
|
||||
|
||||
|
||||
// Test invoke.
|
||||
let obj = { method: func };
|
||||
let invokeResult = yield promiseInvoke(obj, obj.method, "foo", "bar", obj);
|
||||
do_check_eq(invokeResult, "foobar");
|
||||
|
||||
|
||||
// Test passing multiple values to the callback.
|
||||
function multipleResults(callback) {
|
||||
callback("foo", "bar");
|
||||
}
|
||||
|
||||
let results = yield promiseCall(multipleResults);
|
||||
do_check_eq(results.length, 2);
|
||||
do_check_eq(results[0], "foo");
|
||||
do_check_eq(results[1], "bar");
|
||||
|
||||
|
||||
// Test throwing from the function.
|
||||
function thrower() {
|
||||
throw "boom";
|
||||
}
|
||||
|
||||
yield promiseCall(thrower).then(null, error => {
|
||||
do_check_eq(error, "boom");
|
||||
});
|
||||
});
|
||||
}
|
||||
133
devtools/shared/tests/unit/test_console_filtering.js
Normal file
133
devtools/shared/tests/unit/test_console_filtering.js
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { console, ConsoleAPI } = require("resource://gre/modules/Console.jsm");
|
||||
const { ConsoleAPIListener } = require("devtools/server/actors/utils/webconsole-utils");
|
||||
const Services = require("Services");
|
||||
|
||||
var seenMessages = 0;
|
||||
var seenTypes = 0;
|
||||
|
||||
var callback = {
|
||||
onConsoleAPICall: function (aMessage) {
|
||||
if (aMessage.consoleID && aMessage.consoleID == "addon/foo") {
|
||||
do_check_eq(aMessage.level, "warn");
|
||||
do_check_eq(aMessage.arguments[0], "Warning from foo");
|
||||
seenTypes |= 1;
|
||||
} else if (aMessage.originAttributes &&
|
||||
aMessage.originAttributes.addonId == "bar") {
|
||||
do_check_eq(aMessage.level, "error");
|
||||
do_check_eq(aMessage.arguments[0], "Error from bar");
|
||||
seenTypes |= 2;
|
||||
} else {
|
||||
do_check_eq(aMessage.level, "log");
|
||||
do_check_eq(aMessage.arguments[0], "Hello from default console");
|
||||
seenTypes |= 4;
|
||||
}
|
||||
seenMessages++;
|
||||
}
|
||||
};
|
||||
|
||||
function createFakeAddonWindow({addonId} = {}) {
|
||||
let baseURI = Services.io.newURI("about:blank", null, null);
|
||||
let originAttributes = {addonId};
|
||||
let principal = Services.scriptSecurityManager
|
||||
.createCodebasePrincipal(baseURI, originAttributes);
|
||||
let chromeWebNav = Services.appShell.createWindowlessBrowser(true);
|
||||
let docShell = chromeWebNav.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell);
|
||||
docShell.createAboutBlankContentViewer(principal);
|
||||
let addonWindow = docShell.contentViewer.DOMDocument.defaultView;
|
||||
|
||||
return {addonWindow, chromeWebNav};
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the consoleID property of the ConsoleAPI options gets passed
|
||||
* through to console messages.
|
||||
*/
|
||||
function run_test() {
|
||||
// console1 Test Console.jsm messages tagged by the Addon SDK
|
||||
// are still filtered correctly.
|
||||
let console1 = new ConsoleAPI({
|
||||
consoleID: "addon/foo"
|
||||
});
|
||||
|
||||
// console2 - WebExtension page's console messages tagged
|
||||
// by 'originAttributes.addonId' are filtered correctly.
|
||||
let {addonWindow, chromeWebNav} = createFakeAddonWindow({addonId: "bar"});
|
||||
let console2 = addonWindow.console;
|
||||
|
||||
// console - Plain console object (messages are tagged with window ids
|
||||
// and originAttributes, but the addonId will be empty).
|
||||
console.log("Hello from default console");
|
||||
|
||||
console1.warn("Warning from foo");
|
||||
console2.error("Error from bar");
|
||||
|
||||
let listener = new ConsoleAPIListener(null, callback);
|
||||
listener.init();
|
||||
let messages = listener.getCachedMessages();
|
||||
|
||||
seenTypes = 0;
|
||||
seenMessages = 0;
|
||||
messages.forEach(callback.onConsoleAPICall);
|
||||
do_check_eq(seenMessages, 3);
|
||||
do_check_eq(seenTypes, 7);
|
||||
|
||||
seenTypes = 0;
|
||||
seenMessages = 0;
|
||||
console.log("Hello from default console");
|
||||
console1.warn("Warning from foo");
|
||||
console2.error("Error from bar");
|
||||
do_check_eq(seenMessages, 3);
|
||||
do_check_eq(seenTypes, 7);
|
||||
|
||||
listener.destroy();
|
||||
|
||||
listener = new ConsoleAPIListener(null, callback, {addonId: "foo"});
|
||||
listener.init();
|
||||
messages = listener.getCachedMessages();
|
||||
|
||||
seenTypes = 0;
|
||||
seenMessages = 0;
|
||||
messages.forEach(callback.onConsoleAPICall);
|
||||
do_check_eq(seenMessages, 2);
|
||||
do_check_eq(seenTypes, 1);
|
||||
|
||||
seenTypes = 0;
|
||||
seenMessages = 0;
|
||||
console.log("Hello from default console");
|
||||
console1.warn("Warning from foo");
|
||||
console2.error("Error from bar");
|
||||
do_check_eq(seenMessages, 1);
|
||||
do_check_eq(seenTypes, 1);
|
||||
|
||||
listener.destroy();
|
||||
|
||||
listener = new ConsoleAPIListener(null, callback, {addonId: "bar"});
|
||||
listener.init();
|
||||
messages = listener.getCachedMessages();
|
||||
|
||||
seenTypes = 0;
|
||||
seenMessages = 0;
|
||||
messages.forEach(callback.onConsoleAPICall);
|
||||
do_check_eq(seenMessages, 3);
|
||||
do_check_eq(seenTypes, 2);
|
||||
|
||||
seenTypes = 0;
|
||||
seenMessages = 0;
|
||||
console.log("Hello from default console");
|
||||
console1.warn("Warning from foo");
|
||||
console2.error("Error from bar");
|
||||
|
||||
do_check_eq(seenMessages, 1);
|
||||
do_check_eq(seenTypes, 2);
|
||||
|
||||
listener.destroy();
|
||||
|
||||
// Close the addon window's chromeWebNav.
|
||||
chromeWebNav.close();
|
||||
}
|
||||
136
devtools/shared/tests/unit/test_css-properties-db.js
Normal file
136
devtools/shared/tests/unit/test_css-properties-db.js
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that the devtool's client-side CSS properties database is in sync with the values
|
||||
* on the platform (in Nightly only). If they are not, then `mach devtools-css-db` needs
|
||||
* to be run to make everything up to date. Nightly, aurora, beta, and release may have
|
||||
* different CSS properties and values. These are based on preferences and compiler flags.
|
||||
*
|
||||
* This test broke uplifts as the database needed to be regenerated every uplift. The
|
||||
* combination of compiler flags and preferences means that it's too difficult to
|
||||
* statically determine which properties are enabled between Firefox releases.
|
||||
*
|
||||
* Because of these difficulties, the database only needs to be up to date with Nightly.
|
||||
* It is a fallback that is only used if the remote debugging protocol doesn't support
|
||||
* providing a CSS database, so it's ok if the provided properties don't exactly match
|
||||
* the inspected target in this particular case.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const DOMUtils = Components.classes["@mozilla.org/inspector/dom-utils;1"]
|
||||
.getService(Components.interfaces.inIDOMUtils);
|
||||
|
||||
const {PSEUDO_ELEMENTS, CSS_PROPERTIES} = require("devtools/shared/css/generated/properties-db");
|
||||
const {generateCssProperties} = require("devtools/server/actors/css-properties");
|
||||
|
||||
function run_test() {
|
||||
const propertiesErrorMessage = "If this assertion fails, then the client side CSS " +
|
||||
"properties list in devtools is out of sync with the " +
|
||||
"CSS properties on the platform. To fix this " +
|
||||
"assertion run `mach devtools-css-db` to re-generate " +
|
||||
"the client side properties.";
|
||||
|
||||
// Check that the platform and client match for pseudo elements.
|
||||
deepEqual(PSEUDO_ELEMENTS, DOMUtils.getCSSPseudoElementNames(), `The pseudo elements ` +
|
||||
`match on the client and platform. ${propertiesErrorMessage}`);
|
||||
|
||||
/**
|
||||
* Check that the platform and client match for the details on their CSS properties.
|
||||
* Enumerate each property to aid in debugging.
|
||||
*/
|
||||
const platformProperties = generateCssProperties();
|
||||
|
||||
for (let propertyName in CSS_PROPERTIES) {
|
||||
const platformProperty = platformProperties[propertyName];
|
||||
const clientProperty = CSS_PROPERTIES[propertyName];
|
||||
const deepEqual = isJsonDeepEqual(platformProperty, clientProperty);
|
||||
|
||||
if (deepEqual) {
|
||||
ok(true, `The static database and platform match for "${propertyName}".`);
|
||||
} else {
|
||||
const prefMessage = `The static database and platform do not match ` +
|
||||
`for "${propertyName}".`;
|
||||
if (getPreference(propertyName) === false) {
|
||||
ok(true, `${prefMessage} However, there is a preference for disabling this ` +
|
||||
`property on the current build.`);
|
||||
} else {
|
||||
ok(false, `${prefMessage} ${propertiesErrorMessage}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the list of properties on the platform and client are the same. If
|
||||
* they are not, check that there may be preferences that are disabling them on the
|
||||
* target platform.
|
||||
*/
|
||||
const mismatches = getKeyMismatches(platformProperties, CSS_PROPERTIES)
|
||||
// Filter out OS-specific properties.
|
||||
.filter(name => name && name.indexOf("-moz-osx-") === -1);
|
||||
|
||||
if (mismatches.length === 0) {
|
||||
ok(true, "No client and platform CSS property database mismatches were found.");
|
||||
}
|
||||
|
||||
mismatches.forEach(propertyName => {
|
||||
ok(false, `The static database and platform do not agree on the property ` +
|
||||
`"${propertyName}" ${propertiesErrorMessage}`);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check JSON-serializable objects for deep equality.
|
||||
*/
|
||||
function isJsonDeepEqual(a, b) {
|
||||
// Handle primitives.
|
||||
if (a === b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle arrays.
|
||||
if (Array.isArray(a) && Array.isArray(b)) {
|
||||
if (a.length !== b.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
if (!isJsonDeepEqual(a[i], b[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle objects
|
||||
if (typeof a === "object" && typeof b === "object") {
|
||||
for (let key in a) {
|
||||
if (!isJsonDeepEqual(a[key], b[key])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return Object.keys(a).length === Object.keys(b).length;
|
||||
}
|
||||
|
||||
// Not something handled by these cases, therefore not equal.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the keys of two objects, and return the ones that don't match.
|
||||
*
|
||||
* @param {Object} a
|
||||
* @param {Object} b
|
||||
* @return {Array} keys
|
||||
*/
|
||||
function getKeyMismatches(a, b) {
|
||||
const aNames = Object.keys(a);
|
||||
const bNames = Object.keys(b);
|
||||
const aMismatches = aNames.filter(key => !bNames.includes(key));
|
||||
const bMismatches = bNames.filter(key => {
|
||||
return !aNames.includes(key) && !aMismatches.includes(key);
|
||||
});
|
||||
|
||||
return aMismatches.concat(bMismatches);
|
||||
}
|
||||
242
devtools/shared/tests/unit/test_csslexer.js
Normal file
242
devtools/shared/tests/unit/test_csslexer.js
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
/* 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/.
|
||||
*/
|
||||
|
||||
// This file is a copy of layout/style/test/test_csslexer.js, modified
|
||||
// to use both our pure-JS lexer and the DOMUtils lexer for
|
||||
// cross-checking.
|
||||
|
||||
"use strict";
|
||||
|
||||
const jsLexer = require("devtools/shared/css/lexer");
|
||||
const domutils = Components.classes["@mozilla.org/inspector/dom-utils;1"]
|
||||
.getService(Components.interfaces.inIDOMUtils);
|
||||
|
||||
// An object that acts like a CSSLexer but verifies that the DOM lexer
|
||||
// and the JS lexer do the same thing.
|
||||
function DoubleLexer(input) {
|
||||
do_print("DoubleLexer input: " + input);
|
||||
this.domLexer = domutils.getCSSLexer(input);
|
||||
this.jsLexer = jsLexer.getCSSLexer(input);
|
||||
}
|
||||
|
||||
DoubleLexer.prototype = {
|
||||
checkState: function () {
|
||||
equal(this.domLexer.lineNumber, this.jsLexer.lineNumber,
|
||||
"check line number");
|
||||
equal(this.domLexer.columnNumber, this.jsLexer.columnNumber,
|
||||
"check column number");
|
||||
},
|
||||
|
||||
get lineNumber() {
|
||||
return this.domLexer.lineNumber;
|
||||
},
|
||||
|
||||
get columnNumber() {
|
||||
return this.domLexer.columnNumber;
|
||||
},
|
||||
|
||||
performEOFFixup: function (inputString, preserveBackslash) {
|
||||
let d = this.domLexer.performEOFFixup(inputString, preserveBackslash);
|
||||
let j = this.jsLexer.performEOFFixup(inputString, preserveBackslash);
|
||||
|
||||
equal(d, j);
|
||||
return d;
|
||||
},
|
||||
|
||||
mungeNumber: function (token) {
|
||||
if (token && (token.tokenType === "number" ||
|
||||
token.tokenType === "percentage") &&
|
||||
!token.isInteger) {
|
||||
// The JS lexer does its computations in double, but the
|
||||
// platform lexer does its computations in float. Account for
|
||||
// this discrepancy in a way that's sufficient for this test.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1163047
|
||||
token.number = parseFloat(token.number.toPrecision(8));
|
||||
}
|
||||
},
|
||||
|
||||
nextToken: function () {
|
||||
// Check state both before and after.
|
||||
this.checkState();
|
||||
|
||||
let d = this.domLexer.nextToken();
|
||||
let j = this.jsLexer.nextToken();
|
||||
|
||||
this.mungeNumber(d);
|
||||
this.mungeNumber(j);
|
||||
|
||||
deepEqual(d, j);
|
||||
|
||||
this.checkState();
|
||||
|
||||
return d;
|
||||
}
|
||||
};
|
||||
|
||||
function test_lexer(cssText, tokenTypes) {
|
||||
let lexer = new DoubleLexer(cssText);
|
||||
let reconstructed = "";
|
||||
let lastTokenEnd = 0;
|
||||
let i = 0;
|
||||
while (true) {
|
||||
let token = lexer.nextToken();
|
||||
if (!token) {
|
||||
break;
|
||||
}
|
||||
let combined = token.tokenType;
|
||||
if (token.text) {
|
||||
combined += ":" + token.text;
|
||||
}
|
||||
equal(combined, tokenTypes[i]);
|
||||
ok(token.endOffset > token.startOffset);
|
||||
equal(token.startOffset, lastTokenEnd);
|
||||
lastTokenEnd = token.endOffset;
|
||||
reconstructed += cssText.substring(token.startOffset, token.endOffset);
|
||||
++i;
|
||||
}
|
||||
// Ensure that we saw the correct number of tokens.
|
||||
equal(i, tokenTypes.length);
|
||||
// Ensure that the reported offsets cover all the text.
|
||||
equal(reconstructed, cssText);
|
||||
}
|
||||
|
||||
var LEX_TESTS = [
|
||||
["simple", ["ident:simple"]],
|
||||
["simple: { hi; }",
|
||||
["ident:simple", "symbol::",
|
||||
"whitespace", "symbol:{",
|
||||
"whitespace", "ident:hi",
|
||||
"symbol:;", "whitespace",
|
||||
"symbol:}"]],
|
||||
["/* whatever */", ["comment"]],
|
||||
["'string'", ["string:string"]],
|
||||
['"string"', ["string:string"]],
|
||||
["rgb(1,2,3)", ["function:rgb", "number",
|
||||
"symbol:,", "number",
|
||||
"symbol:,", "number",
|
||||
"symbol:)"]],
|
||||
["@media", ["at:media"]],
|
||||
["#hibob", ["id:hibob"]],
|
||||
["#123", ["hash:123"]],
|
||||
["23px", ["dimension:px"]],
|
||||
["23%", ["percentage"]],
|
||||
["url(http://example.com)", ["url:http://example.com"]],
|
||||
["url('http://example.com')", ["url:http://example.com"]],
|
||||
["url( 'http://example.com' )",
|
||||
["url:http://example.com"]],
|
||||
// In CSS Level 3, this is an ordinary URL, not a BAD_URL.
|
||||
["url(http://example.com", ["url:http://example.com"]],
|
||||
// See bug 1153981 to understand why this gets a SYMBOL token.
|
||||
["url(http://example.com @", ["bad_url:http://example.com", "symbol:@"]],
|
||||
["quo\\ting", ["ident:quoting"]],
|
||||
["'bad string\n", ["bad_string:bad string", "whitespace"]],
|
||||
["~=", ["includes"]],
|
||||
["|=", ["dashmatch"]],
|
||||
["^=", ["beginsmatch"]],
|
||||
["$=", ["endsmatch"]],
|
||||
["*=", ["containsmatch"]],
|
||||
|
||||
// URANGE may be on the way out, and it isn't used by devutils, so
|
||||
// let's skip it.
|
||||
|
||||
["<!-- html comment -->", ["htmlcomment", "whitespace", "ident:html",
|
||||
"whitespace", "ident:comment", "whitespace",
|
||||
"htmlcomment"]],
|
||||
|
||||
// earlier versions of CSS had "bad comment" tokens, but in level 3,
|
||||
// unterminated comments are just comments.
|
||||
["/* bad comment", ["comment"]]
|
||||
];
|
||||
|
||||
function test_lexer_linecol(cssText, locations) {
|
||||
let lexer = new DoubleLexer(cssText);
|
||||
let i = 0;
|
||||
while (true) {
|
||||
let token = lexer.nextToken();
|
||||
let startLine = lexer.lineNumber;
|
||||
let startColumn = lexer.columnNumber;
|
||||
|
||||
// We do this in a bit of a funny way so that we can also test the
|
||||
// location of the EOF.
|
||||
let combined = ":" + startLine + ":" + startColumn;
|
||||
if (token) {
|
||||
combined = token.tokenType + combined;
|
||||
}
|
||||
|
||||
equal(combined, locations[i]);
|
||||
++i;
|
||||
|
||||
if (!token) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Ensure that we saw the correct number of tokens.
|
||||
equal(i, locations.length);
|
||||
}
|
||||
|
||||
function test_lexer_eofchar(cssText, argText, expectedAppend,
|
||||
expectedNoAppend) {
|
||||
let lexer = new DoubleLexer(cssText);
|
||||
while (lexer.nextToken()) {
|
||||
// Nothing.
|
||||
}
|
||||
|
||||
do_print("EOF char test, input = " + cssText);
|
||||
|
||||
let result = lexer.performEOFFixup(argText, true);
|
||||
equal(result, expectedAppend);
|
||||
|
||||
result = lexer.performEOFFixup(argText, false);
|
||||
equal(result, expectedNoAppend);
|
||||
}
|
||||
|
||||
var LINECOL_TESTS = [
|
||||
["simple", ["ident:0:0", ":0:6"]],
|
||||
["\n stuff", ["whitespace:0:0", "ident:1:4", ":1:9"]],
|
||||
['"string with \\\nnewline" \r\n', ["string:0:0", "whitespace:1:8",
|
||||
":2:0"]]
|
||||
];
|
||||
|
||||
var EOFCHAR_TESTS = [
|
||||
["hello", "hello"],
|
||||
["hello \\", "hello \\\\", "hello \\\uFFFD"],
|
||||
["'hello", "'hello'"],
|
||||
["\"hello", "\"hello\""],
|
||||
["'hello\\", "'hello\\\\'", "'hello'"],
|
||||
["\"hello\\", "\"hello\\\\\"", "\"hello\""],
|
||||
["/*hello", "/*hello*/"],
|
||||
["/*hello*", "/*hello*/"],
|
||||
["/*hello\\", "/*hello\\*/"],
|
||||
["url(hello", "url(hello)"],
|
||||
["url('hello", "url('hello')"],
|
||||
["url(\"hello", "url(\"hello\")"],
|
||||
["url(hello\\", "url(hello\\\\)", "url(hello\\\uFFFD)"],
|
||||
["url('hello\\", "url('hello\\\\')", "url('hello')"],
|
||||
["url(\"hello\\", "url(\"hello\\\\\")", "url(\"hello\")"],
|
||||
];
|
||||
|
||||
function run_test() {
|
||||
let text, result;
|
||||
for ([text, result] of LEX_TESTS) {
|
||||
test_lexer(text, result);
|
||||
}
|
||||
|
||||
for ([text, result] of LINECOL_TESTS) {
|
||||
test_lexer_linecol(text, result);
|
||||
}
|
||||
|
||||
let expectedAppend, expectedNoAppend;
|
||||
for ([text, expectedAppend, expectedNoAppend] of EOFCHAR_TESTS) {
|
||||
if (!expectedNoAppend) {
|
||||
expectedNoAppend = expectedAppend;
|
||||
}
|
||||
test_lexer_eofchar(text, text, expectedAppend, expectedNoAppend);
|
||||
}
|
||||
|
||||
// Ensure that passing a different inputString to performEOFFixup
|
||||
// doesn't cause an assertion trying to strip a backslash from the
|
||||
// end of an empty string.
|
||||
test_lexer_eofchar("'\\", "", "\\'", "'");
|
||||
}
|
||||
32
devtools/shared/tests/unit/test_defer.js
Normal file
32
devtools/shared/tests/unit/test_defer.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const defer = require("devtools/shared/defer");
|
||||
|
||||
function testResolve() {
|
||||
const deferred = defer();
|
||||
deferred.resolve("success");
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testReject() {
|
||||
const deferred = defer();
|
||||
deferred.reject("error");
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
const success = yield testResolve();
|
||||
equal(success, "success");
|
||||
|
||||
let error;
|
||||
try {
|
||||
yield testReject();
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
|
||||
equal(error, "error");
|
||||
});
|
||||
68
devtools/shared/tests/unit/test_defineLazyPrototypeGetter.js
Normal file
68
devtools/shared/tests/unit/test_defineLazyPrototypeGetter.js
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test DevToolsUtils.defineLazyPrototypeGetter
|
||||
|
||||
function Class() {}
|
||||
DevToolsUtils.defineLazyPrototypeGetter(Class.prototype, "foo", () => []);
|
||||
|
||||
|
||||
function run_test() {
|
||||
test_prototype_attributes();
|
||||
test_instance_attributes();
|
||||
test_multiple_instances();
|
||||
test_callback_receiver();
|
||||
}
|
||||
|
||||
function test_prototype_attributes() {
|
||||
// Check that the prototype has a getter property with expected attributes.
|
||||
let descriptor = Object.getOwnPropertyDescriptor(Class.prototype, "foo");
|
||||
do_check_eq(typeof descriptor.get, "function");
|
||||
do_check_eq(descriptor.set, undefined);
|
||||
do_check_eq(descriptor.enumerable, false);
|
||||
do_check_eq(descriptor.configurable, true);
|
||||
}
|
||||
|
||||
function test_instance_attributes() {
|
||||
// Instances should not have an own property until the lazy getter has been
|
||||
// activated.
|
||||
let instance = new Class();
|
||||
do_check_false(instance.hasOwnProperty("foo"));
|
||||
instance.foo;
|
||||
do_check_true(instance.hasOwnProperty("foo"));
|
||||
|
||||
// Check that the instance has an own property with the expecred value and
|
||||
// attributes after the lazy getter is activated.
|
||||
let descriptor = Object.getOwnPropertyDescriptor(instance, "foo");
|
||||
do_check_true(descriptor.value instanceof Array);
|
||||
do_check_eq(descriptor.writable, true);
|
||||
do_check_eq(descriptor.enumerable, false);
|
||||
do_check_eq(descriptor.configurable, true);
|
||||
}
|
||||
|
||||
function test_multiple_instances() {
|
||||
let instance1 = new Class();
|
||||
let instance2 = new Class();
|
||||
let foo1 = instance1.foo;
|
||||
let foo2 = instance2.foo;
|
||||
// Check that the lazy getter returns the expected type of value.
|
||||
do_check_true(foo1 instanceof Array);
|
||||
do_check_true(foo2 instanceof Array);
|
||||
// Make sure the lazy getter runs once and only once per instance.
|
||||
do_check_eq(instance1.foo, foo1);
|
||||
do_check_eq(instance2.foo, foo2);
|
||||
// Make sure each instance gets its own unique value.
|
||||
do_check_neq(foo1, foo2);
|
||||
}
|
||||
|
||||
function test_callback_receiver() {
|
||||
function Foo() {}
|
||||
DevToolsUtils.defineLazyPrototypeGetter(Foo.prototype, "foo", function () {
|
||||
return this;
|
||||
});
|
||||
|
||||
// Check that the |this| value in the callback is the instance itself.
|
||||
let instance = new Foo();
|
||||
do_check_eq(instance.foo, instance);
|
||||
}
|
||||
48
devtools/shared/tests/unit/test_executeSoon.js
Normal file
48
devtools/shared/tests/unit/test_executeSoon.js
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Client request stacks should span the entire process from before making the
|
||||
* request to handling the reply from the server. The server frames are not
|
||||
* included, nor can they be in most cases, since the server can be a remote
|
||||
* device.
|
||||
*/
|
||||
|
||||
var { executeSoon } = require("devtools/shared/DevToolsUtils");
|
||||
var promise = require("promise");
|
||||
var defer = require("devtools/shared/defer");
|
||||
var Services = require("Services");
|
||||
|
||||
var asyncStackEnabled =
|
||||
Services.prefs.getBoolPref("javascript.options.asyncstack");
|
||||
|
||||
do_register_cleanup(() => {
|
||||
Services.prefs.setBoolPref("javascript.options.asyncstack",
|
||||
asyncStackEnabled);
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
Services.prefs.setBoolPref("javascript.options.asyncstack", true);
|
||||
|
||||
yield waitForTick();
|
||||
|
||||
let stack = Components.stack;
|
||||
while (stack) {
|
||||
do_print(stack.name);
|
||||
if (stack.name == "waitForTick") {
|
||||
// Reached back to outer function before executeSoon
|
||||
ok(true, "Complete stack");
|
||||
return;
|
||||
}
|
||||
stack = stack.asyncCaller || stack.caller;
|
||||
}
|
||||
ok(false, "Incomplete stack");
|
||||
});
|
||||
|
||||
function waitForTick() {
|
||||
let deferred = defer();
|
||||
executeSoon(deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
76
devtools/shared/tests/unit/test_fetch-bom.js
Normal file
76
devtools/shared/tests/unit/test_fetch-bom.js
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
// Tests for DevToolsUtils.fetch BOM detection.
|
||||
|
||||
const CC = Components.Constructor;
|
||||
|
||||
const { HttpServer } = Cu.import("resource://testing-common/httpd.js", {});
|
||||
const BinaryOutputStream = CC("@mozilla.org/binaryoutputstream;1",
|
||||
"nsIBinaryOutputStream", "setOutputStream");
|
||||
|
||||
function write8(bos) {
|
||||
bos.write8(0xef);
|
||||
bos.write8(0xbb);
|
||||
bos.write8(0xbf);
|
||||
bos.write8(0x68);
|
||||
bos.write8(0xc4);
|
||||
bos.write8(0xb1);
|
||||
}
|
||||
|
||||
function write16be(bos) {
|
||||
bos.write8(0xfe);
|
||||
bos.write8(0xff);
|
||||
bos.write8(0x00);
|
||||
bos.write8(0x68);
|
||||
bos.write8(0x01);
|
||||
bos.write8(0x31);
|
||||
}
|
||||
|
||||
function write16le(bos) {
|
||||
bos.write8(0xff);
|
||||
bos.write8(0xfe);
|
||||
bos.write8(0x68);
|
||||
bos.write8(0x00);
|
||||
bos.write8(0x31);
|
||||
bos.write8(0x01);
|
||||
}
|
||||
|
||||
function getHandler(writer) {
|
||||
return function (request, response) {
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
|
||||
let bos = new BinaryOutputStream(response.bodyOutputStream);
|
||||
writer(bos);
|
||||
};
|
||||
}
|
||||
|
||||
const server = new HttpServer();
|
||||
server.registerDirectory("/", do_get_cwd());
|
||||
server.registerPathHandler("/u8", getHandler(write8));
|
||||
server.registerPathHandler("/u16be", getHandler(write16be));
|
||||
server.registerPathHandler("/u16le", getHandler(write16le));
|
||||
server.start(-1);
|
||||
|
||||
const port = server.identity.primaryPort;
|
||||
const serverURL = "http://localhost:" + port;
|
||||
|
||||
do_register_cleanup(() => {
|
||||
return new Promise(resolve => server.stop(resolve));
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
yield test_one(serverURL + "/u8", "UTF-8");
|
||||
yield test_one(serverURL + "/u16be", "UTF-16BE");
|
||||
yield test_one(serverURL + "/u16le", "UTF-16LE");
|
||||
});
|
||||
|
||||
function* test_one(url, encoding) {
|
||||
// Be sure to set the encoding to something that will yield an
|
||||
// invalid result if BOM sniffing is not done.
|
||||
yield DevToolsUtils.fetch(url, { charset: "ISO-8859-1" }).then(({content}) => {
|
||||
do_check_eq(content, "hı", "The content looks correct for " + encoding);
|
||||
});
|
||||
}
|
||||
31
devtools/shared/tests/unit/test_fetch-chrome.js
Normal file
31
devtools/shared/tests/unit/test_fetch-chrome.js
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
// Tests for DevToolsUtils.fetch on chrome:// URI's.
|
||||
|
||||
const URL_FOUND = "chrome://devtools-shared/locale/debugger.properties";
|
||||
const URL_NOT_FOUND = "chrome://this/is/not/here.js";
|
||||
|
||||
/**
|
||||
* Test that non-existent files are handled correctly.
|
||||
*/
|
||||
add_task(function* test_missing() {
|
||||
yield DevToolsUtils.fetch(URL_NOT_FOUND).then(result => {
|
||||
do_print(result);
|
||||
ok(false, "fetch resolved unexpectedly for non-existent chrome:// URI");
|
||||
}, () => {
|
||||
ok(true, "fetch rejected as the chrome:// URI was non-existent.");
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that existing files are handled correctly.
|
||||
*/
|
||||
add_task(function* test_normal() {
|
||||
yield DevToolsUtils.fetch(URL_FOUND).then(result => {
|
||||
notDeepEqual(result.content, "",
|
||||
"chrome:// URI seems to be read correctly.");
|
||||
});
|
||||
});
|
||||
104
devtools/shared/tests/unit/test_fetch-file.js
Normal file
104
devtools/shared/tests/unit/test_fetch-file.js
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
// Tests for DevToolsUtils.fetch on file:// URI's.
|
||||
|
||||
const { FileUtils } = Cu.import("resource://gre/modules/FileUtils.jsm", {});
|
||||
const { OS } = Cu.import("resource://gre/modules/osfile.jsm", {});
|
||||
|
||||
const TEST_CONTENT = "aéd";
|
||||
|
||||
// The TEST_CONTENT encoded as UTF-8.
|
||||
const UTF8_TEST_BUFFER = new Uint8Array([0x61, 0xc3, 0xa9, 0x64]);
|
||||
|
||||
// The TEST_CONTENT encoded as ISO 8859-1.
|
||||
const ISO_8859_1_BUFFER = new Uint8Array([0x61, 0xe9, 0x64]);
|
||||
|
||||
/**
|
||||
* Tests that URLs with arrows pointing to an actual source are handled properly
|
||||
* (bug 808960). For example 'resource://gre/modules/XPIProvider.jsm ->
|
||||
* file://l10n.js' should load 'file://l10n.js'.
|
||||
*/
|
||||
add_task(function* test_arrow_urls() {
|
||||
let { path } = createTemporaryFile(".js");
|
||||
let url = "resource://gre/modules/XPIProvider.jsm -> file://" + path;
|
||||
|
||||
yield OS.File.writeAtomic(path, TEST_CONTENT, { encoding: "utf-8" });
|
||||
let { content } = yield DevToolsUtils.fetch(url);
|
||||
|
||||
deepEqual(content, TEST_CONTENT, "The file contents were correctly read.");
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that empty files are read correctly.
|
||||
*/
|
||||
add_task(function* test_empty() {
|
||||
let { path } = createTemporaryFile();
|
||||
let { content } = yield DevToolsUtils.fetch("file://" + path);
|
||||
deepEqual(content, "", "The empty file was read correctly.");
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that UTF-8 encoded files are correctly read.
|
||||
*/
|
||||
add_task(function* test_encoding_utf8() {
|
||||
let { path } = createTemporaryFile();
|
||||
yield OS.File.writeAtomic(path, UTF8_TEST_BUFFER);
|
||||
|
||||
let { content } = yield DevToolsUtils.fetch(path);
|
||||
deepEqual(content, TEST_CONTENT,
|
||||
"The UTF-8 encoded file was correctly read.");
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that ISO 8859-1 (Latin-1) encoded files are correctly read.
|
||||
*/
|
||||
add_task(function* test_encoding_iso_8859_1() {
|
||||
let { path } = createTemporaryFile();
|
||||
yield OS.File.writeAtomic(path, ISO_8859_1_BUFFER);
|
||||
|
||||
let { content } = yield DevToolsUtils.fetch(path);
|
||||
deepEqual(content, TEST_CONTENT,
|
||||
"The ISO 8859-1 encoded file was correctly read.");
|
||||
});
|
||||
|
||||
/**
|
||||
* Test that non-existent files are handled correctly.
|
||||
*/
|
||||
add_task(function* test_missing() {
|
||||
yield DevToolsUtils.fetch("file:///file/not/found.right").then(result => {
|
||||
do_print(result);
|
||||
ok(false, "Fetch resolved unexpectedly when the file was not found.");
|
||||
}, () => {
|
||||
ok(true, "Fetch rejected as expected because the file was not found.");
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Test that URLs without file:// scheme work.
|
||||
*/
|
||||
add_task(function* test_schemeless_files() {
|
||||
let { path } = createTemporaryFile();
|
||||
|
||||
yield OS.File.writeAtomic(path, TEST_CONTENT, { encoding: "utf-8" });
|
||||
|
||||
let { content } = yield DevToolsUtils.fetch(path);
|
||||
deepEqual(content, TEST_CONTENT, "The content was correct.");
|
||||
});
|
||||
|
||||
/**
|
||||
* Creates a temporary file that is removed after the test completes.
|
||||
*/
|
||||
function createTemporaryFile(extension) {
|
||||
let name = "test_fetch-file-" + Math.random() + (extension || "");
|
||||
let file = FileUtils.getFile("TmpD", [name]);
|
||||
file.create(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("0755", 8));
|
||||
|
||||
do_register_cleanup(() => {
|
||||
file.remove(false);
|
||||
});
|
||||
|
||||
return file;
|
||||
}
|
||||
61
devtools/shared/tests/unit/test_fetch-http.js
Normal file
61
devtools/shared/tests/unit/test_fetch-http.js
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
// Tests for DevToolsUtils.fetch on http:// URI's.
|
||||
|
||||
const { HttpServer } = Cu.import("resource://testing-common/httpd.js", {});
|
||||
|
||||
const server = new HttpServer();
|
||||
server.registerDirectory("/", do_get_cwd());
|
||||
server.registerPathHandler("/cached.json", cacheRequestHandler);
|
||||
server.start(-1);
|
||||
|
||||
const port = server.identity.primaryPort;
|
||||
const serverURL = "http://localhost:" + port;
|
||||
const CACHED_URL = serverURL + "/cached.json";
|
||||
const NORMAL_URL = serverURL + "/test_fetch-http.js";
|
||||
|
||||
function cacheRequestHandler(request, response) {
|
||||
do_print("Got request for " + request.path);
|
||||
response.setHeader("Cache-Control", "max-age=10000", false);
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "application/json", false);
|
||||
|
||||
let body = "[" + Math.random() + "]";
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
}
|
||||
|
||||
do_register_cleanup(() => {
|
||||
return new Promise(resolve => server.stop(resolve));
|
||||
});
|
||||
|
||||
add_task(function* test_normal() {
|
||||
yield DevToolsUtils.fetch(NORMAL_URL).then(({content}) => {
|
||||
ok(content.includes("The content looks correct."),
|
||||
"The content looks correct.");
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function* test_caching() {
|
||||
let initialContent = null;
|
||||
|
||||
do_print("Performing the first request.");
|
||||
yield DevToolsUtils.fetch(CACHED_URL).then(({content}) => {
|
||||
do_print("Got the first response: " + content);
|
||||
initialContent = content;
|
||||
});
|
||||
|
||||
do_print("Performing another request, expecting to get cached response.");
|
||||
yield DevToolsUtils.fetch(CACHED_URL).then(({content}) => {
|
||||
deepEqual(content, initialContent, "The content was loaded from cache.");
|
||||
});
|
||||
|
||||
do_print("Performing a third request with cache bypassed.");
|
||||
let opts = { loadFromCache: false };
|
||||
yield DevToolsUtils.fetch(CACHED_URL, opts).then(({content}) => {
|
||||
notDeepEqual(content, initialContent,
|
||||
"The URL wasn't loaded from cache with loadFromCache: false.");
|
||||
});
|
||||
});
|
||||
31
devtools/shared/tests/unit/test_fetch-resource.js
Normal file
31
devtools/shared/tests/unit/test_fetch-resource.js
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
// Tests for DevToolsUtils.fetch on resource:// URI's.
|
||||
|
||||
const URL_FOUND = "resource://devtools/shared/DevToolsUtils.js";
|
||||
const URL_NOT_FOUND = "resource://devtools/this/is/not/here.js";
|
||||
|
||||
/**
|
||||
* Test that non-existent files are handled correctly.
|
||||
*/
|
||||
add_task(function* test_missing() {
|
||||
yield DevToolsUtils.fetch(URL_NOT_FOUND).then(result => {
|
||||
do_print(result);
|
||||
ok(false, "fetch resolved unexpectedly for non-existent resource:// URI");
|
||||
}, () => {
|
||||
ok(true, "fetch rejected as the resource:// URI was non-existent.");
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that existing files are handled correctly.
|
||||
*/
|
||||
add_task(function* test_normal() {
|
||||
yield DevToolsUtils.fetch(URL_FOUND).then(result => {
|
||||
notDeepEqual(result.content, "",
|
||||
"resource:// URI seems to be read correctly.");
|
||||
});
|
||||
});
|
||||
24
devtools/shared/tests/unit/test_flatten.js
Normal file
24
devtools/shared/tests/unit/test_flatten.js
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test ThreadSafeDevToolsUtils.flatten
|
||||
|
||||
function run_test() {
|
||||
const { flatten } = DevToolsUtils;
|
||||
|
||||
const flat = flatten([["a", "b", "c"],
|
||||
["d", "e", "f"],
|
||||
["g", "h", "i"]]);
|
||||
|
||||
equal(flat.length, 9);
|
||||
equal(flat[0], "a");
|
||||
equal(flat[1], "b");
|
||||
equal(flat[2], "c");
|
||||
equal(flat[3], "d");
|
||||
equal(flat[4], "e");
|
||||
equal(flat[5], "f");
|
||||
equal(flat[6], "g");
|
||||
equal(flat[7], "h");
|
||||
equal(flat[8], "i");
|
||||
}
|
||||
133
devtools/shared/tests/unit/test_indentation.js
Normal file
133
devtools/shared/tests/unit/test_indentation.js
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const Services = require("Services");
|
||||
const {
|
||||
EXPAND_TAB,
|
||||
TAB_SIZE,
|
||||
DETECT_INDENT,
|
||||
getIndentationFromPrefs,
|
||||
getIndentationFromIteration,
|
||||
getIndentationFromString,
|
||||
} = require("devtools/shared/indentation");
|
||||
|
||||
function test_indent_from_prefs() {
|
||||
Services.prefs.setBoolPref(DETECT_INDENT, true);
|
||||
equal(getIndentationFromPrefs(), false,
|
||||
"getIndentationFromPrefs returning false");
|
||||
|
||||
Services.prefs.setIntPref(TAB_SIZE, 73);
|
||||
Services.prefs.setBoolPref(EXPAND_TAB, false);
|
||||
Services.prefs.setBoolPref(DETECT_INDENT, false);
|
||||
deepEqual(getIndentationFromPrefs(), {indentUnit: 73, indentWithTabs: true},
|
||||
"getIndentationFromPrefs basic test");
|
||||
}
|
||||
|
||||
const TESTS = [
|
||||
{
|
||||
desc: "two spaces",
|
||||
input: [
|
||||
"/*",
|
||||
" * tricky comment block",
|
||||
" */",
|
||||
"div {",
|
||||
" color: red;",
|
||||
" background: blue;",
|
||||
"}",
|
||||
" ",
|
||||
"span {",
|
||||
" padding-left: 10px;",
|
||||
"}"
|
||||
],
|
||||
expected: {indentUnit: 2, indentWithTabs: false}
|
||||
},
|
||||
{
|
||||
desc: "four spaces",
|
||||
input: [
|
||||
"var obj = {",
|
||||
" addNumbers: function() {",
|
||||
" var x = 5;",
|
||||
" var y = 18;",
|
||||
" return x + y;",
|
||||
" },",
|
||||
" ",
|
||||
" /*",
|
||||
" * Do some stuff to two numbers",
|
||||
" * ",
|
||||
" * @param x",
|
||||
" * @param y",
|
||||
" * ",
|
||||
" * @return the result of doing stuff",
|
||||
" */",
|
||||
" subtractNumbers: function(x, y) {",
|
||||
" var x += 7;",
|
||||
" var y += 18;",
|
||||
" var result = x - y;",
|
||||
" result %= 2;",
|
||||
" }",
|
||||
"}"
|
||||
],
|
||||
expected: {indentUnit: 4, indentWithTabs: false}
|
||||
},
|
||||
{
|
||||
desc: "tabs",
|
||||
input: [
|
||||
"/*",
|
||||
" * tricky comment block",
|
||||
" */",
|
||||
"div {",
|
||||
"\tcolor: red;",
|
||||
"\tbackground: blue;",
|
||||
"}",
|
||||
"",
|
||||
"span {",
|
||||
"\tpadding-left: 10px;",
|
||||
"}"
|
||||
],
|
||||
expected: {indentUnit: 2, indentWithTabs: true}
|
||||
},
|
||||
{
|
||||
desc: "no indent",
|
||||
input: [
|
||||
"var x = 0;",
|
||||
" // stray thing",
|
||||
"var y = 9;",
|
||||
" ",
|
||||
""
|
||||
],
|
||||
expected: {indentUnit: 2, indentWithTabs: false}
|
||||
},
|
||||
];
|
||||
|
||||
function test_indent_detection() {
|
||||
Services.prefs.setIntPref(TAB_SIZE, 2);
|
||||
Services.prefs.setBoolPref(EXPAND_TAB, true);
|
||||
Services.prefs.setBoolPref(DETECT_INDENT, true);
|
||||
|
||||
for (let test of TESTS) {
|
||||
let iterFn = function (start, end, callback) {
|
||||
test.input.slice(start, end).forEach(callback);
|
||||
};
|
||||
|
||||
deepEqual(getIndentationFromIteration(iterFn), test.expected,
|
||||
"test getIndentationFromIteration " + test.desc);
|
||||
}
|
||||
|
||||
for (let test of TESTS) {
|
||||
deepEqual(getIndentationFromString(test.input.join("\n")), test.expected,
|
||||
"test getIndentationFromString " + test.desc);
|
||||
}
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
try {
|
||||
test_indent_from_prefs();
|
||||
test_indent_detection();
|
||||
} finally {
|
||||
Services.prefs.clearUserPref(TAB_SIZE);
|
||||
Services.prefs.clearUserPref(EXPAND_TAB);
|
||||
Services.prefs.clearUserPref(DETECT_INDENT);
|
||||
}
|
||||
}
|
||||
20
devtools/shared/tests/unit/test_independent_loaders.js
Normal file
20
devtools/shared/tests/unit/test_independent_loaders.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Ensure that each instance of the Dev Tools loader contains its own loader
|
||||
* instance, and also returns unique objects. This ensures there is no sharing
|
||||
* in place between loaders.
|
||||
*/
|
||||
function run_test() {
|
||||
let loader1 = new DevToolsLoader();
|
||||
let loader2 = new DevToolsLoader();
|
||||
|
||||
let indent1 = loader1.require("devtools/shared/indentation");
|
||||
let indent2 = loader2.require("devtools/shared/indentation");
|
||||
|
||||
do_check_true(indent1 !== indent2);
|
||||
|
||||
do_check_true(loader1._provider !== loader2._provider);
|
||||
do_check_true(loader1._provider.loader !== loader2._provider.loader);
|
||||
}
|
||||
60
devtools/shared/tests/unit/test_invisible_loader.js
Normal file
60
devtools/shared/tests/unit/test_invisible_loader.js
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { addDebuggerToGlobal } = Cu.import("resource://gre/modules/jsdebugger.jsm", {});
|
||||
addDebuggerToGlobal(this);
|
||||
|
||||
/**
|
||||
* Ensure that sandboxes created via the Dev Tools loader respect the
|
||||
* invisibleToDebugger flag.
|
||||
*/
|
||||
function run_test() {
|
||||
visible_loader();
|
||||
invisible_loader();
|
||||
}
|
||||
|
||||
function visible_loader() {
|
||||
let loader = new DevToolsLoader();
|
||||
loader.invisibleToDebugger = false;
|
||||
loader.require("devtools/shared/indentation");
|
||||
|
||||
let dbg = new Debugger();
|
||||
let sandbox = loader._provider.loader.sharedGlobalSandbox;
|
||||
|
||||
try {
|
||||
dbg.addDebuggee(sandbox);
|
||||
do_check_true(true);
|
||||
} catch (e) {
|
||||
do_throw("debugger could not add visible value");
|
||||
}
|
||||
|
||||
// Check that for common loader used for tabs, promise modules is Promise.jsm
|
||||
// Which is required to support unhandled promises rejection in mochitests
|
||||
const promise = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
|
||||
do_check_eq(loader.require("promise"), promise);
|
||||
}
|
||||
|
||||
function invisible_loader() {
|
||||
let loader = new DevToolsLoader();
|
||||
loader.invisibleToDebugger = true;
|
||||
loader.require("devtools/shared/indentation");
|
||||
|
||||
let dbg = new Debugger();
|
||||
let sandbox = loader._provider.loader.sharedGlobalSandbox;
|
||||
|
||||
try {
|
||||
dbg.addDebuggee(sandbox);
|
||||
do_throw("debugger added invisible value");
|
||||
} catch (e) {
|
||||
do_check_true(true);
|
||||
}
|
||||
|
||||
// But for browser toolbox loader, promise is loaded as a regular modules out
|
||||
// of Promise-backend.js, that to be invisible to the debugger and not step
|
||||
// into it.
|
||||
const promise = loader.require("promise");
|
||||
const promiseModule = loader._provider.loader.modules["resource://gre/modules/Promise-backend.js"];
|
||||
do_check_eq(promise, promiseModule.exports);
|
||||
}
|
||||
25
devtools/shared/tests/unit/test_isSet.js
Normal file
25
devtools/shared/tests/unit/test_isSet.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test ThreadSafeDevToolsUtils.isSet
|
||||
|
||||
function run_test() {
|
||||
const { isSet } = DevToolsUtils;
|
||||
|
||||
equal(isSet(new Set()), true);
|
||||
equal(isSet(new Map()), false);
|
||||
equal(isSet({}), false);
|
||||
equal(isSet("I swear I'm a Set"), false);
|
||||
equal(isSet(5), false);
|
||||
|
||||
const systemPrincipal = Cc["@mozilla.org/systemprincipal;1"]
|
||||
.createInstance(Ci.nsIPrincipal);
|
||||
const sandbox = new Cu.Sandbox(systemPrincipal);
|
||||
|
||||
equal(isSet(Cu.evalInSandbox("new Set()", sandbox)), true);
|
||||
equal(isSet(Cu.evalInSandbox("new Map()", sandbox)), false);
|
||||
equal(isSet(Cu.evalInSandbox("({})", sandbox)), false);
|
||||
equal(isSet(Cu.evalInSandbox("'I swear I\\'m a Set'", sandbox)), false);
|
||||
equal(isSet(Cu.evalInSandbox("5", sandbox)), false);
|
||||
}
|
||||
29
devtools/shared/tests/unit/test_pluralForm-english.js
Normal file
29
devtools/shared/tests/unit/test_pluralForm-english.js
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/* 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";
|
||||
|
||||
/**
|
||||
* This unit test makes sure the plural form for Irish Gaeilge is working by
|
||||
* using the makeGetter method instead of using the default language (by
|
||||
* development), English.
|
||||
*/
|
||||
|
||||
const {PluralForm} = require("devtools/shared/plural-form");
|
||||
|
||||
function run_test() {
|
||||
// English has 2 plural forms
|
||||
do_check_eq(2, PluralForm.numForms());
|
||||
|
||||
// Make sure for good inputs, things work as expected
|
||||
for (let num = 0; num <= 200; num++) {
|
||||
do_check_eq(num == 1 ? "word" : "words", PluralForm.get(num, "word;words"));
|
||||
}
|
||||
|
||||
// Not having enough plural forms defaults to the first form
|
||||
do_check_eq("word", PluralForm.get(2, "word"));
|
||||
|
||||
// Empty forms defaults to the first form
|
||||
do_check_eq("word", PluralForm.get(2, "word;"));
|
||||
}
|
||||
38
devtools/shared/tests/unit/test_pluralForm-makeGetter.js
Normal file
38
devtools/shared/tests/unit/test_pluralForm-makeGetter.js
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/* 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";
|
||||
|
||||
/**
|
||||
* This unit test makes sure the plural form for Irish Gaeilge is working by
|
||||
* using the makeGetter method instead of using the default language (by
|
||||
* development), English.
|
||||
*/
|
||||
|
||||
const {PluralForm} = require("devtools/shared/plural-form");
|
||||
|
||||
function run_test() {
|
||||
// Irish is plural rule #11
|
||||
let [get, numForms] = PluralForm.makeGetter(11);
|
||||
|
||||
// Irish has 5 plural forms
|
||||
do_check_eq(5, numForms());
|
||||
|
||||
// I don't really know Irish, so I'll stick in some dummy text
|
||||
let words = "is 1;is 2;is 3-6;is 7-10;everything else";
|
||||
|
||||
let test = function (text, low, high) {
|
||||
for (let num = low; num <= high; num++) {
|
||||
do_check_eq(text, get(num, words));
|
||||
}
|
||||
};
|
||||
|
||||
// Make sure for good inputs, things work as expected
|
||||
test("everything else", 0, 0);
|
||||
test("is 1", 1, 1);
|
||||
test("is 2", 2, 2);
|
||||
test("is 3-6", 3, 6);
|
||||
test("is 7-10", 7, 10);
|
||||
test("everything else", 11, 200);
|
||||
}
|
||||
68
devtools/shared/tests/unit/test_prettifyCSS.js
Normal file
68
devtools/shared/tests/unit/test_prettifyCSS.js
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test prettifyCSS.
|
||||
|
||||
"use strict";
|
||||
|
||||
const {prettifyCSS} = require("devtools/shared/inspector/css-logic");
|
||||
|
||||
const TESTS = [
|
||||
{ name: "simple test",
|
||||
input: "div { font-family:'Arial Black', Arial, sans-serif; }",
|
||||
expected: [
|
||||
"div {",
|
||||
"\tfont-family:'Arial Black', Arial, sans-serif;",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
|
||||
{ name: "whitespace before open brace",
|
||||
input: "div{}",
|
||||
expected: [
|
||||
"div {",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
|
||||
{ name: "minified with trailing newline",
|
||||
input: "\nbody{background:white;}div{font-size:4em;color:red}span{color:green;}\n",
|
||||
expected: [
|
||||
"body {",
|
||||
"\tbackground:white;",
|
||||
"}",
|
||||
"div {",
|
||||
"\tfont-size:4em;",
|
||||
"\tcolor:red",
|
||||
"}",
|
||||
"span {",
|
||||
"\tcolor:green;",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
|
||||
{ name: "leading whitespace",
|
||||
input: "\n div{color: red;}",
|
||||
expected: [
|
||||
"div {",
|
||||
"\tcolor: red;",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
function run_test() {
|
||||
// Note that prettifyCSS.LINE_SEPARATOR is computed lazily, so we
|
||||
// ensure it is set.
|
||||
prettifyCSS("");
|
||||
|
||||
for (let test of TESTS) {
|
||||
do_print(test.name);
|
||||
|
||||
let input = test.input.split("\n").join(prettifyCSS.LINE_SEPARATOR);
|
||||
let output = prettifyCSS(input);
|
||||
let expected = test.expected.join(prettifyCSS.LINE_SEPARATOR) +
|
||||
prettifyCSS.LINE_SEPARATOR;
|
||||
equal(output, expected, test.name);
|
||||
}
|
||||
}
|
||||
20
devtools/shared/tests/unit/test_require.js
Normal file
20
devtools/shared/tests/unit/test_require.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test require
|
||||
|
||||
// Ensure that DevtoolsLoader.require doesn't spawn multiple
|
||||
// loader/modules when early cached
|
||||
function testBug1091706() {
|
||||
let loader = new DevToolsLoader();
|
||||
let require = loader.require;
|
||||
|
||||
let indent1 = require("devtools/shared/indentation");
|
||||
let indent2 = require("devtools/shared/indentation");
|
||||
|
||||
do_check_true(indent1 === indent2);
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
testBug1091706();
|
||||
}
|
||||
32
devtools/shared/tests/unit/test_require_lazy.js
Normal file
32
devtools/shared/tests/unit/test_require_lazy.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test devtools.lazyRequireGetter
|
||||
|
||||
function run_test() {
|
||||
const name = "asyncUtils";
|
||||
const path = "devtools/shared/async-utils";
|
||||
const o = {};
|
||||
devtools.lazyRequireGetter(o, name, path);
|
||||
const asyncUtils = require(path);
|
||||
// XXX: do_check_eq only works on primitive types, so we have this
|
||||
// do_check_true of an equality expression.
|
||||
do_check_true(o.asyncUtils === asyncUtils);
|
||||
|
||||
// A non-main loader should get a new object via |lazyRequireGetter|, just
|
||||
// as it would via a direct |require|.
|
||||
const o2 = {};
|
||||
let loader = new DevToolsLoader();
|
||||
|
||||
// We have to init the loader by loading any module before lazyRequireGetter is available
|
||||
loader.require("devtools/shared/DevToolsUtils");
|
||||
|
||||
loader.lazyRequireGetter(o2, name, path);
|
||||
do_check_true(o2.asyncUtils !== asyncUtils);
|
||||
|
||||
// A module required via a non-main loader that then uses |lazyRequireGetter|
|
||||
// should also get the same object from that non-main loader.
|
||||
let exposeLoader = loader.require("xpcshell-test/exposeLoader");
|
||||
const o3 = exposeLoader.exerciseLazyRequire(name, path);
|
||||
do_check_true(o3.asyncUtils === o2.asyncUtils);
|
||||
}
|
||||
19
devtools/shared/tests/unit/test_require_raw.js
Normal file
19
devtools/shared/tests/unit/test_require_raw.js
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test require using "raw!".
|
||||
|
||||
function run_test() {
|
||||
let loader = new DevToolsLoader();
|
||||
let require = loader.require;
|
||||
|
||||
let variableFileContents = require("raw!devtools/client/themes/variables.css");
|
||||
ok(variableFileContents.length > 0, "raw browserRequire worked");
|
||||
|
||||
let propertiesFileContents = require("raw!devtools/client/locales/shared.properties");
|
||||
ok(propertiesFileContents.length > 0, "unprefixed properties raw require worked");
|
||||
|
||||
let chromePropertiesFileContents =
|
||||
require("raw!chrome://devtools/locale/shared.properties");
|
||||
ok(chromePropertiesFileContents.length > 0, "prefixed properties raw require worked");
|
||||
}
|
||||
58
devtools/shared/tests/unit/test_safeErrorString.js
Normal file
58
devtools/shared/tests/unit/test_safeErrorString.js
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test DevToolsUtils.safeErrorString
|
||||
|
||||
function run_test() {
|
||||
test_with_error();
|
||||
test_with_tricky_error();
|
||||
test_with_string();
|
||||
test_with_thrower();
|
||||
test_with_psychotic();
|
||||
}
|
||||
|
||||
function test_with_error() {
|
||||
let s = DevToolsUtils.safeErrorString(new Error("foo bar"));
|
||||
// Got the message.
|
||||
do_check_true(s.includes("foo bar"));
|
||||
// Got the stack.
|
||||
do_check_true(s.includes("test_with_error"));
|
||||
do_check_true(s.includes("test_safeErrorString.js"));
|
||||
// Got the lineNumber and columnNumber.
|
||||
do_check_true(s.includes("Line"));
|
||||
do_check_true(s.includes("column"));
|
||||
}
|
||||
|
||||
function test_with_tricky_error() {
|
||||
let e = new Error("batman");
|
||||
e.stack = { toString: Object.create(null) };
|
||||
let s = DevToolsUtils.safeErrorString(e);
|
||||
// Still got the message, despite a bad stack property.
|
||||
do_check_true(s.includes("batman"));
|
||||
}
|
||||
|
||||
function test_with_string() {
|
||||
let s = DevToolsUtils.safeErrorString("not really an error");
|
||||
// Still get the message.
|
||||
do_check_true(s.includes("not really an error"));
|
||||
}
|
||||
|
||||
function test_with_thrower() {
|
||||
let s = DevToolsUtils.safeErrorString({
|
||||
toString: () => {
|
||||
throw new Error("Muahahaha");
|
||||
}
|
||||
});
|
||||
// Still don't fail, get string back.
|
||||
do_check_eq(typeof s, "string");
|
||||
}
|
||||
|
||||
function test_with_psychotic() {
|
||||
let s = DevToolsUtils.safeErrorString({
|
||||
toString: () => Object.create(null)
|
||||
});
|
||||
// Still get a string out, and no exceptions thrown
|
||||
do_check_eq(typeof s, "string");
|
||||
do_check_eq(s, "[object Object]");
|
||||
}
|
||||
45
devtools/shared/tests/unit/test_stack.js
Normal file
45
devtools/shared/tests/unit/test_stack.js
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test stack.js.
|
||||
|
||||
function run_test() {
|
||||
let loader = new DevToolsLoader();
|
||||
let require = loader.require;
|
||||
|
||||
const {StackFrameCache} = require("devtools/server/actors/utils/stack");
|
||||
|
||||
let cache = new StackFrameCache();
|
||||
cache.initFrames();
|
||||
let baseFrame = {
|
||||
line: 23,
|
||||
column: 77,
|
||||
source: "nowhere",
|
||||
functionDisplayName: "nobody",
|
||||
parent: null,
|
||||
asyncParent: null,
|
||||
asyncCause: null
|
||||
};
|
||||
cache.addFrame(baseFrame);
|
||||
|
||||
let event = cache.makeEvent();
|
||||
do_check_eq(event[0], null);
|
||||
do_check_eq(event[1].functionDisplayName, "nobody");
|
||||
do_check_eq(event.length, 2);
|
||||
|
||||
cache.addFrame({
|
||||
line: 24,
|
||||
column: 78,
|
||||
source: "nowhere",
|
||||
functionDisplayName: "still nobody",
|
||||
parent: null,
|
||||
asyncParent: baseFrame,
|
||||
asyncCause: "async"
|
||||
});
|
||||
|
||||
event = cache.makeEvent();
|
||||
do_check_eq(event[0].functionDisplayName, "still nobody");
|
||||
do_check_eq(event[0].parent, 0);
|
||||
do_check_eq(event[0].asyncParent, 1);
|
||||
do_check_eq(event.length, 1);
|
||||
}
|
||||
40
devtools/shared/tests/unit/xpcshell.ini
Normal file
40
devtools/shared/tests/unit/xpcshell.ini
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[DEFAULT]
|
||||
tags = devtools
|
||||
head = head_devtools.js
|
||||
tail =
|
||||
firefox-appdir = browser
|
||||
skip-if = toolkit == 'android'
|
||||
support-files =
|
||||
exposeLoader.js
|
||||
|
||||
[test_assert.js]
|
||||
[test_csslexer.js]
|
||||
[test_css-properties-db.js]
|
||||
# This test only enforces that the CSS database is up to date with nightly. The DB is
|
||||
# only used when inspecting a target that doesn't support the getCSSDatabase actor.
|
||||
# CSS properties are behind compile-time flags, and there is no automatic rebuild
|
||||
# process for uplifts, so this test breaks on uplift.
|
||||
run-if = nightly_build
|
||||
[test_fetch-bom.js]
|
||||
[test_fetch-chrome.js]
|
||||
[test_fetch-file.js]
|
||||
[test_fetch-http.js]
|
||||
[test_fetch-resource.js]
|
||||
[test_flatten.js]
|
||||
[test_indentation.js]
|
||||
[test_independent_loaders.js]
|
||||
[test_invisible_loader.js]
|
||||
[test_isSet.js]
|
||||
[test_safeErrorString.js]
|
||||
[test_defineLazyPrototypeGetter.js]
|
||||
[test_async-utils.js]
|
||||
[test_console_filtering.js]
|
||||
[test_pluralForm-english.js]
|
||||
[test_pluralForm-makeGetter.js]
|
||||
[test_prettifyCSS.js]
|
||||
[test_require_lazy.js]
|
||||
[test_require_raw.js]
|
||||
[test_require.js]
|
||||
[test_stack.js]
|
||||
[test_defer.js]
|
||||
[test_executeSoon.js]
|
||||
Loading…
Add table
Add a link
Reference in a new issue