From 4e9e1c3a66c586813007dd604153ffaccd06c1e4 Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Mon, 26 Aug 2013 08:17:58 -0700 Subject: [PATCH] Bug 909341 - Uplift Addon SDK to Firefox. r=me --- addon-sdk/source/lib/sdk/addon/runner.js | 15 +-- addon-sdk/source/lib/sdk/test/runner.js | 5 +- addon-sdk/source/lib/toolkit/loader.js | 37 ++++-- addon-sdk/source/test/test-deprecated-list.js | 114 +++++++++--------- addon-sdk/source/test/test-globals.js | 27 +++-- addon-sdk/source/test/test-list.js | 28 +++-- addon-sdk/source/test/test-tmp-file.js | 15 ++- 7 files changed, 127 insertions(+), 114 deletions(-) diff --git a/addon-sdk/source/lib/sdk/addon/runner.js b/addon-sdk/source/lib/sdk/addon/runner.js index 53b316006cbc..c70c7edaa35e 100644 --- a/addon-sdk/source/lib/sdk/addon/runner.js +++ b/addon-sdk/source/lib/sdk/addon/runner.js @@ -13,7 +13,6 @@ const { exit, env, staticArgs } = require('../system'); const { when: unload } = require('../system/unload'); const { loadReason } = require('../self'); const { rootURI } = require("@loader/options"); -const cfxArgs = require("@test/options"); const globals = require('../system/globals'); const xulApp = require('../system/xul-app'); const appShellService = Cc['@mozilla.org/appshell/appShellService;1']. @@ -102,11 +101,7 @@ function startup(reason, options) { // Run the addon even in case of error (best effort approach) require('../l10n/loader'). load(rootURI). - then(function l10nSuccess() { - if (cfxArgs.parseable) { - console.info("localization information has loaded successfully."); - } - }, function l10nFailure(error) { + then(null, function failure(error) { console.info("Error while loading localization: " + error.message); }). then(function onLocalizationReady(data) { @@ -115,10 +110,6 @@ function startup(reason, options) { definePseudo(options.loader, '@l10n/data', data ? data : null); return ready; }).then(function() { - if (cfxArgs.parseable) { - console.info("addon window has loaded successfully."); - } - run(options); }).then(null, console.exception); } @@ -137,7 +128,6 @@ function run(options) { catch(error) { console.exception(error); } - // Initialize inline options localization, without preventing addon to be // run in case of error try { @@ -167,8 +157,7 @@ function run(options) { quit: exit }); } - } - catch (error) { + } catch (error) { console.exception(error); throw error; } diff --git a/addon-sdk/source/lib/sdk/test/runner.js b/addon-sdk/source/lib/sdk/test/runner.js index 8e449fcbde39..4e6779524b45 100644 --- a/addon-sdk/source/lib/sdk/test/runner.js +++ b/addon-sdk/source/lib/sdk/test/runner.js @@ -1,17 +1,14 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - "use strict"; module.metadata = { "stability": "experimental" }; -var obsvc = require("../deprecated/observer-service"); var { exit, stdout } = require("../system"); var cfxArgs = require("@test/options"); -var { Cc, Ci} = require("chrome"); function runTests(findAndRunTests) { var harness = require("./harness"); @@ -62,7 +59,7 @@ function printFailedTests(tests, print) { iterationNumber++; if (!singleIteration) - print(" Iteration " + iterationNumber + ":\n"); + print(" Iteration " + iterationNumber + ":\n"); for each (let test in testRun) { if (test.failed > 0) { diff --git a/addon-sdk/source/lib/toolkit/loader.js b/addon-sdk/source/lib/toolkit/loader.js index 1853457dccb4..40bee373cb0e 100644 --- a/addon-sdk/source/lib/toolkit/loader.js +++ b/addon-sdk/source/lib/toolkit/loader.js @@ -48,6 +48,20 @@ const prototypeOf = Object.getPrototypeOf; const create = Object.create; const keys = Object.keys; + +const COMPONENT_ERROR = '`Components` is not available in this context.\n' + + 'Functionality provided by Components may be available in an SDK\n' + + 'module: https://jetpack.mozillalabs.com/sdk/latest/docs/ \n\n' + + 'However, if you still need to import Components, you may use the\n' + + '`chrome` module\'s properties for shortcuts to Component properties:\n\n' + + 'Shortcuts: \n' + + ' Cc = Components' + '.classes \n' + + ' Ci = Components' + '.interfaces \n' + + ' Cu = Components' + '.utils \n' + + ' CC = Components' + '.Constructor \n' + + 'Example: \n' + + ' let { Cc, Ci } = require(\'chrome\');\n'; + // Workaround for bug 674195. Freezing objects from other compartments fail, // so we use `Object.freeze` from the same component instead. function freeze(object) { @@ -216,19 +230,26 @@ const load = iced(function load(loader, module) { let { sandboxes, globals } = loader; let require = Require(loader, module); + // We expose set of properties defined by `CommonJS` specification via + // prototype of the sandbox. Also globals are deeper in the prototype + // chain so that each module has access to them as well. + let descriptors = descriptor({ + require: require, + module: module, + exports: module.exports, + get Components() { + // Expose `Components` property to throw error on usage with + // additional information + throw new ReferenceError(COMPONENT_ERROR); + } + }); + let sandbox = sandboxes[module.uri] = Sandbox({ name: module.uri, // Get an existing module sandbox, if any, so we can reuse its compartment // when creating the new one to reduce memory consumption. sandbox: sandboxes[keys(sandboxes).shift()], - // We expose set of properties defined by `CommonJS` specification via - // prototype of the sandbox. Also globals are deeper in the prototype - // chain so that each module has access to them as well. - prototype: create(globals, descriptor({ - require: require, - module: module, - exports: module.exports - })), + prototype: create(globals, descriptors), wantXrays: false }); diff --git a/addon-sdk/source/test/test-deprecated-list.js b/addon-sdk/source/test/test-deprecated-list.js index 81c473e32f77..beae09f6c8a3 100644 --- a/addon-sdk/source/test/test-deprecated-list.js +++ b/addon-sdk/source/test/test-deprecated-list.js @@ -1,26 +1,24 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +'use strict'; -"use strict"; +const { List } = require('sdk/deprecated/list'); -function assertList(test, array, list) { - for (let i = 0, ii = array.length; i < ii; i < ii, i++) { - test.assertEqual( +function assertList(assert, array, list) { + for (let i = 0, l = array.length; i < l; i++) { + assert.equal( array.length, list.length, 'list must contain same amount of elements as array' ); - test.assertEqual( + assert.equal( 'List(' + array + ')', list + '', 'toString must output array like result' ); - test.assert( - i in list, - 'must contain element with index: ' + i - ); - test.assertEqual( + assert.ok(i in list, 'must contain element with index: ' + i); + assert.equal( array[i], list[i], 'element with index: ' + i + ' should match' @@ -28,89 +26,83 @@ function assertList(test, array, list) { } } -const { List } = require('sdk/deprecated/list'); - -exports['test:test for'] = function(test) { +exports['test:test for'] = function(assert) { let fixture = List(3, 2, 1); - test.assertEqual(3, fixture.length, 'length is 3'); + assert.equal(3, fixture.length, 'length is 3'); let i = 0; for (let key in fixture) { - test.assertEqual(i++, key, 'key should match'); + assert.equal(i++, key, 'key should match'); } }; -exports['test:test for each'] = function(test) { +exports['test:test for each'] = function(assert) { let fixture = new List(3, 2, 1); - test.assertEqual(3, fixture.length, 'length is 3'); - let i = 3; - for each (let value in fixture) { - test.assertEqual(i--, value, 'value should match'); - } -}; - -exports['test:test for of'] = function(test) { - let fixture = new List(3, 2, 1); - - test.assertEqual(3, fixture.length, 'length is 3'); + assert.equal(3, fixture.length, 'length is 3'); let i = 3; for (let value of fixture) { - test.assertEqual(i--, value, 'value should match'); + assert.equal(i--, value, 'value should match'); } }; -exports['test:test toString'] = function(test) { +exports['test:test for of'] = function(assert) { + let fixture = new List(3, 2, 1); + + assert.equal(3, fixture.length, 'length is 3'); + let i = 3; + for (let value of fixture) { + assert.equal(i--, value, 'value should match'); + } +}; + +exports['test:test toString'] = function(assert) { let fixture = List(3, 2, 1); - test.assertEqual( + assert.equal( 'List(3,2,1)', fixture + '', 'toString must output array like result' ) }; -exports['test:test constructor with apply'] = function(test) { +exports['test:test constructor with apply'] = function(assert) { let array = ['a', 'b', 'c']; let fixture = List.apply(null, array); - test.assertEqual( + assert.equal( 3, fixture.length, 'should have applied arguments' ); }; -exports['test:direct element access'] = function(test) { - let array = [1, 'foo', 2, 'bar', {}, 'bar', function a() {}, test, 1]; +exports['test:direct element access'] = function(assert) { + let array = [1, 'foo', 2, 'bar', {}, 'bar', function a() {}, assert, 1]; let fixture = List.apply(null, array); array.splice(5, 1); array.splice(7, 1); - test.assertEqual( + assert.equal( array.length, fixture.length, 'list should omit duplicate elements' ); - test.assertEqual( + assert.equal( 'List(' + array + ')', fixture.toString(), 'elements should not be rearranged' ); for (let key in array) { - test.assert(key in fixture,'should contain key for index:' + key); - test.assertEqual( - array[key], - fixture[key], - 'values should match for: ' + key - ); + assert.ok(key in fixture,'should contain key for index:' + key); + assert.equal(array[key], fixture[key], 'values should match for: ' + key); } }; -exports['test:removing adding elements'] = function(test) { - let array = [1, 'foo', 2, 'bar', {}, 'bar', function a() {}, test, 1]; +exports['test:removing adding elements'] = function(assert) { + let array = [1, 'foo', 2, 'bar', {}, 'bar', function a() {}, assert, 1]; let fixture = List.compose({ add: function() this._add.apply(this, arguments), remove: function() this._remove.apply(this, arguments), @@ -119,11 +111,11 @@ exports['test:removing adding elements'] = function(test) { array.splice(5, 1); array.splice(7, 1); - assertList(test, array, fixture); + assertList(assert, array, fixture); array.splice(array.indexOf(2), 1); fixture.remove(2); - assertList(test, array, fixture); + assertList(assert, array, fixture); array.splice(array.indexOf('foo'), 1); fixture.remove('foo'); @@ -131,11 +123,11 @@ exports['test:removing adding elements'] = function(test) { fixture.remove(1); array.push('foo'); fixture.add('foo'); - assertList(test, array, fixture); + assertList(assert, array, fixture); array.splice(0); fixture.clear(0); - assertList(test, array, fixture); + assertList(assert, array, fixture); array.push(1, 'foo', 2, 'bar', 3); fixture.add(1); @@ -144,26 +136,26 @@ exports['test:removing adding elements'] = function(test) { fixture.add('bar'); fixture.add(3); - assertList(test, array, fixture); + assertList(assert, array, fixture); }; -exports['test: remove does not leave invalid numerical properties'] = function(test) { +exports['test: remove does not leave invalid numerical properties'] = function(assert) { let fixture = List.compose({ remove: function() this._remove.apply(this, arguments), }).apply(null, [1, 2, 3]); fixture.remove(1); - test.assertEqual(fixture[fixture.length], undefined); + assert.equal(fixture[fixture.length], undefined); } -exports['test:add list item from Iterator'] = function(test) { +exports['test:add list item from Iterator'] = function(assert) { let array = [1, 2, 3, 4], sum = 0, added = false; let fixture = List.compose({ add: function() this._add.apply(this, arguments), }).apply(null, array); - for each (let item in fixture) { + for (let item of fixture) { sum += item; if (!added) { @@ -172,35 +164,37 @@ exports['test:add list item from Iterator'] = function(test) { } } - test.assertEqual(sum, 1 + 2 + 3 + 4); + assert.equal(sum, 1 + 2 + 3 + 4, 'sum = 1 + 2 + 3 + 4'); }; -exports['test:remove list item from Iterator'] = function(test) { +exports['test:remove list item from Iterator'] = function(assert) { let array = [1, 2, 3, 4], sum = 0; let fixture = List.compose({ remove: function() this._remove.apply(this, arguments), }).apply(null, array); - for each (let item in fixture) { + for (let item of fixture) { sum += item; fixture.remove(item); } - test.assertEqual(sum, 1 + 2 + 3 + 4); + assert.equal(sum, 1 + 2 + 3 + 4, 'sum = 1 + 2 + 3 + 4'); }; -exports['test:clear list from Iterator'] = function(test) { +exports['test:clear list from Iterator'] = function(assert) { let array = [1, 2, 3, 4], sum = 0; let fixture = List.compose({ clear: function() this._clear() }).apply(null, array); - for each (let item in fixture) { + for (let item of fixture) { sum += item; fixture.clear(); } - test.assertEqual(sum, 1 + 2 + 3 + 4); + assert.equal(sum, 1 + 2 + 3 + 4, 'sum = 1 + 2 + 3 + 4'); }; + +require('sdk/test').run(exports); diff --git a/addon-sdk/source/test/test-globals.js b/addon-sdk/source/test/test-globals.js index 1396b2d5a2fc..ba38ed7fb7c6 100644 --- a/addon-sdk/source/test/test-globals.js +++ b/addon-sdk/source/test/test-globals.js @@ -7,17 +7,24 @@ Object.defineProperty(this, 'global', { value: this }); exports.testGlobals = function(assert) { // the only globals in module scope should be: - assert.equal(typeof module, 'object', 'have "module" global'); - assert.equal(typeof exports, 'object', 'have "exports" global'); - assert.equal(typeof require, 'function', 'have "require" global'); - assert.equal(typeof dump, 'function', 'have "dump" global'); - assert.equal(typeof console, 'object', 'have "console" global'); + // module, exports, require, dump, console + assert.equal(typeof module, 'object', 'have "module", good'); + assert.equal(typeof exports, 'object', 'have "exports", good'); + assert.equal(typeof require, 'function', 'have "require", good'); + assert.equal(typeof dump, 'function', 'have "dump", good'); + assert.equal(typeof console, 'object', 'have "console", good'); // in particular, these old globals should no longer be present - assert.ok(!('packaging' in global), 'no "packaging" global was found'); - assert.ok(!('memory' in global), 'no "memory" global was found'); - - assert.ok(/test-globals\.js$/.test(module.uri), 'should contain filename'); + assert.ok(!('packaging' in global), "no 'packaging', good"); + assert.ok(!('memory' in global), "no 'memory', good"); + assert.ok(/test-globals\.js$/.test(module.uri), + 'should contain filename'); }; -require("test").run(exports); +exports.testComponent = function (assert) { + assert.throws(() => { + Components; + }, /`Components` is not available/, 'using `Components` throws'); +}; + +require('test').run(exports); diff --git a/addon-sdk/source/test/test-list.js b/addon-sdk/source/test/test-list.js index 88e67507939b..10be4bee77e2 100644 --- a/addon-sdk/source/test/test-list.js +++ b/addon-sdk/source/test/test-list.js @@ -6,32 +6,32 @@ const { List, addListItem, removeListItem } = require('sdk/util/list'); const { Class } = require('sdk/core/heritage'); -exports.testList = function(test) { +exports.testList = function(assert) { let list = List(); addListItem(list, 1); for (let key in list) { - test.assertEqual(key, 0, 'key is correct'); - test.assertEqual(list[key], 1, 'value is correct'); + assert.equal(key, 0, 'key is correct'); + assert.equal(list[key], 1, 'value is correct'); } let count = 0; for each (let ele in list) { - test.assertEqual(ele, 1, 'ele is correct'); - test.assertEqual(++count, 1, 'count is correct'); + assert.equal(ele, 1, 'ele is correct'); + assert.equal(++count, 1, 'count is correct'); } count = 0; for (let ele of list) { - test.assertEqual(ele, 1, 'ele is correct'); - test.assertEqual(++count, 1, 'count is correct'); + assert.equal(ele, 1, 'ele is correct'); + assert.equal(++count, 1, 'count is correct'); } removeListItem(list, 1); - test.assertEqual(list.length, 0, 'remove worked'); + assert.equal(list.length, 0, 'remove worked'); }; -exports.testImplementsList = function(test) { +exports.testImplementsList = function(assert) { let List2 = Class({ implements: [List], initialize: function() { @@ -42,15 +42,17 @@ exports.testImplementsList = function(test) { let count = 0; for each (let ele in list2) { - test.assertEqual(ele, count++, 'ele is correct'); + assert.equal(ele, count++, 'ele is correct'); } count = 0; for (let ele of list2) { - test.assertEqual(ele, count++, 'ele is correct'); + assert.equal(ele, count++, 'ele is correct'); } addListItem(list2, 3); - test.assertEqual(list2.length, 4, '3 was added'); - test.assertEqual(list2[list2.length-1], 3, '3 was added'); + assert.equal(list2.length, 4, '3 was added'); + assert.equal(list2[list2.length-1], 3, '3 was added'); } + +require('sdk/test').run(exports); diff --git a/addon-sdk/source/test/test-tmp-file.js b/addon-sdk/source/test/test-tmp-file.js index 187f9e7e82d2..de171c16ba7a 100644 --- a/addon-sdk/source/test/test-tmp-file.js +++ b/addon-sdk/source/test/test-tmp-file.js @@ -1,24 +1,27 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; const tmp = require("sdk/test/tmp-file"); const file = require("sdk/io/file"); const testFolderURL = module.uri.split('test-tmp-file.js')[0]; -exports.testCreateFromString = function (test) { +exports.testCreateFromString = function (assert) { let expectedContent = "foo"; let path = tmp.createFromString(expectedContent); let content = file.read(path); - test.assertEqual(content, expectedContent, - "Temporary file contains the expected content"); + assert.equal(content, expectedContent, + "Temporary file contains the expected content"); } -exports.testCreateFromURL = function (test) { +exports.testCreateFromURL = function (assert) { let url = testFolderURL + "test-tmp-file.txt"; let path = tmp.createFromURL(url); let content = file.read(path); - test.assertEqual(content, "foo", - "Temporary file contains the expected content"); + assert.equal(content, "foo", + "Temporary file contains the expected content"); } + +require("sdk/test").run(exports);