diff options
Diffstat (limited to 'js/xpconnect/tests/unit/test_compileScript.js')
-rw-r--r-- | js/xpconnect/tests/unit/test_compileScript.js | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/js/xpconnect/tests/unit/test_compileScript.js b/js/xpconnect/tests/unit/test_compileScript.js new file mode 100644 index 0000000000..1baf7ab56e --- /dev/null +++ b/js/xpconnect/tests/unit/test_compileScript.js @@ -0,0 +1,99 @@ +"use strict"; + +const { AddonTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/AddonTestUtils.sys.mjs" +); + +AddonTestUtils.init(this); + +add_task(async function() { + let scriptUrl = Services.io.newFileURI(do_get_file("file_simple_script.js")).spec; + + + let script1 = await ChromeUtils.compileScript(scriptUrl, {hasReturnValue: true}); + let script2 = await ChromeUtils.compileScript(scriptUrl, {hasReturnValue: false}); + + equal(script1.url, scriptUrl, "Script URL is correct") + equal(script2.url, scriptUrl, "Script URL is correct") + + equal(script1.hasReturnValue, true, "Script hasReturnValue property is correct") + equal(script2.hasReturnValue, false, "Script hasReturnValue property is correct") + + + // Test return-value version. + + let sandbox1 = Cu.Sandbox("http://example.com"); + let sandbox2 = Cu.Sandbox("http://example.org"); + + let obj = script1.executeInGlobal(sandbox1); + equal(Cu.getObjectPrincipal(obj).origin, "http://example.com", "Return value origin is correct"); + equal(obj.foo, "\u00ae", "Return value has the correct charset"); + + obj = script1.executeInGlobal(sandbox2); + equal(Cu.getObjectPrincipal(obj).origin, "http://example.org", "Return value origin is correct"); + equal(obj.foo, "\u00ae", "Return value has the correct charset"); + + + // Test no-return-value version. + + sandbox1.bar = null; + equal(sandbox1.bar, null); + + obj = script2.executeInGlobal(sandbox1); + equal(obj, undefined, "No-return script has no return value"); + + equal(Cu.getObjectPrincipal(sandbox1.bar).origin, "http://example.com", "Object value origin is correct"); + equal(sandbox1.bar.foo, "\u00ae", "Object value has the correct charset"); + + + sandbox2.bar = null; + equal(sandbox2.bar, null); + + obj = script2.executeInGlobal(sandbox2); + equal(obj, undefined, "No-return script has no return value"); + + equal(Cu.getObjectPrincipal(sandbox2.bar).origin, "http://example.org", "Object value origin is correct"); + equal(sandbox2.bar.foo, "\u00ae", "Object value has the correct charset"); +}); + +add_task(async function test_syntaxError() { + // Generate an artificially large script to force off-main-thread + // compilation. + let scriptUrl = `data:,${";".repeat(1024 * 1024)}(`; + + await Assert.rejects( + ChromeUtils.compileScript(scriptUrl), + SyntaxError); + + // Generate a small script to force main thread compilation. + scriptUrl = `data:,;(`; + + await Assert.rejects( + ChromeUtils.compileScript(scriptUrl), + SyntaxError); +}); + +/** + * Assert that executeInGlobal throws a special exception when the content script throws. + * And the content script exception is notified to the console. + */ +add_task(async function test_exceptions_in_webconsole() { + const scriptUrl = `data:,throw new Error("foo")`; + const script = await ChromeUtils.compileScript(scriptUrl); + const sandbox = Cu.Sandbox("http://example.com"); + + Assert.throws(() => script.executeInGlobal(sandbox), + /Error: foo/, + "Without reportException set to true, executeInGlobal throws an exception"); + + info("With reportException, executeInGlobal doesn't throw, but notifies the console"); + const { messages } = await AddonTestUtils.promiseConsoleOutput(() => { + script.executeInGlobal(sandbox, { reportExceptions: true }); + }); + + info("Wait for the console message related to the content script exception"); + equal(messages.length, 1, "Got one console message"); + messages[0].QueryInterface(Ci.nsIScriptError); + equal(messages[0].errorMessage, "Error: foo", "We are notified about the plain content script exception via the console"); + ok(messages[0].stack, "The message has a stack"); +}); |