addon-sdk/source/test/test-native-loader.js

changeset 0
6474c204b198
     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);

mercurial