Wed, 31 Dec 2014 06:09:35 +0100
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);