Backed out changeset 713114c0331a (bug 1938707) by developer request CLOSED TREE
[gecko.git] / js / xpconnect / tests / unit / test_compileScript.js
blob91d1e194e7acda2217efa7abc32cce5d1a0e0e43
1 "use strict";
3 const { AddonTestUtils } = ChromeUtils.importESModule(
4   "resource://testing-common/AddonTestUtils.sys.mjs"
5 );
7 AddonTestUtils.init(this);
9 add_task(async function() {
10   let scriptUrl = Services.io.newFileURI(do_get_file("file_simple_script.js")).spec;
13   let script1 = await ChromeUtils.compileScript(scriptUrl, {hasReturnValue: true});
14   let script2 = await ChromeUtils.compileScript(scriptUrl, {hasReturnValue: false});
16   equal(script1.url, scriptUrl, "Script URL is correct")
17   equal(script2.url, scriptUrl, "Script URL is correct")
19   equal(script1.hasReturnValue, true, "Script hasReturnValue property is correct")
20   equal(script2.hasReturnValue, false, "Script hasReturnValue property is correct")
23   // Test return-value version.
25   let sandbox1 = Cu.Sandbox("http://example.com");
26   let sandbox2 = Cu.Sandbox("http://example.org");
28   let obj = script1.executeInGlobal(sandbox1);
29   equal(Cu.getObjectPrincipal(obj).origin, "http://example.com", "Return value origin is correct");
30   equal(obj.foo, "\u00ae", "Return value has the correct charset");
32   obj = script1.executeInGlobal(sandbox2);
33   equal(Cu.getObjectPrincipal(obj).origin, "http://example.org", "Return value origin is correct");
34   equal(obj.foo, "\u00ae", "Return value has the correct charset");
37   // Test no-return-value version.
39   sandbox1.bar = null;
40   equal(sandbox1.bar, null);
42   obj = script2.executeInGlobal(sandbox1);
43   equal(obj, undefined, "No-return script has no return value");
45   equal(Cu.getObjectPrincipal(sandbox1.bar).origin, "http://example.com", "Object value origin is correct");
46   equal(sandbox1.bar.foo, "\u00ae", "Object value has the correct charset");
49   sandbox2.bar = null;
50   equal(sandbox2.bar, null);
52   obj = script2.executeInGlobal(sandbox2);
53   equal(obj, undefined, "No-return script has no return value");
55   equal(Cu.getObjectPrincipal(sandbox2.bar).origin, "http://example.org", "Object value origin is correct");
56   equal(sandbox2.bar.foo, "\u00ae", "Object value has the correct charset");
57 });
59 add_task(async function test_syntaxError() {
60   // Generate an artificially large script to force off-main-thread
61   // compilation.
62   let scriptUrl = `data:,${";".repeat(1024 * 1024)}(`;
64   await Assert.rejects(
65     ChromeUtils.compileScript(scriptUrl),
66     SyntaxError);
68   // Generate a small script to force main thread compilation.
69   scriptUrl = `data:,;(`;
71   await Assert.rejects(
72     ChromeUtils.compileScript(scriptUrl),
73     SyntaxError);
74 });
76 add_task(async function test_Error_filename() {
77   // This function will be serialized as a data:-URL and called.
78   function getMyError() {
79     let err = new Error();
80     return {
81       fileName: err.fileName,
82       stackFirstLine: err.stack.split("\n")[0],
83     };
84   }
85   const scriptUrl = `data:,(${encodeURIComponent(getMyError)})()`;
86   const dummyFilename = "dummy filename";
87   let script1 = await ChromeUtils.compileScript(scriptUrl, { hasReturnValue: true });
88   let script2 = await ChromeUtils.compileScript(scriptUrl, { hasReturnValue: true, filename: dummyFilename });
90   equal(script1.url, scriptUrl, "Script URL is correct");
91   equal(script2.url, "dummy filename", "Script URL overridden");
93   let sandbox = Cu.Sandbox("http://example.com");
94   let err1 = script1.executeInGlobal(sandbox);
95   equal(err1.fileName, scriptUrl, "fileName is original script URL");
96   equal(err1.stackFirstLine, `getMyError@${scriptUrl}:2:15`, "Stack has original URL");
98   let err2 = script2.executeInGlobal(sandbox);
99   equal(err2.fileName, dummyFilename, "fileName is overridden filename");
100   equal(err2.stackFirstLine, `getMyError@${dummyFilename}:2:15`, "Stack has overridden URL");
103 add_task(async function test_invalid_url() {
104   // In this test we want a URL that doesn't resolve to a valid file.
105   // Moreover, the name is chosen such that it does not trigger the
106   // CheckForBrokenChromeURL check.
107   await Assert.rejects(
108     ChromeUtils.compileScript("resource:///invalid.ftl"),
109     /^Unable to load script: resource:\/\/\/invalid\.ftl$/
110   );
112   await Assert.rejects(
113     ChromeUtils.compileScript("resource:///invalid.ftl", { filename: "bye bye" }),
114     /^Unable to load script: bye bye$/
115   );
119  * Assert that executeInGlobal throws a special exception when the content script throws.
120  * And the content script exception is notified to the console.
121  */
122 add_task(async function test_exceptions_in_webconsole() {
123   const scriptUrl = `data:,throw new Error("foo")`;
124   const script = await ChromeUtils.compileScript(scriptUrl);
125   const sandbox = Cu.Sandbox("http://example.com");
127   Assert.throws(() => script.executeInGlobal(sandbox),
128     /Error: foo/,
129     "Without reportException set to true, executeInGlobal throws an exception");
131   info("With reportException, executeInGlobal doesn't throw, but notifies the console");
132   const { messages } = await AddonTestUtils.promiseConsoleOutput(() => {
133     script.executeInGlobal(sandbox, { reportExceptions: true });
134   });
136   info("Wait for the console message related to the content script exception");
137   equal(messages.length, 1, "Got one console message");
138   messages[0].QueryInterface(Ci.nsIScriptError);
139   equal(messages[0].errorMessage, "Error: foo", "We are notified about the plain content script exception via the console");
140   ok(messages[0].stack, "The message has a stack");