Repository: eslint/eslint
Pull request #10357 (2018-05-16 11:01:25)

Update: config-validator should validate overrides
**What is the purpose of this pull request? (put an "X" next to item)**

[X] Bug fix

**What changes did you make? (Give an overview)**

This PR fixes a bug that ESLint overlooks invalid `env` and `rules` option values in the `overrides` option. This is important to catch invalid rule options.

This might be a breaking change since it can throw new error on invalid configs.

**Is there anything you'd like reviewers to focus on?**

Nothing in particular.



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/docs/rules/max-classes-per-file.md b/docs/rules/max-classes-per-file.md
index 83608594d..98ca1d100 100644
--- a/docs/rules/max-classes-per-file.md
+++ b/docs/rules/max-classes-per-file.md
@@ -31,9 +31,19 @@ class Foo {}
 This rule has a numeric option (defaulted to 1) to specify the
 maximum number of classes.
 
+For example:
+
+```json
+{
+    "max-classes-per-file": ["error", 1]
+}
+```
+
 Examples of **correct** code for this rule with the numeric option set to `2`:
 
 ```js
+/* eslint max-classes-per-file: ["error", 2] */
+
 class Foo {}
 class Bar {}
 ```
diff --git a/docs/user-guide/integrations.md b/docs/user-guide/integrations.md
index 159066348..17d037860 100644
--- a/docs/user-guide/integrations.md
+++ b/docs/user-guide/integrations.md
@@ -27,7 +27,7 @@
 * Rollup: [rollup-plugin-eslint](https://www.npmjs.com/package/rollup-plugin-eslint)
 * Ember-cli: [ember-cli-eslint](https://www.npmjs.com/package/ember-cli-eslint)
 * Sails.js: [sails-hook-lint](https://www.npmjs.com/package/sails-hook-lint), [sails-eslint](https://www.npmjs.com/package/sails-eslint)
-* Start: [start-eslint](https://www.npmjs.com/package/start-eslint)
+* Start: [@start/plugin-lib-eslint](https://www.npmjs.com/package/@start/plugin-lib-eslint)
 * Brunch: [eslint-brunch](https://www.npmjs.com/package/eslint-brunch)
 
 ## Command Line Tools
diff --git a/lib/config/config-file.js b/lib/config/config-file.js
index 46d561516..87f60f91c 100644
--- a/lib/config/config-file.js
+++ b/lib/config/config-file.js
@@ -567,6 +567,22 @@ function load(filePath, configContext, relativeTo) {
     return config;
 }
 
+/**
+ * Checks whether the given filename points to a file
+ * @param {string} filename A path to a file
+ * @returns {boolean} `true` if a file exists at the given location
+ */
+function isExistingFile(filename) {
+    try {
+        return fs.statSync(filename).isFile();
+    } catch (err) {
+        if (err.code === "ENOENT") {
+            return false;
+        }
+        throw err;
+    }
+}
+
 
 //------------------------------------------------------------------------------
 // Public Interface
@@ -591,14 +607,6 @@ module.exports = {
      *      or null if there is no configuration file in the directory.
      */
     getFilenameForDirectory(directory) {
-        for (let i = 0, len = CONFIG_FILES.length; i < len; i++) {
-            const filename = path.join(directory, CONFIG_FILES[i]);
-
-            if (fs.existsSync(filename) && fs.statSync(filename).isFile()) {
-                return filename;
-            }
-        }
-
-        return null;
+        return CONFIG_FILES.map(filename => path.join(directory, filename)).find(isExistingFile) || null;
     }
 };
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/config/config-ops.js b/lib/config/config-ops.js
index 67c23a8a6..6c298d364 100644
--- a/lib/config/config-ops.js
+++ b/lib/config/config-ops.js
@@ -240,14 +240,7 @@ module.exports = {
      * @returns {boolean} True if the rule represents an error, false if not.
      */
     isErrorSeverity(ruleConfig) {
-
-        let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig;
-
-        if (typeof severity === "string") {
-            severity = RULE_SEVERITY[severity.toLowerCase()] || 0;
-        }
-
-        return (typeof severity === "number" && severity === 2);
+        return module.exports.getRuleSeverity(ruleConfig) === 2;
     },
 
     /**
diff --git a/lib/config/config-validator.js b/lib/config/config-validator.js
index ed9a34cb0..185d4650d 100644
--- a/lib/config/config-validator.js
+++ b/lib/config/config-validator.js
@@ -254,6 +254,11 @@ function validate(config, source, ruleMapper, envContext) {
     validateConfigSchema(config, source);
     validateRules(config.rules, source, ruleMapper);
     validateEnvironment(config.env, source, envContext);
+
+    for (const override of config.overrides || []) {
+        validateRules(override.rules, source, ruleMapper);
+        validateEnvironment(override.env, source, envContext);
+    }
 }
 
 //------------------------------------------------------------------------------
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/arrow-body-style.js b/lib/rules/arrow-body-style.js
index 1f0d1377b..49feb0670 100644
--- a/lib/rules/arrow-body-style.js
+++ b/lib/rules/arrow-body-style.js
@@ -124,6 +124,8 @@ module.exports = {
                         messageId = "unexpectedEmptyBlock";
                     } else if (blockBody.length > 1) {
                         messageId = "unexpectedOtherBlock";
+                    } else if (blockBody[0].argument === null) {
+                        messageId = "unexpectedSingleBlock";
                     } else if (astUtils.isOpeningBraceToken(sourceCode.getFirstToken(blockBody[0], { skip: 1 }))) {
                         messageId = "unexpectedObjectBlock";
                     } else {
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/prefer-object-spread.js b/lib/rules/prefer-object-spread.js
index 6a213c690..d6577df7d 100644
--- a/lib/rules/prefer-object-spread.js
+++ b/lib/rules/prefer-object-spread.js
@@ -22,6 +22,15 @@ function isObjectAssign(node) {
     );
 }
 
+/**
+ * Helper that checks if the Object.assign call has array spread
+ * @param {ASTNode} node - The node that the rule warns on
+ * @returns {boolean} - Returns true if the Object.assign call has array spread
+ */
+function hasArraySpread(node) {
+    return node.arguments.some(arg => arg.type === "SpreadElement");
+}
+
 /**
  * Helper that checks if the node needs parentheses to be valid JS.
  * The default is to wrap the node in parentheses to avoid parsing errors.
@@ -187,6 +196,34 @@ function autofixObjectLiteral(node, sourceCode) {
     };
 }
 
+/**
+ * Check if the node has modified a given variable
+ * @param {ASTNode|null} node - The node that the rule warns on, i.e. the Object.assign call
+ * @returns {boolean} - true if node is an assignment, variable declaration, or import statement
+ */
+function isModifier(node) {
+    if (!node.type) {
+        return false;
+    }
+
+    return node.type === "AssignmentExpression" ||
+        node.type === "VariableDeclarator" ||
+        node.type === "ImportDeclaration";
+}
+
+/**
+ * Check if the node has modified a given variable
+ * @param {array} references - list of reference nodes
+ * @returns {boolean} - true if node is has been overwritten by an assignment or import
+ */
+function modifyingObjectReference(references) {
+    return references.some(ref => (
+        ref.identifier &&
+        ref.identifier.parent &&
+        isModifier(ref.identifier.parent)
+    ));
+}
+
 
 module.exports = {
     meta: {
@@ -207,35 +244,25 @@ module.exports = {
 
     create: function rule(context) {
         const sourceCode = context.getSourceCode();
-        let overWritingNativeObject = false;
+        const scope = context.getScope();
+        const objectVariable = scope.variables.filter(variable => variable.name === "Object");
+        const moduleReferences = scope.childScopes.filter(childScope => {
+            const varNamedObject = childScope.variables.filter(variable => variable.name === "Object");
 
-        return {
-            VariableDeclaration(node) {
-
-                /*
-                 * If a declared variable is overwriting the native `Object`, eg. `const Object = 'something'`
-                 * we want to skip warning on them since the behavior might be different.
-                 */
-                if (node.declarations.length) {
-                    const declarationNames = node.declarations.map(dec => dec.id);
-                    const nativeObjectOverride = declarationNames.filter(identifier => identifier.name === "Object");
+            return childScope.type === "module" && varNamedObject.length;
+        });
+        const references = [].concat(...objectVariable.map(variable => variable.references || []));
 
-                    if (nativeObjectOverride.length) {
-                        overWritingNativeObject = true;
-                    }
-                }
-            },
-            AssignmentExpression(node) {
+        return {
+            CallExpression(node) {
 
                 /*
-                 * If an assignment is reassigning the native `Object`, eg. `Object = 'something'`
-                 * we want to skip warning on them since the behavior might be different.
+                 * If current file is either importing Object or redefining it,
+                 * we skip warning on this rule.
                  */
-                if (node.left.name === "Object") {
-                    overWritingNativeObject = true;
+                if (moduleReferences.length || (references.length && modifyingObjectReference(references))) {
+                    return;
                 }
-            },
-            CallExpression(node) {
 
                 /*
                  * The condition below is cases where Object.assign has a single argument and
@@ -243,7 +270,6 @@ module.exports = {
                  * For now, we will warn on this case and autofix it.
                  */
                 if (
-                    !overWritingNativeObject &&
                     node.arguments.length === 1 &&
                     node.arguments[0].type === "ObjectExpression" &&
                     isObjectAssign(node)
@@ -261,10 +287,10 @@ module.exports = {
                  * that can be spread. e.g `Object.assign({ foo: bar }, baz)`
                  */
                 if (
-                    !overWritingNativeObject &&
                     node.arguments.length > 1 &&
                     node.arguments[0].type === "ObjectExpression" &&
-                    isObjectAssign(node)
+                    isObjectAssign(node) &&
+                    !hasArraySpread(node)
                 ) {
                     context.report({
                         node,
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..456b15183 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", () => {
@@ -407,6 +362,40 @@ describe("Validator", () => {
 
                 assert.throws(fn, "ESLint configuration in tests is invalid:\n\t- Unexpected top-level property \"overrides[0].root\".\n");
             });
+
+            describe("env", () => {
+
+                it("should catch invalid environments", () => {
+                    const fn = validator.validate.bind(null, { overrides: [{ files: "*", env: { browser: true, invalid: true } }] }, null, ruleMapper, linter.environments);
+
+                    assert.throws(fn, "Environment key \"invalid\" is unknown\n");
+                });
+
+                it("should catch disabled invalid environments", () => {
+                    const fn = validator.validate.bind(null, { overrides: [{ files: "*", env: { browser: true, invalid: false } }] }, null, ruleMapper, linter.environments);
+
+                    assert.throws(fn, "Environment key \"invalid\" is unknown\n");
+                });
+
+            });
+
+            describe("rules", () => {
+
+                it("should catch invalid rule options", () => {
+                    const fn = validator.validate.bind(null, { overrides: [{ files: "*", rules: { "mock-rule": [3, "third"] } }] }, "tests", ruleMapper, linter.environments);
+
+                    assert.throws(fn, "tests:\n\tConfiguration for rule \"mock-rule\" is invalid:\n\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '3').\n");
+                });
+
+                it("should not allow options for rules with no options", () => {
+                    linter.defineRule("mock-no-options-rule", mockNoOptionsRule);
+
+                    const fn = validator.validate.bind(null, { overrides: [{ files: "*", rules: { "mock-no-options-rule": [2, "extra"] } }] }, "tests", ruleMapper, linter.environments);
+
+                    assert.throws(fn, "tests:\n\tConfiguration for rule \"mock-no-options-rule\" is invalid:\n\tValue [\"extra\"] should NOT have more than 0 items.\n");
+                });
+            });
+
         });
 
     });
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/arrow-body-style.js b/tests/lib/rules/arrow-body-style.js
index 14572e98a..5e5fbc351 100644
--- a/tests/lib/rules/arrow-body-style.js
+++ b/tests/lib/rules/arrow-body-style.js
@@ -162,6 +162,19 @@ ruleTester.run("arrow-body-style", rule, {
                 }
             ]
         },
+        {
+            code: "var foo = () => { return };",
+            output: null, // not fixed
+            options: ["as-needed", { requireReturnForObjectLiteral: true }],
+            errors: [
+                {
+                    line: 1,
+                    column: 17,
+                    type: "ArrowFunctionExpression",
+                    messageId: "unexpectedSingleBlock"
+                }
+            ]
+        },
         {
             code: "var foo = () => { return; };",
             output: null, // not fixed
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/prefer-object-spread.js b/tests/lib/rules/prefer-object-spread.js
index 51c7e8be3..14bfa2f1e 100644
--- a/tests/lib/rules/prefer-object-spread.js
+++ b/tests/lib/rules/prefer-object-spread.js
@@ -14,7 +14,8 @@ const parserOptions = {
     ecmaVersion: 2018,
     ecmaFeatures: {
         experimentalObjectRestSpread: true
-    }
+    },
+    sourceType: "module"
 };
 
 const ruleTester = new RuleTester({ parserOptions });
@@ -28,6 +29,7 @@ ruleTester.run("prefer-object-spread", rule, {
         "const bar = { ...foo }",
         "Object.assign(...foo)",
         "Object.assign(foo, { bar: baz })",
+        "Object.assign({}, ...objects)",
         "foo({ foo: 'bar' })",
         `
         const Object = {};
@@ -44,6 +46,22 @@ ruleTester.run("prefer-object-spread", rule, {
         `
         Object = {};
         Object.assign({ foo: 'bar' });
+        `,
+        `
+        const Object = require('foo');
+        Object.assign({ foo: 'bar' });
+        `,
+        `
+        import Object from 'foo';
+        Object.assign({ foo: 'bar' });
+        `,
+        `
+        import { Something as Object } from 'foo';
+        Object.assign({ foo: 'bar' });
+        `,
+        `
+        import { Object, Array } from 'globals';
+        Object.assign({ foo: 'bar' });
         `
     ],
 
@@ -290,6 +308,9 @@ ruleTester.run("prefer-object-spread", rule, {
                 baz: "cats"
                 --> weird
 }`,
+            parserOptions: {
+                sourceType: "script"
+            },
             errors: [
                 {
                     messageId: "useSpreadMessage",
@@ -536,18 +557,6 @@ ruleTester.run("prefer-object-spread", rule, {
                 }
             ]
         },
-        {
-            code: "let a = Object.assign({}, ...b)",
-            output: "let a = {...b}",
-            errors: [
-                {
-                    messageId: "useSpreadMessage",
-                    type: "CallExpression",
-                    line: 1,
-                    column: 9
-                }
-            ]
-        },
         {
             code: "function foo() { return Object.assign({}, a) }",
             output: "function foo() { return {...a} }",
@@ -583,6 +592,114 @@ ruleTester.run("prefer-object-spread", rule, {
                     column: 30
                 }
             ]
+        },
+        {
+            code: `
+                import Foo from 'foo';
+                Object.assign({ foo: Foo });
+            `,
+            output: `
+                import Foo from 'foo';
+                ({ foo: Foo });
+            `,
+            errors: [
+                {
+                    messageId: "useLiteralMessage",
+                    type: "CallExpression",
+                    line: 3,
+                    column: 17
+                }
+            ]
+        },
+        {
+            code: `
+                import Foo from 'foo';
+                Object.assign({}, Foo);
+            `,
+            output: `
+                import Foo from 'foo';
+                ({...Foo});
+            `,
+            errors: [
+                {
+                    messageId: "useSpreadMessage",
+                    type: "CallExpression",
+                    line: 3,
+                    column: 17
+                }
+            ]
+        },
+        {
+            code: `
+                const Foo = require('foo');
+                Object.assign({ foo: Foo });
+            `,
+            output: `
+                const Foo = require('foo');
+                ({ foo: Foo });
+            `,
+            errors: [
+                {
+                    messageId: "useLiteralMessage",
+                    type: "CallExpression",
+                    line: 3,
+                    column: 17
+                }
+            ]
+        },
+        {
+            code: `
+                import { Something as somethingelse } from 'foo';
+                Object.assign({}, somethingelse);
+            `,
+            output: `
+                import { Something as somethingelse } from 'foo';
+                ({...somethingelse});
+            `,
+            errors: [
+                {
+                    messageId: "useSpreadMessage",
+                    type: "CallExpression",
+                    line: 3,
+                    column: 17
+                }
+            ]
+        },
+        {
+            code: `
+                import { foo } from 'foo';
+                Object.assign({ foo: Foo });
+            `,
+            output: `
+                import { foo } from 'foo';
+                ({ foo: Foo });
+            `,
+            errors: [
+                {
+                    messageId: "useLiteralMessage",
+                    type: "CallExpression",
+                    line: 3,
+                    column: 17
+                }
+            ]
+        },
+        {
+            code: `
+                const Foo = require('foo');
+                Object.assign({}, Foo);
+            `,
+            output: `
+                const Foo = require('foo');
+                ({...Foo});
+            `,
+            errors: [
+                {
+                    messageId: "useSpreadMessage",
+                    type: "CallExpression",
+                    line: 3,
+                    column: 17
+                }
+            ]
         }
     ]
 });
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", () => {