1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/test/test-native-loader.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,234 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +'use strict'; 1.9 + 1.10 +let { 1.11 + Loader, main, unload, parseStack, generateMap, resolve, nodeResolve 1.12 +} = require('toolkit/loader'); 1.13 +let { readURI } = require('sdk/net/url'); 1.14 +let { all } = require('sdk/core/promise'); 1.15 +let testOptions = require('@test/options'); 1.16 + 1.17 +let root = module.uri.substr(0, module.uri.lastIndexOf('/')) 1.18 +// The following adds Debugger constructor to the global namespace. 1.19 +const { Cu } = require('chrome'); 1.20 +const { addDebuggerToGlobal } = Cu.import('resource://gre/modules/jsdebugger.jsm', {}); 1.21 +addDebuggerToGlobal(this); 1.22 + 1.23 + 1.24 +exports['test nodeResolve'] = function (assert) { 1.25 + let rootURI = root + '/fixtures/native-addon-test/'; 1.26 + let manifest = {}; 1.27 + manifest.dependencies = {}; 1.28 + 1.29 + // Handles extensions 1.30 + resolveTest('../package.json', './dir/c.js', './package.json'); 1.31 + resolveTest('../dir/b.js', './dir/c.js', './dir/b.js'); 1.32 + 1.33 + resolveTest('./dir/b', './index.js', './dir/b.js'); 1.34 + resolveTest('../index', './dir/b.js', './index.js'); 1.35 + resolveTest('../', './dir/b.js', './index.js'); 1.36 + resolveTest('./dir/a', './index.js', './dir/a.js', 'Precedence dir/a.js over dir/a/'); 1.37 + resolveTest('../utils', './dir/a.js', './utils/index.js', 'Requiring a directory defaults to dir/index.js'); 1.38 + resolveTest('../newmodule', './dir/c.js', './newmodule/lib/file.js', 'Uses package.json main in dir to load appropriate "main"'); 1.39 + resolveTest('test-math', './utils/index.js', './node_modules/test-math/index.js', 1.40 + 'Dependencies default to their index.js'); 1.41 + resolveTest('test-custom-main', './utils/index.js', './node_modules/test-custom-main/lib/custom-entry.js', 1.42 + 'Dependencies use "main" entry'); 1.43 + resolveTest('test-math/lib/sqrt', './utils/index.js', './node_modules/test-math/lib/sqrt.js', 1.44 + 'Dependencies\' files can be consumed via "/"'); 1.45 + 1.46 + resolveTest('sdk/tabs/utils', './index.js', undefined, 1.47 + 'correctly ignores SDK references in paths'); 1.48 + resolveTest('fs', './index.js', undefined, 1.49 + 'correctly ignores built in node modules in paths'); 1.50 + 1.51 + resolveTest('test-add', './node_modules/test-math/index.js', 1.52 + './node_modules/test-math/node_modules/test-add/index.js', 1.53 + 'Dependencies\' dependencies can be found'); 1.54 + 1.55 + 1.56 + function resolveTest (id, requirer, expected, msg) { 1.57 + let result = nodeResolve(id, requirer, { manifest: manifest, rootURI: rootURI }); 1.58 + assert.equal(result, expected, 'nodeResolve ' + id + ' from ' + requirer + ' ' +msg); 1.59 + } 1.60 +} 1.61 + 1.62 +/* 1.63 +// TODO not working in current env 1.64 +exports['test bundle'] = function (assert, done) { 1.65 + loadAddon('/native-addons/native-addon-test/') 1.66 +}; 1.67 +*/ 1.68 + 1.69 +exports['test generateMap()'] = function (assert, done) { 1.70 + getJSON('/fixtures/native-addon-test/expectedmap.json').then(expected => { 1.71 + generateMap({ 1.72 + rootURI: root + '/fixtures/native-addon-test/' 1.73 + }, map => { 1.74 + assert.deepEqual(map, expected, 'generateMap returns expected mappings'); 1.75 + assert.equal(map['./index.js']['./dir/a'], './dir/a.js', 1.76 + 'sanity check on correct mappings'); 1.77 + done(); 1.78 + }); 1.79 + }).then(null, (reason) => console.error(reason)); 1.80 +}; 1.81 + 1.82 +exports['test JSM loading'] = function (assert, done) { 1.83 + getJSON('/fixtures/jsm-package/package.json').then(manifest => { 1.84 + let rootURI = root + '/fixtures/jsm-package/'; 1.85 + let loader = Loader({ 1.86 + paths: makePaths(rootURI), 1.87 + rootURI: rootURI, 1.88 + manifest: manifest, 1.89 + isNative: true 1.90 + }); 1.91 + 1.92 + let program = main(loader); 1.93 + assert.ok(program.localJSMCached, 'local relative JSMs are cached'); 1.94 + assert.ok(program.isCachedJSAbsolute , 'absolute resource:// js are cached'); 1.95 + assert.ok(program.isCachedPath, 'JSMs resolved in paths are cached'); 1.96 + assert.ok(program.isCachedAbsolute, 'absolute resource:// JSMs are cached'); 1.97 + 1.98 + assert.ok(program.localJSM, 'able to load local relative JSMs'); 1.99 + all([ 1.100 + program.isLoadedPath(10), 1.101 + program.isLoadedAbsolute(20), 1.102 + program.isLoadedJSAbsolute(30) 1.103 + ]).then(([path, absolute, jsabsolute]) => { 1.104 + assert.equal(path, 10, 'JSM files resolved from path work'); 1.105 + assert.equal(absolute, 20, 'JSM files resolved from full resource:// work'); 1.106 + assert.equal(jsabsolute, 30, 'JS files resolved from full resource:// work'); 1.107 + }).then(done, console.error); 1.108 + 1.109 + }).then(null, console.error); 1.110 +}; 1.111 + 1.112 +exports['test native Loader with mappings'] = function (assert, done) { 1.113 + all([ 1.114 + getJSON('/fixtures/native-addon-test/expectedmap.json'), 1.115 + getJSON('/fixtures/native-addon-test/package.json') 1.116 + ]).then(([expectedMap, manifest]) => { 1.117 + 1.118 + // Override dummy module and point it to `test-math` to see if the 1.119 + // require is pulling from the mapping 1.120 + expectedMap['./index.js']['./dir/dummy'] = './dir/a.js'; 1.121 + 1.122 + let rootURI = root + '/fixtures/native-addon-test/'; 1.123 + let loader = Loader({ 1.124 + paths: makePaths(rootURI), 1.125 + rootURI: rootURI, 1.126 + manifest: manifest, 1.127 + requireMap: expectedMap, 1.128 + isNative: true 1.129 + }); 1.130 + 1.131 + let program = main(loader); 1.132 + assert.equal(program.dummyModule, 'dir/a', 1.133 + 'The lookup uses the information given in the mapping'); 1.134 + 1.135 + testLoader(program, assert); 1.136 + unload(loader); 1.137 + done(); 1.138 + }).then(null, (reason) => console.error(reason)); 1.139 +}; 1.140 + 1.141 +exports['test native Loader without mappings'] = function (assert, done) { 1.142 + getJSON('/fixtures/native-addon-test/package.json').then(manifest => { 1.143 + let rootURI = root + '/fixtures/native-addon-test/'; 1.144 + let loader = Loader({ 1.145 + paths: makePaths(rootURI), 1.146 + rootURI: rootURI, 1.147 + manifest: manifest, 1.148 + isNative: true 1.149 + }); 1.150 + 1.151 + let program = main(loader); 1.152 + testLoader(program, assert); 1.153 + unload(loader); 1.154 + done(); 1.155 + }).then(null, (reason) => console.error(reason)); 1.156 +}; 1.157 + 1.158 +function testLoader (program, assert) { 1.159 + // Test 'main' entries 1.160 + // no relative custom main `lib/index.js` 1.161 + assert.equal(program.customMainModule, 'custom entry file', 1.162 + 'a node_module dependency correctly uses its `main` entry in manifest'); 1.163 + // relative custom main `./lib/index.js` 1.164 + assert.equal(program.customMainModuleRelative, 'custom entry file relative', 1.165 + 'a node_module dependency correctly uses its `main` entry in manifest with relative ./'); 1.166 + // implicit './index.js' 1.167 + assert.equal(program.defaultMain, 'default main', 1.168 + 'a node_module dependency correctly defautls to index.js for main'); 1.169 + 1.170 + // Test directory exports 1.171 + assert.equal(program.directoryDefaults, 'utils', 1.172 + '`require`ing a directory defaults to dir/index.js'); 1.173 + assert.equal(program.directoryMain, 'main from new module', 1.174 + '`require`ing a directory correctly loads the `main` entry and not index.js'); 1.175 + assert.equal(program.resolvesJSoverDir, 'dir/a', 1.176 + '`require`ing "a" resolves "a.js" over "a/index.js"'); 1.177 + 1.178 + // Test dependency's dependencies 1.179 + assert.ok(program.math.add, 1.180 + 'correctly defaults to index.js of a module'); 1.181 + assert.equal(program.math.add(10, 5), 15, 1.182 + 'node dependencies correctly include their own dependencies'); 1.183 + assert.equal(program.math.subtract(10, 5), 5, 1.184 + 'node dependencies correctly include their own dependencies'); 1.185 + assert.equal(program.mathInRelative.subtract(10, 5), 5, 1.186 + 'relative modules can also include node dependencies'); 1.187 + 1.188 + // Test SDK natives 1.189 + assert.ok(program.promise.defer, 'main entry can include SDK modules with no deps'); 1.190 + assert.ok(program.promise.resolve, 'main entry can include SDK modules with no deps'); 1.191 + assert.ok(program.eventCore.on, 'main entry can include SDK modules that have dependencies'); 1.192 + assert.ok(program.eventCore.off, 'main entry can include SDK modules that have dependencies'); 1.193 + 1.194 + // Test JSMs 1.195 + assert.ok(program.promisejsm.defer, 'can require JSM files in path'); 1.196 + assert.equal(program.localJSM.test, 'this is a jsm', 1.197 + 'can require relative JSM files'); 1.198 + 1.199 + // Other tests 1.200 + assert.equal(program.areModulesCached, true, 1.201 + 'modules are correctly cached'); 1.202 + assert.equal(program.testJSON.dependencies['test-math'], '*', 1.203 + 'correctly requires JSON files'); 1.204 +} 1.205 + 1.206 +function getJSON (uri) { 1.207 + return readURI(root + uri).then(manifest => JSON.parse(manifest)); 1.208 +} 1.209 + 1.210 +function makePaths (uri) { 1.211 + // Uses development SDK modules if overloaded in loader 1.212 + let sdkPaths = testOptions.paths ? testOptions.paths[''] : 'resource://gre/modules/commonjs/'; 1.213 + return { 1.214 + './': uri, 1.215 + 'sdk/': sdkPaths + 'sdk/', 1.216 + 'toolkit/': sdkPaths + 'toolkit/', 1.217 + 'modules/': 'resource://gre/modules/' 1.218 + }; 1.219 +} 1.220 + 1.221 +function loadAddon (uri, map) { 1.222 + let rootURI = root + uri; 1.223 + getJSON(uri + '/package.json').then(manifest => { 1.224 + let loader = Loader({ 1.225 + paths: makePaths(rootURI), 1.226 + rootURI: rootURI, 1.227 + manifest: manifest, 1.228 + isNative: true, 1.229 + modules: { 1.230 + '@test/options': testOptions 1.231 + } 1.232 + }); 1.233 + let program = main(loader); 1.234 + }).then(null, console.error); 1.235 +} 1.236 + 1.237 +require('test').run(exports);