Bug 1465762 - Enable ESLint rule require-expected-throws-or-rejects for toolkit/**/extensions. r=aswan
☠☠ backed out by 4bec004cc30f ☠ ☠
authorMark Banner <standard8@mozilla.com>
Thu, 31 May 2018 13:45:44 +0100
changeset 475052 6630148c9beab7e1f239cc231bddedb142db23d7
parent 475051 d42b5abd0201bbe83f6e641377b0991d58735d5d
child 475053 02dbf7b85baab16f9abdcc902f2ec71f2ff9854b
push id9374
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:43:20 +0000
treeherdermozilla-beta@160e085dfb0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaswan
bugs1465762
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1465762 - Enable ESLint rule require-expected-throws-or-rejects for toolkit/**/extensions. r=aswan MozReview-Commit-ID: 5pS6RHs0naW
.eslintrc.js
toolkit/components/extensions/test/mochitest/head.js
toolkit/components/extensions/test/mochitest/test_ext_protocolHandlers.html
toolkit/components/extensions/test/mochitest/test_ext_webrequest_auth.html
toolkit/components/extensions/test/xpcshell/test_ext_contexts.js
toolkit/components/extensions/test/xpcshell/test_ext_schemas.js
toolkit/components/extensions/test/xpcshell/test_ext_schemas_async.js
toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository.js
toolkit/mozapps/extensions/test/xpcshell/test_LightweightThemeManager.js
toolkit/mozapps/extensions/test/xpcshell/test_bootstrapped_chrome_manifest.js
toolkit/mozapps/extensions/test/xpcshell/test_corrupt.js
toolkit/mozapps/extensions/test/xpcshell/test_dictionary_webextension.js
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -49,18 +49,16 @@ module.exports = {
       "mozilla/no-define-cc-etc": "off",
     }
   }, {
     // XXX Bug 1452706. These directories are still being fixed, so turn off
     //  mozilla/require-expected-throws-or-rejects for now.
     "files": [
       "devtools/client/inspector/extensions/test/head_devtools_inspector_sidebar.js",
       "storage/test/unit/**",
-      "toolkit/components/extensions/**",
-      "toolkit/mozapps/extensions/test/xpcshell/**"
     ],
     "rules": {
       "mozilla/require-expected-throws-or-rejects": "off",
     }
   }, {
     // XXX Bug 1452706. These directories are still being fixed, so turn off
     //  mozilla/require-expected-throws-or-rejects for now.
     "files": [
--- a/toolkit/components/extensions/test/mochitest/head.js
+++ b/toolkit/components/extensions/test/mochitest/head.js
@@ -32,21 +32,36 @@ if (remote) {
 
     if (results.extraWindows.length || results.extraTabs.length) {
       ok(false, `Test left extra windows or tabs: ${JSON.stringify(results)}\n`);
     }
   });
 }
 
 let Assert = {
-  rejects(promise, msg) {
+  // Cut-down version based on Assert.jsm. Only supports regexp and objects as
+  // the expected variables.
+  rejects(promise, expected, msg) {
     return promise.then(() => {
       ok(false, msg);
-    }, () => {
-      ok(true, msg);
+    }, actual => {
+      let matched = false;
+      if (Object.prototype.toString.call(expected) == "[object RegExp]") {
+        if (expected.test(actual)) {
+          matched = true;
+        }
+      } else if (actual instanceof expected) {
+        matched = true;
+      }
+
+      if (matched) {
+        ok(true, msg);
+      } else {
+        ok(false, `Unexpected exception for "${msg}": ${actual}`);
+      }
     });
   },
 };
 
 /* exported waitForLoad */
 
 function waitForLoad(win) {
   return new Promise(resolve => {
--- a/toolkit/components/extensions/test/mochitest/test_ext_protocolHandlers.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_protocolHandlers.html
@@ -167,17 +167,19 @@ add_task(async function test_protocolHan
         },
       ],
     },
   };
 
   consoleMonitor.start([{message: /processing protocol_handlers\.0\.protocol/}]);
 
   let extension = ExtensionTestUtils.loadExtension(extensionData);
-  await Assert.rejects(extension.startup(), "unable to register restricted handler protocol");
+  await Assert.rejects(extension.startup(),
+                       /startup failed/,
+                       "unable to register restricted handler protocol");
 
   await consoleMonitor.finished();
 });
 
 add_task(async function test_protocolHandler_restricted_uriTemplate() {
   let extensionData = {
     manifest: {
       "protocol_handlers": [
@@ -188,17 +190,19 @@ add_task(async function test_protocolHan
         },
       ],
     },
   };
 
   consoleMonitor.start([{message: /processing protocol_handlers\.0\.uriTemplate/}]);
 
   let extension = ExtensionTestUtils.loadExtension(extensionData);
-  await Assert.rejects(extension.startup(), "unable to register restricted handler uriTemplate");
+  await Assert.rejects(extension.startup(),
+                       /startup failed/,
+                       "unable to register restricted handler uriTemplate");
 
   await consoleMonitor.finished();
 });
 
 add_task(async function test_protocolHandler_duplicate() {
   let extensionData = {
     manifest: {
       "protocol_handlers": [
--- a/toolkit/components/extensions/test/mochitest/test_ext_webrequest_auth.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_webrequest_auth.html
@@ -103,17 +103,19 @@ add_task(async function test_webRequest_
     sendAsyncMessage("chrome-ready");
   });
   await chromeScript.promiseOneMessage("chrome-ready");
   let callbackComplete = chromeScript.promiseOneMessage("callback-complete");
 
   let handlingExt = getAuthHandler();
   await handlingExt.startup();
 
-  await Assert.rejects(testXHR(`${baseUrl}?realm=auth_nonblocking_forwardAuth&user=auth_nonblocking_forwardAuth&pass=auth_nonblocking_forwardAuth`), "caught rejected xhr");
+  await Assert.rejects(testXHR(`${baseUrl}?realm=auth_nonblocking_forwardAuth&user=auth_nonblocking_forwardAuth&pass=auth_nonblocking_forwardAuth`),
+                       ProgressEvent,
+                       "caught rejected xhr");
 
   await callbackComplete;
   await handlingExt.awaitMessage("onAuthRequired");
   // We expect onErrorOccurred because the "default" authprompt above cancelled
   // the auth request to avoid a dialog.
   await handlingExt.awaitMessage("onErrorOccurred");
   await handlingExt.unload();
   chromeScript.destroy();
@@ -157,17 +159,19 @@ add_task(async function test_webRequest_
     sendAsyncMessage("chrome-ready");
   });
   await chromeScript.promiseOneMessage("chrome-ready");
   let callbackComplete = chromeScript.promiseOneMessage("callback-complete");
 
   let handlingExt = getAuthHandler();
   await handlingExt.startup();
 
-  await Assert.rejects(testXHR(`${baseUrl}?realm=auth_nonblocking_forwardAuthPromptProvider&user=auth_nonblocking_forwardAuth&pass=auth_nonblocking_forwardAuth`), "caught rejected xhr");
+  await Assert.rejects(testXHR(`${baseUrl}?realm=auth_nonblocking_forwardAuthPromptProvider&user=auth_nonblocking_forwardAuth&pass=auth_nonblocking_forwardAuth`),
+                       ProgressEvent,
+                       "caught rejected xhr");
 
   await callbackComplete;
   await handlingExt.awaitMessage("onAuthRequired");
   // We expect onErrorOccurred because the "default" authprompt above cancelled
   // the auth request to avoid a dialog.
   await handlingExt.awaitMessage("onErrorOccurred");
   await handlingExt.unload();
   chromeScript.destroy();
--- a/toolkit/components/extensions/test/xpcshell/test_ext_contexts.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_contexts.js
@@ -152,26 +152,25 @@ add_task(async function test_stringify_i
   let context = new Context(PRINCIPAL1);
   let sandbox = context.sandbox;
   let sandbox2 = Cu.Sandbox(PRINCIPAL2);
 
   Cu.waiveXrays(sandbox).subobj = Cu.evalInSandbox("({ subobject: true })", sandbox2);
   let obj = Cu.evalInSandbox("({ local: true, nested: subobj })", sandbox);
   Assert.throws(() => {
     context.jsonStringify(obj);
-  });
+  }, /Permission denied to access property "toJSON"/);
 });
 
 add_task(async function test_stringify_accessible() {
   // Test that an accessible property from another global is included
   let principal = Cu.getObjectPrincipal(Cu.Sandbox([PRINCIPAL1, PRINCIPAL2]));
   let context = new Context(principal);
   let sandbox = context.sandbox;
   let sandbox2 = Cu.Sandbox(PRINCIPAL2);
 
   Cu.waiveXrays(sandbox).subobj = Cu.evalInSandbox("({ subobject: true })", sandbox2);
   let obj = Cu.evalInSandbox("({ local: true, nested: subobj })", sandbox);
   let stringified = context.jsonStringify(obj);
 
   let expected = JSON.stringify({local: true, nested: {subobject: true}});
   equal(stringified, expected, "Stringified object with accessible property is as expected");
 });
-
--- a/toolkit/components/extensions/test/xpcshell/test_ext_schemas.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_schemas.js
@@ -1728,15 +1728,15 @@ add_task(async function testReturns() {
   Schemas.inject(root, localWrapper);
 
   deepEqual(root.returns.complete(), {size: 3, colour: "orange"});
   deepEqual(root.returns.optional(), {size: 4},
             "Missing optional properties is allowed");
 
   if (AppConstants.DEBUG) {
     Assert.throws(() => root.returns.invalid(),
-                  `Type error for result value (Property "size" is required)`,
+                  /Type error for result value (Property "size" is required)/,
                   "Should throw for invalid result in DEBUG builds");
   } else {
     deepEqual(root.returns.invalid(), {},
               "Doesn't throw for invalid result value in release builds");
   }
 });
--- a/toolkit/components/extensions/test/xpcshell/test_ext_schemas_async.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_schemas_async.js
@@ -185,17 +185,17 @@ add_task(async function testCheckAsyncRe
   deepEqual(await complete.async_result(), {size: 5, colour: "green"});
 
   deepEqual(await optional.async_result(), {size: 6},
             "Missing optional properties is allowed");
 
   if (AppConstants.DEBUG) {
     await Assert.rejects(
       invalid.async_result(),
-      `Type error for widget value (Property "size" is required)`,
+      /Type error for widget value (Property "size" is required)/,
       "Should throw for invalid callback argument in DEBUG builds");
   } else {
     deepEqual(await invalid.async_result(), {},
               "Invalid callback argument doesn't throw in release builds");
   }
 });
 
 add_task(async function testAsyncResults() {
--- a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository.js
@@ -253,17 +253,18 @@ add_task(async function test_1() {
   });
 });
 
 // Tests failure of AddonRepository.getAddonsByIDs()
 add_task(async function test_getAddonsByID_fails() {
   Services.prefs.setCharPref(GET_TEST.preference, GET_TEST.preferenceValue);
 
   await Assert.rejects(
-    AddonRepository.getAddonsByIDs(GET_TEST.failedIDs));
+    AddonRepository.getAddonsByIDs(GET_TEST.failedIDs),
+    /Error: GET.*?failed/);
 });
 
 // Tests success of AddonRepository.getAddonsByIDs()
 add_task(async function test_getAddonsByID_succeeds() {
   let result = await AddonRepository.getAddonsByIDs(GET_TEST.successfulIDs);
 
   check_results(result, GET_RESULTS);
 });
--- a/toolkit/mozapps/extensions/test/xpcshell/test_LightweightThemeManager.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_LightweightThemeManager.js
@@ -543,18 +543,20 @@ add_task(async function run_test() {
   Assert.equal([...ltm._builtInThemes].length, 2);
   Assert.equal(ltm.usedThemes.length, 3);
   Assert.equal(ltm.usedThemes[0].id, "x0");
   Assert.equal(ltm.currentTheme.id, "x0");
   Assert.equal(ltm.usedThemes[1].id, "builtInTheme0");
   Assert.equal(ltm.usedThemes[2].id, "builtInTheme1");
 
   Assert.throws(() => { ltm.addBuiltInTheme(dummy("builtInTheme0")); },
+    /Error: Trying to add invalid builtIn theme/,
     "Exception is thrown adding a duplicate theme");
   Assert.throws(() => { ltm.addBuiltInTheme("not a theme object"); },
+    /Error: Trying to add invalid builtIn theme/,
     "Exception is thrown adding an invalid theme");
 
   let x0Addon = await AddonManager.getAddonByID("x0@personas.mozilla.org");
   Assert.equal(hasPermission(x0Addon, "uninstall"), true);
   Assert.equal(hasPermission(x0Addon, "disable"), true);
   Assert.equal(hasPermission(x0Addon, "enable"), false);
 
   ltm.forgetUsedTheme("x0");
--- a/toolkit/mozapps/extensions/test/xpcshell/test_bootstrapped_chrome_manifest.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_bootstrapped_chrome_manifest.js
@@ -30,17 +30,17 @@ function checkActive(expected) {
   let target = { active: false };
   let load = () => {
     Services.scriptloader.loadSubScript("chrome://bug675371/content/test.js", target);
   };
 
   if (expected) {
     load();
   } else {
-    Assert.throws(load);
+    Assert.throws(load, /Error opening input stream/);
   }
   equal(target.active, expected, "Manifest is active?");
 }
 
 add_task(async function test() {
   let {addon} = await AddonTestUtils.promiseInstallXPI(ADDON);
 
   Assert.ok(addon.isActive);
--- a/toolkit/mozapps/extensions/test/xpcshell/test_corrupt.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_corrupt.js
@@ -266,23 +266,23 @@ add_task(async function test_after_corru
   // Accessing the add-ons should open and recover the database
   info("Test add-on state after corruption");
   let addons = await getAddons(IDS);
   for (let [id, addon] of Object.entries(ADDONS)) {
     checkAddon(id, addons.get(id),
                Object.assign({}, addon.desiredState, addon.afterCorruption));
   }
 
-  await Assert.rejects(promiseShutdownManager());
+  await Assert.rejects(promiseShutdownManager(), OS.File.Error);
 });
 
 add_task(async function test_after_second_restart() {
   await promiseStartupManager();
 
   info("Test add-on state after second restart");
   let addons = await getAddons(IDS);
   for (let [id, addon] of Object.entries(ADDONS)) {
     checkAddon(id, addons.get(id),
                Object.assign({}, addon.desiredState, addon.afterSecondRestart));
   }
 
-  await Assert.rejects(promiseShutdownManager());
+  await Assert.rejects(promiseShutdownManager(), OS.File.Error);
 });
--- a/toolkit/mozapps/extensions/test/xpcshell/test_dictionary_webextension.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_dictionary_webextension.js
@@ -20,32 +20,32 @@ add_task(async function test_validation(
   await Assert.rejects(
     promiseInstallWebExtension({
       manifest: {
         applications: {gecko: {id: "en-US-no-dic@dictionaries.mozilla.org"}},
         "dictionaries": {
           "en-US": "en-US.dic",
         },
       },
-    })
+    }), /Expected file to be downloaded for install/
   );
 
   await Assert.rejects(
     promiseInstallWebExtension({
       manifest: {
         applications: {gecko: {id: "en-US-no-aff@dictionaries.mozilla.org"}},
         "dictionaries": {
           "en-US": "en-US.dic",
         },
       },
 
       files: {
         "en-US.dic": "",
       },
-    })
+    }), /Expected file to be downloaded for install/
   );
 
   let addon = await promiseInstallWebExtension({
     manifest: {
       applications: {gecko: {id: "en-US-1@dictionaries.mozilla.org"}},
       "dictionaries": {
         "en-US": "en-US.dic",
       },