diff options
Diffstat (limited to 'toolkit/modules')
105 files changed, 1 insertions, 14838 deletions
diff --git a/toolkit/modules/moz.build b/toolkit/modules/moz.build index c9d3fc7a01..c386759e75 100644 --- a/toolkit/modules/moz.build +++ b/toolkit/modules/moz.build @@ -4,17 +4,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/. -XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell/xpcshell.ini'] -BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini'] -MOCHITEST_MANIFESTS += ['tests/mochitest/mochitest.ini'] -MOCHITEST_CHROME_MANIFESTS += ['tests/chrome/chrome.ini'] - -TESTING_JS_MODULES += [ - 'tests/MockDocument.jsm', - 'tests/PromiseTestUtils.jsm', - 'tests/xpcshell/TestIntegration.jsm', -] - SPHINX_TREES['toolkit_modules'] = 'docs' EXTRA_JS_MODULES += [ diff --git a/toolkit/modules/subprocess/moz.build b/toolkit/modules/subprocess/moz.build index c4548c8f6c..e9c6e11981 100644 --- a/toolkit/modules/subprocess/moz.build +++ b/toolkit/modules/subprocess/moz.build @@ -4,9 +4,7 @@ # 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/. -EXTRA_PP_JS_MODULES += [ - 'Subprocess.jsm', -] +EXTRA_PP_JS_MODULES += ['Subprocess.jsm'] EXTRA_JS_MODULES.subprocess += [ 'subprocess_common.jsm', @@ -27,6 +25,4 @@ else: 'subprocess_worker_unix.js', ] -XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini'] - SPHINX_TREES['toolkit_modules/subprocess'] = ['docs'] diff --git a/toolkit/modules/subprocess/test/xpcshell/.eslintrc.js b/toolkit/modules/subprocess/test/xpcshell/.eslintrc.js deleted file mode 100644 index fc63a79b75..0000000000 --- a/toolkit/modules/subprocess/test/xpcshell/.eslintrc.js +++ /dev/null @@ -1,5 +0,0 @@ -"use strict"; - -module.exports = { // eslint-disable-line no-undef - "extends": "../../../../../testing/xpcshell/xpcshell.eslintrc.js", -}; diff --git a/toolkit/modules/subprocess/test/xpcshell/data_test_script.py b/toolkit/modules/subprocess/test/xpcshell/data_test_script.py deleted file mode 100644 index 035d8ac569..0000000000 --- a/toolkit/modules/subprocess/test/xpcshell/data_test_script.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python2 -from __future__ import print_function - -import os -import signal -import struct -import sys - - -def output(line): - sys.stdout.write(struct.pack('@I', len(line))) - sys.stdout.write(line) - sys.stdout.flush() - - -def echo_loop(): - while True: - line = sys.stdin.readline() - if not line: - break - - output(line) - - -if sys.platform == "win32": - import msvcrt - msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY) - - -cmd = sys.argv[1] -if cmd == 'echo': - echo_loop() -elif cmd == 'exit': - sys.exit(int(sys.argv[2])) -elif cmd == 'env': - for var in sys.argv[2:]: - output(os.environ.get(var, '')) -elif cmd == 'pwd': - output(os.path.abspath(os.curdir)) -elif cmd == 'print_args': - for arg in sys.argv[2:]: - output(arg) -elif cmd == 'ignore_sigterm': - signal.signal(signal.SIGTERM, signal.SIG_IGN) - - output('Ready') - while True: - try: - signal.pause() - except AttributeError: - import time - time.sleep(3600) -elif cmd == 'print': - sys.stdout.write(sys.argv[2]) - sys.stderr.write(sys.argv[3]) diff --git a/toolkit/modules/subprocess/test/xpcshell/data_text_file.txt b/toolkit/modules/subprocess/test/xpcshell/data_text_file.txt deleted file mode 100644 index e69de29bb2..0000000000 --- a/toolkit/modules/subprocess/test/xpcshell/data_text_file.txt +++ /dev/null diff --git a/toolkit/modules/subprocess/test/xpcshell/head.js b/toolkit/modules/subprocess/test/xpcshell/head.js deleted file mode 100644 index b3175d08a0..0000000000 --- a/toolkit/modules/subprocess/test/xpcshell/head.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "AppConstants", - "resource://gre/modules/AppConstants.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "OS", - "resource://gre/modules/osfile.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Services", - "resource://gre/modules/Services.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Subprocess", - "resource://gre/modules/Subprocess.jsm"); diff --git a/toolkit/modules/subprocess/test/xpcshell/test_subprocess.js b/toolkit/modules/subprocess/test/xpcshell/test_subprocess.js deleted file mode 100644 index 1b8e02820b..0000000000 --- a/toolkit/modules/subprocess/test/xpcshell/test_subprocess.js +++ /dev/null @@ -1,769 +0,0 @@ -"use strict"; - -Cu.import("resource://gre/modules/AppConstants.jsm"); -Cu.import("resource://gre/modules/Task.jsm"); -Cu.import("resource://gre/modules/Timer.jsm"); - - -const env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); - -const MAX_ROUND_TRIP_TIME_MS = AppConstants.DEBUG || AppConstants.ASAN ? 18 : 9; -const MAX_RETRIES = 5; - -let PYTHON; -let PYTHON_BIN; -let PYTHON_DIR; - -const TEST_SCRIPT = do_get_file("data_test_script.py").path; - -let read = pipe => { - return pipe.readUint32().then(count => { - return pipe.readString(count); - }); -}; - - -let readAll = Task.async(function* (pipe) { - let result = []; - let string; - while ((string = yield pipe.readString())) { - result.push(string); - } - - return result.join(""); -}); - - -add_task(function* setup() { - PYTHON = yield Subprocess.pathSearch(env.get("PYTHON")); - - PYTHON_BIN = OS.Path.basename(PYTHON); - PYTHON_DIR = OS.Path.dirname(PYTHON); -}); - - -add_task(function* test_subprocess_io() { - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "echo"], - }); - - Assert.throws(() => { proc.stdout.read(-1); }, - /non-negative integer/); - Assert.throws(() => { proc.stdout.read(1.1); }, - /non-negative integer/); - - Assert.throws(() => { proc.stdout.read(Infinity); }, - /non-negative integer/); - Assert.throws(() => { proc.stdout.read(NaN); }, - /non-negative integer/); - - Assert.throws(() => { proc.stdout.readString(-1); }, - /non-negative integer/); - Assert.throws(() => { proc.stdout.readString(1.1); }, - /non-negative integer/); - - Assert.throws(() => { proc.stdout.readJSON(-1); }, - /positive integer/); - Assert.throws(() => { proc.stdout.readJSON(0); }, - /positive integer/); - Assert.throws(() => { proc.stdout.readJSON(1.1); }, - /positive integer/); - - - const LINE1 = "I'm a leaf on the wind.\n"; - const LINE2 = "Watch how I soar.\n"; - - - let outputPromise = read(proc.stdout); - - yield new Promise(resolve => setTimeout(resolve, 100)); - - let [output] = yield Promise.all([ - outputPromise, - proc.stdin.write(LINE1), - ]); - - equal(output, LINE1, "Got expected output"); - - - // Make sure it succeeds whether the write comes before or after the - // read. - let inputPromise = proc.stdin.write(LINE2); - - yield new Promise(resolve => setTimeout(resolve, 100)); - - [output] = yield Promise.all([ - read(proc.stdout), - inputPromise, - ]); - - equal(output, LINE2, "Got expected output"); - - - let JSON_BLOB = {foo: {bar: "baz"}}; - - inputPromise = proc.stdin.write(JSON.stringify(JSON_BLOB) + "\n"); - - output = yield proc.stdout.readUint32().then(count => { - return proc.stdout.readJSON(count); - }); - - Assert.deepEqual(output, JSON_BLOB, "Got expected JSON output"); - - - yield proc.stdin.close(); - - let {exitCode} = yield proc.wait(); - - equal(exitCode, 0, "Got expected exit code"); -}); - - -add_task(function* test_subprocess_large_io() { - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "echo"], - }); - - const LINE = "I'm a leaf on the wind.\n"; - const BUFFER_SIZE = 4096; - - // Create a message that's ~3/4 the input buffer size. - let msg = Array(BUFFER_SIZE * .75 / 16 | 0).fill("0123456789abcdef").join("") + "\n"; - - // This sequence of writes and reads crosses several buffer size - // boundaries, and causes some branches of the read buffer code to be - // exercised which are not exercised by other tests. - proc.stdin.write(msg); - proc.stdin.write(msg); - proc.stdin.write(LINE); - - let output = yield read(proc.stdout); - equal(output, msg, "Got the expected output"); - - output = yield read(proc.stdout); - equal(output, msg, "Got the expected output"); - - output = yield read(proc.stdout); - equal(output, LINE, "Got the expected output"); - - proc.stdin.close(); - - - let {exitCode} = yield proc.wait(); - - equal(exitCode, 0, "Got expected exit code"); -}); - - -add_task(function* test_subprocess_huge() { - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "echo"], - }); - - // This should be large enough to fill most pipe input/output buffers. - const MESSAGE_SIZE = 1024 * 16; - - let msg = Array(MESSAGE_SIZE).fill("0123456789abcdef").join("") + "\n"; - - proc.stdin.write(msg); - - let output = yield read(proc.stdout); - equal(output, msg, "Got the expected output"); - - proc.stdin.close(); - - - let {exitCode} = yield proc.wait(); - - equal(exitCode, 0, "Got expected exit code"); -}); - - -add_task(function* test_subprocess_round_trip_perf() { - let roundTripTime = Infinity; - for (let i = 0; i < MAX_RETRIES && roundTripTime > MAX_ROUND_TRIP_TIME_MS; i++) { - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "echo"], - }); - - - const LINE = "I'm a leaf on the wind.\n"; - - let now = Date.now(); - const COUNT = 1000; - for (let j = 0; j < COUNT; j++) { - let [output] = yield Promise.all([ - read(proc.stdout), - proc.stdin.write(LINE), - ]); - - // We don't want to log this for every iteration, but we still need - // to fail if it goes wrong. - if (output !== LINE) { - equal(output, LINE, "Got expected output"); - } - } - - roundTripTime = (Date.now() - now) / COUNT; - - yield proc.stdin.close(); - - let {exitCode} = yield proc.wait(); - - equal(exitCode, 0, "Got expected exit code"); - } - - ok(roundTripTime <= MAX_ROUND_TRIP_TIME_MS, - `Expected round trip time (${roundTripTime}ms) to be less than ${MAX_ROUND_TRIP_TIME_MS}ms`); -}); - - -add_task(function* test_subprocess_stderr_default() { - const LINE1 = "I'm a leaf on the wind.\n"; - const LINE2 = "Watch how I soar.\n"; - - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "print", LINE1, LINE2], - }); - - equal(proc.stderr, undefined, "There should be no stderr pipe by default"); - - let stdout = yield readAll(proc.stdout); - - equal(stdout, LINE1, "Got the expected stdout output"); - - - let {exitCode} = yield proc.wait(); - - equal(exitCode, 0, "Got expected exit code"); -}); - - -add_task(function* test_subprocess_stderr_pipe() { - const LINE1 = "I'm a leaf on the wind.\n"; - const LINE2 = "Watch how I soar.\n"; - - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "print", LINE1, LINE2], - stderr: "pipe", - }); - - let [stdout, stderr] = yield Promise.all([ - readAll(proc.stdout), - readAll(proc.stderr), - ]); - - equal(stdout, LINE1, "Got the expected stdout output"); - equal(stderr, LINE2, "Got the expected stderr output"); - - - let {exitCode} = yield proc.wait(); - - equal(exitCode, 0, "Got expected exit code"); -}); - - -add_task(function* test_subprocess_stderr_merged() { - const LINE1 = "I'm a leaf on the wind.\n"; - const LINE2 = "Watch how I soar.\n"; - - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "print", LINE1, LINE2], - stderr: "stdout", - }); - - equal(proc.stderr, undefined, "There should be no stderr pipe by default"); - - let stdout = yield readAll(proc.stdout); - - equal(stdout, LINE1 + LINE2, "Got the expected merged stdout output"); - - - let {exitCode} = yield proc.wait(); - - equal(exitCode, 0, "Got expected exit code"); -}); - - -add_task(function* test_subprocess_read_after_exit() { - const LINE1 = "I'm a leaf on the wind.\n"; - const LINE2 = "Watch how I soar.\n"; - - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "print", LINE1, LINE2], - stderr: "pipe", - }); - - - let {exitCode} = yield proc.wait(); - equal(exitCode, 0, "Process exited with expected code"); - - - let [stdout, stderr] = yield Promise.all([ - readAll(proc.stdout), - readAll(proc.stderr), - ]); - - equal(stdout, LINE1, "Got the expected stdout output"); - equal(stderr, LINE2, "Got the expected stderr output"); -}); - - -add_task(function* test_subprocess_lazy_close_output() { - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "echo"], - }); - - const LINE1 = "I'm a leaf on the wind.\n"; - const LINE2 = "Watch how I soar.\n"; - - let writePromises = [ - proc.stdin.write(LINE1), - proc.stdin.write(LINE2), - ]; - let closedPromise = proc.stdin.close(); - - - let output1 = yield read(proc.stdout); - let output2 = yield read(proc.stdout); - - yield Promise.all([...writePromises, closedPromise]); - - equal(output1, LINE1, "Got expected output"); - equal(output2, LINE2, "Got expected output"); - - - let {exitCode} = yield proc.wait(); - - equal(exitCode, 0, "Got expected exit code"); -}); - - -add_task(function* test_subprocess_lazy_close_input() { - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "echo"], - }); - - let readPromise = proc.stdout.readUint32(); - let closedPromise = proc.stdout.close(); - - - const LINE = "I'm a leaf on the wind.\n"; - - proc.stdin.write(LINE); - proc.stdin.close(); - - let len = yield readPromise; - equal(len, LINE.length); - - yield closedPromise; - - - // Don't test for a successful exit here. The process may exit with a - // write error if we close the pipe after it's written the message - // size but before it's written the message. - yield proc.wait(); -}); - - -add_task(function* test_subprocess_force_close() { - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "echo"], - }); - - let readPromise = proc.stdout.readUint32(); - let closedPromise = proc.stdout.close(true); - - yield Assert.rejects( - readPromise, - function(e) { - equal(e.errorCode, Subprocess.ERROR_END_OF_FILE, - "Got the expected error code"); - return /File closed/.test(e.message); - }, - "Promise should be rejected when file is closed"); - - yield closedPromise; - yield proc.stdin.close(); - - - let {exitCode} = yield proc.wait(); - - equal(exitCode, 0, "Got expected exit code"); -}); - - -add_task(function* test_subprocess_eof() { - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "echo"], - }); - - let readPromise = proc.stdout.readUint32(); - - yield proc.stdin.close(); - - yield Assert.rejects( - readPromise, - function(e) { - equal(e.errorCode, Subprocess.ERROR_END_OF_FILE, - "Got the expected error code"); - return /File closed/.test(e.message); - }, - "Promise should be rejected on EOF"); - - let {exitCode} = yield proc.wait(); - - equal(exitCode, 0, "Got expected exit code"); -}); - - -add_task(function* test_subprocess_invalid_json() { - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "echo"], - }); - - const LINE = "I'm a leaf on the wind.\n"; - - proc.stdin.write(LINE); - proc.stdin.close(); - - let count = yield proc.stdout.readUint32(); - let readPromise = proc.stdout.readJSON(count); - - yield Assert.rejects( - readPromise, - function(e) { - equal(e.errorCode, Subprocess.ERROR_INVALID_JSON, - "Got the expected error code"); - return /SyntaxError/.test(e); - }, - "Promise should be rejected on EOF"); - - let {exitCode} = yield proc.wait(); - - equal(exitCode, 0, "Got expected exit code"); -}); - - -if (AppConstants.isPlatformAndVersionAtLeast("win", "6")) { - add_task(function* test_subprocess_inherited_descriptors() { - let {ctypes, libc, win32} = Cu.import("resource://gre/modules/subprocess/subprocess_win.jsm"); - - let secAttr = new win32.SECURITY_ATTRIBUTES(); - secAttr.nLength = win32.SECURITY_ATTRIBUTES.size; - secAttr.bInheritHandle = true; - - let handles = win32.createPipe(secAttr, 0); - - - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "echo"], - }); - - - // Close the output end of the pipe. - // Ours should be the only copy, so reads should fail after this. - handles[1].dispose(); - - let buffer = new ArrayBuffer(1); - let succeeded = libc.ReadFile(handles[0], buffer, buffer.byteLength, - null, null); - - ok(!succeeded, "ReadFile should fail on broken pipe"); - equal(ctypes.winLastError, win32.ERROR_BROKEN_PIPE, "Read should fail with ERROR_BROKEN_PIPE"); - - - proc.stdin.close(); - - let {exitCode} = yield proc.wait(); - - equal(exitCode, 0, "Got expected exit code"); - }); -} - - -add_task(function* test_subprocess_wait() { - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "exit", "42"], - }); - - let {exitCode} = yield proc.wait(); - - equal(exitCode, 42, "Got expected exit code"); -}); - - -add_task(function* test_subprocess_pathSearch() { - let promise = Subprocess.call({ - command: PYTHON_BIN, - arguments: ["-u", TEST_SCRIPT, "exit", "13"], - environment: { - PATH: PYTHON_DIR, - }, - }); - - yield Assert.rejects( - promise, - function(error) { - return error.errorCode == Subprocess.ERROR_BAD_EXECUTABLE; - }, - "Subprocess.call should fail for a bad executable"); -}); - - -add_task(function* test_subprocess_workdir() { - let procDir = yield OS.File.getCurrentDirectory(); - let tmpDirFile = Components.classes["@mozilla.org/file/local;1"] - .createInstance(Components.interfaces.nsILocalFile); - tmpDirFile.initWithPath(OS.Constants.Path.tmpDir); - tmpDirFile.normalize(); - let tmpDir = tmpDirFile.path; - - notEqual(procDir, tmpDir, - "Current process directory must not be the current temp directory"); - - function* pwd(options) { - let proc = yield Subprocess.call(Object.assign({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "pwd"], - }, options)); - - let pwdOutput = read(proc.stdout); - - let {exitCode} = yield proc.wait(); - equal(exitCode, 0, "Got expected exit code"); - - return pwdOutput; - } - - let dir = yield pwd({}); - equal(dir, procDir, "Process should normally launch in current process directory"); - - dir = yield pwd({workdir: tmpDir}); - equal(dir, tmpDir, "Process should launch in the directory specified in `workdir`"); - - dir = yield OS.File.getCurrentDirectory(); - equal(dir, procDir, "`workdir` should not change the working directory of the current process"); -}); - - -add_task(function* test_subprocess_term() { - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "echo"], - }); - - // Windows does not support killing processes gracefully, so they will - // always exit with -9 there. - let retVal = AppConstants.platform == "win" ? -9 : -15; - - // Kill gracefully with the default timeout of 300ms. - let {exitCode} = yield proc.kill(); - - equal(exitCode, retVal, "Got expected exit code"); - - ({exitCode} = yield proc.wait()); - - equal(exitCode, retVal, "Got expected exit code"); -}); - - -add_task(function* test_subprocess_kill() { - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "echo"], - }); - - // Force kill with no gracefull termination timeout. - let {exitCode} = yield proc.kill(0); - - equal(exitCode, -9, "Got expected exit code"); - - ({exitCode} = yield proc.wait()); - - equal(exitCode, -9, "Got expected exit code"); -}); - - -add_task(function* test_subprocess_kill_timeout() { - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "ignore_sigterm"], - }); - - // Wait for the process to set up its signal handler and tell us it's - // ready. - let msg = yield read(proc.stdout); - equal(msg, "Ready", "Process is ready"); - - // Kill gracefully with the default timeout of 300ms. - // Expect a force kill after 300ms, since the process traps SIGTERM. - const TIMEOUT = 300; - let startTime = Date.now(); - - let {exitCode} = yield proc.kill(TIMEOUT); - - // Graceful termination is not supported on Windows, so don't bother - // testing the timeout there. - if (AppConstants.platform != "win") { - let diff = Date.now() - startTime; - ok(diff >= TIMEOUT, `Process was killed after ${diff}ms (expected ~${TIMEOUT}ms)`); - } - - equal(exitCode, -9, "Got expected exit code"); - - ({exitCode} = yield proc.wait()); - - equal(exitCode, -9, "Got expected exit code"); -}); - - -add_task(function* test_subprocess_arguments() { - let args = [ - String.raw`C:\Program Files\Company\Program.exe`, - String.raw`\\NETWORK SHARE\Foo Directory${"\\"}`, - String.raw`foo bar baz`, - String.raw`"foo bar baz"`, - String.raw`foo " bar`, - String.raw`Thing \" with "" "\" \\\" \\\\" quotes\\" \\`, - ]; - - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "print_args", ...args], - }); - - for (let [i, arg] of args.entries()) { - let val = yield read(proc.stdout); - equal(val, arg, `Got correct value for args[${i}]`); - } - - let {exitCode} = yield proc.wait(); - - equal(exitCode, 0, "Got expected exit code"); -}); - - -// Windows XP can't handle launching Python with a partial environment. -if (!AppConstants.isPlatformAndVersionAtMost("win", "5.2")) { - add_task(function* test_subprocess_environment() { - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "env", "PATH", "FOO"], - environment: { - FOO: "BAR", - }, - }); - - let path = yield read(proc.stdout); - let foo = yield read(proc.stdout); - - equal(path, "", "Got expected $PATH value"); - equal(foo, "BAR", "Got expected $FOO value"); - - let {exitCode} = yield proc.wait(); - - equal(exitCode, 0, "Got expected exit code"); - }); -} - - -add_task(function* test_subprocess_environmentAppend() { - let proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "env", "PATH", "FOO"], - environmentAppend: true, - environment: { - FOO: "BAR", - }, - }); - - let path = yield read(proc.stdout); - let foo = yield read(proc.stdout); - - equal(path, env.get("PATH"), "Got expected $PATH value"); - equal(foo, "BAR", "Got expected $FOO value"); - - let {exitCode} = yield proc.wait(); - - equal(exitCode, 0, "Got expected exit code"); - - proc = yield Subprocess.call({ - command: PYTHON, - arguments: ["-u", TEST_SCRIPT, "env", "PATH", "FOO"], - environmentAppend: true, - }); - - path = yield read(proc.stdout); - foo = yield read(proc.stdout); - - equal(path, env.get("PATH"), "Got expected $PATH value"); - equal(foo, "", "Got expected $FOO value"); - - ({exitCode} = yield proc.wait()); - - equal(exitCode, 0, "Got expected exit code"); -}); - - -add_task(function* test_bad_executable() { - // Test with a non-executable file. - - let textFile = do_get_file("data_text_file.txt").path; - - let promise = Subprocess.call({ - command: textFile, - arguments: [], - }); - - yield Assert.rejects( - promise, - function(error) { - if (AppConstants.platform == "win") { - return /Failed to create process/.test(error.message); - } - return error.errorCode == Subprocess.ERROR_BAD_EXECUTABLE; - }, - "Subprocess.call should fail for a bad executable"); - - // Test with a nonexistent file. - promise = Subprocess.call({ - command: textFile + ".doesNotExist", - arguments: [], - }); - - yield Assert.rejects( - promise, - function(error) { - return error.errorCode == Subprocess.ERROR_BAD_EXECUTABLE; - }, - "Subprocess.call should fail for a bad executable"); -}); - - -add_task(function* test_cleanup() { - let {SubprocessImpl} = Cu.import("resource://gre/modules/Subprocess.jsm"); - - let worker = SubprocessImpl.Process.getWorker(); - - let openFiles = yield worker.call("getOpenFiles", []); - let processes = yield worker.call("getProcesses", []); - - equal(openFiles.size, 0, "No remaining open files"); - equal(processes.size, 0, "No remaining processes"); -}); diff --git a/toolkit/modules/subprocess/test/xpcshell/test_subprocess_getEnvironment.js b/toolkit/modules/subprocess/test/xpcshell/test_subprocess_getEnvironment.js deleted file mode 100644 index 4606aec04e..0000000000 --- a/toolkit/modules/subprocess/test/xpcshell/test_subprocess_getEnvironment.js +++ /dev/null @@ -1,17 +0,0 @@ -"use strict"; - -let env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); - -add_task(function* test_getEnvironment() { - env.set("FOO", "BAR"); - - let environment = Subprocess.getEnvironment(); - - equal(environment.FOO, "BAR"); - equal(environment.PATH, env.get("PATH")); - - env.set("FOO", null); - - environment = Subprocess.getEnvironment(); - equal(environment.FOO || "", ""); -}); diff --git a/toolkit/modules/subprocess/test/xpcshell/test_subprocess_pathSearch.js b/toolkit/modules/subprocess/test/xpcshell/test_subprocess_pathSearch.js deleted file mode 100644 index 5eb4cd412d..0000000000 --- a/toolkit/modules/subprocess/test/xpcshell/test_subprocess_pathSearch.js +++ /dev/null @@ -1,73 +0,0 @@ -"use strict"; - -let envService = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); - -const PYTHON = envService.get("PYTHON"); - -const PYTHON_BIN = OS.Path.basename(PYTHON); -const PYTHON_DIR = OS.Path.dirname(PYTHON); - -const DOES_NOT_EXIST = OS.Path.join(OS.Constants.Path.tmpDir, - "ThisPathDoesNotExist"); - -const PATH_SEP = AppConstants.platform == "win" ? ";" : ":"; - - -add_task(function* test_pathSearchAbsolute() { - let env = {}; - - let path = yield Subprocess.pathSearch(PYTHON, env); - equal(path, PYTHON, "Full path resolves even with no PATH."); - - env.PATH = ""; - path = yield Subprocess.pathSearch(PYTHON, env); - equal(path, PYTHON, "Full path resolves even with empty PATH."); - - yield Assert.rejects( - Subprocess.pathSearch(DOES_NOT_EXIST, env), - function(e) { - equal(e.errorCode, Subprocess.ERROR_BAD_EXECUTABLE, - "Got the expected error code"); - return /File at path .* does not exist, or is not (executable|a normal file)/.test(e.message); - }, - "Absolute path should throw for a nonexistent execuable"); -}); - - -add_task(function* test_pathSearchRelative() { - let env = {}; - - yield Assert.rejects( - Subprocess.pathSearch(PYTHON_BIN, env), - function(e) { - equal(e.errorCode, Subprocess.ERROR_BAD_EXECUTABLE, - "Got the expected error code"); - return /Executable not found:/.test(e.message); - }, - "Relative path should not be found when PATH is missing"); - - env.PATH = [DOES_NOT_EXIST, PYTHON_DIR].join(PATH_SEP); - - let path = yield Subprocess.pathSearch(PYTHON_BIN, env); - equal(path, PYTHON, "Correct executable should be found in the path"); -}); - - -add_task({ - skip_if: () => AppConstants.platform != "win", -}, function* test_pathSearch_PATHEXT() { - ok(PYTHON_BIN.endsWith(".exe"), "Python executable must end with .exe"); - - const python_bin = PYTHON_BIN.slice(0, -4); - - let env = { - PATH: PYTHON_DIR, - PATHEXT: [".com", ".exe", ".foobar"].join(";"), - }; - - let path = yield Subprocess.pathSearch(python_bin, env); - equal(path, PYTHON, "Correct executable should be found in the path, with guessed extension"); -}); -// IMPORTANT: Do not add any tests beyond this point without removing -// the `skip_if` condition from the previous task, or it will prevent -// all succeeding tasks from running when it does not match. diff --git a/toolkit/modules/subprocess/test/xpcshell/xpcshell.ini b/toolkit/modules/subprocess/test/xpcshell/xpcshell.ini deleted file mode 100644 index 7b7d49a73c..0000000000 --- a/toolkit/modules/subprocess/test/xpcshell/xpcshell.ini +++ /dev/null @@ -1,14 +0,0 @@ -[DEFAULT] -head = head.js -tail = -firefox-appdir = browser -skip-if = os == 'android' -subprocess = true -support-files = - data_text_file.txt - data_test_script.py - -[test_subprocess.js] -skip-if = os == 'win' # Path issues due to venv changes on the test machines -[test_subprocess_getEnvironment.js] -[test_subprocess_pathSearch.js] diff --git a/toolkit/modules/tests/MockDocument.jsm b/toolkit/modules/tests/MockDocument.jsm deleted file mode 100644 index 3cae9bb910..0000000000 --- a/toolkit/modules/tests/MockDocument.jsm +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Provides infrastructure for tests that would require mock document. - */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["MockDocument"] - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.importGlobalProperties(["URL"]); - -const MockDocument = { - /** - * Create a document for the given URL containing the given HTML with the ownerDocument of all <form>s having a mocked location. - */ - createTestDocument(aDocumentURL, aContent = "<form>", aType = "text/html") { - let parser = Cc["@mozilla.org/xmlextras/domparser;1"]. - createInstance(Ci.nsIDOMParser); - parser.init(); - let parsedDoc = parser.parseFromString(aContent, aType); - - for (let element of parsedDoc.forms) { - this.mockOwnerDocumentProperty(element, parsedDoc, aDocumentURL); - } - return parsedDoc; - }, - - mockOwnerDocumentProperty(aElement, aDoc, aURL) { - // Mock the document.location object so we can unit test without a frame. We use a proxy - // instead of just assigning to the property since it's not configurable or writable. - let document = new Proxy(aDoc, { - get(target, property, receiver) { - // document.location is normally null when a document is outside of a "browsing context". - // See https://html.spec.whatwg.org/#the-location-interface - if (property == "location") { - return new URL(aURL); - } - return target[property]; - }, - }); - - // Assign element.ownerDocument to the proxy so document.location works. - Object.defineProperty(aElement, "ownerDocument", { - value: document, - }); - }, - -}; - diff --git a/toolkit/modules/tests/PromiseTestUtils.jsm b/toolkit/modules/tests/PromiseTestUtils.jsm deleted file mode 100644 index d60b785a58..0000000000 --- a/toolkit/modules/tests/PromiseTestUtils.jsm +++ /dev/null @@ -1,241 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/* - * Detects and reports unhandled rejections during test runs. Test harnesses - * will fail tests in this case, unless the test whitelists itself. - */ - -"use strict"; - -this.EXPORTED_SYMBOLS = [ - "PromiseTestUtils", -]; - -const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; - -Cu.import("resource://gre/modules/Services.jsm", this); - -// Keep "JSMPromise" separate so "Promise" still refers to DOM Promises. -let JSMPromise = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise; - -// For now, we need test harnesses to provide a reference to Assert.jsm. -let Assert = null; - -this.PromiseTestUtils = { - /** - * Array of objects containing the details of the Promise rejections that are - * currently left uncaught. This includes DOM Promise and Promise.jsm. When - * rejections in DOM Promises are consumed, they are removed from this list. - * - * The objects contain at least the following properties: - * { - * message: The error message associated with the rejection, if any. - * date: Date object indicating when the rejection was observed. - * id: For DOM Promise only, the Promise ID from PromiseDebugging. This is - * only used for tracking and should not be checked by the callers. - * stack: nsIStackFrame, SavedFrame, or string indicating the stack at the - * time the rejection was triggered. May also be null if the - * rejection was triggered while a script was on the stack. - * } - */ - _rejections: [], - - /** - * When an uncaught rejection is detected, it is ignored if one of the - * functions in this array returns true when called with the rejection details - * as its only argument. When a function matches an expected rejection, it is - * then removed from the array. - */ - _rejectionIgnoreFns: [], - - /** - * Called only by the test infrastructure, registers the rejection observers. - * - * This should be called only once, and a matching "uninit" call must be made - * or the tests will crash on shutdown. - */ - init() { - if (this._initialized) { - Cu.reportError("This object was already initialized."); - return; - } - - PromiseDebugging.addUncaughtRejectionObserver(this); - - // Promise.jsm rejections are only reported to this observer when requested, - // so we don't have to store a key to remove them when consumed. - JSMPromise.Debugging.addUncaughtErrorObserver( - rejection => this._rejections.push(rejection)); - - this._initialized = true; - }, - _initialized: false, - - /** - * Called only by the test infrastructure, unregisters the observers. - */ - uninit() { - if (!this._initialized) { - return; - } - - PromiseDebugging.removeUncaughtRejectionObserver(this); - JSMPromise.Debugging.clearUncaughtErrorObservers(); - - this._initialized = false; - }, - - /** - * Called only by the test infrastructure, spins the event loop until the - * messages for pending DOM Promise rejections have been processed. - */ - ensureDOMPromiseRejectionsProcessed() { - let observed = false; - let observer = { - onLeftUncaught: promise => { - if (PromiseDebugging.getState(promise).reason === - this._ensureDOMPromiseRejectionsProcessedReason) { - observed = true; - } - }, - onConsumed() {}, - }; - - PromiseDebugging.addUncaughtRejectionObserver(observer); - Promise.reject(this._ensureDOMPromiseRejectionsProcessedReason); - while (!observed) { - Services.tm.mainThread.processNextEvent(true); - } - PromiseDebugging.removeUncaughtRejectionObserver(observer); - }, - _ensureDOMPromiseRejectionsProcessedReason: {}, - - /** - * Called only by the tests for PromiseDebugging.addUncaughtRejectionObserver - * and for JSMPromise.Debugging, disables the observers in this module. - */ - disableUncaughtRejectionObserverForSelfTest() { - this.uninit(); - }, - - /** - * Called by tests that have been whitelisted, disables the observers in this - * module. For new tests where uncaught rejections are expected, you should - * use the more granular expectUncaughtRejection function instead. - */ - thisTestLeaksUncaughtRejectionsAndShouldBeFixed() { - this.uninit(); - }, - - /** - * Sets or updates the Assert object instance to be used for error reporting. - */ - set Assert(assert) { - Assert = assert; - }, - - // UncaughtRejectionObserver - onLeftUncaught(promise) { - let message = "(Unable to convert rejection reason to string.)"; - try { - let reason = PromiseDebugging.getState(promise).reason; - if (reason === this._ensureDOMPromiseRejectionsProcessedReason) { - // Ignore the special promise for ensureDOMPromiseRejectionsProcessed. - return; - } - message = reason.message || ("" + reason); - } catch (ex) {} - - // It's important that we don't store any reference to the provided Promise - // object or its value after this function returns in order to avoid leaks. - this._rejections.push({ - id: PromiseDebugging.getPromiseID(promise), - message, - date: new Date(), - stack: PromiseDebugging.getRejectionStack(promise), - }); - }, - - // UncaughtRejectionObserver - onConsumed(promise) { - // We don't expect that many unhandled rejections will appear at the same - // time, so the algorithm doesn't need to be optimized for that case. - let id = PromiseDebugging.getPromiseID(promise); - let index = this._rejections.findIndex(rejection => rejection.id == id); - // If we get a consumption notification for a rejection that was left - // uncaught before this module was initialized, we can safely ignore it. - if (index != -1) { - this._rejections.splice(index, 1); - } - }, - - /** - * Informs the test suite that the test code will generate a Promise rejection - * that will still be unhandled when the test file terminates. - * - * This method must be called once for each instance of Promise that is - * expected to be uncaught, even if the rejection reason is the same for each - * instance. - * - * If the expected rejection does not occur, the test will fail. - * - * @param regExpOrCheckFn - * This can either be a regular expression that should match the error - * message of the rejection, or a check function that is invoked with - * the rejection details object as its first argument. - */ - expectUncaughtRejection(regExpOrCheckFn) { - let checkFn = !("test" in regExpOrCheckFn) ? regExpOrCheckFn : - rejection => regExpOrCheckFn.test(rejection.message); - this._rejectionIgnoreFns.push(checkFn); - }, - - /** - * Fails the test if there are any uncaught rejections at this time that have - * not been whitelisted using expectUncaughtRejection. - * - * Depending on the configuration of the test suite, this function might only - * report the details of the first uncaught rejection that was generated. - * - * This is called by the test suite at the end of each test function. - */ - assertNoUncaughtRejections() { - // Ask Promise.jsm to report all uncaught rejections to the observer now. - JSMPromise.Debugging.flushUncaughtErrors(); - - // If there is any uncaught rejection left at this point, the test fails. - while (this._rejections.length > 0) { - let rejection = this._rejections.shift(); - - // If one of the ignore functions matches, ignore the rejection, then - // remove the function so that each function only matches one rejection. - let index = this._rejectionIgnoreFns.findIndex(f => f(rejection)); - if (index != -1) { - this._rejectionIgnoreFns.splice(index, 1); - continue; - } - - // Report the error. This operation can throw an exception, depending on - // the configuration of the test suite that handles the assertion. - Assert.ok(false, - `A promise chain failed to handle a rejection:` + - ` ${rejection.message} - rejection date: ${rejection.date}`+ - ` - stack: ${rejection.stack}`); - } - }, - - /** - * Fails the test if any rejection indicated by expectUncaughtRejection has - * not yet been reported at this time. - * - * This is called by the test suite at the end of each test file. - */ - assertNoMoreExpectedRejections() { - // Only log this condition is there is a failure. - if (this._rejectionIgnoreFns.length > 0) { - Assert.equal(this._rejectionIgnoreFns.length, 0, - "Unable to find a rejection expected by expectUncaughtRejection."); - } - }, -}; diff --git a/toolkit/modules/tests/browser/.eslintrc.js b/toolkit/modules/tests/browser/.eslintrc.js deleted file mode 100644 index c764b133dc..0000000000 --- a/toolkit/modules/tests/browser/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; - -module.exports = { - "extends": [ - "../../../../testing/mochitest/browser.eslintrc.js" - ] -}; diff --git a/toolkit/modules/tests/browser/WebRequest_dynamic.sjs b/toolkit/modules/tests/browser/WebRequest_dynamic.sjs deleted file mode 100644 index 7b34a377d3..0000000000 --- a/toolkit/modules/tests/browser/WebRequest_dynamic.sjs +++ /dev/null @@ -1,13 +0,0 @@ -function handleRequest(aRequest, aResponse) { - aResponse.setStatusLine(aRequest.httpVersion, 200); - if (aRequest.hasHeader('Cookie')) { - let value = aRequest.getHeader("Cookie"); - if (value == "blinky=1") { - aResponse.setHeader("Set-Cookie", "dinky=1"); - } - aResponse.write("cookie-present"); - } else { - aResponse.setHeader("Set-Cookie", "foopy=1"); - aResponse.write("cookie-not-present"); - } -} diff --git a/toolkit/modules/tests/browser/WebRequest_redirection.sjs b/toolkit/modules/tests/browser/WebRequest_redirection.sjs deleted file mode 100644 index 370ecd213f..0000000000 --- a/toolkit/modules/tests/browser/WebRequest_redirection.sjs +++ /dev/null @@ -1,4 +0,0 @@ -function handleRequest(aRequest, aResponse) { - aResponse.setStatusLine(aRequest.httpVersion, 302); - aResponse.setHeader("Location", "./dummy_page.html"); -} diff --git a/toolkit/modules/tests/browser/browser.ini b/toolkit/modules/tests/browser/browser.ini deleted file mode 100644 index e82feaa427..0000000000 --- a/toolkit/modules/tests/browser/browser.ini +++ /dev/null @@ -1,41 +0,0 @@ -[DEFAULT] -support-files = - dummy_page.html - metadata_*.html - testremotepagemanager.html - file_WebNavigation_page1.html - file_WebNavigation_page2.html - file_WebNavigation_page3.html - file_WebRequest_page1.html - file_WebRequest_page2.html - file_image_good.png - file_image_bad.png - file_image_redirect.png - file_style_good.css - file_style_bad.css - file_style_redirect.css - file_script_good.js - file_script_bad.js - file_script_redirect.js - file_script_xhr.js - WebRequest_dynamic.sjs - WebRequest_redirection.sjs - -[browser_AsyncPrefs.js] -[browser_Battery.js] -[browser_Deprecated.js] -[browser_Finder.js] -[browser_Finder_hidden_textarea.js] -[browser_FinderHighlighter.js] -skip-if = debug || os = "linux" -support-files = file_FinderSample.html -[browser_Geometry.js] -[browser_InlineSpellChecker.js] -[browser_WebNavigation.js] -[browser_WebRequest.js] -[browser_WebRequest_cookies.js] -[browser_WebRequest_filtering.js] -[browser_PageMetadata.js] -[browser_PromiseMessage.js] -[browser_RemotePageManager.js] -[browser_Troubleshoot.js] diff --git a/toolkit/modules/tests/browser/browser_AsyncPrefs.js b/toolkit/modules/tests/browser/browser_AsyncPrefs.js deleted file mode 100644 index 1d20a37898..0000000000 --- a/toolkit/modules/tests/browser/browser_AsyncPrefs.js +++ /dev/null @@ -1,97 +0,0 @@ -"use strict"; - -const kWhiteListedBool = "testing.allowed-prefs.some-bool-pref"; -const kWhiteListedChar = "testing.allowed-prefs.some-char-pref"; -const kWhiteListedInt = "testing.allowed-prefs.some-int-pref"; - -function resetPrefs() { - for (let pref of [kWhiteListedBool, kWhiteListedChar, kWhiteListedBool]) { - Services.prefs.clearUserPref(pref); - } -} - -registerCleanupFunction(resetPrefs); - -Services.prefs.getDefaultBranch("testing.allowed-prefs.").setBoolPref("some-bool-pref", false); -Services.prefs.getDefaultBranch("testing.allowed-prefs.").setCharPref("some-char-pref", ""); -Services.prefs.getDefaultBranch("testing.allowed-prefs.").setIntPref("some-int-pref", 0); - -function* runTest() { - let {AsyncPrefs} = Cu.import("resource://gre/modules/AsyncPrefs.jsm", {}); - const kInChildProcess = Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT; - - // Need to define these again because when run in a content task we have no scope access. - const kNotWhiteListed = "some.pref.thats.not.whitelisted"; - const kWhiteListedBool = "testing.allowed-prefs.some-bool-pref"; - const kWhiteListedChar = "testing.allowed-prefs.some-char-pref"; - const kWhiteListedInt = "testing.allowed-prefs.some-int-pref"; - - const procDesc = kInChildProcess ? "child process" : "parent process"; - - const valueResultMap = [ - [true, "Bool"], - [false, "Bool"], - [10, "Int"], - [-1, "Int"], - ["", "Char"], - ["stuff", "Char"], - [[], false], - [{}, false], - [BrowserUtils.makeURI("http://mozilla.org/"), false], - ]; - - const prefMap = [ - ["Bool", kWhiteListedBool], - ["Char", kWhiteListedChar], - ["Int", kWhiteListedInt], - ]; - - function doesFail(pref, value) { - let msg = `Should not succeed setting ${pref} to ${value} in ${procDesc}`; - return AsyncPrefs.set(pref, value).then(() => ok(false, msg), error => ok(true, msg + "; " + error)); - } - - function doesWork(pref, value) { - let msg = `Should be able to set ${pref} to ${value} in ${procDesc}`; - return AsyncPrefs.set(pref, value).then(() => ok(true, msg), error => ok(false, msg + "; " + error)); - } - - function doReset(pref) { - let msg = `Should be able to reset ${pref} in ${procDesc}`; - return AsyncPrefs.reset(pref).then(() => ok(true, msg), () => ok(false, msg)); - } - - for (let [val, ] of valueResultMap) { - yield doesFail(kNotWhiteListed, val); - is(Services.prefs.prefHasUserValue(kNotWhiteListed), false, "Pref shouldn't get changed"); - } - - let resetMsg = `Should not succeed resetting ${kNotWhiteListed} in ${procDesc}`; - AsyncPrefs.reset(kNotWhiteListed).then(() => ok(false, resetMsg), error => ok(true, resetMsg + "; " + error)); - - for (let [type, pref] of prefMap) { - for (let [val, result] of valueResultMap) { - if (result == type) { - yield doesWork(pref, val); - is(Services.prefs["get" + type + "Pref"](pref), val, "Pref should have been updated"); - yield doReset(pref); - } else { - yield doesFail(pref, val); - is(Services.prefs.prefHasUserValue(pref), false, `Pref ${pref} shouldn't get changed`); - } - } - } -} - -add_task(function* runInParent() { - yield runTest(); - resetPrefs(); -}); - -if (gMultiProcessBrowser) { - add_task(function* runInChild() { - ok(gBrowser.selectedBrowser.isRemoteBrowser, "Should actually run this in child process"); - yield ContentTask.spawn(gBrowser.selectedBrowser, null, runTest); - resetPrefs(); - }); -} diff --git a/toolkit/modules/tests/browser/browser_Battery.js b/toolkit/modules/tests/browser/browser_Battery.js deleted file mode 100644 index 2d3ba5da19..0000000000 --- a/toolkit/modules/tests/browser/browser_Battery.js +++ /dev/null @@ -1,51 +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 imported = Components.utils.import("resource://gre/modules/Battery.jsm", this); -Cu.import("resource://gre/modules/Services.jsm", this); - -function test() { - waitForExplicitFinish(); - - is(imported.Debugging.fake, false, "Battery spoofing is initially false") - - GetBattery().then(function (battery) { - for (let k of ["charging", "chargingTime", "dischargingTime", "level"]) { - let backup = battery[k]; - try { - battery[k] = "__magic__"; - } catch (e) { - // We are testing that we cannot set battery to new values - // when "use strict" is enabled, this throws a TypeError - if (e.name != "TypeError") - throw e; - } - is(battery[k], backup, "Setting battery " + k + " preference without spoofing enabled should fail"); - } - - imported.Debugging.fake = true; - - // reload again to get the fake one - GetBattery().then(function (battery) { - battery.charging = true; - battery.chargingTime = 100; - battery.level = 0.5; - ok(battery.charging, "Test for charging setter"); - is(battery.chargingTime, 100, "Test for chargingTime setter"); - is(battery.level, 0.5, "Test for level setter"); - - battery.charging = false; - battery.dischargingTime = 50; - battery.level = 0.7; - ok(!battery.charging, "Test for charging setter"); - is(battery.dischargingTime, 50, "Test for dischargingTime setter"); - is(battery.level, 0.7, "Test for level setter"); - - // Resetting the value to make the test run successful - // for multiple runs in same browser session. - imported.Debugging.fake = false; - finish(); - }); - }); -} diff --git a/toolkit/modules/tests/browser/browser_Deprecated.js b/toolkit/modules/tests/browser/browser_Deprecated.js deleted file mode 100644 index 3217bdd229..0000000000 --- a/toolkit/modules/tests/browser/browser_Deprecated.js +++ /dev/null @@ -1,157 +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/. */ - -var Ci = Components.interfaces; -var Cu = Components.utils; -const PREF_DEPRECATION_WARNINGS = "devtools.errorconsole.deprecation_warnings"; - -Cu.import("resource://gre/modules/Services.jsm", this); -Cu.import("resource://gre/modules/Deprecated.jsm", this); - -// Using this named functions to test deprecation and the properly logged -// callstacks. -function basicDeprecatedFunction () { - Deprecated.warning("this method is deprecated.", "http://example.com"); - return true; -} - -function deprecationFunctionBogusCallstack () { - Deprecated.warning("this method is deprecated.", "http://example.com", { - caller: {} - }); - return true; -} - -function deprecationFunctionCustomCallstack () { - // Get the nsIStackFrame that will contain the name of this function. - function getStack () { - return Components.stack; - } - Deprecated.warning("this method is deprecated.", "http://example.com", - getStack()); - return true; -} - -var tests = [ -// Test deprecation warning without passing the callstack. -{ - deprecatedFunction: basicDeprecatedFunction, - expectedObservation: function (aMessage) { - testAMessage(aMessage); - ok(aMessage.errorMessage.indexOf("basicDeprecatedFunction") > 0, - "Callstack is correctly logged."); - } -}, -// Test a reported error when URL to documentation is not passed. -{ - deprecatedFunction: function () { - Deprecated.warning("this method is deprecated."); - return true; - }, - expectedObservation: function (aMessage) { - ok(aMessage.errorMessage.indexOf("must provide a URL") > 0, - "Deprecation warning logged an empty URL argument."); - } -}, -// Test deprecation with a bogus callstack passed as an argument (it will be -// replaced with the current call stack). -{ - deprecatedFunction: deprecationFunctionBogusCallstack, - expectedObservation: function (aMessage) { - testAMessage(aMessage); - ok(aMessage.errorMessage.indexOf("deprecationFunctionBogusCallstack") > 0, - "Callstack is correctly logged."); - } -}, -// When pref is unset Deprecated.warning should not log anything. -{ - deprecatedFunction: basicDeprecatedFunction, - expectedObservation: null, - // Set pref to false. - logWarnings: false -}, -// Test deprecation with a valid custom callstack passed as an argument. -{ - deprecatedFunction: deprecationFunctionCustomCallstack, - expectedObservation: function (aMessage) { - testAMessage(aMessage); - ok(aMessage.errorMessage.indexOf("deprecationFunctionCustomCallstack") > 0, - "Callstack is correctly logged."); - }, - // Set pref to true. - logWarnings: true -}]; - -// Which test are we running now? -var idx = -1; - -function test() { - waitForExplicitFinish(); - - // Check if Deprecated is loaded. - ok(Deprecated, "Deprecated object exists"); - - nextTest(); -} - -// Test Consle Message attributes. -function testAMessage (aMessage) { - ok(aMessage.errorMessage.indexOf("DEPRECATION WARNING: " + - "this method is deprecated.") === 0, - "Deprecation is correctly logged."); - ok(aMessage.errorMessage.indexOf("http://example.com") > 0, - "URL is correctly logged."); -} - -function nextTest() { - idx++; - - if (idx == tests.length) { - finish(); - return; - } - - info("Running test #" + idx); - let test = tests[idx]; - - // Deprecation warnings will be logged only when the preference is set. - if (typeof test.logWarnings !== "undefined") { - Services.prefs.setBoolPref(PREF_DEPRECATION_WARNINGS, test.logWarnings); - } - - // Create a console listener. - let consoleListener = { - observe: function (aMessage) { - // Ignore unexpected messages. - if (!(aMessage instanceof Ci.nsIScriptError)) { - return; - } - if (aMessage.errorMessage.indexOf("DEPRECATION WARNING: ") < 0 && - aMessage.errorMessage.indexOf("must provide a URL") < 0) { - return; - } - ok(aMessage instanceof Ci.nsIScriptError, - "Deprecation log message is an instance of type nsIScriptError."); - - - if (test.expectedObservation === null) { - ok(false, "Deprecated warning not expected"); - } - else { - test.expectedObservation(aMessage); - } - - Services.console.unregisterListener(consoleListener); - executeSoon(nextTest); - } - }; - Services.console.registerListener(consoleListener); - test.deprecatedFunction(); - if (test.expectedObservation === null) { - executeSoon(function() { - Services.console.unregisterListener(consoleListener); - executeSoon(nextTest); - }); - } -} diff --git a/toolkit/modules/tests/browser/browser_Finder.js b/toolkit/modules/tests/browser/browser_Finder.js deleted file mode 100644 index 4dfd921d0e..0000000000 --- a/toolkit/modules/tests/browser/browser_Finder.js +++ /dev/null @@ -1,62 +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/. */ - -var Ci = Components.interfaces; - -add_task(function* () { - const url = "data:text/html;base64," + - btoa("<body><iframe srcdoc=\"content\"/></iframe>" + - "<a href=\"http://test.com\">test link</a>"); - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, url); - - let finder = tab.linkedBrowser.finder; - let listener = { - onFindResult: function () { - ok(false, "onFindResult callback wasn't replaced"); - }, - onHighlightFinished: function () { - ok(false, "onHighlightFinished callback wasn't replaced"); - } - }; - finder.addResultListener(listener); - - function waitForFind(which = "onFindResult") { - return new Promise(resolve => { - listener[which] = resolve; - }) - } - - let promiseFind = waitForFind("onHighlightFinished"); - finder.highlight(true, "content"); - let findResult = yield promiseFind; - Assert.ok(findResult.found, "should find string"); - - promiseFind = waitForFind("onHighlightFinished"); - finder.highlight(true, "Bla"); - findResult = yield promiseFind; - Assert.ok(!findResult.found, "should not find string"); - - // Search only for links and draw outlines. - promiseFind = waitForFind(); - finder.fastFind("test link", true, true); - findResult = yield promiseFind; - is(findResult.result, Ci.nsITypeAheadFind.FIND_FOUND, "should find link"); - - yield ContentTask.spawn(tab.linkedBrowser, {}, function* (arg) { - Assert.ok(!!content.document.getElementsByTagName("a")[0].style.outline, "outline set"); - }); - - // Just a simple search for "test link". - promiseFind = waitForFind(); - finder.fastFind("test link", false, false); - findResult = yield promiseFind; - is(findResult.result, Ci.nsITypeAheadFind.FIND_FOUND, "should find link again"); - - yield ContentTask.spawn(tab.linkedBrowser, {}, function* (arg) { - Assert.ok(!content.document.getElementsByTagName("a")[0].style.outline, "outline not set"); - }); - - finder.removeResultListener(listener); - gBrowser.removeTab(tab); -}); diff --git a/toolkit/modules/tests/browser/browser_FinderHighlighter.js b/toolkit/modules/tests/browser/browser_FinderHighlighter.js deleted file mode 100644 index cd7eefa115..0000000000 --- a/toolkit/modules/tests/browser/browser_FinderHighlighter.js +++ /dev/null @@ -1,460 +0,0 @@ -"use strict"; - -Cu.import("resource://testing-common/BrowserTestUtils.jsm", this); -Cu.import("resource://testing-common/ContentTask.jsm", this); -Cu.import("resource://gre/modules/Promise.jsm", this); -Cu.import("resource://gre/modules/Services.jsm", this); -Cu.import("resource://gre/modules/Task.jsm", this); -Cu.import("resource://gre/modules/Timer.jsm", this); -Cu.import("resource://gre/modules/AppConstants.jsm"); - -const kHighlightAllPref = "findbar.highlightAll"; -const kPrefModalHighlight = "findbar.modalHighlight"; -const kFixtureBaseURL = "https://example.com/browser/toolkit/modules/tests/browser/"; -const kIteratorTimeout = Services.prefs.getIntPref("findbar.iteratorTimeout"); - -function promiseOpenFindbar(findbar) { - findbar.onFindCommand() - return gFindBar._startFindDeferred && gFindBar._startFindDeferred.promise; -} - -function promiseFindResult(findbar, str = null) { - let highlightFinished = false; - let findFinished = false; - return new Promise(resolve => { - let listener = { - onFindResult({ searchString }) { - if (str !== null && str != searchString) { - return; - } - findFinished = true; - if (highlightFinished) { - findbar.browser.finder.removeResultListener(listener); - resolve(); - } - }, - onHighlightFinished() { - highlightFinished = true; - if (findFinished) { - findbar.browser.finder.removeResultListener(listener); - resolve(); - } - }, - onMatchesCountResult: () => {} - }; - findbar.browser.finder.addResultListener(listener); - }); -} - -function promiseEnterStringIntoFindField(findbar, str) { - let promise = promiseFindResult(findbar, str); - for (let i = 0; i < str.length; i++) { - let event = document.createEvent("KeyboardEvent"); - event.initKeyEvent("keypress", true, true, null, false, false, - false, false, 0, str.charCodeAt(i)); - findbar._findField.inputField.dispatchEvent(event); - } - return promise; -} - -function promiseTestHighlighterOutput(browser, word, expectedResult, extraTest = () => {}) { - return ContentTask.spawn(browser, { word, expectedResult, extraTest: extraTest.toSource() }, - function* ({ word, expectedResult, extraTest }) { - Cu.import("resource://gre/modules/Timer.jsm", this); - - return new Promise((resolve, reject) => { - let stubbed = {}; - let callCounts = { - insertCalls: [], - removeCalls: [] - }; - let lastMaskNode, lastOutlineNode; - let rects = []; - - // Amount of milliseconds to wait after the last time one of our stubs - // was called. - const kTimeoutMs = 1000; - // The initial timeout may wait for a while for results to come in. - let timeout = setTimeout(() => finish(false, "Timeout"), kTimeoutMs * 5); - - function finish(ok = true, message = "finished with error") { - // Restore the functions we stubbed out. - try { - content.document.insertAnonymousContent = stubbed.insert; - content.document.removeAnonymousContent = stubbed.remove; - } catch (ex) {} - stubbed = {}; - clearTimeout(timeout); - - if (expectedResult.rectCount !== 0) - Assert.ok(ok, message); - - Assert.greaterOrEqual(callCounts.insertCalls.length, expectedResult.insertCalls[0], - `Min. insert calls should match for '${word}'.`); - Assert.lessOrEqual(callCounts.insertCalls.length, expectedResult.insertCalls[1], - `Max. insert calls should match for '${word}'.`); - Assert.greaterOrEqual(callCounts.removeCalls.length, expectedResult.removeCalls[0], - `Min. remove calls should match for '${word}'.`); - Assert.lessOrEqual(callCounts.removeCalls.length, expectedResult.removeCalls[1], - `Max. remove calls should match for '${word}'.`); - - // We reached the amount of calls we expected, so now we can check - // the amount of rects. - if (!lastMaskNode && expectedResult.rectCount !== 0) { - Assert.ok(false, `No mask node found, but expected ${expectedResult.rectCount} rects.`); - } - - Assert.equal(rects.length, expectedResult.rectCount, - `Amount of inserted rects should match for '${word}'.`); - - // Allow more specific assertions to be tested in `extraTest`. - extraTest = eval(extraTest); - extraTest(lastMaskNode, lastOutlineNode, rects); - - resolve(); - } - - function stubAnonymousContentNode(domNode, anonNode) { - let originals = [anonNode.setTextContentForElement, - anonNode.setAttributeForElement, anonNode.removeAttributeForElement, - anonNode.setCutoutRectsForElement]; - anonNode.setTextContentForElement = (id, text) => { - try { - (domNode.querySelector("#" + id) || domNode).textContent = text; - } catch (ex) {} - return originals[0].call(anonNode, id, text); - }; - anonNode.setAttributeForElement = (id, attrName, attrValue) => { - try { - (domNode.querySelector("#" + id) || domNode).setAttribute(attrName, attrValue); - } catch (ex) {} - return originals[1].call(anonNode, id, attrName, attrValue); - }; - anonNode.removeAttributeForElement = (id, attrName) => { - try { - let node = domNode.querySelector("#" + id) || domNode; - if (node.hasAttribute(attrName)) - node.removeAttribute(attrName); - } catch (ex) {} - return originals[2].call(anonNode, id, attrName); - }; - anonNode.setCutoutRectsForElement = (id, cutoutRects) => { - rects = cutoutRects; - return originals[3].call(anonNode, id, cutoutRects); - }; - } - - // Create a function that will stub the original version and collects - // the arguments so we can check the results later. - function stub(which) { - stubbed[which] = content.document[which + "AnonymousContent"]; - let prop = which + "Calls"; - return function(node) { - callCounts[prop].push(node); - if (which == "insert") { - if (node.outerHTML.indexOf("outlineMask") > -1) - lastMaskNode = node; - else - lastOutlineNode = node; - } - clearTimeout(timeout); - timeout = setTimeout(() => { - finish(); - }, kTimeoutMs); - let res = stubbed[which].call(content.document, node); - if (which == "insert") - stubAnonymousContentNode(node, res); - return res; - }; - } - content.document.insertAnonymousContent = stub("insert"); - content.document.removeAnonymousContent = stub("remove"); - }); - }); -} - -add_task(function* setup() { - yield SpecialPowers.pushPrefEnv({ set: [ - [kHighlightAllPref, true], - [kPrefModalHighlight, true] - ]}); -}); - -// Test the results of modal highlighting, which is on by default. -add_task(function* testModalResults() { - let tests = new Map([ - ["Roland", { - rectCount: 2, - insertCalls: [2, 4], - removeCalls: [0, 1] - }], - ["their law might propagate their kind", { - rectCount: 2, - insertCalls: [5, 6], - removeCalls: [4, 5], - extraTest: function(maskNode, outlineNode, rects) { - Assert.equal(outlineNode.getElementsByTagName("div").length, 2, - "There should be multiple rects drawn"); - } - }], - ["ro", { - rectCount: 41, - insertCalls: [1, 4], - removeCalls: [1, 3] - }], - ["new", { - rectCount: 2, - insertCalls: [1, 4], - removeCalls: [0, 2] - }], - ["o", { - rectCount: 492, - insertCalls: [1, 4], - removeCalls: [0, 2] - }] - ]); - let url = kFixtureBaseURL + "file_FinderSample.html"; - yield BrowserTestUtils.withNewTab(url, function* (browser) { - let findbar = gBrowser.getFindBar(); - - for (let [word, expectedResult] of tests) { - yield promiseOpenFindbar(findbar); - Assert.ok(!findbar.hidden, "Findbar should be open now."); - - let timeout = kIteratorTimeout; - if (word.length == 1) - timeout *= 4; - else if (word.length == 2) - timeout *= 2; - yield new Promise(resolve => setTimeout(resolve, timeout)); - let promise = promiseTestHighlighterOutput(browser, word, expectedResult, - expectedResult.extraTest); - yield promiseEnterStringIntoFindField(findbar, word); - yield promise; - - findbar.close(true); - } - }); -}); - -// Test if runtime switching of highlight modes between modal and non-modal works -// as expected. -add_task(function* testModalSwitching() { - let url = kFixtureBaseURL + "file_FinderSample.html"; - yield BrowserTestUtils.withNewTab(url, function* (browser) { - let findbar = gBrowser.getFindBar(); - - yield promiseOpenFindbar(findbar); - Assert.ok(!findbar.hidden, "Findbar should be open now."); - - let word = "Roland"; - let expectedResult = { - rectCount: 2, - insertCalls: [2, 4], - removeCalls: [0, 1] - }; - let promise = promiseTestHighlighterOutput(browser, word, expectedResult); - yield promiseEnterStringIntoFindField(findbar, word); - yield promise; - - yield SpecialPowers.pushPrefEnv({ "set": [[ kPrefModalHighlight, false ]] }); - - expectedResult = { - rectCount: 0, - insertCalls: [0, 0], - removeCalls: [0, 0] - }; - promise = promiseTestHighlighterOutput(browser, word, expectedResult); - findbar.clear(); - yield promiseEnterStringIntoFindField(findbar, word); - yield promise; - - findbar.close(true); - }); - - yield SpecialPowers.pushPrefEnv({ "set": [[ kPrefModalHighlight, true ]] }); -}); - -// Test if highlighting a dark page is detected properly. -add_task(function* testDarkPageDetection() { - let url = kFixtureBaseURL + "file_FinderSample.html"; - yield BrowserTestUtils.withNewTab(url, function* (browser) { - let findbar = gBrowser.getFindBar(); - - yield promiseOpenFindbar(findbar); - - let word = "Roland"; - let expectedResult = { - rectCount: 2, - insertCalls: [1, 3], - removeCalls: [0, 1] - }; - let promise = promiseTestHighlighterOutput(browser, word, expectedResult, function(node) { - Assert.ok(node.style.background.startsWith("rgba(0, 0, 0"), - "White HTML page should have a black background color set for the mask"); - }); - yield promiseEnterStringIntoFindField(findbar, word); - yield promise; - - findbar.close(true); - }); - - yield BrowserTestUtils.withNewTab(url, function* (browser) { - let findbar = gBrowser.getFindBar(); - - yield promiseOpenFindbar(findbar); - - let word = "Roland"; - let expectedResult = { - rectCount: 2, - insertCalls: [2, 4], - removeCalls: [0, 1] - }; - - yield ContentTask.spawn(browser, null, function* () { - let dwu = content.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils); - let uri = "data:text/css;charset=utf-8," + encodeURIComponent(` - body { - background: maroon radial-gradient(circle, #a01010 0%, #800000 80%) center center / cover no-repeat; - color: white; - }`); - try { - dwu.loadSheetUsingURIString(uri, dwu.USER_SHEET); - } catch (e) {} - }); - - let promise = promiseTestHighlighterOutput(browser, word, expectedResult, node => { - Assert.ok(node.style.background.startsWith("rgba(255, 255, 255"), - "Dark HTML page should have a white background color set for the mask"); - }); - yield promiseEnterStringIntoFindField(findbar, word); - yield promise; - - findbar.close(true); - }); -}); - -add_task(function* testHighlightAllToggle() { - let url = kFixtureBaseURL + "file_FinderSample.html"; - yield BrowserTestUtils.withNewTab(url, function* (browser) { - let findbar = gBrowser.getFindBar(); - - yield promiseOpenFindbar(findbar); - - let word = "Roland"; - let expectedResult = { - rectCount: 2, - insertCalls: [2, 4], - removeCalls: [0, 1] - }; - let promise = promiseTestHighlighterOutput(browser, word, expectedResult); - yield promiseEnterStringIntoFindField(findbar, word); - yield promise; - - // We now know we have multiple rectangles highlighted, so it's a good time - // to flip the pref. - expectedResult = { - rectCount: 0, - insertCalls: [0, 1], - removeCalls: [0, 1] - }; - promise = promiseTestHighlighterOutput(browser, word, expectedResult); - yield SpecialPowers.pushPrefEnv({ "set": [[ kHighlightAllPref, false ]] }); - yield promise; - - // For posterity, let's switch back. - expectedResult = { - rectCount: 2, - insertCalls: [1, 3], - removeCalls: [0, 1] - }; - promise = promiseTestHighlighterOutput(browser, word, expectedResult); - yield SpecialPowers.pushPrefEnv({ "set": [[ kHighlightAllPref, true ]] }); - yield promise; - }); -}); - -add_task(function* testXMLDocument() { - let url = "data:text/xml;charset=utf-8," + encodeURIComponent(`<?xml version="1.0"?> -<result> - <Title>Example</Title> - <Error>Error</Error> -</result>`); - yield BrowserTestUtils.withNewTab(url, function* (browser) { - let findbar = gBrowser.getFindBar(); - - yield promiseOpenFindbar(findbar); - - let word = "Example"; - let expectedResult = { - rectCount: 0, - insertCalls: [1, 4], - removeCalls: [0, 1] - }; - let promise = promiseTestHighlighterOutput(browser, word, expectedResult); - yield promiseEnterStringIntoFindField(findbar, word); - yield promise; - - findbar.close(true); - }); -}); - -add_task(function* testHideOnLocationChange() { - let url = kFixtureBaseURL + "file_FinderSample.html"; - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, url); - let browser = tab.linkedBrowser; - let findbar = gBrowser.getFindBar(); - - yield promiseOpenFindbar(findbar); - - let word = "Roland"; - let expectedResult = { - rectCount: 2, - insertCalls: [2, 4], - removeCalls: [0, 1] - }; - let promise = promiseTestHighlighterOutput(browser, word, expectedResult); - yield promiseEnterStringIntoFindField(findbar, word); - yield promise; - - // Now we try to navigate away! (Using the same page) - promise = promiseTestHighlighterOutput(browser, word, { - rectCount: 0, - insertCalls: [0, 0], - removeCalls: [1, 2] - }); - yield BrowserTestUtils.loadURI(browser, url); - yield promise; - - yield BrowserTestUtils.removeTab(tab); -}); - -add_task(function* testHideOnClear() { - let url = kFixtureBaseURL + "file_FinderSample.html"; - yield BrowserTestUtils.withNewTab(url, function* (browser) { - let findbar = gBrowser.getFindBar(); - yield promiseOpenFindbar(findbar); - - let word = "Roland"; - let expectedResult = { - rectCount: 2, - insertCalls: [2, 4], - removeCalls: [0, 2] - }; - let promise = promiseTestHighlighterOutput(browser, word, expectedResult); - yield promiseEnterStringIntoFindField(findbar, word); - yield promise; - - yield new Promise(resolve => setTimeout(resolve, kIteratorTimeout)); - promise = promiseTestHighlighterOutput(browser, "", { - rectCount: 0, - insertCalls: [0, 0], - removeCalls: [1, 2] - }); - findbar.clear(); - yield promise; - - findbar.close(true); - }); -}); diff --git a/toolkit/modules/tests/browser/browser_Finder_hidden_textarea.js b/toolkit/modules/tests/browser/browser_Finder_hidden_textarea.js deleted file mode 100644 index 99d838adaf..0000000000 --- a/toolkit/modules/tests/browser/browser_Finder_hidden_textarea.js +++ /dev/null @@ -1,52 +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/. */ -add_task(function* test_bug1174036() { - const URI = - "<body><textarea>e1</textarea><textarea>e2</textarea><textarea>e3</textarea></body>"; - yield BrowserTestUtils.withNewTab({ gBrowser, url: "data:text/html;charset=utf-8," + encodeURIComponent(URI) }, - function* (browser) { - // Hide the first textarea. - yield ContentTask.spawn(browser, null, function() { - content.document.getElementsByTagName("textarea")[0].style.display = "none"; - }); - - let finder = browser.finder; - let listener = { - onFindResult: function () { - ok(false, "callback wasn't replaced"); - } - }; - finder.addResultListener(listener); - - function waitForFind() { - return new Promise(resolve => { - listener.onFindResult = resolve; - }) - } - - // Find the first 'e' (which should be in the second textarea). - let promiseFind = waitForFind(); - finder.fastFind("e", false, false); - let findResult = yield promiseFind; - is(findResult.result, Ci.nsITypeAheadFind.FIND_FOUND, "find first string"); - - let firstRect = findResult.rect; - - // Find the second 'e' (in the third textarea). - promiseFind = waitForFind(); - finder.findAgain(false, false, false); - findResult = yield promiseFind; - is(findResult.result, Ci.nsITypeAheadFind.FIND_FOUND, "find second string"); - ok(!findResult.rect.equals(firstRect), "found new string"); - - // Ensure that we properly wrap to the second textarea. - promiseFind = waitForFind(); - finder.findAgain(false, false, false); - findResult = yield promiseFind; - is(findResult.result, Ci.nsITypeAheadFind.FIND_WRAPPED, "wrapped to first string"); - ok(findResult.rect.equals(firstRect), "wrapped to original string"); - - finder.removeResultListener(listener); - }); -}); diff --git a/toolkit/modules/tests/browser/browser_Geometry.js b/toolkit/modules/tests/browser/browser_Geometry.js deleted file mode 100644 index aaca79a06b..0000000000 --- a/toolkit/modules/tests/browser/browser_Geometry.js +++ /dev/null @@ -1,111 +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/. */ - -var tempScope = {}; -Components.utils.import("resource://gre/modules/Geometry.jsm", tempScope); -var Point = tempScope.Point; -var Rect = tempScope.Rect; - -function test() { - ok(Rect, "Rect class exists"); - for (var fname in tests) { - tests[fname](); - } -} - -var tests = { - testGetDimensions: function() { - let r = new Rect(5, 10, 100, 50); - ok(r.left == 5, "rect has correct left value"); - ok(r.top == 10, "rect has correct top value"); - ok(r.right == 105, "rect has correct right value"); - ok(r.bottom == 60, "rect has correct bottom value"); - ok(r.width == 100, "rect has correct width value"); - ok(r.height == 50, "rect has correct height value"); - ok(r.x == 5, "rect has correct x value"); - ok(r.y == 10, "rect has correct y value"); - }, - - testIsEmpty: function() { - let r = new Rect(0, 0, 0, 10); - ok(r.isEmpty(), "rect with nonpositive width is empty"); - r = new Rect(0, 0, 10, 0); - ok(r.isEmpty(), "rect with nonpositive height is empty"); - r = new Rect(0, 0, 10, 10); - ok(!r.isEmpty(), "rect with positive dimensions is not empty"); - }, - - testRestrictTo: function() { - let r1 = new Rect(10, 10, 100, 100); - let r2 = new Rect(50, 50, 100, 100); - r1.restrictTo(r2); - ok(r1.equals(new Rect(50, 50, 60, 60)), "intersection is non-empty"); - - r1 = new Rect(10, 10, 100, 100); - r2 = new Rect(120, 120, 100, 100); - r1.restrictTo(r2); - ok(r1.isEmpty(), "intersection is empty"); - - r1 = new Rect(10, 10, 100, 100); - r2 = new Rect(0, 0, 0, 0); - r1.restrictTo(r2); - ok(r1.isEmpty(), "intersection of rect and empty is empty"); - - r1 = new Rect(0, 0, 0, 0); - r2 = new Rect(0, 0, 0, 0); - r1.restrictTo(r2); - ok(r1.isEmpty(), "intersection of empty and empty is empty"); - }, - - testExpandToContain: function() { - let r1 = new Rect(10, 10, 100, 100); - let r2 = new Rect(50, 50, 100, 100); - r1.expandToContain(r2); - ok(r1.equals(new Rect(10, 10, 140, 140)), "correct expandToContain on intersecting rectangles"); - - r1 = new Rect(10, 10, 100, 100); - r2 = new Rect(120, 120, 100, 100); - r1.expandToContain(r2); - ok(r1.equals(new Rect(10, 10, 210, 210)), "correct expandToContain on non-intersecting rectangles"); - - r1 = new Rect(10, 10, 100, 100); - r2 = new Rect(0, 0, 0, 0); - r1.expandToContain(r2); - ok(r1.equals(new Rect(10, 10, 100, 100)), "expandToContain of rect and empty is rect"); - - r1 = new Rect(10, 10, 0, 0); - r2 = new Rect(0, 0, 0, 0); - r1.expandToContain(r2); - ok(r1.isEmpty(), "expandToContain of empty and empty is empty"); - }, - - testSubtract: function testSubtract() { - function equals(rects1, rects2) { - return rects1.length == rects2.length && rects1.every(function(r, i) { - return r.equals(rects2[i]); - }); - } - - let r1 = new Rect(0, 0, 100, 100); - let r2 = new Rect(500, 500, 100, 100); - ok(equals(r1.subtract(r2), [r1]), "subtract area outside of region yields same region"); - - r1 = new Rect(0, 0, 100, 100); - r2 = new Rect(-10, -10, 50, 120); - ok(equals(r1.subtract(r2), [new Rect(40, 0, 60, 100)]), "subtracting vertical bar from edge leaves one rect"); - - r1 = new Rect(0, 0, 100, 100); - r2 = new Rect(-10, -10, 120, 50); - ok(equals(r1.subtract(r2), [new Rect(0, 40, 100, 60)]), "subtracting horizontal bar from edge leaves one rect"); - - r1 = new Rect(0, 0, 100, 100); - r2 = new Rect(40, 40, 20, 20); - ok(equals(r1.subtract(r2), [ - new Rect(0, 0, 40, 100), - new Rect(40, 0, 20, 40), - new Rect(40, 60, 20, 40), - new Rect(60, 0, 40, 100)]), - "subtracting rect in middle leaves union of rects"); - }, -}; diff --git a/toolkit/modules/tests/browser/browser_InlineSpellChecker.js b/toolkit/modules/tests/browser/browser_InlineSpellChecker.js deleted file mode 100644 index 2bffc97222..0000000000 --- a/toolkit/modules/tests/browser/browser_InlineSpellChecker.js +++ /dev/null @@ -1,121 +0,0 @@ -function test() { - let tempScope = {}; - Components.utils.import("resource://gre/modules/InlineSpellChecker.jsm", tempScope); - let InlineSpellChecker = tempScope.InlineSpellChecker; - - ok(InlineSpellChecker, "InlineSpellChecker class exists"); - for (var fname in tests) { - tests[fname](); - } -} - -var tests = { - // Test various possible dictionary name to ensure they display as expected. - // XXX: This only works for the 'en-US' locale, as the testing involves localized output. - testDictionaryDisplayNames: function() { - let isc = new InlineSpellChecker(); - - // Check non-well-formed language tag. - is(isc.getDictionaryDisplayName("-invalid-"), "-invalid-", "'-invalid-' should display as '-invalid-'"); - - // XXX: It isn't clear how we'd ideally want to display variant subtags. - - // Check valid language subtag. - is(isc.getDictionaryDisplayName("en"), "English", "'en' should display as 'English'"); - is(isc.getDictionaryDisplayName("en-fonipa"), "English (fonipa)", "'en-fonipa' should display as 'English (fonipa)'"); - is(isc.getDictionaryDisplayName("en-qxqaaaaz"), "English (qxqaaaaz)", "'en-qxqaaaaz' should display as 'English (qxqaaaaz)'"); - - // Check valid language subtag and valid region subtag. - is(isc.getDictionaryDisplayName("en-US"), "English (United States)", "'en-US' should display as 'English (United States)'"); - is(isc.getDictionaryDisplayName("en-US-fonipa"), "English (United States) (fonipa)", "'en-US-fonipa' should display as 'English (United States) (fonipa)'"); - is(isc.getDictionaryDisplayName("en-US-qxqaaaaz"), "English (United States) (qxqaaaaz)", "'en-US-qxqaaaaz' should display as 'English (United States) (qxqaaaaz)'"); - - // Check valid language subtag and invalid but well-formed region subtag. - is(isc.getDictionaryDisplayName("en-WO"), "English (WO)", "'en-WO' should display as 'English (WO)'"); - is(isc.getDictionaryDisplayName("en-WO-fonipa"), "English (WO) (fonipa)", "'en-WO-fonipa' should display as 'English (WO) (fonipa)'"); - is(isc.getDictionaryDisplayName("en-WO-qxqaaaaz"), "English (WO) (qxqaaaaz)", "'en-WO-qxqaaaaz' should display as 'English (WO) (qxqaaaaz)'"); - - // Check valid language subtag and valid script subtag. - todo_is(isc.getDictionaryDisplayName("en-Cyrl"), "English / Cyrillic", "'en-Cyrl' should display as 'English / Cyrillic'"); - todo_is(isc.getDictionaryDisplayName("en-Cyrl-fonipa"), "English / Cyrillic (fonipa)", "'en-Cyrl-fonipa' should display as 'English / Cyrillic (fonipa)'"); - todo_is(isc.getDictionaryDisplayName("en-Cyrl-qxqaaaaz"), "English / Cyrillic (qxqaaaaz)", "'en-Cyrl-qxqaaaaz' should display as 'English / Cyrillic (qxqaaaaz)'"); - todo_is(isc.getDictionaryDisplayName("en-Cyrl-US"), "English (United States) / Cyrillic", "'en-Cyrl-US' should display as 'English (United States) / Cyrillic'"); - todo_is(isc.getDictionaryDisplayName("en-Cyrl-US-fonipa"), "English (United States) / Cyrillic (fonipa)", "'en-Cyrl-US-fonipa' should display as 'English (United States) / Cyrillic (fonipa)'"); - todo_is(isc.getDictionaryDisplayName("en-Cyrl-US-qxqaaaaz"), "English (United States) / Cyrillic (qxqaaaaz)", "'en-Cyrl-US-qxqaaaaz' should display as 'English (United States) / Cyrillic (qxqaaaaz)'"); - todo_is(isc.getDictionaryDisplayName("en-Cyrl-WO"), "English (WO) / Cyrillic", "'en-Cyrl-WO' should display as 'English (WO) / Cyrillic'"); - todo_is(isc.getDictionaryDisplayName("en-Cyrl-WO-fonipa"), "English (WO) / Cyrillic (fonipa)", "'en-Cyrl-WO-fonipa' should display as 'English (WO) / Cyrillic (fonipa)'"); - todo_is(isc.getDictionaryDisplayName("en-Cyrl-WO-qxqaaaaz"), "English (WO) / Cyrillic (qxqaaaaz)", "'en-Cyrl-WO-qxqaaaaz' should display as 'English (WO) / Cyrillic (qxqaaaaz)'"); - - // Check valid language subtag and invalid but well-formed script subtag. - is(isc.getDictionaryDisplayName("en-Qaaz"), "English / Qaaz", "'en-Qaaz' should display as 'English / Qaaz'"); - is(isc.getDictionaryDisplayName("en-Qaaz-fonipa"), "English / Qaaz (fonipa)", "'en-Qaaz-fonipa' should display as 'English / Qaaz (fonipa)'"); - is(isc.getDictionaryDisplayName("en-Qaaz-qxqaaaaz"), "English / Qaaz (qxqaaaaz)", "'en-Qaaz-qxqaaaaz' should display as 'English / Qaaz (qxqaaaaz)'"); - is(isc.getDictionaryDisplayName("en-Qaaz-US"), "English (United States) / Qaaz", "'en-Qaaz-US' should display as 'English (United States) / Qaaz'"); - is(isc.getDictionaryDisplayName("en-Qaaz-US-fonipa"), "English (United States) / Qaaz (fonipa)", "'en-Qaaz-US-fonipa' should display as 'English (United States) / Qaaz (fonipa)'"); - is(isc.getDictionaryDisplayName("en-Qaaz-US-qxqaaaaz"), "English (United States) / Qaaz (qxqaaaaz)", "'en-Qaaz-US-qxqaaaaz' should display as 'English (United States) / Qaaz (qxqaaaaz)'"); - is(isc.getDictionaryDisplayName("en-Qaaz-WO"), "English (WO) / Qaaz", "'en-Qaaz-WO' should display as 'English (WO) / Qaaz'"); - is(isc.getDictionaryDisplayName("en-Qaaz-WO-fonipa"), "English (WO) / Qaaz (fonipa)", "'en-Qaaz-WO-fonipa' should display as 'English (WO) / Qaaz (fonipa)'"); - is(isc.getDictionaryDisplayName("en-Qaaz-WO-qxqaaaaz"), "English (WO) / Qaaz (qxqaaaaz)", "'en-Qaaz-WO-qxqaaaaz' should display as 'English (WO) / Qaaz (qxqaaaaz)'"); - - // Check invalid but well-formed language subtag. - is(isc.getDictionaryDisplayName("qaz"), "qaz", "'qaz' should display as 'qaz'"); - is(isc.getDictionaryDisplayName("qaz-fonipa"), "qaz (fonipa)", "'qaz-fonipa' should display as 'qaz (fonipa)'"); - is(isc.getDictionaryDisplayName("qaz-qxqaaaaz"), "qaz (qxqaaaaz)", "'qaz-qxqaaaaz' should display as 'qaz (qxqaaaaz)'"); - - // Check invalid but well-formed language subtag and valid region subtag. - is(isc.getDictionaryDisplayName("qaz-US"), "qaz (United States)", "'qaz-US' should display as 'qaz (United States)'"); - is(isc.getDictionaryDisplayName("qaz-US-fonipa"), "qaz (United States) (fonipa)", "'qaz-US-fonipa' should display as 'qaz (United States) (fonipa)'"); - is(isc.getDictionaryDisplayName("qaz-US-qxqaaaaz"), "qaz (United States) (qxqaaaaz)", "'qaz-US-qxqaaaaz' should display as 'qaz (United States) (qxqaaaaz)'"); - - // Check invalid but well-formed language subtag and invalid but well-formed region subtag. - is(isc.getDictionaryDisplayName("qaz-WO"), "qaz (WO)", "'qaz-WO' should display as 'qaz (WO)'"); - is(isc.getDictionaryDisplayName("qaz-WO-fonipa"), "qaz (WO) (fonipa)", "'qaz-WO-fonipa' should display as 'qaz (WO) (fonipa)'"); - is(isc.getDictionaryDisplayName("qaz-WO-qxqaaaaz"), "qaz (WO) (qxqaaaaz)", "'qaz-WO-qxqaaaaz' should display as 'qaz (WO) (qxqaaaaz)'"); - - // Check invalid but well-formed language subtag and valid script subtag. - todo_is(isc.getDictionaryDisplayName("qaz-Cyrl"), "qaz / Cyrillic", "'qaz-Cyrl' should display as 'qaz / Cyrillic'"); - todo_is(isc.getDictionaryDisplayName("qaz-Cyrl-fonipa"), "qaz / Cyrillic (fonipa)", "'qaz-Cyrl-fonipa' should display as 'qaz / Cyrillic (fonipa)'"); - todo_is(isc.getDictionaryDisplayName("qaz-Cyrl-qxqaaaaz"), "qaz / Cyrillic (qxqaaaaz)", "'qaz-Cyrl-qxqaaaaz' should display as 'qaz / Cyrillic (qxqaaaaz)'"); - todo_is(isc.getDictionaryDisplayName("qaz-Cyrl-US"), "qaz (United States) / Cyrillic", "'qaz-Cyrl-US' should display as 'qaz (United States) / Cyrillic'"); - todo_is(isc.getDictionaryDisplayName("qaz-Cyrl-US-fonipa"), "qaz (United States) / Cyrillic (fonipa)", "'qaz-Cyrl-US-fonipa' should display as 'qaz (United States) / Cyrillic (fonipa)'"); - todo_is(isc.getDictionaryDisplayName("qaz-Cyrl-US-qxqaaaaz"), "qaz (United States) / Cyrillic (qxqaaaaz)", "'qaz-Cyrl-US-qxqaaaaz' should display as 'qaz (United States) / Cyrillic (qxqaaaaz)'"); - todo_is(isc.getDictionaryDisplayName("qaz-Cyrl-WO"), "qaz (WO) / Cyrillic", "'qaz-Cyrl-WO' should display as 'qaz (WO) / Cyrillic'"); - todo_is(isc.getDictionaryDisplayName("qaz-Cyrl-WO-fonipa"), "qaz (WO) / Cyrillic (fonipa)", "'qaz-Cyrl-WO-fonipa' should display as 'qaz (WO) / Cyrillic (fonipa)'"); - todo_is(isc.getDictionaryDisplayName("qaz-Cyrl-WO-qxqaaaaz"), "qaz (WO) / Cyrillic (qxqaaaaz)", "'qaz-Cyrl-WO-qxqaaaaz' should display as 'qaz (WO) / Cyrillic (qxqaaaaz)'"); - - // Check invalid but well-formed language subtag and invalid but well-formed script subtag. - is(isc.getDictionaryDisplayName("qaz-Qaaz"), "qaz / Qaaz", "'qaz-Qaaz' should display as 'qaz / Qaaz'"); - is(isc.getDictionaryDisplayName("qaz-Qaaz-fonipa"), "qaz / Qaaz (fonipa)", "'qaz-Qaaz-fonipa' should display as 'qaz / Qaaz (fonipa)'"); - is(isc.getDictionaryDisplayName("qaz-Qaaz-qxqaaaaz"), "qaz / Qaaz (qxqaaaaz)", "'qaz-Qaaz-qxqaaaaz' should display as 'qaz / Qaaz (qxqaaaaz)'"); - is(isc.getDictionaryDisplayName("qaz-Qaaz-US"), "qaz (United States) / Qaaz", "'qaz-Qaaz-US' should display as 'qaz (United States) / Qaaz'"); - is(isc.getDictionaryDisplayName("qaz-Qaaz-US-fonipa"), "qaz (United States) / Qaaz (fonipa)", "'qaz-Qaaz-US-fonipa' should display as 'qaz (United States) / Qaaz (fonipa)'"); - is(isc.getDictionaryDisplayName("qaz-Qaaz-US-qxqaaaaz"), "qaz (United States) / Qaaz (qxqaaaaz)", "'qaz-Qaaz-US-qxqaaaaz' should display as 'qaz (United States) / Qaaz (qxqaaaaz)'"); - is(isc.getDictionaryDisplayName("qaz-Qaaz-WO"), "qaz (WO) / Qaaz", "'qaz-Qaaz-WO' should display as 'qaz (WO) / Qaaz'"); - is(isc.getDictionaryDisplayName("qaz-Qaaz-WO-fonipa"), "qaz (WO) / Qaaz (fonipa)", "'qaz-Qaaz-WO-fonipa' should display as 'qaz (WO) / Qaaz (fonipa)'"); - is(isc.getDictionaryDisplayName("qaz-Qaaz-WO-qxqaaaaz"), "qaz (WO) / Qaaz (qxqaaaaz)", "'qaz-Qaaz-WO-qxqaaaaz' should display as 'qaz (WO) / Qaaz (qxqaaaaz)'"); - - // Check multiple variant subtags. - todo_is(isc.getDictionaryDisplayName("en-Cyrl-US-fonipa-fonxsamp"), "English (United States) / Cyrillic (fonipa / fonxsamp)", "'en-Cyrl-US-fonipa-fonxsamp' should display as 'English (United States) / Cyrillic (fonipa / fonxsamp)'"); - todo_is(isc.getDictionaryDisplayName("en-Cyrl-US-fonipa-qxqaaaaz"), "English (United States) / Cyrillic (fonipa / qxqaaaaz)", "'en-Cyrl-US-fonipa-qxqaaaaz' should display as 'English (United States) / Cyrillic (fonipa / qxqaaaaz)'"); - todo_is(isc.getDictionaryDisplayName("en-Cyrl-US-fonipa-fonxsamp-qxqaaaaz"), "English (United States) / Cyrillic (fonipa / fonxsamp / qxqaaaaz)", "'en-Cyrl-US-fonipa-fonxsamp-qxqaaaaz' should display as 'English (United States) / Cyrillic (fonipa / fonxsamp / qxqaaaaz)'"); - is(isc.getDictionaryDisplayName("qaz-Qaaz-WO-fonipa-fonxsamp"), "qaz (WO) / Qaaz (fonipa / fonxsamp)", "'qaz-Qaaz-WO-fonipa-fonxsamp' should display as 'qaz (WO) / Qaaz (fonipa / fonxsamp)'"); - is(isc.getDictionaryDisplayName("qaz-Qaaz-WO-fonipa-qxqaaaaz"), "qaz (WO) / Qaaz (fonipa / qxqaaaaz)", "'qaz-Qaaz-WO-fonipa-qxqaaaaz' should display as 'qaz (WO) / Qaaz (fonipa / qxqaaaaz)'"); - is(isc.getDictionaryDisplayName("qaz-Qaaz-WO-fonipa-fonxsamp-qxqaaaaz"), "qaz (WO) / Qaaz (fonipa / fonxsamp / qxqaaaaz)", "'qaz-Qaaz-WO-fonipa-fonxsamp-qxqaaaaz' should display as 'qaz (WO) / Qaaz (fonipa / fonxsamp / qxqaaaaz)'"); - - // Check numeric region subtag. - todo_is(isc.getDictionaryDisplayName("es-419"), "Spanish (Latin America and the Caribbean)", "'es-419' should display as 'Spanish (Latin America and the Caribbean)'"); - - // Check that extension subtags are ignored. - todo_is(isc.getDictionaryDisplayName("en-Cyrl-t-en-latn-m0-ungegn-2007"), "English / Cyrillic", "'en-Cyrl-t-en-latn-m0-ungegn-2007' should display as 'English / Cyrillic'"); - - // Check that privateuse subtags are ignored. - is(isc.getDictionaryDisplayName("en-x-ignore"), "English", "'en-x-ignore' should display as 'English'"); - is(isc.getDictionaryDisplayName("en-x-ignore-this"), "English", "'en-x-ignore-this' should display as 'English'"); - is(isc.getDictionaryDisplayName("en-x-ignore-this-subtag"), "English", "'en-x-ignore-this-subtag' should display as 'English'"); - - // Check that both extension and privateuse subtags are ignored. - todo_is(isc.getDictionaryDisplayName("en-Cyrl-t-en-latn-m0-ungegn-2007-x-ignore-this-subtag"), "English / Cyrillic", "'en-Cyrl-t-en-latn-m0-ungegn-2007-x-ignore-this-subtag' should display as 'English / Cyrillic'"); - - // XXX: Check grandfathered tags. - }, -}; diff --git a/toolkit/modules/tests/browser/browser_PageMetadata.js b/toolkit/modules/tests/browser/browser_PageMetadata.js deleted file mode 100644 index ca6e183687..0000000000 --- a/toolkit/modules/tests/browser/browser_PageMetadata.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Tests PageMetadata.jsm, which extracts metadata and microdata from a - * document. - */ - -var {PageMetadata} = Cu.import("resource://gre/modules/PageMetadata.jsm", {}); - -var rootURL = "http://example.com/browser/toolkit/modules/tests/browser/"; - -function promiseDocument(fileName) { - let url = rootURL + fileName; - - return new Promise((resolve, reject) => { - let xhr = new XMLHttpRequest(); - xhr.onload = () => resolve(xhr.responseXML); - xhr.onerror = () => reject(new Error("Error loading document")); - xhr.open("GET", url); - xhr.responseType = "document"; - xhr.send(); - }); -} - -/** - * Load a simple document. - */ -add_task(function* simpleDoc() { - let fileName = "metadata_simple.html"; - info(`Loading a simple page, ${fileName}`); - - let doc = yield promiseDocument(fileName); - Assert.notEqual(doc, null, - "Should have a document to analyse"); - - let data = PageMetadata.getData(doc); - Assert.notEqual(data, null, - "Should have non-null result"); - Assert.equal(data.url, rootURL + fileName, - "Should have expected url property"); - Assert.equal(data.title, "Test Title", - "Should have expected title property"); - Assert.equal(data.description, "A very simple test page", - "Should have expected title property"); -}); - -add_task(function* titlesDoc() { - let fileName = "metadata_titles.html"; - info(`Loading titles page, ${fileName}`); - - let doc = yield promiseDocument(fileName); - Assert.notEqual(doc, null, - "Should have a document to analyse"); - - let data = PageMetadata.getData(doc); - Assert.notEqual(data, null, - "Should have non-null result"); - Assert.equal(data.title, "Test Titles", - "Should use the page title, not the open graph title"); -}); - -add_task(function* titlesFallbackDoc() { - let fileName = "metadata_titles_fallback.html"; - info(`Loading titles page, ${fileName}`); - - let doc = yield promiseDocument(fileName); - Assert.notEqual(doc, null, - "Should have a document to analyse"); - - let data = PageMetadata.getData(doc); - Assert.notEqual(data, null, - "Should have non-null result"); - Assert.equal(data.title, "Title", - "Should use the open graph title"); -}); diff --git a/toolkit/modules/tests/browser/browser_PromiseMessage.js b/toolkit/modules/tests/browser/browser_PromiseMessage.js deleted file mode 100644 index e967ac4c97..0000000000 --- a/toolkit/modules/tests/browser/browser_PromiseMessage.js +++ /dev/null @@ -1,38 +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/. */ -/* global Cu, BrowserTestUtils, is, ok, add_task, gBrowser */ -"use strict"; -Cu.import("resource://gre/modules/PromiseMessage.jsm", this); - - -const url = "http://example.org/tests/dom/manifest/test/resource.sjs"; - -/** - * Test basic API error conditions - */ -add_task(function* () { - yield BrowserTestUtils.withNewTab({gBrowser, url}, testPromiseMessageAPI) -}); - -function* testPromiseMessageAPI(aBrowser) { - // Reusing an existing message. - const msgKey = "DOM:WebManifest:hasManifestLink"; - const mm = aBrowser.messageManager; - const id = "this should not change"; - const foo = "neitherShouldThis"; - const data = {id, foo}; - - // This just returns false, and it doesn't matter for this test. - yield PromiseMessage.send(mm, msgKey, data); - - // Check that no new props were added - const props = Object.getOwnPropertyNames(data); - ok(props.length === 2, "There should only be 2 props"); - ok(props.includes("id"), "Has the id property"); - ok(props.includes("foo"), "Has the foo property"); - - // Check that the props didn't change. - is(data.id, id, "The id prop must not change."); - is(data.foo, foo, "The foo prop must not change."); -} diff --git a/toolkit/modules/tests/browser/browser_RemotePageManager.js b/toolkit/modules/tests/browser/browser_RemotePageManager.js deleted file mode 100644 index 774d330348..0000000000 --- a/toolkit/modules/tests/browser/browser_RemotePageManager.js +++ /dev/null @@ -1,400 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -const TEST_URL = "http://www.example.com/browser/toolkit/modules/tests/browser/testremotepagemanager.html"; - -var { RemotePages, RemotePageManager } = Cu.import("resource://gre/modules/RemotePageManager.jsm", {}); - -function failOnMessage(message) { - ok(false, "Should not have seen message " + message.name); -} - -function waitForMessage(port, message, expectedPort = port) { - return new Promise((resolve) => { - function listener(message) { - is(message.target, expectedPort, "Message should be from the right port."); - - port.removeMessageListener(listener); - resolve(message); - } - - port.addMessageListener(message, listener); - }); -} - -function waitForPort(url, createTab = true) { - return new Promise((resolve) => { - RemotePageManager.addRemotePageListener(url, (port) => { - RemotePageManager.removeRemotePageListener(url); - - waitForMessage(port, "RemotePage:Load").then(() => resolve(port)); - }); - - if (createTab) - gBrowser.selectedTab = gBrowser.addTab(url); - }); -} - -function waitForPage(pages) { - return new Promise((resolve) => { - function listener({ target }) { - pages.removeMessageListener("RemotePage:Init", listener); - - waitForMessage(target, "RemotePage:Load").then(() => resolve(target)); - } - - pages.addMessageListener("RemotePage:Init", listener); - gBrowser.selectedTab = gBrowser.addTab(TEST_URL); - }); -} - -function swapDocShells(browser1, browser2) { - // Swap frameLoaders. - browser1.swapDocShells(browser2); - - // Swap permanentKeys. - let tmp = browser1.permanentKey; - browser1.permanentKey = browser2.permanentKey; - browser2.permanentKey = tmp; -} - -// Test that opening a page creates a port, sends the load event and then -// navigating to a new page sends the unload event. Going back should create a -// new port -add_task(function* init_navigate() { - let port = yield waitForPort(TEST_URL); - is(port.browser, gBrowser.selectedBrowser, "Port is for the correct browser"); - - let loaded = new Promise(resolve => { - function listener() { - gBrowser.selectedBrowser.removeEventListener("load", listener, true); - resolve(); - } - gBrowser.selectedBrowser.addEventListener("load", listener, true); - gBrowser.loadURI("about:blank"); - }); - - yield waitForMessage(port, "RemotePage:Unload"); - - // Port should be destroyed now - try { - port.addMessageListener("Foo", failOnMessage); - ok(false, "Should have seen exception"); - } - catch (e) { - ok(true, "Should have seen exception"); - } - - try { - port.sendAsyncMessage("Foo"); - ok(false, "Should have seen exception"); - } - catch (e) { - ok(true, "Should have seen exception"); - } - - yield loaded; - - gBrowser.goBack(); - port = yield waitForPort(TEST_URL, false); - - port.sendAsyncMessage("Ping2"); - let message = yield waitForMessage(port, "Pong2"); - port.destroy(); - - gBrowser.removeCurrentTab(); -}); - -// Test that opening a page creates a port, sends the load event and then -// closing the tab sends the unload event -add_task(function* init_close() { - let port = yield waitForPort(TEST_URL); - is(port.browser, gBrowser.selectedBrowser, "Port is for the correct browser"); - - let unloadPromise = waitForMessage(port, "RemotePage:Unload"); - gBrowser.removeCurrentTab(); - yield unloadPromise; - - // Port should be destroyed now - try { - port.addMessageListener("Foo", failOnMessage); - ok(false, "Should have seen exception"); - } - catch (e) { - ok(true, "Should have seen exception"); - } - - try { - port.sendAsyncMessage("Foo"); - ok(false, "Should have seen exception"); - } - catch (e) { - ok(true, "Should have seen exception"); - } -}); - -// Tests that we can send messages to individual pages even when more than one -// is open -add_task(function* multiple_ports() { - let port1 = yield waitForPort(TEST_URL); - is(port1.browser, gBrowser.selectedBrowser, "Port is for the correct browser"); - - let port2 = yield waitForPort(TEST_URL); - is(port2.browser, gBrowser.selectedBrowser, "Port is for the correct browser"); - - port2.addMessageListener("Pong", failOnMessage); - port1.sendAsyncMessage("Ping", { str: "foobar", counter: 0 }); - let message = yield waitForMessage(port1, "Pong"); - port2.removeMessageListener("Pong", failOnMessage); - is(message.data.str, "foobar", "String should pass through"); - is(message.data.counter, 1, "Counter should be incremented"); - - port1.addMessageListener("Pong", failOnMessage); - port2.sendAsyncMessage("Ping", { str: "foobaz", counter: 5 }); - message = yield waitForMessage(port2, "Pong"); - port1.removeMessageListener("Pong", failOnMessage); - is(message.data.str, "foobaz", "String should pass through"); - is(message.data.counter, 6, "Counter should be incremented"); - - let unloadPromise = waitForMessage(port2, "RemotePage:Unload"); - gBrowser.removeTab(gBrowser.getTabForBrowser(port2.browser)); - yield unloadPromise; - - try { - port2.addMessageListener("Pong", failOnMessage); - ok(false, "Should not have been able to add a new message listener to a destroyed port."); - } - catch (e) { - ok(true, "Should not have been able to add a new message listener to a destroyed port."); - } - - port1.sendAsyncMessage("Ping", { str: "foobar", counter: 0 }); - message = yield waitForMessage(port1, "Pong"); - is(message.data.str, "foobar", "String should pass through"); - is(message.data.counter, 1, "Counter should be incremented"); - - unloadPromise = waitForMessage(port1, "RemotePage:Unload"); - gBrowser.removeTab(gBrowser.getTabForBrowser(port1.browser)); - yield unloadPromise; -}); - -// Tests that swapping browser docshells doesn't break the ports -add_task(function* browser_switch() { - let port1 = yield waitForPort(TEST_URL); - is(port1.browser, gBrowser.selectedBrowser, "Port is for the correct browser"); - let browser1 = gBrowser.selectedBrowser; - port1.sendAsyncMessage("SetCookie", { value: "om nom" }); - - let port2 = yield waitForPort(TEST_URL); - is(port2.browser, gBrowser.selectedBrowser, "Port is for the correct browser"); - let browser2 = gBrowser.selectedBrowser; - port2.sendAsyncMessage("SetCookie", { value: "om nom nom" }); - - port2.addMessageListener("Cookie", failOnMessage); - port1.sendAsyncMessage("GetCookie"); - let message = yield waitForMessage(port1, "Cookie"); - port2.removeMessageListener("Cookie", failOnMessage); - is(message.data.value, "om nom", "Should have the right cookie"); - - port1.addMessageListener("Cookie", failOnMessage); - port2.sendAsyncMessage("GetCookie", { str: "foobaz", counter: 5 }); - message = yield waitForMessage(port2, "Cookie"); - port1.removeMessageListener("Cookie", failOnMessage); - is(message.data.value, "om nom nom", "Should have the right cookie"); - - swapDocShells(browser1, browser2); - is(port1.browser, browser2, "Should have noticed the swap"); - is(port2.browser, browser1, "Should have noticed the swap"); - - // Cookies should have stayed the same - port2.addMessageListener("Cookie", failOnMessage); - port1.sendAsyncMessage("GetCookie"); - message = yield waitForMessage(port1, "Cookie"); - port2.removeMessageListener("Cookie", failOnMessage); - is(message.data.value, "om nom", "Should have the right cookie"); - - port1.addMessageListener("Cookie", failOnMessage); - port2.sendAsyncMessage("GetCookie", { str: "foobaz", counter: 5 }); - message = yield waitForMessage(port2, "Cookie"); - port1.removeMessageListener("Cookie", failOnMessage); - is(message.data.value, "om nom nom", "Should have the right cookie"); - - swapDocShells(browser1, browser2); - is(port1.browser, browser1, "Should have noticed the swap"); - is(port2.browser, browser2, "Should have noticed the swap"); - - // Cookies should have stayed the same - port2.addMessageListener("Cookie", failOnMessage); - port1.sendAsyncMessage("GetCookie"); - message = yield waitForMessage(port1, "Cookie"); - port2.removeMessageListener("Cookie", failOnMessage); - is(message.data.value, "om nom", "Should have the right cookie"); - - port1.addMessageListener("Cookie", failOnMessage); - port2.sendAsyncMessage("GetCookie", { str: "foobaz", counter: 5 }); - message = yield waitForMessage(port2, "Cookie"); - port1.removeMessageListener("Cookie", failOnMessage); - is(message.data.value, "om nom nom", "Should have the right cookie"); - - let unloadPromise = waitForMessage(port2, "RemotePage:Unload"); - gBrowser.removeTab(gBrowser.getTabForBrowser(browser2)); - yield unloadPromise; - - unloadPromise = waitForMessage(port1, "RemotePage:Unload"); - gBrowser.removeTab(gBrowser.getTabForBrowser(browser1)); - yield unloadPromise; -}); - -// Tests that removeMessageListener in chrome works -add_task(function* remove_chrome_listener() { - let port = yield waitForPort(TEST_URL); - is(port.browser, gBrowser.selectedBrowser, "Port is for the correct browser"); - - // This relies on messages sent arriving in the same order. Pong will be - // sent back before Pong2 so if removeMessageListener fails the test will fail - port.addMessageListener("Pong", failOnMessage); - port.removeMessageListener("Pong", failOnMessage); - port.sendAsyncMessage("Ping", { str: "remove_listener", counter: 27 }); - port.sendAsyncMessage("Ping2"); - yield waitForMessage(port, "Pong2"); - - let unloadPromise = waitForMessage(port, "RemotePage:Unload"); - gBrowser.removeCurrentTab(); - yield unloadPromise; -}); - -// Tests that removeMessageListener in content works -add_task(function* remove_content_listener() { - let port = yield waitForPort(TEST_URL); - is(port.browser, gBrowser.selectedBrowser, "Port is for the correct browser"); - - // This relies on messages sent arriving in the same order. Pong3 would be - // sent back before Pong2 so if removeMessageListener fails the test will fail - port.addMessageListener("Pong3", failOnMessage); - port.sendAsyncMessage("Ping3"); - port.sendAsyncMessage("Ping2"); - yield waitForMessage(port, "Pong2"); - - let unloadPromise = waitForMessage(port, "RemotePage:Unload"); - gBrowser.removeCurrentTab(); - yield unloadPromise; -}); - -// Test RemotePages works -add_task(function* remote_pages_basic() { - let pages = new RemotePages(TEST_URL); - let port = yield waitForPage(pages); - is(port.browser, gBrowser.selectedBrowser, "Port is for the correct browser"); - - // Listening to global messages should work - let unloadPromise = waitForMessage(pages, "RemotePage:Unload", port); - gBrowser.removeCurrentTab(); - yield unloadPromise; - - pages.destroy(); - - // RemotePages should be destroyed now - try { - pages.addMessageListener("Foo", failOnMessage); - ok(false, "Should have seen exception"); - } - catch (e) { - ok(true, "Should have seen exception"); - } - - try { - pages.sendAsyncMessage("Foo"); - ok(false, "Should have seen exception"); - } - catch (e) { - ok(true, "Should have seen exception"); - } -}); - -// Test sending messages to all remote pages works -add_task(function* remote_pages_multiple() { - let pages = new RemotePages(TEST_URL); - let port1 = yield waitForPage(pages); - let port2 = yield waitForPage(pages); - - let pongPorts = []; - yield new Promise((resolve) => { - function listener({ name, target, data }) { - is(name, "Pong", "Should have seen the right response."); - is(data.str, "remote_pages", "String should pass through"); - is(data.counter, 43, "Counter should be incremented"); - pongPorts.push(target); - if (pongPorts.length == 2) - resolve(); - } - - pages.addMessageListener("Pong", listener); - pages.sendAsyncMessage("Ping", { str: "remote_pages", counter: 42 }); - }); - - // We don't make any guarantees about which order messages are sent to known - // pages so the pongs could have come back in any order. - isnot(pongPorts[0], pongPorts[1], "Should have received pongs from different ports"); - ok(pongPorts.indexOf(port1) >= 0, "Should have seen a pong from port1"); - ok(pongPorts.indexOf(port2) >= 0, "Should have seen a pong from port2"); - - // After destroy we should see no messages - pages.addMessageListener("RemotePage:Unload", failOnMessage); - pages.destroy(); - - gBrowser.removeTab(gBrowser.getTabForBrowser(port1.browser)); - gBrowser.removeTab(gBrowser.getTabForBrowser(port2.browser)); -}); - -// Test sending various types of data across the boundary -add_task(function* send_data() { - let port = yield waitForPort(TEST_URL); - is(port.browser, gBrowser.selectedBrowser, "Port is for the correct browser"); - - let data = { - integer: 45, - real: 45.78, - str: "foobar", - array: [1, 2, 3, 5, 27] - }; - - port.sendAsyncMessage("SendData", data); - let message = yield waitForMessage(port, "ReceivedData"); - - ok(message.data.result, message.data.status); - - gBrowser.removeCurrentTab(); -}); - -// Test sending an object of data across the boundary -add_task(function* send_data2() { - let port = yield waitForPort(TEST_URL); - is(port.browser, gBrowser.selectedBrowser, "Port is for the correct browser"); - - let data = { - integer: 45, - real: 45.78, - str: "foobar", - array: [1, 2, 3, 5, 27] - }; - - port.sendAsyncMessage("SendData2", {data}); - let message = yield waitForMessage(port, "ReceivedData2"); - - ok(message.data.result, message.data.status); - - gBrowser.removeCurrentTab(); -}); - -add_task(function* get_ports_for_browser() { - let pages = new RemotePages(TEST_URL); - let port = yield waitForPage(pages); - // waitForPage creates a new tab and selects it by default, so - // the selected tab should be the one hosting this port. - let browser = gBrowser.selectedBrowser; - let foundPorts = pages.portsForBrowser(browser); - is(foundPorts.length, 1, "There should only be one port for this simple page"); - is(foundPorts[0], port, "Should find the port"); - gBrowser.removeCurrentTab(); -}); diff --git a/toolkit/modules/tests/browser/browser_Troubleshoot.js b/toolkit/modules/tests/browser/browser_Troubleshoot.js deleted file mode 100644 index ebc4de1f92..0000000000 --- a/toolkit/modules/tests/browser/browser_Troubleshoot.js +++ /dev/null @@ -1,559 +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/. */ - -// Ideally this would be an xpcshell test, but Troubleshoot relies on things -// that aren't initialized outside of a XUL app environment like AddonManager -// and the "@mozilla.org/xre/app-info;1" component. - -Components.utils.import("resource://gre/modules/AppConstants.jsm"); -Components.utils.import("resource://gre/modules/Services.jsm"); -Components.utils.import("resource://gre/modules/Troubleshoot.jsm"); - -function test() { - waitForExplicitFinish(); - function doNextTest() { - if (!tests.length) { - finish(); - return; - } - tests.shift()(doNextTest); - } - doNextTest(); -} - -registerCleanupFunction(function () { - // Troubleshoot.jsm is imported into the global scope -- the window -- above. - // If it's not deleted, it outlives the test and is reported as a leak. - delete window.Troubleshoot; -}); - -var tests = [ - - function snapshotSchema(done) { - Troubleshoot.snapshot(function (snapshot) { - try { - validateObject(snapshot, SNAPSHOT_SCHEMA); - ok(true, "The snapshot should conform to the schema."); - } - catch (err) { - ok(false, "Schema mismatch, " + err); - } - done(); - }); - }, - - function modifiedPreferences(done) { - let prefs = [ - "javascript.troubleshoot", - "troubleshoot.foo", - "javascript.print_to_filename", - "network.proxy.troubleshoot", - ]; - prefs.forEach(function (p) { - Services.prefs.setBoolPref(p, true); - is(Services.prefs.getBoolPref(p), true, "The pref should be set: " + p); - }); - Troubleshoot.snapshot(function (snapshot) { - let p = snapshot.modifiedPreferences; - is(p["javascript.troubleshoot"], true, - "The pref should be present because it's whitelisted " + - "but not blacklisted."); - ok(!("troubleshoot.foo" in p), - "The pref should be absent because it's not in the whitelist."); - ok(!("javascript.print_to_filename" in p), - "The pref should be absent because it's blacklisted."); - ok(!("network.proxy.troubleshoot" in p), - "The pref should be absent because it's blacklisted."); - prefs.forEach(p => Services.prefs.deleteBranch(p)); - done(); - }); - }, - - function unicodePreferences(done) { - let name = "font.name.sans-serif.x-western"; - let utf8Value = "\xc4\x8capk\xc5\xafv Krasopis" - let unicodeValue = "\u010Capk\u016Fv Krasopis"; - - // set/getCharPref work with 8bit strings (utf8) - Services.prefs.setCharPref(name, utf8Value); - - Troubleshoot.snapshot(function (snapshot) { - let p = snapshot.modifiedPreferences; - is(p[name], unicodeValue, "The pref should have correct Unicode value."); - Services.prefs.deleteBranch(name); - done(); - }); - } -]; - -// This is inspired by JSON Schema, or by the example on its Wikipedia page -// anyway. -const SNAPSHOT_SCHEMA = { - type: "object", - required: true, - properties: { - application: { - required: true, - type: "object", - properties: { - name: { - required: true, - type: "string", - }, - version: { - required: true, - type: "string", - }, - buildID: { - required: true, - type: "string", - }, - userAgent: { - required: true, - type: "string", - }, - osVersion: { - required: true, - type: "string", - }, - vendor: { - type: "string", - }, - updateChannel: { - type: "string", - }, - supportURL: { - type: "string", - }, - numTotalWindows: { - type: "number", - }, - numRemoteWindows: { - type: "number", - }, - safeMode: { - type: "boolean", - }, - }, - }, - crashes: { - required: false, - type: "object", - properties: { - pending: { - required: true, - type: "number", - }, - submitted: { - required: true, - type: "array", - items: { - type: "object", - properties: { - id: { - required: true, - type: "string", - }, - date: { - required: true, - type: "number", - }, - pending: { - required: true, - type: "boolean", - }, - }, - }, - }, - }, - }, - extensions: { - required: true, - type: "array", - items: { - type: "object", - properties: { - name: { - required: true, - type: "string", - }, - version: { - required: true, - type: "string", - }, - id: { - required: true, - type: "string", - }, - isActive: { - required: true, - type: "boolean", - }, - }, - }, - }, - modifiedPreferences: { - required: true, - type: "object", - }, - lockedPreferences: { - required: true, - type: "object", - }, - graphics: { - required: true, - type: "object", - properties: { - numTotalWindows: { - required: true, - type: "number", - }, - numAcceleratedWindows: { - required: true, - type: "number", - }, - windowLayerManagerType: { - type: "string", - }, - windowLayerManagerRemote: { - type: "boolean", - }, - supportsHardwareH264: { - type: "string", - }, - currentAudioBackend: { - type: "string", - }, - numAcceleratedWindowsMessage: { - type: "array", - }, - adapterDescription: { - type: "string", - }, - adapterVendorID: { - type: "string", - }, - adapterDeviceID: { - type: "string", - }, - adapterSubsysID: { - type: "string", - }, - adapterRAM: { - type: "string", - }, - adapterDrivers: { - type: "string", - }, - driverVersion: { - type: "string", - }, - driverDate: { - type: "string", - }, - adapterDescription2: { - type: "string", - }, - adapterVendorID2: { - type: "string", - }, - adapterDeviceID2: { - type: "string", - }, - adapterSubsysID2: { - type: "string", - }, - adapterRAM2: { - type: "string", - }, - adapterDrivers2: { - type: "string", - }, - driverVersion2: { - type: "string", - }, - driverDate2: { - type: "string", - }, - isGPU2Active: { - type: "boolean", - }, - direct2DEnabled: { - type: "boolean", - }, - directWriteEnabled: { - type: "boolean", - }, - directWriteVersion: { - type: "string", - }, - clearTypeParameters: { - type: "string", - }, - webgl1Renderer: { - type: "string", - }, - webgl1Version: { - type: "string", - }, - webgl1DriverExtensions: { - type: "string", - }, - webgl1Extensions: { - type: "string", - }, - webgl1WSIInfo: { - type: "string", - }, - webgl2Renderer: { - type: "string", - }, - webgl2Version: { - type: "string", - }, - webgl2DriverExtensions: { - type: "string", - }, - webgl2Extensions: { - type: "string", - }, - webgl2WSIInfo: { - type: "string", - }, - info: { - type: "object", - }, - failures: { - type: "array", - items: { - type: "string", - }, - }, - indices: { - type: "array", - items: { - type: "number", - }, - }, - featureLog: { - type: "object", - }, - crashGuards: { - type: "array", - }, - direct2DEnabledMessage: { - type: "array", - }, - }, - }, - javaScript: { - required: true, - type: "object", - properties: { - incrementalGCEnabled: { - type: "boolean", - }, - }, - }, - accessibility: { - required: true, - type: "object", - properties: { - isActive: { - required: true, - type: "boolean", - }, - forceDisabled: { - type: "number", - }, - }, - }, - libraryVersions: { - required: true, - type: "object", - properties: { - NSPR: { - required: true, - type: "object", - properties: { - minVersion: { - required: true, - type: "string", - }, - version: { - required: true, - type: "string", - }, - }, - }, - NSS: { - required: true, - type: "object", - properties: { - minVersion: { - required: true, - type: "string", - }, - version: { - required: true, - type: "string", - }, - }, - }, - NSSUTIL: { - required: true, - type: "object", - properties: { - minVersion: { - required: true, - type: "string", - }, - version: { - required: true, - type: "string", - }, - }, - }, - NSSSSL: { - required: true, - type: "object", - properties: { - minVersion: { - required: true, - type: "string", - }, - version: { - required: true, - type: "string", - }, - }, - }, - NSSSMIME: { - required: true, - type: "object", - properties: { - minVersion: { - required: true, - type: "string", - }, - version: { - required: true, - type: "string", - }, - }, - }, - }, - }, - userJS: { - required: true, - type: "object", - properties: { - exists: { - required: true, - type: "boolean", - }, - }, - }, - experiments: { - type: "array", - }, - sandbox: { - required: false, - type: "object", - properties: { - hasSeccompBPF: { - required: AppConstants.platform == "linux", - type: "boolean" - }, - hasSeccompTSync: { - required: AppConstants.platform == "linux", - type: "boolean" - }, - hasUserNamespaces: { - required: AppConstants.platform == "linux", - type: "boolean" - }, - hasPrivilegedUserNamespaces: { - required: AppConstants.platform == "linux", - type: "boolean" - }, - canSandboxContent: { - required: false, - type: "boolean" - }, - canSandboxMedia: { - required: false, - type: "boolean" - }, - }, - }, - }, -}; - -/** - * Throws an Error if obj doesn't conform to schema. That way you get a nice - * error message and a stack to help you figure out what went wrong, which you - * wouldn't get if this just returned true or false instead. There's still - * room for improvement in communicating validation failures, however. - * - * @param obj The object to validate. - * @param schema The schema that obj should conform to. - */ -function validateObject(obj, schema) { - if (obj === undefined && !schema.required) - return; - if (typeof(schema.type) != "string") - throw schemaErr("'type' must be a string", schema); - if (objType(obj) != schema.type) - throw validationErr("Object is not of the expected type", obj, schema); - let validatorFnName = "validateObject_" + schema.type; - if (!(validatorFnName in this)) - throw schemaErr("Validator function not defined for type", schema); - this[validatorFnName](obj, schema); -} - -function validateObject_object(obj, schema) { - if (typeof(schema.properties) != "object") - // Don't care what obj's properties are. - return; - // First check that all the schema's properties match the object. - for (let prop in schema.properties) - validateObject(obj[prop], schema.properties[prop]); - // Now check that the object doesn't have any properties not in the schema. - for (let prop in obj) - if (!(prop in schema.properties)) - throw validationErr("Object has property "+prop+" not in schema", obj, schema); -} - -function validateObject_array(array, schema) { - if (typeof(schema.items) != "object") - // Don't care what the array's elements are. - return; - array.forEach(elt => validateObject(elt, schema.items)); -} - -function validateObject_string(str, schema) {} -function validateObject_boolean(bool, schema) {} -function validateObject_number(num, schema) {} - -function validationErr(msg, obj, schema) { - return new Error("Validation error: " + msg + - ": object=" + JSON.stringify(obj) + - ", schema=" + JSON.stringify(schema)); -} - -function schemaErr(msg, schema) { - return new Error("Schema error: " + msg + ": " + JSON.stringify(schema)); -} - -function objType(obj) { - let type = typeof(obj); - if (type != "object") - return type; - if (Array.isArray(obj)) - return "array"; - if (obj === null) - return "null"; - return type; -} diff --git a/toolkit/modules/tests/browser/browser_WebNavigation.js b/toolkit/modules/tests/browser/browser_WebNavigation.js deleted file mode 100644 index e09cb19948..0000000000 --- a/toolkit/modules/tests/browser/browser_WebNavigation.js +++ /dev/null @@ -1,140 +0,0 @@ -"use strict"; - -var { interfaces: Ci, classes: Cc, utils: Cu, results: Cr } = Components; - -var {WebNavigation} = Cu.import("resource://gre/modules/WebNavigation.jsm", {}); - -const BASE = "http://example.com/browser/toolkit/modules/tests/browser"; -const URL = BASE + "/file_WebNavigation_page1.html"; -const FRAME = BASE + "/file_WebNavigation_page2.html"; -const FRAME2 = BASE + "/file_WebNavigation_page3.html"; - -const EVENTS = [ - "onBeforeNavigate", - "onCommitted", - "onDOMContentLoaded", - "onCompleted", - "onErrorOccurred", - "onReferenceFragmentUpdated", -]; - -const REQUIRED = [ - "onBeforeNavigate", - "onCommitted", - "onDOMContentLoaded", - "onCompleted", -]; - -var expectedBrowser; -var received = []; -var completedResolve; -var waitingURL, waitingEvent; -var rootWindowID; - -function gotEvent(event, details) -{ - if (!details.url.startsWith(BASE)) { - return; - } - info(`Got ${event} ${details.url} ${details.windowId} ${details.parentWindowId}`); - - is(details.browser, expectedBrowser, "correct <browser> element"); - - received.push({url: details.url, event}); - - if (typeof(rootWindowID) == "undefined") { - rootWindowID = details.windowId; - } - - if (details.url == URL) { - is(details.windowId, rootWindowID, "root window ID correct"); - } else { - is(details.parentWindowId, rootWindowID, "parent window ID correct"); - isnot(details.windowId, rootWindowID, "window ID probably okay"); - } - - isnot(details.windowId, undefined); - isnot(details.parentWindowId, undefined); - - if (details.url == waitingURL && event == waitingEvent) { - completedResolve(); - } -} - -function loadViaFrameScript(url, event, script) -{ - // Loading via a frame script ensures that the chrome process never - // "gets ahead" of frame scripts in non-e10s mode. - received = []; - waitingURL = url; - waitingEvent = event; - expectedBrowser.messageManager.loadFrameScript("data:," + script, false); - return new Promise(resolve => { completedResolve = resolve; }); -} - -add_task(function* webnav_ordering() { - let listeners = {}; - for (let event of EVENTS) { - listeners[event] = gotEvent.bind(null, event); - WebNavigation[event].addListener(listeners[event]); - } - - gBrowser.selectedTab = gBrowser.addTab(); - let browser = gBrowser.selectedBrowser; - expectedBrowser = browser; - - yield BrowserTestUtils.browserLoaded(browser); - - yield loadViaFrameScript(URL, "onCompleted", `content.location = "${URL}";`); - - function checkRequired(url) { - for (let event of REQUIRED) { - let found = false; - for (let r of received) { - if (r.url == url && r.event == event) { - found = true; - } - } - ok(found, `Received event ${event} from ${url}`); - } - } - - checkRequired(URL); - checkRequired(FRAME); - - function checkBefore(action1, action2) { - function find(action) { - for (let i = 0; i < received.length; i++) { - if (received[i].url == action.url && received[i].event == action.event) { - return i; - } - } - return -1; - } - - let index1 = find(action1); - let index2 = find(action2); - ok(index1 != -1, `Action ${JSON.stringify(action1)} happened`); - ok(index2 != -1, `Action ${JSON.stringify(action2)} happened`); - ok(index1 < index2, `Action ${JSON.stringify(action1)} happened before ${JSON.stringify(action2)}`); - } - - checkBefore({url: URL, event: "onCommitted"}, {url: FRAME, event: "onBeforeNavigate"}); - checkBefore({url: FRAME, event: "onCompleted"}, {url: URL, event: "onCompleted"}); - - yield loadViaFrameScript(FRAME2, "onCompleted", `content.frames[0].location = "${FRAME2}";`); - - checkRequired(FRAME2); - - yield loadViaFrameScript(FRAME2 + "#ref", "onReferenceFragmentUpdated", - "content.frames[0].document.getElementById('elt').click();"); - - info("Received onReferenceFragmentUpdated from FRAME2"); - - gBrowser.removeCurrentTab(); - - for (let event of EVENTS) { - WebNavigation[event].removeListener(listeners[event]); - } -}); - diff --git a/toolkit/modules/tests/browser/browser_WebRequest.js b/toolkit/modules/tests/browser/browser_WebRequest.js deleted file mode 100644 index cdb28b16cd..0000000000 --- a/toolkit/modules/tests/browser/browser_WebRequest.js +++ /dev/null @@ -1,214 +0,0 @@ -"use strict"; - -var { interfaces: Ci, classes: Cc, utils: Cu, results: Cr } = Components; - -var {WebRequest} = Cu.import("resource://gre/modules/WebRequest.jsm", {}); - -const BASE = "http://example.com/browser/toolkit/modules/tests/browser"; -const URL = BASE + "/file_WebRequest_page1.html"; - -var expected_browser; - -function checkType(details) -{ - let expected_type = "???"; - if (details.url.indexOf("style") != -1) { - expected_type = "stylesheet"; - } else if (details.url.indexOf("image") != -1) { - expected_type = "image"; - } else if (details.url.indexOf("script") != -1) { - expected_type = "script"; - } else if (details.url.indexOf("page1") != -1) { - expected_type = "main_frame"; - } else if (/page2|_redirection\.|dummy_page/.test(details.url)) { - expected_type = "sub_frame"; - } else if (details.url.indexOf("xhr") != -1) { - expected_type = "xmlhttprequest"; - } - is(details.type, expected_type, "resource type is correct"); -} - -var windowIDs = new Map(); - -var requested = []; - -function onBeforeRequest(details) -{ - info(`onBeforeRequest ${details.url}`); - if (details.url.startsWith(BASE)) { - requested.push(details.url); - - is(details.browser, expected_browser, "correct <browser> element"); - checkType(details); - - windowIDs.set(details.url, details.windowId); - if (details.url.indexOf("page2") != -1) { - let page1id = windowIDs.get(URL); - ok(details.windowId != page1id, "sub-frame gets its own window ID"); - is(details.parentWindowId, page1id, "parent window id is correct"); - } - } - if (details.url.indexOf("_bad.") != -1) { - return {cancel: true}; - } - return undefined; -} - -var sendHeaders = []; - -function onBeforeSendHeaders(details) -{ - info(`onBeforeSendHeaders ${details.url}`); - if (details.url.startsWith(BASE)) { - sendHeaders.push(details.url); - - is(details.browser, expected_browser, "correct <browser> element"); - checkType(details); - - let id = windowIDs.get(details.url); - is(id, details.windowId, "window ID same in onBeforeSendHeaders as onBeforeRequest"); - } - if (details.url.indexOf("_redirect.") != -1) { - return {redirectUrl: details.url.replace("_redirect.", "_good.")}; - } - return undefined; -} - -var beforeRedirect = []; - -function onBeforeRedirect(details) -{ - info(`onBeforeRedirect ${details.url} -> ${details.redirectUrl}`); - checkType(details); - if (details.url.startsWith(BASE)) { - beforeRedirect.push(details.url); - - is(details.browser, expected_browser, "correct <browser> element"); - checkType(details); - - let expectedUrl = details.url.replace("_redirect.", "_good.").replace(/\w+_redirection\..*/, "dummy_page.html") - is(details.redirectUrl, expectedUrl, "Correct redirectUrl value"); - } - let id = windowIDs.get(details.url); - is(id, details.windowId, "window ID same in onBeforeRedirect as onBeforeRequest"); - // associate stored windowId with final url - windowIDs.set(details.redirectUrl, details.windowId); - return {}; -} - -var headersReceived = []; - -function onResponseStarted(details) -{ - if (details.url.startsWith(BASE)) { - headersReceived.push(details.url); - } -} - -const expected_requested = [BASE + "/file_WebRequest_page1.html", - BASE + "/file_style_good.css", - BASE + "/file_style_bad.css", - BASE + "/file_style_redirect.css", - BASE + "/file_image_good.png", - BASE + "/file_image_bad.png", - BASE + "/file_image_redirect.png", - BASE + "/file_script_good.js", - BASE + "/file_script_bad.js", - BASE + "/file_script_redirect.js", - BASE + "/file_script_xhr.js", - BASE + "/file_WebRequest_page2.html", - BASE + "/nonexistent_script_url.js", - BASE + "/WebRequest_redirection.sjs", - BASE + "/dummy_page.html", - BASE + "/xhr_resource"]; - -const expected_sendHeaders = [BASE + "/file_WebRequest_page1.html", - BASE + "/file_style_good.css", - BASE + "/file_style_redirect.css", - BASE + "/file_image_good.png", - BASE + "/file_image_redirect.png", - BASE + "/file_script_good.js", - BASE + "/file_script_redirect.js", - BASE + "/file_script_xhr.js", - BASE + "/file_WebRequest_page2.html", - BASE + "/nonexistent_script_url.js", - BASE + "/WebRequest_redirection.sjs", - BASE + "/dummy_page.html", - BASE + "/xhr_resource"]; - -const expected_beforeRedirect = expected_sendHeaders.filter(u => /_redirect\./.test(u)) - .concat(BASE + "/WebRequest_redirection.sjs"); - -const expected_headersReceived = [BASE + "/file_WebRequest_page1.html", - BASE + "/file_style_good.css", - BASE + "/file_image_good.png", - BASE + "/file_script_good.js", - BASE + "/file_script_xhr.js", - BASE + "/file_WebRequest_page2.html", - BASE + "/nonexistent_script_url.js", - BASE + "/dummy_page.html", - BASE + "/xhr_resource"]; - -function removeDupes(list) -{ - let j = 0; - for (let i = 1; i < list.length; i++) { - if (list[i] != list[j]) { - j++; - if (i != j) { - list[j] = list[i]; - } - } - } - list.length = j + 1; -} - -function compareLists(list1, list2, kind) -{ - list1.sort(); - removeDupes(list1); - list2.sort(); - removeDupes(list2); - is(String(list1), String(list2), `${kind} URLs correct`); -} - -function* test_once() -{ - WebRequest.onBeforeRequest.addListener(onBeforeRequest, null, ["blocking"]); - WebRequest.onBeforeSendHeaders.addListener(onBeforeSendHeaders, null, ["blocking"]); - WebRequest.onBeforeRedirect.addListener(onBeforeRedirect); - WebRequest.onResponseStarted.addListener(onResponseStarted); - - yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, - function* (browser) { - expected_browser = browser; - BrowserTestUtils.loadURI(browser, URL); - yield BrowserTestUtils.browserLoaded(expected_browser); - - expected_browser = null; - - yield ContentTask.spawn(browser, null, function() { - let win = content.wrappedJSObject; - is(win.success, 2, "Good script ran"); - is(win.failure, undefined, "Failure script didn't run"); - - let style = - content.getComputedStyle(content.document.getElementById("test"), null); - is(style.getPropertyValue("color"), "rgb(255, 0, 0)", "Good CSS loaded"); - }); - }); - - compareLists(requested, expected_requested, "requested"); - compareLists(sendHeaders, expected_sendHeaders, "sendHeaders"); - compareLists(beforeRedirect, expected_beforeRedirect, "beforeRedirect"); - compareLists(headersReceived, expected_headersReceived, "headersReceived"); - - WebRequest.onBeforeRequest.removeListener(onBeforeRequest); - WebRequest.onBeforeSendHeaders.removeListener(onBeforeSendHeaders); - WebRequest.onBeforeRedirect.removeListener(onBeforeRedirect); - WebRequest.onResponseStarted.removeListener(onResponseStarted); -} - -// Run the test twice to make sure it works with caching. -add_task(test_once); -add_task(test_once); diff --git a/toolkit/modules/tests/browser/browser_WebRequest_cookies.js b/toolkit/modules/tests/browser/browser_WebRequest_cookies.js deleted file mode 100644 index b8c4f24cb4..0000000000 --- a/toolkit/modules/tests/browser/browser_WebRequest_cookies.js +++ /dev/null @@ -1,89 +0,0 @@ -"use strict"; - -var { interfaces: Ci, classes: Cc, utils: Cu, results: Cr } = Components; - -var {WebRequest} = Cu.import("resource://gre/modules/WebRequest.jsm", {}); - -const BASE = "http://example.com/browser/toolkit/modules/tests/browser"; -const URL = BASE + "/WebRequest_dynamic.sjs"; - -var countBefore = 0; -var countAfter = 0; - -function onBeforeSendHeaders(details) -{ - if (details.url != URL) { - return undefined; - } - - countBefore++; - - info(`onBeforeSendHeaders ${details.url}`); - let found = false; - let headers = []; - for (let {name, value} of details.requestHeaders) { - info(`Saw header ${name} '${value}'`); - if (name == "Cookie") { - is(value, "foopy=1", "Cookie is correct"); - headers.push({name, value: "blinky=1"}); - found = true; - } else { - headers.push({name, value}); - } - } - ok(found, "Saw cookie header"); - - return {requestHeaders: headers}; -} - -function onResponseStarted(details) -{ - if (details.url != URL) { - return; - } - - countAfter++; - - info(`onResponseStarted ${details.url}`); - let found = false; - for (let {name, value} of details.responseHeaders) { - info(`Saw header ${name} '${value}'`); - if (name == "Set-Cookie") { - is(value, "dinky=1", "Cookie is correct"); - found = true; - } - } - ok(found, "Saw cookie header"); -} - -add_task(function* filter_urls() { - // First load the URL so that we set cookie foopy=1. - gBrowser.selectedTab = gBrowser.addTab(URL); - yield waitForLoad(); - gBrowser.removeCurrentTab(); - - // Now load with WebRequest set up. - WebRequest.onBeforeSendHeaders.addListener(onBeforeSendHeaders, null, ["blocking"]); - WebRequest.onResponseStarted.addListener(onResponseStarted, null); - - gBrowser.selectedTab = gBrowser.addTab(URL); - - yield waitForLoad(); - - gBrowser.removeCurrentTab(); - - WebRequest.onBeforeSendHeaders.removeListener(onBeforeSendHeaders); - WebRequest.onResponseStarted.removeListener(onResponseStarted); - - is(countBefore, 1, "onBeforeSendHeaders hit once"); - is(countAfter, 1, "onResponseStarted hit once"); -}); - -function waitForLoad(browser = gBrowser.selectedBrowser) { - return new Promise(resolve => { - browser.addEventListener("load", function listener() { - browser.removeEventListener("load", listener, true); - resolve(); - }, true); - }); -} diff --git a/toolkit/modules/tests/browser/browser_WebRequest_filtering.js b/toolkit/modules/tests/browser/browser_WebRequest_filtering.js deleted file mode 100644 index a456678c16..0000000000 --- a/toolkit/modules/tests/browser/browser_WebRequest_filtering.js +++ /dev/null @@ -1,118 +0,0 @@ -"use strict"; - -var { interfaces: Ci, classes: Cc, utils: Cu, results: Cr } = Components; - -var {WebRequest} = Cu.import("resource://gre/modules/WebRequest.jsm", {}); -var {MatchPattern} = Cu.import("resource://gre/modules/MatchPattern.jsm", {}); - -const BASE = "http://example.com/browser/toolkit/modules/tests/browser"; -const URL = BASE + "/file_WebRequest_page2.html"; - -var requested = []; - -function onBeforeRequest(details) -{ - info(`onBeforeRequest ${details.url}`); - if (details.url.startsWith(BASE)) { - requested.push(details.url); - } -} - -var sendHeaders = []; - -function onBeforeSendHeaders(details) -{ - info(`onBeforeSendHeaders ${details.url}`); - if (details.url.startsWith(BASE)) { - sendHeaders.push(details.url); - } -} - -var completed = []; - -function onResponseStarted(details) -{ - if (details.url.startsWith(BASE)) { - completed.push(details.url); - } -} - -const expected_urls = [BASE + "/file_style_good.css", - BASE + "/file_style_bad.css", - BASE + "/file_style_redirect.css"]; - -function removeDupes(list) -{ - let j = 0; - for (let i = 1; i < list.length; i++) { - if (list[i] != list[j]) { - j++; - if (i != j) { - list[j] = list[i]; - } - } - } - list.length = j + 1; -} - -function compareLists(list1, list2, kind) -{ - list1.sort(); - removeDupes(list1); - list2.sort(); - removeDupes(list2); - is(String(list1), String(list2), `${kind} URLs correct`); -} - -add_task(function* filter_urls() { - let filter = {urls: new MatchPattern("*://*/*_style_*")}; - - WebRequest.onBeforeRequest.addListener(onBeforeRequest, filter, ["blocking"]); - WebRequest.onBeforeSendHeaders.addListener(onBeforeSendHeaders, filter, ["blocking"]); - WebRequest.onResponseStarted.addListener(onResponseStarted, filter); - - gBrowser.selectedTab = gBrowser.addTab(URL); - - yield waitForLoad(); - - gBrowser.removeCurrentTab(); - - compareLists(requested, expected_urls, "requested"); - compareLists(sendHeaders, expected_urls, "sendHeaders"); - compareLists(completed, expected_urls, "completed"); - - WebRequest.onBeforeRequest.removeListener(onBeforeRequest); - WebRequest.onBeforeSendHeaders.removeListener(onBeforeSendHeaders); - WebRequest.onResponseStarted.removeListener(onResponseStarted); -}); - -add_task(function* filter_types() { - let filter = {types: ["stylesheet"]}; - - WebRequest.onBeforeRequest.addListener(onBeforeRequest, filter, ["blocking"]); - WebRequest.onBeforeSendHeaders.addListener(onBeforeSendHeaders, filter, ["blocking"]); - WebRequest.onResponseStarted.addListener(onResponseStarted, filter); - - gBrowser.selectedTab = gBrowser.addTab(URL); - - yield waitForLoad(); - - gBrowser.removeCurrentTab(); - - compareLists(requested, expected_urls, "requested"); - compareLists(sendHeaders, expected_urls, "sendHeaders"); - compareLists(completed, expected_urls, "completed"); - - WebRequest.onBeforeRequest.removeListener(onBeforeRequest); - WebRequest.onBeforeSendHeaders.removeListener(onBeforeSendHeaders); - WebRequest.onResponseStarted.removeListener(onResponseStarted); -}); - -function waitForLoad(browser = gBrowser.selectedBrowser) { - return new Promise(resolve => { - browser.addEventListener("load", function listener() { - browser.removeEventListener("load", listener, true); - resolve(); - }, true); - }); -} diff --git a/toolkit/modules/tests/browser/dummy_page.html b/toolkit/modules/tests/browser/dummy_page.html deleted file mode 100644 index c1c9a4e043..0000000000 --- a/toolkit/modules/tests/browser/dummy_page.html +++ /dev/null @@ -1,7 +0,0 @@ -<!DOCTYPE html> - -<html> -<body> -<p>Page</p> -</body> -</html> diff --git a/toolkit/modules/tests/browser/file_FinderSample.html b/toolkit/modules/tests/browser/file_FinderSample.html deleted file mode 100644 index e952d1fe97..0000000000 --- a/toolkit/modules/tests/browser/file_FinderSample.html +++ /dev/null @@ -1,824 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <title>Childe Roland</title> -</head> -<body> -<h1>"Childe Roland to the Dark Tower Came"</h1><h5>Robert Browning</h5> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>I.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>My first thought was, he lied in every word, -<dl> -<dd>That hoary cripple, with malicious eye</dd> -<dd>Askance to watch the working of his lie</dd> -</dl> -</dd> -<dd>On mine, and mouth scarce able to afford</dd> -<dd>Suppression of the glee that pursed and scored -<dl> -<dd>Its edge, at one more victim gained thereby.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>II.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>What else should he be set for, with his staff? -<dl> -<dd>What, save to waylay with his lies, ensnare</dd> -<dd>All travellers who might find him posted there,</dd> -</dl> -</dd> -<dd>And ask the road? I guessed what skull-like laugh</dd> -<dd>Would break, what crutch 'gin write my epitaph -<dl> -<dd>For pastime in the dusty thoroughfare,</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>III.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>If at his counsel I should turn aside -<dl> -<dd>Into that ominous tract which, all agree,</dd> -<dd>Hides the Dark Tower. Yet acquiescingly</dd> -</dl> -</dd> -<dd>I did turn as he pointed: neither pride</dd> -<dd>Nor hope rekindling at the end descried, -<dl> -<dd>So much as gladness that some end might be.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>IV.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>For, what with my whole world-wide wandering, -<dl> -<dd>What with my search drawn out thro' years, my hope</dd> -<dd>Dwindled into a ghost not fit to cope</dd> -</dl> -</dd> -<dd>With that obstreperous joy success would bring,</dd> -<dd>I hardly tried now to rebuke the spring -<dl> -<dd>My heart made, finding failure in its scope.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>V.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>As when a sick man very near to death -<dl> -<dd>Seems dead indeed, and feels begin and end</dd> -<dd>The tears and takes the farewell of each friend,</dd> -</dl> -</dd> -<dd>And hears one bid the other go, draw breath</dd> -<dd>Freelier outside ("since all is o'er," he saith, -<dl> -<dd>"And the blow fallen no grieving can amend;")</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>VI.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>While some discuss if near the other graves -<dl> -<dd>Be room enough for this, and when a day</dd> -<dd>Suits best for carrying the corpse away,</dd> -</dl> -</dd> -<dd>With care about the banners, scarves and staves:</dd> -<dd>And still the man hears all, and only craves -<dl> -<dd>He may not shame such tender love and stay.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>VII.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>Thus, I had so long suffered in this quest, -<dl> -<dd>Heard failure prophesied so oft, been writ</dd> -<dd>So many times among "The Band" - to wit,</dd> -</dl> -</dd> -<dd>The knights who to the Dark Tower's search addressed</dd> -<dd>Their steps - that just to fail as they, seemed best, -<dl> -<dd>And all the doubt was now—should I be fit?</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>VIII.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>So, quiet as despair, I turned from him, -<dl> -<dd>That hateful cripple, out of his highway</dd> -<dd>Into the path he pointed. All the day</dd> -</dl> -</dd> -<dd>Had been a dreary one at best, and dim</dd> -<dd>Was settling to its close, yet shot one grim -<dl> -<dd>Red leer to see the plain catch its estray.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>IX.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>For mark! no sooner was I fairly found -<dl> -<dd>Pledged to the plain, after a pace or two,</dd> -<dd>Than, pausing to throw backward a last view</dd> -</dl> -</dd> -<dd>O'er the safe road, 'twas gone; grey plain all round:</dd> -<dd>Nothing but plain to the horizon's bound. -<dl> -<dd>I might go on; nought else remained to do.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>X.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>So, on I went. I think I never saw -<dl> -<dd>Such starved ignoble nature; nothing throve:</dd> -<dd>For flowers - as well expect a cedar grove!</dd> -</dl> -</dd> -<dd>But cockle, spurge, according to their law</dd> -<dd>Might propagate their kind, with none to awe, -<dl> -<dd>You'd think; a burr had been a treasure trove.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XI.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>No! penury, inertness and grimace, -<dl> -<dd>In some strange sort, were the land's portion. "See</dd> -<dd>Or shut your eyes," said Nature peevishly,</dd> -</dl> -</dd> -<dd>"It nothing skills: I cannot help my case:</dd> -<dd>'Tis the Last Judgment's fire must cure this place, -<dl> -<dd>Calcine its clods and set my prisoners free."</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XII.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>If there pushed any ragged thistle-stalk -<dl> -<dd>Above its mates, the head was chopped; the bents</dd> -<dd>Were jealous else. What made those holes and rents</dd> -</dl> -</dd> -<dd>In the dock's harsh swarth leaves, bruised as to baulk</dd> -<dd>All hope of greenness? 'tis a brute must walk -<dl> -<dd>Pashing their life out, with a brute's intents.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XIII.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>As for the grass, it grew as scant as hair -<dl> -<dd>In leprosy; thin dry blades pricked the mud</dd> -<dd>Which underneath looked kneaded up with blood.</dd> -</dl> -</dd> -<dd>One stiff blind horse, his every bone a-stare,</dd> -<dd>Stood stupefied, however he came there: -<dl> -<dd>Thrust out past service from the devil's stud!</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XIV.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>Alive? he might be dead for aught I know, -<dl> -<dd>With that red gaunt and colloped neck a-strain,</dd> -<dd>And shut eyes underneath the rusty mane;</dd> -</dl> -</dd> -<dd>Seldom went such grotesqueness with such woe;</dd> -<dd>I never saw a brute I hated so; -<dl> -<dd>He must be wicked to deserve such pain.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XV.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>I shut my eyes and turned them on my heart. -<dl> -<dd>As a man calls for wine before he fights,</dd> -<dd>I asked one draught of earlier, happier sights,</dd> -</dl> -</dd> -<dd>Ere fitly I could hope to play my part.</dd> -<dd>Think first, fight afterwards - the soldier's art: -<dl> -<dd>One taste of the old time sets all to rights.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XVI.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>Not it! I fancied Cuthbert's reddening face -<dl> -<dd>Beneath its garniture of curly gold,</dd> -<dd>Dear fellow, till I almost felt him fold</dd> -</dl> -</dd> -<dd>An arm in mine to fix me to the place</dd> -<dd>That way he used. Alas, one night's disgrace! -<dl> -<dd>Out went my heart's new fire and left it cold.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XVII.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>Giles then, the soul of honour - there he stands -<dl> -<dd>Frank as ten years ago when knighted first.</dd> -<dd>What honest men should dare (he said) he durst.</dd> -</dl> -</dd> -<dd>Good - but the scene shifts - faugh! what hangman hands</dd> -<dd>Pin to his breast a parchment? His own bands -<dl> -<dd>Read it. Poor traitor, spit upon and curst!</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XVIII.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>Better this present than a past like that; -<dl> -<dd>Back therefore to my darkening path again!</dd> -<dd>No sound, no sight as far as eye could strain.</dd> -</dl> -</dd> -<dd>Will the night send a howlet or a bat?</dd> -<dd>I asked: when something on the dismal flat -<dl> -<dd>Came to arrest my thoughts and change their train.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XIX.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>A sudden little river crossed my path -<dl> -<dd>As unexpected as a serpent comes.</dd> -<dd>No sluggish tide congenial to the glooms;</dd> -</dl> -</dd> -<dd>This, as it frothed by, might have been a bath</dd> -<dd>For the fiend's glowing hoof - to see the wrath -<dl> -<dd>Of its black eddy bespate with flakes and spumes.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XX.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>So petty yet so spiteful! All along -<dl> -<dd>Low scrubby alders kneeled down over it;</dd> -<dd>Drenched willows flung them headlong in a fit</dd> -</dl> -</dd> -<dd>Of mute despair, a suicidal throng:</dd> -<dd>The river which had done them all the wrong, -<dl> -<dd>Whate'er that was, rolled by, deterred no whit.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XXI.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>Which, while I forded, - good saints, how I feared -<dl> -<dd>To set my foot upon a dead man's cheek,</dd> -<dd>Each step, or feel the spear I thrust to seek</dd> -</dl> -</dd> -<dd>For hollows, tangled in his hair or beard!</dd> -<dd>—It may have been a water-rat I speared, -<dl> -<dd>But, ugh! it sounded like a baby's shriek.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XXII.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>Glad was I when I reached the other bank. -<dl> -<dd>Now for a better country. Vain presage!</dd> -<dd>Who were the strugglers, what war did they wage,</dd> -</dl> -</dd> -<dd>Whose savage trample thus could pad the dank</dd> -<dd>Soil to a plash? Toads in a poisoned tank, -<dl> -<dd>Or wild cats in a red-hot iron cage—</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XXIII.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>The fight must so have seemed in that fell cirque. -<dl> -<dd>What penned them there, with all the plain to choose?</dd> -<dd>No foot-print leading to that horrid mews,</dd> -</dl> -</dd> -<dd>None out of it. Mad brewage set to work</dd> -<dd>Their brains, no doubt, like galley-slaves the Turk -<dl> -<dd>Pits for his pastime, Christians against Jews.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XXIV.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>And more than that - a furlong on - why, there! -<dl> -<dd>What bad use was that engine for, that wheel,</dd> -<dd>Or brake, not wheel - that harrow fit to reel</dd> -</dl> -</dd> -<dd>Men's bodies out like silk? with all the air</dd> -<dd>Of Tophet's tool, on earth left unaware, -<dl> -<dd>Or brought to sharpen its rusty teeth of steel.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XXV.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>Then came a bit of stubbed ground, once a wood, -<dl> -<dd>Next a marsh, it would seem, and now mere earth</dd> -<dd>Desperate and done with; (so a fool finds mirth,</dd> -</dl> -</dd> -<dd>Makes a thing and then mars it, till his mood</dd> -<dd>Changes and off he goes!) within a rood— -<dl> -<dd>Bog, clay and rubble, sand and stark black dearth.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XXVI.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>Now blotches rankling, coloured gay and grim, -<dl> -<dd>Now patches where some leanness of the soil's</dd> -<dd>Broke into moss or substances like boils;</dd> -</dl> -</dd> -<dd>Then came some palsied oak, a cleft in him</dd> -<dd>Like a distorted mouth that splits its rim -<dl> -<dd>Gaping at death, and dies while it recoils.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XXVII.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>And just as far as ever from the end! -<dl> -<dd>Nought in the distance but the evening, nought</dd> -<dd>To point my footstep further! At the thought,</dd> -</dl> -</dd> -<dd>A great black bird, Apollyon's bosom-friend,</dd> -<dd>Sailed past, nor beat his wide wing dragon-penned -<dl> -<dd>That brushed my cap—perchance the guide I sought.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XXVIII.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>For, looking up, aware I somehow grew, -<dl> -<dd>'Spite of the dusk, the plain had given place</dd> -<dd>All round to mountains - with such name to grace</dd> -</dl> -</dd> -<dd>Mere ugly heights and heaps now stolen in view.</dd> -<dd>How thus they had surprised me, - solve it, you! -<dl> -<dd>How to get from them was no clearer case.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XXIX.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>Yet half I seemed to recognise some trick -<dl> -<dd>Of mischief happened to me, God knows when—</dd> -<dd>In a bad dream perhaps. Here ended, then,</dd> -</dl> -</dd> -<dd>Progress this way. When, in the very nick</dd> -<dd>Of giving up, one time more, came a click -<dl> -<dd>As when a trap shuts - you're inside the den!</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XXX.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>Burningly it came on me all at once, -<dl> -<dd>This was the place! those two hills on the right,</dd> -<dd>Crouched like two bulls locked horn in horn in fight;</dd> -</dl> -</dd> -<dd>While to the left, a tall scalped mountain... Dunce,</dd> -<dd>Dotard, a-dozing at the very nonce, -<dl> -<dd>After a life spent training for the sight!</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XXXI.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>What in the midst lay but the Tower itself? -<dl> -<dd>The round squat turret, blind as the fool's heart</dd> -<dd>Built of brown stone, without a counterpart</dd> -</dl> -</dd> -<dd>In the whole world. The tempest's mocking elf</dd> -<dd>Points to the shipman thus the unseen shelf -<dl> -<dd>He strikes on, only when the timbers start.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XXXII.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>Not see? because of night perhaps? - why, day -<dl> -<dd>Came back again for that! before it left,</dd> -<dd>The dying sunset kindled through a cleft:</dd> -</dl> -</dd> -<dd>The hills, like giants at a hunting, lay</dd> -<dd>Chin upon hand, to see the game at bay,— -<dl> -<dd>"Now stab and end the creature - to the heft!"</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XXXIII.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>Not hear? when noise was everywhere! it tolled -<dl> -<dd>Increasing like a bell. Names in my ears</dd> -<dd>Of all the lost adventurers my peers,—</dd> -</dl> -</dd> -<dd>How such a one was strong, and such was bold,</dd> -<dd>And such was fortunate, yet each of old -<dl> -<dd>Lost, lost! one moment knelled the woe of years.</dd> -</dl> -</dd> -</dl> -<p><br /></p> -<dl> -<dd> -<dl> -<dd> -<dl> -<dd>XXXIV.</dd> -</dl> -</dd> -</dl> -</dd> -<dd>There they stood, ranged along the hillsides, met -<dl> -<dd>To view the last of me, a living frame</dd> -<dd>For one more picture! in a sheet of flame</dd> -</dl> -</dd> -<dd>I saw them and I knew them all. And yet</dd> -<dd>Dauntless the slug-horn to my lips I set, -<dl> -<dd>And blew "<i>Childe Roland to the Dark Tower came.</i>"</dd> -</dl> -</dd> -</dl> -</body> -</html> diff --git a/toolkit/modules/tests/browser/file_WebNavigation_page1.html b/toolkit/modules/tests/browser/file_WebNavigation_page1.html deleted file mode 100644 index 1b68697562..0000000000 --- a/toolkit/modules/tests/browser/file_WebNavigation_page1.html +++ /dev/null @@ -1,9 +0,0 @@ -<!DOCTYPE HTML> - -<html> -<body> - -<iframe src="file_WebNavigation_page2.html" width="200" height="200"></iframe> - -</body> -</html> diff --git a/toolkit/modules/tests/browser/file_WebNavigation_page2.html b/toolkit/modules/tests/browser/file_WebNavigation_page2.html deleted file mode 100644 index cc1acc83d6..0000000000 --- a/toolkit/modules/tests/browser/file_WebNavigation_page2.html +++ /dev/null @@ -1,7 +0,0 @@ -<!DOCTYPE HTML> - -<html> -<body> - -</body> -</html> diff --git a/toolkit/modules/tests/browser/file_WebNavigation_page3.html b/toolkit/modules/tests/browser/file_WebNavigation_page3.html deleted file mode 100644 index a0a26a2e9d..0000000000 --- a/toolkit/modules/tests/browser/file_WebNavigation_page3.html +++ /dev/null @@ -1,9 +0,0 @@ -<!DOCTYPE HTML> - -<html> -<body> - -<a id="elt" href="file_WebNavigation_page3.html#ref">click me</a> - -</body> -</html> diff --git a/toolkit/modules/tests/browser/file_WebRequest_page1.html b/toolkit/modules/tests/browser/file_WebRequest_page1.html deleted file mode 100644 index 00a0b9b4b6..0000000000 --- a/toolkit/modules/tests/browser/file_WebRequest_page1.html +++ /dev/null @@ -1,29 +0,0 @@ -<!DOCTYPE HTML> - -<html> -<head> -<meta charset="utf-8"> -<link rel="stylesheet" href="file_style_good.css"> -<link rel="stylesheet" href="file_style_bad.css"> -<link rel="stylesheet" href="file_style_redirect.css"> -</head> -<body> - -<div id="test">Sample text</div> - -<img id="img_good" src="file_image_good.png"> -<img id="img_bad" src="file_image_bad.png"> -<img id="img_redirect" src="file_image_redirect.png"> - -<script src="file_script_good.js"></script> -<script src="file_script_bad.js"></script> -<script src="file_script_redirect.js"></script> - -<script src="file_script_xhr.js"></script> - -<script src="nonexistent_script_url.js"></script> - -<iframe src="file_WebRequest_page2.html" width="200" height="200"></iframe> -<iframe src="WebRequest_redirection.sjs" width="200" height="50"></iframe> -</body> -</html> diff --git a/toolkit/modules/tests/browser/file_WebRequest_page2.html b/toolkit/modules/tests/browser/file_WebRequest_page2.html deleted file mode 100644 index b2cf48f9e1..0000000000 --- a/toolkit/modules/tests/browser/file_WebRequest_page2.html +++ /dev/null @@ -1,25 +0,0 @@ -<!DOCTYPE HTML> - -<html> -<head> -<meta charset="utf-8"> -<link rel="stylesheet" href="file_style_good.css"> -<link rel="stylesheet" href="file_style_bad.css"> -<link rel="stylesheet" href="file_style_redirect.css"> -</head> -<body> - -<div class="test">Sample text</div> - -<img id="img_good" src="file_image_good.png"> -<img id="img_bad" src="file_image_bad.png"> -<img id="img_redirect" src="file_image_redirect.png"> - -<script src="file_script_good.js"></script> -<script src="file_script_bad.js"></script> -<script src="file_script_redirect.js"></script> - -<script src="nonexistent_script_url.js"></script> - -</body> -</html> diff --git a/toolkit/modules/tests/browser/file_image_bad.png b/toolkit/modules/tests/browser/file_image_bad.png Binary files differdeleted file mode 100644 index 4c3be50847..0000000000 --- a/toolkit/modules/tests/browser/file_image_bad.png +++ /dev/null diff --git a/toolkit/modules/tests/browser/file_image_good.png b/toolkit/modules/tests/browser/file_image_good.png Binary files differdeleted file mode 100644 index 769c636340..0000000000 --- a/toolkit/modules/tests/browser/file_image_good.png +++ /dev/null diff --git a/toolkit/modules/tests/browser/file_image_redirect.png b/toolkit/modules/tests/browser/file_image_redirect.png Binary files differdeleted file mode 100644 index 4c3be50847..0000000000 --- a/toolkit/modules/tests/browser/file_image_redirect.png +++ /dev/null diff --git a/toolkit/modules/tests/browser/file_script_bad.js b/toolkit/modules/tests/browser/file_script_bad.js deleted file mode 100644 index 90655f136f..0000000000 --- a/toolkit/modules/tests/browser/file_script_bad.js +++ /dev/null @@ -1 +0,0 @@ -window.failure = true; diff --git a/toolkit/modules/tests/browser/file_script_good.js b/toolkit/modules/tests/browser/file_script_good.js deleted file mode 100644 index b128e54a16..0000000000 --- a/toolkit/modules/tests/browser/file_script_good.js +++ /dev/null @@ -1 +0,0 @@ -window.success = window.success ? window.success + 1 : 1; diff --git a/toolkit/modules/tests/browser/file_script_redirect.js b/toolkit/modules/tests/browser/file_script_redirect.js deleted file mode 100644 index 917b5d6202..0000000000 --- a/toolkit/modules/tests/browser/file_script_redirect.js +++ /dev/null @@ -1,2 +0,0 @@ -window.failure = true; - diff --git a/toolkit/modules/tests/browser/file_script_xhr.js b/toolkit/modules/tests/browser/file_script_xhr.js deleted file mode 100644 index bc1f65eae1..0000000000 --- a/toolkit/modules/tests/browser/file_script_xhr.js +++ /dev/null @@ -1,3 +0,0 @@ -var request = new XMLHttpRequest(); -request.open("get", "http://example.com/browser/toolkit/modules/tests/browser/xhr_resource", false); -request.send(); diff --git a/toolkit/modules/tests/browser/file_style_bad.css b/toolkit/modules/tests/browser/file_style_bad.css deleted file mode 100644 index 8dbc8dc7a4..0000000000 --- a/toolkit/modules/tests/browser/file_style_bad.css +++ /dev/null @@ -1,3 +0,0 @@ -#test { - color: green !important; -} diff --git a/toolkit/modules/tests/browser/file_style_good.css b/toolkit/modules/tests/browser/file_style_good.css deleted file mode 100644 index 46f9774b5f..0000000000 --- a/toolkit/modules/tests/browser/file_style_good.css +++ /dev/null @@ -1,3 +0,0 @@ -#test { - color: red; -} diff --git a/toolkit/modules/tests/browser/file_style_redirect.css b/toolkit/modules/tests/browser/file_style_redirect.css deleted file mode 100644 index 8dbc8dc7a4..0000000000 --- a/toolkit/modules/tests/browser/file_style_redirect.css +++ /dev/null @@ -1,3 +0,0 @@ -#test { - color: green !important; -} diff --git a/toolkit/modules/tests/browser/head.js b/toolkit/modules/tests/browser/head.js deleted file mode 100644 index 777e087e11..0000000000 --- a/toolkit/modules/tests/browser/head.js +++ /dev/null @@ -1,23 +0,0 @@ -function removeDupes(list) -{ - let j = 0; - for (let i = 1; i < list.length; i++) { - if (list[i] != list[j]) { - j++; - if (i != j) { - list[j] = list[i]; - } - } - } - list.length = j + 1; -} - -function compareLists(list1, list2, kind) -{ - list1.sort(); - removeDupes(list1); - list2.sort(); - removeDupes(list2); - is(String(list1), String(list2), `${kind} URLs correct`); -} - diff --git a/toolkit/modules/tests/browser/metadata_simple.html b/toolkit/modules/tests/browser/metadata_simple.html deleted file mode 100644 index 18089e3992..0000000000 --- a/toolkit/modules/tests/browser/metadata_simple.html +++ /dev/null @@ -1,10 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>Test Title</title> - <meta property="description" content="A very simple test page"> - </head> - <body> - Llama. - </body> -</html> diff --git a/toolkit/modules/tests/browser/metadata_titles.html b/toolkit/modules/tests/browser/metadata_titles.html deleted file mode 100644 index bd42013044..0000000000 --- a/toolkit/modules/tests/browser/metadata_titles.html +++ /dev/null @@ -1,11 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>Test Titles</title> - <meta property="description" content="A very simple test page" /> - <meta property="og:title" content="Title" /> - </head> - <body> - Llama. - </body> -</html> diff --git a/toolkit/modules/tests/browser/metadata_titles_fallback.html b/toolkit/modules/tests/browser/metadata_titles_fallback.html deleted file mode 100644 index 5b71879b22..0000000000 --- a/toolkit/modules/tests/browser/metadata_titles_fallback.html +++ /dev/null @@ -1,10 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta property="description" content="A very simple test page" /> - <meta property="og:title" content="Title" /> - </head> - <body> - Llama. - </body> -</html> diff --git a/toolkit/modules/tests/browser/testremotepagemanager.html b/toolkit/modules/tests/browser/testremotepagemanager.html deleted file mode 100644 index 4303a38f54..0000000000 --- a/toolkit/modules/tests/browser/testremotepagemanager.html +++ /dev/null @@ -1,66 +0,0 @@ -<!DOCTYPE HTML> - -<html> -<head> -<script type="text/javascript"> -addMessageListener("Ping", function(message) { - sendAsyncMessage("Pong", { - str: message.data.str, - counter: message.data.counter + 1 - }); -}); - -addMessageListener("Ping2", function(message) { - sendAsyncMessage("Pong2", message.data); -}); - -function neverCalled() { - sendAsyncMessage("Pong3"); -} -addMessageListener("Pong3", neverCalled); -removeMessageListener("Pong3", neverCalled); - -function testData(data) { - var response = { - result: true, - status: "All data correctly received" - } - - function compare(prop, expected) { - if (uneval(data[prop]) == uneval(expected)) - return; - if (response.result) - response.status = ""; - response.result = false; - response.status += "Property " + prop + " should have been " + expected + " but was " + data[prop] + "\n"; - } - - compare("integer", 45); - compare("real", 45.78); - compare("str", "foobar"); - compare("array", [1, 2, 3, 5, 27]); - - return response; -} - -addMessageListener("SendData", function(message) { - sendAsyncMessage("ReceivedData", testData(message.data)); -}); - -addMessageListener("SendData2", function(message) { - sendAsyncMessage("ReceivedData2", testData(message.data.data)); -}); - -var cookie = "nom"; -addMessageListener("SetCookie", function(message) { - cookie = message.data.value; -}); - -addMessageListener("GetCookie", function(message) { - sendAsyncMessage("Cookie", { value: cookie }); -}); -</script> -</head> -<body> -</body> -</html> diff --git a/toolkit/modules/tests/chrome/.eslintrc.js b/toolkit/modules/tests/chrome/.eslintrc.js deleted file mode 100644 index 2c669d844e..0000000000 --- a/toolkit/modules/tests/chrome/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; - -module.exports = { - "extends": [ - "../../../../testing/mochitest/chrome.eslintrc.js" - ] -}; diff --git a/toolkit/modules/tests/chrome/chrome.ini b/toolkit/modules/tests/chrome/chrome.ini deleted file mode 100644 index a272309190..0000000000 --- a/toolkit/modules/tests/chrome/chrome.ini +++ /dev/null @@ -1,3 +0,0 @@ -[DEFAULT] - -[test_bug544442_checkCert.xul] diff --git a/toolkit/modules/tests/chrome/test_bug544442_checkCert.xul b/toolkit/modules/tests/chrome/test_bug544442_checkCert.xul deleted file mode 100644 index dd0ce8fbd0..0000000000 --- a/toolkit/modules/tests/chrome/test_bug544442_checkCert.xul +++ /dev/null @@ -1,155 +0,0 @@ -<?xml version="1.0"?> -<!-- -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ ---> - -<?xml-stylesheet href="chrome://global/skin" type="text/css"?> -<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> - -<window title="Test CertUtils.jsm checkCert - bug 340198 and bug 544442" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - onload="testStart();"> -<script type="application/javascript" - src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> - -<script type="application/javascript"> -<![CDATA[ - -var Cc = Components.classes; -var Ci = Components.interfaces; -var Cr = Components.results; - -SimpleTest.waitForExplicitFinish(); - -Components.utils.import("resource://gre/modules/CertUtils.jsm"); - -function testStart() { - ok(true, "Entering testStart"); - - var request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]. - createInstance(Ci.nsIXMLHttpRequest); - request.open("GET", "https://example.com/", true); - request.channel.notificationCallbacks = new BadCertHandler(true); - request.onerror = function(event) { testXHRError(event); }; - request.onload = function(event) { testXHRLoad(event); }; - request.send(null); -} - -function testXHRError(aEvent) { - ok(true, "Entering testXHRError - something went wrong"); - - var request = aEvent.target; - var status = 0; - try { - status = request.status; - } - catch (e) { - } - - if (status == 0) - status = request.channel.QueryInterface(Ci.nsIRequest).status; - - ok(false, "XHR onerror called: " + status); - - SimpleTest.finish(); -} - -function getCheckCertResult(aChannel, aAllowNonBuiltIn, aCerts) { - try { - checkCert(aChannel, aAllowNonBuiltIn, aCerts); - } - catch (e) { - return e.result; - } - return Cr.NS_OK; -} - -function testXHRLoad(aEvent) { - ok(true, "Entering testXHRLoad"); - - var channel = aEvent.target.channel; - - var certs = null; - is(getCheckCertResult(channel, false, certs), Cr.NS_ERROR_ABORT, - "checkCert should throw NS_ERROR_ABORT when the certificate attributes " + - "array passed to checkCert is null and the certificate is not builtin"); - - is(getCheckCertResult(channel, true, certs), Cr.NS_OK, - "checkCert should not throw when the certificate attributes array " + - "passed to checkCert is null and builtin certificates aren't enforced"); - - certs = [ { invalidAttribute: "Invalid attribute" } ]; - is(getCheckCertResult(channel, false, certs), Cr.NS_ERROR_ILLEGAL_VALUE, - "checkCert should throw NS_ERROR_ILLEGAL_VALUE when the certificate " + - "attributes array passed to checkCert has an element that has an " + - "attribute that does not exist on the certificate"); - - certs = [ { issuerName: "Incorrect issuerName" } ]; - is(getCheckCertResult(channel, false, certs), Cr.NS_ERROR_ILLEGAL_VALUE, - "checkCert should throw NS_ERROR_ILLEGAL_VALUE when the certificate " + - "attributes array passed to checkCert has an element that has an " + - "issuerName that is not the same as the certificate's"); - - var cert = channel.securityInfo.QueryInterface(Ci.nsISSLStatusProvider). - SSLStatus.QueryInterface(Ci.nsISSLStatus).serverCert; - - certs = [ { issuerName: cert.issuerName, - commonName: cert.commonName } ]; - is(getCheckCertResult(channel, false, certs), Cr.NS_ERROR_ABORT, - "checkCert should throw NS_ERROR_ABORT when the certificate attributes " + - "array passed to checkCert has a single element that has the same " + - "issuerName and commonName as the certificate's and the certificate is " + - "not builtin"); - - is(getCheckCertResult(channel, true, certs), Cr.NS_OK, - "checkCert should not throw when the certificate attributes array " + - "passed to checkCert has a single element that has the same issuerName " + - "and commonName as the certificate's and and builtin certificates " + - "aren't enforced"); - - certs = [ { issuerName: "Incorrect issuerName", - invalidAttribute: "Invalid attribute" }, - { issuerName: cert.issuerName, - commonName: "Invalid Common Name" }, - { issuerName: cert.issuerName, - commonName: cert.commonName } ]; - is(getCheckCertResult(channel, false, certs), Cr.NS_ERROR_ABORT, - "checkCert should throw NS_ERROR_ABORT when the certificate attributes " + - "array passed to checkCert has an element that has the same issuerName " + - "and commonName as the certificate's and the certificate is not builtin"); - - is(getCheckCertResult(channel, true, certs), Cr.NS_OK, - "checkCert should not throw when the certificate attributes array " + - "passed to checkCert has an element that has the same issuerName and " + - "commonName as the certificate's and builtin certificates aren't enforced"); - - var mockChannel = { originalURI: Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService). - newURI("http://example.com/", null, null) }; - - certs = [ ]; - is(getCheckCertResult(mockChannel, false, certs), Cr.NS_ERROR_UNEXPECTED, - "checkCert should throw NS_ERROR_UNEXPECTED when the certificate " + - "attributes array passed to checkCert is not null and the channel's " + - "originalURI is not https"); - - certs = null; - is(getCheckCertResult(mockChannel, false, certs), Cr.NS_OK, - "checkCert should not throw when the certificate attributes object " + - "passed to checkCert is null and the the channel's originalURI is not " + - "https"); - - SimpleTest.finish(); -} - -]]> -</script> - -<body xmlns="http://www.w3.org/1999/xhtml"> - <p id="display"></p> - <div id="content" style="display: none"></div> - <pre id="test"></pre> -</body> -</window> diff --git a/toolkit/modules/tests/mochitest/.eslintrc.js b/toolkit/modules/tests/mochitest/.eslintrc.js deleted file mode 100644 index 3c788d6d68..0000000000 --- a/toolkit/modules/tests/mochitest/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; - -module.exports = { - "extends": [ - "../../../../testing/mochitest/mochitest.eslintrc.js" - ] -}; diff --git a/toolkit/modules/tests/mochitest/mochitest.ini b/toolkit/modules/tests/mochitest/mochitest.ini deleted file mode 100644 index 852d95539f..0000000000 --- a/toolkit/modules/tests/mochitest/mochitest.ini +++ /dev/null @@ -1,3 +0,0 @@ -[DEFAULT] - -[test_spatial_navigation.html] diff --git a/toolkit/modules/tests/mochitest/test_spatial_navigation.html b/toolkit/modules/tests/mochitest/test_spatial_navigation.html deleted file mode 100644 index c1fbb0eec8..0000000000 --- a/toolkit/modules/tests/mochitest/test_spatial_navigation.html +++ /dev/null @@ -1,76 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=698437 ---> -<head> - <meta charset="utf-8"> - <title>Test for Bug 698437</title> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <script type="application/javascript"> - - /** Test for Bug 698437 **/ - - SimpleTest.waitForExplicitFinish(); - - function Test() { - if (!SpecialPowers.getBoolPref("snav.enabled")) { - todo(false, "Enable spatial navigiation on this platform."); - SimpleTest.finish(); - return; - } - - var center = document.getElementById("center"); - var right = document.getElementById("right"); - var left = document.getElementById("left"); - var top = document.getElementById("top"); - var bottom = document.getElementById("bottom"); - - console.log(top); - console.log(bottom); - console.log(center); - console.log(left); - console.log(right); - - center.focus(); - is(center.id, document.activeElement.id, "How did we call focus on center and it did" + - " not become the active element?"); - - synthesizeKey("VK_UP", { }); - is(document.activeElement.id, top.id, - "Spatial navigation up key is not handled correctly."); - - center.focus(); - synthesizeKey("VK_DOWN", { }); - is(document.activeElement.id, bottom.id, - "Spatial navigation down key is not handled correctly."); - - center.focus(); - synthesizeKey("VK_RIGHT", { }); - is(document.activeElement.id, right.id, - "Spatial navigation right key is not handled correctly."); - - center.focus(); - synthesizeKey("VK_LEFT", { }); - is(document.activeElement.id, left.id, - "Spatial navigation left key is not handled correctly."); - - SimpleTest.finish(); - } - - </script> -</head> -<body onload="Test();"> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=698437">Mozilla Bug 698437</a> -<p id="display"></p> -<div id="content"> - <button id="lefttop">1</button><button id="top">2</button><button id="righttop">3</button><br> - <button id="left">4</button><button id="center">5</button><button id="right">6</button><br> - <button id="leftbottom">7</button><button id="bottom">8</button><button id="rightbottom">9</button><br> -</div> -<pre id="test"> -</pre> -</body> -</html> diff --git a/toolkit/modules/tests/xpcshell/.eslintrc.js b/toolkit/modules/tests/xpcshell/.eslintrc.js deleted file mode 100644 index fee088c179..0000000000 --- a/toolkit/modules/tests/xpcshell/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; - -module.exports = { - "extends": [ - "../../../../testing/xpcshell/xpcshell.eslintrc.js" - ] -}; diff --git a/toolkit/modules/tests/xpcshell/TestIntegration.jsm b/toolkit/modules/tests/xpcshell/TestIntegration.jsm deleted file mode 100644 index 78a0b72671..0000000000 --- a/toolkit/modules/tests/xpcshell/TestIntegration.jsm +++ /dev/null @@ -1,42 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/* - * Internal module used to test the generation of Integration.jsm getters. - */ - -"use strict"; - -this.EXPORTED_SYMBOLS = [ - "TestIntegration", -]; - -const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; - -Cu.import("resource://gre/modules/Task.jsm"); - -this.TestIntegration = { - value: "value", - - get valueFromThis() { - return this.value; - }, - - get property() { - return this._property; - }, - - set property(value) { - this._property = value; - }, - - method(argument) { - this.methodArgument = argument; - return "method" + argument; - }, - - asyncMethod: Task.async(function* (argument) { - this.asyncMethodArgument = argument; - return "asyncMethod" + argument; - }), -}; diff --git a/toolkit/modules/tests/xpcshell/chromeappsstore.sqlite b/toolkit/modules/tests/xpcshell/chromeappsstore.sqlite Binary files differdeleted file mode 100644 index 15d309df50..0000000000 --- a/toolkit/modules/tests/xpcshell/chromeappsstore.sqlite +++ /dev/null diff --git a/toolkit/modules/tests/xpcshell/propertyLists/bug710259_propertyListBinary.plist b/toolkit/modules/tests/xpcshell/propertyLists/bug710259_propertyListBinary.plist Binary files differdeleted file mode 100644 index 5888c9c9c5..0000000000 --- a/toolkit/modules/tests/xpcshell/propertyLists/bug710259_propertyListBinary.plist +++ /dev/null diff --git a/toolkit/modules/tests/xpcshell/propertyLists/bug710259_propertyListXML.plist b/toolkit/modules/tests/xpcshell/propertyLists/bug710259_propertyListXML.plist deleted file mode 100644 index 9b6decc1e6..0000000000 --- a/toolkit/modules/tests/xpcshell/propertyLists/bug710259_propertyListXML.plist +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>Boolean</key> - <false/> - <key>Array</key> - <array> - <string>abc</string> - <string>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</string> - <string>אאא</string> - <string>אאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאאא</string> - <string>𐀀𐀀𐀀</string> - <date>2011-12-31T11:15:23Z</date> - <data>MjAxMS0xMi0zMVQxMToxNTozM1o=</data> - <dict> - <key>Negative Number</key> - <integer>-400</integer> - <key>Real Number</key> - <real>2.71828183</real> - <key>Big Int</key> - <integer>9007199254740993</integer> - <key>Negative Big Int</key> - <integer>-9007199254740993</integer> - </dict> - </array> -</dict> -</plist> diff --git a/toolkit/modules/tests/xpcshell/test_BinarySearch.js b/toolkit/modules/tests/xpcshell/test_BinarySearch.js deleted file mode 100644 index f48b0bccff..0000000000 --- a/toolkit/modules/tests/xpcshell/test_BinarySearch.js +++ /dev/null @@ -1,81 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -Components.utils.import("resource://gre/modules/BinarySearch.jsm"); - -function run_test() { - // empty array - ok([], 1, false, 0); - - // one-element array - ok([2], 2, true, 0); - ok([2], 1, false, 0); - ok([2], 3, false, 1); - - // two-element array - ok([2, 4], 2, true, 0); - ok([2, 4], 4, true, 1); - ok([2, 4], 1, false, 0); - ok([2, 4], 3, false, 1); - ok([2, 4], 5, false, 2); - - // three-element array - ok([2, 4, 6], 2, true, 0); - ok([2, 4, 6], 4, true, 1); - ok([2, 4, 6], 6, true, 2); - ok([2, 4, 6], 1, false, 0); - ok([2, 4, 6], 3, false, 1); - ok([2, 4, 6], 5, false, 2); - ok([2, 4, 6], 7, false, 3); - - // duplicates - ok([2, 2], 2, true, 0); - ok([2, 2], 1, false, 0); - ok([2, 2], 3, false, 2); - - // duplicates on the left - ok([2, 2, 4], 2, true, 1); - ok([2, 2, 4], 4, true, 2); - ok([2, 2, 4], 1, false, 0); - ok([2, 2, 4], 3, false, 2); - ok([2, 2, 4], 5, false, 3); - - // duplicates on the right - ok([2, 4, 4], 2, true, 0); - ok([2, 4, 4], 4, true, 1); - ok([2, 4, 4], 1, false, 0); - ok([2, 4, 4], 3, false, 1); - ok([2, 4, 4], 5, false, 3); - - // duplicates in the middle - ok([2, 4, 4, 6], 2, true, 0); - ok([2, 4, 4, 6], 4, true, 1); - ok([2, 4, 4, 6], 6, true, 3); - ok([2, 4, 4, 6], 1, false, 0); - ok([2, 4, 4, 6], 3, false, 1); - ok([2, 4, 4, 6], 5, false, 3); - ok([2, 4, 4, 6], 7, false, 4); - - // duplicates all around - ok([2, 2, 4, 4, 6, 6], 2, true, 0); - ok([2, 2, 4, 4, 6, 6], 4, true, 2); - ok([2, 2, 4, 4, 6, 6], 6, true, 4); - ok([2, 2, 4, 4, 6, 6], 1, false, 0); - ok([2, 2, 4, 4, 6, 6], 3, false, 2); - ok([2, 2, 4, 4, 6, 6], 5, false, 4); - ok([2, 2, 4, 4, 6, 6], 7, false, 6); -} - -function ok(array, target, expectedFound, expectedIdx) { - let [found, idx] = BinarySearch.search(cmp, array, target); - do_check_eq(found, expectedFound); - do_check_eq(idx, expectedIdx); - - idx = expectedFound ? expectedIdx : -1; - do_check_eq(BinarySearch.indexOf(cmp, array, target), idx); - do_check_eq(BinarySearch.insertionIndexOf(cmp, array, target), expectedIdx); -} - -function cmp(num1, num2) { - return num1 - num2; -} diff --git a/toolkit/modules/tests/xpcshell/test_CanonicalJSON.js b/toolkit/modules/tests/xpcshell/test_CanonicalJSON.js deleted file mode 100644 index fa61f5a010..0000000000 --- a/toolkit/modules/tests/xpcshell/test_CanonicalJSON.js +++ /dev/null @@ -1,146 +0,0 @@ -const { CanonicalJSON } = Components.utils.import("resource://gre/modules/CanonicalJSON.jsm"); - -function stringRepresentation(obj) { - const clone = JSON.parse(JSON.stringify(obj)); - return JSON.stringify(clone); -} - -add_task(function* test_canonicalJSON_should_preserve_array_order() { - const input = ['one', 'two', 'three']; - // No sorting should be done on arrays. - do_check_eq(CanonicalJSON.stringify(input), '["one","two","three"]'); -}); - -add_task(function* test_canonicalJSON_orders_object_keys() { - const input = [{ - b: ['two', 'three'], - a: ['zero', 'one'] - }]; - do_check_eq( - CanonicalJSON.stringify(input), - '[{"a":["zero","one"],"b":["two","three"]}]' - ); -}); - -add_task(function* test_canonicalJSON_orders_nested_object_keys() { - const input = [{ - b: {d: 'd', c: 'c'}, - a: {b: 'b', a: 'a'} - }]; - do_check_eq( - CanonicalJSON.stringify(input), - '[{"a":{"a":"a","b":"b"},"b":{"c":"c","d":"d"}}]' - ); -}); - -add_task(function* test_canonicalJSON_escapes_unicode_values() { - do_check_eq( - CanonicalJSON.stringify([{key: '✓'}]), - '[{"key":"\\u2713"}]' - ); - // Unicode codepoints should be output in lowercase. - do_check_eq( - CanonicalJSON.stringify([{key: 'é'}]), - '[{"key":"\\u00e9"}]' - ); -}); - -add_task(function* test_canonicalJSON_escapes_unicode_object_keys() { - do_check_eq( - CanonicalJSON.stringify([{'é': 'check'}]), - '[{"\\u00e9":"check"}]' - ); -}); - - -add_task(function* test_canonicalJSON_does_not_alter_input() { - const records = [ - {'foo': 'bar', 'last_modified': '12345', 'id': '1'}, - {'bar': 'baz', 'last_modified': '45678', 'id': '2'} - ]; - const serializedJSON = JSON.stringify(records); - CanonicalJSON.stringify(records); - do_check_eq(JSON.stringify(records), serializedJSON); -}); - - -add_task(function* test_canonicalJSON_preserves_data() { - const records = [ - {'foo': 'bar', 'last_modified': '12345', 'id': '1'}, - {'bar': 'baz', 'last_modified': '45678', 'id': '2'}, - ] - const serialized = CanonicalJSON.stringify(records); - const expected = '[{"foo":"bar","id":"1","last_modified":"12345"},' + - '{"bar":"baz","id":"2","last_modified":"45678"}]'; - do_check_eq(CanonicalJSON.stringify(records), expected); -}); - -add_task(function* test_canonicalJSON_does_not_add_space_separators() { - const records = [ - {'foo': 'bar', 'last_modified': '12345', 'id': '1'}, - {'bar': 'baz', 'last_modified': '45678', 'id': '2'}, - ] - const serialized = CanonicalJSON.stringify(records); - do_check_false(serialized.includes(" ")); -}); - -add_task(function* test_canonicalJSON_serializes_empty_object() { - do_check_eq(CanonicalJSON.stringify({}), "{}"); -}); - -add_task(function* test_canonicalJSON_serializes_empty_array() { - do_check_eq(CanonicalJSON.stringify([]), "[]"); -}); - -add_task(function* test_canonicalJSON_serializes_NaN() { - do_check_eq(CanonicalJSON.stringify(NaN), "null"); -}); - -add_task(function* test_canonicalJSON_serializes_inf() { - // This isn't part of the JSON standard. - do_check_eq(CanonicalJSON.stringify(Infinity), "null"); -}); - - -add_task(function* test_canonicalJSON_serializes_empty_string() { - do_check_eq(CanonicalJSON.stringify(""), '""'); -}); - -add_task(function* test_canonicalJSON_escapes_backslashes() { - do_check_eq(CanonicalJSON.stringify("This\\and this"), '"This\\\\and this"'); -}); - -add_task(function* test_canonicalJSON_handles_signed_zeros() { - // do_check_eq doesn't support comparison of -0 and 0 properly. - do_check_true(CanonicalJSON.stringify(-0) === '-0'); - do_check_true(CanonicalJSON.stringify(0) === '0'); -}); - - -add_task(function* test_canonicalJSON_with_deeply_nested_dicts() { - const records = [{ - 'a': { - 'b': 'b', - 'a': 'a', - 'c': { - 'b': 'b', - 'a': 'a', - 'c': ['b', 'a', 'c'], - 'd': {'b': 'b', 'a': 'a'}, - 'id': '1', - 'e': 1, - 'f': [2, 3, 1], - 'g': {2: 2, 3: 3, 1: { - 'b': 'b', 'a': 'a', 'c': 'c'}}}}, - 'id': '1'}] - const expected = - '[{"a":{"a":"a","b":"b","c":{"a":"a","b":"b","c":["b","a","c"],' + - '"d":{"a":"a","b":"b"},"e":1,"f":[2,3,1],"g":{' + - '"1":{"a":"a","b":"b","c":"c"},"2":2,"3":3},"id":"1"}},"id":"1"}]'; - - do_check_eq(CanonicalJSON.stringify(records), expected); -}); - -function run_test() { - run_next_test(); -} diff --git a/toolkit/modules/tests/xpcshell/test_Color.js b/toolkit/modules/tests/xpcshell/test_Color.js deleted file mode 100644 index 9bf9bf861c..0000000000 --- a/toolkit/modules/tests/xpcshell/test_Color.js +++ /dev/null @@ -1,53 +0,0 @@ -"use strict"; - -Components.utils.import("resource://gre/modules/Color.jsm"); - -function run_test() { - testRelativeLuminance(); - testIsBright(); - testContrastRatio(); - testIsContrastRatioAcceptable(); -} - -function testRelativeLuminance() { - let c = new Color(0, 0, 0); - Assert.equal(c.relativeLuminance, 0, "Black is not illuminating"); - - c = new Color(255, 255, 255); - Assert.equal(c.relativeLuminance, 1, "White is quite the luminant one"); - - c = new Color(142, 42, 142); - Assert.equal(c.relativeLuminance, 0.25263952353998204, - "This purple is not that luminant"); -} - -function testIsBright() { - let c = new Color(0, 0, 0); - Assert.equal(c.isBright, 0, "Black is bright"); - - c = new Color(255, 255, 255); - Assert.equal(c.isBright, 1, "White is bright"); -} - -function testContrastRatio() { - let c = new Color(0, 0, 0); - let c2 = new Color(255, 255, 255); - Assert.equal(c.contrastRatio(c2), 21, "Contrast between black and white is max"); - Assert.equal(c.contrastRatio(c), 1, "Contrast between equals is min"); - - let c3 = new Color(142, 42, 142); - Assert.equal(c.contrastRatio(c3), 6.05279047079964, "Contrast between black and purple"); - Assert.equal(c2.contrastRatio(c3), 3.469474137806338, "Contrast between white and purple"); -} - -function testIsContrastRatioAcceptable() { - // Let's assert what browser.js is doing for window frames. - let c = new Color(...[55, 156, 152]); - let c2 = new Color(0, 0, 0); - Assert.equal(c.r, 55, "Reds should match"); - Assert.equal(c.g, 156, "Greens should match"); - Assert.equal(c.b, 152, "Blues should match"); - Assert.ok(c.isContrastRatioAcceptable(c2), "The blue is high contrast enough"); - c = new Color(...[35, 65, 100]); - Assert.ok(!c.isContrastRatioAcceptable(c2), "The blue is not high contrast enough"); -} diff --git a/toolkit/modules/tests/xpcshell/test_DeferredTask.js b/toolkit/modules/tests/xpcshell/test_DeferredTask.js deleted file mode 100644 index 441f9054c2..0000000000 --- a/toolkit/modules/tests/xpcshell/test_DeferredTask.js +++ /dev/null @@ -1,390 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * This file tests the DeferredTask.jsm module. - */ - -// Globals - -var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "DeferredTask", - "resource://gre/modules/DeferredTask.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Promise", - "resource://gre/modules/Promise.jsm"); - -/** - * Due to the nature of this module, most of the tests are time-dependent. All - * the timeouts are designed to occur at multiples of this granularity value, - * in milliseconds, that should be high enough to prevent intermittent failures, - * but low enough to prevent an excessive overall test execution time. - */ -const T = 100; - -/** - * Waits for the specified timeout before resolving the returned promise. - */ -function promiseTimeout(aTimeoutMs) -{ - let deferred = Promise.defer(); - do_timeout(aTimeoutMs, deferred.resolve); - return deferred.promise; -} - -function run_test() -{ - run_next_test(); -} - -// Tests - -/** - * Creates a simple DeferredTask and executes it once. - */ -add_test(function test_arm_simple() -{ - new DeferredTask(run_next_test, 10).arm(); -}); - -/** - * Checks that the delay set for the task is respected. - */ -add_test(function test_arm_delay_respected() -{ - let executed1 = false; - let executed2 = false; - - new DeferredTask(function () { - executed1 = true; - do_check_false(executed2); - }, 1*T).arm(); - - new DeferredTask(function () { - executed2 = true; - do_check_true(executed1); - run_next_test(); - }, 2*T).arm(); -}); - -/** - * Checks that calling "arm" again does not introduce further delay. - */ -add_test(function test_arm_delay_notrestarted() -{ - let executed = false; - - // Create a task that will run later. - let deferredTask = new DeferredTask(() => { executed = true; }, 4*T); - deferredTask.arm(); - - // Before the task starts, call "arm" again. - do_timeout(2*T, () => deferredTask.arm()); - - // The "arm" call should not have introduced further delays. - do_timeout(5*T, function () { - do_check_true(executed); - run_next_test(); - }); -}); - -/** - * Checks that a task runs only once when armed multiple times synchronously. - */ -add_test(function test_arm_coalesced() -{ - let executed = false; - - let deferredTask = new DeferredTask(function () { - do_check_false(executed); - executed = true; - run_next_test(); - }, 50); - - deferredTask.arm(); - deferredTask.arm(); -}); - -/** - * Checks that a task runs only once when armed multiple times synchronously, - * even when it has been created with a delay of zero milliseconds. - */ -add_test(function test_arm_coalesced_nodelay() -{ - let executed = false; - - let deferredTask = new DeferredTask(function () { - do_check_false(executed); - executed = true; - run_next_test(); - }, 0); - - deferredTask.arm(); - deferredTask.arm(); -}); - -/** - * Checks that a task can be armed again while running. - */ -add_test(function test_arm_recursive() -{ - let executed = false; - - let deferredTask = new DeferredTask(function () { - if (!executed) { - executed = true; - deferredTask.arm(); - } else { - run_next_test(); - } - }, 50); - - deferredTask.arm(); -}); - -/** - * Checks that calling "arm" while an asynchronous task is running waits until - * the task is finished before restarting the delay. - */ -add_test(function test_arm_async() -{ - let finishedExecution = false; - let finishedExecutionAgain = false; - - // Create a task that will run later. - let deferredTask = new DeferredTask(function* () { - yield promiseTimeout(4*T); - if (!finishedExecution) { - finishedExecution = true; - } else if (!finishedExecutionAgain) { - finishedExecutionAgain = true; - } - }, 2*T); - deferredTask.arm(); - - // While the task is running, call "arm" again. This will result in a wait - // of 2*T until the task finishes, then another 2*T for the normal task delay - // specified on construction. - do_timeout(4*T, function () { - do_check_true(deferredTask.isRunning); - do_check_false(finishedExecution); - deferredTask.arm(); - }); - - // This will fail in case the task was started without waiting 2*T after it - // has finished. - do_timeout(7*T, function () { - do_check_false(deferredTask.isRunning); - do_check_true(finishedExecution); - }); - - // This is in the middle of the second execution. - do_timeout(10*T, function () { - do_check_true(deferredTask.isRunning); - do_check_false(finishedExecutionAgain); - }); - - // Wait enough time to verify that the task was executed as expected. - do_timeout(13*T, function () { - do_check_false(deferredTask.isRunning); - do_check_true(finishedExecutionAgain); - run_next_test(); - }); -}); - -/** - * Checks that an armed task can be disarmed. - */ -add_test(function test_disarm() -{ - // Create a task that will run later. - let deferredTask = new DeferredTask(function () { - do_throw("This task should not run."); - }, 2*T); - deferredTask.arm(); - - // Disable execution later, but before the task starts. - do_timeout(1*T, () => deferredTask.disarm()); - - // Wait enough time to verify that the task did not run. - do_timeout(3*T, run_next_test); -}); - -/** - * Checks that calling "disarm" allows the delay to be restarted. - */ -add_test(function test_disarm_delay_restarted() -{ - let executed = false; - - let deferredTask = new DeferredTask(() => { executed = true; }, 4*T); - deferredTask.arm(); - - do_timeout(2*T, function () { - deferredTask.disarm(); - deferredTask.arm(); - }); - - do_timeout(5*T, function () { - do_check_false(executed); - }); - - do_timeout(7*T, function () { - do_check_true(executed); - run_next_test(); - }); -}); - -/** - * Checks that calling "disarm" while an asynchronous task is running does not - * prevent the task to finish. - */ -add_test(function test_disarm_async() -{ - let finishedExecution = false; - - let deferredTask = new DeferredTask(function* () { - deferredTask.arm(); - yield promiseTimeout(2*T); - finishedExecution = true; - }, 1*T); - deferredTask.arm(); - - do_timeout(2*T, function () { - do_check_true(deferredTask.isRunning); - do_check_true(deferredTask.isArmed); - do_check_false(finishedExecution); - deferredTask.disarm(); - }); - - do_timeout(4*T, function () { - do_check_false(deferredTask.isRunning); - do_check_false(deferredTask.isArmed); - do_check_true(finishedExecution); - run_next_test(); - }); -}); - -/** - * Checks that calling "arm" immediately followed by "disarm" while an - * asynchronous task is running does not cause it to run again. - */ -add_test(function test_disarm_immediate_async() -{ - let executed = false; - - let deferredTask = new DeferredTask(function* () { - do_check_false(executed); - executed = true; - yield promiseTimeout(2*T); - }, 1*T); - deferredTask.arm(); - - do_timeout(2*T, function () { - do_check_true(deferredTask.isRunning); - do_check_false(deferredTask.isArmed); - deferredTask.arm(); - deferredTask.disarm(); - }); - - do_timeout(4*T, function () { - do_check_true(executed); - do_check_false(deferredTask.isRunning); - do_check_false(deferredTask.isArmed); - run_next_test(); - }); -}); - -/** - * Checks the isArmed and isRunning properties with a synchronous task. - */ -add_test(function test_isArmed_isRunning() -{ - let deferredTask = new DeferredTask(function () { - do_check_true(deferredTask.isRunning); - do_check_false(deferredTask.isArmed); - deferredTask.arm(); - do_check_true(deferredTask.isArmed); - deferredTask.disarm(); - do_check_false(deferredTask.isArmed); - run_next_test(); - }, 50); - - do_check_false(deferredTask.isArmed); - deferredTask.arm(); - do_check_true(deferredTask.isArmed); - do_check_false(deferredTask.isRunning); -}); - -/** - * Checks that the "finalize" method executes a synchronous task. - */ -add_test(function test_finalize() -{ - let executed = false; - let timePassed = false; - - let deferredTask = new DeferredTask(function () { - do_check_false(timePassed); - executed = true; - }, 2*T); - deferredTask.arm(); - - do_timeout(1*T, () => { timePassed = true; }); - - // This should trigger the immediate execution of the task. - deferredTask.finalize().then(function () { - do_check_true(executed); - run_next_test(); - }); -}); - -/** - * Checks that the "finalize" method executes the task again from start to - * finish in case it is already running. - */ -add_test(function test_finalize_executes_entirely() -{ - let executed = false; - let executedAgain = false; - let timePassed = false; - - let deferredTask = new DeferredTask(function* () { - // The first time, we arm the timer again and set up the finalization. - if (!executed) { - deferredTask.arm(); - do_check_true(deferredTask.isArmed); - do_check_true(deferredTask.isRunning); - - deferredTask.finalize().then(function () { - // When we reach this point, the task must be finished. - do_check_true(executedAgain); - do_check_false(timePassed); - do_check_false(deferredTask.isArmed); - do_check_false(deferredTask.isRunning); - run_next_test(); - }); - - // The second execution triggered by the finalization waits 1*T for the - // current task to finish (see the timeout below), but then it must not - // wait for the 2*T specified on construction as normal task delay. The - // second execution will finish after the timeout below has passed again, - // for a total of 2*T of wait time. - do_timeout(3*T, () => { timePassed = true; }); - } - - yield promiseTimeout(1*T); - - // Just before finishing, indicate if we completed the second execution. - if (executed) { - do_check_true(deferredTask.isRunning); - executedAgain = true; - } else { - executed = true; - } - }, 2*T); - - deferredTask.arm(); -}); diff --git a/toolkit/modules/tests/xpcshell/test_FileUtils.js b/toolkit/modules/tests/xpcshell/test_FileUtils.js deleted file mode 100644 index 86ac743890..0000000000 --- a/toolkit/modules/tests/xpcshell/test_FileUtils.js +++ /dev/null @@ -1,226 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -Components.utils.import("resource://gre/modules/FileUtils.jsm"); - -function do_check_throws(f, result, stack) { - if (!stack) - stack = Components.stack.caller; - - try { - f(); - } catch (exc) { - if (exc.result == result) - return; - do_throw("expected result " + result + ", caught " + exc, stack); - } - do_throw("expected result " + result + ", none thrown", stack); -} - -const gProfD = do_get_profile(); - -add_test(function test_getFile() { - let file = FileUtils.getFile("ProfD", ["foobar"]); - do_check_true(file instanceof Components.interfaces.nsIFile); - do_check_false(file.exists()); - - let other = gProfD.clone(); - other.append("foobar"); - do_check_true(file.equals(other)); - - run_next_test(); -}); - -add_test(function test_getFile_nonexistentDir() { - do_check_throws(function () { - let file = FileUtils.getFile("NonexistentD", ["foobar"]); - }, Components.results.NS_ERROR_FAILURE); - - run_next_test(); -}); - -add_test(function test_getFile_createDirs() { - let file = FileUtils.getFile("ProfD", ["a", "b", "foobar"]); - do_check_true(file instanceof Components.interfaces.nsIFile); - do_check_false(file.exists()); - - let other = gProfD.clone(); - other.append("a"); - do_check_true(other.isDirectory()); - other.append("b"); - do_check_true(other.isDirectory()); - other.append("foobar"); - do_check_true(file.equals(other)); - - run_next_test(); -}); - -add_test(function test_getDir() { - let dir = FileUtils.getDir("ProfD", ["foodir"]); - do_check_true(dir instanceof Components.interfaces.nsIFile); - do_check_false(dir.exists()); - - let other = gProfD.clone(); - other.append("foodir"); - do_check_true(dir.equals(other)); - - run_next_test(); -}); - -add_test(function test_getDir_nonexistentDir() { - do_check_throws(function () { - let file = FileUtils.getDir("NonexistentD", ["foodir"]); - }, Components.results.NS_ERROR_FAILURE); - - run_next_test(); -}); - -add_test(function test_getDir_shouldCreate() { - let dir = FileUtils.getDir("ProfD", ["c", "d", "foodir"], true); - do_check_true(dir instanceof Components.interfaces.nsIFile); - do_check_true(dir.exists()); - - let other = gProfD.clone(); - other.append("c"); - do_check_true(other.isDirectory()); - other.append("d"); - do_check_true(other.isDirectory()); - other.append("foodir"); - do_check_true(dir.equals(other)); - - run_next_test(); -}); - -var openFileOutputStream_defaultFlags = function (aKind, aFileName) { - let file = FileUtils.getFile("ProfD", [aFileName]); - let fos; - do_check_true(aKind == "atomic" || aKind == "safe" || aKind == ""); - if (aKind == "atomic") { - fos = FileUtils.openAtomicFileOutputStream(file); - } else if (aKind == "safe") { - fos = FileUtils.openSafeFileOutputStream(file); - } else { - fos = FileUtils.openFileOutputStream(file); - } - do_check_true(fos instanceof Components.interfaces.nsIFileOutputStream); - if (aKind == "atomic" || aKind == "safe") { - do_check_true(fos instanceof Components.interfaces.nsISafeOutputStream); - } - - // FileUtils.openFileOutputStream or FileUtils.openAtomicFileOutputStream() - // or FileUtils.openSafeFileOutputStream() opens the stream with DEFER_OPEN - // which means the file will not be open until we write to it. - do_check_false(file.exists()); - - let data = "test_default_flags"; - fos.write(data, data.length); - do_check_true(file.exists()); - - // No nsIXULRuntime in xpcshell, so use this trick to determine whether we're - // on Windows. - if ("@mozilla.org/windows-registry-key;1" in Components.classes) { - do_check_eq(file.permissions, 0o666); - } else { - do_check_eq(file.permissions, FileUtils.PERMS_FILE); - } - - run_next_test(); -}; - -var openFileOutputStream_modeFlags = function(aKind, aFileName) { - let file = FileUtils.getFile("ProfD", [aFileName]); - let fos; - do_check_true(aKind == "atomic" || aKind == "safe" || aKind == ""); - if (aKind == "atomic") { - fos = FileUtils.openAtomicFileOutputStream(file, FileUtils.MODE_WRONLY); - } else if (aKind == "safe") { - fos = FileUtils.openSafeFileOutputStream(file, FileUtils.MODE_WRONLY); - } else { - fos = FileUtils.openFileOutputStream(file, FileUtils.MODE_WRONLY); - } - let data = "test_modeFlags"; - do_check_throws(function () { - fos.write(data, data.length); - }, Components.results.NS_ERROR_FILE_NOT_FOUND); - do_check_false(file.exists()); - - run_next_test(); -}; - -var closeFileOutputStream = function(aKind, aFileName) { - let file = FileUtils.getFile("ProfD", [aFileName]); - let fos; - do_check_true(aKind == "atomic" || aKind == "safe"); - if (aKind == "atomic") { - fos = FileUtils.openAtomicFileOutputStream(file); - } else if (aKind == "safe") { - fos = FileUtils.openSafeFileOutputStream(file); - } - - // We can write data to the stream just fine while it's open. - let data = "testClose"; - fos.write(data, data.length); - - // But once we close it, we can't anymore. - if (aKind == "atomic") { - FileUtils.closeAtomicFileOutputStream(fos); - } else if (aKind == "safe") { - FileUtils.closeSafeFileOutputStream(fos); - } - do_check_throws(function () { - fos.write(data, data.length); - }, Components.results.NS_BASE_STREAM_CLOSED); - run_next_test(); -}; - -add_test(function test_openFileOutputStream_defaultFlags() { - openFileOutputStream_defaultFlags("", "george"); -}); - -// openFileOutputStream will uses MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE -// as the default mode flags, but we can pass in our own if we want to. -add_test(function test_openFileOutputStream_modeFlags() { - openFileOutputStream_modeFlags("", "ringo"); -}); - -add_test(function test_openAtomicFileOutputStream_defaultFlags() { - openFileOutputStream_defaultFlags("atomic", "peiyong"); -}); - -// openAtomicFileOutputStream will uses MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE -// as the default mode flags, but we can pass in our own if we want to. -add_test(function test_openAtomicFileOutputStream_modeFlags() { - openFileOutputStream_modeFlags("atomic", "lin"); -}); - -add_test(function test_closeAtomicFileOutputStream() { - closeFileOutputStream("atomic", "peiyonglin"); -}); - -add_test(function test_openSafeFileOutputStream_defaultFlags() { - openFileOutputStream_defaultFlags("safe", "john"); -}); - -// openSafeFileOutputStream will uses MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE -// as the default mode flags, but we can pass in our own if we want to. -add_test(function test_openSafeFileOutputStream_modeFlags() { - openFileOutputStream_modeFlags("safe", "paul"); -}); - -add_test(function test_closeSafeFileOutputStream() { - closeFileOutputStream("safe", "georgee"); -}); - -add_test(function test_newFile() { - let testfile = FileUtils.getFile("ProfD", ["test"]); - let testpath = testfile.path; - let file = new FileUtils.File(testpath); - do_check_true(file instanceof Components.interfaces.nsILocalFile); - do_check_true(file.equals(testfile)); - do_check_eq(file.path, testpath); - run_next_test(); -}); - -function run_test() { - run_next_test(); -} diff --git a/toolkit/modules/tests/xpcshell/test_FinderIterator.js b/toolkit/modules/tests/xpcshell/test_FinderIterator.js deleted file mode 100644 index 02c923a007..0000000000 --- a/toolkit/modules/tests/xpcshell/test_FinderIterator.js +++ /dev/null @@ -1,265 +0,0 @@ -const { interfaces: Ci, classes: Cc, utils: Cu } = Components; -const { FinderIterator } = Cu.import("resource://gre/modules/FinderIterator.jsm", {}); -Cu.import("resource://gre/modules/Promise.jsm"); - -var gFindResults = []; -// Stub the method that instantiates nsIFind and does all the interaction with -// the docShell to be searched through. -FinderIterator._iterateDocument = function* (word, window, finder) { - for (let range of gFindResults) - yield range; -}; - -FinderIterator._rangeStartsInLink = fakeRange => fakeRange.startsInLink; - -function FakeRange(textContent, startsInLink = false) { - this.startContainer = {}; - this.startsInLink = startsInLink; - this.toString = () => textContent; -} - -var gMockWindow = { - setTimeout(cb, delay) { - Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer) - .initWithCallback(cb, delay, Ci.nsITimer.TYPE_ONE_SHOT); - } -}; - -var gMockFinder = { - _getWindow() { return gMockWindow; } -}; - -function prepareIterator(findText, rangeCount) { - gFindResults = []; - for (let i = rangeCount; --i >= 0;) - gFindResults.push(new FakeRange(findText)); -} - -add_task(function* test_start() { - let findText = "test"; - let rangeCount = 300; - prepareIterator(findText, rangeCount); - - let count = 0; - yield FinderIterator.start({ - caseSensitive: false, - entireWord: false, - finder: gMockFinder, - listener: { - onIteratorRangeFound(range) { - ++count; - Assert.equal(range.toString(), findText, "Text content should match"); - } - }, - word: findText - }); - - Assert.equal(rangeCount, count, "Amount of ranges yielded should match!"); - Assert.ok(!FinderIterator.running, "Running state should match"); - Assert.equal(FinderIterator._previousRanges.length, rangeCount, "Ranges cache should match"); - - FinderIterator.reset(); -}); - -add_task(function* test_valid_arguments() { - let findText = "foo"; - let rangeCount = 20; - prepareIterator(findText, rangeCount); - - let count = 0; - - yield FinderIterator.start({ - caseSensitive: false, - entireWord: false, - finder: gMockFinder, - listener: { onIteratorRangeFound(range) { ++count; } }, - word: findText - }); - - let params = FinderIterator._previousParams; - Assert.ok(!params.linksOnly, "Default for linksOnly is false"); - Assert.ok(!params.useCache, "Default for useCache is false"); - Assert.equal(params.word, findText, "Words should match"); - - count = 0; - Assert.throws(() => FinderIterator.start({ - entireWord: false, - listener: { onIteratorRangeFound(range) { ++count; } }, - word: findText - }), /Missing required option 'caseSensitive'/, "Should throw when missing an argument"); - FinderIterator.reset(); - - Assert.throws(() => FinderIterator.start({ - caseSensitive: false, - listener: { onIteratorRangeFound(range) { ++count; } }, - word: findText - }), /Missing required option 'entireWord'/, "Should throw when missing an argument"); - FinderIterator.reset(); - - Assert.throws(() => FinderIterator.start({ - caseSensitive: false, - entireWord: false, - listener: { onIteratorRangeFound(range) { ++count; } }, - word: findText - }), /Missing required option 'finder'/, "Should throw when missing an argument"); - FinderIterator.reset(); - - Assert.throws(() => FinderIterator.start({ - caseSensitive: true, - entireWord: false, - finder: gMockFinder, - word: findText - }), /Missing valid, required option 'listener'/, "Should throw when missing an argument"); - FinderIterator.reset(); - - Assert.throws(() => FinderIterator.start({ - caseSensitive: false, - entireWord: true, - finder: gMockFinder, - listener: { onIteratorRangeFound(range) { ++count; } }, - }), /Missing required option 'word'/, "Should throw when missing an argument"); - FinderIterator.reset(); - - Assert.equal(count, 0, "No ranges should've been counted"); -}); - -add_task(function* test_stop() { - let findText = "bar"; - let rangeCount = 120; - prepareIterator(findText, rangeCount); - - let count = 0; - let whenDone = FinderIterator.start({ - caseSensitive: false, - entireWord: false, - finder: gMockFinder, - listener: { onIteratorRangeFound(range) { ++count; } }, - word: findText - }); - - FinderIterator.stop(); - - yield whenDone; - - Assert.equal(count, 0, "Number of ranges should be 0"); - - FinderIterator.reset(); -}); - -add_task(function* test_reset() { - let findText = "tik"; - let rangeCount = 142; - prepareIterator(findText, rangeCount); - - let count = 0; - let whenDone = FinderIterator.start({ - caseSensitive: false, - entireWord: false, - finder: gMockFinder, - listener: { onIteratorRangeFound(range) { ++count; } }, - word: findText - }); - - Assert.ok(FinderIterator.running, "Yup, running we are"); - Assert.equal(count, 0, "Number of ranges should match 0"); - Assert.equal(FinderIterator.ranges.length, 0, "Number of ranges should match 0"); - - FinderIterator.reset(); - - Assert.ok(!FinderIterator.running, "Nope, running we are not"); - Assert.equal(FinderIterator.ranges.length, 0, "No ranges after reset"); - Assert.equal(FinderIterator._previousRanges.length, 0, "No ranges after reset"); - - yield whenDone; - - Assert.equal(count, 0, "Number of ranges should match 0"); -}); - -add_task(function* test_parallel_starts() { - let findText = "tak"; - let rangeCount = 2143; - prepareIterator(findText, rangeCount); - - // Start off the iterator. - let count = 0; - let whenDone = FinderIterator.start({ - caseSensitive: false, - entireWord: false, - finder: gMockFinder, - listener: { onIteratorRangeFound(range) { ++count; } }, - word: findText - }); - - yield new Promise(resolve => gMockWindow.setTimeout(resolve, 120)); - Assert.ok(FinderIterator.running, "We ought to be running here"); - - let count2 = 0; - let whenDone2 = FinderIterator.start({ - caseSensitive: false, - entireWord: false, - finder: gMockFinder, - listener: { onIteratorRangeFound(range) { ++count2; } }, - word: findText - }); - - // Let the iterator run for a little while longer before we assert the world. - yield new Promise(resolve => gMockWindow.setTimeout(resolve, 10)); - FinderIterator.stop(); - - Assert.ok(!FinderIterator.running, "Stop means stop"); - - yield whenDone; - yield whenDone2; - - Assert.greater(count, FinderIterator.kIterationSizeMax, "At least one range should've been found"); - Assert.less(count, rangeCount, "Not all ranges should've been found"); - Assert.greater(count2, FinderIterator.kIterationSizeMax, "At least one range should've been found"); - Assert.less(count2, rangeCount, "Not all ranges should've been found"); - - Assert.equal(count2, count, "The second start was later, but should have caught up"); - - FinderIterator.reset(); -}); - -add_task(function* test_allowDistance() { - let findText = "gup"; - let rangeCount = 20; - prepareIterator(findText, rangeCount); - - // Start off the iterator. - let count = 0; - let whenDone = FinderIterator.start({ - caseSensitive: false, - entireWord: false, - finder: gMockFinder, - listener: { onIteratorRangeFound(range) { ++count; } }, - word: findText - }); - - let count2 = 0; - let whenDone2 = FinderIterator.start({ - caseSensitive: false, - entireWord: false, - finder: gMockFinder, - listener: { onIteratorRangeFound(range) { ++count2; } }, - word: "gu" - }); - - let count3 = 0; - let whenDone3 = FinderIterator.start({ - allowDistance: 1, - caseSensitive: false, - entireWord: false, - finder: gMockFinder, - listener: { onIteratorRangeFound(range) { ++count3; } }, - word: "gu" - }); - - yield Promise.all([whenDone, whenDone2, whenDone3]); - - Assert.equal(count, rangeCount, "The first iterator invocation should yield all results"); - Assert.equal(count2, 0, "The second iterator invocation should yield _no_ results"); - Assert.equal(count3, rangeCount, "The first iterator invocation should yield all results"); - - FinderIterator.reset(); -}); diff --git a/toolkit/modules/tests/xpcshell/test_GMPInstallManager.js b/toolkit/modules/tests/xpcshell/test_GMPInstallManager.js deleted file mode 100644 index 74d5ad43d0..0000000000 --- a/toolkit/modules/tests/xpcshell/test_GMPInstallManager.js +++ /dev/null @@ -1,794 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -var {classes: Cc, interfaces: Ci, results: Cr, utils: Cu, manager: Cm} = Components; -const URL_HOST = "http://localhost"; - -var GMPScope = Cu.import("resource://gre/modules/GMPInstallManager.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/FileUtils.jsm"); -Cu.import("resource://testing-common/httpd.js"); -Cu.import("resource://gre/modules/Promise.jsm"); -Cu.import("resource://gre/modules/Preferences.jsm") -Cu.import("resource://gre/modules/UpdateUtils.jsm"); - -var { computeHash } = Cu.import("resource://gre/modules/addons/ProductAddonChecker.jsm"); -var ProductAddonCheckerScope = Cu.import("resource://gre/modules/addons/ProductAddonChecker.jsm"); - -do_get_profile(); - -function run_test() { Cu.import("resource://gre/modules/Preferences.jsm") - Preferences.set("media.gmp.log.dump", true); - Preferences.set("media.gmp.log.level", 0); - run_next_test(); -} - -/** - * Tests that the helper used for preferences works correctly - */ -add_task(function* test_prefs() { - let addon1 = "addon1", addon2 = "addon2"; - - GMPScope.GMPPrefs.set(GMPScope.GMPPrefs.KEY_URL, "http://not-really-used"); - GMPScope.GMPPrefs.set(GMPScope.GMPPrefs.KEY_URL_OVERRIDE, "http://not-really-used-2"); - GMPScope.GMPPrefs.set(GMPScope.GMPPrefs.KEY_PLUGIN_LAST_UPDATE, "1", addon1); - GMPScope.GMPPrefs.set(GMPScope.GMPPrefs.KEY_PLUGIN_VERSION, "2", addon1); - GMPScope.GMPPrefs.set(GMPScope.GMPPrefs.KEY_PLUGIN_LAST_UPDATE, "3", addon2); - GMPScope.GMPPrefs.set(GMPScope.GMPPrefs.KEY_PLUGIN_VERSION, "4", addon2); - GMPScope.GMPPrefs.set(GMPScope.GMPPrefs.KEY_PLUGIN_AUTOUPDATE, false, addon2); - GMPScope.GMPPrefs.set(GMPScope.GMPPrefs.KEY_CERT_CHECKATTRS, true); - - do_check_eq(GMPScope.GMPPrefs.get(GMPScope.GMPPrefs.KEY_URL), "http://not-really-used"); - do_check_eq(GMPScope.GMPPrefs.get(GMPScope.GMPPrefs.KEY_URL_OVERRIDE), - "http://not-really-used-2"); - do_check_eq(GMPScope.GMPPrefs.get(GMPScope.GMPPrefs.KEY_PLUGIN_LAST_UPDATE, "", addon1), "1"); - do_check_eq(GMPScope.GMPPrefs.get(GMPScope.GMPPrefs.KEY_PLUGIN_VERSION, "", addon1), "2"); - do_check_eq(GMPScope.GMPPrefs.get(GMPScope.GMPPrefs.KEY_PLUGIN_LAST_UPDATE, "", addon2), "3"); - do_check_eq(GMPScope.GMPPrefs.get(GMPScope.GMPPrefs.KEY_PLUGIN_VERSION, "", addon2), "4"); - do_check_eq(GMPScope.GMPPrefs.get(GMPScope.GMPPrefs.KEY_PLUGIN_AUTOUPDATE, undefined, addon2), - false); - do_check_true(GMPScope.GMPPrefs.get(GMPScope.GMPPrefs.KEY_CERT_CHECKATTRS)); - GMPScope.GMPPrefs.set(GMPScope.GMPPrefs.KEY_PLUGIN_AUTOUPDATE, true, addon2); -}); - -/** - * Tests that an uninit without a check works fine - */ -add_task(function* test_checkForAddons_uninitWithoutCheck() { - let installManager = new GMPInstallManager(); - installManager.uninit(); -}); - -/** - * Tests that an uninit without an install works fine - */ -add_test(function test_checkForAddons_uninitWithoutInstall() { - overrideXHR(200, ""); - let installManager = new GMPInstallManager(); - let promise = installManager.checkForAddons(); - promise.then(res => { - do_check_true(res.usedFallback); - installManager.uninit(); - run_next_test(); - }); -}); - -/** - * Tests that no response returned rejects - */ -add_test(function test_checkForAddons_noResponse() { - overrideXHR(200, ""); - let installManager = new GMPInstallManager(); - let promise = installManager.checkForAddons(); - promise.then(res => { - do_check_true(res.usedFallback); - installManager.uninit(); - run_next_test(); - }); -}); - -/** - * Tests that no addons element returned resolves with no addons - */ -add_task(function* test_checkForAddons_noAddonsElement() { - overrideXHR(200, "<updates></updates>"); - let installManager = new GMPInstallManager(); - let res = yield installManager.checkForAddons(); - do_check_eq(res.gmpAddons.length, 0); - installManager.uninit(); -}); - -/** - * Tests that empty addons element returned resolves with no addons - */ -add_task(function* test_checkForAddons_emptyAddonsElement() { - overrideXHR(200, "<updates><addons/></updates>"); - let installManager = new GMPInstallManager(); - let res = yield installManager.checkForAddons(); - do_check_eq(res.gmpAddons.length, 0); - installManager.uninit(); -}); - -/** - * Tests that a response with the wrong root element rejects - */ -add_test(function test_checkForAddons_wrongResponseXML() { - overrideXHR(200, "<digits_of_pi>3.141592653589793....</digits_of_pi>"); - let installManager = new GMPInstallManager(); - let promise = installManager.checkForAddons(); - promise.then(res => { - do_check_true(res.usedFallback); - installManager.uninit(); - run_next_test(); - }); -}); - -/** - * Tests that a 404 error works as expected - */ -add_test(function test_checkForAddons_404Error() { - overrideXHR(404, ""); - let installManager = new GMPInstallManager(); - let promise = installManager.checkForAddons(); - promise.then(res => { - do_check_true(res.usedFallback); - installManager.uninit(); - run_next_test(); - }); -}); - -/** - * Tests that a xhr abort() works as expected - */ -add_test(function test_checkForAddons_abort() { - let overriddenXhr = overrideXHR(200, "", { dropRequest: true} ); - let installManager = new GMPInstallManager(); - let promise = installManager.checkForAddons(); - overriddenXhr.abort(); - promise.then(res => { - do_check_true(res.usedFallback); - installManager.uninit(); - run_next_test(); - }); -}); - -/** - * Tests that a defensive timeout works as expected - */ -add_test(function test_checkForAddons_timeout() { - overrideXHR(200, "", { dropRequest: true, timeout: true }); - let installManager = new GMPInstallManager(); - let promise = installManager.checkForAddons(); - promise.then(res => { - do_check_true(res.usedFallback); - installManager.uninit(); - run_next_test(); - }); -}); - -/** - * Tests that we throw correctly in case of ssl certification error. - */ -add_test(function test_checkForAddons_bad_ssl() { - // - // Add random stuff that cause CertUtil to require https. - // - let PREF_KEY_URL_OVERRIDE_BACKUP = - Preferences.get(GMPScope.GMPPrefs.KEY_URL_OVERRIDE, undefined); - Preferences.reset(GMPScope.GMPPrefs.KEY_URL_OVERRIDE); - - let CERTS_BRANCH_DOT_ONE = GMPScope.GMPPrefs.KEY_CERTS_BRANCH + ".1"; - let PREF_CERTS_BRANCH_DOT_ONE_BACKUP = - Preferences.get(CERTS_BRANCH_DOT_ONE, undefined); - Services.prefs.setCharPref(CERTS_BRANCH_DOT_ONE, "funky value"); - - - overrideXHR(200, ""); - let installManager = new GMPInstallManager(); - let promise = installManager.checkForAddons(); - promise.then(res => { - do_check_true(res.usedFallback); - installManager.uninit(); - if (PREF_KEY_URL_OVERRIDE_BACKUP) { - Preferences.set(GMPScope.GMPPrefs.KEY_URL_OVERRIDE, - PREF_KEY_URL_OVERRIDE_BACKUP); - } - if (PREF_CERTS_BRANCH_DOT_ONE_BACKUP) { - Preferences.set(CERTS_BRANCH_DOT_ONE, - PREF_CERTS_BRANCH_DOT_ONE_BACKUP); - } - run_next_test(); - }); -}); - -/** - * Tests that gettinga a funky non XML response works as expected - */ -add_test(function test_checkForAddons_notXML() { - overrideXHR(200, "3.141592653589793...."); - let installManager = new GMPInstallManager(); - let promise = installManager.checkForAddons(); - - promise.then(res => { - do_check_true(res.usedFallback); - installManager.uninit(); - run_next_test(); - }); -}); - -/** - * Tests that getting a response with a single addon works as expected - */ -add_task(function* test_checkForAddons_singleAddon() { - let responseXML = - "<?xml version=\"1.0\"?>" + - "<updates>" + - " <addons>" + - " <addon id=\"gmp-gmpopenh264\"" + - " URL=\"http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip\"" + - " hashFunction=\"sha256\"" + - " hashValue=\"1118b90d6f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee\"" + - " version=\"1.1\"/>" + - " </addons>" + - "</updates>" - overrideXHR(200, responseXML); - let installManager = new GMPInstallManager(); - let res = yield installManager.checkForAddons(); - do_check_eq(res.gmpAddons.length, 1); - let gmpAddon = res.gmpAddons[0]; - do_check_eq(gmpAddon.id, "gmp-gmpopenh264"); - do_check_eq(gmpAddon.URL, "http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip"); - do_check_eq(gmpAddon.hashFunction, "sha256"); - do_check_eq(gmpAddon.hashValue, "1118b90d6f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee"); - do_check_eq(gmpAddon.version, "1.1"); - do_check_eq(gmpAddon.size, undefined); - do_check_true(gmpAddon.isValid); - do_check_false(gmpAddon.isInstalled); - installManager.uninit(); -}); - -/** - * Tests that getting a response with a single addon with the optional size - * attribute parses as expected. - */ -add_task(function* test_checkForAddons_singleAddonWithSize() { - let responseXML = - "<?xml version=\"1.0\"?>" + - "<updates>" + - " <addons>" + - " <addon id=\"openh264-plugin-no-at-symbol\"" + - " URL=\"http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip\"" + - " hashFunction=\"sha256\"" + - " size=\"42\"" + - " hashValue=\"1118b90d6f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee\"" + - " version=\"1.1\"/>" + - " </addons>" + - "</updates>" - overrideXHR(200, responseXML); - let installManager = new GMPInstallManager(); - let res = yield installManager.checkForAddons(); - do_check_eq(res.gmpAddons.length, 1); - let gmpAddon = res.gmpAddons[0]; - do_check_eq(gmpAddon.id, "openh264-plugin-no-at-symbol"); - do_check_eq(gmpAddon.URL, "http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip"); - do_check_eq(gmpAddon.hashFunction, "sha256"); - do_check_eq(gmpAddon.hashValue, "1118b90d6f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee"); - do_check_eq(gmpAddon.size, 42); - do_check_eq(gmpAddon.version, "1.1"); - do_check_true(gmpAddon.isValid); - do_check_false(gmpAddon.isInstalled); - installManager.uninit(); -}); - -/** - * Tests that checking for multiple addons work correctly. - * Also tests that invalid addons work correctly. - */ -add_task(function* test_checkForAddons_multipleAddonNoUpdatesSomeInvalid() { - let responseXML = - "<?xml version=\"1.0\"?>" + - "<updates>" + - " <addons>" + - // valid openh264 - " <addon id=\"gmp-gmpopenh264\"" + - " URL=\"http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip\"" + - " hashFunction=\"sha256\"" + - " hashValue=\"1118b90d6f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee\"" + - " version=\"1.1\"/>" + - // valid not openh264 - " <addon id=\"NOT-gmp-gmpopenh264\"" + - " URL=\"http://127.0.0.1:8011/NOT-gmp-gmpopenh264-1.1.zip\"" + - " hashFunction=\"sha512\"" + - " hashValue=\"141592656f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee\"" + - " version=\"9.1\"/>" + - // noid - " <addon notid=\"NOT-gmp-gmpopenh264\"" + - " URL=\"http://127.0.0.1:8011/NOT-gmp-gmpopenh264-1.1.zip\"" + - " hashFunction=\"sha512\"" + - " hashValue=\"141592656f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee\"" + - " version=\"9.1\"/>" + - // no URL - " <addon id=\"NOT-gmp-gmpopenh264\"" + - " notURL=\"http://127.0.0.1:8011/NOT-gmp-gmpopenh264-1.1.zip\"" + - " hashFunction=\"sha512\"" + - " hashValue=\"141592656f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee\"" + - " version=\"9.1\"/>" + - // no hash function - " <addon id=\"NOT-gmp-gmpopenh264\"" + - " URL=\"http://127.0.0.1:8011/NOT-gmp-gmpopenh264-1.1.zip\"" + - " nothashFunction=\"sha512\"" + - " hashValue=\"141592656f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee\"" + - " version=\"9.1\"/>" + - // no hash function - " <addon id=\"NOT-gmp-gmpopenh264\"" + - " URL=\"http://127.0.0.1:8011/NOT-gmp-gmpopenh264-1.1.zip\"" + - " hashFunction=\"sha512\"" + - " nothashValue=\"141592656f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee\"" + - " version=\"9.1\"/>" + - // not version - " <addon id=\"NOT-gmp-gmpopenh264\"" + - " URL=\"http://127.0.0.1:8011/NOT-gmp-gmpopenh264-1.1.zip\"" + - " hashFunction=\"sha512\"" + - " hashValue=\"141592656f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee\"" + - " notversion=\"9.1\"/>" + - " </addons>" + - "</updates>" - overrideXHR(200, responseXML); - let installManager = new GMPInstallManager(); - let res = yield installManager.checkForAddons(); - do_check_eq(res.gmpAddons.length, 7); - let gmpAddon = res.gmpAddons[0]; - do_check_eq(gmpAddon.id, "gmp-gmpopenh264"); - do_check_eq(gmpAddon.URL, "http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip"); - do_check_eq(gmpAddon.hashFunction, "sha256"); - do_check_eq(gmpAddon.hashValue, "1118b90d6f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee"); - do_check_eq(gmpAddon.version, "1.1"); - do_check_true(gmpAddon.isValid); - do_check_false(gmpAddon.isInstalled); - - gmpAddon = res.gmpAddons[1]; - do_check_eq(gmpAddon.id, "NOT-gmp-gmpopenh264"); - do_check_eq(gmpAddon.URL, "http://127.0.0.1:8011/NOT-gmp-gmpopenh264-1.1.zip"); - do_check_eq(gmpAddon.hashFunction, "sha512"); - do_check_eq(gmpAddon.hashValue, "141592656f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee"); - do_check_eq(gmpAddon.version, "9.1"); - do_check_true(gmpAddon.isValid); - do_check_false(gmpAddon.isInstalled); - - for (let i = 2; i < res.gmpAddons.length; i++) { - do_check_false(res.gmpAddons[i].isValid); - do_check_false(res.gmpAddons[i].isInstalled); - } - installManager.uninit(); -}); - -/** - * Tests that checking for addons when there are also updates available - * works as expected. - */ -add_task(function* test_checkForAddons_updatesWithAddons() { - let responseXML = - "<?xml version=\"1.0\"?>" + - " <updates>" + - " <update type=\"minor\" displayVersion=\"33.0a1\" appVersion=\"33.0a1\" platformVersion=\"33.0a1\" buildID=\"20140628030201\">" + - " <patch type=\"complete\" URL=\"http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/2014/06/2014-06-28-03-02-01-mozilla-central/firefox-33.0a1.en-US.mac.complete.mar\" hashFunction=\"sha512\" hashValue=\"f3f90d71dff03ae81def80e64bba3e4569da99c9e15269f731c2b167c4fc30b3aed9f5fee81c19614120230ca333e73a5e7def1b8e45d03135b2069c26736219\" size=\"85249896\"/>" + - " </update>" + - " <addons>" + - " <addon id=\"gmp-gmpopenh264\"" + - " URL=\"http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip\"" + - " hashFunction=\"sha256\"" + - " hashValue=\"1118b90d6f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee\"" + - " version=\"1.1\"/>" + - " </addons>" + - "</updates>" - overrideXHR(200, responseXML); - let installManager = new GMPInstallManager(); - let res = yield installManager.checkForAddons(); - do_check_eq(res.gmpAddons.length, 1); - let gmpAddon = res.gmpAddons[0]; - do_check_eq(gmpAddon.id, "gmp-gmpopenh264"); - do_check_eq(gmpAddon.URL, "http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip"); - do_check_eq(gmpAddon.hashFunction, "sha256"); - do_check_eq(gmpAddon.hashValue, "1118b90d6f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee"); - do_check_eq(gmpAddon.version, "1.1"); - do_check_true(gmpAddon.isValid); - do_check_false(gmpAddon.isInstalled); - installManager.uninit(); -}); - -/** - * Tests that installing found addons works as expected - */ -function* test_checkForAddons_installAddon(id, includeSize, wantInstallReject) { - do_print("Running installAddon for id: " + id + - ", includeSize: " + includeSize + - " and wantInstallReject: " + wantInstallReject); - let httpServer = new HttpServer(); - let dir = FileUtils.getDir("TmpD", [], true); - httpServer.registerDirectory("/", dir); - httpServer.start(-1); - let testserverPort = httpServer.identity.primaryPort; - let zipFileName = "test_" + id + "_GMP.zip"; - - let zipURL = URL_HOST + ":" + testserverPort + "/" + zipFileName; - do_print("zipURL: " + zipURL); - - let data = "e~=0.5772156649"; - let zipFile = createNewZipFile(zipFileName, data); - let hashFunc = "sha256"; - let expectedDigest = yield computeHash(hashFunc, zipFile.path); - let fileSize = zipFile.fileSize; - if (wantInstallReject) { - fileSize = 1; - } - - let responseXML = - "<?xml version=\"1.0\"?>" + - "<updates>" + - " <addons>" + - " <addon id=\"" + id + "-gmp-gmpopenh264\"" + - " URL=\"" + zipURL + "\"" + - " hashFunction=\"" + hashFunc + "\"" + - " hashValue=\"" + expectedDigest + "\"" + - (includeSize ? " size=\"" + fileSize + "\"" : "") + - " version=\"1.1\"/>" + - " </addons>" + - "</updates>" - - overrideXHR(200, responseXML); - let installManager = new GMPInstallManager(); - let res = yield installManager.checkForAddons(); - do_check_eq(res.gmpAddons.length, 1); - let gmpAddon = res.gmpAddons[0]; - do_check_false(gmpAddon.isInstalled); - - try { - let extractedPaths = yield installManager.installAddon(gmpAddon); - if (wantInstallReject) { - do_check_true(false); // installAddon() should have thrown. - } - do_check_eq(extractedPaths.length, 1); - let extractedPath = extractedPaths[0]; - - do_print("Extracted path: " + extractedPath); - - let extractedFile = Cc["@mozilla.org/file/local;1"]. - createInstance(Ci.nsIFile); - extractedFile.initWithPath(extractedPath); - do_check_true(extractedFile.exists()); - let readData = readStringFromFile(extractedFile); - do_check_eq(readData, data); - - // Make sure the prefs are set correctly - do_check_true(!!GMPScope.GMPPrefs.get( - GMPScope.GMPPrefs.KEY_PLUGIN_LAST_UPDATE, "", gmpAddon.id)); - do_check_eq(GMPScope.GMPPrefs.get(GMPScope.GMPPrefs.KEY_PLUGIN_VERSION, "", - gmpAddon.id), - "1.1"); - do_check_eq(GMPScope.GMPPrefs.get(GMPScope.GMPPrefs.KEY_PLUGIN_ABI, "", - gmpAddon.id), - UpdateUtils.ABI); - // Make sure it reports as being installed - do_check_true(gmpAddon.isInstalled); - - // Cleanup - extractedFile.parent.remove(true); - zipFile.remove(false); - httpServer.stop(function() {}); - installManager.uninit(); - } catch (ex) { - zipFile.remove(false); - if (!wantInstallReject) { - do_throw("install update should not reject " + ex.message); - } - } -} - -add_task(test_checkForAddons_installAddon.bind(null, "1", true, false)); -add_task(test_checkForAddons_installAddon.bind(null, "2", false, false)); -add_task(test_checkForAddons_installAddon.bind(null, "3", true, true)); - -/** - * Tests simpleCheckAndInstall when autoupdate is disabled for a GMP - */ -add_task(function* test_simpleCheckAndInstall_autoUpdateDisabled() { - GMPScope.GMPPrefs.set(GMPScope.GMPPrefs.KEY_PLUGIN_AUTOUPDATE, false, GMPScope.OPEN_H264_ID); - let responseXML = - "<?xml version=\"1.0\"?>" + - "<updates>" + - " <addons>" + - // valid openh264 - " <addon id=\"gmp-gmpopenh264\"" + - " URL=\"http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip\"" + - " hashFunction=\"sha256\"" + - " hashValue=\"1118b90d6f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee\"" + - " version=\"1.1\"/>" + - " </addons>" + - "</updates>" - - overrideXHR(200, responseXML); - let installManager = new GMPInstallManager(); - let result = yield installManager.simpleCheckAndInstall(); - do_check_eq(result.status, "nothing-new-to-install"); - Preferences.reset(GMPScope.GMPPrefs.KEY_UPDATE_LAST_CHECK); - GMPScope.GMPPrefs.set(GMPScope.GMPPrefs.KEY_PLUGIN_AUTOUPDATE, true, GMPScope.OPEN_H264_ID); -}); - -/** - * Tests simpleCheckAndInstall nothing to install - */ -add_task(function* test_simpleCheckAndInstall_nothingToInstall() { - let responseXML = - "<?xml version=\"1.0\"?>" + - "<updates>" + - "</updates>" - - overrideXHR(200, responseXML); - let installManager = new GMPInstallManager(); - let result = yield installManager.simpleCheckAndInstall(); - do_check_eq(result.status, "nothing-new-to-install"); -}); - -/** - * Tests simpleCheckAndInstall too frequent - */ -add_task(function* test_simpleCheckAndInstall_tooFrequent() { - let responseXML = - "<?xml version=\"1.0\"?>" + - "<updates>" + - "</updates>" - - overrideXHR(200, responseXML); - let installManager = new GMPInstallManager(); - let result = yield installManager.simpleCheckAndInstall(); - do_check_eq(result.status, "too-frequent-no-check"); -}); - -/** - * Tests that installing addons when there is no server works as expected - */ -add_test(function test_installAddon_noServer() { - let dir = FileUtils.getDir("TmpD", [], true); - let zipFileName = "test_GMP.zip"; - let zipURL = URL_HOST + ":0/" + zipFileName; - - let data = "e~=0.5772156649"; - let zipFile = createNewZipFile(zipFileName, data); - - let responseXML = - "<?xml version=\"1.0\"?>" + - "<updates>" + - " <addons>" + - " <addon id=\"gmp-gmpopenh264\"" + - " URL=\"" + zipURL + "\"" + - " hashFunction=\"sha256\"" + - " hashValue=\"11221cbda000347b054028b527a60e578f919cb10f322ef8077d3491c6fcb474\"" + - " version=\"1.1\"/>" + - " </addons>" + - "</updates>" - - overrideXHR(200, responseXML); - let installManager = new GMPInstallManager(); - let checkPromise = installManager.checkForAddons(); - checkPromise.then(res => { - do_check_eq(res.gmpAddons.length, 1); - let gmpAddon = res.gmpAddons[0]; - - GMPInstallManager.overrideLeaveDownloadedZip = true; - let installPromise = installManager.installAddon(gmpAddon); - installPromise.then(extractedPaths => { - do_throw("No server for install should reject"); - }, err => { - do_check_true(!!err); - installManager.uninit(); - run_next_test(); - }); - }, () => { - do_throw("check should not reject for install no server"); - }); -}); - -/** - * Returns the read stream into a string - */ -function readStringFromInputStream(inputStream) { - let sis = Cc["@mozilla.org/scriptableinputstream;1"]. - createInstance(Ci.nsIScriptableInputStream); - sis.init(inputStream); - let text = sis.read(sis.available()); - sis.close(); - return text; -} - -/** - * Reads a string of text from a file. - * This function only works with ASCII text. - */ -function readStringFromFile(file) { - if (!file.exists()) { - do_print("readStringFromFile - file doesn't exist: " + file.path); - return null; - } - let fis = Cc["@mozilla.org/network/file-input-stream;1"]. - createInstance(Ci.nsIFileInputStream); - fis.init(file, FileUtils.MODE_RDONLY, FileUtils.PERMS_FILE, 0); - return readStringFromInputStream(fis); -} - -/** - * Bare bones XMLHttpRequest implementation for testing onprogress, onerror, - * and onload nsIDomEventListener handleEvent. - */ -function makeHandler(aVal) { - if (typeof aVal == "function") - return { handleEvent: aVal }; - return aVal; -} -/** - * Constructs a mock xhr which is used for testing different aspects - * of responses. - */ -function xhr(inputStatus, inputResponse, options) { - this.inputStatus = inputStatus; - this.inputResponse = inputResponse; - this.status = 0; - this.responseXML = null; - this._aborted = false; - this._onabort = null; - this._onprogress = null; - this._onerror = null; - this._onload = null; - this._onloadend = null; - this._ontimeout = null; - this._url = null; - this._method = null; - this._timeout = 0; - this._notified = false; - this._options = options || {}; -} -xhr.prototype = { - overrideMimeType: function(aMimetype) { }, - setRequestHeader: function(aHeader, aValue) { }, - status: null, - channel: { set notificationCallbacks(aVal) { } }, - open: function(aMethod, aUrl) { - this.channel.originalURI = Services.io.newURI(aUrl, null, null); - this._method = aMethod; this._url = aUrl; - }, - abort: function() { - this._dropRequest = true; - this._notify(["abort", "loadend"]); - }, - responseXML: null, - responseText: null, - send: function(aBody) { - do_execute_soon(function() { - try { - if (this._options.dropRequest) { - if (this._timeout > 0 && this._options.timeout) { - this._notify(["timeout", "loadend"]); - } - return; - } - this.status = this.inputStatus; - this.responseText = this.inputResponse; - try { - let parser = Cc["@mozilla.org/xmlextras/domparser;1"]. - createInstance(Ci.nsIDOMParser); - this.responseXML = parser.parseFromString(this.inputResponse, - "application/xml"); - } catch (e) { - this.responseXML = null; - } - if (this.inputStatus === 200) { - this._notify(["load", "loadend"]); - } else { - this._notify(["error", "loadend"]); - } - } catch (ex) { - do_throw(ex); - } - }.bind(this)); - }, - set onabort(aValue) { this._onabort = makeHandler(aValue); }, - get onabort() { return this._onabort; }, - set onprogress(aValue) { this._onprogress = makeHandler(aValue); }, - get onprogress() { return this._onprogress; }, - set onerror(aValue) { this._onerror = makeHandler(aValue); }, - get onerror() { return this._onerror; }, - set onload(aValue) { this._onload = makeHandler(aValue); }, - get onload() { return this._onload; }, - set onloadend(aValue) { this._onloadend = makeHandler(aValue); }, - get onloadend() { return this._onloadend; }, - set ontimeout(aValue) { this._ontimeout = makeHandler(aValue); }, - get ontimeout() { return this._ontimeout; }, - set timeout(aValue) { this._timeout = aValue; }, - _notify: function(events) { - if (this._notified) { - return; - } - this._notified = true; - for (let item of events) { - let k = "on" + item; - if (this[k]) { - do_print("Notifying " + item); - let e = { - target: this, - type: item, - }; - this[k](e); - } else { - do_print("Notifying " + item + ", but there are no listeners"); - } - } - }, - addEventListener: function(aEvent, aValue, aCapturing) { - eval("this._on" + aEvent + " = aValue"); - }, - flags: Ci.nsIClassInfo.SINGLETON, - getScriptableHelper: () => null, - getInterfaces: function(aCount) { - let interfaces = [Ci.nsISupports]; - aCount.value = interfaces.length; - return interfaces; - }, - classDescription: "XMLHttpRequest", - contractID: "@mozilla.org/xmlextras/xmlhttprequest;1", - classID: Components.ID("{c9b37f43-4278-4304-a5e0-600991ab08cb}"), - createInstance: function(aOuter, aIID) { - if (aOuter == null) - return this.QueryInterface(aIID); - throw Cr.NS_ERROR_NO_AGGREGATION; - }, - QueryInterface: function(aIID) { - if (aIID.equals(Ci.nsIClassInfo) || - aIID.equals(Ci.nsISupports)) - return this; - throw Cr.NS_ERROR_NO_INTERFACE; - }, - get wrappedJSObject() { return this; } -}; - -/** - * Helper used to overrideXHR requests (no matter to what URL) with the - * specified status and response. - * @param status The status you want to get back when an XHR request is made - * @param response The response you want to get back when an XHR request is made - */ -function overrideXHR(status, response, options) { - overrideXHR.myxhr = new xhr(status, response, options); - ProductAddonCheckerScope.CreateXHR = function() { - return overrideXHR.myxhr; - }; - return overrideXHR.myxhr; -} - -/** - * Creates a new zip file containing a file with the specified data - * @param zipName The name of the zip file - * @param data The data to go inside the zip for the filename entry1.info - */ -function createNewZipFile(zipName, data) { - // Create a zip file which will be used for extracting - let stream = Cc["@mozilla.org/io/string-input-stream;1"]. - createInstance(Ci.nsIStringInputStream); - stream.setData(data, data.length); - let zipWriter = Cc["@mozilla.org/zipwriter;1"]. - createInstance(Components.interfaces.nsIZipWriter); - let zipFile = FileUtils.getFile("TmpD", [zipName]); - if (zipFile.exists()) { - zipFile.remove(false); - } - // From prio.h - const PR_RDWR = 0x04; - const PR_CREATE_FILE = 0x08; - const PR_TRUNCATE = 0x20; - zipWriter.open(zipFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); - zipWriter.addEntryStream("entry1.info", Date.now(), - Ci.nsIZipWriter.COMPRESSION_BEST, stream, false); - zipWriter.close(); - stream.close(); - do_print("zip file created on disk at: " + zipFile.path); - return zipFile; -} diff --git a/toolkit/modules/tests/xpcshell/test_Http.js b/toolkit/modules/tests/xpcshell/test_Http.js deleted file mode 100644 index 3dfd769b71..0000000000 --- a/toolkit/modules/tests/xpcshell/test_Http.js +++ /dev/null @@ -1,257 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -Components.utils.import("resource://gre/modules/Http.jsm"); -Components.utils.import("resource://testing-common/httpd.js"); - -const BinaryInputStream = Components.Constructor("@mozilla.org/binaryinputstream;1", - "nsIBinaryInputStream", "setInputStream"); - -var server; - -const kDefaultServerPort = 9000; -const kSuccessPath = "/success"; -const kBaseUrl = "http://localhost:" + kDefaultServerPort; -const kSuccessUrl = kBaseUrl + kSuccessPath; - -const kPostPath = "/post"; -const kPostUrl = kBaseUrl + kPostPath; -const kPostDataSent = [["foo", "bar"], ["complex", "!*()@"]]; -const kPostDataReceived = "foo=bar&complex=%21%2A%28%29%40"; -const kPostMimeTypeReceived = "application/x-www-form-urlencoded; charset=utf-8"; - -const kJsonPostPath = "/json_post"; -const kJsonPostUrl = kBaseUrl + kJsonPostPath; -const kJsonPostData = JSON.stringify(kPostDataSent); -const kJsonPostMimeType = "application/json"; - -const kPutPath = "/put"; -const kPutUrl = kBaseUrl + kPutPath; -const kPutDataSent = [["P", "NP"]]; -const kPutDataReceived = "P=NP"; - -const kGetPath = "/get"; -const kGetUrl = kBaseUrl + kGetPath; - -function successResult(aRequest, aResponse) { - aResponse.setStatusLine(null, 200, "OK"); - aResponse.setHeader("Content-Type", "application/json"); - aResponse.write("Success!"); -} - -function getDataChecker(aExpectedMethod, aExpectedData, aExpectedMimeType = null) { - return function(aRequest, aResponse) { - let body = new BinaryInputStream(aRequest.bodyInputStream); - let bytes = []; - let avail; - while ((avail = body.available()) > 0) - Array.prototype.push.apply(bytes, body.readByteArray(avail)); - - do_check_eq(aRequest.method, aExpectedMethod); - - // Checking if the Content-Type is as expected. - if (aExpectedMimeType) { - let contentType = aRequest.getHeader("Content-Type"); - do_check_eq(contentType, aExpectedMimeType); - } - - var data = String.fromCharCode.apply(null, bytes); - - do_check_eq(data, aExpectedData); - - aResponse.setStatusLine(null, 200, "OK"); - aResponse.setHeader("Content-Type", "application/json"); - aResponse.write("Success!"); - } -} - -add_test(function test_successCallback() { - do_test_pending(); - let options = { - onLoad: function(aResponse) { - do_check_eq(aResponse, "Success!"); - do_test_finished(); - run_next_test(); - }, - onError: function(e) { - do_check_true(false); - do_test_finished(); - run_next_test(); - } - } - httpRequest(kSuccessUrl, options); -}); - -add_test(function test_errorCallback() { - do_test_pending(); - let options = { - onSuccess: function(aResponse) { - do_check_true(false); - do_test_finished(); - run_next_test(); - }, - onError: function(e, aResponse) { - do_check_eq(e, "404 - Not Found"); - do_test_finished(); - run_next_test(); - } - } - httpRequest(kBaseUrl + "/failure", options); -}); - -add_test(function test_PostData() { - do_test_pending(); - let options = { - onLoad: function(aResponse) { - do_check_eq(aResponse, "Success!"); - do_test_finished(); - run_next_test(); - }, - onError: function(e) { - do_check_true(false); - do_test_finished(); - run_next_test(); - }, - postData: kPostDataSent - } - httpRequest(kPostUrl, options); -}); - -add_test(function test_PutData() { - do_test_pending(); - let options = { - method: "PUT", - onLoad: function(aResponse) { - do_check_eq(aResponse, "Success!"); - do_test_finished(); - run_next_test(); - }, - onError: function(e) { - do_check_true(false); - do_test_finished(); - run_next_test(); - }, - postData: kPutDataSent - } - httpRequest(kPutUrl, options); -}); - -add_test(function test_GetData() { - do_test_pending(); - let options = { - onLoad: function(aResponse) { - do_check_eq(aResponse, "Success!"); - do_test_finished(); - run_next_test(); - }, - onError: function(e) { - do_check_true(false); - do_test_finished(); - run_next_test(); - }, - postData: null - } - httpRequest(kGetUrl, options); -}); - -add_test(function test_OptionalParameters() { - let options = { - onLoad: null, - onError: null, - logger: null - }; - // Just make sure that nothing throws when doing this (i.e. httpRequest - // doesn't try to access null options). - httpRequest(kGetUrl, options); - run_next_test(); -}); - -/** - * Makes sure that httpRequest API allows setting a custom Content-Type header - * for POST requests when data is a string. - */ -add_test(function test_CustomContentTypeOnPost() { - do_test_pending(); - - // Preparing the request parameters. - let options = { - onLoad: function(aResponse) { - do_check_eq(aResponse, "Success!"); - do_test_finished(); - run_next_test(); - }, - onError: function(e) { - do_check_true(false); - do_test_finished(); - run_next_test(); - }, - postData: kJsonPostData, - // Setting a custom Content-Type header. - headers: [['Content-Type', "application/json"]] - } - - // Firing the request. - httpRequest(kJsonPostUrl, options); -}); - -/** - * Ensures that the httpRequest API provides a way to override the response - * MIME type. - */ -add_test(function test_OverrideMimeType() { - do_test_pending(); - - // Preparing the request parameters. - const kMimeType = 'text/xml; charset=UTF-8'; - let options = { - onLoad: function(aResponse, xhr) { - do_check_eq(aResponse, "Success!"); - - // Set the expected MIME-type. - let reportedMimeType = xhr.getResponseHeader("Content-Type"); - do_check_neq(reportedMimeType, kMimeType); - - // responseXML should not be not null if overriding mime type succeeded. - do_check_true(xhr.responseXML != null); - - do_test_finished(); - run_next_test(); - }, - onError: function(e) { - do_check_true(false); - do_test_finished(); - run_next_test(); - } - }; - - // Firing the request. - let xhr = httpRequest(kGetUrl, options); - - // Override the response MIME type. - xhr.overrideMimeType(kMimeType); -}); - -function run_test() { - // Set up a mock HTTP server to serve a success page. - server = new HttpServer(); - server.registerPathHandler(kSuccessPath, successResult); - server.registerPathHandler(kPostPath, - getDataChecker("POST", kPostDataReceived, - kPostMimeTypeReceived)); - server.registerPathHandler(kPutPath, - getDataChecker("PUT", kPutDataReceived)); - server.registerPathHandler(kGetPath, getDataChecker("GET", "")); - server.registerPathHandler(kJsonPostPath, - getDataChecker("POST", kJsonPostData, - kJsonPostMimeType)); - - server.start(kDefaultServerPort); - - run_next_test(); - - // Teardown. - do_register_cleanup(function() { - server.stop(function() { }); - }); -} - diff --git a/toolkit/modules/tests/xpcshell/test_Integration.js b/toolkit/modules/tests/xpcshell/test_Integration.js deleted file mode 100644 index 808e2d34fb..0000000000 --- a/toolkit/modules/tests/xpcshell/test_Integration.js +++ /dev/null @@ -1,238 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/* - * Tests the Integration.jsm module. - */ - -"use strict"; - -const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; - -Cu.import("resource://gre/modules/Integration.jsm", this); -Cu.import("resource://gre/modules/Services.jsm", this); -Cu.import("resource://gre/modules/Task.jsm", this); - -const TestIntegration = { - value: "value", - - get valueFromThis() { - return this.value; - }, - - get property() { - return this._property; - }, - - set property(value) { - this._property = value; - }, - - method(argument) { - this.methodArgument = argument; - return "method" + argument; - }, - - asyncMethod: Task.async(function* (argument) { - this.asyncMethodArgument = argument; - return "asyncMethod" + argument; - }), -}; - -let overrideFn = base => ({ - value: "overridden-value", - - get property() { - return "overridden-" + base.__lookupGetter__("property").call(this); - }, - - set property(value) { - base.__lookupSetter__("property").call(this, "overridden-" + value); - }, - - method() { - return "overridden-" + base.method.apply(this, arguments); - }, - - asyncMethod: Task.async(function* () { - return "overridden-" + (yield base.asyncMethod.apply(this, arguments)); - }), -}); - -let superOverrideFn = base => ({ - __proto__: base, - - value: "overridden-value", - - get property() { - return "overridden-" + super.property; - }, - - set property(value) { - super.property = "overridden-" + value; - }, - - method() { - return "overridden-" + super.method(...arguments); - }, - - asyncMethod: Task.async(function* () { - // We cannot use the "super" keyword in methods defined using "Task.async". - return "overridden-" + (yield base.asyncMethod.apply(this, arguments)); - }), -}); - -/** - * Fails the test if the results of method invocations on the combined object - * don't match the expected results based on how many overrides are registered. - * - * @param combined - * The combined object based on the TestIntegration root. - * @param overridesCount - * Zero if the root object is not overridden, or a higher value to test - * the presence of one or more integration overrides. - */ -function* assertCombinedResults(combined, overridesCount) { - let expectedValue = overridesCount > 0 ? "overridden-value" : "value"; - let prefix = "overridden-".repeat(overridesCount); - - Assert.equal(combined.value, expectedValue); - Assert.equal(combined.valueFromThis, expectedValue); - - combined.property = "property"; - Assert.equal(combined.property, prefix.repeat(2) + "property"); - - combined.methodArgument = ""; - Assert.equal(combined.method("-argument"), prefix + "method-argument"); - Assert.equal(combined.methodArgument, "-argument"); - - combined.asyncMethodArgument = ""; - Assert.equal(yield combined.asyncMethod("-argument"), - prefix + "asyncMethod-argument"); - Assert.equal(combined.asyncMethodArgument, "-argument"); -} - -/** - * Fails the test if the results of method invocations on the combined object - * for the "testModule" integration point don't match the expected results based - * on how many overrides are registered. - * - * @param overridesCount - * Zero if the root object is not overridden, or a higher value to test - * the presence of one or more integration overrides. - */ -function* assertCurrentCombinedResults(overridesCount) { - let combined = Integration.testModule.getCombined(TestIntegration); - yield assertCombinedResults(combined, overridesCount); -} - -/** - * Checks the initial state with no integration override functions registered. - */ -add_task(function* test_base() { - yield assertCurrentCombinedResults(0); -}); - -/** - * Registers and unregisters an integration override function. - */ -add_task(function* test_override() { - Integration.testModule.register(overrideFn); - yield assertCurrentCombinedResults(1); - - // Registering the same function more than once has no effect. - Integration.testModule.register(overrideFn); - yield assertCurrentCombinedResults(1); - - Integration.testModule.unregister(overrideFn); - yield assertCurrentCombinedResults(0); -}); - -/** - * Registers and unregisters more than one integration override function, of - * which one uses the prototype and the "super" keyword to access the base. - */ -add_task(function* test_override_super_multiple() { - Integration.testModule.register(overrideFn); - Integration.testModule.register(superOverrideFn); - yield assertCurrentCombinedResults(2); - - Integration.testModule.unregister(overrideFn); - yield assertCurrentCombinedResults(1); - - Integration.testModule.unregister(superOverrideFn); - yield assertCurrentCombinedResults(0); -}); - -/** - * Registers an integration override function that throws an exception, and - * ensures that this does not block other functions from being registered. - */ -add_task(function* test_override_error() { - let errorOverrideFn = base => { throw "Expected error." }; - - Integration.testModule.register(errorOverrideFn); - Integration.testModule.register(overrideFn); - yield assertCurrentCombinedResults(1); - - Integration.testModule.unregister(errorOverrideFn); - Integration.testModule.unregister(overrideFn); - yield assertCurrentCombinedResults(0); -}); - -/** - * Checks that state saved using the "this" reference is preserved as a shallow - * copy when registering new integration override functions. - */ -add_task(function* test_state_preserved() { - let valueObject = { toString: () => "toString" }; - - let combined = Integration.testModule.getCombined(TestIntegration); - combined.property = valueObject; - Assert.ok(combined.property === valueObject); - - Integration.testModule.register(overrideFn); - combined = Integration.testModule.getCombined(TestIntegration); - Assert.equal(combined.property, "overridden-toString"); - - Integration.testModule.unregister(overrideFn); - combined = Integration.testModule.getCombined(TestIntegration); - Assert.ok(combined.property === valueObject); -}); - -/** - * Checks that the combined integration objects cannot be used with XPCOM. - * - * This is limited by the fact that interfaces with the "[function]" annotation, - * for example nsIObserver, do not call the QueryInterface implementation. - */ -add_task(function* test_xpcom_throws() { - let combined = Integration.testModule.getCombined(TestIntegration); - - // This calls QueryInterface because it looks for nsISupportsWeakReference. - Assert.throws(() => Services.obs.addObserver(combined, "test-topic", true), - "NS_NOINTERFACE"); -}); - -/** - * Checks that getters defined by defineModuleGetter are able to retrieve the - * latest version of the combined integration object. - */ -add_task(function* test_defineModuleGetter() { - let objectForGetters = {}; - - // Test with and without the optional "symbol" parameter. - Integration.testModule.defineModuleGetter(objectForGetters, - "TestIntegration", "resource://testing-common/TestIntegration.jsm"); - Integration.testModule.defineModuleGetter(objectForGetters, - "integration", "resource://testing-common/TestIntegration.jsm", - "TestIntegration"); - - Integration.testModule.register(overrideFn); - yield assertCombinedResults(objectForGetters.integration, 1); - yield assertCombinedResults(objectForGetters.TestIntegration, 1); - - Integration.testModule.unregister(overrideFn); - yield assertCombinedResults(objectForGetters.integration, 0); - yield assertCombinedResults(objectForGetters.TestIntegration, 0); -}); diff --git a/toolkit/modules/tests/xpcshell/test_JSONFile.js b/toolkit/modules/tests/xpcshell/test_JSONFile.js deleted file mode 100644 index 77e8c55b92..0000000000 --- a/toolkit/modules/tests/xpcshell/test_JSONFile.js +++ /dev/null @@ -1,242 +0,0 @@ -/** - * Tests the JSONFile object. - */ - -"use strict"; - -// Globals - -const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "DownloadPaths", - "resource://gre/modules/DownloadPaths.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", - "resource://gre/modules/FileUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "OS", - "resource://gre/modules/osfile.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "JSONFile", - "resource://gre/modules/JSONFile.jsm"); - -let gFileCounter = Math.floor(Math.random() * 1000000); - -/** - * Returns a reference to a temporary file, that is guaranteed not to exist, and - * to have never been created before. - * - * @param aLeafName - * Suggested leaf name for the file to be created. - * - * @return nsIFile pointing to a non-existent file in a temporary directory. - * - * @note It is not enough to delete the file if it exists, or to delete the file - * after calling nsIFile.createUnique, because on Windows the delete - * operation in the file system may still be pending, preventing a new - * file with the same name to be created. - */ -function getTempFile(aLeafName) -{ - // Prepend a serial number to the extension in the suggested leaf name. - let [base, ext] = DownloadPaths.splitBaseNameAndExtension(aLeafName); - let leafName = base + "-" + gFileCounter + ext; - gFileCounter++; - - // Get a file reference under the temporary directory for this test file. - let file = FileUtils.getFile("TmpD", [leafName]); - do_check_false(file.exists()); - - do_register_cleanup(function () { - if (file.exists()) { - file.remove(false); - } - }); - - return file; -} - -const TEST_STORE_FILE_NAME = "test-store.json"; - -const TEST_DATA = { - number: 123, - string: "test", - object: { - prop1: 1, - prop2: 2, - }, -}; - -// Tests - -add_task(function* test_save_reload() -{ - let storeForSave = new JSONFile({ - path: getTempFile(TEST_STORE_FILE_NAME).path, - }); - - yield storeForSave.load(); - - do_check_true(storeForSave.dataReady); - do_check_matches(storeForSave.data, {}); - - Object.assign(storeForSave.data, TEST_DATA); - - yield new Promise((resolve) => { - let save = storeForSave._save.bind(storeForSave); - storeForSave._save = () => { - save(); - resolve(); - }; - storeForSave.saveSoon(); - }); - - let storeForLoad = new JSONFile({ - path: storeForSave.path, - }); - - yield storeForLoad.load(); - - Assert.deepEqual(storeForLoad.data, TEST_DATA); -}); - -add_task(function* test_load_sync() -{ - let storeForSave = new JSONFile({ - path: getTempFile(TEST_STORE_FILE_NAME).path - }); - yield storeForSave.load(); - Object.assign(storeForSave.data, TEST_DATA); - yield storeForSave._save(); - - let storeForLoad = new JSONFile({ - path: storeForSave.path, - }); - storeForLoad.ensureDataReady(); - - Assert.deepEqual(storeForLoad.data, TEST_DATA); -}); - -add_task(function* test_load_with_dataPostProcessor() -{ - let storeForSave = new JSONFile({ - path: getTempFile(TEST_STORE_FILE_NAME).path - }); - yield storeForSave.load(); - Object.assign(storeForSave.data, TEST_DATA); - yield storeForSave._save(); - - let random = Math.random(); - let storeForLoad = new JSONFile({ - path: storeForSave.path, - dataPostProcessor: (data) => { - Assert.deepEqual(data, TEST_DATA); - - data.test = random; - return data; - }, - }); - - yield storeForLoad.load(); - - do_check_eq(storeForLoad.data.test, random); -}); - -add_task(function* test_load_with_dataPostProcessor_fails() -{ - let store = new JSONFile({ - path: getTempFile(TEST_STORE_FILE_NAME).path, - dataPostProcessor: () => { - throw new Error("dataPostProcessor fails."); - }, - }); - - yield Assert.rejects(store.load(), /dataPostProcessor fails\./); - - do_check_false(store.dataReady); -}); - -add_task(function* test_load_sync_with_dataPostProcessor_fails() -{ - let store = new JSONFile({ - path: getTempFile(TEST_STORE_FILE_NAME).path, - dataPostProcessor: () => { - throw new Error("dataPostProcessor fails."); - }, - }); - - Assert.throws(() => store.ensureDataReady(), /dataPostProcessor fails\./); - - do_check_false(store.dataReady); -}); - -/** - * Loads data from a string in a predefined format. The purpose of this test is - * to verify that the JSON format used in previous versions can be loaded. - */ -add_task(function* test_load_string_predefined() -{ - let store = new JSONFile({ - path: getTempFile(TEST_STORE_FILE_NAME).path, - }); - - let string = - "{\"number\":123,\"string\":\"test\",\"object\":{\"prop1\":1,\"prop2\":2}}"; - - yield OS.File.writeAtomic(store.path, new TextEncoder().encode(string), - { tmpPath: store.path + ".tmp" }); - - yield store.load(); - - Assert.deepEqual(store.data, TEST_DATA); -}); - -/** - * Loads data from a malformed JSON string. - */ -add_task(function* test_load_string_malformed() -{ - let store = new JSONFile({ - path: getTempFile(TEST_STORE_FILE_NAME).path, - }); - - let string = "{\"number\":123,\"string\":\"test\",\"object\":{\"prop1\":1,"; - - yield OS.File.writeAtomic(store.path, new TextEncoder().encode(string), - { tmpPath: store.path + ".tmp" }); - - yield store.load(); - - // A backup file should have been created. - do_check_true(yield OS.File.exists(store.path + ".corrupt")); - yield OS.File.remove(store.path + ".corrupt"); - - // The store should be ready to accept new data. - do_check_true(store.dataReady); - do_check_matches(store.data, {}); -}); - -/** - * Loads data from a malformed JSON string, using the synchronous initialization - * path. - */ -add_task(function* test_load_string_malformed_sync() -{ - let store = new JSONFile({ - path: getTempFile(TEST_STORE_FILE_NAME).path, - }); - - let string = "{\"number\":123,\"string\":\"test\",\"object\":{\"prop1\":1,"; - - yield OS.File.writeAtomic(store.path, new TextEncoder().encode(string), - { tmpPath: store.path + ".tmp" }); - - store.ensureDataReady(); - - // A backup file should have been created. - do_check_true(yield OS.File.exists(store.path + ".corrupt")); - yield OS.File.remove(store.path + ".corrupt"); - - // The store should be ready to accept new data. - do_check_true(store.dataReady); - do_check_matches(store.data, {}); -}); diff --git a/toolkit/modules/tests/xpcshell/test_Log.js b/toolkit/modules/tests/xpcshell/test_Log.js deleted file mode 100644 index 6aee99c936..0000000000 --- a/toolkit/modules/tests/xpcshell/test_Log.js +++ /dev/null @@ -1,592 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -/* eslint-disable block-spacing */ - -var {utils: Cu} = Components; - -Cu.import("resource://gre/modules/NetUtil.jsm"); -Cu.import("resource://gre/modules/osfile.jsm"); - -Cu.import("resource://gre/modules/Promise.jsm") -Cu.import("resource://gre/modules/Log.jsm"); - -var testFormatter = { - format: function format(message) { - return message.loggerName + "\t" + - message.levelDesc + "\t" + - message.message; - } -}; - -function MockAppender(formatter) { - Log.Appender.call(this, formatter); - this.messages = []; -} -MockAppender.prototype = { - __proto__: Log.Appender.prototype, - - doAppend: function DApp_doAppend(message) { - this.messages.push(message); - } -}; - -function run_test() { - run_next_test(); -} - -add_task(function test_Logger() { - let log = Log.repository.getLogger("test.logger"); - let appender = new MockAppender(new Log.BasicFormatter()); - - log.level = Log.Level.Debug; - appender.level = Log.Level.Info; - log.addAppender(appender); - log.info("info test"); - log.debug("this should be logged but not appended."); - - do_check_eq(appender.messages.length, 1); - - let msgRe = /\d+\ttest.logger\t\INFO\tinfo test/; - do_check_true(msgRe.test(appender.messages[0])); -}); - -add_task(function test_Logger_parent() { - // Check whether parenting is correct - let grandparentLog = Log.repository.getLogger("grandparent"); - let childLog = Log.repository.getLogger("grandparent.parent.child"); - do_check_eq(childLog.parent.name, "grandparent"); - - let parentLog = Log.repository.getLogger("grandparent.parent"); - do_check_eq(childLog.parent.name, "grandparent.parent"); - - // Check that appends are exactly in scope - let gpAppender = new MockAppender(new Log.BasicFormatter()); - gpAppender.level = Log.Level.Info; - grandparentLog.addAppender(gpAppender); - childLog.info("child info test"); - Log.repository.rootLogger.info("this shouldn't show up in gpAppender"); - - do_check_eq(gpAppender.messages.length, 1); - do_check_true(gpAppender.messages[0].indexOf("child info test") > 0); -}); - -add_test(function test_LoggerWithMessagePrefix() { - let log = Log.repository.getLogger("test.logger.prefix"); - let appender = new MockAppender(new Log.MessageOnlyFormatter()); - log.addAppender(appender); - - let prefixed = Log.repository.getLoggerWithMessagePrefix( - "test.logger.prefix", "prefix: "); - - log.warn("no prefix"); - prefixed.warn("with prefix"); - - Assert.equal(appender.messages.length, 2, "2 messages were logged."); - Assert.deepEqual(appender.messages, [ - "no prefix", - "prefix: with prefix", - ], "Prefix logger works."); - - run_next_test(); -}); - -/* - * A utility method for checking object equivalence. - * Fields with a reqular expression value in expected will be tested - * against the corresponding value in actual. Otherwise objects - * are expected to have the same keys and equal values. - */ -function checkObjects(expected, actual) { - do_check_true(expected instanceof Object); - do_check_true(actual instanceof Object); - for (let key in expected) { - do_check_neq(actual[key], undefined); - if (expected[key] instanceof RegExp) { - do_check_true(expected[key].test(actual[key].toString())); - } else if (expected[key] instanceof Object) { - checkObjects(expected[key], actual[key]); - } else { - do_check_eq(expected[key], actual[key]); - } - } - - for (let key in actual) { - do_check_neq(expected[key], undefined); - } -} - -add_task(function test_StructuredLogCommands() { - let appender = new MockAppender(new Log.StructuredFormatter()); - let logger = Log.repository.getLogger("test.StructuredOutput"); - logger.addAppender(appender); - logger.level = Log.Level.Info; - - logger.logStructured("test_message", {_message: "message string one"}); - logger.logStructured("test_message", {_message: "message string two", - _level: "ERROR", - source_file: "test_Log.js"}); - logger.logStructured("test_message"); - logger.logStructured("test_message", {source_file: "test_Log.js", - message_position: 4}); - - let messageOne = {"_time": /\d+/, - "_namespace": "test.StructuredOutput", - "_level": "INFO", - "_message": "message string one", - "action": "test_message"}; - - let messageTwo = {"_time": /\d+/, - "_namespace": "test.StructuredOutput", - "_level": "ERROR", - "_message": "message string two", - "action": "test_message", - "source_file": "test_Log.js"}; - - let messageThree = {"_time": /\d+/, - "_namespace": "test.StructuredOutput", - "_level": "INFO", - "action": "test_message"}; - - let messageFour = {"_time": /\d+/, - "_namespace": "test.StructuredOutput", - "_level": "INFO", - "action": "test_message", - "source_file": "test_Log.js", - "message_position": 4}; - - checkObjects(messageOne, JSON.parse(appender.messages[0])); - checkObjects(messageTwo, JSON.parse(appender.messages[1])); - checkObjects(messageThree, JSON.parse(appender.messages[2])); - checkObjects(messageFour, JSON.parse(appender.messages[3])); - - let errored = false; - try { - logger.logStructured("", {_message: "invalid message"}); - } catch (e) { - errored = true; - do_check_eq(e, "An action is required when logging a structured message."); - } finally { - do_check_true(errored); - } - - errored = false; - try { - logger.logStructured("message_action", "invalid params"); - } catch (e) { - errored = true; - do_check_eq(e, "The params argument is required to be an object."); - } finally { - do_check_true(errored); - } - - // Logging with unstructured interface should produce the same messages - // as the structured interface for these cases. - appender = new MockAppender(new Log.StructuredFormatter()); - logger = Log.repository.getLogger("test.StructuredOutput1"); - messageOne._namespace = "test.StructuredOutput1"; - messageTwo._namespace = "test.StructuredOutput1"; - logger.addAppender(appender); - logger.level = Log.Level.All; - logger.info("message string one", {action: "test_message"}); - logger.error("message string two", {action: "test_message", - source_file: "test_Log.js"}); - - checkObjects(messageOne, JSON.parse(appender.messages[0])); - checkObjects(messageTwo, JSON.parse(appender.messages[1])); -}); - -add_task(function test_StorageStreamAppender() { - let appender = new Log.StorageStreamAppender(testFormatter); - do_check_eq(appender.getInputStream(), null); - - // Log to the storage stream and verify the log was written and can be - // read back. - let logger = Log.repository.getLogger("test.StorageStreamAppender"); - logger.addAppender(appender); - logger.info("OHAI"); - let inputStream = appender.getInputStream(); - let data = NetUtil.readInputStreamToString(inputStream, - inputStream.available()); - do_check_eq(data, "test.StorageStreamAppender\tINFO\tOHAI\n"); - - // We can read it again even. - let sndInputStream = appender.getInputStream(); - let sameData = NetUtil.readInputStreamToString(sndInputStream, - sndInputStream.available()); - do_check_eq(data, sameData); - - // Reset the appender and log some more. - appender.reset(); - do_check_eq(appender.getInputStream(), null); - logger.debug("wut?!?"); - inputStream = appender.getInputStream(); - data = NetUtil.readInputStreamToString(inputStream, - inputStream.available()); - do_check_eq(data, "test.StorageStreamAppender\tDEBUG\twut?!?\n"); -}); - -function fileContents(path) { - let decoder = new TextDecoder(); - return OS.File.read(path).then(array => { - return decoder.decode(array); - }); -} - -add_task(function* test_FileAppender() { - // This directory does not exist yet - let dir = OS.Path.join(do_get_profile().path, "test_Log"); - do_check_false(yield OS.File.exists(dir)); - let path = OS.Path.join(dir, "test_FileAppender"); - let appender = new Log.FileAppender(path, testFormatter); - let logger = Log.repository.getLogger("test.FileAppender"); - logger.addAppender(appender); - - // Logging to a file that can't be created won't do harm. - do_check_false(yield OS.File.exists(path)); - logger.info("OHAI!"); - - yield OS.File.makeDir(dir); - logger.info("OHAI"); - yield appender._lastWritePromise; - - do_check_eq((yield fileContents(path)), - "test.FileAppender\tINFO\tOHAI\n"); - - logger.info("OHAI"); - yield appender._lastWritePromise; - - do_check_eq((yield fileContents(path)), - "test.FileAppender\tINFO\tOHAI\n" + - "test.FileAppender\tINFO\tOHAI\n"); - - // Reset the appender and log some more. - yield appender.reset(); - do_check_false(yield OS.File.exists(path)); - - logger.debug("O RLY?!?"); - yield appender._lastWritePromise; - do_check_eq((yield fileContents(path)), - "test.FileAppender\tDEBUG\tO RLY?!?\n"); - - yield appender.reset(); - logger.debug("1"); - logger.info("2"); - logger.info("3"); - logger.info("4"); - logger.info("5"); - // Waiting on only the last promise should account for all of these. - yield appender._lastWritePromise; - - // Messages ought to be logged in order. - do_check_eq((yield fileContents(path)), - "test.FileAppender\tDEBUG\t1\n" + - "test.FileAppender\tINFO\t2\n" + - "test.FileAppender\tINFO\t3\n" + - "test.FileAppender\tINFO\t4\n" + - "test.FileAppender\tINFO\t5\n"); -}); - -add_task(function* test_BoundedFileAppender() { - let dir = OS.Path.join(do_get_profile().path, "test_Log"); - - if (!(yield OS.File.exists(dir))) { - yield OS.File.makeDir(dir); - } - - let path = OS.Path.join(dir, "test_BoundedFileAppender"); - // This appender will hold about two lines at a time. - let appender = new Log.BoundedFileAppender(path, testFormatter, 40); - let logger = Log.repository.getLogger("test.BoundedFileAppender"); - logger.addAppender(appender); - - logger.info("ONE"); - logger.info("TWO"); - yield appender._lastWritePromise; - - do_check_eq((yield fileContents(path)), - "test.BoundedFileAppender\tINFO\tONE\n" + - "test.BoundedFileAppender\tINFO\tTWO\n"); - - logger.info("THREE"); - logger.info("FOUR"); - - do_check_neq(appender._removeFilePromise, undefined); - yield appender._removeFilePromise; - yield appender._lastWritePromise; - - do_check_eq((yield fileContents(path)), - "test.BoundedFileAppender\tINFO\tTHREE\n" + - "test.BoundedFileAppender\tINFO\tFOUR\n"); - - yield appender.reset(); - logger.info("ONE"); - logger.info("TWO"); - logger.info("THREE"); - logger.info("FOUR"); - - do_check_neq(appender._removeFilePromise, undefined); - yield appender._removeFilePromise; - yield appender._lastWritePromise; - - do_check_eq((yield fileContents(path)), - "test.BoundedFileAppender\tINFO\tTHREE\n" + - "test.BoundedFileAppender\tINFO\tFOUR\n"); - -}); - -/* - * Test parameter formatting. - */ -add_task(function* log_message_with_params() { - let formatter = new Log.BasicFormatter(); - - function formatMessage(text, params) { - let full = formatter.format(new Log.LogMessage("test.logger", Log.Level.Warn, text, params)); - return full.split("\t")[3]; - } - - // Strings are substituted directly. - do_check_eq(formatMessage("String is ${foo}", {foo: "bar"}), - "String is bar"); - - // Numbers are substituted. - do_check_eq(formatMessage("Number is ${number}", {number: 47}), - "Number is 47") - - // The entire params object is JSON-formatted and substituted. - do_check_eq(formatMessage("Object is ${}", {foo: "bar"}), - 'Object is {"foo":"bar"}'); - - // An object nested inside params is JSON-formatted and substituted. - do_check_eq(formatMessage("Sub object is ${sub}", {sub: {foo: "bar"}}), - 'Sub object is {"foo":"bar"}'); - - // The substitution field is missing from params. Leave the placeholder behind - // to make the mistake obvious. - do_check_eq(formatMessage("Missing object is ${missing}", {}), - 'Missing object is ${missing}'); - - // Make sure we don't treat the parameter name 'false' as a falsey value. - do_check_eq(formatMessage("False is ${false}", {false: true}), - 'False is true'); - - // If an object has a .toJSON method, the formatter uses it. - let ob = function() {}; - ob.toJSON = function() {return {sneaky: "value"}}; - do_check_eq(formatMessage("JSON is ${sub}", {sub: ob}), - 'JSON is {"sneaky":"value"}'); - - // Fall back to .toSource() if JSON.stringify() fails on an object. - ob = function() {}; - ob.toJSON = function() {throw "oh noes JSON"}; - do_check_eq(formatMessage("Fail is ${sub}", {sub: ob}), - 'Fail is (function() {})'); - - // Fall back to .toString if both .toJSON and .toSource fail. - ob.toSource = function() {throw "oh noes SOURCE"}; - do_check_eq(formatMessage("Fail is ${sub}", {sub: ob}), - 'Fail is function() {}'); - - // Fall back to '[object]' if .toJSON, .toSource and .toString fail. - ob.toString = function() {throw "oh noes STRING"}; - do_check_eq(formatMessage("Fail is ${sub}", {sub: ob}), - 'Fail is [object]'); - - // If params are passed but there are no substitution in the text - // we JSON format and append the entire parameters object. - do_check_eq(formatMessage("Text with no subs", {a: "b", c: "d"}), - 'Text with no subs: {"a":"b","c":"d"}'); - - // If we substitute one parameter but not the other, - // we ignore any params that aren't substituted. - do_check_eq(formatMessage("Text with partial sub ${a}", {a: "b", c: "d"}), - 'Text with partial sub b'); - - // We don't format internal fields stored in params. - do_check_eq(formatMessage("Params with _ ${}", {a: "b", _c: "d", _level:20, _message:"froo", - _time:123456, _namespace:"here.there"}), - 'Params with _ {"a":"b","_c":"d"}'); - - // Don't print an empty params holder if all params are internal. - do_check_eq(formatMessage("All params internal", {_level:20, _message:"froo", - _time:123456, _namespace:"here.there"}), - 'All params internal'); - - // Format params with null and undefined values. - do_check_eq(formatMessage("Null ${n} undefined ${u}", {n: null, u: undefined}), - 'Null null undefined undefined'); - - // Format params with number, bool, and Object/String type. - do_check_eq(formatMessage("number ${n} boolean ${b} boxed Boolean ${bx} String ${s}", - {n: 45, b: false, bx: new Boolean(true), s: new String("whatevs")}), - 'number 45 boolean false boxed Boolean true String whatevs'); - - /* - * Check that errors get special formatting if they're formatted directly as - * a named param or they're the only param, but not if they're a field in a - * larger structure. - */ - let err = Components.Exception("test exception", Components.results.NS_ERROR_FAILURE); - let str = formatMessage("Exception is ${}", err); - do_check_true(str.includes('Exception is [Exception... "test exception"')); - do_check_true(str.includes("(NS_ERROR_FAILURE)")); - str = formatMessage("Exception is", err); - do_check_true(str.includes('Exception is: [Exception... "test exception"')); - str = formatMessage("Exception is ${error}", {error: err}); - do_check_true(str.includes('Exception is [Exception... "test exception"')); - str = formatMessage("Exception is", {_error: err}); - do_print(str); - // Exceptions buried inside objects are formatted badly. - do_check_true(str.includes('Exception is: {"_error":{}')); - // If the message text is null, the message contains only the formatted params object. - str = formatMessage(null, err); - do_check_true(str.startsWith('[Exception... "test exception"')); - // If the text is null and 'params' is a String object, the message is exactly that string. - str = formatMessage(null, new String("String in place of params")); - do_check_eq(str, "String in place of params"); - - // We use object.valueOf() internally; make sure a broken valueOf() method - // doesn't cause the logger to fail. - let vOf = {a: 1, valueOf: function() {throw "oh noes valueOf"}}; - do_check_eq(formatMessage("Broken valueOf ${}", vOf), - 'Broken valueOf ({a:1, valueOf:(function() {throw "oh noes valueOf"})})'); - - // Test edge cases of bad data to formatter: - // If 'params' is not an object, format it as a basic type. - do_check_eq(formatMessage("non-object no subst", 1), - 'non-object no subst: 1'); - do_check_eq(formatMessage("non-object all subst ${}", 2), - 'non-object all subst 2'); - do_check_eq(formatMessage("false no subst", false), - 'false no subst: false'); - do_check_eq(formatMessage("null no subst", null), - 'null no subst: null'); - // If 'params' is undefined and there are no substitutions expected, - // the message should still be output. - do_check_eq(formatMessage("undefined no subst", undefined), - 'undefined no subst'); - // If 'params' is not an object, no named substitutions can succeed; - // therefore we leave the placeholder and append the formatted params. - do_check_eq(formatMessage("non-object named subst ${junk} space", 3), - 'non-object named subst ${junk} space: 3'); - // If there are no params, we leave behind the placeholders in the text. - do_check_eq(formatMessage("no params ${missing}", undefined), - 'no params ${missing}'); - // If params doesn't contain any of the tags requested in the text, - // we leave them all behind and append the formatted params. - do_check_eq(formatMessage("object missing tag ${missing} space", {mising: "not here"}), - 'object missing tag ${missing} space: {"mising":"not here"}'); - // If we are given null text and no params, the resulting formatted message is empty. - do_check_eq(formatMessage(null), ''); -}); - -/* - * If we call a log function with a non-string object in place of the text - * argument, and no parameters, treat that the same as logging empty text - * with the object argument as parameters. This makes the log useful when the - * caller does "catch(err) {logger.error(err)}" - */ -add_task(function* test_log_err_only() { - let log = Log.repository.getLogger("error.only"); - let mockFormatter = { format: msg => msg }; - let appender = new MockAppender(mockFormatter); - log.addAppender(appender); - - /* - * Check that log.error(err) is treated the same as - * log.error(null, err) by the logMessage constructor; the formatMessage() - * tests above ensure that the combination of null text and an error object - * is formatted correctly. - */ - try { - eval("javascript syntax error"); - } - catch (e) { - log.error(e); - msg = appender.messages.pop(); - do_check_eq(msg.message, null); - do_check_eq(msg.params, e); - } -}); - -/* - * Test logStructured() messages through basic formatter. - */ -add_task(function* test_structured_basic() { - let log = Log.repository.getLogger("test.logger"); - let appender = new MockAppender(new Log.BasicFormatter()); - - log.level = Log.Level.Info; - appender.level = Log.Level.Info; - log.addAppender(appender); - - // A structured entry with no _message is treated the same as log./level/(null, params) - // except the 'action' field is added to the object. - log.logStructured("action", {data: "structure"}); - do_check_eq(appender.messages.length, 1); - do_check_true(appender.messages[0].includes('{"data":"structure","action":"action"}')); - - // A structured entry with _message and substitution is treated the same as - // log./level/(null, params). - log.logStructured("action", {_message: "Structured sub ${data}", data: "structure"}); - do_check_eq(appender.messages.length, 2); - do_print(appender.messages[1]); - do_check_true(appender.messages[1].includes('Structured sub structure')); -}); - -/* - * Test that all the basic logger methods pass the message and params through to the appender. - */ -add_task(function* log_message_with_params() { - let log = Log.repository.getLogger("error.logger"); - let mockFormatter = { format: msg => msg }; - let appender = new MockAppender(mockFormatter); - log.addAppender(appender); - - let testParams = {a:1, b:2}; - log.fatal("Test fatal", testParams); - log.error("Test error", testParams); - log.warn("Test warn", testParams); - log.info("Test info", testParams); - log.config("Test config", testParams); - log.debug("Test debug", testParams); - log.trace("Test trace", testParams); - do_check_eq(appender.messages.length, 7); - for (let msg of appender.messages) { - do_check_true(msg.params === testParams); - do_check_true(msg.message.startsWith("Test ")); - } -}); - -/* - * Check that we format JS Errors reasonably. - */ -add_task(function* format_errors() { - let pFormat = new Log.ParameterFormatter(); - - // Test that subclasses of Error are recognized as errors. - err = new ReferenceError("Ref Error", "ERROR_FILE", 28); - str = pFormat.format(err); - do_check_true(str.includes("ReferenceError")); - do_check_true(str.includes("ERROR_FILE:28")); - do_check_true(str.includes("Ref Error")); - - // Test that JS-generated Errors are recognized and formatted. - try { - yield Promise.resolve(); // Scrambles the stack - eval("javascript syntax error"); - } - catch (e) { - str = pFormat.format(e); - do_check_true(str.includes("SyntaxError: missing ;")); - // Make sure we identified it as an Error and formatted the error location as - // lineNumber:columnNumber. - do_check_true(str.includes(":1:11)")); - // Make sure that we use human-readable stack traces - // Check that the error doesn't contain any reference to "Promise.jsm" or "Task.jsm" - do_check_false(str.includes("Promise.jsm")); - do_check_false(str.includes("Task.jsm")); - do_check_true(str.includes("format_errors")); - } -}); diff --git a/toolkit/modules/tests/xpcshell/test_Log_stackTrace.js b/toolkit/modules/tests/xpcshell/test_Log_stackTrace.js deleted file mode 100644 index 6e53db058c..0000000000 --- a/toolkit/modules/tests/xpcshell/test_Log_stackTrace.js +++ /dev/null @@ -1,30 +0,0 @@ -print("Define some functions in well defined line positions for the test"); -function foo(v) { return bar(v + 1); } // line 2 -function bar(v) { return baz(v + 1); } // line 3 -function baz(v) { throw new Error(v + 1); } // line 4 - -print("Make sure lazy constructor calling/assignment works"); -Components.utils.import("resource://gre/modules/Log.jsm"); - -function run_test() { - print("Make sure functions, arguments, files are pretty printed in the trace"); - let trace = ""; - try { - foo(0); - } - catch (ex) { - trace = Log.stackTrace(ex); - } - print(`Got trace: ${trace}`); - do_check_neq(trace, ""); - - let bazPos = trace.indexOf("baz@test_Log_stackTrace.js:4"); - let barPos = trace.indexOf("bar@test_Log_stackTrace.js:3"); - let fooPos = trace.indexOf("foo@test_Log_stackTrace.js:2"); - print(`String positions: ${bazPos} ${barPos} ${fooPos}`); - - print("Make sure the desired messages show up"); - do_check_true(bazPos >= 0); - do_check_true(barPos > bazPos); - do_check_true(fooPos > barPos); -} diff --git a/toolkit/modules/tests/xpcshell/test_MatchGlobs.js b/toolkit/modules/tests/xpcshell/test_MatchGlobs.js deleted file mode 100644 index 5dcfd19cba..0000000000 --- a/toolkit/modules/tests/xpcshell/test_MatchGlobs.js +++ /dev/null @@ -1,58 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Components.utils.import("resource://gre/modules/MatchPattern.jsm"); -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test(url, pattern) { - let uri = Services.io.newURI(url, null, null); - let m = new MatchGlobs(pattern); - return m.matches(uri.spec); -} - -function pass({url, pattern}) { - ok(test(url, pattern), `Expected match: ${JSON.stringify(pattern)}, ${url}`); -} - -function fail({url, pattern}) { - ok(!test(url, pattern), `Expected no match: ${JSON.stringify(pattern)}, ${url}`); -} - -function run_test() { - let moz = "http://mozilla.org"; - - pass({url: moz, pattern: ["*"]}); - pass({url: moz, pattern: ["http://*"]}), - pass({url: moz, pattern: ["*mozilla*"]}); - pass({url: moz, pattern: ["*example*", "*mozilla*"]}); - - pass({url: moz, pattern: ["*://*"]}); - pass({url: "https://mozilla.org", pattern: ["*://*"]}); - - // Documentation example - pass({url: "http://www.example.com/foo/bar", pattern: ["http://???.example.com/foo/*"]}); - pass({url: "http://the.example.com/foo/", pattern: ["http://???.example.com/foo/*"]}); - fail({url: "http://my.example.com/foo/bar", pattern: ["http://???.example.com/foo/*"]}); - fail({url: "http://example.com/foo/", pattern: ["http://???.example.com/foo/*"]}); - fail({url: "http://www.example.com/foo", pattern: ["http://???.example.com/foo/*"]}); - - // Matches path - let path = moz + "/abc/def"; - pass({url: path, pattern: ["*def"]}); - pass({url: path, pattern: ["*c/d*"]}); - pass({url: path, pattern: ["*org/abc*"]}); - fail({url: path + "/", pattern: ["*def"]}); - - // Trailing slash - pass({url: moz, pattern: ["*.org/"]}); - fail({url: moz, pattern: ["*.org"]}); - - // Wrong TLD - fail({url: moz, pattern: ["www*.m*.com/"]}); - // Case sensitive - fail({url: moz, pattern: ["*.ORG/"]}); - - fail({url: moz, pattern: []}); -} diff --git a/toolkit/modules/tests/xpcshell/test_MatchPattern.js b/toolkit/modules/tests/xpcshell/test_MatchPattern.js deleted file mode 100644 index 5830383610..0000000000 --- a/toolkit/modules/tests/xpcshell/test_MatchPattern.js +++ /dev/null @@ -1,95 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Components.utils.import("resource://gre/modules/MatchPattern.jsm"); -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test(url, pattern) -{ - let uri = Services.io.newURI(url, null, null); - let m = new MatchPattern(pattern); - return m.matches(uri); -} - -function pass({url, pattern}) -{ - do_check_true(test(url, pattern), `Expected match: ${JSON.stringify(pattern)}, ${url}`); -} - -function fail({url, pattern}) -{ - do_check_false(test(url, pattern), `Expected no match: ${JSON.stringify(pattern)}, ${url}`); -} - -function run_test() -{ - // Invalid pattern. - fail({url: "http://mozilla.org", pattern: ""}); - - // Pattern must include trailing slash. - fail({url: "http://mozilla.org", pattern: "http://mozilla.org"}); - - // Protocol not allowed. - fail({url: "http://mozilla.org", pattern: "gopher://wuarchive.wustl.edu/"}); - - pass({url: "http://mozilla.org", pattern: "http://mozilla.org/"}); - pass({url: "http://mozilla.org/", pattern: "http://mozilla.org/"}); - - pass({url: "http://mozilla.org/", pattern: "*://mozilla.org/"}); - pass({url: "https://mozilla.org/", pattern: "*://mozilla.org/"}); - fail({url: "file://mozilla.org/", pattern: "*://mozilla.org/"}); - fail({url: "ftp://mozilla.org/", pattern: "*://mozilla.org/"}); - - fail({url: "http://mozilla.com", pattern: "http://*mozilla.com*/"}); - fail({url: "http://mozilla.com", pattern: "http://mozilla.*/"}); - fail({url: "http://mozilla.com", pattern: "http:/mozilla.com/"}); - - pass({url: "http://google.com", pattern: "http://*.google.com/"}); - pass({url: "http://docs.google.com", pattern: "http://*.google.com/"}); - - pass({url: "http://mozilla.org:8080", pattern: "http://mozilla.org/"}); - pass({url: "http://mozilla.org:8080", pattern: "*://mozilla.org/"}); - fail({url: "http://mozilla.org:8080", pattern: "http://mozilla.org:8080/"}); - - // Now try with * in the path. - pass({url: "http://mozilla.org", pattern: "http://mozilla.org/*"}); - pass({url: "http://mozilla.org/", pattern: "http://mozilla.org/*"}); - - pass({url: "http://mozilla.org/", pattern: "*://mozilla.org/*"}); - pass({url: "https://mozilla.org/", pattern: "*://mozilla.org/*"}); - fail({url: "file://mozilla.org/", pattern: "*://mozilla.org/*"}); - fail({url: "http://mozilla.com", pattern: "http://mozilla.*/*"}); - - pass({url: "http://google.com", pattern: "http://*.google.com/*"}); - pass({url: "http://docs.google.com", pattern: "http://*.google.com/*"}); - - // Check path stuff. - fail({url: "http://mozilla.com/abc/def", pattern: "http://mozilla.com/"}); - pass({url: "http://mozilla.com/abc/def", pattern: "http://mozilla.com/*"}); - pass({url: "http://mozilla.com/abc/def", pattern: "http://mozilla.com/a*f"}); - pass({url: "http://mozilla.com/abc/def", pattern: "http://mozilla.com/a*"}); - pass({url: "http://mozilla.com/abc/def", pattern: "http://mozilla.com/*f"}); - fail({url: "http://mozilla.com/abc/def", pattern: "http://mozilla.com/*e"}); - fail({url: "http://mozilla.com/abc/def", pattern: "http://mozilla.com/*c"}); - - fail({url: "http:///a.html", pattern: "http:///a.html"}); - pass({url: "file:///foo", pattern: "file:///foo*"}); - pass({url: "file:///foo/bar.html", pattern: "file:///foo*"}); - - pass({url: "http://mozilla.org/a", pattern: "<all_urls>"}); - pass({url: "https://mozilla.org/a", pattern: "<all_urls>"}); - pass({url: "ftp://mozilla.org/a", pattern: "<all_urls>"}); - pass({url: "file:///a", pattern: "<all_urls>"}); - fail({url: "gopher://wuarchive.wustl.edu/a", pattern: "<all_urls>"}); - - // Multiple patterns. - pass({url: "http://mozilla.org", pattern: ["http://mozilla.org/"]}); - pass({url: "http://mozilla.org", pattern: ["http://mozilla.org/", "http://mozilla.com/"]}); - pass({url: "http://mozilla.com", pattern: ["http://mozilla.org/", "http://mozilla.com/"]}); - fail({url: "http://mozilla.biz", pattern: ["http://mozilla.org/", "http://mozilla.com/"]}); - - // Match url with fragments. - pass({url: "http://mozilla.org/base#some-fragment", pattern: "http://mozilla.org/base"}); -} diff --git a/toolkit/modules/tests/xpcshell/test_MatchURLFilters.js b/toolkit/modules/tests/xpcshell/test_MatchURLFilters.js deleted file mode 100644 index 52e03a6cc1..0000000000 --- a/toolkit/modules/tests/xpcshell/test_MatchURLFilters.js +++ /dev/null @@ -1,396 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Components.utils.import("resource://gre/modules/MatchPattern.jsm"); -Components.utils.import("resource://gre/modules/Services.jsm"); - -function createTestFilter({url, filters}) { - let m = new MatchURLFilters(filters); - return m.matches(url); -} - -function expectPass({url, filters}) { - ok(createTestFilter({url, filters}), - `Expected match: ${JSON.stringify(filters)}, ${url}`); -} - -function expectFail({url, filters}) { - ok(!createTestFilter({url, filters}), - `Expected no match: ${JSON.stringify(filters)}, ${url}`); -} - -function expectThrow({url, filters, exceptionMessageContains}) { - let logData = {filters, url}; - - Assert.throws( - () => { - createTestFilter({url, filters}); - }, - exceptionMessageContains, - `Check received exception for expected message: ${JSON.stringify(logData)}` - ); -} - -add_task(function* test_match_url_filters() { - const shouldPass = true; - const shouldFail = true; - const shouldThrow = true; - - var testCases = [ - // Empty, undefined and null filters. - {shouldThrow, exceptionMessageContains: "filters array should not be empty", - filters: [], url: "http://mozilla.org", }, - {shouldThrow, exceptionMessageContains: "filters should be an array", - filters: undefined, url: "http://mozilla.org"}, - {shouldThrow, exceptionMessageContains: "filters should be an array", - filters: null, url: "http://mozilla.org"}, - - // Wrong formats (in a real webextension this will be blocked by the schema validation). - {shouldThrow, exceptionMessageContains: "filters should be an array", filters: {}, - url: "http://mozilla.org"}, - {shouldThrow, exceptionMessageContains: "filters should be an array", - filters: {nonExistentCriteria: true}, url: "http://mozilla.org", }, - {shouldPass, filters: [{nonExistentCriteria: true}], url: "http://mozilla.org"}, - - // Schemes filter over various url schemes. - {shouldPass, filters: [{schemes: ["http"]}], url: "http://mozilla.org"}, - {shouldPass, filters: [{schemes: ["https"]}], url: "https://mozilla.org"}, - {shouldPass, filters: [{schemes: ["ftp"]}], url: "ftp://fake/ftp/url"}, - {shouldPass, filters: [{schemes: ["about"]}], url: "about:blank"}, - {shouldPass, filters: [{schemes: ["data"]}], url: "data:,testDataURL"}, - {shouldFail, filters: [{schemes: ["http"]}], url: "ftp://fake/ftp/url"}, - - // Multiple schemes: pass when at least one scheme matches. - {shouldPass, filters: [{schemes: ["https", "about"]}], url: "https://mozilla.org"}, - {shouldPass, filters: [{schemes: ["about", "https"]}], url: "https://mozilla.org"}, - {shouldFail, filters: [{schemes: ["about", "http"]}], url: "https://mozilla.org"}, - - // Port filter: standard (implicit) ports. - {shouldPass, filters: [{ports: [443]}], url: "https://mozilla.org"}, - {shouldPass, filters: [{ports: [80]}], url: "http://mozilla.org"}, - {shouldPass, filters: [{ports: [21]}], url: "ftp://ftp.mozilla.org"}, - - // Port filter: schemes without a default port. - {shouldFail, filters: [{ports: [-1]}], url: "about:blank"}, - {shouldFail, filters: [{ports: [-1]}], url: "data:,testDataURL"}, - - {shouldFail, filters: [{ports: [[1, 65535]]}], url: "about:blank"}, - {shouldFail, filters: [{ports: [[1, 65535]]}], url: "data:,testDataURL"}, - - // Host filters (hostEquals, hostContains, hostPrefix, hostSuffix): schemes with an host. - {shouldFail, filters: [{hostEquals: ""}], url: "https://mozilla.org"}, - {shouldPass, filters: [{hostEquals: null}], url: "https://mozilla.org"}, - {shouldPass, filters: [{hostEquals: "mozilla.org"}], url: "https://mozilla.org"}, - {shouldFail, filters: [{hostEquals: "mozilla.com"}], url: "https://mozilla.org"}, - // NOTE: trying at least once another valid protocol. - {shouldPass, filters: [{hostEquals: "mozilla.org"}], url: "ftp://mozilla.org"}, - {shouldFail, filters: [{hostEquals: "mozilla.com"}], url: "ftp://mozilla.org"}, - {shouldPass, filters: [{hostEquals: "mozilla.org"}], url: "https://mozilla.org:8888"}, - - {shouldPass, filters: [{hostContains: "moz"}], url: "https://mozilla.org"}, - // NOTE: an implicit '.' char is inserted into the host. - {shouldPass, filters: [{hostContains: ".moz"}], url: "https://mozilla.org"}, - {shouldFail, filters: [{hostContains: "com"}], url: "https://mozilla.org"}, - {shouldPass, filters: [{hostContains: ""}], url: "https://mozilla.org"}, - {shouldPass, filters: [{hostContains: null}], url: "https://mozilla.org"}, - - {shouldPass, filters: [{hostPrefix: "moz"}], url: "https://mozilla.org"}, - {shouldFail, filters: [{hostPrefix: "org"}], url: "https://mozilla.org"}, - {shouldPass, filters: [{hostPrefix: ""}], url: "https://mozilla.org"}, - {shouldPass, filters: [{hostPrefix: null}], url: "https://mozilla.org"}, - - {shouldPass, filters: [{hostSuffix: ".org"}], url: "https://mozilla.org"}, - {shouldFail, filters: [{hostSuffix: "moz"}], url: "https://mozilla.org"}, - {shouldPass, filters: [{hostSuffix: ""}], url: "https://mozilla.org"}, - {shouldPass, filters: [{hostSuffix: null}], url: "https://mozilla.org"}, - {shouldPass, filters: [{hostSuffix: "lla.org"}], url: "https://mozilla.org:8888"}, - - // hostEquals: urls without an host. - // TODO: should we explicitly cover hostContains, hostPrefix, hostSuffix for - // these sub-cases? - {shouldFail, filters: [{hostEquals: "blank"}], url: "about:blank"}, - {shouldFail, filters: [{hostEquals: "blank"}], url: "about://blank"}, - {shouldFail, filters: [{hostEquals: "testDataURL"}], url: "data:,testDataURL"}, - {shouldPass, filters: [{hostEquals: ""}], url: "about:blank"}, - {shouldPass, filters: [{hostEquals: ""}], url: "about://blank"}, - {shouldPass, filters: [{hostEquals: ""}], url: "data:,testDataURL"}, - - // Path filters (pathEquals, pathContains, pathPrefix, pathSuffix). - {shouldFail, filters: [{pathEquals: ""}], url: "https://mozilla.org/test/path"}, - {shouldPass, filters: [{pathEquals: null}], url: "https://mozilla.org/test/path"}, - {shouldPass, filters: [{pathEquals: "/test/path"}], url: "https://mozilla.org/test/path"}, - {shouldFail, filters: [{pathEquals: "/wrong/path"}], url: "https://mozilla.org/test/path"}, - {shouldPass, filters: [{pathEquals: "/test/path"}], url: "https://mozilla.org:8888/test/path"}, - // NOTE: trying at least once another valid protocol - {shouldPass, filters: [{pathEquals: "/test/path"}], url: "ftp://mozilla.org/test/path"}, - {shouldFail, filters: [{pathEquals: "/wrong/path"}], url: "ftp://mozilla.org/test/path"}, - - {shouldPass, filters: [{pathContains: "st/"}], url: "https://mozilla.org/test/path"}, - {shouldPass, filters: [{pathContains: "/test"}], url: "https://mozilla.org/test/path"}, - {shouldFail, filters: [{pathContains: "org"}], url: "https://mozilla.org/test/path"}, - {shouldPass, filters: [{pathContains: ""}], url: "https://mozilla.org/test/path"}, - {shouldPass, filters: [{pathContains: null}], url: "https://mozilla.org/test/path"}, - {shouldFail, filters: [{pathContains: "param"}], url: "https://mozilla.org:8888/test/path?param=1"}, - {shouldFail, filters: [{pathContains: "ref"}], url: "https://mozilla.org:8888/test/path#ref"}, - {shouldPass, filters: [{pathContains: "st/pa"}], url: "https://mozilla.org:8888/test/path"}, - - {shouldPass, filters: [{pathPrefix: "/te"}], url: "https://mozilla.org/test/path"}, - {shouldFail, filters: [{pathPrefix: "org/"}], url: "https://mozilla.org/test/path"}, - {shouldPass, filters: [{pathPrefix: ""}], url: "https://mozilla.org/test/path"}, - {shouldPass, filters: [{pathPrefix: null}], url: "https://mozilla.org/test/path"}, - - {shouldPass, filters: [{pathSuffix: "/path"}], url: "https://mozilla.org/test/path"}, - {shouldFail, filters: [{pathSuffix: "th/"}], url: "https://mozilla.org/test/path"}, - {shouldPass, filters: [{pathSuffix: ""}], url: "https://mozilla.org/test/path"}, - {shouldPass, filters: [{pathSuffix: null}], url: "https://mozilla.org/test/path"}, - {shouldFail, filters: [{pathSuffix: "p=1"}], url: "https://mozilla.org:8888/test/path?p=1"}, - {shouldFail, filters: [{pathSuffix: "ref"}], url: "https://mozilla.org:8888/test/path#ref"}, - - // Query filters (queryEquals, queryContains, queryPrefix, querySuffix). - {shouldFail, filters: [{queryEquals: ""}], url: "https://mozilla.org/?param=val"}, - {shouldPass, filters: [{queryEquals: null}], url: "https://mozilla.org/?param=val"}, - {shouldPass, filters: [{queryEquals: "param=val"}], url: "https://mozilla.org/?param=val"}, - {shouldFail, filters: [{queryEquals: "?param=val"}], url: "https://mozilla.org/?param=val"}, - {shouldFail, filters: [{queryEquals: "/path?param=val"}], url: "https://mozilla.org/path?param=val"}, - - // NOTE: about scheme urls cannot be matched by query. - {shouldFail, filters: [{queryEquals: "param=val"}], url: "about:blank?param=val"}, - {shouldFail, filters: [{queryEquals: "param"}], url: "ftp://mozilla.org?param=val"}, - - {shouldPass, filters: [{queryContains: "ram"}], url: "https://mozilla.org/?param=val"}, - {shouldPass, filters: [{queryContains: "=val"}], url: "https://mozilla.org/?param=val"}, - {shouldFail, filters: [{queryContains: "?param"}], url: "https://mozilla.org/?param=val"}, - {shouldFail, filters: [{queryContains: "path"}], url: "https://mozilla.org/path/?p=v#ref"}, - {shouldPass, filters: [{queryContains: ""}], url: "https://mozilla.org/?param=val"}, - {shouldPass, filters: [{queryContains: null}], url: "https://mozilla.org/?param=val"}, - - {shouldPass, filters: [{queryPrefix: "param"}], url: "https://mozilla.org/?param=val"}, - {shouldFail, filters: [{queryPrefix: "p="}], url: "https://mozilla.org/?param=val"}, - {shouldFail, filters: [{queryPrefix: "path"}], url: "https://mozilla.org/path?param=val"}, - {shouldPass, filters: [{queryPrefix: ""}], url: "https://mozilla.org/?param=val"}, - {shouldPass, filters: [{queryPrefix: null}], url: "https://mozilla.org/?param=val"}, - - {shouldPass, filters: [{querySuffix: "=val"}], url: "https://mozilla.org/?param=val"}, - {shouldFail, filters: [{querySuffix: "=wrong"}], url: "https://mozilla.org/?param=val"}, - {shouldPass, filters: [{querySuffix: ""}], url: "https://mozilla.org/?param=val"}, - {shouldPass, filters: [{querySuffix: null}], url: "https://mozilla.org/?param=val"}, - - // URL filters (urlEquals, urlContains, urlPrefix, urlSuffix). - {shouldFail, filters: [{urlEquals: ""}], url: "https://mozilla.org/?p=v#ref"}, - {shouldPass, filters: [{urlEquals: null}], url: "https://mozilla.org/?p=v#ref"}, - {shouldPass, filters: [{urlEquals: "https://mozilla.org/?p=v#ref"}], - url: "https://mozilla.org/?p=v#ref"}, - {shouldFail, filters: [{urlEquals: "https://mozilla.org/?p=v#ref2"}], - url: "https://mozilla.org/?p=v#ref"}, - {shouldPass, filters: [{urlEquals: "about:blank?p=v#ref"}], url: "about:blank?p=v#ref"}, - {shouldPass, filters: [{urlEquals: "ftp://mozilla.org?p=v#ref"}], - url: "ftp://mozilla.org?p=v#ref"}, - - {shouldPass, filters: [{urlContains: "org/?p"}], url: "https://mozilla.org/?p=v#ref"}, - {shouldPass, filters: [{urlContains: "=v#ref"}], url: "https://mozilla.org/?p=v#ref"}, - {shouldFail, filters: [{urlContains: "ftp"}], url: "https://mozilla.org/?p=v#ref"}, - {shouldPass, filters: [{urlContains: ""}], url: "https://mozilla.org/?p=v#ref"}, - {shouldPass, filters: [{urlContains: null}], url: "https://mozilla.org/?p=v#ref"}, - - {shouldPass, filters: [{urlPrefix: "http"}], url: "https://mozilla.org/?p=v#ref"}, - {shouldFail, filters: [{urlPrefix: "moz"}], url: "https://mozilla.org/?p=v#ref"}, - {shouldPass, filters: [{urlPrefix: ""}], url: "https://mozilla.org/?p=v#ref"}, - {shouldPass, filters: [{urlPrefix: null}], url: "https://mozilla.org/?p=v#ref"}, - - {shouldPass, filters: [{urlSuffix: "#ref"}], url: "https://mozilla.org/?p=v#ref"}, - {shouldFail, filters: [{urlSuffix: "=wrong"}], url: "https://mozilla.org/?p=v#ref"}, - {shouldPass, filters: [{urlSuffix: ""}], url: "https://mozilla.org/?p=v#ref"}, - {shouldPass, filters: [{urlSuffix: null}], url: "https://mozilla.org/?p=v#ref"}, - - // More url filters: urlMatches. - {shouldPass, filters: [{urlMatches: ".*://mozilla"}], url: "https://mozilla.org/?p=v#ref"}, - {shouldPass, filters: [{urlMatches: ".*://mozilla"}], url: "ftp://mozilla.org/?p=v#ref"}, - {shouldPass, filters: [{urlMatches: ".*://.*/\?p"}], url: "ftp://mozilla.org/?p=v#ref"}, - // NOTE: urlMatches should not match the url without the ref. - {shouldFail, filters: [{urlMatches: "v#ref$"}], url: "https://mozilla.org/?p=v#ref"}, - {shouldPass, filters: [{urlMatches: "^ftp"}], url: "ftp://mozilla.org/?p=v#ref"}, - - // More url filters: originAndPathMatches. - {shouldPass, filters: [{originAndPathMatches: ".*://mozilla"}], - url: "https://mozilla.org/?p=v#ref"}, - {shouldPass, filters: [{originAndPathMatches: ".*://mozilla"}], - url: "ftp://mozilla.org/?p=v#ref"}, - // NOTE: urlMatches should not match the url without the query and the ref. - {shouldFail, filters: [{originAndPathMatches: ".*://.*/\?p"}], - url: "ftp://mozilla.org/?p=v#ref"}, - {shouldFail, filters: [{originAndPathMatches: "v#ref$"}], - url: "https://mozilla.org/?p=v#ref"}, - {shouldPass, filters: [{originAndPathMatches: "^ftp"}], - url: "ftp://mozilla.org/?p=v#ref"}, - - // Filter with all criteria: all matches, none matches, some matches. - - // All matches. - {shouldPass, filters: [ - { - schemes: ["https", "http"], - ports: [443, 80], - hostEquals: "www.mozilla.org", - hostContains: ".moz", - hostPrefix: "www", - hostSuffix: "org", - pathEquals: "/sub/path", - pathContains: "b/p", - pathPrefix: "/sub", - pathSuffix: "/path", - queryEquals: "p=v", - queryContains: "1=", - queryPrefix: "p1", - querySuffix: "=v", - urlEquals: "https://www.mozilla.org/sub/path?p1=v#ref", - urlContains: "org/sub", - urlPrefix: "https://moz", - urlSuffix: "#ref", - urlMatches: "v#ref$", - originAndPathMatches: ".*://moz.*/" - }, - ], url: "https://www.mozilla.org/sub/path?p1=v#ref"}, - // None matches. - {shouldFail, filters: [ - { - schemes: ["http"], - ports: [80], - hostEquals: "mozilla.com", - hostContains: "www.moz", - hostPrefix: "www", - hostSuffix: "com", - pathEquals: "/wrong/path", - pathContains: "g/p", - pathPrefix: "/wrong", - pathSuffix: "/wrong", - queryEquals: "p2=v", - queryContains: "2=", - queryPrefix: "p2", - querySuffix: "=value", - urlEquals: "http://mozilla.com/sub/path?p1=v#ref", - urlContains: "com/sub", - urlPrefix: "http://moz", - urlSuffix: "#ref2", - urlMatches: "value#ref2$", - originAndPathMatches: ".*://moz.*com/" - }, - ], url: "https://mozilla.org/sub/path?p1=v#ref"}, - // Some matches - {shouldFail, filters: [ - { - schemes: ["https"], - ports: [80], - hostEquals: "mozilla.com", - hostContains: "www.moz", - hostPrefix: "www", - hostSuffix: "com", - pathEquals: "/wrong/path", - pathContains: "g/p", - pathPrefix: "/wrong", - pathSuffix: "/wrong", - queryEquals: "p2=v", - queryContains: "2=", - queryPrefix: "p2", - querySuffix: "=value", - urlEquals: "http://mozilla.com/sub/path?p1=v#ref", - urlContains: "com/sub", - urlPrefix: "http://moz", - urlSuffix: "#ref2", - urlMatches: "value#ref2$", - originAndPathMatches: ".*://moz.*com/" - }, - ], url: "https://mozilla.org/sub/path?p1=v#ref"}, - - // Filter with multiple filters: all matches, some matches, none matches. - - // All matches. - {shouldPass, filters: [ - {schemes: ["https", "http"]}, - {ports: [443, 80]}, - {hostEquals: "www.mozilla.org"}, - {hostContains: ".moz"}, - {hostPrefix: "www"}, - {hostSuffix: "org"}, - {pathEquals: "/sub/path"}, - {pathContains: "b/p"}, - {pathPrefix: "/sub"}, - {pathSuffix: "/path"}, - {queryEquals: "p=v"}, - {queryContains: "1="}, - {queryPrefix: "p1"}, - {querySuffix: "=v"}, - {urlEquals: "https://www.mozilla.org/sub/path?p1=v#ref"}, - {urlContains: "org/sub"}, - {urlPrefix: "https://moz"}, - {urlSuffix: "#ref"}, - {urlMatches: "v#ref$"}, - {originAndPathMatches: ".*://moz.*/"}, - ], url: "https://www.mozilla.org/sub/path?p1=v#ref"}, - - // None matches. - {shouldFail, filters: [ - {schemes: ["http"]}, - {ports: [80]}, - {hostEquals: "mozilla.com"}, - {hostContains: "www.moz"}, - {hostPrefix: "www"}, - {hostSuffix: "com"}, - {pathEquals: "/wrong/path"}, - {pathContains: "g/p"}, - {pathPrefix: "/wrong"}, - {pathSuffix: "/wrong"}, - {queryEquals: "p2=v"}, - {queryContains: "2="}, - {queryPrefix: "p2"}, - {querySuffix: "=value"}, - {urlEquals: "http://mozilla.com/sub/path?p1=v#ref"}, - {urlContains: "com/sub"}, - {urlPrefix: "http://moz"}, - {urlSuffix: "#ref2"}, - {urlMatches: "value#ref2$"}, - {originAndPathMatches: ".*://moz.*com/"}, - ], url: "https://mozilla.org/sub/path?p1=v#ref"}, - - // Some matches. - {shouldPass, filters: [ - {schemes: ["https"]}, - {ports: [80]}, - {hostEquals: "mozilla.com"}, - {hostContains: "www.moz"}, - {hostPrefix: "www"}, - {hostSuffix: "com"}, - {pathEquals: "/wrong/path"}, - {pathContains: "g/p"}, - {pathPrefix: "/wrong"}, - {pathSuffix: "/wrong"}, - {queryEquals: "p2=v"}, - {queryContains: "2="}, - {queryPrefix: "p2"}, - {querySuffix: "=value"}, - {urlEquals: "http://mozilla.com/sub/path?p1=v#ref"}, - {urlContains: "com/sub"}, - {urlPrefix: "http://moz"}, - {urlSuffix: "#ref2"}, - {urlMatches: "value#ref2$"}, - {originAndPathMatches: ".*://moz.*com/"}, - ], url: "https://mozilla.org/sub/path?p1=v#ref"}, - ]; - - // Run all the the testCases defined above. - for (let currentTest of testCases) { - let { - exceptionMessageContains, - url, filters, - } = currentTest; - - if (currentTest.shouldThrow) { - expectThrow({url, filters, exceptionMessageContains}) - } else if (currentTest.shouldFail) { - expectFail({url, filters}); - } else { - expectPass({url, filters}); - } - } -}); diff --git a/toolkit/modules/tests/xpcshell/test_NewTabUtils.js b/toolkit/modules/tests/xpcshell/test_NewTabUtils.js deleted file mode 100644 index 8cdb635501..0000000000 --- a/toolkit/modules/tests/xpcshell/test_NewTabUtils.js +++ /dev/null @@ -1,378 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -// See also browser/base/content/test/newtab/. - -var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components; -Cu.import("resource://gre/modules/NewTabUtils.jsm"); -Cu.import("resource://gre/modules/Promise.jsm"); -Cu.import("resource://gre/modules/Task.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -const PREF_NEWTAB_ENHANCED = "browser.newtabpage.enhanced"; - -function run_test() { - Services.prefs.setBoolPref(PREF_NEWTAB_ENHANCED, true); - run_next_test(); -} - -add_task(function* validCacheMidPopulation() { - let expectedLinks = makeLinks(0, 3, 1); - - let provider = new TestProvider(done => done(expectedLinks)); - provider.maxNumLinks = expectedLinks.length; - - NewTabUtils.initWithoutProviders(); - NewTabUtils.links.addProvider(provider); - let promise = new Promise(resolve => NewTabUtils.links.populateCache(resolve)); - - // isTopSiteGivenProvider() and getProviderLinks() should still return results - // even when cache is empty or being populated. - do_check_false(NewTabUtils.isTopSiteGivenProvider("example1.com", provider)); - do_check_links(NewTabUtils.getProviderLinks(provider), []); - - yield promise; - - // Once the cache is populated, we get the expected results - do_check_true(NewTabUtils.isTopSiteGivenProvider("example1.com", provider)); - do_check_links(NewTabUtils.getProviderLinks(provider), expectedLinks); - NewTabUtils.links.removeProvider(provider); -}); - -add_task(function* notifyLinkDelete() { - let expectedLinks = makeLinks(0, 3, 1); - - let provider = new TestProvider(done => done(expectedLinks)); - provider.maxNumLinks = expectedLinks.length; - - NewTabUtils.initWithoutProviders(); - NewTabUtils.links.addProvider(provider); - yield new Promise(resolve => NewTabUtils.links.populateCache(resolve)); - - do_check_links(NewTabUtils.links.getLinks(), expectedLinks); - - // Remove a link. - let removedLink = expectedLinks[2]; - provider.notifyLinkChanged(removedLink, 2, true); - let links = NewTabUtils.links._providers.get(provider); - - // Check that sortedLinks is correctly updated. - do_check_links(NewTabUtils.links.getLinks(), expectedLinks.slice(0, 2)); - - // Check that linkMap is accurately updated. - do_check_eq(links.linkMap.size, 2); - do_check_true(links.linkMap.get(expectedLinks[0].url)); - do_check_true(links.linkMap.get(expectedLinks[1].url)); - do_check_false(links.linkMap.get(removedLink.url)); - - // Check that siteMap is correctly updated. - do_check_eq(links.siteMap.size, 2); - do_check_true(links.siteMap.has(NewTabUtils.extractSite(expectedLinks[0].url))); - do_check_true(links.siteMap.has(NewTabUtils.extractSite(expectedLinks[1].url))); - do_check_false(links.siteMap.has(NewTabUtils.extractSite(removedLink.url))); - - NewTabUtils.links.removeProvider(provider); -}); - -add_task(function* populatePromise() { - let count = 0; - let expectedLinks = makeLinks(0, 10, 2); - - let getLinksFcn = Task.async(function* (callback) { - // Should not be calling getLinksFcn twice - count++; - do_check_eq(count, 1); - yield Promise.resolve(); - callback(expectedLinks); - }); - - let provider = new TestProvider(getLinksFcn); - - NewTabUtils.initWithoutProviders(); - NewTabUtils.links.addProvider(provider); - - NewTabUtils.links.populateProviderCache(provider, () => {}); - NewTabUtils.links.populateProviderCache(provider, () => { - do_check_links(NewTabUtils.links.getLinks(), expectedLinks); - NewTabUtils.links.removeProvider(provider); - }); -}); - -add_task(function* isTopSiteGivenProvider() { - let expectedLinks = makeLinks(0, 10, 2); - - // The lowest 2 frecencies have the same base domain. - expectedLinks[expectedLinks.length - 2].url = expectedLinks[expectedLinks.length - 1].url + "Test"; - - let provider = new TestProvider(done => done(expectedLinks)); - provider.maxNumLinks = expectedLinks.length; - - NewTabUtils.initWithoutProviders(); - NewTabUtils.links.addProvider(provider); - yield new Promise(resolve => NewTabUtils.links.populateCache(resolve)); - - do_check_eq(NewTabUtils.isTopSiteGivenProvider("example2.com", provider), true); - do_check_eq(NewTabUtils.isTopSiteGivenProvider("example1.com", provider), false); - - // Push out frecency 2 because the maxNumLinks is reached when adding frecency 3 - let newLink = makeLink(3); - provider.notifyLinkChanged(newLink); - - // There is still a frecent url with example2 domain, so it's still frecent. - do_check_eq(NewTabUtils.isTopSiteGivenProvider("example3.com", provider), true); - do_check_eq(NewTabUtils.isTopSiteGivenProvider("example2.com", provider), true); - - // Push out frecency 3 - newLink = makeLink(5); - provider.notifyLinkChanged(newLink); - - // Push out frecency 4 - newLink = makeLink(9); - provider.notifyLinkChanged(newLink); - - // Our count reached 0 for the example2.com domain so it's no longer a frecent site. - do_check_eq(NewTabUtils.isTopSiteGivenProvider("example5.com", provider), true); - do_check_eq(NewTabUtils.isTopSiteGivenProvider("example2.com", provider), false); - - NewTabUtils.links.removeProvider(provider); -}); - -add_task(function* multipleProviders() { - // Make each provider generate NewTabUtils.links.maxNumLinks links to check - // that no more than maxNumLinks are actually returned in the merged list. - let evenLinks = makeLinks(0, 2 * NewTabUtils.links.maxNumLinks, 2); - let evenProvider = new TestProvider(done => done(evenLinks)); - let oddLinks = makeLinks(0, 2 * NewTabUtils.links.maxNumLinks - 1, 2); - let oddProvider = new TestProvider(done => done(oddLinks)); - - NewTabUtils.initWithoutProviders(); - NewTabUtils.links.addProvider(evenProvider); - NewTabUtils.links.addProvider(oddProvider); - - yield new Promise(resolve => NewTabUtils.links.populateCache(resolve)); - - let links = NewTabUtils.links.getLinks(); - let expectedLinks = makeLinks(NewTabUtils.links.maxNumLinks, - 2 * NewTabUtils.links.maxNumLinks, - 1); - do_check_eq(links.length, NewTabUtils.links.maxNumLinks); - do_check_links(links, expectedLinks); - - NewTabUtils.links.removeProvider(evenProvider); - NewTabUtils.links.removeProvider(oddProvider); -}); - -add_task(function* changeLinks() { - let expectedLinks = makeLinks(0, 20, 2); - let provider = new TestProvider(done => done(expectedLinks)); - - NewTabUtils.initWithoutProviders(); - NewTabUtils.links.addProvider(provider); - - yield new Promise(resolve => NewTabUtils.links.populateCache(resolve)); - - do_check_links(NewTabUtils.links.getLinks(), expectedLinks); - - // Notify of a new link. - let newLink = makeLink(19); - expectedLinks.splice(1, 0, newLink); - provider.notifyLinkChanged(newLink); - do_check_links(NewTabUtils.links.getLinks(), expectedLinks); - - // Notify of a link that's changed sort criteria. - newLink.frecency = 17; - expectedLinks.splice(1, 1); - expectedLinks.splice(2, 0, newLink); - provider.notifyLinkChanged({ - url: newLink.url, - frecency: 17, - }); - do_check_links(NewTabUtils.links.getLinks(), expectedLinks); - - // Notify of a link that's changed title. - newLink.title = "My frecency is now 17"; - provider.notifyLinkChanged({ - url: newLink.url, - title: newLink.title, - }); - do_check_links(NewTabUtils.links.getLinks(), expectedLinks); - - // Notify of a new link again, but this time make it overflow maxNumLinks. - provider.maxNumLinks = expectedLinks.length; - newLink = makeLink(21); - expectedLinks.unshift(newLink); - expectedLinks.pop(); - do_check_eq(expectedLinks.length, provider.maxNumLinks); // Sanity check. - provider.notifyLinkChanged(newLink); - do_check_links(NewTabUtils.links.getLinks(), expectedLinks); - - // Notify of many links changed. - expectedLinks = makeLinks(0, 3, 1); - provider.notifyManyLinksChanged(); - - // Since _populateProviderCache() is async, we must wait until the provider's - // populate promise has been resolved. - yield NewTabUtils.links._providers.get(provider).populatePromise; - - // NewTabUtils.links will now repopulate its cache - do_check_links(NewTabUtils.links.getLinks(), expectedLinks); - - NewTabUtils.links.removeProvider(provider); -}); - -add_task(function* oneProviderAlreadyCached() { - let links1 = makeLinks(0, 10, 1); - let provider1 = new TestProvider(done => done(links1)); - - NewTabUtils.initWithoutProviders(); - NewTabUtils.links.addProvider(provider1); - - yield new Promise(resolve => NewTabUtils.links.populateCache(resolve)); - do_check_links(NewTabUtils.links.getLinks(), links1); - - let links2 = makeLinks(10, 20, 1); - let provider2 = new TestProvider(done => done(links2)); - NewTabUtils.links.addProvider(provider2); - - yield new Promise(resolve => NewTabUtils.links.populateCache(resolve)); - do_check_links(NewTabUtils.links.getLinks(), links2.concat(links1)); - - NewTabUtils.links.removeProvider(provider1); - NewTabUtils.links.removeProvider(provider2); -}); - -add_task(function* newLowRankedLink() { - // Init a provider with 10 links and make its maximum number also 10. - let links = makeLinks(0, 10, 1); - let provider = new TestProvider(done => done(links)); - provider.maxNumLinks = links.length; - - NewTabUtils.initWithoutProviders(); - NewTabUtils.links.addProvider(provider); - - yield new Promise(resolve => NewTabUtils.links.populateCache(resolve)); - do_check_links(NewTabUtils.links.getLinks(), links); - - // Notify of a new link that's low-ranked enough not to make the list. - let newLink = makeLink(0); - provider.notifyLinkChanged(newLink); - do_check_links(NewTabUtils.links.getLinks(), links); - - // Notify about the new link's title change. - provider.notifyLinkChanged({ - url: newLink.url, - title: "a new title", - }); - do_check_links(NewTabUtils.links.getLinks(), links); - - NewTabUtils.links.removeProvider(provider); -}); - -add_task(function* extractSite() { - // All these should extract to the same site - [ "mozilla.org", - "m.mozilla.org", - "mobile.mozilla.org", - "www.mozilla.org", - "www3.mozilla.org", - ].forEach(host => { - let url = "http://" + host; - do_check_eq(NewTabUtils.extractSite(url), "mozilla.org", "extracted same " + host); - }); - - // All these should extract to the same subdomain - [ "bugzilla.mozilla.org", - "www.bugzilla.mozilla.org", - ].forEach(host => { - let url = "http://" + host; - do_check_eq(NewTabUtils.extractSite(url), "bugzilla.mozilla.org", "extracted eTLD+2 " + host); - }); - - // All these should not extract to the same site - [ "bugzilla.mozilla.org", - "bug123.bugzilla.mozilla.org", - "too.many.levels.bugzilla.mozilla.org", - "m2.mozilla.org", - "mobile30.mozilla.org", - "ww.mozilla.org", - "ww2.mozilla.org", - "wwwww.mozilla.org", - "wwwww50.mozilla.org", - "wwws.mozilla.org", - "secure.mozilla.org", - "secure10.mozilla.org", - "many.levels.deep.mozilla.org", - "just.check.in", - "192.168.0.1", - "localhost", - ].forEach(host => { - let url = "http://" + host; - do_check_neq(NewTabUtils.extractSite(url), "mozilla.org", "extracted diff " + host); - }); - - // All these should not extract to the same site - [ "about:blank", - "file:///Users/user/file", - "chrome://browser/something", - "ftp://ftp.mozilla.org/", - ].forEach(url => { - do_check_neq(NewTabUtils.extractSite(url), "mozilla.org", "extracted diff url " + url); - }); -}); - -function TestProvider(getLinksFn) { - this.getLinks = getLinksFn; - this._observers = new Set(); -} - -TestProvider.prototype = { - addObserver: function (observer) { - this._observers.add(observer); - }, - notifyLinkChanged: function (link, index=-1, deleted=false) { - this._notifyObservers("onLinkChanged", link, index, deleted); - }, - notifyManyLinksChanged: function () { - this._notifyObservers("onManyLinksChanged"); - }, - _notifyObservers: function () { - let observerMethodName = arguments[0]; - let args = Array.prototype.slice.call(arguments, 1); - args.unshift(this); - for (let obs of this._observers) { - if (obs[observerMethodName]) - obs[observerMethodName].apply(NewTabUtils.links, args); - } - }, -}; - -function do_check_links(actualLinks, expectedLinks) { - do_check_true(Array.isArray(actualLinks)); - do_check_eq(actualLinks.length, expectedLinks.length); - for (let i = 0; i < expectedLinks.length; i++) { - let expected = expectedLinks[i]; - let actual = actualLinks[i]; - do_check_eq(actual.url, expected.url); - do_check_eq(actual.title, expected.title); - do_check_eq(actual.frecency, expected.frecency); - do_check_eq(actual.lastVisitDate, expected.lastVisitDate); - } -} - -function makeLinks(frecRangeStart, frecRangeEnd, step) { - let links = []; - // Remember, links are ordered by frecency descending. - for (let i = frecRangeEnd; i > frecRangeStart; i -= step) { - links.push(makeLink(i)); - } - return links; -} - -function makeLink(frecency) { - return { - url: "http://example" + frecency + ".com/", - title: "My frecency is " + frecency, - frecency: frecency, - lastVisitDate: 0, - }; -} diff --git a/toolkit/modules/tests/xpcshell/test_ObjectUtils.js b/toolkit/modules/tests/xpcshell/test_ObjectUtils.js deleted file mode 100644 index 9aef3e9079..0000000000 --- a/toolkit/modules/tests/xpcshell/test_ObjectUtils.js +++ /dev/null @@ -1,96 +0,0 @@ -Components.utils.import("resource://gre/modules/ObjectUtils.jsm"); - -function run_test() { - run_next_test(); -} - -add_task(function* test_deepEqual() { - let deepEqual = ObjectUtils.deepEqual.bind(ObjectUtils); - // CommonJS 7.2 - Assert.ok(deepEqual(new Date(2000, 3, 14), new Date(2000, 3, 14)), "deepEqual date"); - Assert.ok(deepEqual(new Date(NaN), new Date(NaN)), "deepEqual invalid dates"); - - Assert.ok(!deepEqual(new Date(), new Date(2000, 3, 14)), "deepEqual date"); - - // 7.3 - Assert.ok(deepEqual(/a/, /a/)); - Assert.ok(deepEqual(/a/g, /a/g)); - Assert.ok(deepEqual(/a/i, /a/i)); - Assert.ok(deepEqual(/a/m, /a/m)); - Assert.ok(deepEqual(/a/igm, /a/igm)); - Assert.ok(!deepEqual(/ab/, /a/)); - Assert.ok(!deepEqual(/a/g, /a/)); - Assert.ok(!deepEqual(/a/i, /a/)); - Assert.ok(!deepEqual(/a/m, /a/)); - Assert.ok(!deepEqual(/a/igm, /a/im)); - - let re1 = /a/; - re1.lastIndex = 3; - Assert.ok(!deepEqual(re1, /a/)); - - // 7.4 - Assert.ok(deepEqual(4, "4"), "deepEqual == check"); - Assert.ok(deepEqual(true, 1), "deepEqual == check"); - Assert.ok(!deepEqual(4, "5"), "deepEqual == check"); - - // 7.5 - // having the same number of owned properties && the same set of keys - Assert.ok(deepEqual({a: 4}, {a: 4})); - Assert.ok(deepEqual({a: 4, b: "2"}, {a: 4, b: "2"})); - Assert.ok(deepEqual([4], ["4"])); - Assert.ok(!deepEqual({a: 4}, {a: 4, b: true})); - Assert.ok(deepEqual(["a"], {0: "a"})); - - let a1 = [1, 2, 3]; - let a2 = [1, 2, 3]; - a1.a = "test"; - a1.b = true; - a2.b = true; - a2.a = "test"; - Assert.ok(!deepEqual(Object.keys(a1), Object.keys(a2))); - Assert.ok(deepEqual(a1, a2)); - - let nbRoot = { - toString: function() { return this.first + " " + this.last; } - }; - - function nameBuilder(first, last) { - this.first = first; - this.last = last; - return this; - } - nameBuilder.prototype = nbRoot; - - function nameBuilder2(first, last) { - this.first = first; - this.last = last; - return this; - } - nameBuilder2.prototype = nbRoot; - - let nb1 = new nameBuilder("Ryan", "Dahl"); - let nb2 = new nameBuilder2("Ryan", "Dahl"); - - Assert.ok(deepEqual(nb1, nb2)); - - nameBuilder2.prototype = Object; - nb2 = new nameBuilder2("Ryan", "Dahl"); - Assert.ok(!deepEqual(nb1, nb2)); - - // String literal + object - Assert.ok(!deepEqual("a", {})); - - // Make sure deepEqual doesn't loop forever on circular refs - - let b = {}; - b.b = b; - - let c = {}; - c.b = c; - - try { - Assert.ok(!deepEqual(b, c)); - } catch (e) { - Assert.ok(true, "Didn't recurse infinitely."); - } -}); diff --git a/toolkit/modules/tests/xpcshell/test_ObjectUtils_strict.js b/toolkit/modules/tests/xpcshell/test_ObjectUtils_strict.js deleted file mode 100644 index 44572e6001..0000000000 --- a/toolkit/modules/tests/xpcshell/test_ObjectUtils_strict.js +++ /dev/null @@ -1,29 +0,0 @@ -"use strict"; - -var {ObjectUtils} = Components.utils.import("resource://gre/modules/ObjectUtils.jsm", {}); -var {PromiseTestUtils} = Components.utils.import("resource://testing-common/PromiseTestUtils.jsm", {}); - -add_task(function* test_strict() { - let loose = { a: 1 }; - let strict = ObjectUtils.strict(loose); - - loose.a; // Should not throw. - loose.b || undefined; // Should not throw. - - strict.a; // Should not throw. - PromiseTestUtils.expectUncaughtRejection(/No such property: "b"/); - Assert.throws(() => strict.b, /No such property: "b"/); - "b" in strict; // Should not throw. - strict.b = 2; - strict.b; // Should not throw. - - PromiseTestUtils.expectUncaughtRejection(/No such property: "c"/); - Assert.throws(() => strict.c, /No such property: "c"/); - "c" in strict; // Should not throw. - loose.c = 3; - strict.c; // Should not throw. -}); - -function run_test() { - run_next_test(); -} diff --git a/toolkit/modules/tests/xpcshell/test_PermissionsUtils.js b/toolkit/modules/tests/xpcshell/test_PermissionsUtils.js deleted file mode 100644 index 3982ce0151..0000000000 --- a/toolkit/modules/tests/xpcshell/test_PermissionsUtils.js +++ /dev/null @@ -1,85 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -// Tests that PerrmissionsUtils.jsm works as expected, including: -// * PermissionsUtils.importfromPrefs() -// <ROOT>.[whitelist|blacklist].add preferences are emptied when -// converted into permissions on startup. - - -const PREF_ROOT = "testpermissions."; -const TEST_PERM = "test-permission"; - -Components.utils.import("resource://gre/modules/Services.jsm"); -Components.utils.import("resource://gre/modules/PermissionsUtils.jsm"); - -function run_test() { - test_importfromPrefs(); -} - - -function test_importfromPrefs() { - // Create own preferences to test - Services.prefs.setCharPref(PREF_ROOT + "whitelist.add.EMPTY", ""); - Services.prefs.setCharPref(PREF_ROOT + "whitelist.add.EMPTY2", ","); - Services.prefs.setCharPref(PREF_ROOT + "whitelist.add.TEST", "http://whitelist.example.com"); - Services.prefs.setCharPref(PREF_ROOT + "whitelist.add.TEST2", "https://whitelist2-1.example.com,http://whitelist2-2.example.com:8080,about:home"); - Services.prefs.setCharPref(PREF_ROOT + "whitelist.add.TEST3", "whitelist3-1.example.com,about:config"); // legacy style - host only - Services.prefs.setCharPref(PREF_ROOT + "blacklist.add.EMPTY", ""); - Services.prefs.setCharPref(PREF_ROOT + "blacklist.add.TEST", "http://blacklist.example.com,"); - Services.prefs.setCharPref(PREF_ROOT + "blacklist.add.TEST2", ",https://blacklist2-1.example.com,http://blacklist2-2.example.com:8080,about:mozilla"); - Services.prefs.setCharPref(PREF_ROOT + "blacklist.add.TEST3", "blacklist3-1.example.com,about:preferences"); // legacy style - host only - - // Check they are unknown in the permission manager prior to importing. - let whitelisted = ["http://whitelist.example.com", - "https://whitelist2-1.example.com", - "http://whitelist2-2.example.com:8080", - "http://whitelist3-1.example.com", - "https://whitelist3-1.example.com", - "about:config", - "about:home"]; - let blacklisted = ["http://blacklist.example.com", - "https://blacklist2-1.example.com", - "http://blacklist2-2.example.com:8080", - "http://blacklist3-1.example.com", - "https://blacklist3-1.example.com", - "about:preferences", - "about:mozilla"]; - let untouched = ["https://whitelist.example.com", - "https://blacklist.example.com", - "http://whitelist2-1.example.com", - "http://blacklist2-1.example.com", - "https://whitelist2-2.example.com:8080", - "https://blacklist2-2.example.com:8080"]; - let unknown = whitelisted.concat(blacklisted).concat(untouched); - for (let url of unknown) { - let uri = Services.io.newURI(url, null, null); - do_check_eq(Services.perms.testPermission(uri, TEST_PERM), Services.perms.UNKNOWN_ACTION); - } - - // Import them - PermissionsUtils.importFromPrefs(PREF_ROOT, TEST_PERM); - - // Get list of preferences to check - let preferences = Services.prefs.getChildList(PREF_ROOT, {}); - - // Check preferences were emptied - for (let pref of preferences) { - do_check_eq(Services.prefs.getCharPref(pref), ""); - } - - // Check they were imported into the permissions manager - for (let url of whitelisted) { - let uri = Services.io.newURI(url, null, null); - do_check_eq(Services.perms.testPermission(uri, TEST_PERM), Services.perms.ALLOW_ACTION); - } - for (let url of blacklisted) { - let uri = Services.io.newURI(url, null, null); - do_check_eq(Services.perms.testPermission(uri, TEST_PERM), Services.perms.DENY_ACTION); - } - for (let url of untouched) { - let uri = Services.io.newURI(url, null, null); - do_check_eq(Services.perms.testPermission(uri, TEST_PERM), Services.perms.UNKNOWN_ACTION); - } -} diff --git a/toolkit/modules/tests/xpcshell/test_Preferences.js b/toolkit/modules/tests/xpcshell/test_Preferences.js deleted file mode 100644 index ef430909fd..0000000000 --- a/toolkit/modules/tests/xpcshell/test_Preferences.js +++ /dev/null @@ -1,378 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -var {classes: Cc, interfaces: Ci, results: Cr, utils: Cu, manager: Cm} = Components; - -Cu.import("resource://gre/modules/Preferences.jsm"); - -function run_test() { - run_next_test(); -} - -add_test(function test_set_get_pref() { - Preferences.set("test_set_get_pref.integer", 1); - do_check_eq(Preferences.get("test_set_get_pref.integer"), 1); - - Preferences.set("test_set_get_pref.string", "foo"); - do_check_eq(Preferences.get("test_set_get_pref.string"), "foo"); - - Preferences.set("test_set_get_pref.boolean", true); - do_check_eq(Preferences.get("test_set_get_pref.boolean"), true); - - // Clean up. - Preferences.resetBranch("test_set_get_pref."); - - run_next_test(); -}); - -add_test(function test_set_get_branch_pref() { - let prefs = new Preferences("test_set_get_branch_pref."); - - prefs.set("something", 1); - do_check_eq(prefs.get("something"), 1); - do_check_false(Preferences.has("something")); - - // Clean up. - prefs.reset("something"); - - run_next_test(); -}); - -add_test(function test_set_get_multiple_prefs() { - Preferences.set({ "test_set_get_multiple_prefs.integer": 1, - "test_set_get_multiple_prefs.string": "foo", - "test_set_get_multiple_prefs.boolean": true }); - - let [i, s, b] = Preferences.get(["test_set_get_multiple_prefs.integer", - "test_set_get_multiple_prefs.string", - "test_set_get_multiple_prefs.boolean"]); - - do_check_eq(i, 1); - do_check_eq(s, "foo"); - do_check_eq(b, true); - - // Clean up. - Preferences.resetBranch("test_set_get_multiple_prefs."); - - run_next_test(); -}); - -add_test(function test_get_multiple_prefs_with_default_value() { - Preferences.set({ "test_get_multiple_prefs_with_default_value.a": 1, - "test_get_multiple_prefs_with_default_value.b": 2 }); - - let [a, b, c] = Preferences.get(["test_get_multiple_prefs_with_default_value.a", - "test_get_multiple_prefs_with_default_value.b", - "test_get_multiple_prefs_with_default_value.c"], - 0); - - do_check_eq(a, 1); - do_check_eq(b, 2); - do_check_eq(c, 0); - - // Clean up. - Preferences.resetBranch("test_get_multiple_prefs_with_default_value."); - - run_next_test(); -}); - -add_test(function test_set_get_unicode_pref() { - Preferences.set("test_set_get_unicode_pref", String.fromCharCode(960)); - do_check_eq(Preferences.get("test_set_get_unicode_pref"), String.fromCharCode(960)); - - // Clean up. - Preferences.reset("test_set_get_unicode_pref"); - - run_next_test(); -}); - -add_test(function test_set_null_pref() { - try { - Preferences.set("test_set_null_pref", null); - // We expect this to throw, so the test is designed to fail if it doesn't. - do_check_true(false); - } - catch (ex) {} - - run_next_test(); -}); - -add_test(function test_set_undefined_pref() { - try { - Preferences.set("test_set_undefined_pref"); - // We expect this to throw, so the test is designed to fail if it doesn't. - do_check_true(false); - } - catch (ex) {} - - run_next_test(); -}); - -add_test(function test_set_unsupported_pref() { - try { - Preferences.set("test_set_unsupported_pref", new Array()); - // We expect this to throw, so the test is designed to fail if it doesn't. - do_check_true(false); - } - catch (ex) {} - - run_next_test(); -}); - -// Make sure that we can get a string pref that we didn't set ourselves -// (i.e. that the way we get a string pref using getComplexValue doesn't -// hork us getting a string pref that wasn't set using setComplexValue). -add_test(function test_get_string_pref() { - let svc = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefService). - getBranch(""); - svc.setCharPref("test_get_string_pref", "a normal string"); - do_check_eq(Preferences.get("test_get_string_pref"), "a normal string"); - - // Clean up. - Preferences.reset("test_get_string_pref"); - - run_next_test(); -}); - -add_test(function test_get_localized_string_pref() { - let svc = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefService). - getBranch(""); - let prefName = "test_get_localized_string_pref"; - let localizedString = Cc["@mozilla.org/pref-localizedstring;1"] - .createInstance(Ci.nsIPrefLocalizedString); - localizedString.data = "a localized string"; - svc.setComplexValue(prefName, Ci.nsIPrefLocalizedString, localizedString); - do_check_eq(Preferences.get(prefName, null, Ci.nsIPrefLocalizedString), - "a localized string"); - - // Clean up. - Preferences.reset(prefName); - - run_next_test(); -}); - -add_test(function test_set_get_number_pref() { - Preferences.set("test_set_get_number_pref", 5); - do_check_eq(Preferences.get("test_set_get_number_pref"), 5); - - // Non-integer values get converted to integers. - Preferences.set("test_set_get_number_pref", 3.14159); - do_check_eq(Preferences.get("test_set_get_number_pref"), 3); - - // Values outside the range -(2^31-1) to 2^31-1 overflow. - try { - Preferences.set("test_set_get_number_pref", Math.pow(2, 31)); - // We expect this to throw, so the test is designed to fail if it doesn't. - do_check_true(false); - } - catch (ex) {} - - // Clean up. - Preferences.reset("test_set_get_number_pref"); - - run_next_test(); -}); - -add_test(function test_reset_pref() { - Preferences.set("test_reset_pref", 1); - Preferences.reset("test_reset_pref"); - do_check_eq(Preferences.get("test_reset_pref"), undefined); - - run_next_test(); -}); - -add_test(function test_reset_pref_branch() { - Preferences.set("test_reset_pref_branch.foo", 1); - Preferences.set("test_reset_pref_branch.bar", 2); - Preferences.resetBranch("test_reset_pref_branch."); - do_check_eq(Preferences.get("test_reset_pref_branch.foo"), undefined); - do_check_eq(Preferences.get("test_reset_pref_branch.bar"), undefined); - - run_next_test(); -}); - -// Make sure the module doesn't throw an exception when asked to reset -// a nonexistent pref. -add_test(function test_reset_nonexistent_pref() { - Preferences.reset("test_reset_nonexistent_pref"); - - run_next_test(); -}); - -// Make sure the module doesn't throw an exception when asked to reset -// a nonexistent pref branch. -add_test(function test_reset_nonexistent_pref_branch() { - Preferences.resetBranch("test_reset_nonexistent_pref_branch."); - - run_next_test(); -}); - -add_test(function test_observe_prefs_function() { - let observed = false; - let observer = function() { observed = !observed }; - - Preferences.observe("test_observe_prefs_function", observer); - Preferences.set("test_observe_prefs_function", "something"); - do_check_true(observed); - - Preferences.ignore("test_observe_prefs_function", observer); - Preferences.set("test_observe_prefs_function", "something else"); - do_check_true(observed); - - // Clean up. - Preferences.reset("test_observe_prefs_function"); - - run_next_test(); -}); - -add_test(function test_observe_prefs_object() { - let observer = { - observed: false, - observe: function() { - this.observed = !this.observed; - } - }; - - Preferences.observe("test_observe_prefs_object", observer.observe, observer); - Preferences.set("test_observe_prefs_object", "something"); - do_check_true(observer.observed); - - Preferences.ignore("test_observe_prefs_object", observer.observe, observer); - Preferences.set("test_observe_prefs_object", "something else"); - do_check_true(observer.observed); - - // Clean up. - Preferences.reset("test_observe_prefs_object"); - - run_next_test(); -}); - -add_test(function test_observe_prefs_nsIObserver() { - let observer = { - observed: false, - observe: function(subject, topic, data) { - this.observed = !this.observed; - do_check_true(subject instanceof Ci.nsIPrefBranch); - do_check_eq(topic, "nsPref:changed"); - do_check_eq(data, "test_observe_prefs_nsIObserver"); - } - }; - - Preferences.observe("test_observe_prefs_nsIObserver", observer); - Preferences.set("test_observe_prefs_nsIObserver", "something"); - do_check_true(observer.observed); - - Preferences.ignore("test_observe_prefs_nsIObserver", observer); - Preferences.set("test_observe_prefs_nsIObserver", "something else"); - do_check_true(observer.observed); - - // Clean up. - Preferences.reset("test_observe_prefs_nsIObserver"); - - run_next_test(); -}); - -/* -add_test(function test_observe_exact_pref() { - let observed = false; - let observer = function() { observed = !observed }; - - Preferences.observe("test_observe_exact_pref", observer); - Preferences.set("test_observe_exact_pref.sub-pref", "something"); - do_check_false(observed); - - // Clean up. - Preferences.ignore("test_observe_exact_pref", observer); - Preferences.reset("test_observe_exact_pref.sub-pref"); - - run_next_test(); -}); -*/ - -add_test(function test_observe_value_of_set_pref() { - let observer = function(newVal) { do_check_eq(newVal, "something") }; - - Preferences.observe("test_observe_value_of_set_pref", observer); - Preferences.set("test_observe_value_of_set_pref", "something"); - - // Clean up. - Preferences.ignore("test_observe_value_of_set_pref", observer); - Preferences.reset("test_observe_value_of_set_pref"); - - run_next_test(); -}); - -add_test(function test_observe_value_of_reset_pref() { - let observer = function(newVal) { do_check_true(typeof newVal == "undefined") }; - - Preferences.set("test_observe_value_of_reset_pref", "something"); - Preferences.observe("test_observe_value_of_reset_pref", observer); - Preferences.reset("test_observe_value_of_reset_pref"); - - // Clean up. - Preferences.ignore("test_observe_value_of_reset_pref", observer); - - run_next_test(); -}); - -add_test(function test_has_pref() { - do_check_false(Preferences.has("test_has_pref")); - Preferences.set("test_has_pref", "foo"); - do_check_true(Preferences.has("test_has_pref")); - - Preferences.set("test_has_pref.foo", "foo"); - Preferences.set("test_has_pref.bar", "bar"); - let [hasFoo, hasBar, hasBaz] = Preferences.has(["test_has_pref.foo", - "test_has_pref.bar", - "test_has_pref.baz"]); - do_check_true(hasFoo); - do_check_true(hasBar); - do_check_false(hasBaz); - - // Clean up. - Preferences.resetBranch("test_has_pref"); - - run_next_test(); -}); - -add_test(function test_isSet_pref() { - // Use a pref that we know has a default value but no user-set value. - // This feels dangerous; perhaps we should create some other default prefs - // that we can use for testing. - do_check_false(Preferences.isSet("toolkit.defaultChromeURI")); - Preferences.set("toolkit.defaultChromeURI", "foo"); - do_check_true(Preferences.isSet("toolkit.defaultChromeURI")); - - // Clean up. - Preferences.reset("toolkit.defaultChromeURI"); - - run_next_test(); -}); - -/* -add_test(function test_lock_prefs() { - // Use a pref that we know has a default value. - // This feels dangerous; perhaps we should create some other default prefs - // that we can use for testing. - do_check_false(Preferences.locked("toolkit.defaultChromeURI")); - Preferences.lock("toolkit.defaultChromeURI"); - do_check_true(Preferences.locked("toolkit.defaultChromeURI")); - Preferences.unlock("toolkit.defaultChromeURI"); - do_check_false(Preferences.locked("toolkit.defaultChromeURI")); - - let val = Preferences.get("toolkit.defaultChromeURI"); - Preferences.set("toolkit.defaultChromeURI", "test_lock_prefs"); - do_check_eq(Preferences.get("toolkit.defaultChromeURI"), "test_lock_prefs"); - Preferences.lock("toolkit.defaultChromeURI"); - do_check_eq(Preferences.get("toolkit.defaultChromeURI"), val); - Preferences.unlock("toolkit.defaultChromeURI"); - do_check_eq(Preferences.get("toolkit.defaultChromeURI"), "test_lock_prefs"); - - // Clean up. - Preferences.reset("toolkit.defaultChromeURI"); - - run_next_test(); -}); -*/ diff --git a/toolkit/modules/tests/xpcshell/test_Promise.js b/toolkit/modules/tests/xpcshell/test_Promise.js deleted file mode 100644 index 6c72206922..0000000000 --- a/toolkit/modules/tests/xpcshell/test_Promise.js +++ /dev/null @@ -1,1105 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -Components.utils.import("resource://gre/modules/Promise.jsm"); -Components.utils.import("resource://gre/modules/Services.jsm"); -Components.utils.import("resource://gre/modules/Task.jsm"); -Components.utils.import("resource://testing-common/PromiseTestUtils.jsm"); - -// Prevent test failures due to the unhandled rejections in this test file. -PromiseTestUtils.disableUncaughtRejectionObserverForSelfTest(); - -// Test runner - -var run_promise_tests = function run_promise_tests(tests, cb) { - let loop = function loop(index) { - if (index >= tests.length) { - if (cb) { - cb.call(); - } - return; - } - do_print("Launching test " + (index + 1) + "/" + tests.length); - let test = tests[index]; - // Execute from an empty stack - let next = function next() { - do_print("Test " + (index + 1) + "/" + tests.length + " complete"); - do_execute_soon(function() { - loop(index + 1); - }); - }; - let result = test(); - result.then(next, next); - }; - return loop(0); -}; - -var make_promise_test = function(test) { - return function runtest() { - do_print("Test starting: " + test.name); - try { - let result = test(); - if (result && "promise" in result) { - result = result.promise; - } - if (!result || !("then" in result)) { - let exn; - try { - do_throw("Test " + test.name + " did not return a promise: " + result); - } catch (x) { - exn = x; - } - return Promise.reject(exn); - } - // The test returns a promise - result = result.then( - // Test complete - function onResolve() { - do_print("Test complete: " + test.name); - }, - // The test failed with an unexpected error - function onReject(err) { - let detail; - if (err && typeof err == "object" && "stack" in err) { - detail = err.stack; - } else { - detail = "(no stack)"; - } - do_throw("Test " + test.name + " rejected with the following reason: " - + err + detail); - }); - return result; - } catch (x) { - // The test failed because of an error outside of a promise - do_throw("Error in body of test " + test.name + ": " + x + " at " + x.stack); - return Promise.reject(); - } - }; -}; - -// Tests - -var tests = []; - -// Utility function to observe an failures in a promise -// This function is useful if the promise itself is -// not returned. -var observe_failures = function observe_failures(promise) { - promise.catch(function onReject(reason) { - test.do_throw("Observed failure in test " + test + ": " + reason); - }); -}; - -// Test that all observers are notified -tests.push(make_promise_test( - function notification(test) { - // The size of the test - const SIZE = 10; - const RESULT = "this is an arbitrary value"; - - // Number of observers that yet need to be notified - let expected = SIZE; - - // |true| once an observer has been notified - let notified = []; - - // The promise observed - let source = Promise.defer(); - let result = Promise.defer(); - - let install_observer = function install_observer(i) { - observe_failures(source.promise.then( - function onSuccess(value) { - do_check_true(!notified[i], "Ensuring that observer is notified at most once"); - notified[i] = true; - - do_check_eq(value, RESULT, "Ensuring that the observed value is correct"); - if (--expected == 0) { - result.resolve(); - } - })); - }; - - // Install a number of observers before resolving - let i; - for (i = 0; i < SIZE/2; ++i) { - install_observer(i); - } - - source.resolve(RESULT); - - // Install remaining observers - for (;i < SIZE; ++i) { - install_observer(i); - } - - return result; - })); - -// Test that observers get the correct "this" value in strict mode. -tests.push( - make_promise_test(function handlers_this_value(test) { - return Promise.resolve().then( - function onResolve() { - // Since this file is in strict mode, the correct value is "undefined". - do_check_eq(this, undefined); - throw "reject"; - } - ).then( - null, - function onReject() { - // Since this file is in strict mode, the correct value is "undefined". - do_check_eq(this, undefined); - } - ); - })); - -// Test that observers registered on a pending promise are notified in order. -tests.push( - make_promise_test(function then_returns_before_callbacks(test) { - let deferred = Promise.defer(); - let promise = deferred.promise; - - let order = 0; - - promise.then( - function onResolve() { - do_check_eq(order, 0); - order++; - } - ); - - promise.then( - function onResolve() { - do_check_eq(order, 1); - order++; - } - ); - - let newPromise = promise.then( - function onResolve() { - do_check_eq(order, 2); - } - ); - - deferred.resolve(); - - // This test finishes after the last handler succeeds. - return newPromise; - })); - -// Test that observers registered on a resolved promise are notified in order. -tests.push( - make_promise_test(function then_returns_before_callbacks(test) { - let promise = Promise.resolve(); - - let order = 0; - - promise.then( - function onResolve() { - do_check_eq(order, 0); - order++; - } - ); - - promise.then( - function onResolve() { - do_check_eq(order, 1); - order++; - } - ); - - // This test finishes after the last handler succeeds. - return promise.then( - function onResolve() { - do_check_eq(order, 2); - } - ); - })); - -// Test that all observers are notified at most once, even if source -// is resolved/rejected several times -tests.push(make_promise_test( - function notification_once(test) { - // The size of the test - const SIZE = 10; - const RESULT = "this is an arbitrary value"; - - // Number of observers that yet need to be notified - let expected = SIZE; - - // |true| once an observer has been notified - let notified = []; - - // The promise observed - let observed = Promise.defer(); - let result = Promise.defer(); - - let install_observer = function install_observer(i) { - observe_failures(observed.promise.then( - function onSuccess(value) { - do_check_true(!notified[i], "Ensuring that observer is notified at most once"); - notified[i] = true; - - do_check_eq(value, RESULT, "Ensuring that the observed value is correct"); - if (--expected == 0) { - result.resolve(); - } - })); - }; - - // Install a number of observers before resolving - let i; - for (i = 0; i < SIZE/2; ++i) { - install_observer(i); - } - - observed.resolve(RESULT); - - // Install remaining observers - for (;i < SIZE; ++i) { - install_observer(i); - } - - // Resolve some more - for (i = 0; i < 10; ++i) { - observed.resolve(RESULT); - observed.reject(); - } - - return result; - })); - -// Test that throwing an exception from a onResolve listener -// does not prevent other observers from receiving the notification -// of success. -tests.push( - make_promise_test(function exceptions_do_not_stop_notifications(test) { - let source = Promise.defer(); - - let exception_thrown = false; - let exception_content = new Error("Boom!"); - - let observer_1 = source.promise.then( - function onResolve() { - exception_thrown = true; - throw exception_content; - }); - - let observer_2 = source.promise.then( - function onResolve() { - do_check_true(exception_thrown, "Second observer called after first observer has thrown"); - } - ); - - let result = observer_1.then( - function onResolve() { - do_throw("observer_1 should not have resolved"); - }, - function onReject(reason) { - do_check_true(reason == exception_content, "Obtained correct rejection"); - } - ); - - source.resolve(); - return result; - } -)); - -// Test that, once a promise is resolved, further resolve/reject -// are ignored. -tests.push( - make_promise_test(function subsequent_resolves_are_ignored(test) { - let deferred = Promise.defer(); - deferred.resolve(1); - deferred.resolve(2); - deferred.reject(3); - - let result = deferred.promise.then( - function onResolve(value) { - do_check_eq(value, 1, "Resolution chose the first value"); - }, - function onReject(reason) { - do_throw("Obtained a rejection while the promise was already resolved"); - } - ); - - return result; - })); - -// Test that, once a promise is rejected, further resolve/reject -// are ignored. -tests.push( - make_promise_test(function subsequent_rejects_are_ignored(test) { - let deferred = Promise.defer(); - deferred.reject(1); - deferred.reject(2); - deferred.resolve(3); - - let result = deferred.promise.then( - function onResolve() { - do_throw("Obtained a resolution while the promise was already rejected"); - }, - function onReject(reason) { - do_check_eq(reason, 1, "Rejection chose the first value"); - } - ); - - return result; - })); - -// Test that returning normally from a rejection recovers from the error -// and that listeners are informed of a success. -tests.push( - make_promise_test(function recovery(test) { - let boom = new Error("Boom!"); - let deferred = Promise.defer(); - const RESULT = "An arbitrary value"; - - let promise = deferred.promise.then( - function onResolve() { - do_throw("A rejected promise should not resolve"); - }, - function onReject(reason) { - do_check_true(reason == boom, "Promise was rejected with the correct error"); - return RESULT; - } - ); - - promise = promise.then( - function onResolve(value) { - do_check_eq(value, RESULT, "Promise was recovered with the correct value"); - } - ); - - deferred.reject(boom); - return promise; - })); - -// Test that returning a resolved promise from a onReject causes a resolution -// (recovering from the error) and that returning a rejected promise -// from a onResolve listener causes a rejection (raising an error). -tests.push( - make_promise_test(function recovery_with_promise(test) { - let boom = new Error("Arbitrary error"); - let deferred = Promise.defer(); - const RESULT = "An arbitrary value"; - const boom2 = new Error("Another arbitrary error"); - - // return a resolved promise from a onReject listener - let promise = deferred.promise.then( - function onResolve() { - do_throw("A rejected promise should not resolve"); - }, - function onReject(reason) { - do_check_true(reason == boom, "Promise was rejected with the correct error"); - return Promise.resolve(RESULT); - } - ); - - // return a rejected promise from a onResolve listener - promise = promise.then( - function onResolve(value) { - do_check_eq(value, RESULT, "Promise was recovered with the correct value"); - return Promise.reject(boom2); - } - ); - - promise = promise.catch( - function onReject(reason) { - do_check_eq(reason, boom2, "Rejection was propagated with the correct " + - "reason, through a promise"); - } - ); - - deferred.reject(boom); - return promise; - })); - -// Test that we can resolve with promises of promises -tests.push( - make_promise_test(function test_propagation(test) { - const RESULT = "Yet another arbitrary value"; - let d1 = Promise.defer(); - let d2 = Promise.defer(); - let d3 = Promise.defer(); - - d3.resolve(d2.promise); - d2.resolve(d1.promise); - d1.resolve(RESULT); - - return d3.promise.then( - function onSuccess(value) { - do_check_eq(value, RESULT, "Resolution with a promise eventually yielded " - + " the correct result"); - } - ); - })); - -// Test sequences of |then| and |catch| -tests.push( - make_promise_test(function test_chaining(test) { - let error_1 = new Error("Error 1"); - let error_2 = new Error("Error 2"); - let result_1 = "First result"; - let result_2 = "Second result"; - let result_3 = "Third result"; - - let source = Promise.defer(); - - let promise = source.promise.then().then(); - - source.resolve(result_1); - - // Check that result_1 is correctly propagated - promise = promise.then( - function onSuccess(result) { - do_check_eq(result, result_1, "Result was propagated correctly through " + - " several applications of |then|"); - return result_2; - } - ); - - // Check that returning from the promise produces a resolution - promise = promise.catch( - function onReject() { - do_throw("Incorrect rejection"); - } - ); - - // ... and that the check did not alter the value - promise = promise.then( - function onResolve(value) { - do_check_eq(value, result_2, "Result was propagated correctly once again"); - } - ); - - // Now the same kind of tests for rejections - promise = promise.then( - function onResolve() { - throw error_1; - } - ); - - promise = promise.then( - function onResolve() { - do_throw("Incorrect resolution: the exception should have caused a rejection"); - } - ); - - promise = promise.catch( - function onReject(reason) { - do_check_true(reason == error_1, "Reason was propagated correctly"); - throw error_2; - } - ); - - promise = promise.catch( - function onReject(reason) { - do_check_true(reason == error_2, "Throwing an error altered the reason " + - "as expected"); - return result_3; - } - ); - - promise = promise.then( - function onResolve(result) { - do_check_eq(result, result_3, "Error was correctly recovered"); - } - ); - - return promise; - })); - -// Test that resolving with a rejected promise actually rejects -tests.push( - make_promise_test(function resolve_to_rejected(test) { - let source = Promise.defer(); - let error = new Error("Boom"); - - let promise = source.promise.then( - function onResolve() { - do_throw("Incorrect call to onResolve listener"); - }, - function onReject(reason) { - do_check_eq(reason, error, "Rejection lead to the expected reason"); - } - ); - - source.resolve(Promise.reject(error)); - - return promise; - })); - -// Test that Promise.resolve resolves as expected -tests.push( - make_promise_test(function test_resolve(test) { - const RESULT = "arbitrary value"; - let p1 = Promise.resolve(RESULT); - let p2 = Promise.resolve(p1); - do_check_eq(p1, p2, "Promise.resolve used on a promise just returns the promise"); - - return p1.then( - function onResolve(result) { - do_check_eq(result, RESULT, "Promise.resolve propagated the correct result"); - } - ); - })); - -// Test that Promise.resolve throws when its argument is an async function. -tests.push( - make_promise_test(function test_promise_resolve_throws_with_async_function(test) { - Assert.throws(() => Promise.resolve(Task.async(function* () {})), - /Cannot resolve a promise with an async function/); - return Promise.resolve(); - })); - -// Test that the code after "then" is always executed before the callbacks -tests.push( - make_promise_test(function then_returns_before_callbacks(test) { - let promise = Promise.resolve(); - - let thenExecuted = false; - - promise = promise.then( - function onResolve() { - thenExecuted = true; - } - ); - - do_check_false(thenExecuted); - - return promise; - })); - -// Test that chaining promises does not generate long stack traces -tests.push( - make_promise_test(function chaining_short_stack(test) { - let source = Promise.defer(); - let promise = source.promise; - - const NUM_ITERATIONS = 100; - - for (let i = 0; i < NUM_ITERATIONS; i++) { - promise = promise.then( - function onResolve(result) { - return result + "."; - } - ); - } - - promise = promise.then( - function onResolve(result) { - // Check that the execution went as expected. - let expectedString = new Array(1 + NUM_ITERATIONS).join("."); - do_check_true(result == expectedString); - - // Check that we didn't generate one or more stack frames per iteration. - let stackFrameCount = 0; - let stackFrame = Components.stack; - while (stackFrame) { - stackFrameCount++; - stackFrame = stackFrame.caller; - } - - do_check_true(stackFrameCount < NUM_ITERATIONS); - } - ); - - source.resolve(""); - - return promise; - })); - -// Test that the values of the promise return by Promise.all() are kept in the -// given order even if the given promises are resolved in arbitrary order -tests.push( - make_promise_test(function all_resolve(test) { - let d1 = Promise.defer(); - let d2 = Promise.defer(); - let d3 = Promise.defer(); - - d3.resolve(4); - d2.resolve(2); - do_execute_soon(() => d1.resolve(1)); - - let promises = [d1.promise, d2.promise, 3, d3.promise]; - - return Promise.all(promises).then( - function onResolve([val1, val2, val3, val4]) { - do_check_eq(val1, 1); - do_check_eq(val2, 2); - do_check_eq(val3, 3); - do_check_eq(val4, 4); - } - ); - })); - -// Test that rejecting one of the promises passed to Promise.all() -// rejects the promise return by Promise.all() -tests.push( - make_promise_test(function all_reject(test) { - let error = new Error("Boom"); - - let d1 = Promise.defer(); - let d2 = Promise.defer(); - let d3 = Promise.defer(); - - d3.resolve(3); - d2.resolve(2); - do_execute_soon(() => d1.reject(error)); - - let promises = [d1.promise, d2.promise, d3.promise]; - - return Promise.all(promises).then( - function onResolve() { - do_throw("Incorrect call to onResolve listener"); - }, - function onReject(reason) { - do_check_eq(reason, error, "Rejection lead to the expected reason"); - } - ); - })); - -// Test that passing only values (not promises) to Promise.all() -// forwards them all as resolution values. -tests.push( - make_promise_test(function all_resolve_no_promises(test) { - try { - Promise.all(null); - do_check_true(false, "all() should only accept iterables"); - } catch (e) { - do_check_true(true, "all() fails when first the arg is not an iterable"); - } - - let p1 = Promise.all([]).then( - function onResolve(val) { - do_check_true(Array.isArray(val) && val.length == 0); - } - ); - - let p2 = Promise.all([1, 2, 3]).then( - function onResolve([val1, val2, val3]) { - do_check_eq(val1, 1); - do_check_eq(val2, 2); - do_check_eq(val3, 3); - } - ); - - return Promise.all([p1, p2]); - })); - -// Test that Promise.all() handles non-array iterables -tests.push( - make_promise_test(function all_iterable(test) { - function* iterable() { - yield 1; - yield 2; - yield 3; - } - - return Promise.all(iterable()).then( - function onResolve([val1, val2, val3]) { - do_check_eq(val1, 1); - do_check_eq(val2, 2); - do_check_eq(val3, 3); - }, - function onReject() { - do_throw("all() unexpectedly rejected"); - } - ); - })); - -// Test that throwing from the iterable passed to Promise.all() rejects the -// promise returned by Promise.all() -tests.push( - make_promise_test(function all_iterable_throws(test) { - function* iterable() { - throw 1; - } - - return Promise.all(iterable()).then( - function onResolve() { - do_throw("all() unexpectedly resolved"); - }, - function onReject(reason) { - do_check_eq(reason, 1, "all() rejects when the iterator throws"); - } - ); - })); - -// Test that Promise.race() resolves with the first available resolution value -tests.push( - make_promise_test(function race_resolve(test) { - let p1 = Promise.resolve(1); - let p2 = Promise.resolve().then(() => 2); - - return Promise.race([p1, p2]).then( - function onResolve(value) { - do_check_eq(value, 1); - } - ); - })); - -// Test that passing only values (not promises) to Promise.race() works -tests.push( - make_promise_test(function race_resolve_no_promises(test) { - try { - Promise.race(null); - do_check_true(false, "race() should only accept iterables"); - } catch (e) { - do_check_true(true, "race() fails when first the arg is not an iterable"); - } - - return Promise.race([1, 2, 3]).then( - function onResolve(value) { - do_check_eq(value, 1); - } - ); - })); - -// Test that Promise.race() never resolves when passed an empty iterable -tests.push( - make_promise_test(function race_resolve_never(test) { - return new Promise(resolve => { - Promise.race([]).then( - function onResolve() { - do_throw("race() unexpectedly resolved"); - }, - function onReject() { - do_throw("race() unexpectedly rejected"); - } - ); - - // Approximate "never" so we don't have to solve the halting problem. - do_timeout(200, resolve); - }); - })); - -// Test that Promise.race() handles non-array iterables. -tests.push( - make_promise_test(function race_iterable(test) { - function* iterable() { - yield 1; - yield 2; - yield 3; - } - - return Promise.race(iterable()).then( - function onResolve(value) { - do_check_eq(value, 1); - }, - function onReject() { - do_throw("race() unexpectedly rejected"); - } - ); - })); - -// Test that throwing from the iterable passed to Promise.race() rejects the -// promise returned by Promise.race() -tests.push( - make_promise_test(function race_iterable_throws(test) { - function* iterable() { - throw 1; - } - - return Promise.race(iterable()).then( - function onResolve() { - do_throw("race() unexpectedly resolved"); - }, - function onReject(reason) { - do_check_eq(reason, 1, "race() rejects when the iterator throws"); - } - ); - })); - -// Test that rejecting one of the promises passed to Promise.race() rejects the -// promise returned by Promise.race() -tests.push( - make_promise_test(function race_reject(test) { - let p1 = Promise.reject(1); - let p2 = Promise.resolve(2); - let p3 = Promise.resolve(3); - - return Promise.race([p1, p2, p3]).then( - function onResolve() { - do_throw("race() unexpectedly resolved"); - }, - function onReject(reason) { - do_check_eq(reason, 1, "race() rejects when given a rejected promise"); - } - ); - })); - -// Test behavior of the Promise constructor. -tests.push( - make_promise_test(function test_constructor(test) { - try { - new Promise(null); - do_check_true(false, "Constructor should fail when not passed a function"); - } catch (e) { - do_check_true(true, "Constructor fails when not passed a function"); - } - - let executorRan = false; - let promise = new Promise( - function executor(resolve, reject) { - executorRan = true; - do_check_eq(this, undefined); - do_check_eq(typeof resolve, "function", - "resolve function should be passed to the executor"); - do_check_eq(typeof reject, "function", - "reject function should be passed to the executor"); - } - ); - do_check_instanceof(promise, Promise); - do_check_true(executorRan, "Executor should execute synchronously"); - - // resolve a promise from the executor - let resolvePromise = new Promise( - function executor(resolve) { - resolve(1); - } - ).then( - function onResolve(value) { - do_check_eq(value, 1, "Executor resolved with correct value"); - }, - function onReject() { - do_throw("Executor unexpectedly rejected"); - } - ); - - // reject a promise from the executor - let rejectPromise = new Promise( - function executor(_, reject) { - reject(1); - } - ).then( - function onResolve() { - do_throw("Executor unexpectedly resolved"); - }, - function onReject(reason) { - do_check_eq(reason, 1, "Executor rejected with correct value"); - } - ); - - // throw from the executor, causing a rejection - let throwPromise = new Promise( - function executor() { - throw 1; - } - ).then( - function onResolve() { - do_throw("Throwing inside an executor should not resolve the promise"); - }, - function onReject(reason) { - do_check_eq(reason, 1, "Executor rejected with correct value"); - } - ); - - return Promise.all([resolvePromise, rejectPromise, throwPromise]); - })); - -// Test deadlock in Promise.jsm with nested event loops -// The scenario being tested is: -// promise_1.then({ -// do some work that will asynchronously signal done -// start an event loop waiting for the done signal -// } -// where the async work uses resolution of a second promise to -// trigger the "done" signal. While this would likely work in a -// naive implementation, our constant-stack implementation needs -// a special case to avoid deadlock. Note that this test is -// sensitive to the implementation-dependent order in which then() -// clauses for two different promises are executed, so it is -// possible for other implementations to pass this test and still -// have similar deadlocks. -tests.push( - make_promise_test(function promise_nested_eventloop_deadlock(test) { - // Set up a (long enough to be noticeable) timeout to - // exit the nested event loop and throw if the test run is hung - let shouldExitNestedEventLoop = false; - - function event_loop() { - let thr = Services.tm.mainThread; - while (!shouldExitNestedEventLoop) { - thr.processNextEvent(true); - } - } - - // I wish there was a way to cancel xpcshell do_timeout()s - do_timeout(2000, () => { - if (!shouldExitNestedEventLoop) { - shouldExitNestedEventLoop = true; - do_throw("Test timed out"); - } - }); - - let promise1 = Promise.resolve(1); - let promise2 = Promise.resolve(2); - - do_print("Setting wait for first promise"); - promise1.then(value => { - do_print("Starting event loop"); - event_loop(); - }, null); - - do_print("Setting wait for second promise"); - return promise2.catch(error => { return 3; }) - .then( - count => { - shouldExitNestedEventLoop = true; - }); - })); - -function wait_for_uncaught(aMustAppear, aTimeout = undefined) { - let remaining = new Set(); - for (let k of aMustAppear) { - remaining.add(k); - } - let deferred = Promise.defer(); - let print = do_print; - let execute_soon = do_execute_soon; - let observer = function({message, stack}) { - let data = message + stack; - print("Observing " + message + ", looking for " + aMustAppear.join(", ")); - for (let expected of remaining) { - if (data.indexOf(expected) != -1) { - print("I found " + expected); - remaining.delete(expected); - } - if (remaining.size == 0 && observer) { - Promise.Debugging.removeUncaughtErrorObserver(observer); - observer = null; - deferred.resolve(); - } - } - }; - Promise.Debugging.addUncaughtErrorObserver(observer); - if (aTimeout) { - do_timeout(aTimeout, function timeout() { - if (observer) { - Promise.Debugging.removeUncaughtErrorObserver(observer); - observer = null; - } - deferred.reject(new Error("Timeout")); - }); - } - return deferred.promise; -} - -// Test that uncaught errors are reported as uncaught -(function() { - let make_string_rejection = function make_string_rejection() { - let salt = (Math.random() * ( Math.pow(2, 24) - 1 )); - let string = "This is an uncaught rejection " + salt; - // Our error is not Error-like nor an nsIException, so the stack will - // include the closure doing the actual rejection. - return {mustFind: ["test_rejection_closure", string], error: string}; - }; - let make_num_rejection = function make_num_rejection() { - let salt = (Math.random() * ( Math.pow(2, 24) - 1 )); - // Our error is not Error-like nor an nsIException, so the stack will - // include the closure doing the actual rejection. - return {mustFind: ["test_rejection_closure", salt], error: salt}; - }; - let make_undefined_rejection = function make_undefined_rejection() { - // Our error is not Error-like nor an nsIException, so the stack will - // include the closure doing the actual rejection. - return {mustFind: ["test_rejection_closure"], error: undefined}; - }; - let make_error_rejection = function make_error_rejection() { - let salt = (Math.random() * ( Math.pow(2, 24) - 1 )); - let error = new Error("This is an uncaught error " + salt); - return { - mustFind: [error.message, error.fileName, error.lineNumber, error.stack], - error: error - }; - }; - let make_exception_rejection = function make_exception_rejection() { - let salt = (Math.random() * ( Math.pow(2, 24) - 1 )); - let exn = new Components.Exception("This is an uncaught exception " + salt, - Components.results.NS_ERROR_NOT_AVAILABLE); - return { - mustFind: [exn.message, exn.filename, exn.lineNumber, exn.location.toString()], - error: exn - }; - }; - for (let make_rejection of [make_string_rejection, - make_num_rejection, - make_undefined_rejection, - make_error_rejection, - make_exception_rejection]) { - let {mustFind, error} = make_rejection(); - let name = make_rejection.name; - tests.push(make_promise_test(function test_uncaught_is_reported() { - do_print("Testing with rejection " + name); - let promise = wait_for_uncaught(mustFind); - (function test_rejection_closure() { - // For the moment, we cannot be absolutely certain that a value is - // garbage-collected, even if it is not referenced anymore, due to - // the conservative stack-scanning algorithm. - // - // To be _almost_ certain that a value will be garbage-collected, we - // 1. isolate that value in an anonymous closure; - // 2. allocate 100 values instead of 1 (gc-ing a single value from - // these is sufficient for the test); - // 3. place everything in a loop, as the JIT typically reuses memory; - // 4. call all the GC methods we can. - // - // Unfortunately, we might still have intermittent failures, - // materialized as timeouts. - // - for (let i = 0; i < 100; ++i) { - Promise.reject(error); - } - })(); - do_print("Posted all rejections"); - Components.utils.forceGC(); - Components.utils.forceCC(); - Components.utils.forceShrinkingGC(); - return promise; - })); - } -})(); - - -// Test that caught errors are not reported as uncaught -tests.push( -make_promise_test(function test_caught_is_not_reported() { - let salt = (Math.random() * ( Math.pow(2, 24) - 1 )); - let promise = wait_for_uncaught([salt], 500); - (function() { - let uncaught = Promise.reject("This error, on the other hand, is caught " + salt); - uncaught.catch(function() { /* ignore rejection */ }); - uncaught = null; - })(); - // Isolate this in a function to increase likelihood that the gc will - // realise that |uncaught| has remained uncaught. - Components.utils.forceGC(); - - return promise.then(function onSuccess() { - throw new Error("This error was caught and should not have been reported"); - }, function onError() { - do_print("The caught error was not reported, all is fine"); - } - ); -})); - -// Bug 1033406 - Make sure Promise works even after freezing. -tests.push( - make_promise_test(function test_freezing_promise(test) { - var p = new Promise(function executor(resolve) { - do_execute_soon(resolve); - }); - Object.freeze(p); - return p; - }) -); - -function run_test() -{ - do_test_pending(); - run_promise_tests(tests, do_test_finished); -} diff --git a/toolkit/modules/tests/xpcshell/test_PromiseUtils.js b/toolkit/modules/tests/xpcshell/test_PromiseUtils.js deleted file mode 100644 index c3ab839e4b..0000000000 --- a/toolkit/modules/tests/xpcshell/test_PromiseUtils.js +++ /dev/null @@ -1,105 +0,0 @@ - /* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Components.utils.import("resource://gre/modules/PromiseUtils.jsm"); -Components.utils.import("resource://gre/modules/Timer.jsm"); -Components.utils.import("resource://testing-common/PromiseTestUtils.jsm"); - -// Tests for PromiseUtils.jsm -function run_test() { - run_next_test(); -} - -// Tests for PromiseUtils.defer() - -/* Tests for checking the resolve method of the Deferred object - * returned by PromiseUtils.defer() */ -add_task(function* test_resolve_string() { - let def = PromiseUtils.defer(); - let expected = "The promise is resolved " + Math.random(); - def.resolve(expected); - let result = yield def.promise; - Assert.equal(result, expected, "def.resolve() resolves the promise"); -}); - -/* Test for the case when undefined is passed to the resolve method - * of the Deferred object */ -add_task(function* test_resolve_undefined() { - let def = PromiseUtils.defer(); - def.resolve(); - let result = yield def.promise; - Assert.equal(result, undefined, "resolve works with undefined as well"); -}); - -/* Test when a pending promise is passed to the resolve method - * of the Deferred object */ -add_task(function* test_resolve_pending_promise() { - let def = PromiseUtils.defer(); - let expected = 100 + Math.random(); - let p = new Promise((resolve, reject) => { - setTimeout(() => resolve(expected), 100); - }); - def.resolve(p); - let result = yield def.promise; - Assert.equal(result, expected, "def.promise assumed the state of the passed promise"); -}); - -/* Test when a resovled promise is passed - * to the resolve method of the Deferred object */ -add_task(function* test_resolve_resolved_promise() { - let def = PromiseUtils.defer(); - let expected = "Yeah resolved" + Math.random(); - let p = new Promise((resolve, reject) => resolve(expected)); - def.resolve(p); - let result = yield def.promise; - Assert.equal(result, expected, "Resolved promise is passed to the resolve method"); -}); - -/* Test for the case when a rejected promise is - * passed to the resolve method */ -add_task(function* test_resolve_rejected_promise() { - let def = PromiseUtils.defer(); - let p = new Promise((resolve, reject) => reject(new Error("There its an rejection"))); - def.resolve(p); - yield Assert.rejects(def.promise, /There its an rejection/, "Settled rejection promise passed to the resolve method"); -}); - -/* Test for the checking the reject method of - * the Deferred object returned by PromiseUtils.defer() */ -add_task(function* test_reject_Error() { - let def = PromiseUtils.defer(); - def.reject(new Error("This one rejects")); - yield Assert.rejects(def.promise, /This one rejects/, "reject method with Error for rejection"); -}); - -/* Test for the case when a pending Promise is passed to - * the reject method of Deferred object */ -add_task(function* test_reject_pending_promise() { - let def = PromiseUtils.defer(); - let p = new Promise((resolve, reject) => { - setTimeout(() => resolve(100), 100); - }); - def.reject(p); - yield Assert.rejects(def.promise, Promise, "Rejection with a pending promise uses the passed promise itself as the reason of rejection"); -}); - -/* Test for the case when a resolved Promise - * is passed to the reject method */ -add_task(function* test_reject_resolved_promise() { - let def = PromiseUtils.defer(); - let p = new Promise((resolve, reject) => resolve("This resolved")); - def.reject(p); - yield Assert.rejects(def.promise, Promise, "Rejection with a resolved promise uses the passed promise itself as the reason of rejection"); -}); - -/* Test for the case when a rejected Promise is - * passed to the reject method */ -add_task(function* test_reject_resolved_promise() { - PromiseTestUtils.expectUncaughtRejection(/This one rejects/); - let def = PromiseUtils.defer(); - let p = new Promise((resolve, reject) => reject(new Error("This one rejects"))); - def.reject(p); - yield Assert.rejects(def.promise, Promise, "Rejection with a rejected promise uses the passed promise itself as the reason of rejection"); -}); diff --git a/toolkit/modules/tests/xpcshell/test_Services.js b/toolkit/modules/tests/xpcshell/test_Services.js deleted file mode 100644 index a50ecca3da..0000000000 --- a/toolkit/modules/tests/xpcshell/test_Services.js +++ /dev/null @@ -1,90 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * This file tests the Services.jsm module. - */ - -// Globals - -var Cc = Components.classes; -var Ci = Components.interfaces; -var Cu = Components.utils; -var Cr = Components.results; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -function checkService(service, interface) { - do_print("Checking that Services." + service + " is an " + interface); - do_check_true(service in Services); - do_check_true(Services[service] instanceof interface); -} - -// Tests - -function run_test() -{ - do_get_profile(); - - checkService("appShell", Ci.nsIAppShellService); - checkService("appinfo", Ci.nsIXULRuntime); - checkService("blocklist", Ci.nsIBlocklistService); - checkService("cache", Ci.nsICacheService); - checkService("cache2", Ci.nsICacheStorageService); - checkService("clipboard", Ci.nsIClipboard); - checkService("console", Ci.nsIConsoleService); - checkService("contentPrefs", Ci.nsIContentPrefService); - checkService("cookies", Ci.nsICookieManager2); - checkService("dirsvc", Ci.nsIDirectoryService); - checkService("dirsvc", Ci.nsIProperties); - checkService("DOMRequest", Ci.nsIDOMRequestService); - checkService("domStorageManager", Ci.nsIDOMStorageManager); - checkService("downloads", Ci.nsIDownloadManager); - checkService("droppedLinkHandler", Ci.nsIDroppedLinkHandler); - checkService("eTLD", Ci.nsIEffectiveTLDService); - checkService("focus", Ci.nsIFocusManager); - checkService("io", Ci.nsIIOService); - checkService("io", Ci.nsIIOService2); - checkService("locale", Ci.nsILocaleService); - checkService("logins", Ci.nsILoginManager); - checkService("obs", Ci.nsIObserverService); - checkService("perms", Ci.nsIPermissionManager); - checkService("prefs", Ci.nsIPrefBranch); - checkService("prefs", Ci.nsIPrefService); - checkService("prompt", Ci.nsIPromptService); - checkService("scriptSecurityManager", Ci.nsIScriptSecurityManager); - checkService("scriptloader", Ci.mozIJSSubScriptLoader); - checkService("startup", Ci.nsIAppStartup); - checkService("storage", Ci.mozIStorageService); - checkService("strings", Ci.nsIStringBundleService); - checkService("sysinfo", Ci.nsIPropertyBag2); - checkService("telemetry", Ci.nsITelemetry); - checkService("tm", Ci.nsIThreadManager); - checkService("uriFixup", Ci.nsIURIFixup); - checkService("urlFormatter", Ci.nsIURLFormatter); - checkService("vc", Ci.nsIVersionComparator); - checkService("wm", Ci.nsIWindowMediator); - checkService("ww", Ci.nsIWindowWatcher); - if ("nsIBrowserSearchService" in Ci) { - checkService("search", Ci.nsIBrowserSearchService); - } - if ("nsIAndroidBridge" in Ci) { - checkService("androidBridge", Ci.nsIAndroidBridge); - } - - // In xpcshell tests, the "@mozilla.org/xre/app-info;1" component implements - // only the nsIXULRuntime interface, but not nsIXULAppInfo. To test the - // service getter for the latter interface, load mock app-info. - let tmp = {}; - Cu.import("resource://testing-common/AppInfo.jsm", tmp); - tmp.updateAppInfo(); - - // We need to reload the module to update the lazy getter. - Cu.unload("resource://gre/modules/Services.jsm"); - Cu.import("resource://gre/modules/Services.jsm"); - - checkService("appinfo", Ci.nsIXULAppInfo); - - Cu.unload("resource://gre/modules/Services.jsm"); -} diff --git a/toolkit/modules/tests/xpcshell/test_UpdateUtils_updatechannel.js b/toolkit/modules/tests/xpcshell/test_UpdateUtils_updatechannel.js deleted file mode 100644 index 75d7a19928..0000000000 --- a/toolkit/modules/tests/xpcshell/test_UpdateUtils_updatechannel.js +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* 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/. */ - -var { utils: Cu } = Components; - -Cu.import("resource://gre/modules/Preferences.jsm"); -Cu.import("resource://gre/modules/UpdateUtils.jsm"); - -const PREF_APP_UPDATE_CHANNEL = "app.update.channel"; -const TEST_CHANNEL = "TestChannel"; -const PREF_PARTNER_A = "app.partner.test_partner_a"; -const TEST_PARTNER_A = "TestPartnerA"; -const PREF_PARTNER_B = "app.partner.test_partner_b"; -const TEST_PARTNER_B = "TestPartnerB"; - -add_task(function* test_updatechannel() { - let defaultPrefs = new Preferences({ defaultBranch: true }); - let currentChannel = defaultPrefs.get(PREF_APP_UPDATE_CHANNEL); - - do_check_eq(UpdateUtils.UpdateChannel, currentChannel); - do_check_eq(UpdateUtils.getUpdateChannel(true), currentChannel); - do_check_eq(UpdateUtils.getUpdateChannel(false), currentChannel); - - defaultPrefs.set(PREF_APP_UPDATE_CHANNEL, TEST_CHANNEL); - do_check_eq(UpdateUtils.UpdateChannel, TEST_CHANNEL); - do_check_eq(UpdateUtils.getUpdateChannel(true), TEST_CHANNEL); - do_check_eq(UpdateUtils.getUpdateChannel(false), TEST_CHANNEL); - - defaultPrefs.set(PREF_PARTNER_A, TEST_PARTNER_A); - defaultPrefs.set(PREF_PARTNER_B, TEST_PARTNER_B); - do_check_eq(UpdateUtils.UpdateChannel, - TEST_CHANNEL + "-cck-" + TEST_PARTNER_A + "-" + TEST_PARTNER_B); - do_check_eq(UpdateUtils.getUpdateChannel(true), - TEST_CHANNEL + "-cck-" + TEST_PARTNER_A + "-" + TEST_PARTNER_B); - do_check_eq(UpdateUtils.getUpdateChannel(false), TEST_CHANNEL); -}); diff --git a/toolkit/modules/tests/xpcshell/test_UpdateUtils_url.js b/toolkit/modules/tests/xpcshell/test_UpdateUtils_url.js deleted file mode 100644 index da5d868e37..0000000000 --- a/toolkit/modules/tests/xpcshell/test_UpdateUtils_url.js +++ /dev/null @@ -1,292 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* 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/. */ - -var { classes: Cc, interfaces: Ci, utils: Cu } = Components; - -Cu.import("resource://gre/modules/UpdateUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/AppConstants.jsm"); -Cu.import("resource://testing-common/AppInfo.jsm"); -Cu.import("resource://gre/modules/ctypes.jsm"); - -const PREF_APP_UPDATE_CHANNEL = "app.update.channel"; -const PREF_APP_PARTNER_BRANCH = "app.partner."; -const PREF_DISTRIBUTION_ID = "distribution.id"; -const PREF_DISTRIBUTION_VERSION = "distribution.version"; - -const URL_PREFIX = "http://localhost/"; - -const MSG_SHOULD_EQUAL = " should equal the expected value"; - -updateAppInfo(); -const gAppInfo = getAppInfo(); -const gDefaultPrefBranch = Services.prefs.getDefaultBranch(null); - -function setUpdateChannel(aChannel) { - gDefaultPrefBranch.setCharPref(PREF_APP_UPDATE_CHANNEL, aChannel); -} - -function getServicePack() { - // NOTE: This function is a helper function and not a test. Thus, - // it uses throw() instead of do_throw(). Any tests that use this function - // should catch exceptions thrown in this function and deal with them - // appropriately (usually by calling do_throw). - const BYTE = ctypes.uint8_t; - const WORD = ctypes.uint16_t; - const DWORD = ctypes.uint32_t; - const WCHAR = ctypes.char16_t; - const BOOL = ctypes.int; - - // This structure is described at: - // http://msdn.microsoft.com/en-us/library/ms724833%28v=vs.85%29.aspx - const SZCSDVERSIONLENGTH = 128; - const OSVERSIONINFOEXW = new ctypes.StructType('OSVERSIONINFOEXW', - [ - {dwOSVersionInfoSize: DWORD}, - {dwMajorVersion: DWORD}, - {dwMinorVersion: DWORD}, - {dwBuildNumber: DWORD}, - {dwPlatformId: DWORD}, - {szCSDVersion: ctypes.ArrayType(WCHAR, SZCSDVERSIONLENGTH)}, - {wServicePackMajor: WORD}, - {wServicePackMinor: WORD}, - {wSuiteMask: WORD}, - {wProductType: BYTE}, - {wReserved: BYTE} - ]); - - let kernel32 = ctypes.open("kernel32"); - try { - let GetVersionEx = kernel32.declare("GetVersionExW", - ctypes.default_abi, - BOOL, - OSVERSIONINFOEXW.ptr); - let winVer = OSVERSIONINFOEXW(); - winVer.dwOSVersionInfoSize = OSVERSIONINFOEXW.size; - - if (0 === GetVersionEx(winVer.address())) { - // Using "throw" instead of "do_throw" (see NOTE above) - throw ("Failure in GetVersionEx (returned 0)"); - } - - return winVer.wServicePackMajor + "." + winVer.wServicePackMinor; - } finally { - kernel32.close(); - } -} - -function getProcArchitecture() { - // NOTE: This function is a helper function and not a test. Thus, - // it uses throw() instead of do_throw(). Any tests that use this function - // should catch exceptions thrown in this function and deal with them - // appropriately (usually by calling do_throw). - const WORD = ctypes.uint16_t; - const DWORD = ctypes.uint32_t; - - // This structure is described at: - // http://msdn.microsoft.com/en-us/library/ms724958%28v=vs.85%29.aspx - const SYSTEM_INFO = new ctypes.StructType('SYSTEM_INFO', - [ - {wProcessorArchitecture: WORD}, - {wReserved: WORD}, - {dwPageSize: DWORD}, - {lpMinimumApplicationAddress: ctypes.voidptr_t}, - {lpMaximumApplicationAddress: ctypes.voidptr_t}, - {dwActiveProcessorMask: DWORD.ptr}, - {dwNumberOfProcessors: DWORD}, - {dwProcessorType: DWORD}, - {dwAllocationGranularity: DWORD}, - {wProcessorLevel: WORD}, - {wProcessorRevision: WORD} - ]); - - let kernel32 = ctypes.open("kernel32"); - try { - let GetNativeSystemInfo = kernel32.declare("GetNativeSystemInfo", - ctypes.default_abi, - ctypes.void_t, - SYSTEM_INFO.ptr); - let sysInfo = SYSTEM_INFO(); - // Default to unknown - sysInfo.wProcessorArchitecture = 0xffff; - - GetNativeSystemInfo(sysInfo.address()); - switch (sysInfo.wProcessorArchitecture) { - case 9: - return "x64"; - case 6: - return "IA64"; - case 0: - return "x86"; - default: - // Using "throw" instead of "do_throw" (see NOTE above) - throw ("Unknown architecture returned from GetNativeSystemInfo: " + sysInfo.wProcessorArchitecture); - } - } finally { - kernel32.close(); - } -} - -// Helper function for formatting a url and getting the result we're -// interested in -function getResult(url) { - url = UpdateUtils.formatUpdateURL(url); - return url.substr(URL_PREFIX.length).split("/")[0]; -} - -// url constructed with %PRODUCT% -add_task(function* test_product() { - let url = URL_PREFIX + "%PRODUCT%/"; - Assert.equal(getResult(url), gAppInfo.name, - "the url param for %PRODUCT%" + MSG_SHOULD_EQUAL); -}); - -// url constructed with %VERSION% -add_task(function* test_version() { - let url = URL_PREFIX + "%VERSION%/"; - Assert.equal(getResult(url), gAppInfo.version, - "the url param for %VERSION%" + MSG_SHOULD_EQUAL); -}); - -// url constructed with %BUILD_ID% -add_task(function* test_build_id() { - let url = URL_PREFIX + "%BUILD_ID%/"; - Assert.equal(getResult(url), gAppInfo.appBuildID, - "the url param for %BUILD_ID%" + MSG_SHOULD_EQUAL); -}); - -// url constructed with %BUILD_TARGET% -// XXX TODO - it might be nice if we tested the actual ABI -add_task(function* test_build_target() { - let url = URL_PREFIX + "%BUILD_TARGET%/"; - - let abi; - try { - abi = gAppInfo.XPCOMABI; - } catch (e) { - do_throw("nsIXULAppInfo:XPCOMABI not defined\n"); - } - - if (AppConstants.platform == "macosx") { - // Mac universal build should report a different ABI than either macppc - // or mactel. This is necessary since nsUpdateService.js will set the ABI to - // Universal-gcc3 for Mac universal builds. - let macutils = Cc["@mozilla.org/xpcom/mac-utils;1"]. - getService(Ci.nsIMacUtils); - - if (macutils.isUniversalBinary) { - abi += "-u-" + macutils.architecturesInBinary; - } - } else if (AppConstants.platform == "win") { - // Windows build should report the CPU architecture that it's running on. - abi += "-" + getProcArchitecture(); - } - - Assert.equal(getResult(url), gAppInfo.OS + "_" + abi, - "the url param for %BUILD_TARGET%" + MSG_SHOULD_EQUAL); -}); - -// url constructed with %LOCALE% -// Bug 488936 added the update.locale file that stores the update locale -add_task(function* test_locale() { - // The code that gets the locale accesses the profile which is only available - // after calling do_get_profile in xpcshell tests. This prevents an error from - // being logged. - do_get_profile(); - - let url = URL_PREFIX + "%LOCALE%/"; - Assert.equal(getResult(url), AppConstants.INSTALL_LOCALE, - "the url param for %LOCALE%" + MSG_SHOULD_EQUAL); -}); - -// url constructed with %CHANNEL% -add_task(function* test_channel() { - let url = URL_PREFIX + "%CHANNEL%/"; - setUpdateChannel("test_channel"); - Assert.equal(getResult(url), "test_channel", - "the url param for %CHANNEL%" + MSG_SHOULD_EQUAL); -}); - -// url constructed with %CHANNEL% with distribution partners -add_task(function* test_channel_distribution() { - let url = URL_PREFIX + "%CHANNEL%/"; - gDefaultPrefBranch.setCharPref(PREF_APP_PARTNER_BRANCH + "test_partner1", - "test_partner1"); - gDefaultPrefBranch.setCharPref(PREF_APP_PARTNER_BRANCH + "test_partner2", - "test_partner2"); - Assert.equal(getResult(url), - "test_channel-cck-test_partner1-test_partner2", - "the url param for %CHANNEL%" + MSG_SHOULD_EQUAL); -}); - -// url constructed with %PLATFORM_VERSION% -add_task(function* test_platform_version() { - let url = URL_PREFIX + "%PLATFORM_VERSION%/"; - Assert.equal(getResult(url), gAppInfo.platformVersion, - "the url param for %PLATFORM_VERSION%" + MSG_SHOULD_EQUAL); -}); - -// url constructed with %OS_VERSION% -add_task(function* test_os_version() { - let url = URL_PREFIX + "%OS_VERSION%/"; - let osVersion; - let sysInfo = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2); - osVersion = sysInfo.getProperty("name") + " " + sysInfo.getProperty("version"); - - if (AppConstants.platform == "win") { - try { - let servicePack = getServicePack(); - osVersion += "." + servicePack; - } catch (e) { - do_throw("Failure obtaining service pack: " + e); - } - - if ("5.0" === sysInfo.getProperty("version")) { // Win2K - osVersion += " (unknown)"; - } else { - try { - osVersion += " (" + getProcArchitecture() + ")"; - } catch (e) { - do_throw("Failed to obtain processor architecture: " + e); - } - } - } - - if (osVersion) { - try { - osVersion += " (" + sysInfo.getProperty("secondaryLibrary") + ")"; - } catch (e) { - // Not all platforms have a secondary widget library, so an error is - // nothing to worry about. - } - osVersion = encodeURIComponent(osVersion); - } - - Assert.equal(getResult(url), osVersion, - "the url param for %OS_VERSION%" + MSG_SHOULD_EQUAL); -}); - -// url constructed with %DISTRIBUTION% -add_task(function* test_distribution() { - let url = URL_PREFIX + "%DISTRIBUTION%/"; - gDefaultPrefBranch.setCharPref(PREF_DISTRIBUTION_ID, "test_distro"); - Assert.equal(getResult(url), "test_distro", - "the url param for %DISTRIBUTION%" + MSG_SHOULD_EQUAL); -}); - -// url constructed with %DISTRIBUTION_VERSION% -add_task(function* test_distribution_version() { - let url = URL_PREFIX + "%DISTRIBUTION_VERSION%/"; - gDefaultPrefBranch.setCharPref(PREF_DISTRIBUTION_VERSION, "test_distro_version"); - Assert.equal(getResult(url), "test_distro_version", - "the url param for %DISTRIBUTION_VERSION%" + MSG_SHOULD_EQUAL); -}); - -add_task(function* test_custom() { - Services.prefs.setCharPref("app.update.custom", "custom"); - let url = URL_PREFIX + "%CUSTOM%/"; - Assert.equal(getResult(url), "custom", - "the url query string for %CUSTOM%" + MSG_SHOULD_EQUAL); -}); diff --git a/toolkit/modules/tests/xpcshell/test_ZipUtils.js b/toolkit/modules/tests/xpcshell/test_ZipUtils.js deleted file mode 100644 index 71c6884d46..0000000000 --- a/toolkit/modules/tests/xpcshell/test_ZipUtils.js +++ /dev/null @@ -1,79 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -const ARCHIVE = "zips/zen.zip"; -const SUBDIR = "zen"; -const SYMLINK = "beyond_link"; -const ENTRIES = ["beyond.txt", SYMLINK, "waterwood.txt"]; - -Components.utils.import("resource://gre/modules/ZipUtils.jsm"); -Components.utils.import("resource://gre/modules/FileUtils.jsm"); -Components.utils.import("resource://gre/modules/Services.jsm"); - -const archive = do_get_file(ARCHIVE, false); -const dir = do_get_profile().clone(); -dir.append("test_ZipUtils"); - -function run_test() { - run_next_test(); -} - -function ensureExtracted(target) { - target.append(SUBDIR); - do_check_true(target.exists()); - - for (let i = 0; i < ENTRIES.length; i++) { - let entry = target.clone(); - entry.append(ENTRIES[i]); - do_print("ENTRY " + entry.path); - do_check_true(entry.exists()); - } -} - -function ensureHasSymlink(target) { - // Just bail out if running on Windows, since symlinks do not exists there. - if (Services.appinfo.OS === "WINNT") { - return; - } - - let entry = target.clone(); - entry.append(SYMLINK); - - do_print("ENTRY " + entry.path); - do_check_true(entry.exists()); - do_check_true(entry.isSymlink()); -} - -add_task(function test_extractFiles() { - let target = dir.clone(); - target.append("test_extractFiles"); - - try { - ZipUtils.extractFiles(archive, target); - } catch (e) { - do_throw("Failed to extract synchronously!"); - } - - ensureExtracted(target); - ensureHasSymlink(target); -}); - -add_task(function* test_extractFilesAsync() { - let target = dir.clone(); - target.append("test_extractFilesAsync"); - target.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, - FileUtils.PERMS_DIRECTORY); - - yield ZipUtils.extractFilesAsync(archive, target).then( - function success() { - do_print("SUCCESS"); - ensureExtracted(target); - }, - function failure() { - do_print("FAILURE"); - do_throw("Failed to extract asynchronously!"); - } - ); -}); diff --git a/toolkit/modules/tests/xpcshell/test_client_id.js b/toolkit/modules/tests/xpcshell/test_client_id.js deleted file mode 100644 index 10ef2a3eaf..0000000000 --- a/toolkit/modules/tests/xpcshell/test_client_id.js +++ /dev/null @@ -1,95 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource://gre/modules/ClientID.jsm"); -Cu.import("resource://gre/modules/Task.jsm"); -Cu.import("resource://services-common/utils.js"); -Cu.import("resource://gre/modules/osfile.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Preferences.jsm"); - -function run_test() { - do_get_profile(); - run_next_test(); -} - -add_task(function* () { - const drsPath = OS.Path.join(OS.Constants.Path.profileDir, "datareporting", "state.json"); - const fhrDir = OS.Path.join(OS.Constants.Path.profileDir, "healthreport"); - const fhrPath = OS.Path.join(fhrDir, "state.json"); - const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; - const invalidIDs = [-1, 0.5, "INVALID-UUID", true, "", "3d1e1560-682a-4043-8cf2-aaaaaaaaaaaZ"]; - const PREF_CACHED_CLIENTID = "toolkit.telemetry.cachedClientID"; - - yield OS.File.makeDir(fhrDir); - - // Check that we are importing the FHR client ID. - let clientID = CommonUtils.generateUUID(); - yield CommonUtils.writeJSON({clientID: clientID}, fhrPath); - Assert.equal(clientID, yield ClientID.getClientID()); - - // We should persist the ID in DRS now and not pick up a differing ID from FHR. - yield ClientID._reset(); - yield CommonUtils.writeJSON({clientID: CommonUtils.generateUUID()}, fhrPath); - Assert.equal(clientID, yield ClientID.getClientID()); - - // We should be guarded against broken FHR data. - for (let invalidID of invalidIDs) { - yield ClientID._reset(); - yield OS.File.remove(drsPath); - yield CommonUtils.writeJSON({clientID: invalidID}, fhrPath); - clientID = yield ClientID.getClientID(); - Assert.equal(typeof(clientID), 'string'); - Assert.ok(uuidRegex.test(clientID)); - } - - // We should be guarded against invalid FHR json. - yield ClientID._reset(); - yield OS.File.remove(drsPath); - yield OS.File.writeAtomic(fhrPath, "abcd", {encoding: "utf-8", tmpPath: fhrPath + ".tmp"}); - clientID = yield ClientID.getClientID(); - Assert.equal(typeof(clientID), 'string'); - Assert.ok(uuidRegex.test(clientID)); - - // We should be guarded against broken DRS data too and fall back to loading - // the FHR ID. - for (let invalidID of invalidIDs) { - yield ClientID._reset(); - clientID = CommonUtils.generateUUID(); - yield CommonUtils.writeJSON({clientID: clientID}, fhrPath); - yield CommonUtils.writeJSON({clientID: invalidID}, drsPath); - Assert.equal(clientID, yield ClientID.getClientID()); - } - - // We should be guarded against invalid DRS json too. - yield ClientID._reset(); - yield OS.File.remove(fhrPath); - yield OS.File.writeAtomic(drsPath, "abcd", {encoding: "utf-8", tmpPath: drsPath + ".tmp"}); - clientID = yield ClientID.getClientID(); - Assert.equal(typeof(clientID), 'string'); - Assert.ok(uuidRegex.test(clientID)); - - // If both the FHR and DSR data are broken, we should end up with a new client ID. - for (let invalidID of invalidIDs) { - yield ClientID._reset(); - yield CommonUtils.writeJSON({clientID: invalidID}, fhrPath); - yield CommonUtils.writeJSON({clientID: invalidID}, drsPath); - clientID = yield ClientID.getClientID(); - Assert.equal(typeof(clientID), 'string'); - Assert.ok(uuidRegex.test(clientID)); - } - - // Assure that cached IDs are being checked for validity. - for (let invalidID of invalidIDs) { - yield ClientID._reset(); - Preferences.set(PREF_CACHED_CLIENTID, invalidID); - let cachedID = ClientID.getCachedClientID(); - Assert.strictEqual(cachedID, null, "ClientID should ignore invalid cached IDs"); - let prefID = Preferences.get(PREF_CACHED_CLIENTID, null); - Assert.strictEqual(prefID, null, "ClientID should reset invalid cached IDs"); - } -}); diff --git a/toolkit/modules/tests/xpcshell/test_jsesc.js b/toolkit/modules/tests/xpcshell/test_jsesc.js deleted file mode 100644 index 0c6cbba690..0000000000 --- a/toolkit/modules/tests/xpcshell/test_jsesc.js +++ /dev/null @@ -1,9 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -Components.utils.import("resource://gre/modules/third_party/jsesc/jsesc.js"); - -function run_test() { - do_check_eq(jsesc("teééést", {lowercaseHex: true}), "te\\xe9\\xe9\\xe9st"); - do_check_eq(jsesc("teééést", {lowercaseHex: false}), "te\\xE9\\xE9\\xE9st"); -} diff --git a/toolkit/modules/tests/xpcshell/test_propertyListsUtils.js b/toolkit/modules/tests/xpcshell/test_propertyListsUtils.js deleted file mode 100644 index 9ccf50b739..0000000000 --- a/toolkit/modules/tests/xpcshell/test_propertyListsUtils.js +++ /dev/null @@ -1,106 +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"; - -Components.utils.import("resource://gre/modules/PropertyListUtils.jsm"); - -function checkValue(aPropertyListObject, aType, aValue) { - do_check_eq(PropertyListUtils.getObjectType(aPropertyListObject), aType); - if (aValue !== undefined) { - // Perform strict equality checks until Bug 714467 is fixed. - let strictEqualityCheck = function(a, b) { - do_check_eq(typeof(a), typeof(b)); - do_check_eq(a, b); - }; - - if (typeof(aPropertyListObject) == "object") - strictEqualityCheck(aPropertyListObject.valueOf(), aValue.valueOf()); - else - strictEqualityCheck(aPropertyListObject, aValue); - } -} - -function checkLazyGetterValue(aObject, aPropertyName, aType, aValue) { - let descriptor = Object.getOwnPropertyDescriptor(aObject, aPropertyName); - do_check_eq(typeof(descriptor.get), "function"); - do_check_eq(typeof(descriptor.value), "undefined"); - checkValue(aObject[aPropertyName], aType, aValue); - descriptor = Object.getOwnPropertyDescriptor(aObject, aPropertyName); - do_check_eq(typeof(descriptor.get), "undefined"); - do_check_neq(typeof(descriptor.value), "undefined"); -} - -function checkMainPropertyList(aPropertyListRoot) { - const PRIMITIVE = PropertyListUtils.TYPE_PRIMITIVE; - - checkValue(aPropertyListRoot, PropertyListUtils.TYPE_DICTIONARY); - - // Check .has() - Assert.ok(aPropertyListRoot.has("Boolean")); - Assert.ok(!aPropertyListRoot.has("Nonexistent")); - - checkValue(aPropertyListRoot.get("Boolean"), PRIMITIVE, false); - - let array = aPropertyListRoot.get("Array"); - checkValue(array, PropertyListUtils.TYPE_ARRAY); - do_check_eq(array.length, 8); - - // Test both long and short values, since binary property lists store - // long values a little bit differently (see readDataLengthAndOffset). - - // Short ASCII string - checkLazyGetterValue(array, 0, PRIMITIVE, "abc"); - // Long ASCII string - checkLazyGetterValue(array, 1, PRIMITIVE, new Array(1001).join("a")); - // Short unicode string - checkLazyGetterValue(array, 2, PRIMITIVE, "\u05D0\u05D0\u05D0"); - // Long unicode string - checkLazyGetterValue(array, 3, PRIMITIVE, new Array(1001).join("\u05D0")); - // Unicode surrogate pair - checkLazyGetterValue(array, 4, PRIMITIVE, - "\uD800\uDC00\uD800\uDC00\uD800\uDC00"); - - // Date - checkLazyGetterValue(array, 5, PropertyListUtils.TYPE_DATE, - new Date("2011-12-31T11:15:23Z")); - - // Data - checkLazyGetterValue(array, 6, PropertyListUtils.TYPE_UINT8_ARRAY); - let dataAsString = Array.from(array[6]).map(b => String.fromCharCode(b)).join(""); - do_check_eq(dataAsString, "2011-12-31T11:15:33Z"); - - // Dict - let dict = array[7]; - checkValue(dict, PropertyListUtils.TYPE_DICTIONARY); - checkValue(dict.get("Negative Number"), PRIMITIVE, -400); - checkValue(dict.get("Real Number"), PRIMITIVE, 2.71828183); - checkValue(dict.get("Big Int"), - PropertyListUtils.TYPE_INT64, - "9007199254740993"); - checkValue(dict.get("Negative Big Int"), - PropertyListUtils.TYPE_INT64, - "-9007199254740993"); -} - -function readPropertyList(aFile, aCallback) { - PropertyListUtils.read(aFile, function(aPropertyListRoot) { - // Null root indicates failure to read property list. - // Note: It is important not to run do_check_n/eq directly on Dict and array - // objects, because it cases their toString to get invoked, doing away with - // all the lazy getter we'd like to test later. - do_check_true(aPropertyListRoot !== null); - aCallback(aPropertyListRoot); - run_next_test(); - }); -} - -function run_test() { - add_test(readPropertyList.bind(this, - do_get_file("propertyLists/bug710259_propertyListBinary.plist", false), - checkMainPropertyList)); - add_test(readPropertyList.bind(this, - do_get_file("propertyLists/bug710259_propertyListXML.plist", false), - checkMainPropertyList)); - run_next_test(); -} diff --git a/toolkit/modules/tests/xpcshell/test_readCertPrefs.js b/toolkit/modules/tests/xpcshell/test_readCertPrefs.js deleted file mode 100644 index 837a9912a0..0000000000 --- a/toolkit/modules/tests/xpcshell/test_readCertPrefs.js +++ /dev/null @@ -1,97 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -Components.utils.import("resource://gre/modules/Services.jsm"); -Components.utils.import("resource://gre/modules/CertUtils.jsm"); - -const PREF_PREFIX = "certutils.certs."; - -function run_test() { - run_next_test(); -} - -function resetPrefs() { - var prefs = Services.prefs.getChildList(PREF_PREFIX); - prefs.forEach(Services.prefs.clearUserPref); -} - -function attributes_match(aCert, aExpected) { - if (Object.keys(aCert).length != Object.keys(aExpected).length) - return false; - - for (var attribute in aCert) { - if (!(attribute in aExpected)) - return false; - if (aCert[attribute] != aExpected[attribute]) - return false; - } - - return true; -} - -function test_results(aCerts, aExpected) { - do_check_eq(aCerts.length, aExpected.length); - - for (var i = 0; i < aCerts.length; i++) { - if (!attributes_match(aCerts[i], aExpected[i])) { - dump("Attributes for certificate " + (i + 1) + " did not match expected attributes\n"); - dump("Saw: " + aCerts[i].toSource() + "\n"); - dump("Expected: " + aExpected[i].toSource() + "\n"); - do_check_true(false); - } - } -} - -add_test(function test_singleCert() { - Services.prefs.setCharPref(PREF_PREFIX + "1.attribute1", "foo"); - Services.prefs.setCharPref(PREF_PREFIX + "1.attribute2", "bar"); - - var certs = readCertPrefs(PREF_PREFIX); - test_results(certs, [{ - attribute1: "foo", - attribute2: "bar" - }]); - - resetPrefs(); - run_next_test(); -}); - -add_test(function test_multipleCert() { - Services.prefs.setCharPref(PREF_PREFIX + "1.md5Fingerprint", "cf84a9a2a804e021f27cb5128fe151f4"); - Services.prefs.setCharPref(PREF_PREFIX + "1.nickname", "1st cert"); - Services.prefs.setCharPref(PREF_PREFIX + "2.md5Fingerprint", "9441051b7eb50e5ca2226095af710c1a"); - Services.prefs.setCharPref(PREF_PREFIX + "2.nickname", "2nd cert"); - - var certs = readCertPrefs(PREF_PREFIX); - test_results(certs, [{ - md5Fingerprint: "cf84a9a2a804e021f27cb5128fe151f4", - nickname: "1st cert" - }, { - md5Fingerprint: "9441051b7eb50e5ca2226095af710c1a", - nickname: "2nd cert" - }]); - - resetPrefs(); - run_next_test(); -}); - -add_test(function test_skippedCert() { - Services.prefs.setCharPref(PREF_PREFIX + "1.issuerName", "Mozilla"); - Services.prefs.setCharPref(PREF_PREFIX + "1.nickname", "1st cert"); - Services.prefs.setCharPref(PREF_PREFIX + "2.issuerName", "Top CA"); - Services.prefs.setCharPref(PREF_PREFIX + "2.nickname", "2nd cert"); - Services.prefs.setCharPref(PREF_PREFIX + "4.issuerName", "Unknown CA"); - Services.prefs.setCharPref(PREF_PREFIX + "4.nickname", "Ignored cert"); - - var certs = readCertPrefs(PREF_PREFIX); - test_results(certs, [{ - issuerName: "Mozilla", - nickname: "1st cert" - }, { - issuerName: "Top CA", - nickname: "2nd cert" - }]); - - resetPrefs(); - run_next_test(); -}); diff --git a/toolkit/modules/tests/xpcshell/test_servicerequest_xhr.js b/toolkit/modules/tests/xpcshell/test_servicerequest_xhr.js deleted file mode 100644 index b3c8a443ed..0000000000 --- a/toolkit/modules/tests/xpcshell/test_servicerequest_xhr.js +++ /dev/null @@ -1,25 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource://gre/modules/ServiceRequest.jsm"); - -add_task(function* test_tls_conservative() { - const request = new ServiceRequest(); - request.open("GET", "http://example.com", false); - - const sr_channel = request.channel.QueryInterface(Ci.nsIHttpChannelInternal); - ok(("beConservative" in sr_channel), "TLS setting is present in SR channel"); - ok(sr_channel.beConservative, "TLS setting in request channel is set to conservative for SR"); - - const xhr = new XMLHttpRequest(); - xhr.open("GET", "http://example.com", false); - - const xhr_channel = xhr.channel.QueryInterface(Ci.nsIHttpChannelInternal); - ok(("beConservative" in xhr_channel), "TLS setting is present in XHR channel"); - ok(!xhr_channel.beConservative, "TLS setting in request channel is not set to conservative for XHR"); - -}); diff --git a/toolkit/modules/tests/xpcshell/test_session_recorder.js b/toolkit/modules/tests/xpcshell/test_session_recorder.js deleted file mode 100644 index dd9159c6e8..0000000000 --- a/toolkit/modules/tests/xpcshell/test_session_recorder.js +++ /dev/null @@ -1,306 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var {utils: Cu} = Components; - -Cu.import("resource://gre/modules/Promise.jsm"); -Cu.import("resource://gre/modules/SessionRecorder.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://services-common/utils.js"); - - -function run_test() { - run_next_test(); -} - -function monkeypatchStartupInfo(recorder, start=new Date(), offset=500) { - Object.defineProperty(recorder, "_getStartupInfo", { - value: function _getStartupInfo() { - return { - process: start, - main: new Date(start.getTime() + offset), - firstPaint: new Date(start.getTime() + 2 * offset), - sessionRestored: new Date(start.getTime() + 3 * offset), - }; - } - }); -} - -function sleep(wait) { - let deferred = Promise.defer(); - - let timer = CommonUtils.namedTimer(function onTimer() { - deferred.resolve(); - }, wait, deferred.promise, "_sleepTimer"); - - return deferred.promise; -} - -function getRecorder(name, start, offset) { - let recorder = new SessionRecorder("testing." + name + "."); - monkeypatchStartupInfo(recorder, start, offset); - - return recorder; -} - -add_test(function test_basic() { - let recorder = getRecorder("basic"); - recorder.onStartup(); - recorder.onShutdown(); - - run_next_test(); -}); - -add_task(function* test_current_properties() { - let now = new Date(); - let recorder = getRecorder("current_properties", now); - yield sleep(25); - recorder.onStartup(); - - do_check_eq(recorder.startDate.getTime(), now.getTime()); - do_check_eq(recorder.activeTicks, 0); - do_check_true(recorder.fineTotalTime > 0); - do_check_eq(recorder.main, 500); - do_check_eq(recorder.firstPaint, 1000); - do_check_eq(recorder.sessionRestored, 1500); - - recorder.incrementActiveTicks(); - do_check_eq(recorder.activeTicks, 1); - - recorder._startDate = new Date(Date.now() - 1000); - recorder.updateTotalTime(); - do_check_eq(recorder.totalTime, 1); - - recorder.onShutdown(); -}); - -// If startup info isn't present yet, we should install a timer and get -// it eventually. -add_task(function* test_current_availability() { - let recorder = new SessionRecorder("testing.current_availability."); - let now = new Date(); - - Object.defineProperty(recorder, "_getStartupInfo", { - value: function _getStartupInfo() { - return { - process: now, - main: new Date(now.getTime() + 500), - firstPaint: new Date(now.getTime() + 1000), - }; - }, - writable: true, - }); - - Object.defineProperty(recorder, "STARTUP_RETRY_INTERVAL_MS", { - value: 100, - }); - - let oldRecord = recorder.recordStartupFields; - let recordCount = 0; - - Object.defineProperty(recorder, "recordStartupFields", { - value: function () { - recordCount++; - return oldRecord.call(recorder); - } - }); - - do_check_null(recorder._timer); - recorder.onStartup(); - do_check_eq(recordCount, 1); - do_check_eq(recorder.sessionRestored, -1); - do_check_neq(recorder._timer, null); - - yield sleep(125); - do_check_eq(recordCount, 2); - yield sleep(100); - do_check_eq(recordCount, 3); - do_check_eq(recorder.sessionRestored, -1); - - monkeypatchStartupInfo(recorder, now); - yield sleep(100); - do_check_eq(recordCount, 4); - do_check_eq(recorder.sessionRestored, 1500); - - // The timer should be removed and we should not fire again. - do_check_null(recorder._timer); - yield sleep(100); - do_check_eq(recordCount, 4); - - recorder.onShutdown(); -}); - -add_test(function test_timer_clear_on_shutdown() { - let recorder = new SessionRecorder("testing.timer_clear_on_shutdown."); - let now = new Date(); - - Object.defineProperty(recorder, "_getStartupInfo", { - value: function _getStartupInfo() { - return { - process: now, - main: new Date(now.getTime() + 500), - firstPaint: new Date(now.getTime() + 1000), - }; - }, - }); - - do_check_null(recorder._timer); - recorder.onStartup(); - do_check_neq(recorder._timer, null); - - recorder.onShutdown(); - do_check_null(recorder._timer); - - run_next_test(); -}); - -add_task(function* test_previous_clean() { - let now = new Date(); - let recorder = getRecorder("previous_clean", now); - yield sleep(25); - recorder.onStartup(); - - recorder.incrementActiveTicks(); - recorder.incrementActiveTicks(); - - yield sleep(25); - recorder.onShutdown(); - - let total = recorder.totalTime; - - yield sleep(25); - let now2 = new Date(); - let recorder2 = getRecorder("previous_clean", now2, 100); - yield sleep(25); - recorder2.onStartup(); - - do_check_eq(recorder2.startDate.getTime(), now2.getTime()); - do_check_eq(recorder2.main, 100); - do_check_eq(recorder2.firstPaint, 200); - do_check_eq(recorder2.sessionRestored, 300); - - let sessions = recorder2.getPreviousSessions(); - do_check_eq(Object.keys(sessions).length, 1); - do_check_true(0 in sessions); - let session = sessions[0]; - do_check_true(session.clean); - do_check_eq(session.startDate.getTime(), now.getTime()); - do_check_eq(session.main, 500); - do_check_eq(session.firstPaint, 1000); - do_check_eq(session.sessionRestored, 1500); - do_check_eq(session.totalTime, total); - do_check_eq(session.activeTicks, 2); - - recorder2.onShutdown(); -}); - -add_task(function* test_previous_abort() { - let now = new Date(); - let recorder = getRecorder("previous_abort", now); - yield sleep(25); - recorder.onStartup(); - recorder.incrementActiveTicks(); - yield sleep(25); - let total = recorder.totalTime; - yield sleep(25); - - let now2 = new Date(); - let recorder2 = getRecorder("previous_abort", now2); - yield sleep(25); - recorder2.onStartup(); - - let sessions = recorder2.getPreviousSessions(); - do_check_eq(Object.keys(sessions).length, 1); - do_check_true(0 in sessions); - let session = sessions[0]; - do_check_false(session.clean); - do_check_eq(session.totalTime, total); - - recorder.onShutdown(); - recorder2.onShutdown(); -}); - -add_task(function* test_multiple_sessions() { - for (let i = 0; i < 10; i++) { - let recorder = getRecorder("multiple_sessions"); - yield sleep(25); - recorder.onStartup(); - for (let j = 0; j < i; j++) { - recorder.incrementActiveTicks(); - } - yield sleep(25); - recorder.onShutdown(); - yield sleep(25); - } - - let recorder = getRecorder("multiple_sessions"); - recorder.onStartup(); - - let sessions = recorder.getPreviousSessions(); - do_check_eq(Object.keys(sessions).length, 10); - - for (let [i, session] of Object.entries(sessions)) { - do_check_eq(session.activeTicks, i); - - if (i > 0) { - do_check_true(session.startDate.getTime() > sessions[i-1].startDate.getTime()); - } - } - - // #6 is preserved since >=. - let threshold = sessions[6].startDate; - recorder.pruneOldSessions(threshold); - - sessions = recorder.getPreviousSessions(); - do_check_eq(Object.keys(sessions).length, 4); - - recorder.pruneOldSessions(threshold); - sessions = recorder.getPreviousSessions(); - do_check_eq(Object.keys(sessions).length, 4); - do_check_eq(recorder._prunedIndex, 5); - - recorder.onShutdown(); -}); - -add_task(function* test_record_activity() { - let recorder = getRecorder("record_activity"); - yield sleep(25); - recorder.onStartup(); - let total = recorder.totalTime; - yield sleep(25); - - for (let i = 0; i < 3; i++) { - Services.obs.notifyObservers(null, "user-interaction-active", null); - yield sleep(25); - do_check_true(recorder.fineTotalTime > total); - total = recorder.fineTotalTime; - } - - do_check_eq(recorder.activeTicks, 3); - - // Now send inactive. We should increment total time but not active. - Services.obs.notifyObservers(null, "user-interaction-inactive", null); - do_check_eq(recorder.activeTicks, 3); - do_check_true(recorder.fineTotalTime > total); - total = recorder.fineTotalTime; - yield sleep(25); - - // If we send active again, this should be counted as inactive. - Services.obs.notifyObservers(null, "user-interaction-active", null); - do_check_eq(recorder.activeTicks, 3); - do_check_true(recorder.fineTotalTime > total); - total = recorder.fineTotalTime; - yield sleep(25); - - // If we send active again, this should be counted as active. - Services.obs.notifyObservers(null, "user-interaction-active", null); - do_check_eq(recorder.activeTicks, 4); - - Services.obs.notifyObservers(null, "user-interaction-active", null); - do_check_eq(recorder.activeTicks, 5); - - recorder.onShutdown(); -}); - diff --git a/toolkit/modules/tests/xpcshell/test_sqlite.js b/toolkit/modules/tests/xpcshell/test_sqlite.js deleted file mode 100644 index edd39d9770..0000000000 --- a/toolkit/modules/tests/xpcshell/test_sqlite.js +++ /dev/null @@ -1,1094 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -do_get_profile(); - -Cu.import("resource://gre/modules/Promise.jsm"); -Cu.import("resource://gre/modules/PromiseUtils.jsm"); -Cu.import("resource://gre/modules/osfile.jsm"); -Cu.import("resource://gre/modules/FileUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/Sqlite.jsm"); -Cu.import("resource://gre/modules/Task.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -// To spin the event loop in test. -Cu.import("resource://services-common/async.js"); - -function sleep(ms) { - let deferred = Promise.defer(); - - let timer = Cc["@mozilla.org/timer;1"] - .createInstance(Ci.nsITimer); - - timer.initWithCallback({ - notify: function () { - deferred.resolve(); - }, - }, ms, timer.TYPE_ONE_SHOT); - - return deferred.promise; -} - -// When testing finalization, use this to tell Sqlite.jsm to not throw -// an uncatchable `Promise.reject` -function failTestsOnAutoClose(enabled) { - Cu.getGlobalForObject(Sqlite).Debugging.failTestsOnAutoClose = enabled; -} - -function getConnection(dbName, extraOptions={}) { - let path = dbName + ".sqlite"; - let options = {path: path}; - for (let [k, v] of Object.entries(extraOptions)) { - options[k] = v; - } - - return Sqlite.openConnection(options); -} - -function* getDummyDatabase(name, extraOptions={}) { - const TABLES = { - dirs: "id INTEGER PRIMARY KEY AUTOINCREMENT, path TEXT", - files: "id INTEGER PRIMARY KEY AUTOINCREMENT, dir_id INTEGER, path TEXT", - }; - - let c = yield getConnection(name, extraOptions); - c._initialStatementCount = 0; - - for (let [k, v] of Object.entries(TABLES)) { - yield c.execute("CREATE TABLE " + k + "(" + v + ")"); - c._initialStatementCount++; - } - - return c; -} - -function* getDummyTempDatabase(name, extraOptions={}) { - const TABLES = { - dirs: "id INTEGER PRIMARY KEY AUTOINCREMENT, path TEXT", - files: "id INTEGER PRIMARY KEY AUTOINCREMENT, dir_id INTEGER, path TEXT", - }; - - let c = yield getConnection(name, extraOptions); - c._initialStatementCount = 0; - - for (let [k, v] of Object.entries(TABLES)) { - yield c.execute("CREATE TEMP TABLE " + k + "(" + v + ")"); - c._initialStatementCount++; - } - - return c; -} - -function run_test() { - Cu.import("resource://testing-common/services/common/logging.js"); - initTestLogging("Trace"); - - run_next_test(); -} - -add_task(function* test_open_normal() { - let c = yield Sqlite.openConnection({path: "test_open_normal.sqlite"}); - yield c.close(); -}); - -add_task(function* test_open_unshared() { - let path = OS.Path.join(OS.Constants.Path.profileDir, "test_open_unshared.sqlite"); - - let c = yield Sqlite.openConnection({path: path, sharedMemoryCache: false}); - yield c.close(); -}); - -add_task(function* test_get_dummy_database() { - let db = yield getDummyDatabase("get_dummy_database"); - - do_check_eq(typeof(db), "object"); - yield db.close(); -}); - -add_task(function* test_schema_version() { - let db = yield getDummyDatabase("schema_version"); - - let version = yield db.getSchemaVersion(); - do_check_eq(version, 0); - - db.setSchemaVersion(14); - version = yield db.getSchemaVersion(); - do_check_eq(version, 14); - - for (let v of [0.5, "foobar", NaN]) { - let success; - try { - yield db.setSchemaVersion(v); - do_print("Schema version " + v + " should have been rejected"); - success = false; - } catch (ex) { - if (!ex.message.startsWith("Schema version must be an integer.")) - throw ex; - success = true; - } - do_check_true(success); - - version = yield db.getSchemaVersion(); - do_check_eq(version, 14); - } - - yield db.close(); -}); - -add_task(function* test_simple_insert() { - let c = yield getDummyDatabase("simple_insert"); - - let result = yield c.execute("INSERT INTO dirs VALUES (NULL, 'foo')"); - do_check_true(Array.isArray(result)); - do_check_eq(result.length, 0); - yield c.close(); -}); - -add_task(function* test_simple_bound_array() { - let c = yield getDummyDatabase("simple_bound_array"); - - let result = yield c.execute("INSERT INTO dirs VALUES (?, ?)", [1, "foo"]); - do_check_eq(result.length, 0); - yield c.close(); -}); - -add_task(function* test_simple_bound_object() { - let c = yield getDummyDatabase("simple_bound_object"); - let result = yield c.execute("INSERT INTO dirs VALUES (:id, :path)", - {id: 1, path: "foo"}); - do_check_eq(result.length, 0); - result = yield c.execute("SELECT id, path FROM dirs"); - do_check_eq(result.length, 1); - do_check_eq(result[0].getResultByName("id"), 1); - do_check_eq(result[0].getResultByName("path"), "foo"); - yield c.close(); -}); - -// This is mostly a sanity test to ensure simple executions work. -add_task(function* test_simple_insert_then_select() { - let c = yield getDummyDatabase("simple_insert_then_select"); - - yield c.execute("INSERT INTO dirs VALUES (NULL, 'foo')"); - yield c.execute("INSERT INTO dirs (path) VALUES (?)", ["bar"]); - - let result = yield c.execute("SELECT * FROM dirs"); - do_check_eq(result.length, 2); - - let i = 0; - for (let row of result) { - i++; - - do_check_eq(row.numEntries, 2); - do_check_eq(row.getResultByIndex(0), i); - - let expected = {1: "foo", 2: "bar"}[i]; - do_check_eq(row.getResultByName("path"), expected); - } - - yield c.close(); -}); - -add_task(function* test_repeat_execution() { - let c = yield getDummyDatabase("repeat_execution"); - - let sql = "INSERT INTO dirs (path) VALUES (:path)"; - yield c.executeCached(sql, {path: "foo"}); - yield c.executeCached(sql); - - let result = yield c.execute("SELECT * FROM dirs"); - - do_check_eq(result.length, 2); - - yield c.close(); -}); - -add_task(function* test_table_exists() { - let c = yield getDummyDatabase("table_exists"); - - do_check_false(yield c.tableExists("does_not_exist")); - do_check_true(yield c.tableExists("dirs")); - do_check_true(yield c.tableExists("files")); - - yield c.close(); -}); - -add_task(function* test_index_exists() { - let c = yield getDummyDatabase("index_exists"); - - do_check_false(yield c.indexExists("does_not_exist")); - - yield c.execute("CREATE INDEX my_index ON dirs (path)"); - do_check_true(yield c.indexExists("my_index")); - - yield c.close(); -}); - -add_task(function* test_temp_table_exists() { - let c = yield getDummyTempDatabase("temp_table_exists"); - - do_check_false(yield c.tableExists("temp_does_not_exist")); - do_check_true(yield c.tableExists("dirs")); - do_check_true(yield c.tableExists("files")); - - yield c.close(); -}); - -add_task(function* test_temp_index_exists() { - let c = yield getDummyTempDatabase("temp_index_exists"); - - do_check_false(yield c.indexExists("temp_does_not_exist")); - - yield c.execute("CREATE INDEX my_index ON dirs (path)"); - do_check_true(yield c.indexExists("my_index")); - - yield c.close(); -}); - -add_task(function* test_close_cached() { - let c = yield getDummyDatabase("close_cached"); - - yield c.executeCached("SELECT * FROM dirs"); - yield c.executeCached("SELECT * FROM files"); - - yield c.close(); -}); - -add_task(function* test_execute_invalid_statement() { - let c = yield getDummyDatabase("invalid_statement"); - - let deferred = Promise.defer(); - - do_check_eq(c._connectionData._anonymousStatements.size, 0); - - c.execute("SELECT invalid FROM unknown").then(do_throw, function onError(error) { - deferred.resolve(); - }); - - yield deferred.promise; - - // Ensure we don't leak the statement instance. - do_check_eq(c._connectionData._anonymousStatements.size, 0); - - yield c.close(); -}); - -add_task(function* test_incorrect_like_bindings() { - let c = yield getDummyDatabase("incorrect_like_bindings"); - - let sql = "select * from dirs where path LIKE 'non%'"; - Assert.throws(() => c.execute(sql), /Please enter a LIKE clause/); - Assert.throws(() => c.executeCached(sql), /Please enter a LIKE clause/); - - yield c.close(); -}); -add_task(function* test_on_row_exception_ignored() { - let c = yield getDummyDatabase("on_row_exception_ignored"); - - let sql = "INSERT INTO dirs (path) VALUES (?)"; - for (let i = 0; i < 10; i++) { - yield c.executeCached(sql, ["dir" + i]); - } - - let i = 0; - let hasResult = yield c.execute("SELECT * FROM DIRS", null, function onRow(row) { - i++; - - throw new Error("Some silly error."); - }); - - do_check_eq(hasResult, true); - do_check_eq(i, 10); - - yield c.close(); -}); - -// Ensure StopIteration during onRow causes processing to stop. -add_task(function* test_on_row_stop_iteration() { - let c = yield getDummyDatabase("on_row_stop_iteration"); - - let sql = "INSERT INTO dirs (path) VALUES (?)"; - for (let i = 0; i < 10; i++) { - yield c.executeCached(sql, ["dir" + i]); - } - - let i = 0; - let hasResult = yield c.execute("SELECT * FROM dirs", null, function onRow(row) { - i++; - - if (i == 5) { - throw StopIteration; - } - }); - - do_check_eq(hasResult, true); - do_check_eq(i, 5); - - yield c.close(); -}); - -// Ensure execute resolves to false when no rows are selected. -add_task(function* test_on_row_stop_iteration() { - let c = yield getDummyDatabase("no_on_row"); - - let i = 0; - let hasResult = yield c.execute(`SELECT * FROM dirs WHERE path="nonexistent"`, null, function onRow(row) { - i++; - }); - - do_check_eq(hasResult, false); - do_check_eq(i, 0); - - yield c.close(); -}); - -add_task(function* test_invalid_transaction_type() { - let c = yield getDummyDatabase("invalid_transaction_type"); - - Assert.throws(() => c.executeTransaction(function* () {}, "foobar"), - /Unknown transaction type/, - "Unknown transaction type should throw"); - - yield c.close(); -}); - -add_task(function* test_execute_transaction_success() { - let c = yield getDummyDatabase("execute_transaction_success"); - - do_check_false(c.transactionInProgress); - - yield c.executeTransaction(function* transaction(conn) { - do_check_eq(c, conn); - do_check_true(conn.transactionInProgress); - - yield conn.execute("INSERT INTO dirs (path) VALUES ('foo')"); - }); - - do_check_false(c.transactionInProgress); - let rows = yield c.execute("SELECT * FROM dirs"); - do_check_true(Array.isArray(rows)); - do_check_eq(rows.length, 1); - - yield c.close(); -}); - -add_task(function* test_execute_transaction_rollback() { - let c = yield getDummyDatabase("execute_transaction_rollback"); - - let deferred = Promise.defer(); - - c.executeTransaction(function* transaction(conn) { - yield conn.execute("INSERT INTO dirs (path) VALUES ('foo')"); - print("Expecting error with next statement."); - yield conn.execute("INSERT INTO invalid VALUES ('foo')"); - - // We should never get here. - do_throw(); - }).then(do_throw, function onError(error) { - deferred.resolve(); - }); - - yield deferred.promise; - - let rows = yield c.execute("SELECT * FROM dirs"); - do_check_eq(rows.length, 0); - - yield c.close(); -}); - -add_task(function* test_close_during_transaction() { - let c = yield getDummyDatabase("close_during_transaction"); - - yield c.execute("INSERT INTO dirs (path) VALUES ('foo')"); - - let promise = c.executeTransaction(function* transaction(conn) { - yield c.execute("INSERT INTO dirs (path) VALUES ('bar')"); - }); - yield c.close(); - - yield Assert.rejects(promise, - /Transaction canceled due to a closed connection/, - "closing a connection in the middle of a transaction should reject it"); - - let c2 = yield getConnection("close_during_transaction"); - let rows = yield c2.execute("SELECT * FROM dirs"); - do_check_eq(rows.length, 1); - - yield c2.close(); -}); - -// Verify that we support concurrent transactions. -add_task(function* test_multiple_transactions() { - let c = yield getDummyDatabase("detect_multiple_transactions"); - - for (let i = 0; i < 10; ++i) { - // We don't wait for these transactions. - c.executeTransaction(function* () { - yield c.execute("INSERT INTO dirs (path) VALUES (:path)", - { path: `foo${i}` }); - yield c.execute("SELECT * FROM dirs"); - }); - } - for (let i = 0; i < 10; ++i) { - yield c.executeTransaction(function* () { - yield c.execute("INSERT INTO dirs (path) VALUES (:path)", - { path: `bar${i}` }); - yield c.execute("SELECT * FROM dirs"); - }); - } - - let rows = yield c.execute("SELECT * FROM dirs"); - do_check_eq(rows.length, 20); - - yield c.close(); -}); - -// Verify that wrapped transactions ignore a BEGIN TRANSACTION failure, when -// an externally opened transaction exists. -add_task(function* test_wrapped_connection_transaction() { - let file = new FileUtils.File(OS.Path.join(OS.Constants.Path.profileDir, - "test_wrapStorageConnection.sqlite")); - let c = yield new Promise((resolve, reject) => { - Services.storage.openAsyncDatabase(file, null, (status, db) => { - if (Components.isSuccessCode(status)) { - resolve(db.QueryInterface(Ci.mozIStorageAsyncConnection)); - } else { - reject(new Error(status)); - } - }); - }); - - let wrapper = yield Sqlite.wrapStorageConnection({ connection: c }); - // Start a transaction on the raw connection. - yield c.executeSimpleSQLAsync("BEGIN"); - // Now use executeTransaction, it will be executed, but not in a transaction. - yield wrapper.executeTransaction(function* () { - yield wrapper.execute("CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT)"); - }); - // This should not fail cause the internal transaction has not been created. - yield c.executeSimpleSQLAsync("COMMIT"); - - yield wrapper.execute("SELECT * FROM test"); - - // Closing the wrapper should just finalize statements but not close the - // database. - yield wrapper.close(); - yield c.asyncClose(); -}); - -add_task(function* test_shrink_memory() { - let c = yield getDummyDatabase("shrink_memory"); - - // It's just a simple sanity test. We have no way of measuring whether this - // actually does anything. - - yield c.shrinkMemory(); - yield c.close(); -}); - -add_task(function* test_no_shrink_on_init() { - let c = yield getConnection("no_shrink_on_init", - {shrinkMemoryOnConnectionIdleMS: 200}); - - let oldShrink = c._connectionData.shrinkMemory; - let count = 0; - Object.defineProperty(c._connectionData, "shrinkMemory", { - value: function () { - count++; - }, - }); - - // We should not shrink until a statement has been executed. - yield sleep(220); - do_check_eq(count, 0); - - yield c.execute("SELECT 1"); - yield sleep(220); - do_check_eq(count, 1); - - yield c.close(); -}); - -add_task(function* test_idle_shrink_fires() { - let c = yield getDummyDatabase("idle_shrink_fires", - {shrinkMemoryOnConnectionIdleMS: 200}); - c._connectionData._clearIdleShrinkTimer(); - - let oldShrink = c._connectionData.shrinkMemory; - let shrinkPromises = []; - - let count = 0; - Object.defineProperty(c._connectionData, "shrinkMemory", { - value: function () { - count++; - let promise = oldShrink.call(c._connectionData); - shrinkPromises.push(promise); - return promise; - }, - }); - - // We reset the idle shrink timer after monkeypatching because otherwise the - // installed timer callback will reference the non-monkeypatched function. - c._connectionData._startIdleShrinkTimer(); - - yield sleep(220); - do_check_eq(count, 1); - do_check_eq(shrinkPromises.length, 1); - yield shrinkPromises[0]; - shrinkPromises.shift(); - - // We shouldn't shrink again unless a statement was executed. - yield sleep(300); - do_check_eq(count, 1); - - yield c.execute("SELECT 1"); - yield sleep(300); - - do_check_eq(count, 2); - do_check_eq(shrinkPromises.length, 1); - yield shrinkPromises[0]; - - yield c.close(); -}); - -add_task(function* test_idle_shrink_reset_on_operation() { - const INTERVAL = 500; - let c = yield getDummyDatabase("idle_shrink_reset_on_operation", - {shrinkMemoryOnConnectionIdleMS: INTERVAL}); - - c._connectionData._clearIdleShrinkTimer(); - - let oldShrink = c._connectionData.shrinkMemory; - let shrinkPromises = []; - let count = 0; - - Object.defineProperty(c._connectionData, "shrinkMemory", { - value: function () { - count++; - let promise = oldShrink.call(c._connectionData); - shrinkPromises.push(promise); - return promise; - }, - }); - - let now = new Date(); - c._connectionData._startIdleShrinkTimer(); - - let initialIdle = new Date(now.getTime() + INTERVAL); - - // Perform database operations until initial scheduled time has been passed. - let i = 0; - while (new Date() < initialIdle) { - yield c.execute("INSERT INTO dirs (path) VALUES (?)", ["" + i]); - i++; - } - - do_check_true(i > 0); - - // We should not have performed an idle while doing operations. - do_check_eq(count, 0); - - // Wait for idle timer. - yield sleep(INTERVAL); - - // Ensure we fired. - do_check_eq(count, 1); - do_check_eq(shrinkPromises.length, 1); - yield shrinkPromises[0]; - - yield c.close(); -}); - -add_task(function* test_in_progress_counts() { - let c = yield getDummyDatabase("in_progress_counts"); - do_check_eq(c._connectionData._statementCounter, c._initialStatementCount); - do_check_eq(c._connectionData._pendingStatements.size, 0); - yield c.executeCached("INSERT INTO dirs (path) VALUES ('foo')"); - do_check_eq(c._connectionData._statementCounter, c._initialStatementCount + 1); - do_check_eq(c._connectionData._pendingStatements.size, 0); - - let expectOne; - let expectTwo; - - // Please forgive me. - let inner = Async.makeSpinningCallback(); - let outer = Async.makeSpinningCallback(); - - // We want to make sure that two queries executing simultaneously - // result in `_pendingStatements.size` reaching 2, then dropping back to 0. - // - // To do so, we kick off a second statement within the row handler - // of the first, then wait for both to finish. - - yield c.executeCached("SELECT * from dirs", null, function onRow() { - // In the onRow handler, we're still an outstanding query. - // Expect a single in-progress entry. - expectOne = c._connectionData._pendingStatements.size; - - // Start another query, checking that after its statement has been created - // there are two statements in progress. - let p = c.executeCached("SELECT 10, path from dirs"); - expectTwo = c._connectionData._pendingStatements.size; - - // Now wait for it to be done before we return from the row handler … - p.then(function onInner() { - inner(); - }); - }).then(function onOuter() { - // … and wait for the inner to be done before we finish … - inner.wait(); - outer(); - }); - - // … and wait for both queries to have finished before we go on and - // test postconditions. - outer.wait(); - - do_check_eq(expectOne, 1); - do_check_eq(expectTwo, 2); - do_check_eq(c._connectionData._statementCounter, c._initialStatementCount + 3); - do_check_eq(c._connectionData._pendingStatements.size, 0); - - yield c.close(); -}); - -add_task(function* test_discard_while_active() { - let c = yield getDummyDatabase("discard_while_active"); - - yield c.executeCached("INSERT INTO dirs (path) VALUES ('foo')"); - yield c.executeCached("INSERT INTO dirs (path) VALUES ('bar')"); - - let discarded = -1; - let first = true; - let sql = "SELECT * FROM dirs"; - yield c.executeCached(sql, null, function onRow(row) { - if (!first) { - return; - } - first = false; - discarded = c.discardCachedStatements(); - }); - - // We discarded everything, because the SELECT had already started to run. - do_check_eq(3, discarded); - - // And again is safe. - do_check_eq(0, c.discardCachedStatements()); - - yield c.close(); -}); - -add_task(function* test_discard_cached() { - let c = yield getDummyDatabase("discard_cached"); - - yield c.executeCached("SELECT * from dirs"); - do_check_eq(1, c._connectionData._cachedStatements.size); - - yield c.executeCached("SELECT * from files"); - do_check_eq(2, c._connectionData._cachedStatements.size); - - yield c.executeCached("SELECT * from dirs"); - do_check_eq(2, c._connectionData._cachedStatements.size); - - c.discardCachedStatements(); - do_check_eq(0, c._connectionData._cachedStatements.size); - - yield c.close(); -}); - -add_task(function* test_programmatic_binding() { - let c = yield getDummyDatabase("programmatic_binding"); - - let bindings = [ - {id: 1, path: "foobar"}, - {id: null, path: "baznoo"}, - {id: 5, path: "toofoo"}, - ]; - - let sql = "INSERT INTO dirs VALUES (:id, :path)"; - let result = yield c.execute(sql, bindings); - do_check_eq(result.length, 0); - - let rows = yield c.executeCached("SELECT * from dirs"); - do_check_eq(rows.length, 3); - yield c.close(); -}); - -add_task(function* test_programmatic_binding_transaction() { - let c = yield getDummyDatabase("programmatic_binding_transaction"); - - let bindings = [ - {id: 1, path: "foobar"}, - {id: null, path: "baznoo"}, - {id: 5, path: "toofoo"}, - ]; - - let sql = "INSERT INTO dirs VALUES (:id, :path)"; - yield c.executeTransaction(function* transaction() { - let result = yield c.execute(sql, bindings); - do_check_eq(result.length, 0); - - let rows = yield c.executeCached("SELECT * from dirs"); - do_check_eq(rows.length, 3); - }); - - // Transaction committed. - let rows = yield c.executeCached("SELECT * from dirs"); - do_check_eq(rows.length, 3); - yield c.close(); -}); - -add_task(function* test_programmatic_binding_transaction_partial_rollback() { - let c = yield getDummyDatabase("programmatic_binding_transaction_partial_rollback"); - - let bindings = [ - {id: 2, path: "foobar"}, - {id: 3, path: "toofoo"}, - ]; - - let sql = "INSERT INTO dirs VALUES (:id, :path)"; - - // Add some data in an implicit transaction before beginning the batch insert. - yield c.execute(sql, {id: 1, path: "works"}); - - let secondSucceeded = false; - try { - yield c.executeTransaction(function* transaction() { - // Insert one row. This won't implicitly start a transaction. - let result = yield c.execute(sql, bindings[0]); - - // Insert multiple rows. mozStorage will want to start a transaction. - // One of the inserts will fail, so the transaction should be rolled back. - result = yield c.execute(sql, bindings); - secondSucceeded = true; - }); - } catch (ex) { - print("Caught expected exception: " + ex); - } - - // We did not get to the end of our in-transaction block. - do_check_false(secondSucceeded); - - // Everything that happened in *our* transaction, not mozStorage's, got - // rolled back, but the first row still exists. - let rows = yield c.executeCached("SELECT * from dirs"); - do_check_eq(rows.length, 1); - do_check_eq(rows[0].getResultByName("path"), "works"); - yield c.close(); -}); - -// Just like the previous test, but relying on the implicit -// transaction established by mozStorage. -add_task(function* test_programmatic_binding_implicit_transaction() { - let c = yield getDummyDatabase("programmatic_binding_implicit_transaction"); - - let bindings = [ - {id: 2, path: "foobar"}, - {id: 1, path: "toofoo"}, - ]; - - let sql = "INSERT INTO dirs VALUES (:id, :path)"; - let secondSucceeded = false; - yield c.execute(sql, {id: 1, path: "works"}); - try { - let result = yield c.execute(sql, bindings); - secondSucceeded = true; - } catch (ex) { - print("Caught expected exception: " + ex); - } - - do_check_false(secondSucceeded); - - // The entire batch failed. - let rows = yield c.executeCached("SELECT * from dirs"); - do_check_eq(rows.length, 1); - do_check_eq(rows[0].getResultByName("path"), "works"); - yield c.close(); -}); - -// Test that direct binding of params and execution through mozStorage doesn't -// error when we manually create a transaction. See Bug 856925. -add_task(function* test_direct() { - let file = FileUtils.getFile("TmpD", ["test_direct.sqlite"]); - file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE); - print("Opening " + file.path); - - let db = Services.storage.openDatabase(file); - print("Opened " + db); - - db.executeSimpleSQL("CREATE TABLE types (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, UNIQUE (name))"); - print("Executed setup."); - - let statement = db.createAsyncStatement("INSERT INTO types (name) VALUES (:name)"); - let params = statement.newBindingParamsArray(); - let one = params.newBindingParams(); - one.bindByName("name", null); - params.addParams(one); - let two = params.newBindingParams(); - two.bindByName("name", "bar"); - params.addParams(two); - - print("Beginning transaction."); - let begin = db.createAsyncStatement("BEGIN DEFERRED TRANSACTION"); - let end = db.createAsyncStatement("COMMIT TRANSACTION"); - - let deferred = Promise.defer(); - begin.executeAsync({ - handleCompletion: function (reason) { - deferred.resolve(); - } - }); - yield deferred.promise; - - statement.bindParameters(params); - - deferred = Promise.defer(); - print("Executing async."); - statement.executeAsync({ - handleResult: function (resultSet) { - }, - - handleError: function (error) { - print("Error when executing SQL (" + error.result + "): " + - error.message); - print("Original error: " + error.error); - errors.push(error); - deferred.reject(); - }, - - handleCompletion: function (reason) { - print("Completed."); - deferred.resolve(); - } - }); - - yield deferred.promise; - - deferred = Promise.defer(); - end.executeAsync({ - handleCompletion: function (reason) { - deferred.resolve(); - } - }); - yield deferred.promise; - - statement.finalize(); - begin.finalize(); - end.finalize(); - - deferred = Promise.defer(); - db.asyncClose(function () { - deferred.resolve() - }); - yield deferred.promise; -}); - -// Test Sqlite.cloneStorageConnection. -add_task(function* test_cloneStorageConnection() { - let file = new FileUtils.File(OS.Path.join(OS.Constants.Path.profileDir, - "test_cloneStorageConnection.sqlite")); - let c = yield new Promise((resolve, reject) => { - Services.storage.openAsyncDatabase(file, null, (status, db) => { - if (Components.isSuccessCode(status)) { - resolve(db.QueryInterface(Ci.mozIStorageAsyncConnection)); - } else { - reject(new Error(status)); - } - }); - }); - - let clone = yield Sqlite.cloneStorageConnection({ connection: c, readOnly: true }); - // Just check that it works. - yield clone.execute("SELECT 1"); - - let clone2 = yield Sqlite.cloneStorageConnection({ connection: c, readOnly: false }); - // Just check that it works. - yield clone2.execute("CREATE TABLE test (id INTEGER PRIMARY KEY)"); - - // Closing order should not matter. - yield c.asyncClose(); - yield clone2.close(); - yield clone.close(); -}); - -// Test Sqlite.cloneStorageConnection invalid argument. -add_task(function* test_cloneStorageConnection() { - try { - let clone = yield Sqlite.cloneStorageConnection({ connection: null }); - do_throw(new Error("Should throw on invalid connection")); - } catch (ex) { - if (ex.name != "TypeError") { - throw ex; - } - } -}); - -// Test clone() method. -add_task(function* test_clone() { - let c = yield getDummyDatabase("clone"); - - let clone = yield c.clone(); - // Just check that it works. - yield clone.execute("SELECT 1"); - // Closing order should not matter. - yield c.close(); - yield clone.close(); -}); - -// Test clone(readOnly) method. -add_task(function* test_readOnly_clone() { - let path = OS.Path.join(OS.Constants.Path.profileDir, "test_readOnly_clone.sqlite"); - let c = yield Sqlite.openConnection({path: path, sharedMemoryCache: false}); - - let clone = yield c.clone(true); - // Just check that it works. - yield clone.execute("SELECT 1"); - // But should not be able to write. - - yield Assert.rejects(clone.execute("CREATE TABLE test (id INTEGER PRIMARY KEY)"), - /readonly/); - // Closing order should not matter. - yield c.close(); - yield clone.close(); -}); - -// Test Sqlite.wrapStorageConnection. -add_task(function* test_wrapStorageConnection() { - let file = new FileUtils.File(OS.Path.join(OS.Constants.Path.profileDir, - "test_wrapStorageConnection.sqlite")); - let c = yield new Promise((resolve, reject) => { - Services.storage.openAsyncDatabase(file, null, (status, db) => { - if (Components.isSuccessCode(status)) { - resolve(db.QueryInterface(Ci.mozIStorageAsyncConnection)); - } else { - reject(new Error(status)); - } - }); - }); - - let wrapper = yield Sqlite.wrapStorageConnection({ connection: c }); - // Just check that it works. - yield wrapper.execute("SELECT 1"); - yield wrapper.executeCached("SELECT 1"); - - // Closing the wrapper should just finalize statements but not close the - // database. - yield wrapper.close(); - yield c.asyncClose(); -}); - -// Test finalization -add_task(function* test_closed_by_witness() { - failTestsOnAutoClose(false); - let c = yield getDummyDatabase("closed_by_witness"); - - Services.obs.notifyObservers(null, "sqlite-finalization-witness", - c._connectionData._identifier); - // Since we triggered finalization ourselves, tell the witness to - // forget the connection so it does not trigger a finalization again - c._witness.forget(); - yield c._connectionData._deferredClose.promise; - do_check_false(c._connectionData._open); - failTestsOnAutoClose(true); -}); - -add_task(function* test_warning_message_on_finalization() { - failTestsOnAutoClose(false); - let c = yield getDummyDatabase("warning_message_on_finalization"); - let identifier = c._connectionData._identifier; - let deferred = Promise.defer(); - - let listener = { - observe: function(msg) { - let messageText = msg.message; - // Make sure the message starts with a warning containing the - // connection identifier - if (messageText.indexOf("Warning: Sqlite connection '" + identifier + "'") !== -1) { - deferred.resolve(); - } - } - }; - Services.console.registerListener(listener); - - Services.obs.notifyObservers(null, "sqlite-finalization-witness", identifier); - // Since we triggered finalization ourselves, tell the witness to - // forget the connection so it does not trigger a finalization again - c._witness.forget(); - - yield deferred.promise; - Services.console.unregisterListener(listener); - failTestsOnAutoClose(true); -}); - -add_task(function* test_error_message_on_unknown_finalization() { - failTestsOnAutoClose(false); - let deferred = Promise.defer(); - - let listener = { - observe: function(msg) { - let messageText = msg.message; - if (messageText.indexOf("Error: Attempt to finalize unknown " + - "Sqlite connection: foo") !== -1) { - deferred.resolve(); - } - } - }; - Services.console.registerListener(listener); - Services.obs.notifyObservers(null, "sqlite-finalization-witness", "foo"); - - yield deferred.promise; - Services.console.unregisterListener(listener); - failTestsOnAutoClose(true); -}); - -add_task(function* test_forget_witness_on_close() { - let c = yield getDummyDatabase("forget_witness_on_close"); - - let forgetCalled = false; - let oldWitness = c._witness; - c._witness = { - forget: function () { - forgetCalled = true; - oldWitness.forget(); - }, - }; - - yield c.close(); - // After close, witness should have forgotten the connection - do_check_true(forgetCalled); -}); - -add_task(function* test_close_database_on_gc() { - failTestsOnAutoClose(false); - let finalPromise; - - { - let collectedPromises = []; - for (let i = 0; i < 100; ++i) { - let deferred = PromiseUtils.defer(); - let c = yield getDummyDatabase("gc_" + i); - c._connectionData._deferredClose.promise.then(deferred.resolve); - collectedPromises.push(deferred.promise); - } - finalPromise = Promise.all(collectedPromises); - } - - // Call getDummyDatabase once more to clear any remaining - // references. This is needed at the moment, otherwise - // garbage-collection takes place after the shutdown barrier and the - // test will timeout. Once that is fixed, we can remove this line - // and be fine as long as the connections are garbage-collected. - let last = yield getDummyDatabase("gc_last"); - yield last.close(); - - Components.utils.forceGC(); - Components.utils.forceCC(); - Components.utils.forceShrinkingGC(); - - yield finalPromise; - failTestsOnAutoClose(true); -}); diff --git a/toolkit/modules/tests/xpcshell/test_sqlite_shutdown.js b/toolkit/modules/tests/xpcshell/test_sqlite_shutdown.js deleted file mode 100644 index b97fd85582..0000000000 --- a/toolkit/modules/tests/xpcshell/test_sqlite_shutdown.js +++ /dev/null @@ -1,122 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -do_get_profile(); - -Cu.import("resource://gre/modules/osfile.jsm"); - // OS.File doesn't like to be first imported during shutdown -Cu.import("resource://gre/modules/Sqlite.jsm"); -Cu.import("resource://gre/modules/Task.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/AsyncShutdown.jsm"); -Cu.import("resource://gre/modules/Promise.jsm"); - -function getConnection(dbName, extraOptions={}) { - let path = dbName + ".sqlite"; - let options = {path: path}; - for (let [k, v] of Object.entries(extraOptions)) { - options[k] = v; - } - - return Sqlite.openConnection(options); -} - -function* getDummyDatabase(name, extraOptions={}) { - const TABLES = { - dirs: "id INTEGER PRIMARY KEY AUTOINCREMENT, path TEXT", - files: "id INTEGER PRIMARY KEY AUTOINCREMENT, dir_id INTEGER, path TEXT", - }; - - let c = yield getConnection(name, extraOptions); - c._initialStatementCount = 0; - - for (let [k, v] of Object.entries(TABLES)) { - yield c.execute("CREATE TABLE " + k + "(" + v + ")"); - c._initialStatementCount++; - } - - return c; -} - -function sleep(ms) { - let deferred = Promise.defer(); - - let timer = Cc["@mozilla.org/timer;1"] - .createInstance(Ci.nsITimer); - - timer.initWithCallback({ - notify: function () { - deferred.resolve(); - }, - }, ms, timer.TYPE_ONE_SHOT); - - return deferred.promise; -} - -function run_test() { - run_next_test(); -} - - -// -// ----------- Don't add a test after this one, as it shuts down Sqlite.jsm -// -add_task(function* test_shutdown_clients() { - do_print("Ensuring that Sqlite.jsm doesn't shutdown before its clients"); - - let assertions = []; - - let sleepStarted = false; - let sleepComplete = false; - Sqlite.shutdown.addBlocker("test_sqlite.js shutdown blocker (sleep)", - Task.async(function*() { - sleepStarted = true; - yield sleep(100); - sleepComplete = true; - })); - assertions.push({name: "sleepStarted", value: () => sleepStarted}); - assertions.push({name: "sleepComplete", value: () => sleepComplete}); - - Sqlite.shutdown.addBlocker("test_sqlite.js shutdown blocker (immediate)", - true); - - let dbOpened = false; - let dbClosed = false; - - Sqlite.shutdown.addBlocker("test_sqlite.js shutdown blocker (open a connection during shutdown)", - Task.async(function*() { - let db = yield getDummyDatabase("opened during shutdown"); - dbOpened = true; - db.close().then( - () => dbClosed = true - ); // Don't wait for this task to complete, Sqlite.jsm must wait automatically - })); - - assertions.push({name: "dbOpened", value: () => dbOpened}); - assertions.push({name: "dbClosed", value: () => dbClosed}); - - do_print("Now shutdown Sqlite.jsm synchronously"); - Services.prefs.setBoolPref("toolkit.asyncshutdown.testing", true); - AsyncShutdown.profileBeforeChange._trigger(); - Services.prefs.clearUserPref("toolkit.asyncshutdown.testing"); - - - for (let {name, value} of assertions) { - do_print("Checking: " + name); - do_check_true(value()); - } - - do_print("Ensure that we cannot open databases anymore"); - let exn; - try { - yield getDummyDatabase("opened after shutdown"); - } catch (ex) { - exn = ex; - } - do_check_true(!!exn); - do_check_true(exn.message.indexOf("Sqlite.jsm has been shutdown") != -1); -}); diff --git a/toolkit/modules/tests/xpcshell/test_task.js b/toolkit/modules/tests/xpcshell/test_task.js deleted file mode 100644 index fdcd565149..0000000000 --- a/toolkit/modules/tests/xpcshell/test_task.js +++ /dev/null @@ -1,642 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * This file tests the Task.jsm module. - */ - -//////////////////////////////////////////////////////////////////////////////// -/// Globals - -var Cc = Components.classes; -var Ci = Components.interfaces; -var Cu = Components.utils; -var Cr = Components.results; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Promise", - "resource://gre/modules/Promise.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Services", - "resource://gre/modules/Services.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Task", - "resource://gre/modules/Task.jsm"); - -/** - * Returns a promise that will be resolved with the given value, when an event - * posted on the event loop of the main thread is processed. - */ -function promiseResolvedLater(aValue) { - let deferred = Promise.defer(); - Services.tm.mainThread.dispatch(() => deferred.resolve(aValue), - Ci.nsIThread.DISPATCH_NORMAL); - return deferred.promise; -} - -//////////////////////////////////////////////////////////////////////////////// -/// Tests - -function run_test() -{ - run_next_test(); -} - -add_test(function test_normal() -{ - Task.spawn(function () { - let result = yield Promise.resolve("Value"); - for (let i = 0; i < 3; i++) { - result += yield promiseResolvedLater("!"); - } - throw new Task.Result("Task result: " + result); - }).then(function (result) { - do_check_eq("Task result: Value!!!", result); - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_exceptions() -{ - Task.spawn(function () { - try { - yield Promise.reject("Rejection result by promise."); - do_throw("Exception expected because the promise was rejected."); - } catch (ex) { - // We catch this exception now, we will throw a different one later. - do_check_eq("Rejection result by promise.", ex); - } - throw new Error("Exception uncaught by task."); - }).then(function (result) { - do_throw("Unexpected success!"); - }, function (ex) { - do_check_eq("Exception uncaught by task.", ex.message); - run_next_test(); - }); -}); - -add_test(function test_recursion() -{ - function task_fibonacci(n) { - throw new Task.Result(n < 2 ? n : (yield task_fibonacci(n - 1)) + - (yield task_fibonacci(n - 2))); - }; - - Task.spawn(task_fibonacci(6)).then(function (result) { - do_check_eq(8, result); - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_spawn_primitive() -{ - function fibonacci(n) { - return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); - }; - - // Polymorphism between task and non-task functions (see "test_recursion"). - Task.spawn(fibonacci(6)).then(function (result) { - do_check_eq(8, result); - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_spawn_function() -{ - Task.spawn(function () { - return "This is not a generator."; - }).then(function (result) { - do_check_eq("This is not a generator.", result); - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_spawn_function_this() -{ - Task.spawn(function () { - return this; - }).then(function (result) { - // Since the task function wasn't defined in strict mode, its "this" object - // should be the same as the "this" object in this function, i.e. the global - // object. - do_check_eq(result, this); - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_spawn_function_this_strict() -{ - "use strict"; - Task.spawn(function () { - return this; - }).then(function (result) { - // Since the task function was defined in strict mode, its "this" object - // should be undefined. - do_check_eq(typeof(result), "undefined"); - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_spawn_function_returning_promise() -{ - Task.spawn(function () { - return promiseResolvedLater("Resolution value."); - }).then(function (result) { - do_check_eq("Resolution value.", result); - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_spawn_function_exceptions() -{ - Task.spawn(function () { - throw new Error("Exception uncaught by task."); - }).then(function (result) { - do_throw("Unexpected success!"); - }, function (ex) { - do_check_eq("Exception uncaught by task.", ex.message); - run_next_test(); - }); -}); - -add_test(function test_spawn_function_taskresult() -{ - Task.spawn(function () { - throw new Task.Result("Task result"); - }).then(function (result) { - do_check_eq("Task result", result); - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_yielded_undefined() -{ - Task.spawn(function () { - yield; - throw new Task.Result("We continued correctly."); - }).then(function (result) { - do_check_eq("We continued correctly.", result); - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_yielded_primitive() -{ - Task.spawn(function () { - throw new Task.Result("Primitive " + (yield "value.")); - }).then(function (result) { - do_check_eq("Primitive value.", result); - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_star_normal() -{ - Task.spawn(function* () { - let result = yield Promise.resolve("Value"); - for (let i = 0; i < 3; i++) { - result += yield promiseResolvedLater("!"); - } - return "Task result: " + result; - }).then(function (result) { - do_check_eq("Task result: Value!!!", result); - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_star_exceptions() -{ - Task.spawn(function* () { - try { - yield Promise.reject("Rejection result by promise."); - do_throw("Exception expected because the promise was rejected."); - } catch (ex) { - // We catch this exception now, we will throw a different one later. - do_check_eq("Rejection result by promise.", ex); - } - throw new Error("Exception uncaught by task."); - }).then(function (result) { - do_throw("Unexpected success!"); - }, function (ex) { - do_check_eq("Exception uncaught by task.", ex.message); - run_next_test(); - }); -}); - -add_test(function test_star_recursion() -{ - function* task_fibonacci(n) { - return n < 2 ? n : (yield task_fibonacci(n - 1)) + - (yield task_fibonacci(n - 2)); - }; - - Task.spawn(task_fibonacci(6)).then(function (result) { - do_check_eq(8, result); - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_mixed_legacy_and_star() -{ - Task.spawn(function* () { - return yield (function() { - throw new Task.Result(yield 5); - })(); - }).then(function (result) { - do_check_eq(5, result); - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_async_function_from_generator() -{ - Task.spawn(function* () { - let object = { - asyncFunction: Task.async(function* (param) { - do_check_eq(this, object); - return param; - }) - }; - - // Ensure the async function returns a promise that resolves as expected. - do_check_eq((yield object.asyncFunction(1)), 1); - - // Ensure a second call to the async function also returns such a promise. - do_check_eq((yield object.asyncFunction(3)), 3); - }).then(function () { - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_async_function_from_function() -{ - Task.spawn(function* () { - return Task.spawn(function* () { - let object = { - asyncFunction: Task.async(function (param) { - do_check_eq(this, object); - return param; - }) - }; - - // Ensure the async function returns a promise that resolves as expected. - do_check_eq((yield object.asyncFunction(5)), 5); - - // Ensure a second call to the async function also returns such a promise. - do_check_eq((yield object.asyncFunction(7)), 7); - }); - }).then(function () { - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_async_function_that_throws_rejects_promise() -{ - Task.spawn(function* () { - let object = { - asyncFunction: Task.async(function* () { - throw "Rejected!"; - }) - }; - - yield object.asyncFunction(); - }).then(function () { - do_throw("unexpected success calling async function that throws error"); - }, function (ex) { - do_check_eq(ex, "Rejected!"); - run_next_test(); - }); -}); - -add_test(function test_async_return_function() -{ - Task.spawn(function* () { - // Ensure an async function that returns a function resolves to the function - // itself instead of calling the function and resolving to its return value. - return Task.spawn(function* () { - let returnValue = function () { - return "These aren't the droids you're looking for."; - }; - - let asyncFunction = Task.async(function () { - return returnValue; - }); - - do_check_eq((yield asyncFunction()), returnValue); - }); - }).then(function () { - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_async_throw_argument_not_function() -{ - Task.spawn(function* () { - // Ensure Task.async throws if its aTask argument is not a function. - Assert.throws(() => Task.async("not a function"), - /aTask argument must be a function/); - }).then(function () { - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - -add_test(function test_async_throw_on_function_in_place_of_promise() -{ - Task.spawn(function* () { - // Ensure Task.spawn throws if passed an async function. - Assert.throws(() => Task.spawn(Task.async(function* () {})), - /Cannot use an async function in place of a promise/); - }).then(function () { - run_next_test(); - }, function (ex) { - do_throw("Unexpected error: " + ex); - }); -}); - - -////////////////// Test rewriting of stack traces - -// Backup Task.Debuggin.maintainStack. -// Will be restored by `exit_stack_tests`. -var maintainStack; -add_test(function enter_stack_tests() { - maintainStack = Task.Debugging.maintainStack; - Task.Debugging.maintainStack = true; - run_next_test(); -}); - - -/** - * Ensure that a list of frames appear in a stack, in the right order - */ -function do_check_rewritten_stack(frames, ex) { - do_print("Checking that the expected frames appear in the right order"); - do_print(frames.join(", ")); - let stack = ex.stack; - do_print(stack); - - let framesFound = 0; - let lineNumber = 0; - let reLine = /([^\r\n])+/g; - let match; - while (framesFound < frames.length && (match = reLine.exec(stack))) { - let line = match[0]; - let frame = frames[framesFound]; - do_print("Searching for " + frame + " in line " + line); - if (line.indexOf(frame) != -1) { - do_print("Found " + frame); - ++framesFound; - } else { - do_print("Didn't find " + frame); - } - } - - if (framesFound >= frames.length) { - return; - } - do_throw("Did not find: " + frames.slice(framesFound).join(", ") + - " in " + stack.substr(reLine.lastIndex)); - - do_print("Ensuring that we have removed Task.jsm, Promise.jsm"); - do_check_true(stack.indexOf("Task.jsm") == -1); - do_check_true(stack.indexOf("Promise.jsm") == -1); - do_check_true(stack.indexOf("Promise-backend.js") == -1); -} - - -// Test that we get an acceptable rewritten stack when we launch -// an error in a Task.spawn. -add_test(function test_spawn_throw_stack() { - Task.spawn(function* task_spawn_throw_stack() { - for (let i = 0; i < 5; ++i) { - yield Promise.resolve(); // Without stack rewrite, this would lose valuable information - } - throw new Error("BOOM"); - }).then(do_throw, function(ex) { - do_check_rewritten_stack(["task_spawn_throw_stack", - "test_spawn_throw_stack"], - ex); - run_next_test(); - }); -}); - -// Test that we get an acceptable rewritten stack when we yield -// a rejection in a Task.spawn. -add_test(function test_spawn_yield_reject_stack() { - Task.spawn(function* task_spawn_yield_reject_stack() { - for (let i = 0; i < 5; ++i) { - yield Promise.resolve(); // Without stack rewrite, this would lose valuable information - } - yield Promise.reject(new Error("BOOM")); - }).then(do_throw, function(ex) { - do_check_rewritten_stack(["task_spawn_yield_reject_stack", - "test_spawn_yield_reject_stack"], - ex); - run_next_test(); - }); -}); - -// Test that we get an acceptable rewritten stack when we launch -// an error in a Task.async function. -add_test(function test_async_function_throw_stack() { - let task_async_function_throw_stack = Task.async(function*() { - for (let i = 0; i < 5; ++i) { - yield Promise.resolve(); // Without stack rewrite, this would lose valuable information - } - throw new Error("BOOM"); - })().then(do_throw, function(ex) { - do_check_rewritten_stack(["task_async_function_throw_stack", - "test_async_function_throw_stack"], - ex); - run_next_test(); - }); -}); - -// Test that we get an acceptable rewritten stack when we launch -// an error in a Task.async function. -add_test(function test_async_function_yield_reject_stack() { - let task_async_function_yield_reject_stack = Task.async(function*() { - for (let i = 0; i < 5; ++i) { - yield Promise.resolve(); // Without stack rewrite, this would lose valuable information - } - yield Promise.reject(new Error("BOOM")); - })().then(do_throw, function(ex) { - do_check_rewritten_stack(["task_async_function_yield_reject_stack", - "test_async_function_yield_reject_stack"], - ex); - run_next_test(); - }); -}); - -// Test that we get an acceptable rewritten stack when we launch -// an error in a Task.async function. -add_test(function test_async_method_throw_stack() { - let object = { - task_async_method_throw_stack: Task.async(function*() { - for (let i = 0; i < 5; ++i) { - yield Promise.resolve(); // Without stack rewrite, this would lose valuable information - } - throw new Error("BOOM"); - }) - }; - object.task_async_method_throw_stack().then(do_throw, function(ex) { - do_check_rewritten_stack(["task_async_method_throw_stack", - "test_async_method_throw_stack"], - ex); - run_next_test(); - }); -}); - -// Test that we get an acceptable rewritten stack when we launch -// an error in a Task.async function. -add_test(function test_async_method_yield_reject_stack() { - let object = { - task_async_method_yield_reject_stack: Task.async(function*() { - for (let i = 0; i < 5; ++i) { - yield Promise.resolve(); // Without stack rewrite, this would lose valuable information - } - yield Promise.reject(new Error("BOOM")); - }) - }; - object.task_async_method_yield_reject_stack().then(do_throw, function(ex) { - do_check_rewritten_stack(["task_async_method_yield_reject_stack", - "test_async_method_yield_reject_stack"], - ex); - run_next_test(); - }); -}); - -// Test that two tasks whose execution takes place interleaved do not capture each other's stack. -add_test(function test_throw_stack_do_not_capture_the_wrong_task() { - for (let iter_a of [3, 4, 5]) { // Vary the interleaving - for (let iter_b of [3, 4, 5]) { - Task.spawn(function* task_a() { - for (let i = 0; i < iter_a; ++i) { - yield Promise.resolve(); - } - throw new Error("BOOM"); - }).then(do_throw, function(ex) { - do_check_rewritten_stack(["task_a", - "test_throw_stack_do_not_capture_the_wrong_task"], - ex); - do_check_true(!ex.stack.includes("task_b")); - run_next_test(); - }); - Task.spawn(function* task_b() { - for (let i = 0; i < iter_b; ++i) { - yield Promise.resolve(); - } - }); - } - } -}); - -// Put things together -add_test(function test_throw_complex_stack() -{ - // Setup the following stack: - // inner_method() - // task_3() - // task_2() - // task_1() - // function_3() - // function_2() - // function_1() - // test_throw_complex_stack() - (function function_1() { - return (function function_2() { - return (function function_3() { - return Task.spawn(function* task_1() { - yield Promise.resolve(); - try { - yield Task.spawn(function* task_2() { - yield Promise.resolve(); - yield Task.spawn(function* task_3() { - yield Promise.resolve(); - let inner_object = { - inner_method: Task.async(function*() { - throw new Error("BOOM"); - }) - }; - yield Promise.resolve(); - yield inner_object.inner_method(); - }); - }); - } catch (ex) { - yield Promise.resolve(); - throw ex; - } - }); - })(); - })(); - })().then( - () => do_throw("Shouldn't have succeeded"), - (ex) => { - let expect = ["inner_method", - "task_3", - "task_2", - "task_1", - "function_3", - "function_2", - "function_1", - "test_throw_complex_stack"]; - do_check_rewritten_stack(expect, ex); - - run_next_test(); - }); -}); - -add_test(function test_without_maintainStack() { - do_print("Calling generateReadableStack without a Task"); - Task.Debugging.generateReadableStack(new Error("Not a real error")); - - Task.Debugging.maintainStack = false; - - do_print("Calling generateReadableStack with neither a Task nor maintainStack"); - Task.Debugging.generateReadableStack(new Error("Not a real error")); - - do_print("Calling generateReadableStack without maintainStack"); - Task.spawn(function*() { - Task.Debugging.generateReadableStack(new Error("Not a real error")); - run_next_test(); - }); -}); - -add_test(function exit_stack_tests() { - Task.Debugging.maintainStack = maintainStack; - run_next_test(); -}); - diff --git a/toolkit/modules/tests/xpcshell/test_timer.js b/toolkit/modules/tests/xpcshell/test_timer.js deleted file mode 100644 index 57e3006637..0000000000 --- a/toolkit/modules/tests/xpcshell/test_timer.js +++ /dev/null @@ -1,57 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -// Tests exports from Timer.jsm - -var imported = {}; -Components.utils.import("resource://gre/modules/Timer.jsm", imported); - -function run_test() { - run_next_test(); -} - -add_task(function* test_setTimeout() { - let timeout1 = imported.setTimeout(() => do_throw("Should not be called"), 100); - do_check_eq(typeof timeout1, "number", "setTimeout returns a number"); - do_check_true(timeout1 > 0, "setTimeout returns a positive number"); - - imported.clearTimeout(timeout1); - - yield new Promise((resolve) => { - let timeout2 = imported.setTimeout((param1, param2) => { - do_check_true(true, "Should be called"); - do_check_eq(param1, 5, "first parameter is correct"); - do_check_eq(param2, "test", "second parameter is correct"); - resolve(); - }, 100, 5, "test"); - - do_check_eq(typeof timeout2, "number", "setTimeout returns a number"); - do_check_true(timeout2 > 0, "setTimeout returns a positive number"); - do_check_neq(timeout1, timeout2, "Calling setTimeout again returns a different value"); - }); -}); - -add_task(function* test_setInterval() { - let interval1 = imported.setInterval(() => do_throw("Should not be called!"), 100); - do_check_eq(typeof interval1, "number", "setInterval returns a number"); - do_check_true(interval1 > 0, "setTimeout returns a positive number"); - - imported.clearInterval(interval1); - - const EXPECTED_CALLS = 5; - let calls = 0; - - yield new Promise((resolve) => { - let interval2 = imported.setInterval((param1, param2) => { - do_check_true(true, "Should be called"); - do_check_eq(param1, 15, "first parameter is correct"); - do_check_eq(param2, "hola", "second parameter is correct"); - if (calls >= EXPECTED_CALLS) { - resolve(); - } - calls++; - }, 100, 15, "hola"); - }); -}); diff --git a/toolkit/modules/tests/xpcshell/test_web_channel.js b/toolkit/modules/tests/xpcshell/test_web_channel.js deleted file mode 100644 index 05f1bc03df..0000000000 --- a/toolkit/modules/tests/xpcshell/test_web_channel.js +++ /dev/null @@ -1,149 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var Cu = Components.utils; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/WebChannel.jsm"); - -const ERROR_ID_ORIGIN_REQUIRED = "WebChannel id and originOrPermission are required."; -const VALID_WEB_CHANNEL_ID = "id"; -const URL_STRING = "http://example.com"; -const VALID_WEB_CHANNEL_ORIGIN = Services.io.newURI(URL_STRING, null, null); -const TEST_PERMISSION_NAME = "test-webchannel-permissions"; - -var MockWebChannelBroker = { - _channelMap: new Map(), - registerChannel: function(channel) { - if (!this._channelMap.has(channel)) { - this._channelMap.set(channel); - } - }, - unregisterChannel: function (channelToRemove) { - this._channelMap.delete(channelToRemove) - } -}; - -function run_test() { - run_next_test(); -} - -/** - * Web channel tests - */ - -/** - * Test channel listening with originOrPermission being an nsIURI. - */ -add_task(function test_web_channel_listen() { - return new Promise((resolve, reject) => { - let channel = new WebChannel(VALID_WEB_CHANNEL_ID, VALID_WEB_CHANNEL_ORIGIN, { - broker: MockWebChannelBroker - }); - let delivered = 0; - do_check_eq(channel.id, VALID_WEB_CHANNEL_ID); - do_check_eq(channel._originOrPermission.spec, VALID_WEB_CHANNEL_ORIGIN.spec); - do_check_eq(channel._deliverCallback, null); - - channel.listen(function(id, message, target) { - do_check_eq(id, VALID_WEB_CHANNEL_ID); - do_check_true(message); - do_check_true(message.command); - do_check_true(target.sender); - delivered++; - // 2 messages should be delivered - if (delivered === 2) { - channel.stopListening(); - do_check_eq(channel._deliverCallback, null); - resolve(); - } - }); - - // send two messages - channel.deliver({ - id: VALID_WEB_CHANNEL_ID, - message: { - command: "one" - } - }, { sender: true }); - - channel.deliver({ - id: VALID_WEB_CHANNEL_ID, - message: { - command: "two" - } - }, { sender: true }); - }); -}); - -/** - * Test channel listening with originOrPermission being a permission string. - */ -add_task(function test_web_channel_listen_permission() { - return new Promise((resolve, reject) => { - // add a new permission - Services.perms.add(VALID_WEB_CHANNEL_ORIGIN, TEST_PERMISSION_NAME, Services.perms.ALLOW_ACTION); - do_register_cleanup(() => Services.perms.remove(VALID_WEB_CHANNEL_ORIGIN, TEST_PERMISSION_NAME)); - let channel = new WebChannel(VALID_WEB_CHANNEL_ID, TEST_PERMISSION_NAME, { - broker: MockWebChannelBroker - }); - let delivered = 0; - do_check_eq(channel.id, VALID_WEB_CHANNEL_ID); - do_check_eq(channel._originOrPermission, TEST_PERMISSION_NAME); - do_check_eq(channel._deliverCallback, null); - - channel.listen(function(id, message, target) { - do_check_eq(id, VALID_WEB_CHANNEL_ID); - do_check_true(message); - do_check_true(message.command); - do_check_true(target.sender); - delivered++; - // 2 messages should be delivered - if (delivered === 2) { - channel.stopListening(); - do_check_eq(channel._deliverCallback, null); - resolve(); - } - }); - - // send two messages - channel.deliver({ - id: VALID_WEB_CHANNEL_ID, - message: { - command: "one" - } - }, { sender: true }); - - channel.deliver({ - id: VALID_WEB_CHANNEL_ID, - message: { - command: "two" - } - }, { sender: true }); - }); -}); - - -/** - * Test constructor - */ -add_test(function test_web_channel_constructor() { - do_check_eq(constructorTester(), ERROR_ID_ORIGIN_REQUIRED); - do_check_eq(constructorTester(undefined), ERROR_ID_ORIGIN_REQUIRED); - do_check_eq(constructorTester(undefined, VALID_WEB_CHANNEL_ORIGIN), ERROR_ID_ORIGIN_REQUIRED); - do_check_eq(constructorTester(VALID_WEB_CHANNEL_ID, undefined), ERROR_ID_ORIGIN_REQUIRED); - do_check_false(constructorTester(VALID_WEB_CHANNEL_ID, VALID_WEB_CHANNEL_ORIGIN)); - - run_next_test(); -}); - -function constructorTester(id, origin) { - try { - new WebChannel(id, origin); - } catch (e) { - return e.message; - } - return false; -} diff --git a/toolkit/modules/tests/xpcshell/test_web_channel_broker.js b/toolkit/modules/tests/xpcshell/test_web_channel_broker.js deleted file mode 100644 index 132597c207..0000000000 --- a/toolkit/modules/tests/xpcshell/test_web_channel_broker.js +++ /dev/null @@ -1,88 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var Cu = Components.utils; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/WebChannel.jsm"); - -const VALID_WEB_CHANNEL_ID = "id"; -const URL_STRING = "http://example.com"; -const VALID_WEB_CHANNEL_ORIGIN = Services.io.newURI(URL_STRING, null, null); - -function run_test() { - run_next_test(); -} - -/** - * Test WebChannelBroker channel map - */ -add_test(function test_web_channel_broker_channel_map() { - let channel = {}; - let channel2 = {}; - - do_check_eq(WebChannelBroker._channelMap.size, 0); - do_check_false(WebChannelBroker._messageListenerAttached); - - // make sure _channelMap works correctly - WebChannelBroker.registerChannel(channel); - do_check_eq(WebChannelBroker._channelMap.size, 1); - do_check_true(WebChannelBroker._messageListenerAttached); - - WebChannelBroker.registerChannel(channel2); - do_check_eq(WebChannelBroker._channelMap.size, 2); - - WebChannelBroker.unregisterChannel(channel); - do_check_eq(WebChannelBroker._channelMap.size, 1); - - // make sure the correct channel is unregistered - do_check_false(WebChannelBroker._channelMap.has(channel)); - do_check_true(WebChannelBroker._channelMap.has(channel2)); - - WebChannelBroker.unregisterChannel(channel2); - do_check_eq(WebChannelBroker._channelMap.size, 0); - - run_next_test(); -}); - - -/** - * Test WebChannelBroker _listener test - */ -add_task(function test_web_channel_broker_listener() { - return new Promise((resolve, reject) => { - var channel = { - id: VALID_WEB_CHANNEL_ID, - _originCheckCallback: requestPrincipal => { - return VALID_WEB_CHANNEL_ORIGIN.prePath === requestPrincipal.origin; - }, - deliver: function(data, sender) { - do_check_eq(data.id, VALID_WEB_CHANNEL_ID); - do_check_eq(data.message.command, "hello"); - do_check_neq(sender, undefined); - WebChannelBroker.unregisterChannel(channel); - resolve(); - } - }; - - WebChannelBroker.registerChannel(channel); - - var mockEvent = { - data: { - id: VALID_WEB_CHANNEL_ID, - message: { - command: "hello" - } - }, - principal: { - origin: URL_STRING - }, - objects: { - }, - }; - - WebChannelBroker._listener(mockEvent); - }); -}); diff --git a/toolkit/modules/tests/xpcshell/xpcshell.ini b/toolkit/modules/tests/xpcshell/xpcshell.ini deleted file mode 100644 index 65d7c45e98..0000000000 --- a/toolkit/modules/tests/xpcshell/xpcshell.ini +++ /dev/null @@ -1,75 +0,0 @@ -[DEFAULT] -head = -tail = -support-files = - propertyLists/bug710259_propertyListBinary.plist - propertyLists/bug710259_propertyListXML.plist - chromeappsstore.sqlite - zips/zen.zip - -[test_BinarySearch.js] -skip-if = toolkit == 'android' -[test_CanonicalJSON.js] -[test_client_id.js] -skip-if = toolkit == 'android' -[test_Color.js] -[test_DeferredTask.js] -skip-if = toolkit == 'android' -[test_FileUtils.js] -skip-if = toolkit == 'android' -[test_FinderIterator.js] -[test_GMPInstallManager.js] -skip-if = toolkit == 'android' -[test_Http.js] -skip-if = toolkit == 'android' -[test_Integration.js] -[test_jsesc.js] -skip-if = toolkit == 'android' -[test_JSONFile.js] -skip-if = toolkit == 'android' -[test_Log.js] -skip-if = toolkit == 'android' -[test_MatchPattern.js] -skip-if = toolkit == 'android' -[test_MatchGlobs.js] -skip-if = toolkit == 'android' -[test_MatchURLFilters.js] -skip-if = toolkit == 'android' -[test_NewTabUtils.js] -skip-if = toolkit == 'android' -[test_ObjectUtils.js] -skip-if = toolkit == 'android' -[test_ObjectUtils_strict.js] -skip-if = toolkit == 'android' -[test_PermissionsUtils.js] -skip-if = toolkit == 'android' -[test_Preferences.js] -skip-if = toolkit == 'android' -[test_Promise.js] -skip-if = toolkit == 'android' -[test_PromiseUtils.js] -skip-if = toolkit == 'android' -[test_propertyListsUtils.js] -skip-if = toolkit == 'android' -[test_readCertPrefs.js] -skip-if = toolkit == 'android' -[test_Services.js] -skip-if = toolkit == 'android' -[test_session_recorder.js] -skip-if = toolkit == 'android' -[test_sqlite.js] -skip-if = toolkit == 'android' -[test_sqlite_shutdown.js] -skip-if = toolkit == 'android' -[test_task.js] -skip-if = toolkit == 'android' -[test_timer.js] -skip-if = toolkit == 'android' -[test_UpdateUtils_url.js] -[test_UpdateUtils_updatechannel.js] -[test_web_channel.js] -[test_web_channel_broker.js] -[test_ZipUtils.js] -skip-if = toolkit == 'android' -[test_Log_stackTrace.js] -[test_servicerequest_xhr.js] diff --git a/toolkit/modules/tests/xpcshell/zips/zen.zip b/toolkit/modules/tests/xpcshell/zips/zen.zip Binary files differdeleted file mode 100644 index 4756247936..0000000000 --- a/toolkit/modules/tests/xpcshell/zips/zen.zip +++ /dev/null |