Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | 'use strict'; |
michael@0 | 6 | |
michael@0 | 7 | let { |
michael@0 | 8 | Loader, main, unload, parseStack, generateMap, resolve, nodeResolve |
michael@0 | 9 | } = require('toolkit/loader'); |
michael@0 | 10 | let { readURI } = require('sdk/net/url'); |
michael@0 | 11 | let { all } = require('sdk/core/promise'); |
michael@0 | 12 | let testOptions = require('@test/options'); |
michael@0 | 13 | |
michael@0 | 14 | let root = module.uri.substr(0, module.uri.lastIndexOf('/')) |
michael@0 | 15 | // The following adds Debugger constructor to the global namespace. |
michael@0 | 16 | const { Cu } = require('chrome'); |
michael@0 | 17 | const { addDebuggerToGlobal } = Cu.import('resource://gre/modules/jsdebugger.jsm', {}); |
michael@0 | 18 | addDebuggerToGlobal(this); |
michael@0 | 19 | |
michael@0 | 20 | |
michael@0 | 21 | exports['test nodeResolve'] = function (assert) { |
michael@0 | 22 | let rootURI = root + '/fixtures/native-addon-test/'; |
michael@0 | 23 | let manifest = {}; |
michael@0 | 24 | manifest.dependencies = {}; |
michael@0 | 25 | |
michael@0 | 26 | // Handles extensions |
michael@0 | 27 | resolveTest('../package.json', './dir/c.js', './package.json'); |
michael@0 | 28 | resolveTest('../dir/b.js', './dir/c.js', './dir/b.js'); |
michael@0 | 29 | |
michael@0 | 30 | resolveTest('./dir/b', './index.js', './dir/b.js'); |
michael@0 | 31 | resolveTest('../index', './dir/b.js', './index.js'); |
michael@0 | 32 | resolveTest('../', './dir/b.js', './index.js'); |
michael@0 | 33 | resolveTest('./dir/a', './index.js', './dir/a.js', 'Precedence dir/a.js over dir/a/'); |
michael@0 | 34 | resolveTest('../utils', './dir/a.js', './utils/index.js', 'Requiring a directory defaults to dir/index.js'); |
michael@0 | 35 | resolveTest('../newmodule', './dir/c.js', './newmodule/lib/file.js', 'Uses package.json main in dir to load appropriate "main"'); |
michael@0 | 36 | resolveTest('test-math', './utils/index.js', './node_modules/test-math/index.js', |
michael@0 | 37 | 'Dependencies default to their index.js'); |
michael@0 | 38 | resolveTest('test-custom-main', './utils/index.js', './node_modules/test-custom-main/lib/custom-entry.js', |
michael@0 | 39 | 'Dependencies use "main" entry'); |
michael@0 | 40 | resolveTest('test-math/lib/sqrt', './utils/index.js', './node_modules/test-math/lib/sqrt.js', |
michael@0 | 41 | 'Dependencies\' files can be consumed via "/"'); |
michael@0 | 42 | |
michael@0 | 43 | resolveTest('sdk/tabs/utils', './index.js', undefined, |
michael@0 | 44 | 'correctly ignores SDK references in paths'); |
michael@0 | 45 | resolveTest('fs', './index.js', undefined, |
michael@0 | 46 | 'correctly ignores built in node modules in paths'); |
michael@0 | 47 | |
michael@0 | 48 | resolveTest('test-add', './node_modules/test-math/index.js', |
michael@0 | 49 | './node_modules/test-math/node_modules/test-add/index.js', |
michael@0 | 50 | 'Dependencies\' dependencies can be found'); |
michael@0 | 51 | |
michael@0 | 52 | |
michael@0 | 53 | function resolveTest (id, requirer, expected, msg) { |
michael@0 | 54 | let result = nodeResolve(id, requirer, { manifest: manifest, rootURI: rootURI }); |
michael@0 | 55 | assert.equal(result, expected, 'nodeResolve ' + id + ' from ' + requirer + ' ' +msg); |
michael@0 | 56 | } |
michael@0 | 57 | } |
michael@0 | 58 | |
michael@0 | 59 | /* |
michael@0 | 60 | // TODO not working in current env |
michael@0 | 61 | exports['test bundle'] = function (assert, done) { |
michael@0 | 62 | loadAddon('/native-addons/native-addon-test/') |
michael@0 | 63 | }; |
michael@0 | 64 | */ |
michael@0 | 65 | |
michael@0 | 66 | exports['test generateMap()'] = function (assert, done) { |
michael@0 | 67 | getJSON('/fixtures/native-addon-test/expectedmap.json').then(expected => { |
michael@0 | 68 | generateMap({ |
michael@0 | 69 | rootURI: root + '/fixtures/native-addon-test/' |
michael@0 | 70 | }, map => { |
michael@0 | 71 | assert.deepEqual(map, expected, 'generateMap returns expected mappings'); |
michael@0 | 72 | assert.equal(map['./index.js']['./dir/a'], './dir/a.js', |
michael@0 | 73 | 'sanity check on correct mappings'); |
michael@0 | 74 | done(); |
michael@0 | 75 | }); |
michael@0 | 76 | }).then(null, (reason) => console.error(reason)); |
michael@0 | 77 | }; |
michael@0 | 78 | |
michael@0 | 79 | exports['test JSM loading'] = function (assert, done) { |
michael@0 | 80 | getJSON('/fixtures/jsm-package/package.json').then(manifest => { |
michael@0 | 81 | let rootURI = root + '/fixtures/jsm-package/'; |
michael@0 | 82 | let loader = Loader({ |
michael@0 | 83 | paths: makePaths(rootURI), |
michael@0 | 84 | rootURI: rootURI, |
michael@0 | 85 | manifest: manifest, |
michael@0 | 86 | isNative: true |
michael@0 | 87 | }); |
michael@0 | 88 | |
michael@0 | 89 | let program = main(loader); |
michael@0 | 90 | assert.ok(program.localJSMCached, 'local relative JSMs are cached'); |
michael@0 | 91 | assert.ok(program.isCachedJSAbsolute , 'absolute resource:// js are cached'); |
michael@0 | 92 | assert.ok(program.isCachedPath, 'JSMs resolved in paths are cached'); |
michael@0 | 93 | assert.ok(program.isCachedAbsolute, 'absolute resource:// JSMs are cached'); |
michael@0 | 94 | |
michael@0 | 95 | assert.ok(program.localJSM, 'able to load local relative JSMs'); |
michael@0 | 96 | all([ |
michael@0 | 97 | program.isLoadedPath(10), |
michael@0 | 98 | program.isLoadedAbsolute(20), |
michael@0 | 99 | program.isLoadedJSAbsolute(30) |
michael@0 | 100 | ]).then(([path, absolute, jsabsolute]) => { |
michael@0 | 101 | assert.equal(path, 10, 'JSM files resolved from path work'); |
michael@0 | 102 | assert.equal(absolute, 20, 'JSM files resolved from full resource:// work'); |
michael@0 | 103 | assert.equal(jsabsolute, 30, 'JS files resolved from full resource:// work'); |
michael@0 | 104 | }).then(done, console.error); |
michael@0 | 105 | |
michael@0 | 106 | }).then(null, console.error); |
michael@0 | 107 | }; |
michael@0 | 108 | |
michael@0 | 109 | exports['test native Loader with mappings'] = function (assert, done) { |
michael@0 | 110 | all([ |
michael@0 | 111 | getJSON('/fixtures/native-addon-test/expectedmap.json'), |
michael@0 | 112 | getJSON('/fixtures/native-addon-test/package.json') |
michael@0 | 113 | ]).then(([expectedMap, manifest]) => { |
michael@0 | 114 | |
michael@0 | 115 | // Override dummy module and point it to `test-math` to see if the |
michael@0 | 116 | // require is pulling from the mapping |
michael@0 | 117 | expectedMap['./index.js']['./dir/dummy'] = './dir/a.js'; |
michael@0 | 118 | |
michael@0 | 119 | let rootURI = root + '/fixtures/native-addon-test/'; |
michael@0 | 120 | let loader = Loader({ |
michael@0 | 121 | paths: makePaths(rootURI), |
michael@0 | 122 | rootURI: rootURI, |
michael@0 | 123 | manifest: manifest, |
michael@0 | 124 | requireMap: expectedMap, |
michael@0 | 125 | isNative: true |
michael@0 | 126 | }); |
michael@0 | 127 | |
michael@0 | 128 | let program = main(loader); |
michael@0 | 129 | assert.equal(program.dummyModule, 'dir/a', |
michael@0 | 130 | 'The lookup uses the information given in the mapping'); |
michael@0 | 131 | |
michael@0 | 132 | testLoader(program, assert); |
michael@0 | 133 | unload(loader); |
michael@0 | 134 | done(); |
michael@0 | 135 | }).then(null, (reason) => console.error(reason)); |
michael@0 | 136 | }; |
michael@0 | 137 | |
michael@0 | 138 | exports['test native Loader without mappings'] = function (assert, done) { |
michael@0 | 139 | getJSON('/fixtures/native-addon-test/package.json').then(manifest => { |
michael@0 | 140 | let rootURI = root + '/fixtures/native-addon-test/'; |
michael@0 | 141 | let loader = Loader({ |
michael@0 | 142 | paths: makePaths(rootURI), |
michael@0 | 143 | rootURI: rootURI, |
michael@0 | 144 | manifest: manifest, |
michael@0 | 145 | isNative: true |
michael@0 | 146 | }); |
michael@0 | 147 | |
michael@0 | 148 | let program = main(loader); |
michael@0 | 149 | testLoader(program, assert); |
michael@0 | 150 | unload(loader); |
michael@0 | 151 | done(); |
michael@0 | 152 | }).then(null, (reason) => console.error(reason)); |
michael@0 | 153 | }; |
michael@0 | 154 | |
michael@0 | 155 | function testLoader (program, assert) { |
michael@0 | 156 | // Test 'main' entries |
michael@0 | 157 | // no relative custom main `lib/index.js` |
michael@0 | 158 | assert.equal(program.customMainModule, 'custom entry file', |
michael@0 | 159 | 'a node_module dependency correctly uses its `main` entry in manifest'); |
michael@0 | 160 | // relative custom main `./lib/index.js` |
michael@0 | 161 | assert.equal(program.customMainModuleRelative, 'custom entry file relative', |
michael@0 | 162 | 'a node_module dependency correctly uses its `main` entry in manifest with relative ./'); |
michael@0 | 163 | // implicit './index.js' |
michael@0 | 164 | assert.equal(program.defaultMain, 'default main', |
michael@0 | 165 | 'a node_module dependency correctly defautls to index.js for main'); |
michael@0 | 166 | |
michael@0 | 167 | // Test directory exports |
michael@0 | 168 | assert.equal(program.directoryDefaults, 'utils', |
michael@0 | 169 | '`require`ing a directory defaults to dir/index.js'); |
michael@0 | 170 | assert.equal(program.directoryMain, 'main from new module', |
michael@0 | 171 | '`require`ing a directory correctly loads the `main` entry and not index.js'); |
michael@0 | 172 | assert.equal(program.resolvesJSoverDir, 'dir/a', |
michael@0 | 173 | '`require`ing "a" resolves "a.js" over "a/index.js"'); |
michael@0 | 174 | |
michael@0 | 175 | // Test dependency's dependencies |
michael@0 | 176 | assert.ok(program.math.add, |
michael@0 | 177 | 'correctly defaults to index.js of a module'); |
michael@0 | 178 | assert.equal(program.math.add(10, 5), 15, |
michael@0 | 179 | 'node dependencies correctly include their own dependencies'); |
michael@0 | 180 | assert.equal(program.math.subtract(10, 5), 5, |
michael@0 | 181 | 'node dependencies correctly include their own dependencies'); |
michael@0 | 182 | assert.equal(program.mathInRelative.subtract(10, 5), 5, |
michael@0 | 183 | 'relative modules can also include node dependencies'); |
michael@0 | 184 | |
michael@0 | 185 | // Test SDK natives |
michael@0 | 186 | assert.ok(program.promise.defer, 'main entry can include SDK modules with no deps'); |
michael@0 | 187 | assert.ok(program.promise.resolve, 'main entry can include SDK modules with no deps'); |
michael@0 | 188 | assert.ok(program.eventCore.on, 'main entry can include SDK modules that have dependencies'); |
michael@0 | 189 | assert.ok(program.eventCore.off, 'main entry can include SDK modules that have dependencies'); |
michael@0 | 190 | |
michael@0 | 191 | // Test JSMs |
michael@0 | 192 | assert.ok(program.promisejsm.defer, 'can require JSM files in path'); |
michael@0 | 193 | assert.equal(program.localJSM.test, 'this is a jsm', |
michael@0 | 194 | 'can require relative JSM files'); |
michael@0 | 195 | |
michael@0 | 196 | // Other tests |
michael@0 | 197 | assert.equal(program.areModulesCached, true, |
michael@0 | 198 | 'modules are correctly cached'); |
michael@0 | 199 | assert.equal(program.testJSON.dependencies['test-math'], '*', |
michael@0 | 200 | 'correctly requires JSON files'); |
michael@0 | 201 | } |
michael@0 | 202 | |
michael@0 | 203 | function getJSON (uri) { |
michael@0 | 204 | return readURI(root + uri).then(manifest => JSON.parse(manifest)); |
michael@0 | 205 | } |
michael@0 | 206 | |
michael@0 | 207 | function makePaths (uri) { |
michael@0 | 208 | // Uses development SDK modules if overloaded in loader |
michael@0 | 209 | let sdkPaths = testOptions.paths ? testOptions.paths[''] : 'resource://gre/modules/commonjs/'; |
michael@0 | 210 | return { |
michael@0 | 211 | './': uri, |
michael@0 | 212 | 'sdk/': sdkPaths + 'sdk/', |
michael@0 | 213 | 'toolkit/': sdkPaths + 'toolkit/', |
michael@0 | 214 | 'modules/': 'resource://gre/modules/' |
michael@0 | 215 | }; |
michael@0 | 216 | } |
michael@0 | 217 | |
michael@0 | 218 | function loadAddon (uri, map) { |
michael@0 | 219 | let rootURI = root + uri; |
michael@0 | 220 | getJSON(uri + '/package.json').then(manifest => { |
michael@0 | 221 | let loader = Loader({ |
michael@0 | 222 | paths: makePaths(rootURI), |
michael@0 | 223 | rootURI: rootURI, |
michael@0 | 224 | manifest: manifest, |
michael@0 | 225 | isNative: true, |
michael@0 | 226 | modules: { |
michael@0 | 227 | '@test/options': testOptions |
michael@0 | 228 | } |
michael@0 | 229 | }); |
michael@0 | 230 | let program = main(loader); |
michael@0 | 231 | }).then(null, console.error); |
michael@0 | 232 | } |
michael@0 | 233 | |
michael@0 | 234 | require('test').run(exports); |