test-native-loader.js 8.7 KB

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