diff options
Diffstat (limited to 'toolkit/modules/tests/xpcshell')
45 files changed, 0 insertions, 9480 deletions
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 |