Bug 1461997 - Add an ESLint rule to ensure that Assert.rejects is preceeded by await. r?Mossop draft
authorMark Banner <standard8@mozilla.com>
Wed, 16 May 2018 21:04:13 +0100
changeset 796214 8f6e259568a597d3d6513670ef650e70f7362d7d
parent 796213 0dc8759946cfc268d77abb31dc785d57a4cddfd2
push id110181
push userbmo:standard8@mozilla.com
push dateThu, 17 May 2018 08:34:08 +0000
reviewersMossop
bugs1461997
milestone62.0a1
Bug 1461997 - Add an ESLint rule to ensure that Assert.rejects is preceeded by await. r?Mossop MozReview-Commit-ID: kVrHRIi9l6
.eslintrc.js
tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js
tools/lint/eslint/eslint-plugin-mozilla/lib/index.js
tools/lint/eslint/eslint-plugin-mozilla/lib/rules/rejects-requires-await.js
tools/lint/eslint/eslint-plugin-mozilla/tests/rejects-requires-await.js
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -61,10 +61,20 @@ module.exports = {
       "testing/marionette/test/unit/**",
       "toolkit/components/**",
       "toolkit/modules/tests/xpcshell/**",
       "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": [
+      "services/fxaccounts/**",
+      "toolkit/components/**",
+    ],
+    "rules": {
+      "mozilla/rejects-requires-await": "off",
+    }
   }]
 };
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js
@@ -171,16 +171,17 @@ module.exports = {
     "mozilla/avoid-removeChild": "error",
     "mozilla/import-browser-window-globals": "error",
     "mozilla/import-globals": "error",
     "mozilla/no-compare-against-boolean-literals": "error",
     "mozilla/no-define-cc-etc": "error",
     "mozilla/no-import-into-var-and-global": "error",
     "mozilla/no-useless-parameters": "error",
     "mozilla/no-useless-removeEventListener": "error",
+    "mozilla/rejects-requires-await": "error",
     "mozilla/require-expected-throws-or-rejects": "error",
     "mozilla/use-cc-etc": "error",
     "mozilla/use-chromeutils-generateqi": "error",
     "mozilla/use-chromeutils-import": "error",
     "mozilla/use-default-preference-values": "error",
     "mozilla/use-includes-instead-of-indexOf": "error",
     "mozilla/use-ownerGlobal": "error",
     "mozilla/use-services": "error",
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js
@@ -54,16 +54,17 @@ module.exports = {
       require("../lib/rules/no-useless-removeEventListener"),
     "no-useless-run-test":
       require("../lib/rules/no-useless-run-test"),
     "require-expected-throws-or-rejects":
       require("../lib/rules/require-expected-throws-or-rejects"),
     "reject-importGlobalProperties":
       require("../lib/rules/reject-importGlobalProperties"),
     "reject-some-requires": require("../lib/rules/reject-some-requires"),
+    "rejects-requires-await": require("../lib/rules/rejects-requires-await"),
     "use-cc-etc": require("../lib/rules/use-cc-etc"),
     "use-chromeutils-generateqi": require("../lib/rules/use-chromeutils-generateqi"),
     "use-chromeutils-import": require("../lib/rules/use-chromeutils-import"),
     "use-default-preference-values":
       require("../lib/rules/use-default-preference-values"),
     "use-ownerGlobal": require("../lib/rules/use-ownerGlobal"),
     "use-includes-instead-of-indexOf": require("../lib/rules/use-includes-instead-of-indexOf"),
     "use-services": require("../lib/rules/use-services"),
new file mode 100644
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/rejects-requires-await.js
@@ -0,0 +1,40 @@
+/**
+ * @fileoverview Reject use of Cu.importGlobalProperties
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+"use strict";
+
+module.exports = {
+  meta: {
+    messages: {
+      rejectRequiresAwait: "Assert.rejects needs to be preceded by await."
+    }
+  },
+
+  create(context) {
+    return {
+      "CallExpression": function(node) {
+        if (node.callee.type === "MemberExpression") {
+          let memexp = node.callee;
+          if (memexp.object.type === "Identifier" &&
+              memexp.object.name === "Assert" &&
+              memexp.property.type === "Identifier" &&
+              memexp.property.name === "rejects") {
+            // We have ourselves an Assert.rejects.
+
+            if (node.parent.type !== "AwaitExpression") {
+              context.report({
+                node,
+                messageId: "rejectRequiresAwait"
+              });
+            }
+          }
+        }
+      }
+    };
+  }
+};
new file mode 100644
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/rejects-requires-await.js
@@ -0,0 +1,32 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/rejects-requires-await");
+var RuleTester = require("eslint/lib/testers/rule-tester");
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 8 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code, messageId) {
+  return {code, errors: [{messageId: "rejectRequiresAwait"}]};
+}
+
+ruleTester.run("reject-requires-await", rule, {
+  valid: [
+    "async() => { await Assert.rejects(foo, /assertion/) }",
+    "async() => { await Assert.rejects(foo, /assertion/, 'msg') }"
+  ],
+  invalid: [
+    invalidCode("Assert.rejects(foo)"),
+    invalidCode("Assert.rejects(foo, 'msg')")
+  ]
+});