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

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     5 'use strict';
     7 let {
     8   Loader, main, unload, parseStack, generateMap, resolve, join
     9 } = require('toolkit/loader');
    10 let { readURI } = require('sdk/net/url');
    12 let root = module.uri.substr(0, module.uri.lastIndexOf('/'))
    15 // The following adds Debugger constructor to the global namespace.
    16 const { Cu } = require('chrome');
    17 const { addDebuggerToGlobal } = Cu.import('resource://gre/modules/jsdebugger.jsm', {});
    18 addDebuggerToGlobal(this);
    20 exports['test resolve'] = function (assert) {
    21   let cuddlefish_id = 'sdk/loader/cuddlefish';
    22   assert.equal(resolve('../index.js', './dir/c.js'), './index.js');
    23   assert.equal(resolve('./index.js', './dir/c.js'), './dir/index.js');
    24   assert.equal(resolve('./dir/c.js', './index.js'), './dir/c.js');
    25   assert.equal(resolve('../utils/file.js', './dir/b.js'), './utils/file.js');
    27   assert.equal(resolve('../utils/./file.js', './dir/b.js'), './utils/file.js');
    28   assert.equal(resolve('../utils/file.js', './'), './../utils/file.js');
    29   assert.equal(resolve('./utils/file.js', './'), './utils/file.js');
    30   assert.equal(resolve('./utils/file.js', './index.js'), './utils/file.js');
    32   assert.equal(resolve('../utils/./file.js', cuddlefish_id), 'sdk/utils/file.js');
    33   assert.equal(resolve('../utils/file.js', cuddlefish_id), 'sdk/utils/file.js');
    34   assert.equal(resolve('./utils/file.js', cuddlefish_id), 'sdk/loader/utils/file.js');
    36   assert.equal(resolve('..//index.js', './dir/c.js'), './index.js');
    37   assert.equal(resolve('../../gre/modules/XPCOMUtils.jsm', 'resource://thing/utils/file.js'), 'resource://gre/modules/XPCOMUtils.jsm');
    38   assert.equal(resolve('../../gre/modules/XPCOMUtils.jsm', 'chrome://thing/utils/file.js'), 'chrome://gre/modules/XPCOMUtils.jsm');
    39   assert.equal(resolve('../../a/b/c.json', 'file:///thing/utils/file.js'), 'file:///a/b/c.json');
    41   // Does not change absolute paths
    42   assert.equal(resolve('resource://gre/modules/file.js', './dir/b.js'),
    43     'resource://gre/modules/file.js');
    44   assert.equal(resolve('file:///gre/modules/file.js', './dir/b.js'),
    45     'file:///gre/modules/file.js');
    46   assert.equal(resolve('/root.js', './dir/b.js'),
    47     '/root.js');
    48 };
    50 exports['test join'] = function (assert) {
    51   assert.equal(join('a/path', '../../../module'), '../module');
    52   assert.equal(join('a/path/to', '../module'), 'a/path/module');
    53   assert.equal(join('a/path/to', './module'), 'a/path/to/module');
    54   assert.equal(join('a/path/to', '././../module'), 'a/path/module');
    55   assert.equal(join('resource://my/path/yeah/yuh', '../whoa'),
    56     'resource://my/path/yeah/whoa');
    57   assert.equal(join('resource://my/path/yeah/yuh', './whoa'),
    58     'resource://my/path/yeah/yuh/whoa');
    59   assert.equal(join('file:///my/path/yeah/yuh', '../whoa'),
    60     'file:///my/path/yeah/whoa');
    61   assert.equal(join('file:///my/path/yeah/yuh', './whoa'),
    62     'file:///my/path/yeah/yuh/whoa');
    63   assert.equal(join('a/path/to', '..//module'), 'a/path/module');
    64 };
    66 exports['test dependency cycles'] = function(assert) {
    67   let uri = root + '/fixtures/loader/cycles/';
    68   let loader = Loader({ paths: { '': uri } });
    70   let program = main(loader, 'main');
    72   assert.equal(program.a.b, program.b, 'module `a` gets correct `b`');
    73   assert.equal(program.b.a, program.a, 'module `b` gets correct `a`');
    74   assert.equal(program.c.main, program, 'module `c` gets correct `main`');
    76   unload(loader);
    77 }
    79 exports['test syntax errors'] = function(assert) {
    80   let uri = root + '/fixtures/loader/syntax-error/';
    81   let loader = Loader({ paths: { '': uri } });
    83   try {
    84     let program = main(loader, 'main');
    85   } catch (error) {
    86     assert.equal(error.name, "SyntaxError", "throws syntax error");
    87     assert.equal(error.fileName.split("/").pop(), "error.js",
    88               "Error contains filename");
    89     assert.equal(error.lineNumber, 11, "error is on line 11");
    90     let stack = parseStack(error.stack);
    92     assert.equal(stack.pop().fileName, uri + "error.js",
    93                  "last frame file containing syntax error");
    94     assert.equal(stack.pop().fileName, uri + "main.js",
    95                  "previous frame is a requirer module");
    96     assert.equal(stack.pop().fileName, module.uri,
    97                  "previous to it is a test module");
    99   } finally {
   100     unload(loader);
   101   }
   102 }
   104 exports['test sandboxes are not added if error'] = function (assert) {
   105   let uri = root + '/fixtures/loader/missing-twice/';
   106   let loader = Loader({ paths: { '': uri } });
   107   let program = main(loader, 'main');
   108   assert.ok(!(uri + 'not-found.js' in loader.sandboxes), 'not-found.js not in loader.sandboxes');
   109 }
   111 exports['test missing module'] = function(assert) {
   112   let uri = root + '/fixtures/loader/missing/'
   113   let loader = Loader({ paths: { '': uri } });
   115   try {
   116     let program = main(loader, 'main')
   117   } catch (error) {
   118     assert.equal(error.message, "Module `not-found` is not found at " +
   119                 uri + "not-found.js", "throws if error not found");
   121     assert.equal(error.fileName.split("/").pop(), "main.js",
   122                  "Error fileName is requirer module");
   124     assert.equal(error.lineNumber, 7, "error is on line 7");
   126     let stack = parseStack(error.stack);
   128     assert.equal(stack.pop().fileName, uri + "main.js",
   129                  "loader stack is omitted");
   131     assert.equal(stack.pop().fileName, module.uri,
   132                  "previous in the stack is test module");
   133   } finally {
   134     unload(loader);
   135   }
   136 }
   138 exports["test invalid module not cached and throws everytime"] = function(assert) {
   139   let uri = root + "/fixtures/loader/missing-twice/";
   140   let loader = Loader({ paths: { "": uri } });
   142   let { firstError, secondError, invalidJSON1, invalidJSON2 } = main(loader, "main");
   143   assert.equal(firstError.message, "Module `not-found` is not found at " +
   144     uri + "not-found.js", "throws on first invalid require");
   145   assert.equal(firstError.lineNumber, 8, "first error is on line 7");
   146   assert.equal(secondError.message, "Module `not-found` is not found at " +
   147     uri + "not-found.js", "throws on second invalid require");
   148   assert.equal(secondError.lineNumber, 14, "second error is on line 14");
   150   assert.equal(invalidJSON1.message,
   151     "JSON.parse: unexpected character at line 1 column 1 of the JSON data",
   152     "throws on invalid JSON");
   153   assert.equal(invalidJSON2.message,
   154     "JSON.parse: unexpected character at line 1 column 1 of the JSON data",
   155     "throws on invalid JSON second time");
   156 };
   158 exports['test exceptions in modules'] = function(assert) {
   159   let uri = root + '/fixtures/loader/exceptions/'
   161   let loader = Loader({ paths: { '': uri } });
   163   try {
   164     let program = main(loader, 'main')
   165   } catch (error) {
   166     assert.equal(error.message, "Boom!", "thrown errors propagate");
   168     assert.equal(error.fileName.split("/").pop(), "boomer.js",
   169                  "Error comes from the module that threw it");
   171     assert.equal(error.lineNumber, 8, "error is on line 8");
   173     let stack = parseStack(error.stack);
   175     let frame = stack.pop()
   176     assert.equal(frame.fileName, uri + "boomer.js",
   177                  "module that threw is first in the stack");
   178     assert.equal(frame.name, "exports.boom",
   179                  "name is in the stack");
   181     frame = stack.pop()
   182     assert.equal(frame.fileName, uri + "main.js",
   183                  "module that called it is next in the stack");
   184     assert.equal(frame.lineNumber, 9, "caller line is in the stack");
   187     assert.equal(stack.pop().fileName, module.uri,
   188                  "this test module is next in the stack");
   189   } finally {
   190     unload(loader);
   191   }
   192 }
   194 exports['test early errors in module'] = function(assert) {
   195   let uri = root + '/fixtures/loader/errors/';
   196   let loader = Loader({ paths: { '': uri } });
   198   try {
   199     let program = main(loader, 'main')
   200   } catch (error) {
   201     assert.equal(String(error),
   202                  "Error: opening input stream (invalid filename?)",
   203                  "thrown errors propagate");
   205     assert.equal(error.fileName.split("/").pop(), "boomer.js",
   206                  "Error comes from the module that threw it");
   208     assert.equal(error.lineNumber, 7, "error is on line 7");
   210     let stack = parseStack(error.stack);
   212     let frame = stack.pop()
   213     assert.equal(frame.fileName, uri + "boomer.js",
   214                  "module that threw is first in the stack");
   216     frame = stack.pop()
   217     assert.equal(frame.fileName, uri + "main.js",
   218                  "module that called it is next in the stack");
   219     assert.equal(frame.lineNumber, 7, "caller line is in the stack");
   222     assert.equal(stack.pop().fileName, module.uri,
   223                  "this test module is next in the stack");
   224   } finally {
   225     unload(loader);
   226   }
   227 };
   229 exports['test require json'] = function (assert) {
   230   let data = require('./fixtures/loader/json/manifest.json');
   231   assert.equal(data.name, 'Jetpack Loader Test', 'loads json with strings');
   232   assert.equal(data.version, '1.0.1', 'loads json with strings');
   233   assert.equal(data.dependencies.async, '*', 'loads json with objects');
   234   assert.equal(data.dependencies.underscore, '*', 'loads json with objects');
   235   assert.equal(data.contributors.length, 4, 'loads json with arrays');
   236   assert.ok(Array.isArray(data.contributors), 'loads json with arrays');
   237   data.version = '2.0.0';
   238   let newdata = require('./fixtures/loader/json/manifest.json');
   239   assert.equal(newdata.version, '2.0.0',
   240     'JSON objects returned should be cached and the same instance');
   242   try {
   243     require('./fixtures/loader/json/invalid.json');
   244     assert.fail('Error not thrown when loading invalid json');
   245   } catch (err) {
   246     assert.ok(err, 'error thrown when loading invalid json');
   247     assert.ok(/JSON\.parse/.test(err.message),
   248       'should thrown an error from JSON.parse, not attempt to load .json.js');
   249   }
   251   // Try again to ensure an empty module isn't loaded from cache
   252   try {
   253     require('./fixtures/loader/json/invalid.json');
   254     assert.fail('Error not thrown when loading invalid json a second time');
   255   } catch (err) {
   256     assert.ok(err,
   257       'error thrown when loading invalid json a second time');
   258     assert.ok(/JSON\.parse/.test(err.message),
   259       'should thrown an error from JSON.parse a second time, not attempt to load .json.js');
   260   }
   261 };
   263 exports['test setting metadata for newly created sandboxes'] = function(assert) {
   264   let addonID = 'random-addon-id';
   265   let uri = root + '/fixtures/loader/cycles/';
   266   let loader = Loader({ paths: { '': uri }, id: addonID });
   268   let dbg = new Debugger();
   269   dbg.onNewGlobalObject = function(global) {
   270     dbg.onNewGlobalObject = undefined;
   272     let metadata = Cu.getSandboxMetadata(global.unsafeDereference());
   273     assert.ok(metadata, 'this global has attached metadata');
   274     assert.equal(metadata.URI, uri + 'main.js', 'URI is set properly');
   275     assert.equal(metadata.addonID, addonID, 'addon ID is set');
   276   }
   278   let program = main(loader, 'main');
   279 };
   281 exports['test require .json, .json.js'] = function (assert) {
   282   let testjson = require('./fixtures/loader/json/test.json');
   283   assert.equal(testjson.filename, 'test.json',
   284     'require("./x.json") should load x.json, not x.json.js');
   286   let nodotjson = require('./fixtures/loader/json/nodotjson.json');
   287   assert.equal(nodotjson.filename, 'nodotjson.json.js',
   288     'require("./x.json") should load x.json.js when x.json does not exist');
   289   nodotjson.data.prop = 'hydralisk';
   291   // require('nodotjson.json') and require('nodotjson.json.js')
   292   // should resolve to the same file
   293   let nodotjsonjs = require('./fixtures/loader/json/nodotjson.json.js');
   294   assert.equal(nodotjsonjs.data.prop, 'hydralisk',
   295     'js modules are cached whether access via .json.js or .json');
   296 };
   298 exports['test invisibleToDebugger: false'] = function (assert) {
   299   let uri = root + '/fixtures/loader/cycles/';
   300   let loader = Loader({ paths: { '': uri } });
   301   main(loader, 'main');
   303   let dbg = new Debugger();
   304   let sandbox = loader.sandboxes[uri + 'main.js'];
   306   try {
   307     dbg.addDebuggee(sandbox);
   308     assert.ok(true, 'debugger added visible value');
   309   } catch(e) {
   310     assert.fail('debugger could not add visible value');
   311   }
   312 };
   314 exports['test invisibleToDebugger: true'] = function (assert) {
   315   let uri = root + '/fixtures/loader/cycles/';
   316   let loader = Loader({ paths: { '': uri }, invisibleToDebugger: true });
   317   main(loader, 'main');
   319   let dbg = new Debugger();
   320   let sandbox = loader.sandboxes[uri + 'main.js'];
   322   try {
   323     dbg.addDebuggee(sandbox);
   324     assert.fail('debugger added invisible value');
   325   } catch(e) {
   326     assert.ok(true, 'debugger did not add invisible value');
   327   }
   328 };
   330 exports['test console global by default'] = function (assert) {
   331   let uri = root + '/fixtures/loader/globals/';
   332   let loader = Loader({ paths: { '': uri }});
   333   let program = main(loader, 'main');
   335   assert.ok(typeof program.console === 'object', 'global `console` exists');
   336   assert.ok(typeof program.console.log === 'function', 'global `console.log` exists');
   338   let loader2 = Loader({ paths: { '': uri }, globals: { console: fakeConsole }});
   339   let program2 = main(loader2, 'main');
   341   assert.equal(program2.console, fakeConsole,
   342     'global console can be overridden with Loader options');
   343   function fakeConsole () {};
   344 };
   346 require('test').run(exports);

mercurial