Repository: eslint/eslint
Pull request #9664 (2017-11-29 03:54:03)

Update: Support JSXFragment node
**What is the purpose of this pull request? (put an "X" next to item)**

[ ] Documentation update
[ ] Bug fix ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/bug-report.md))
[ ] New rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-proposal.md))
[ x ] Changes an existing rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-change-proposal.md))
[ ] Add autofixing to a rule
[ ] Add a CLI option
[ ] Add something to the core
[ ] Other, please explain:

**What changes did you make? (Give an overview)**

This is related to https://github.com/eslint/eslint/issues/9662.
Currently, when a parser, such as `babel-eslint` is used, it'll now return `JSXFragment`. This PR updates some standard rules to add some support for fragments so that `JSXFragment`s can generally be used in the place of `JSXElement`.

**Current behavior example**

```
<>foo</>;
```

warns that foo should be wrapped in quotes, using the options:

```
"parser": "babel-eslint",
"rules": { "quotes": [ "error", "single" ] }
```

**Behavior with my changes**

```
<>foo</>;
```

doesn't give any warnings!

**Rationale**

I'm just throwing this out here because I'm not really sure if this is a change makes sense to make in this repo at this point in time. This is only applicable when an external parser is specified. If this makes sense, then I can refine the PR. 🙂 










ilyavolodin: I think Acorn JSX plugin has already been updated to support JSX fragments, so we should have native support for them with the next release of Espree. However, I have no idea what they are supposed to do, so I can't comment on if it makes sense to add this to the rule.
platinumazure: @ilyavolodin Are we any closer to being able to support JSXFragment in espree? (Is that something we definitely want to do?)
ilyavolodin: @platinumazure As far as I understand it, JSXFragment is officially part of the JSX spec, so we should probably support it. However, it looks like we can't upgrade Acorn to the latest version yet, because there are some breaking changes. I think we might have to implement it in Espree ourselves.
Aladdin-ADD: seems this is no longer blocked, since https://github.com/eslint/espree/pull/371 merged.
platinumazure: Hi @clemmy, after a long time, it seems we are ready to look at this again. (We needed to do a breaking change with acorn-jsx and so align this with the ESLint major release-- finally we are doing release candidates.)

At this point, it looks like we need some unit tests (per Ilya's review), and we also need you to fix the commit message. My recommendation is to just push some new commits (with the new unit tests and any other changes you might make), and then edit the PR title to follow our commit message guidelines.

Please let us know if we can help with anything, either by leaving a comment here or by visiting us in our [Gitter chat](https://gitter.im/eslint/eslint).

Thanks again for contributing. Let's get this in! :smile:
clemmy: Hi @platinumazure, sorry for the delayed response! I’ve been busy for the past few weeks and probably won’t have any time to dive into this for another couple of weeks. I’m wondering if there is currently any progress being made here or if anyone else wants to continue this work? If not, I’d be happy to pick this issue up again in a few weeks’ time. :)
clemmy: Ready for review again.

I updated this PR from last time by adding some unit tests, then rebasing & squashing it into 2 commits -- one for lib changes and one for unit test changes.

Patch:
diff --git a/.travis.yml b/.travis.yml
index 5763f04af..ff3e956a7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,6 +3,7 @@ node_js:
     - "6"
     - "8"
     - "9"
+    - "10"
 sudo: false
 branches:
     only:
diff --git a/bin/eslint.js b/bin/eslint.js
index 1255e3d8b..adc07c2e7 100755
--- a/bin/eslint.js
+++ b/bin/eslint.js
@@ -56,7 +56,15 @@ process.once("uncaughtException", err => {
 });
 
 if (useStdIn) {
-    process.exitCode = cli.execute(process.argv, fs.readFileSync(process.stdin.fd, "utf8"));
+
+    /*
+     * Note: `process.stdin.fd` is not used here due to https://github.com/nodejs/node/issues/7439.
+     * Accessing the `process.stdin` property seems to modify the behavior of file descriptor 0, resulting
+     * in an error when stdin is piped in asynchronously.
+     */
+    const STDIN_FILE_DESCRIPTOR = 0;
+
+    process.exitCode = cli.execute(process.argv, fs.readFileSync(STDIN_FILE_DESCRIPTOR, "utf8"));
 } else if (init) {
     const configInit = require("../lib/config/config-initializer");
 
diff --git a/docs/rules/array-element-newline.md b/docs/rules/array-element-newline.md
index 21d957101..6a3a66e1d 100644
--- a/docs/rules/array-element-newline.md
+++ b/docs/rules/array-element-newline.md
@@ -12,6 +12,7 @@ This rule has either a string option:
 
 * `"always"` (default) requires line breaks between array elements
 * `"never"` disallows line breaks between array elements
+* `"consistent"` requires consistent usage of linebreaks between array elements
 
 Or an object option (Requires line breaks if any of properties is satisfied. Otherwise, disallows line breaks):
 
@@ -102,6 +103,69 @@ var e = [
 ];
 ```
 
+### consistent
+
+Examples of **incorrect** code for this rule with the `"consistent"` option:
+
+```js
+/*eslint array-element-newline: ["error", "consistent"]*/
+
+var a = [
+    1, 2,
+    3
+];
+var b = [
+    function foo() {
+        dosomething();
+    }, function bar() {
+        dosomething();
+    },
+    function baz() {
+        dosomething();
+    }
+];
+```
+
+Examples of **correct** code for this rule with the `"consistent"` option:
+
+```js
+/*eslint array-element-newline: ["error", "consistent"]*/
+
+var a = [];
+var b = [1];
+var c = [1, 2];
+var d = [1, 2, 3];
+var e = [
+    1,
+    2
+];
+var f = [
+    1,
+    2,
+    3
+];
+var g = [
+    function foo() {
+        dosomething();
+    }, function bar() {
+        dosomething();
+    }, function baz() {
+        dosomething();
+    }
+];
+var h = [
+    function foo() {
+        dosomething();
+    },
+    function bar() {
+        dosomething();
+    },
+    function baz() {
+        dosomething();
+    }
+];
+```
+
 ### multiline
 
 Examples of **incorrect** code for this rule with the `{ "multiline": true }` option:
diff --git a/lib/config/config-initializer.js b/lib/config/config-initializer.js
index bbeb405d0..ab06909d8 100644
--- a/lib/config/config-initializer.js
+++ b/lib/config/config-initializer.js
@@ -82,12 +82,12 @@ function getPeerDependencies(moduleName) {
 getPeerDependencies.cache = new Map();
 
 /**
- * Synchronously install necessary plugins, configs, parsers, etc. based on the config
+ * Return necessary plugins, configs, parsers, etc. based on the config
  * @param   {Object} config  config object
  * @param   {boolean} [installESLint=true]  If `false` is given, it does not install eslint.
- * @returns {void}
+ * @returns {string[]} An array of modules to be installed.
  */
-function installModules(config, installESLint) {
+function getModulesList(config, installESLint) {
     const modules = {};
 
     // Create a list of modules which should be installed based on config
@@ -106,11 +106,6 @@ function installModules(config, installESLint) {
         );
     }
 
-    // If no modules, do nothing.
-    if (Object.keys(modules).length === 0) {
-        return;
-    }
-
     if (installESLint === false) {
         delete modules.eslint;
     } else {
@@ -124,12 +119,7 @@ function installModules(config, installESLint) {
         }
     }
 
-    // Install packages
-    const modulesToInstall = Object.keys(modules).map(name => `${name}@${modules[name]}`);
-
-    log.info(`Installing ${modulesToInstall.join(", ")}`);
-
-    npmUtil.installSyncSaveDev(modulesToInstall);
+    return Object.keys(modules).map(name => `${name}@${modules[name]}`);
 }
 
 /**
@@ -282,8 +272,6 @@ function processAnswers(answers) {
         config.rules.semi = ["error", answers.semi ? "always" : "never"];
     }
 
-    installModules(config);
-
     if (answers.source === "auto") {
         config = configureRules(answers, config);
         config = autoconfig.extendFromRecommended(config);
@@ -296,10 +284,9 @@ function processAnswers(answers) {
 /**
  * process user's style guide of choice and return an appropriate config object.
  * @param {string} guide name of the chosen style guide
- * @param {boolean} [installESLint=true]  If `false` is given, it does not install eslint.
  * @returns {Object} config object
  */
-function getConfigForStyleGuide(guide, installESLint) {
+function getConfigForStyleGuide(guide) {
     const guides = {
         google: { extends: "google" },
         airbnb: { extends: "airbnb" },
@@ -311,8 +298,6 @@ function getConfigForStyleGuide(guide, installESLint) {
         throw new Error("You referenced an unsupported guide.");
     }
 
-    installModules(guides[guide], installESLint);
-
     return guides[guide];
 }
 
@@ -380,7 +365,50 @@ function hasESLintVersionConflict(answers) {
     return true;
 }
 
-/* istanbul ignore next: no need to test inquirer*/
+/**
+ * Install modules.
+ * @param   {string[]} modules Modules to be installed.
+ * @returns {void}
+ */
+function installModules(modules) {
+    log.info(`Installing ${modules.join(", ")}`);
+    npmUtil.installSyncSaveDev(modules);
+}
+
+/* istanbul ignore next: no need to test inquirer */
+/**
+ * Ask user to install modules.
+ * @param   {string[]} modules Array of modules to be installed.
+ * @param   {boolean} packageJsonExists Indicates if package.json is existed.
+ * @returns {Promise} Answer that indicates if user wants to install.
+ */
+function askInstallModules(modules, packageJsonExists) {
+
+    // If no modules, do nothing.
+    if (modules.length === 0) {
+        return Promise.resolve();
+    }
+
+    log.info("The config that you've selected requires the following dependencies:\n");
+    log.info(modules.join(" "));
+    return inquirer.prompt([
+        {
+            type: "confirm",
+            name: "executeInstallation",
+            message: "Would you like to install them now with npm?",
+            default: true,
+            when() {
+                return modules.length && packageJsonExists;
+            }
+        }
+    ]).then(({ executeInstallation }) => {
+        if (executeInstallation) {
+            installModules(modules);
+        }
+    });
+}
+
+/* istanbul ignore next: no need to test inquirer */
 /**
  * Ask use a few questions on command prompt
  * @returns {Promise} The promise with the result of the prompt
@@ -476,11 +504,11 @@ function promptUser() {
                 earlyAnswers.styleguide = "airbnb-base";
             }
 
-            const config = getConfigForStyleGuide(earlyAnswers.styleguide, earlyAnswers.installESLint);
-
-            writeFile(config, earlyAnswers.format);
+            const config = getConfigForStyleGuide(earlyAnswers.styleguide);
+            const modules = getModulesList(config);
 
-            return void 0;
+            return askInstallModules(modules, earlyAnswers.packageJsonExists)
+                .then(() => writeFile(config, earlyAnswers.format));
         }
 
         // continue with the questions otherwise...
@@ -539,10 +567,9 @@ function promptUser() {
 
                 const config = processAnswers(combinedAnswers);
 
-                installModules(config);
-                writeFile(config, earlyAnswers.format);
+                const modules = getModulesList(config);
 
-                return void 0;
+                return askInstallModules(modules).then(() => writeFile(config, earlyAnswers.format));
             }
 
             // continue with the style questions otherwise...
@@ -585,9 +612,9 @@ function promptUser() {
                 const totalAnswers = Object.assign({}, earlyAnswers, secondAnswers, answers);
 
                 const config = processAnswers(totalAnswers);
+                const modules = getModulesList(config);
 
-                installModules(config);
-                writeFile(config, answers.format);
+                return askInstallModules(modules).then(() => writeFile(config, earlyAnswers.format));
             });
         });
     });
@@ -599,7 +626,9 @@ function promptUser() {
 
 const init = {
     getConfigForStyleGuide,
+    getModulesList,
     hasESLintVersionConflict,
+    installModules,
     processAnswers,
     /* istanbul ignore next */initializeConfig() {
         return promptUser();
diff --git a/lib/rules/array-element-newline.js b/lib/rules/array-element-newline.js
index 359b8d436..b437c6932 100644
--- a/lib/rules/array-element-newline.js
+++ b/lib/rules/array-element-newline.js
@@ -24,7 +24,7 @@ module.exports = {
             {
                 oneOf: [
                     {
-                        enum: ["always", "never"]
+                        enum: ["always", "never", "consistent"]
                     },
                     {
                         type: "object",
@@ -63,6 +63,7 @@ module.exports = {
          * @returns {{multiline: boolean, minItems: number}} Normalized option object.
          */
         function normalizeOptionValue(providedOption) {
+            let consistent = false;
             let multiline = false;
             let minItems;
 
@@ -72,12 +73,15 @@ module.exports = {
                 minItems = 0;
             } else if (option === "never") {
                 minItems = Number.POSITIVE_INFINITY;
+            } else if (option === "consistent") {
+                consistent = true;
+                minItems = Number.POSITIVE_INFINITY;
             } else {
                 multiline = Boolean(option.multiline);
                 minItems = option.minItems || Number.POSITIVE_INFINITY;
             }
 
-            return { multiline, minItems };
+            return { consistent, multiline, minItems };
         }
 
         /**
@@ -193,11 +197,30 @@ module.exports = {
                     .some(element => element.loc.start.line !== element.loc.end.line);
             }
 
+            const linebreaksCount = node.elements.map((element, i) => {
+                const previousElement = elements[i - 1];
+
+                if (i === 0 || element === null || previousElement === null) {
+                    return false;
+                }
+
+                const commaToken = sourceCode.getFirstTokenBetween(previousElement, element, astUtils.isCommaToken);
+                const lastTokenOfPreviousElement = sourceCode.getTokenBefore(commaToken);
+                const firstTokenOfCurrentElement = sourceCode.getTokenAfter(commaToken);
+
+                return !astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement);
+            }).filter(isBreak => isBreak === true).length;
+
             const needsLinebreaks = (
                 elements.length >= options.minItems ||
                 (
                     options.multiline &&
                     elementBreak
+                ) ||
+                (
+                    options.consistent &&
+                    linebreaksCount > 0 &&
+                    linebreaksCount < node.elements.length
                 )
             );
 
diff --git a/lib/rules/no-extra-parens.js b/lib/rules/no-extra-parens.js
index 9765dfa77..3d4ee19e8 100644
--- a/lib/rules/no-extra-parens.js
+++ b/lib/rules/no-extra-parens.js
@@ -86,7 +86,7 @@ module.exports = {
          * @private
          */
         function ruleApplies(node) {
-            if (node.type === "JSXElement") {
+            if (node.type === "JSXElement" || node.type === "JSXFragment") {
                 const isSingleLine = node.loc.start.line === node.loc.end.line;
 
                 switch (IGNORE_JSX) {
diff --git a/lib/rules/no-useless-escape.js b/lib/rules/no-useless-escape.js
index efc9706f4..2ddab7854 100644
--- a/lib/rules/no-useless-escape.js
+++ b/lib/rules/no-useless-escape.js
@@ -174,7 +174,7 @@ module.exports = {
                  * JSXAttribute doesn't have any escape sequence: https://facebook.github.io/jsx/.
                  * In addition, backticks are not supported by JSX yet: https://github.com/facebook/jsx/issues/25.
                  */
-                if (node.parent.type === "JSXAttribute" || node.parent.type === "JSXElement") {
+                if (node.parent.type === "JSXAttribute" || node.parent.type === "JSXElement" || node.parent.type === "JSXFragment") {
                     return;
                 }
 
diff --git a/lib/rules/one-var.js b/lib/rules/one-var.js
index 70223dd2c..412fe615d 100644
--- a/lib/rules/one-var.js
+++ b/lib/rules/one-var.js
@@ -293,7 +293,11 @@ module.exports = {
                 const res = [];
 
                 if (previousNode && previousNode.kind === sourceCode.getText(type)) {
-                    res.push(fixer.replaceText(prevSemi, ","));
+                    if (prevSemi.value === ";") {
+                        res.push(fixer.replaceText(prevSemi, ","));
+                    } else {
+                        res.push(fixer.insertTextAfter(prevSemi, ","));
+                    }
                     res.push(fixer.replaceText(type, ""));
                 }
 
diff --git a/lib/rules/quotes.js b/lib/rules/quotes.js
index fa8bbae5f..78794e72b 100644
--- a/lib/rules/quotes.js
+++ b/lib/rules/quotes.js
@@ -132,6 +132,7 @@ module.exports = {
          *
          * - `<div className="foo"></div>` ... If the literal is an attribute value, the parent of the literal is `JSXAttribute`.
          * - `<div>foo</div>` ... If the literal is a text content, the parent of the literal is `JSXElement`.
+         * - `<>foo</>` ... If the literal is a text content, the parent of the literal is `JSXFragment`.
          *
          * In particular, this function returns `false` in the following cases:
          *
@@ -146,7 +147,7 @@ module.exports = {
          * @private
          */
         function isJSXLiteral(node) {
-            return node.parent.type === "JSXAttribute" || node.parent.type === "JSXElement";
+            return node.parent.type === "JSXAttribute" || node.parent.type === "JSXElement" || node.parent.type === "JSXFragment";
         }
 
         /**


Test patch:
diff --git a/tests/.eslintrc.yml b/tests/.eslintrc.yml
index 9808c3b2b..f2531eaa4 100644
--- a/tests/.eslintrc.yml
+++ b/tests/.eslintrc.yml
@@ -1,2 +1,8 @@
 env:
   mocha: true
+
+rules:
+  no-restricted-syntax:
+    - error
+    - selector: "CallExpression[callee.object.name='assert'][callee.property.name='doesNotThrow']"
+      message: "`assert.doesNotThrow()` should be replaced with a comment next to the code."
diff --git a/tests/bin/eslint.js b/tests/bin/eslint.js
index a48ef6745..75e7c2c4b 100644
--- a/tests/bin/eslint.js
+++ b/tests/bin/eslint.js
@@ -152,6 +152,17 @@ describe("bin/eslint.js", () => {
             }
         );
 
+        it("successfully reads from an asynchronous pipe", () => {
+            const child = runESLint(["--stdin", "--no-eslintrc"]);
+
+            child.stdin.write("var foo = bar;\n");
+            return new Promise(resolve => setTimeout(resolve, 300)).then(() => {
+                child.stdin.write("var baz = qux;\n");
+                child.stdin.end();
+
+                return assertExitCode(child, 0);
+            });
+        });
     });
 
     describe("running on files", () => {
@@ -221,11 +232,8 @@ describe("bin/eslint.js", () => {
                 return assertExitCode(child, 0).then(() => {
                     assert.isTrue(fs.existsSync(CACHE_PATH), "Cache file should exist at the given location");
 
-                    assert.doesNotThrow(
-                        () => JSON.parse(fs.readFileSync(CACHE_PATH, "utf8")),
-                        SyntaxError,
-                        "Cache file should contain valid JSON"
-                    );
+                    // Cache file should contain valid JSON
+                    JSON.parse(fs.readFileSync(CACHE_PATH, "utf8"));
                 });
             });
         });
@@ -289,11 +297,9 @@ describe("bin/eslint.js", () => {
 
                 return assertExitCode(child, 0).then(() => {
                     assert.isTrue(fs.existsSync(CACHE_PATH), "Cache file should exist at the given location");
-                    assert.doesNotThrow(
-                        () => JSON.parse(fs.readFileSync(CACHE_PATH, "utf8")),
-                        SyntaxError,
-                        "Cache file should contain valid JSON"
-                    );
+
+                    // Cache file should contain valid JSON
+                    JSON.parse(fs.readFileSync(CACHE_PATH, "utf8"));
                 });
             });
 
diff --git a/tests/lib/cli.js b/tests/lib/cli.js
index 2abf0d0ef..53e80ba43 100644
--- a/tests/lib/cli.js
+++ b/tests/lib/cli.js
@@ -128,9 +128,7 @@ describe("cli", () => {
             const configPath = getFixturePath(".eslintrc");
             const filePath = getFixturePath("passing.js");
 
-            assert.doesNotThrow(() => {
-                cli.execute(`--config ${configPath} ${filePath}`);
-            });
+            cli.execute(`--config ${configPath} ${filePath}`);
         });
     });
 
@@ -142,10 +140,6 @@ describe("cli", () => {
             // Mock CWD
             process.eslintCwd = getFixturePath("configurations", "single-quotes");
 
-            assert.doesNotThrow(() => {
-                cli.execute(code);
-            });
-
             cli.execute(code);
 
             process.eslintCwd = null;
@@ -170,11 +164,7 @@ describe("cli", () => {
             const filePath = getFixturePath("formatters");
             const code = `--config ${configPath} ${filePath}`;
 
-            let exitStatus;
-
-            assert.doesNotThrow(() => {
-                exitStatus = cli.execute(code);
-            });
+            const exitStatus = cli.execute(code);
 
             assert.strictEqual(exitStatus, 0);
         });
diff --git a/tests/lib/config.js b/tests/lib/config.js
index 6baae0e05..acf68e258 100644
--- a/tests/lib/config.js
+++ b/tests/lib/config.js
@@ -1046,9 +1046,7 @@ describe("Config", () => {
                     useEslintrc: false
                 }, linter);
 
-                assert.doesNotThrow(() => {
-                    config.getConfig(filePath);
-                }, "No ESLint configuration found");
+                config.getConfig(filePath);
             });
 
             it("should not throw an error if no local config and no personal config was found but rules are specified", () => {
@@ -1067,9 +1065,7 @@ describe("Config", () => {
                     rules: { quotes: [2, "single"] }
                 }, linter);
 
-                assert.doesNotThrow(() => {
-                    config.getConfig(filePath);
-                }, "No ESLint configuration found");
+                config.getConfig(filePath);
             });
 
             it("should not throw an error if no local config and no personal config was found but baseConfig is specified", () => {
@@ -1088,9 +1084,7 @@ describe("Config", () => {
                     baseConfig: {}
                 }, linter);
 
-                assert.doesNotThrow(() => {
-                    config.getConfig(filePath);
-                }, "No ESLint configuration found");
+                config.getConfig(filePath);
             });
         });
 
diff --git a/tests/lib/config/config-initializer.js b/tests/lib/config/config-initializer.js
index 72c7d2e99..579c9a526 100644
--- a/tests/lib/config/config-initializer.js
+++ b/tests/lib/config/config-initializer.js
@@ -200,26 +200,34 @@ describe("configInitializer", () => {
         describe("guide", () => {
             it("should support the google style guide", () => {
                 const config = init.getConfigForStyleGuide("google");
+                const modules = init.getModulesList(config);
 
                 assert.deepStrictEqual(config, { extends: "google", installedESLint: true });
+                assert.include(modules, "eslint-config-google@latest");
             });
 
             it("should support the airbnb style guide", () => {
                 const config = init.getConfigForStyleGuide("airbnb");
+                const modules = init.getModulesList(config);
 
                 assert.deepStrictEqual(config, { extends: "airbnb", installedESLint: true });
+                assert.include(modules, "eslint-config-airbnb@latest");
             });
 
             it("should support the airbnb base style guide", () => {
                 const config = init.getConfigForStyleGuide("airbnb-base");
+                const modules = init.getModulesList(config);
 
                 assert.deepStrictEqual(config, { extends: "airbnb-base", installedESLint: true });
+                assert.include(modules, "eslint-config-airbnb-base@latest");
             });
 
             it("should support the standard style guide", () => {
                 const config = init.getConfigForStyleGuide("standard");
+                const modules = init.getModulesList(config);
 
                 assert.deepStrictEqual(config, { extends: "standard", installedESLint: true });
+                assert.include(modules, "eslint-config-standard@latest");
             });
 
             it("should throw when encountering an unsupported style guide", () => {
@@ -229,19 +237,25 @@ describe("configInitializer", () => {
             });
 
             it("should install required sharable config", () => {
-                init.getConfigForStyleGuide("google");
+                const config = init.getConfigForStyleGuide("google");
+
+                init.installModules(init.getModulesList(config));
                 assert(npmInstallStub.calledOnce);
                 assert(npmInstallStub.firstCall.args[0].some(name => name.startsWith("eslint-config-google@")));
             });
 
             it("should install ESLint if not installed locally", () => {
-                init.getConfigForStyleGuide("google");
+                const config = init.getConfigForStyleGuide("google");
+
+                init.installModules(init.getModulesList(config));
                 assert(npmInstallStub.calledOnce);
                 assert(npmInstallStub.firstCall.args[0].some(name => name.startsWith("eslint@")));
             });
 
             it("should install peerDependencies of the sharable config", () => {
-                init.getConfigForStyleGuide("airbnb");
+                const config = init.getConfigForStyleGuide("airbnb");
+
+                init.installModules(init.getModulesList(config));
 
                 assert(npmFetchPeerDependenciesStub.calledOnce);
                 assert(npmFetchPeerDependenciesStub.firstCall.args[0] === "eslint-config-airbnb@latest");
diff --git a/tests/lib/config/config-validator.js b/tests/lib/config/config-validator.js
index 5d6cf8cc0..76e573472 100644
--- a/tests/lib/config/config-validator.js
+++ b/tests/lib/config/config-validator.js
@@ -107,14 +107,11 @@ describe("Validator", () => {
     describe("validate", () => {
 
         it("should do nothing with an empty config", () => {
-            const fn = validator.validate.bind(null, {}, "tests", ruleMapper, linter.environments);
-
-            assert.doesNotThrow(fn);
+            validator.validate({}, "tests", ruleMapper, linter.environments);
         });
 
         it("should do nothing with a valid eslint config", () => {
-            const fn = validator.validate.bind(
-                null,
+            validator.validate(
                 {
                     root: true,
                     globals: { globalFoo: "bar" },
@@ -130,8 +127,6 @@ describe("Validator", () => {
                 ruleMapper,
                 linter.environments
             );
-
-            assert.doesNotThrow(fn);
         });
 
         it("should throw with an unknown property", () => {
@@ -178,9 +173,7 @@ describe("Validator", () => {
 
         describe("parser", () => {
             it("should not throw with a null value", () => {
-                const fn = validator.validate.bind(null, { parser: null }, null, ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ parser: null }, null, ruleMapper, linter.environments);
             });
         });
 
@@ -211,18 +204,14 @@ describe("Validator", () => {
             });
 
             it("should do nothing with an undefined environment", () => {
-                const fn = validator.validate.bind(null, {}, null, ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({}, null, ruleMapper, linter.environments);
             });
 
         });
 
         describe("plugins", () => {
             it("should not throw with an empty array", () => {
-                const fn = validator.validate.bind(null, { plugins: [] }, null, ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ plugins: [] }, null, ruleMapper, linter.environments);
             });
 
             it("should throw with a string", () => {
@@ -234,9 +223,7 @@ describe("Validator", () => {
 
         describe("settings", () => {
             it("should not throw with an empty object", () => {
-                const fn = validator.validate.bind(null, { settings: {} }, null, ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ settings: {} }, null, ruleMapper, linter.environments);
             });
 
             it("should throw with an array", () => {
@@ -248,15 +235,11 @@ describe("Validator", () => {
 
         describe("extends", () => {
             it("should not throw with an empty array", () => {
-                const fn = validator.validate.bind(null, { extends: [] }, null, ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ extends: [] }, null, ruleMapper, linter.environments);
             });
 
             it("should not throw with a string", () => {
-                const fn = validator.validate.bind(null, { extends: "react" }, null, ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ extends: "react" }, null, ruleMapper, linter.environments);
             });
 
             it("should throw with an object", () => {
@@ -268,9 +251,7 @@ describe("Validator", () => {
 
         describe("parserOptions", () => {
             it("should not throw with an empty object", () => {
-                const fn = validator.validate.bind(null, { parserOptions: {} }, null, ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ parserOptions: {} }, null, ruleMapper, linter.environments);
             });
 
             it("should throw with an array", () => {
@@ -283,63 +264,43 @@ describe("Validator", () => {
         describe("rules", () => {
 
             it("should do nothing with an empty rules object", () => {
-                const fn = validator.validate.bind(null, { rules: {} }, "tests", ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ rules: {} }, "tests", ruleMapper, linter.environments);
             });
 
             it("should do nothing with a valid config with rules", () => {
-                const fn = validator.validate.bind(null, { rules: { "mock-rule": [2, "second"] } }, "tests", ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ rules: { "mock-rule": [2, "second"] } }, "tests", ruleMapper, linter.environments);
             });
 
             it("should do nothing with a valid config when severity is off", () => {
-                const fn = validator.validate.bind(null, { rules: { "mock-rule": ["off", "second"] } }, "tests", ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ rules: { "mock-rule": ["off", "second"] } }, "tests", ruleMapper, linter.environments);
             });
 
             it("should do nothing with an invalid config when severity is off", () => {
-                const fn = validator.validate.bind(null, { rules: { "mock-required-options-rule": "off" } }, "tests", ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ rules: { "mock-required-options-rule": "off" } }, "tests", ruleMapper, linter.environments);
             });
 
             it("should do nothing with an invalid config when severity is an array with 'off'", () => {
-                const fn = validator.validate.bind(null, { rules: { "mock-required-options-rule": ["off"] } }, "tests", ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ rules: { "mock-required-options-rule": ["off"] } }, "tests", ruleMapper, linter.environments);
             });
 
             it("should do nothing with a valid config when severity is warn", () => {
-                const fn = validator.validate.bind(null, { rules: { "mock-rule": ["warn", "second"] } }, "tests", ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ rules: { "mock-rule": ["warn", "second"] } }, "tests", ruleMapper, linter.environments);
             });
 
             it("should do nothing with a valid config when severity is error", () => {
-                const fn = validator.validate.bind(null, { rules: { "mock-rule": ["error", "second"] } }, "tests", ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ rules: { "mock-rule": ["error", "second"] } }, "tests", ruleMapper, linter.environments);
             });
 
             it("should do nothing with a valid config when severity is Off", () => {
-                const fn = validator.validate.bind(null, { rules: { "mock-rule": ["Off", "second"] } }, "tests", ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ rules: { "mock-rule": ["Off", "second"] } }, "tests", ruleMapper, linter.environments);
             });
 
             it("should do nothing with a valid config when severity is Warn", () => {
-                const fn = validator.validate.bind(null, { rules: { "mock-rule": ["Warn", "second"] } }, "tests", ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ rules: { "mock-rule": ["Warn", "second"] } }, "tests", ruleMapper, linter.environments);
             });
 
             it("should do nothing with a valid config when severity is Error", () => {
-                const fn = validator.validate.bind(null, { rules: { "mock-rule": ["Error", "second"] } }, "tests", ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ rules: { "mock-rule": ["Error", "second"] } }, "tests", ruleMapper, linter.environments);
             });
 
             it("should catch invalid rule options", () => {
@@ -351,9 +312,7 @@ describe("Validator", () => {
             it("should allow for rules with no options", () => {
                 linter.defineRule("mock-no-options-rule", mockNoOptionsRule);
 
-                const fn = validator.validate.bind(null, { rules: { "mock-no-options-rule": 2 } }, "tests", ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ rules: { "mock-no-options-rule": 2 } }, "tests", ruleMapper, linter.environments);
             });
 
             it("should not allow options for rules with no options", () => {
@@ -367,15 +326,11 @@ describe("Validator", () => {
 
         describe("overrides", () => {
             it("should not throw with an empty overrides array", () => {
-                const fn = validator.validate.bind(null, { overrides: [] }, "tests", ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ overrides: [] }, "tests", ruleMapper, linter.environments);
             });
 
             it("should not throw with a valid overrides array", () => {
-                const fn = validator.validate.bind(null, { overrides: [{ files: "*", rules: {} }] }, "tests", ruleMapper, linter.environments);
-
-                assert.doesNotThrow(fn);
+                validator.validate({ overrides: [{ files: "*", rules: {} }] }, "tests", ruleMapper, linter.environments);
             });
 
             it("should throw if override does not specify files", () => {
diff --git a/tests/lib/ignored-paths.js b/tests/lib/ignored-paths.js
index 42fe5e0e3..bda83c2bd 100644
--- a/tests/lib/ignored-paths.js
+++ b/tests/lib/ignored-paths.js
@@ -302,9 +302,7 @@ describe("IgnoredPaths", () => {
         it("should not throw if given a relative filename", () => {
             const ignoredPaths = new IgnoredPaths({ ignore: true, ignorePattern: "undef.js", cwd: getFixturePath() });
 
-            assert.doesNotThrow(() => {
-                ignoredPaths.contains("undef.js");
-            });
+            ignoredPaths.contains("undef.js");
         });
 
         it("should return true for files which match an ignorePattern even if they do not exist on the filesystem", () => {
diff --git a/tests/lib/linter.js b/tests/lib/linter.js
index d47f016c8..15177c5cd 100644
--- a/tests/lib/linter.js
+++ b/tests/lib/linter.js
@@ -3494,9 +3494,7 @@ describe("Linter", () => {
             const config = {};
 
             Object.freeze(config);
-            assert.doesNotThrow(() => {
-                linter.verify("var foo", config);
-            });
+            linter.verify("var", config);
         });
 
         it("should pass 'id' to rule contexts with the rule id", () => {
@@ -4357,9 +4355,7 @@ describe("Linter", () => {
                 })
             });
 
-            assert.doesNotThrow(() => {
-                linter.verify("0", { rules: { "test-rule": "error" } });
-            });
+            linter.verify("0", { rules: { "test-rule": "error" } });
         });
     });
 
diff --git a/tests/lib/rules/array-element-newline.js b/tests/lib/rules/array-element-newline.js
index f652105fc..c9ddd1605 100644
--- a/tests/lib/rules/array-element-newline.js
+++ b/tests/lib/rules/array-element-newline.js
@@ -53,7 +53,7 @@ ruleTester.run("array-element-newline", rule, {
         { code: "var foo = [// any comment \n1,\n2];", options: ["always"] },
         { code: "var foo = [1,\n2 // any comment\n];", options: ["always"] },
         { code: "var foo = [1,\n2,\n3];", options: ["always"] },
-        { code: "var foo = [\nfunction foo() {\ndosomething();\n},\nfunction bar() {\nosomething();\n}\n];", options: ["always"] },
+        { code: "var foo = [\nfunction foo() {\ndosomething();\n},\nfunction bar() {\ndosomething();\n}\n];", options: ["always"] },
 
         // "never"
         { code: "var foo = [];", options: ["never"] },
@@ -66,6 +66,23 @@ ruleTester.run("array-element-newline", rule, {
         { code: "var foo = [1, (\n2\n), 3];", options: ["never"] },
         { code: "var foo = [\nfunction foo() {\ndosomething();\n}, function bar() {\ndosomething();\n}\n];", options: ["never"] },
 
+        // "consistent"
+        { code: "var foo = [];", options: ["consistent"] },
+        { code: "var foo = [1];", options: ["consistent"] },
+        { code: "var foo = [1, 2];", options: ["consistent"] },
+        { code: "var foo = [1,\n2];", options: ["consistent"] },
+        { code: "var foo = [1, 2, 3];", options: ["consistent"] },
+        { code: "var foo = [1,\n2,\n3];", options: ["consistent"] },
+        { code: "var foo = [1,\n2,\n,\n3];", options: ["consistent"] },
+        { code: "var foo = [1, // any comment\n2];", options: ["consistent"] },
+        { code: "var foo = [/* any comment */ 1, 2];", options: ["consistent"] },
+        { code: "var foo = [1, (\n2\n), 3];", options: ["consistent"] },
+        { code: "var foo = [1,\n(2)\n, 3];", options: ["consistent"] },
+        { code: "var foo = [\nfunction foo() {\ndosomething();\n},\nfunction bar() {\ndosomething();\n}\n];", options: ["consistent"] },
+        { code: "var foo = [\nfunction foo() {\ndosomething();\n}, function bar() {\ndosomething();\n}\n];", options: ["consistent"] },
+        { code: "var foo = [\nfunction foo() {\ndosomething();\n},\nfunction bar() {\ndosomething();\n},\nfunction bar() {\ndosomething();\n}];", options: ["consistent"] },
+        { code: "var foo = [\nfunction foo() {\ndosomething();\n}, function bar() {\ndosomething();\n}, function bar() {\ndosomething();\n}];", options: ["consistent"] },
+
         // { multiline: true }
         { code: "var foo = [];", options: [{ multiline: true }] },
         { code: "var foo = [1];", options: [{ multiline: true }] },
@@ -450,6 +467,88 @@ ruleTester.run("array-element-newline", rule, {
             ]
         },
 
+        // "consistent"
+        {
+            code: "var foo = [1,\n2, 3];",
+            output: "var foo = [1,\n2,\n3];",
+            options: ["consistent"],
+            errors: [
+                {
+                    messageId: "missingLineBreak",
+                    line: 2,
+                    column: 3,
+                    endLine: 2,
+                    endColumn: 4
+                }
+            ]
+        },
+        {
+            code: "var foo = [1, 2,\n3];",
+            output: "var foo = [1,\n2,\n3];",
+            options: ["consistent"],
+            errors: [
+                {
+                    messageId: "missingLineBreak",
+                    line: 1,
+                    column: 14,
+                    endLine: 1,
+                    endColumn: 15
+                }
+            ]
+        },
+        {
+            code: "var foo = [1,\n(\n2), 3];",
+            output: "var foo = [1,\n(\n2),\n3];",
+            options: ["consistent"],
+            errors: [
+                {
+                    messageId: "missingLineBreak",
+                    line: 3,
+                    column: 4,
+                    endLine: 3,
+                    endColumn: 5
+                }
+            ]
+        },
+        {
+            code: "var foo = [1,        \t      (\n2\n),\n3];",
+            output: "var foo = [1,\n(\n2\n),\n3];",
+            options: ["consistent"],
+            errors: [
+                {
+                    messageId: "missingLineBreak",
+                    line: 1,
+                    column: 14,
+                    endLine: 1,
+                    endColumn: 29
+                }
+            ]
+        },
+        {
+            code: "var foo = [1, /* any comment */(2),\n3];",
+            output: "var foo = [1, /* any comment */\n(2),\n3];",
+            options: ["consistent"],
+            errors: [
+                {
+                    messageId: "missingLineBreak",
+                    line: 1,
+                    column: 32
+                }
+            ]
+        },
+        {
+            code: "var foo = [\nfunction foo() {\ndosomething();\n},function bar() {\ndosomething();\n},\nfunction bar() {\ndosomething();\n}];",
+            output: "var foo = [\nfunction foo() {\ndosomething();\n},\nfunction bar() {\ndosomething();\n},\nfunction bar() {\ndosomething();\n}];",
+            options: ["consistent"],
+            errors: [
+                {
+                    messageId: "missingLineBreak",
+                    line: 4,
+                    column: 3
+                }
+            ]
+        },
+
         // { multiline: true }
         {
             code: "var foo = [1,\n2, 3];",
diff --git a/tests/lib/rules/no-extra-parens.js b/tests/lib/rules/no-extra-parens.js
index 1738b1a66..b3481d06a 100644
--- a/tests/lib/rules/no-extra-parens.js
+++ b/tests/lib/rules/no-extra-parens.js
@@ -288,6 +288,13 @@ ruleTester.run("no-extra-parens", rule, {
             "    );",
             "}"
         ].join("\n"),
+        [
+            "function a() {",
+            "    return (",
+            "        <></>",
+            "    );",
+            "}"
+        ].join("\n"),
         [
             "throw (",
             "    a",
@@ -321,6 +328,14 @@ ruleTester.run("no-extra-parens", rule, {
 
         // ["all", { ignoreJSX: "all" }]
         { code: "const Component = (<div />)", options: ["all", { ignoreJSX: "all" }] },
+        {
+            code: [
+                "const Component = (<>",
+                "  <p />",
+                "</>);"
+            ].join("\n"),
+            options: ["all", { ignoreJSX: "all" }]
+        },
         {
             code: [
                 "const Component = (<div>",
@@ -663,6 +678,19 @@ ruleTester.run("no-extra-parens", rule, {
             "    );",
             "}"
         ].join("\n"), "JSXElement", null),
+        invalid([
+            "function a() {",
+            "    return ((",
+            "       <></>",
+            "    ));",
+            "}"
+        ].join("\n"), [
+            "function a() {",
+            "    return (",
+            "       <></>",
+            "    );",
+            "}"
+        ].join("\n"), "JSXFragment", null),
         invalid("throw (a);", "throw a;", "Identifier"),
         invalid([
             "throw ((",
@@ -884,6 +912,13 @@ ruleTester.run("no-extra-parens", rule, {
         ].join("\n"), "const Component = \n  <div />\n;", "JSXElement", 1, {
             options: ["all", { ignoreJSX: "multi-line" }]
         }),
+        invalid([
+            "const Component = (",
+            "  <></>",
+            ");"
+        ].join("\n"), "const Component = \n  <></>\n;", "JSXFragment", 1, {
+            options: ["all", { ignoreJSX: "multi-line" }]
+        }),
 
         // ["all", { ignoreJSX: "single-line" }]
         invalid([
diff --git a/tests/lib/rules/no-useless-escape.js b/tests/lib/rules/no-useless-escape.js
index b22309956..636149635 100644
--- a/tests/lib/rules/no-useless-escape.js
+++ b/tests/lib/rules/no-useless-escape.js
@@ -50,6 +50,8 @@ ruleTester.run("no-useless-escape", rule, {
         { code: "<div> Testing: \\ </div>", parserOptions: { ecmaFeatures: { jsx: true } } },
         { code: "<div> Testing: &#x5C </div>", parserOptions: { ecmaFeatures: { jsx: true } } },
         { code: "<foo attr='\\d'></foo>", parserOptions: { ecmaFeatures: { jsx: true } } },
+        { code: "<> Testing: \\ </>", parserOptions: { ecmaFeatures: { jsx: true } } },
+        { code: "<> Testing: &#x5C </>", parserOptions: { ecmaFeatures: { jsx: true } } },
         { code: "var foo = `\\x123`", parserOptions: { ecmaVersion: 6 } },
         { code: "var foo = `\\u00a9`", parserOptions: { ecmaVersion: 6 } },
         { code: "var foo = `xs\\u2111`", parserOptions: { ecmaVersion: 6 } },
diff --git a/tests/lib/rules/one-var.js b/tests/lib/rules/one-var.js
index 50a2ecf1d..1f6626ad8 100644
--- a/tests/lib/rules/one-var.js
+++ b/tests/lib/rules/one-var.js
@@ -1701,6 +1701,17 @@ ruleTester.run("one-var", rule, {
                 line: 1,
                 column: 41
             }]
+        },
+        {
+            code: "var a\nvar b",
+            output: "var a,\n b",
+            options: ["always"],
+            errors: [{
+                message: "Combine this with the previous 'var' statement.",
+                type: "VariableDeclaration",
+                line: 2,
+                column: 1
+            }]
         }
     ]
 });
diff --git a/tests/lib/rules/quotes.js b/tests/lib/rules/quotes.js
index b6ea51362..812ea737b 100644
--- a/tests/lib/rules/quotes.js
+++ b/tests/lib/rules/quotes.js
@@ -23,6 +23,10 @@ ruleTester.run("quotes", rule, {
         { code: "var foo = 1;", options: ["double"] },
         { code: "var foo = \"'\";", options: ["single", { avoidEscape: true }] },
         { code: "var foo = '\"';", options: ["double", { avoidEscape: true }] },
+        { code: "var foo = <>Hello world</>;", options: ["single"], parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } } },
+        { code: "var foo = <>Hello world</>;", options: ["double"], parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } } },
+        { code: "var foo = <>Hello world</>;", options: ["double", { avoidEscape: true }], parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } } },
+        { code: "var foo = <>Hello world</>;", options: ["backtick"], parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } } },
         { code: "var foo = <div>Hello world</div>;", options: ["single"], parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } } },
         { code: "var foo = <div id=\"foo\"></div>;", options: ["single"], parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } } },
         { code: "var foo = <div>Hello world</div>;", options: ["double"], parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } } },
diff --git a/tests/lib/testers/no-test-runners.js b/tests/lib/testers/no-test-runners.js
index 34d8a2a09..a14ac3bab 100644
--- a/tests/lib/testers/no-test-runners.js
+++ b/tests/lib/testers/no-test-runners.js
@@ -6,8 +6,8 @@
 
 /* global describe, it */
 /* eslint-disable no-global-assign*/
-const assert = require("assert"),
-    RuleTester = require("../../../lib/testers/rule-tester");
+const assert = require("assert");
+const RuleTester = require("../../../lib/testers/rule-tester");
 const tmpIt = it;
 const tmpDescribe = describe;
 
@@ -26,7 +26,7 @@ try {
                 { code: "var foo = bar;", output: "invalid output", errors: 1 }
             ]
         });
-    }, /Output is incorrect\. \(' foo = bar;' === 'invalid output'\)$/);
+    }, new assert.AssertionError({ actual: " foo = bar;", expected: "invalid output", operator: "===" }).message);
 } finally {
     it = tmpIt;
     describe = tmpDescribe;
diff --git a/tests/lib/testers/rule-tester.js b/tests/lib/testers/rule-tester.js
index a3f8073c2..0a51dc26b 100644
--- a/tests/lib/testers/rule-tester.js
+++ b/tests/lib/testers/rule-tester.js
@@ -85,16 +85,13 @@ describe("RuleTester", () => {
     });
 
     it("should not throw an error when everything passes", () => {
-
-        assert.doesNotThrow(() => {
-            ruleTester.run("no-eval", require("../../fixtures/testers/rule-tester/no-eval"), {
-                valid: [
-                    "Eval(foo)"
-                ],
-                invalid: [
-                    { code: "eval(foo)", errors: [{ message: "eval sucks.", type: "CallExpression" }] }
-                ]
-            });
+        ruleTester.run("no-eval", require("../../fixtures/testers/rule-tester/no-eval"), {
+            valid: [
+                "Eval(foo)"
+            ],
+            invalid: [
+                { code: "eval(foo)", errors: [{ message: "eval sucks.", type: "CallExpression" }] }
+            ]
         });
     });
 
@@ -210,44 +207,37 @@ describe("RuleTester", () => {
     });
 
     it("should not throw an error when the error is a string and it matches error message", () => {
-        assert.doesNotThrow(() => {
-            ruleTester.run("no-var", require("../../fixtures/testers/rule-tester/no-var"), {
-
-                // Only the invalid test matters here
-                valid: [
-                    "bar = baz;"
-                ],
-                invalid: [
-                    { code: "var foo = bar;", errors: ["Bad var."] }
-                ]
-            });
+        ruleTester.run("no-var", require("../../fixtures/testers/rule-tester/no-var"), {
+
+            // Only the invalid test matters here
+            valid: [
+                "bar = baz;"
+            ],
+            invalid: [
+                { code: "var foo = bar;", errors: ["Bad var."] }
+            ]
         });
     });
 
     it("should not throw an error when the error is a regex and it matches error message", () => {
-        assert.doesNotThrow(() => {
-            ruleTester.run("no-var", require("../../fixtures/testers/rule-tester/no-var"), {
-                valid: [],
-                invalid: [
-                    { code: "var foo = bar;", errors: [/^Bad var/] }
-                ]
-            });
+        ruleTester.run("no-var", require("../../fixtures/testers/rule-tester/no-var"), {
+            valid: [],
+            invalid: [
+                { code: "var foo = bar;", errors: [/^Bad var/] }
+            ]
         });
     });
 
     it("should not throw an error when the error is a regex in an object and it matches error message", () => {
-        assert.doesNotThrow(() => {
-            ruleTester.run("no-var", require("../../fixtures/testers/rule-tester/no-var"), {
-                valid: [],
-                invalid: [
-                    { code: "var foo = bar;", errors: [{ message: /^Bad var/ }] }
-                ]
-            });
+        ruleTester.run("no-var", require("../../fixtures/testers/rule-tester/no-var"), {
+            valid: [],
+            invalid: [
+                { code: "var foo = bar;", errors: [{ message: /^Bad var/ }] }
+            ]
         });
     });
 
     it("should throw an error when the expected output doesn't match", () => {
-
         assert.throws(() => {
             ruleTester.run("no-var", require("../../fixtures/testers/rule-tester/no-var"), {
                 valid: [
@@ -269,13 +259,12 @@ describe("RuleTester", () => {
             })
         };
 
-        assert.doesNotThrow(() => {
-            ruleTester.run("foo", replaceProgramWith5Rule, {
-                valid: [],
-                invalid: [
-                    { code: "var foo = bar;", output: "5", errors: 1 }
-                ]
-            });
+        // Should not throw.
+        ruleTester.run("foo", replaceProgramWith5Rule, {
+            valid: [],
+            invalid: [
+                { code: "var foo = bar;", output: "5", errors: 1 }
+            ]
         });
 
         assert.throws(() => {
@@ -289,7 +278,6 @@ describe("RuleTester", () => {
     });
 
     it("should throw an error when the expected output doesn't match and errors is just a number", () => {
-
         assert.throws(() => {
             ruleTester.run("no-var", require("../../fixtures/testers/rule-tester/no-var"), {
                 valid: [
@@ -303,16 +291,14 @@ describe("RuleTester", () => {
     });
 
     it("should not throw an error when the expected output is null and no errors produce output", () => {
-        assert.doesNotThrow(() => {
-            ruleTester.run("no-eval", require("../../fixtures/testers/rule-tester/no-eval"), {
-                valid: [
-                    "bar = baz;"
-                ],
-                invalid: [
-                    { code: "eval(x)", errors: 1, output: null },
-                    { code: "eval(x); eval(y);", errors: 2, output: null }
-                ]
-            });
+        ruleTester.run("no-eval", require("../../fixtures/testers/rule-tester/no-eval"), {
+            valid: [
+                "bar = baz;"
+            ],
+            invalid: [
+                { code: "eval(x)", errors: 1, output: null },
+                { code: "eval(x); eval(y);", errors: 2, output: null }
+            ]
         });
     });
 
@@ -352,7 +338,6 @@ describe("RuleTester", () => {
     });
 
     it("should throw an error if invalid code specifies wrong type", () => {
-
         assert.throws(() => {
             ruleTester.run("no-eval", require("../../fixtures/testers/rule-tester/no-eval"), {
                 valid: [
@@ -366,7 +351,6 @@ describe("RuleTester", () => {
     });
 
     it("should throw an error if invalid code specifies wrong line", () => {
-
         assert.throws(() => {
             ruleTester.run("no-eval", require("../../fixtures/testers/rule-tester/no-eval"), {
                 valid: [
@@ -411,7 +395,6 @@ describe("RuleTester", () => {
     });
 
     it("should not skip column assertion if column is a falsy value", () => {
-
         assert.throws(() => {
             ruleTester.run("no-eval", require("../../fixtures/testers/rule-tester/no-eval"), {
                 valid: ["Eval(foo)"],
@@ -450,7 +433,6 @@ describe("RuleTester", () => {
     });
 
     it("should throw an error if invalid code has the wrong number of errors", () => {
-
         assert.throws(() => {
             ruleTester.run("no-eval", require("../../fixtures/testers/rule-tester/no-eval"), {
                 valid: [
@@ -483,7 +465,6 @@ describe("RuleTester", () => {
     });
 
     it("should throw an error if invalid code has the wrong explicit number of errors", () => {
-
         assert.throws(() => {
             ruleTester.run("no-eval", require("../../fixtures/testers/rule-tester/no-eval"), {
                 valid: [
@@ -498,7 +479,6 @@ describe("RuleTester", () => {
 
     // https://github.com/eslint/eslint/issues/4779
     it("should throw an error if there's a parsing error and output doesn't match", () => {
-
         assert.throws(() => {
             ruleTester.run("no-eval", require("../../fixtures/testers/rule-tester/no-eval"), {
                 valid: [],
@@ -510,65 +490,57 @@ describe("RuleTester", () => {
     });
 
     it("should not throw an error if invalid code has at least an expected empty error object", () => {
-        assert.doesNotThrow(() => {
-            ruleTester.run("no-eval", require("../../fixtures/testers/rule-tester/no-eval"), {
-                valid: ["Eval(foo)"],
-                invalid: [{
-                    code: "eval(foo)",
-                    errors: [{}]
-                }]
-            });
+        ruleTester.run("no-eval", require("../../fixtures/testers/rule-tester/no-eval"), {
+            valid: ["Eval(foo)"],
+            invalid: [{
+                code: "eval(foo)",
+                errors: [{}]
+            }]
         });
     });
 
     it("should pass-through the globals config of valid tests to the to rule", () => {
-        assert.doesNotThrow(() => {
-            ruleTester.run("no-test-global", require("../../fixtures/testers/rule-tester/no-test-global"), {
-                valid: [
-                    "var test = 'foo'",
-                    {
-                        code: "var test2 = 'bar'",
-                        globals: { test: true }
-                    }
-                ],
-                invalid: [{ code: "bar", errors: 1 }]
-            });
+        ruleTester.run("no-test-global", require("../../fixtures/testers/rule-tester/no-test-global"), {
+            valid: [
+                "var test = 'foo'",
+                {
+                    code: "var test2 = 'bar'",
+                    globals: { test: true }
+                }
+            ],
+            invalid: [{ code: "bar", errors: 1 }]
         });
     });
 
     it("should pass-through the globals config of invalid tests to the to rule", () => {
-        assert.doesNotThrow(() => {
-            ruleTester.run("no-test-global", require("../../fixtures/testers/rule-tester/no-test-global"), {
-                valid: ["var test = 'foo'"],
-                invalid: [
-                    {
-                        code: "var test = 'foo'; var foo = 'bar'",
-                        errors: 1
-                    },
-                    {
-                        code: "var test = 'foo'",
-                        globals: { foo: true },
-                        errors: [{ message: "Global variable foo should not be used." }]
-                    }
-                ]
-            });
+        ruleTester.run("no-test-global", require("../../fixtures/testers/rule-tester/no-test-global"), {
+            valid: ["var test = 'foo'"],
+            invalid: [
+                {
+                    code: "var test = 'foo'; var foo = 'bar'",
+                    errors: 1
+                },
+                {
+                    code: "var test = 'foo'",
+                    globals: { foo: true },
+                    errors: [{ message: "Global variable foo should not be used." }]
+                }
+            ]
         });
     });
 
     it("should pass-through the settings config to rules", () => {
-        assert.doesNotThrow(() => {
-            ruleTester.run("no-test-settings", require("../../fixtures/testers/rule-tester/no-test-settings"), {
-                valid: [
-                    {
-                        code: "var test = 'bar'", settings: { test: 1 }
-                    }
-                ],
-                invalid: [
-                    {
-                        code: "var test = 'bar'", settings: { "no-test": 22 }, errors: 1
-                    }
-                ]
-            });
+        ruleTester.run("no-test-settings", require("../../fixtures/testers/rule-tester/no-test-settings"), {
+            valid: [
+                {
+                    code: "var test = 'bar'", settings: { test: 1 }
+                }
+            ],
+            invalid: [
+                {
+                    code: "var test = 'bar'", settings: { "no-test": 22 }, errors: 1
+                }
+            ]
         });
     });
 
@@ -594,22 +566,20 @@ describe("RuleTester", () => {
     });
 
     it("should pass-through the options to the rule", () => {
-        assert.doesNotThrow(() => {
-            ruleTester.run("no-invalid-args", require("../../fixtures/testers/rule-tester/no-invalid-args"), {
-                valid: [
-                    {
-                        code: "var foo = 'bar'",
-                        options: [false]
-                    }
-                ],
-                invalid: [
-                    {
-                        code: "var foo = 'bar'",
-                        options: [true],
-                        errors: [{ message: "Invalid args" }]
-                    }
-                ]
-            });
+        ruleTester.run("no-invalid-args", require("../../fixtures/testers/rule-tester/no-invalid-args"), {
+            valid: [
+                {
+                    code: "var foo = 'bar'",
+                    options: [false]
+                }
+            ],
+            invalid: [
+                {
+                    code: "var foo = 'bar'",
+                    options: [true],
+                    errors: [{ message: "Invalid args" }]
+                }
+            ]
         });
     });
 
@@ -642,30 +612,26 @@ describe("RuleTester", () => {
     });
 
     it("should pass-through the parser to the rule", () => {
+        const spy = sinon.spy(ruleTester.linter, "verify");
 
-        assert.doesNotThrow(() => {
-            const spy = sinon.spy(ruleTester.linter, "verify");
-
-            ruleTester.run("no-eval", require("../../fixtures/testers/rule-tester/no-eval"), {
-                valid: [
-                    {
-                        code: "Eval(foo)"
-                    }
-                ],
-                invalid: [
-                    {
-                        code: "eval(foo)",
-                        parser: "esprima",
-                        errors: [{}]
-                    }
-                ]
-            });
-            assert.strictEqual(spy.args[1][1].parser, "esprima");
+        ruleTester.run("no-eval", require("../../fixtures/testers/rule-tester/no-eval"), {
+            valid: [
+                {
+                    code: "Eval(foo)"
+                }
+            ],
+            invalid: [
+                {
+                    code: "eval(foo)",
+                    parser: "esprima",
+                    errors: [{}]
+                }
+            ]
         });
+        assert.strictEqual(spy.args[1][1].parser, "esprima");
     });
 
     it("should prevent invalid options schemas", () => {
-
         assert.throws(() => {
             ruleTester.run("no-invalid-schema", require("../../fixtures/testers/rule-tester/no-invalid-schema"), {
                 valid: [
@@ -681,7 +647,6 @@ describe("RuleTester", () => {
     });
 
     it("should prevent schema violations in options", () => {
-
         assert.throws(() => {
             ruleTester.run("no-schema-violation", require("../../fixtures/testers/rule-tester/no-schema-violation"), {
                 valid: [
@@ -697,7 +662,6 @@ describe("RuleTester", () => {
     });
 
     it("throw an error when an unknown config option is included", () => {
-
         assert.throws(() => {
             ruleTester.run("no-eval", require("../../fixtures/testers/rule-tester/no-eval"), {
                 valid: [
@@ -709,7 +673,6 @@ describe("RuleTester", () => {
     });
 
     it("throw an error when an invalid config value is included", () => {
-
         assert.throws(() => {
             ruleTester.run("no-eval", require("../../fixtures/testers/rule-tester/no-eval"), {
                 valid: [
@@ -725,14 +688,12 @@ describe("RuleTester", () => {
             globals: { test: true }
         });
 
-        assert.doesNotThrow(() => {
-            ruleTester.run("no-test-global", require("../../fixtures/testers/rule-tester/no-test-global"), {
-                valid: [
-                    "var test = 'foo'",
-                    "var test2 = test"
-                ],
-                invalid: [{ code: "bar", errors: 1, globals: { foo: true } }]
-            });
+        ruleTester.run("no-test-global", require("../../fixtures/testers/rule-tester/no-test-global"), {
+            valid: [
+                "var test = 'foo'",
+                "var test2 = test"
+            ],
+            invalid: [{ code: "bar", errors: 1, globals: { foo: true } }]
         });
     });
 
@@ -785,14 +746,12 @@ describe("RuleTester", () => {
         RuleTester.setDefaultConfig(config);
         ruleTester = new RuleTester();
 
-        assert.doesNotThrow(() => {
-            ruleTester.run("no-test-global", require("../../fixtures/testers/rule-tester/no-test-global"), {
-                valid: [
-                    "var test = 'foo'",
-                    "var test2 = test"
-                ],
-                invalid: [{ code: "bar", errors: 1, globals: { foo: true } }]
-            });
+        ruleTester.run("no-test-global", require("../../fixtures/testers/rule-tester/no-test-global"), {
+            valid: [
+                "var test = 'foo'",
+                "var test2 = test"
+            ],
+            invalid: [{ code: "bar", errors: 1, globals: { foo: true } }]
         });
     });
 
@@ -893,11 +852,9 @@ describe("RuleTester", () => {
             });
         }, /Avoid using variables named/);
 
-        assert.doesNotThrow(() => {
-            ruleTester.run("foo", require("../../fixtures/testers/rule-tester/messageId").withMessageOnly, {
-                valid: [],
-                invalid: [{ code: "foo", errors: [{ message: "Avoid using variables named 'foo'." }] }]
-            });
+        ruleTester.run("foo", require("../../fixtures/testers/rule-tester/messageId").withMessageOnly, {
+            valid: [],
+            invalid: [{ code: "foo", errors: [{ message: "Avoid using variables named 'foo'." }] }]
         });
     });
 
@@ -909,11 +866,9 @@ describe("RuleTester", () => {
             });
         }, "messageId 'avoidFoo' does not match expected messageId 'unused'.");
 
-        assert.doesNotThrow(() => {
-            ruleTester.run("foo", require("../../fixtures/testers/rule-tester/messageId").withMetaWithData, {
-                valid: [],
-                invalid: [{ code: "foo", errors: [{ messageId: "avoidFoo" }] }]
-            });
+        ruleTester.run("foo", require("../../fixtures/testers/rule-tester/messageId").withMetaWithData, {
+            valid: [],
+            invalid: [{ code: "foo", errors: [{ messageId: "avoidFoo" }] }]
         });
     });
     it("should assert match between resulting message output if messageId and data provided in both test and result", () => {
diff --git a/tests/lib/util/npm-util.js b/tests/lib/util/npm-util.js
index 7f97f0da3..bdf34666a 100644
--- a/tests/lib/util/npm-util.js
+++ b/tests/lib/util/npm-util.js
@@ -65,9 +65,8 @@ describe("npmUtil", () => {
                 "package.json": JSON.stringify({ private: true, dependencies: {} })
             });
 
-            const fn = npmUtil.checkDevDeps.bind(null, ["some-package"]);
-
-            assert.doesNotThrow(fn);
+            // Should not throw.
+            npmUtil.checkDevDeps(["some-package"]);
         });
 
         it("should throw with message when parsing invalid package.json", () => {
@@ -128,9 +127,8 @@ describe("npmUtil", () => {
                 "package.json": JSON.stringify({ private: true, devDependencies: {} })
             });
 
-            const fn = npmUtil.checkDeps.bind(null, ["some-package"]);
-
-            assert.doesNotThrow(fn);
+            // Should not throw.
+            npmUtil.checkDeps(["some-package"]);
         });
 
         it("should throw with message when parsing invalid package.json", () => {