Repository: eslint/eslint
Pull request #11506 (2019-03-13 21:19:42)

Chore: Update README to pull in reviewer data
<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**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))
[ ] 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:

Updates the script that builds the README to include data from the reviewers team.

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

**What changes did you make? (Give an overview)**

Updated the `update-readme.js` script to include reviewers. This involved some refactoring to make things a bit easier to manage. I'm now using some EJS to do the overall layout of the team section.


**Is there anything you'd like reviewers to focus on?**

Is everything clear?

ilyavolodin: Some linting errors needs to be fixed before this can be merged.

Patch:
diff --git a/.eslintrc.js b/.eslintrc.js
index 86cc48017..ff213cf5f 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -17,7 +17,22 @@ module.exports = {
         "eslint-plugin/prefer-placeholders": "error",
         "eslint-plugin/report-message-format": ["error", "[^a-z].*\\.$"],
         "eslint-plugin/require-meta-type": "error",
-        "eslint-plugin/test-case-property-ordering": "error",
+        "eslint-plugin/test-case-property-ordering": [
+            "error",
+
+            // https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/issues/79
+            [
+                "filename",
+                "code",
+                "output",
+                "options",
+                "parser",
+                "parserOptions",
+                "globals",
+                "env",
+                "errors"
+            ]
+        ],
         "eslint-plugin/test-case-shorthand-strings": "error",
         "internal-rules/multiline-comment-style": "error"
     },
diff --git a/.gitignore b/.gitignore
index d2c98d47b..c65d8d573 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,4 @@ versions.json
 /.vscode
 .sublimelinterrc
 .eslint-release-info.json
+.nyc_output
diff --git a/.nycrc b/.nycrc
new file mode 100644
index 000000000..d0f606dc2
--- /dev/null
+++ b/.nycrc
@@ -0,0 +1,12 @@
+{
+    "include": [
+        "bin/**/*.js",
+        "conf/**/*.js",
+        "lib/**/*.js"
+    ],
+    "reporter": [
+        "lcov",
+        "text-summary"
+    ],
+    "sourceMap": true
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 115a7c3c5..537924921 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,28 @@
+v5.15.3 - March 18, 2019
+
+* [`71adc66`](https://github.com/eslint/eslint/commit/71adc665b9649b173adc76f80723b8de20664ae1) Fix: avoid moving comments in implicit-arrow-linebreak (fixes #11521) (#11522) (Teddy Katz)
+* [`1f715a2`](https://github.com/eslint/eslint/commit/1f715a20c145d8ccc38f3310afccd838495d09d4) Chore: make test-case-property-ordering reasonable (#11511) (Toru Nagashima)
+
+v5.15.2 - March 15, 2019
+
+* [`29dbca7`](https://github.com/eslint/eslint/commit/29dbca73d762a809adb2f457b527e144426d54a7) Fix: implicit-arrow-linebreak adds extra characters (fixes #11268) (#11407) (Mark de Dios)
+* [`5d2083f`](https://github.com/eslint/eslint/commit/5d2083fa3e14c024197f6c386ff72237a145e258) Upgrade: eslint-scope@4.0.3 (#11513) (Teddy Katz)
+* [`a5dae7c`](https://github.com/eslint/eslint/commit/a5dae7c3d30231c2f5f075d98c2c8825899bab16) Fix: Empty glob pattern incorrectly expands to "/**" (#11476) (Ben Chauvette)
+* [`448e8da`](https://github.com/eslint/eslint/commit/448e8da94d09b397e98ffcb6f22b55a578ef79c1) Chore: improve crash reporting (fixes #11304) (#11463) (Alex Zherdev)
+* [`0f56dc6`](https://github.com/eslint/eslint/commit/0f56dc6d9eadad05dc3d5c9d1d9ddef94e10c5d3) Chore: make config validator params more consistent (#11435) (薛定谔的猫)
+* [`d6c1122`](https://github.com/eslint/eslint/commit/d6c112289f0f16ade070865c8786831b7940ca79) Docs: Add working groups to maintainer guide (#11400) (Nicholas C. Zakas)
+* [`5fdb4d3`](https://github.com/eslint/eslint/commit/5fdb4d3fb01b9d8a4c2dff71ed9cddb2f8feefb0) Build: compile deps to ES5 when generating browser file (fixes #11504) (#11505) (Teddy Katz)
+* [`06fa165`](https://github.com/eslint/eslint/commit/06fa1655c3da8394ed9144d727115fc434b0416f) Build: update CI testing configuration (#11500) (Reece Dunham)
+* [`956e883`](https://github.com/eslint/eslint/commit/956e883c21fd9f393bf6718d032a4e2e53b33f22) Docs: Fix example in no-restricted-modules docs (#11454) (Paul O’Shannessy)
+* [`2c7431d`](https://github.com/eslint/eslint/commit/2c7431d6b32063f74e3837ee727f26af215eada7) Docs: fix json schema example dead link (#11498) (kazuya kawaguchi)
+* [`e7266c2`](https://github.com/eslint/eslint/commit/e7266c2478aff5d66e7859313feb49e3a129f85e) Docs: Fix invalid JSON in "Specifying Parser Options" (#11492) (Mihira Jayasekera)
+* [`6693161`](https://github.com/eslint/eslint/commit/6693161978a83e0730d5ea0fecdb627c5a2acdfd) Sponsors: Sync README with website (ESLint Jenkins)
+* [`62fee4a`](https://github.com/eslint/eslint/commit/62fee4a976897d158c8c137339728cd280333286) Chore: eslint-config-eslint enable comma-dangle functions: "never" (#11434) (薛定谔的猫)
+* [`34a5382`](https://github.com/eslint/eslint/commit/34a53829e7a63ff2f6b371d77ce283bbdd373b91) Build: copy bundled espree to website directory (#11478) (Pig Fang)
+* [`f078f9a`](https://github.com/eslint/eslint/commit/f078f9a9e094ec00c61a6ef1c9550d017631e69a) Chore: use "file:" dependencies for internal rules/config (#11465) (Teddy Katz)
+* [`0756128`](https://github.com/eslint/eslint/commit/075612871f85aa04cef8137bd32247e128ad600b) Docs: Add `visualstudio` to formatter list (#11480) (Patrick Eriksson)
+* [`44de9d7`](https://github.com/eslint/eslint/commit/44de9d7e1aa2fcae475a97b8f597b7d8094566b2) Docs: Fix typo in func-name-matching rule docs (#11484) (Iulian Onofrei)
+
 v5.15.1 - March 4, 2019
 
 * [`fe1a892`](https://github.com/eslint/eslint/commit/fe1a892f85b09c3d2fea05bef011530a678a6af5) Build: bundle espree (fixes eslint/eslint.github.io#546) (#11467) (薛定谔的猫)
diff --git a/Makefile.js b/Makefile.js
index e2ddd2ab2..fd501857e 100644
--- a/Makefile.js
+++ b/Makefile.js
@@ -25,7 +25,8 @@ const lodash = require("lodash"),
     semver = require("semver"),
     ejs = require("ejs"),
     loadPerf = require("load-perf"),
-    yaml = require("js-yaml");
+    yaml = require("js-yaml"),
+    CLIEngine = require("./lib/cli-engine");
 
 const { cat, cd, cp, echo, exec, exit, find, ls, mkdir, pwd, rm, test } = require("shelljs");
 
@@ -65,7 +66,7 @@ const NODE = "node ", // intentional extra space
     // Files
     JSON_FILES = find("conf/").filter(fileType("json")),
     MARKDOWN_FILES_ARRAY = find("docs/").concat(ls(".")).filter(fileType("md")),
-    TEST_FILES = getTestFilePatterns(),
+    TEST_FILES = "\"tests/{bin,lib,tools}/**/*.js\"",
     PERF_ESLINTRC = path.join(PERF_TMP_DIR, "eslintrc.yml"),
     PERF_MULTIFILES_TARGET_DIR = path.join(PERF_TMP_DIR, "eslint"),
     PERF_MULTIFILES_TARGETS = `"${PERF_MULTIFILES_TARGET_DIR + path.sep}{lib,tests${path.sep}lib}${path.sep}**${path.sep}*.js"`,
@@ -77,20 +78,6 @@ const NODE = "node ", // intentional extra space
 // Helpers
 //------------------------------------------------------------------------------
 
-/**
- * Generates file patterns for test files
- * @returns {string} test file patterns
- * @private
- */
-function getTestFilePatterns() {
-    return ls("tests/lib/").filter(pathToCheck => test("-d", `tests/lib/${pathToCheck}`)).reduce((initialValue, currentValues) => {
-        if (currentValues !== "rules") {
-            initialValue.push(`"tests/lib/${currentValues}/**/*.js"`);
-        }
-        return initialValue;
-    }, ["\"tests/lib/rules/**/*.js\"", "\"tests/lib/*.js\"", "\"tests/bin/**/*.js\"", "\"tests/tools/**/*.js\""]).join(" ");
-}
-
 /**
  * Simple JSON file validation that relies on ES JSON parser.
  * @param {string} filePath Path to JSON.
@@ -440,8 +427,7 @@ function lintMarkdown(files) {
  * @returns {Object} Output from each formatter
  */
 function getFormatterResults() {
-    const CLIEngine = require("./lib/cli-engine"),
-        stripAnsi = require("strip-ansi");
+    const stripAnsi = require("strip-ansi");
 
     const formatterFiles = fs.readdirSync("./lib/formatters/"),
         cli = new CLIEngine({
@@ -567,19 +553,31 @@ target.test = function() {
 
     echo("Running unit tests");
 
-    lastReturn = exec(`${getBinFile("istanbul")} cover ${MOCHA} -- -R progress -t ${MOCHA_TIMEOUT} -c ${TEST_FILES}`);
+    lastReturn = exec(`${getBinFile("nyc")} -- ${MOCHA} -R progress -t ${MOCHA_TIMEOUT} -c ${TEST_FILES}`);
     if (lastReturn.code !== 0) {
         errors++;
     }
 
-    lastReturn = exec(`${getBinFile("istanbul")} check-coverage --statement 99 --branch 98 --function 99 --lines 99`);
-
+    lastReturn = exec(`${getBinFile("nyc")} check-coverage --statement 99 --branch 98 --function 99 --lines 99`);
     if (lastReturn.code !== 0) {
         errors++;
     }
 
     target.webpack();
 
+    const browserFileLintOutput = new CLIEngine({
+        useEslintrc: false,
+        ignore: false,
+        allowInlineConfig: false,
+        baseConfig: { parserOptions: { ecmaVersion: 5 } }
+    }).executeOnFiles([`${BUILD_DIR}/eslint.js`]);
+
+    if (browserFileLintOutput.errorCount > 0) {
+        echo(`error: Failed to lint ${BUILD_DIR}/eslint.js as ES5 code`);
+        echo(CLIEngine.getFormatter("stylish")(browserFileLintOutput.results));
+        errors++;
+    }
+
     lastReturn = exec(`${getBinFile("karma")} start karma.conf.js`);
     if (lastReturn.code !== 0) {
         errors++;
diff --git a/README.md b/README.md
index 437794dc6..172c956ad 100644
--- a/README.md
+++ b/README.md
@@ -193,12 +193,13 @@ According to our policy, any minor update may report more errors than the previo
 
 These folks keep the project moving and are resources for help.
 
+<!-- NOTE: This section is autogenerated. Do not manually edit.-->
+<!--teamstart-->
+
 ### Technical Steering Committee (TSC)
 
 The people who manage releases, review feature requests, and meet regularly to ensure ESLint is properly maintained.
 
-<!-- NOTE: This section is autogenerated. Do not manually edit.-->
-<!--tscstart-->
 <table><tbody><tr><td align="center" valign="top" width="11%">
 <a href="https://github.com/nzakas">
 <img src="https://github.com/nzakas.png?s=75" width="75" height="75"><br />
@@ -239,14 +240,15 @@ Kai Cataldo
 <img src="https://github.com/not-an-aardvark.png?s=75" width="75" height="75"><br />
 Teddy Katz
 </a>
-</td></tr></tbody></table><!--tscend-->
+</td></tr></tbody></table>
+
+
+
 
 ### Committers
 
 The people who review and fix bugs and help triage issues.
 
-<!-- NOTE: This section is autogenerated. Do not manually edit.-->
-<!--committersstart-->
 <table><tbody><tr><td align="center" valign="top" width="11%">
 <a href="https://github.com/aladdin-add">
 <img src="https://github.com/aladdin-add.png?s=75" width="75" height="75"><br />
@@ -257,7 +259,10 @@ The people who review and fix bugs and help triage issues.
 <img src="https://github.com/g-plane.png?s=75" width="75" height="75"><br />
 Pig Fang
 </a>
-</td></tr></tbody></table><!--committersend-->
+</td></tr></tbody></table>
+
+
+<!--teamend-->
 
 ## Sponsors
 
diff --git a/docs/maintainer-guide/README.md b/docs/maintainer-guide/README.md
index 19c1fb9ee..941ad5599 100644
--- a/docs/maintainer-guide/README.md
+++ b/docs/maintainer-guide/README.md
@@ -17,3 +17,7 @@ Describes how to do an ESLint project release.
 ## [Governance](governance.md)
 
 Describes the governance policy for ESLint, including the rights and privileges of individuals inside the project.
+
+## [Working Groups](working-groups.md)
+
+Describes how working groups are created and how they function within the ESLint project.
diff --git a/docs/maintainer-guide/working-groups.md b/docs/maintainer-guide/working-groups.md
new file mode 100644
index 000000000..d6d22fb6c
--- /dev/null
+++ b/docs/maintainer-guide/working-groups.md
@@ -0,0 +1,22 @@
+# Working Groups
+
+The ESLint TSC may form working groups to focus on a specific area of the project.
+
+## Creating a Working Group
+
+Working groups are created by sending an email to the team mailing list. Each working group:
+
+1. Must have a GitHub team under the "ESLint Team" top-level GitHub team. (The GitHub team name should end with "WG" to distinguish it from other types of teams.)
+1. Must have at least one TSC member.
+1. May have any number of Committers and Reviewers.
+1. Must have at least two members.
+
+Active working groups are listed on the [team page](https://eslint.org/team).
+
+## How Working Groups Work
+
+Each working group is responsible for its own inner working. Working groups can decide how large or small they should be (so long as there is at least two members), when and who to add or remove from the working group, and how to accomplish their objectives.
+
+Working groups may be temporary or permanent.
+
+If working groups intend to make a significant change to the ESLint project, the proposal must still be approved by the TSC.
diff --git a/docs/user-guide/command-line-interface.md b/docs/user-guide/command-line-interface.md
index 7fee37cf4..4cd3b9a53 100644
--- a/docs/user-guide/command-line-interface.md
+++ b/docs/user-guide/command-line-interface.md
@@ -420,7 +420,7 @@ Store the info about processed files in order to only operate on the changed one
 
 **Note:** If you run ESLint with `--cache` and then run ESLint without `--cache`, the `.eslintcache` file will be deleted. This is necessary because the results of the lint might change and make `.eslintcache` invalid. If you want to control when the cache file is deleted, then use `--cache-location` to specify an alternate location for the cache file.
 
-**Note:**: Autofixed files are not placed in the cache. Subsequent linting that does not trigger an autofix will place it in the cache.
+**Note:** Autofixed files are not placed in the cache. Subsequent linting that does not trigger an autofix will place it in the cache.
 
 #### `--cache-file`
 
diff --git a/lib/config/config-file.js b/lib/config/config-file.js
index 492800b7a..80344f509 100644
--- a/lib/config/config-file.js
+++ b/lib/config/config-file.js
@@ -541,7 +541,7 @@ function loadFromDisk(resolvedPath, configContext) {
         const ruleMap = configContext.linterContext.getRules();
 
         // validate the configuration before continuing
-        validator.validate(config, resolvedPath.configFullName, ruleMap.get.bind(ruleMap), configContext.linterContext.environments);
+        validator.validate(config, ruleMap.get.bind(ruleMap), configContext.linterContext.environments, resolvedPath.configFullName);
 
         /*
          * If an `extends` property is defined, it represents a configuration file to use as
diff --git a/lib/config/config-validator.js b/lib/config/config-validator.js
index 2345b2889..386db7775 100644
--- a/lib/config/config-validator.js
+++ b/lib/config/config-validator.js
@@ -116,7 +116,7 @@ function validateRuleSchema(rule, localOptions) {
  * no source is prepended to the message.
  * @returns {void}
  */
-function validateRuleOptions(rule, ruleId, options, source) {
+function validateRuleOptions(rule, ruleId, options, source = null) {
     if (!rule) {
         return;
     }
@@ -140,11 +140,11 @@ function validateRuleOptions(rule, ruleId, options, source) {
 /**
  * Validates an environment object
  * @param {Object} environment The environment config object to validate.
- * @param {string} source The name of the configuration source to report in any errors.
  * @param {Environments} envContext Env context
+ * @param {string} source The name of the configuration source to report in any errors.
  * @returns {void}
  */
-function validateEnvironment(environment, source, envContext) {
+function validateEnvironment(environment, envContext, source = null) {
 
     // not having an environment is ok
     if (!environment) {
@@ -163,11 +163,11 @@ function validateEnvironment(environment, source, envContext) {
 /**
  * Validates a rules config object
  * @param {Object} rulesConfig The rules config object to validate.
- * @param {string} source The name of the configuration source to report in any errors.
  * @param {function(string): {create: Function}} ruleMapper A mapper function from strings to loaded rules
+ * @param {string} source The name of the configuration source to report in any errors.
  * @returns {void}
  */
-function validateRules(rulesConfig, source, ruleMapper) {
+function validateRules(rulesConfig, ruleMapper, source = null) {
     if (!rulesConfig) {
         return;
     }
@@ -228,7 +228,7 @@ const emitDeprecationWarning = lodash.memoize((source, errorCode) => {
  * @param {string} source The name of the configuration source to report in any errors.
  * @returns {void}
  */
-function validateConfigSchema(config, source) {
+function validateConfigSchema(config, source = null) {
     validateSchema = validateSchema || ajv.compile(configSchema);
 
     if (!validateSchema(config)) {
@@ -252,19 +252,19 @@ function validateConfigSchema(config, source) {
 /**
  * Validates an entire config object.
  * @param {Object} config The config object to validate.
- * @param {string} source The name of the configuration source to report in any errors.
  * @param {function(string): {create: Function}} ruleMapper A mapper function from rule IDs to defined rules
  * @param {Environments} envContext The env context
+ * @param {string} source The name of the configuration source to report in any errors.
  * @returns {void}
  */
-function validate(config, source, ruleMapper, envContext) {
+function validate(config, ruleMapper, envContext, source = null) {
     validateConfigSchema(config, source);
-    validateRules(config.rules, source, ruleMapper);
-    validateEnvironment(config.env, source, envContext);
+    validateRules(config.rules, ruleMapper, source);
+    validateEnvironment(config.env, envContext, source);
 
     for (const override of config.overrides || []) {
-        validateRules(override.rules, source, ruleMapper);
-        validateEnvironment(override.env, source, envContext);
+        validateRules(override.rules, ruleMapper, source);
+        validateEnvironment(override.env, envContext, source);
     }
 }
 
diff --git a/lib/linter.js b/lib/linter.js
index 88448d90f..be38b9908 100644
--- a/lib/linter.js
+++ b/lib/linter.js
@@ -747,10 +747,15 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parser
     nodeQueue.forEach(traversalInfo => {
         currentNode = traversalInfo.node;
 
-        if (traversalInfo.isEntering) {
-            eventGenerator.enterNode(currentNode);
-        } else {
-            eventGenerator.leaveNode(currentNode);
+        try {
+            if (traversalInfo.isEntering) {
+                eventGenerator.enterNode(currentNode);
+            } else {
+                eventGenerator.leaveNode(currentNode);
+            }
+        } catch (err) {
+            err.currentNode = currentNode;
+            throw err;
         }
     });
 
@@ -901,8 +906,15 @@ module.exports = class Linter {
                 options.filename
             );
         } catch (err) {
+            err.message += `\nOccurred while linting ${options.filename}`;
             debug("An error occurred while traversing");
             debug("Filename:", options.filename);
+            if (err.currentNode) {
+                const { line } = err.currentNode.loc.start;
+
+                debug("Line:", line);
+                err.message += `:${line}`;
+            }
             debug("Parser Options:", parserOptions);
             debug("Parser Path:", parserName);
             debug("Settings:", settings);
diff --git a/lib/rules/implicit-arrow-linebreak.js b/lib/rules/implicit-arrow-linebreak.js
index ad0d70da6..6fc1268e7 100644
--- a/lib/rules/implicit-arrow-linebreak.js
+++ b/lib/rules/implicit-arrow-linebreak.js
@@ -4,11 +4,7 @@
  */
 "use strict";
 
-const {
-    isArrowToken,
-    isParenthesised,
-    isOpeningParenToken
-} = require("../util/ast-utils");
+const { isCommentToken, isNotOpeningParenToken } = require("../util/ast-utils");
 
 //------------------------------------------------------------------------------
 // Rule Definition
@@ -39,153 +35,7 @@ module.exports = {
 
     create(context) {
         const sourceCode = context.getSourceCode();
-
-        //----------------------------------------------------------------------
-        // Helpers
-        //----------------------------------------------------------------------
-        /**
-         * Gets the applicable preference for a particular keyword
-         * @returns {string} The applicable option for the keyword, e.g. 'beside'
-         */
-        function getOption() {
-            return context.options[0] || "beside";
-        }
-
-        /**
-         * Formats the comments depending on whether it's a line or block comment.
-         * @param {Comment[]} comments The array of comments between the arrow and body
-         * @param {Integer} column The column number of the first token
-         * @returns {string} A string of comment text joined by line breaks
-         */
-        function formatComments(comments, column) {
-            const whiteSpaces = " ".repeat(column);
-
-            return `${comments.map(comment => {
-
-                if (comment.type === "Line") {
-                    return `//${comment.value}`;
-                }
-
-                return `/*${comment.value}*/`;
-            }).join(`\n${whiteSpaces}`)}\n${whiteSpaces}`;
-        }
-
-        /**
-         * Finds the first token to prepend comments to depending on the parent type
-         * @param {Node} node The validated node
-         * @returns {Token|Node} The node to prepend comments to
-         */
-        function findFirstToken(node) {
-            switch (node.parent.type) {
-                case "VariableDeclarator":
-
-                    // If the parent is first or only declarator, return the declaration, else, declarator
-                    return sourceCode.getFirstToken(
-                        node.parent.parent.declarations.length === 1 ||
-                        node.parent.parent.declarations[0].id.name === node.parent.id.name
-                            ? node.parent.parent : node.parent
-                    );
-                case "CallExpression":
-                case "Property":
-
-                    // find the object key
-                    return sourceCode.getFirstToken(node.parent);
-                default:
-                    return node;
-            }
-        }
-
-        /**
-         * Helper function for adding parentheses fixes for nodes containing nested arrow functions
-         * @param {Fixer} fixer Fixer
-         * @param {Token} arrow - The arrow token
-         * @param {ASTNode} arrowBody - The arrow function body
-         * @returns {Function[]} autofixer -- wraps function bodies with parentheses
-         */
-        function addParentheses(fixer, arrow, arrowBody) {
-            const parenthesesFixes = [];
-            let closingParentheses = "";
-
-            let followingBody = arrowBody;
-            let currentArrow = arrow;
-
-            while (currentArrow) {
-                if (!isParenthesised(sourceCode, followingBody)) {
-                    parenthesesFixes.push(
-                        fixer.insertTextAfter(currentArrow, " (")
-                    );
-
-                    const paramsToken = sourceCode.getTokenBefore(currentArrow, token =>
-                        isOpeningParenToken(token) || token.type === "Identifier");
-
-                    const whiteSpaces = " ".repeat(paramsToken.loc.start.column);
-
-                    closingParentheses = `\n${whiteSpaces})${closingParentheses}`;
-                }
-
-                currentArrow = sourceCode.getTokenAfter(currentArrow, isArrowToken);
-
-                if (currentArrow) {
-                    followingBody = sourceCode.getTokenAfter(currentArrow, token => !isOpeningParenToken(token));
-                }
-            }
-
-            return [...parenthesesFixes,
-                fixer.insertTextAfter(arrowBody, closingParentheses)
-            ];
-        }
-
-        /**
-         * Autofixes the function body to collapse onto the same line as the arrow.
-         * If comments exist, prepends the comments before the arrow function.
-         * If the function body contains arrow functions, appends the function bodies with parentheses.
-         * @param {Token} arrowToken The arrow token.
-         * @param {ASTNode} arrowBody the function body
-         * @param {ASTNode} node The evaluated node
-         * @returns {Function} autofixer -- validates the node to adhere to besides
-         */
-        function autoFixBesides(arrowToken, arrowBody, node) {
-            return fixer => {
-                const placeBesides = fixer.replaceTextRange([arrowToken.range[1], arrowBody.range[0]], " ");
-
-                const comments = sourceCode.getCommentsInside(node).filter(comment =>
-                    comment.loc.start.line < arrowBody.loc.start.line);
-
-                if (comments.length) {
-
-                    // If the grandparent is not a variable declarator
-                    if (
-                        arrowBody.parent &&
-                        arrowBody.parent.parent &&
-                        arrowBody.parent.parent.type !== "VariableDeclarator"
-                    ) {
-
-                        // If any arrow functions follow, return the necessary parens fixes.
-                        if (sourceCode.getTokenAfter(arrowToken, isArrowToken) && arrowBody.parent.parent.type !== "VariableDeclarator") {
-                            return addParentheses(fixer, arrowToken, arrowBody);
-                        }
-
-                        // If any arrow functions precede, the necessary fixes have already been returned, so return null.
-                        if (sourceCode.getTokenBefore(arrowToken, isArrowToken) && arrowBody.parent.parent.type !== "VariableDeclarator") {
-                            return null;
-                        }
-                    }
-
-                    const firstToken = findFirstToken(node);
-
-                    const commentText = formatComments(comments, firstToken.loc.start.column);
-
-                    const commentBeforeExpression = fixer.insertTextBeforeRange(
-                        firstToken.range,
-                        commentText
-                    );
-
-                    return [placeBesides, commentBeforeExpression];
-                }
-
-                return placeBesides;
-            };
-        }
+        const option = context.options[0] || "beside";
 
         /**
          * Validates the location of an arrow function body
@@ -193,35 +43,30 @@ module.exports = {
          * @returns {void}
          */
         function validateExpression(node) {
-            const option = getOption();
-
-            let tokenBefore = sourceCode.getTokenBefore(node.body);
-            const hasParens = tokenBefore.value === "(";
-
-            if (node.type === "BlockStatement") {
+            if (node.body.type === "BlockStatement") {
                 return;
             }
 
-            let fixerTarget = node.body;
+            const arrowToken = sourceCode.getTokenBefore(node.body, isNotOpeningParenToken);
+            const firstTokenOfBody = sourceCode.getTokenAfter(arrowToken);
 
-            if (hasParens) {
-
-                // Gets the first token before the function body that is not an open paren
-                tokenBefore = sourceCode.getTokenBefore(node.body, token => token.value !== "(");
-                fixerTarget = sourceCode.getTokenAfter(tokenBefore);
-            }
-
-            if (tokenBefore.loc.end.line === fixerTarget.loc.start.line && option === "below") {
+            if (arrowToken.loc.end.line === firstTokenOfBody.loc.start.line && option === "below") {
                 context.report({
-                    node: fixerTarget,
+                    node: firstTokenOfBody,
                     messageId: "expected",
-                    fix: fixer => fixer.insertTextBefore(fixerTarget, "\n")
+                    fix: fixer => fixer.insertTextBefore(firstTokenOfBody, "\n")
                 });
-            } else if (tokenBefore.loc.end.line !== fixerTarget.loc.start.line && option === "beside") {
+            } else if (arrowToken.loc.end.line !== firstTokenOfBody.loc.start.line && option === "beside") {
                 context.report({
-                    node: fixerTarget,
+                    node: firstTokenOfBody,
                     messageId: "unexpected",
-                    fix: autoFixBesides(tokenBefore, fixerTarget, node)
+                    fix(fixer) {
+                        if (sourceCode.getFirstTokenBetween(arrowToken, firstTokenOfBody, { includeComments: true, filter: isCommentToken })) {
+                            return null;
+                        }
+
+                        return fixer.replaceTextRange([arrowToken.range[1], firstTokenOfBody.range[0]], " ");
+                    }
                 });
             }
         }
diff --git a/lib/util/glob-utils.js b/lib/util/glob-utils.js
index b05c35443..33cb8e7c8 100644
--- a/lib/util/glob-utils.js
+++ b/lib/util/glob-utils.js
@@ -70,6 +70,10 @@ function processPath(options) {
      * @private
      */
     return function(pathname) {
+        if (pathname === "") {
+            return "";
+        }
+
         let newPath = pathname;
         const resolvedPath = path.resolve(cwd, pathname);
 
@@ -201,6 +205,13 @@ function listFilesToProcess(globPatterns, providedOptions) {
 
     debug("Creating list of files to process.");
     const resolvedPathsByGlobPattern = resolvedGlobPatterns.map(pattern => {
+        if (pattern === "") {
+            return [{
+                filename: "",
+                behavior: SILENTLY_IGNORE
+            }];
+        }
+
         const file = path.resolve(cwd, pattern);
 
         if (options.globInputPaths === false || (fs.existsSync(file) && fs.statSync(file).isFile())) {
@@ -240,7 +251,7 @@ function listFilesToProcess(globPatterns, providedOptions) {
     });
 
     const allPathDescriptors = resolvedPathsByGlobPattern.reduce((pathsForAllGlobs, pathsForCurrentGlob, index) => {
-        if (pathsForCurrentGlob.every(pathDescriptor => pathDescriptor.behavior === SILENTLY_IGNORE)) {
+        if (pathsForCurrentGlob.every(pathDescriptor => pathDescriptor.behavior === SILENTLY_IGNORE && pathDescriptor.filename !== "")) {
             throw new (pathsForCurrentGlob.length ? AllFilesIgnoredError : NoFilesFoundError)(globPatterns[index]);
         }
 
diff --git a/package.json b/package.json
index 2d9f0d0be..d07240a4c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint",
-  "version": "5.15.1",
+  "version": "5.15.3",
   "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
   "description": "An AST-based pattern checker for JavaScript.",
   "bin": {
@@ -41,7 +41,7 @@
     "cross-spawn": "^6.0.5",
     "debug": "^4.0.1",
     "doctrine": "^3.0.0",
-    "eslint-scope": "^4.0.2",
+    "eslint-scope": "^4.0.3",
     "eslint-utils": "^1.3.1",
     "eslint-visitor-keys": "^1.0.0",
     "espree": "^5.0.1",
@@ -55,7 +55,7 @@
     "import-fresh": "^3.0.0",
     "imurmurhash": "^0.1.4",
     "inquirer": "^6.2.2",
-    "js-yaml": "^3.12.0",
+    "js-yaml": "^3.13.0",
     "json-stable-stringify-without-jsonify": "^1.0.1",
     "levn": "^0.3.0",
     "lodash": "^4.17.11",
@@ -92,7 +92,6 @@
     "eslint-release": "^1.2.0",
     "eslump": "^2.0.0",
     "esprima": "^4.0.1",
-    "istanbul": "^0.4.5",
     "jsdoc": "^3.5.5",
     "karma": "^3.1.4",
     "karma-chrome-launcher": "^2.2.0",
@@ -105,6 +104,7 @@
     "mocha": "^5.0.5",
     "mock-fs": "^4.8.0",
     "npm-license": "^0.3.3",
+    "nyc": "^13.3.0",
     "proxyquire": "^2.0.1",
     "puppeteer": "^1.12.2",
     "shelljs": "^0.8.2",
diff --git a/tools/update-readme.js b/tools/update-readme.js
index da7ea03a1..ce6c6e191 100644
--- a/tools/update-readme.js
+++ b/tools/update-readme.js
@@ -16,6 +16,7 @@
 const path = require("path");
 const fs = require("fs");
 const { stripIndents } = require("common-tags");
+const ejs = require("ejs");
 
 //-----------------------------------------------------------------------------
 // Data
@@ -37,7 +38,6 @@ const heights = {
 // remove backers from sponsors list - not shown on readme
 delete allSponsors.backers;
 
-
 //-----------------------------------------------------------------------------
 // Helpers
 //-----------------------------------------------------------------------------
@@ -45,12 +45,11 @@ delete allSponsors.backers;
 /**
  * Formats an array of team members for inclusion in the readme.
  * @param {Array} members The array of members to format.
- * @param {string} label The label for the section of the readme.
  * @returns {string} The HTML for the members list.
  */
-function formatTeamMembers(members, label) {
+function formatTeamMembers(members) {
     /* eslint-disable indent*/
-    return stripIndents`<!--${label}start-->
+    return stripIndents`
         <table><tbody><tr>${
         members.map((member, index) => `<td align="center" valign="top" width="11%">
             <a href="https://github.com/${member.username}">
@@ -58,7 +57,7 @@ function formatTeamMembers(members, label) {
                 ${member.name}
             </a>
             </td>${(index + 1) % 9 === 0 ? "</tr><tr>" : ""}`).join("")
-        }</tr></tbody></table><!--${label}end-->`;
+        }</tr></tbody></table>`;
     /* eslint-enable indent*/
 }
 
@@ -86,10 +85,42 @@ function formatSponsors(sponsors) {
 // Main
 //-----------------------------------------------------------------------------
 
+const HTML_TEMPLATE = stripIndents`
+
+    <!--teamstart-->
+
+    ### Technical Steering Committee (TSC)
+
+    The people who manage releases, review feature requests, and meet regularly to ensure ESLint is properly maintained.
+
+    <%- formatTeamMembers(team.tsc) %>
+
+    <% if (team.reviewers.length > 0) { %>
+    ### Reviewers
+
+    The people who review and implement new features.
+
+    <%- formatTeamMembers(team.reviewers) %>
+
+    <% } %>
+
+    <% if (team.committers.length > 0) { %>
+    ### Committers
+
+    The people who review and fix bugs and help triage issues.
+
+    <%- formatTeamMembers(team.committers) %>
+
+    <% } %>
+    <!--teamend-->
+`;
+
 // replace all of the section
-let newReadme = readme.replace(/<!--tscstart-->[\w\W]*?<!--tscend-->/u, formatTeamMembers(team.tsc, "tsc"));
+let newReadme = readme.replace(/<!--teamstart-->[\w\W]*?<!--teamend-->/u, ejs.render(HTML_TEMPLATE, {
+    team,
+    formatTeamMembers
+}));
 
-newReadme = newReadme.replace(/<!--committersstart-->[\w\W]*?<!--committersend-->/u, formatTeamMembers(team.committers, "committers"));
 newReadme = newReadme.replace(/<!--sponsorsstart-->[\w\W]*?<!--sponsorsend-->/u, formatSponsors(allSponsors));
 
 // output to the file
diff --git a/webpack.config.js b/webpack.config.js
index 4ba329837..1a6a2986a 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -15,12 +15,12 @@ module.exports = {
     module: {
         rules: [
             {
-                test: /\.js$/u,
+                test: /\.m?js$/u,
                 loader: "babel-loader",
                 options: {
                     presets: ["@babel/preset-env"]
                 },
-                exclude: /node_modules/u
+                exclude: /node_modules\/lodash/u
             }
         ]
     },


Test patch:
diff --git a/lib/testers/rule-tester.js b/lib/testers/rule-tester.js
index 6d1bba989..f1d915531 100644
--- a/lib/testers/rule-tester.js
+++ b/lib/testers/rule-tester.js
@@ -379,7 +379,7 @@ class RuleTester {
                 }
             }
 
-            validator.validate(config, "rule-tester", ruleMap.get.bind(ruleMap), new Environments());
+            validator.validate(config, ruleMap.get.bind(ruleMap), new Environments(), "rule-tester");
 
             return {
                 messages: linter.verify(code, config, filename, true),
diff --git a/tests/lib/config/config-validator.js b/tests/lib/config/config-validator.js
index 721533c10..9d4c39baf 100644
--- a/tests/lib/config/config-validator.js
+++ b/tests/lib/config/config-validator.js
@@ -108,7 +108,7 @@ describe("Validator", () => {
     describe("validate", () => {
 
         it("should do nothing with an empty config", () => {
-            validator.validate({}, "tests", ruleMapper, linter.environments);
+            validator.validate({}, ruleMapper, linter.environments, "tests");
         });
 
         it("should do nothing with a valid eslint config", () => {
@@ -124,9 +124,9 @@ describe("Validator", () => {
                     parserOptions: { foo: "bar" },
                     rules: {}
                 },
-                "tests",
                 ruleMapper,
-                linter.environments
+                linter.environments,
+                "tests"
             );
         });
 
@@ -136,9 +136,9 @@ describe("Validator", () => {
                 {
                     foo: true
                 },
-                "tests",
                 ruleMapper,
-                linter.environments
+                linter.environments,
+                "tests"
             );
 
             assert.throws(fn, "Unexpected top-level property \"foo\".");
@@ -146,13 +146,13 @@ describe("Validator", () => {
 
         describe("root", () => {
             it("should throw with a string value", () => {
-                const fn = validator.validate.bind(null, { root: "true" }, null, ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { root: "true" }, ruleMapper, linter.environments, null);
 
                 assert.throws(fn, "Property \"root\" is the wrong type (expected boolean but got `\"true\"`).");
             });
 
             it("should throw with a numeric value", () => {
-                const fn = validator.validate.bind(null, { root: 0 }, null, ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { root: 0 }, ruleMapper, linter.environments, null);
 
                 assert.throws(fn, "Property \"root\" is the wrong type (expected boolean but got `0`).");
             });
@@ -160,13 +160,13 @@ describe("Validator", () => {
 
         describe("globals", () => {
             it("should throw with a string value", () => {
-                const fn = validator.validate.bind(null, { globals: "jQuery" }, null, ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { globals: "jQuery" }, ruleMapper, linter.environments, null);
 
                 assert.throws(fn, "Property \"globals\" is the wrong type (expected object but got `\"jQuery\"`).");
             });
 
             it("should throw with an array value", () => {
-                const fn = validator.validate.bind(null, { globals: ["jQuery"] }, null, ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { globals: ["jQuery"] }, ruleMapper, linter.environments, null);
 
                 assert.throws(fn, "Property \"globals\" is the wrong type (expected object but got `[\"jQuery\"]`).");
             });
@@ -174,32 +174,32 @@ describe("Validator", () => {
 
         describe("parser", () => {
             it("should not throw with a null value", () => {
-                validator.validate({ parser: null }, null, ruleMapper, linter.environments);
+                validator.validate({ parser: null }, ruleMapper, linter.environments, null);
             });
         });
 
         describe("env", () => {
 
             it("should throw with an array environment", () => {
-                const fn = validator.validate.bind(null, { env: [] }, null, ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { env: [] }, ruleMapper, linter.environments, null);
 
                 assert.throws(fn, "Property \"env\" is the wrong type (expected object but got `[]`).");
             });
 
             it("should throw with a primitive environment", () => {
-                const fn = validator.validate.bind(null, { env: 1 }, null, ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { env: 1 }, ruleMapper, linter.environments, null);
 
                 assert.throws(fn, "Property \"env\" is the wrong type (expected object but got `1`).");
             });
 
             it("should catch invalid environments", () => {
-                const fn = validator.validate.bind(null, { env: { browser: true, invalid: true } }, null, ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { env: { browser: true, invalid: true } }, ruleMapper, linter.environments, null);
 
                 assert.throws(fn, "Environment key \"invalid\" is unknown\n");
             });
 
             it("should catch disabled invalid environments", () => {
-                const fn = validator.validate.bind(null, { env: { browser: true, invalid: false } }, null, ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { env: { browser: true, invalid: false } }, ruleMapper, linter.environments, null);
 
                 assert.throws(fn, "Environment key \"invalid\" is unknown\n");
             });
@@ -212,11 +212,11 @@ describe("Validator", () => {
 
         describe("plugins", () => {
             it("should not throw with an empty array", () => {
-                validator.validate({ plugins: [] }, null, ruleMapper, linter.environments);
+                validator.validate({ plugins: [] }, ruleMapper, linter.environments, null);
             });
 
             it("should throw with a string", () => {
-                const fn = validator.validate.bind(null, { plugins: "react" }, null, ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { plugins: "react" }, ruleMapper, linter.environments, null);
 
                 assert.throws(fn, "Property \"plugins\" is the wrong type (expected array but got `\"react\"`).");
             });
@@ -224,11 +224,11 @@ describe("Validator", () => {
 
         describe("settings", () => {
             it("should not throw with an empty object", () => {
-                validator.validate({ settings: {} }, null, ruleMapper, linter.environments);
+                validator.validate({ settings: {} }, ruleMapper, linter.environments, null);
             });
 
             it("should throw with an array", () => {
-                const fn = validator.validate.bind(null, { settings: ["foo"] }, null, ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { settings: ["foo"] }, ruleMapper, linter.environments, null);
 
                 assert.throws(fn, "Property \"settings\" is the wrong type (expected object but got `[\"foo\"]`).");
             });
@@ -236,15 +236,15 @@ describe("Validator", () => {
 
         describe("extends", () => {
             it("should not throw with an empty array", () => {
-                validator.validate({ extends: [] }, null, ruleMapper, linter.environments);
+                validator.validate({ extends: [] }, ruleMapper, linter.environments, null);
             });
 
             it("should not throw with a string", () => {
-                validator.validate({ extends: "react" }, null, ruleMapper, linter.environments);
+                validator.validate({ extends: "react" }, ruleMapper, linter.environments, null);
             });
 
             it("should throw with an object", () => {
-                const fn = validator.validate.bind(null, { extends: {} }, null, ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { extends: {} }, ruleMapper, linter.environments, null);
 
                 assert.throws(fn, "Property \"extends\" is the wrong type (expected string/array but got `{}`).");
             });
@@ -252,11 +252,11 @@ describe("Validator", () => {
 
         describe("parserOptions", () => {
             it("should not throw with an empty object", () => {
-                validator.validate({ parserOptions: {} }, null, ruleMapper, linter.environments);
+                validator.validate({ parserOptions: {} }, ruleMapper, linter.environments, null);
             });
 
             it("should throw with an array", () => {
-                const fn = validator.validate.bind(null, { parserOptions: ["foo"] }, null, ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { parserOptions: ["foo"] }, ruleMapper, linter.environments, null);
 
                 assert.throws(fn, "Property \"parserOptions\" is the wrong type (expected object but got `[\"foo\"]`).");
             });
@@ -265,47 +265,47 @@ describe("Validator", () => {
         describe("rules", () => {
 
             it("should do nothing with an empty rules object", () => {
-                validator.validate({ rules: {} }, "tests", ruleMapper, linter.environments);
+                validator.validate({ rules: {} }, ruleMapper, linter.environments, "tests");
             });
 
             it("should do nothing with a valid config with rules", () => {
-                validator.validate({ rules: { "mock-rule": [2, "second"] } }, "tests", ruleMapper, linter.environments);
+                validator.validate({ rules: { "mock-rule": [2, "second"] } }, ruleMapper, linter.environments, "tests");
             });
 
             it("should do nothing with a valid config when severity is off", () => {
-                validator.validate({ rules: { "mock-rule": ["off", "second"] } }, "tests", ruleMapper, linter.environments);
+                validator.validate({ rules: { "mock-rule": ["off", "second"] } }, ruleMapper, linter.environments, "tests");
             });
 
             it("should do nothing with an invalid config when severity is off", () => {
-                validator.validate({ rules: { "mock-required-options-rule": "off" } }, "tests", ruleMapper, linter.environments);
+                validator.validate({ rules: { "mock-required-options-rule": "off" } }, ruleMapper, linter.environments, "tests");
             });
 
             it("should do nothing with an invalid config when severity is an array with 'off'", () => {
-                validator.validate({ rules: { "mock-required-options-rule": ["off"] } }, "tests", ruleMapper, linter.environments);
+                validator.validate({ rules: { "mock-required-options-rule": ["off"] } }, ruleMapper, linter.environments, "tests");
             });
 
             it("should do nothing with a valid config when severity is warn", () => {
-                validator.validate({ rules: { "mock-rule": ["warn", "second"] } }, "tests", ruleMapper, linter.environments);
+                validator.validate({ rules: { "mock-rule": ["warn", "second"] } }, ruleMapper, linter.environments, "tests");
             });
 
             it("should do nothing with a valid config when severity is error", () => {
-                validator.validate({ rules: { "mock-rule": ["error", "second"] } }, "tests", ruleMapper, linter.environments);
+                validator.validate({ rules: { "mock-rule": ["error", "second"] } }, ruleMapper, linter.environments, "tests");
             });
 
             it("should do nothing with a valid config when severity is Off", () => {
-                validator.validate({ rules: { "mock-rule": ["Off", "second"] } }, "tests", ruleMapper, linter.environments);
+                validator.validate({ rules: { "mock-rule": ["Off", "second"] } }, ruleMapper, linter.environments, "tests");
             });
 
             it("should do nothing with a valid config when severity is Warn", () => {
-                validator.validate({ rules: { "mock-rule": ["Warn", "second"] } }, "tests", ruleMapper, linter.environments);
+                validator.validate({ rules: { "mock-rule": ["Warn", "second"] } }, ruleMapper, linter.environments, "tests");
             });
 
             it("should do nothing with a valid config when severity is Error", () => {
-                validator.validate({ rules: { "mock-rule": ["Error", "second"] } }, "tests", ruleMapper, linter.environments);
+                validator.validate({ rules: { "mock-rule": ["Error", "second"] } }, ruleMapper, linter.environments, "tests");
             });
 
             it("should catch invalid rule options", () => {
-                const fn = validator.validate.bind(null, { rules: { "mock-rule": [3, "third"] } }, "tests", ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { rules: { "mock-rule": [3, "third"] } }, ruleMapper, linter.environments, "tests");
 
                 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");
             });
@@ -313,13 +313,13 @@ describe("Validator", () => {
             it("should allow for rules with no options", () => {
                 linter.defineRule("mock-no-options-rule", mockNoOptionsRule);
 
-                validator.validate({ rules: { "mock-no-options-rule": 2 } }, "tests", ruleMapper, linter.environments);
+                validator.validate({ rules: { "mock-no-options-rule": 2 } }, ruleMapper, linter.environments, "tests");
             });
 
             it("should not allow options for rules with no options", () => {
                 linter.defineRule("mock-no-options-rule", mockNoOptionsRule);
 
-                const fn = validator.validate.bind(null, { rules: { "mock-no-options-rule": [2, "extra"] } }, "tests", ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { rules: { "mock-no-options-rule": [2, "extra"] } }, ruleMapper, linter.environments, "tests");
 
                 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");
             });
@@ -327,39 +327,39 @@ describe("Validator", () => {
 
         describe("overrides", () => {
             it("should not throw with an empty overrides array", () => {
-                validator.validate({ overrides: [] }, "tests", ruleMapper, linter.environments);
+                validator.validate({ overrides: [] }, ruleMapper, linter.environments, "tests");
             });
 
             it("should not throw with a valid overrides array", () => {
-                validator.validate({ overrides: [{ files: "*", rules: {} }] }, "tests", ruleMapper, linter.environments);
+                validator.validate({ overrides: [{ files: "*", rules: {} }] }, ruleMapper, linter.environments, "tests");
             });
 
             it("should throw if override does not specify files", () => {
-                const fn = validator.validate.bind(null, { overrides: [{ rules: {} }] }, "tests", ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { overrides: [{ rules: {} }] }, ruleMapper, linter.environments, "tests");
 
                 assert.throws(fn, "ESLint configuration in tests is invalid:\n\t- \"overrides[0]\" should have required property 'files'. Value: {\"rules\":{}}.\n");
             });
 
             it("should throw if override has an empty files array", () => {
-                const fn = validator.validate.bind(null, { overrides: [{ files: [] }] }, "tests", ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { overrides: [{ files: [] }] }, ruleMapper, linter.environments, "tests");
 
                 assert.throws(fn, "ESLint configuration in tests is invalid:\n\t- Property \"overrides[0].files\" is the wrong type (expected string but got `[]`).\n\t- \"overrides[0].files\" should NOT have fewer than 1 items. Value: [].\n\t- \"overrides[0].files\" should match exactly one schema in oneOf. Value: [].\n");
             });
 
             it("should throw if override has nested overrides", () => {
-                const fn = validator.validate.bind(null, { overrides: [{ files: "*", overrides: [{ files: "*", rules: {} }] }] }, "tests", ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { overrides: [{ files: "*", overrides: [{ files: "*", rules: {} }] }] }, ruleMapper, linter.environments, "tests");
 
                 assert.throws(fn, "ESLint configuration in tests is invalid:\n\t- Unexpected top-level property \"overrides[0].overrides\".\n");
             });
 
             it("should throw if override extends", () => {
-                const fn = validator.validate.bind(null, { overrides: [{ files: "*", extends: "eslint-recommended" }] }, "tests", ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { overrides: [{ files: "*", extends: "eslint-recommended" }] }, ruleMapper, linter.environments, "tests");
 
                 assert.throws(fn, "ESLint configuration in tests is invalid:\n\t- Unexpected top-level property \"overrides[0].extends\".\n");
             });
 
             it("should throw if override tries to set root", () => {
-                const fn = validator.validate.bind(null, { overrides: [{ files: "*", root: "true" }] }, "tests", ruleMapper, linter.environments);
+                const fn = validator.validate.bind(null, { overrides: [{ files: "*", root: "true" }] }, ruleMapper, linter.environments, "tests");
 
                 assert.throws(fn, "ESLint configuration in tests is invalid:\n\t- Unexpected top-level property \"overrides[0].root\".\n");
             });
@@ -367,13 +367,13 @@ describe("Validator", () => {
             describe("env", () => {
 
                 it("should catch invalid environments", () => {
-                    const fn = validator.validate.bind(null, { overrides: [{ files: "*", env: { browser: true, invalid: true } }] }, null, ruleMapper, linter.environments);
+                    const fn = validator.validate.bind(null, { overrides: [{ files: "*", env: { browser: true, invalid: true } }] }, ruleMapper, linter.environments, null);
 
                     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);
+                    const fn = validator.validate.bind(null, { overrides: [{ files: "*", env: { browser: true, invalid: false } }] }, ruleMapper, linter.environments, null);
 
                     assert.throws(fn, "Environment key \"invalid\" is unknown\n");
                 });
@@ -383,7 +383,7 @@ describe("Validator", () => {
             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);
+                    const fn = validator.validate.bind(null, { overrides: [{ files: "*", rules: { "mock-rule": [3, "third"] } }] }, ruleMapper, linter.environments, "tests");
 
                     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");
                 });
@@ -391,7 +391,7 @@ describe("Validator", () => {
                 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);
+                    const fn = validator.validate.bind(null, { overrides: [{ files: "*", rules: { "mock-no-options-rule": [2, "extra"] } }] }, ruleMapper, linter.environments, "tests");
 
                     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/formatters/table.js b/tests/lib/formatters/table.js
index 667d1b7a4..6354fcbc2 100644
--- a/tests/lib/formatters/table.js
+++ b/tests/lib/formatters/table.js
@@ -8,14 +8,26 @@
 // Requirements
 //------------------------------------------------------------------------------
 
-const assert = require("chai").assert,
-    formatter = require("../../../lib/formatters/table");
+const assert = require("chai").assert;
+const chalk = require("chalk");
+const formatter = require("../../../lib/formatters/table");
 
 //------------------------------------------------------------------------------
 // Tests
 //------------------------------------------------------------------------------
 
 describe("formatter:table", () => {
+    let originalChalkEnabled;
+
+    before(() => {
+        originalChalkEnabled = chalk.enabled;
+        chalk.enabled = false;
+    });
+
+    after(() => {
+        chalk.enabled = originalChalkEnabled;
+    });
+
     describe("when passed no messages", () => {
         const code = [
             {
diff --git a/tests/lib/linter.js b/tests/lib/linter.js
index 3771ceb26..e31b61d95 100644
--- a/tests/lib/linter.js
+++ b/tests/lib/linter.js
@@ -99,7 +99,7 @@ describe("Linter", () => {
 
             assert.throws(() => {
                 linter.verify(code, config, filename);
-            }, "Intentional error.");
+            }, `Intentional error.\nOccurred while linting ${filename}:1`);
         });
 
         it("does not call rule listeners with a `this` value", () => {
@@ -4381,7 +4381,7 @@ describe("Linter", () => {
 
             assert.throws(() => {
                 linter.verify("0", { rules: { "test-rule": "error" } });
-            }, /Fixable rules should export a `meta\.fixable` property.$/u);
+            }, /Fixable rules should export a `meta\.fixable` property.\nOccurred while linting <input>:1$/u);
         });
 
         it("should not throw an error if fix is passed and there is no metadata", () => {
diff --git a/tests/lib/rules/array-bracket-spacing.js b/tests/lib/rules/array-bracket-spacing.js
index da3dadd6e..efb72ca5f 100644
--- a/tests/lib/rules/array-bracket-spacing.js
+++ b/tests/lib/rules/array-bracket-spacing.js
@@ -174,8 +174,8 @@ ruleTester.run("array-bracket-spacing", rule, {
         { code: "var obj = {'foo': [1, 2]}", options: ["never"] },
 
         // destructuring with type annotation
-        { code: "([ a, b ]: Array<any>) => {}", options: ["always"], parserOptions: { ecmaVersion: 6 }, parser: parser("flow-destructuring-1") },
-        { code: "([a, b]: Array< any >) => {}", options: ["never"], parserOptions: { ecmaVersion: 6 }, parser: parser("flow-destructuring-2") }
+        { code: "([ a, b ]: Array<any>) => {}", options: ["always"], parser: parser("flow-destructuring-1"), parserOptions: { ecmaVersion: 6 } },
+        { code: "([a, b]: Array< any >) => {}", options: ["never"], parser: parser("flow-destructuring-2"), parserOptions: { ecmaVersion: 6 } }
     ],
 
     invalid: [
@@ -830,6 +830,7 @@ ruleTester.run("array-bracket-spacing", rule, {
             code: "([ a, b ]: Array<any>) => {}",
             output: "([a, b]: Array<any>) => {}",
             options: ["never"],
+            parser: parser("flow-destructuring-1"),
             parserOptions: {
                 ecmaVersion: 6
             },
@@ -852,13 +853,13 @@ ruleTester.run("array-bracket-spacing", rule, {
                     line: 1,
                     column: 9
                 }
-            ],
-            parser: parser("flow-destructuring-1")
+            ]
         },
         {
             code: "([a, b]: Array< any >) => {}",
             output: "([ a, b ]: Array< any >) => {}",
             options: ["always"],
+            parser: parser("flow-destructuring-2"),
             parserOptions: {
                 ecmaVersion: 6
             },
@@ -881,8 +882,7 @@ ruleTester.run("array-bracket-spacing", rule, {
                     line: 1,
                     column: 7
                 }
-            ],
-            parser: parser("flow-destructuring-2")
+            ]
         }
     ]
 });
diff --git a/tests/lib/rules/comma-dangle.js b/tests/lib/rules/comma-dangle.js
index 8797dbdcf..1f1fc33cf 100644
--- a/tests/lib/rules/comma-dangle.js
+++ b/tests/lib/rules/comma-dangle.js
@@ -1410,29 +1410,29 @@ let d = 0;export {d,};
             code: "function foo({a}: {a: string,}) {}",
             output: "function foo({a,}: {a: string,}) {}",
             options: ["always"],
-            errors: [{ messageId: "missing" }],
-            parser: parser("object-pattern-1")
+            parser: parser("object-pattern-1"),
+            errors: [{ messageId: "missing" }]
         },
         {
             code: "function foo({a,}: {a: string}) {}",
             output: "function foo({a}: {a: string}) {}",
             options: ["never"],
-            errors: [{ messageId: "unexpected" }],
-            parser: parser("object-pattern-2")
+            parser: parser("object-pattern-2"),
+            errors: [{ messageId: "unexpected" }]
         },
         {
             code: "function foo(a): {b: boolean,} {}",
             output: "function foo(a,): {b: boolean,} {}",
             options: [{ functions: "always" }],
-            errors: [{ messageId: "missing" }],
-            parser: parser("return-type-1")
+            parser: parser("return-type-1"),
+            errors: [{ messageId: "missing" }]
         },
         {
             code: "function foo(a,): {b: boolean} {}",
             output: "function foo(a): {b: boolean} {}",
             options: [{ functions: "never" }],
-            errors: [{ messageId: "unexpected" }],
-            parser: parser("return-type-2")
+            parser: parser("return-type-2"),
+            errors: [{ messageId: "unexpected" }]
         }
     ]
 });
diff --git a/tests/lib/rules/implicit-arrow-linebreak.js b/tests/lib/rules/implicit-arrow-linebreak.js
index 0ed7213dc..4e2c0e12c 100644
--- a/tests/lib/rules/implicit-arrow-linebreak.js
+++ b/tests/lib/rules/implicit-arrow-linebreak.js
@@ -20,6 +20,20 @@ const UNEXPECTED_LINEBREAK = { messageId: "unexpected" };
 
 const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
 
+/**
+ * Prevents leading spaces in a multiline template literal from appearing in the resulting string
+ * @param {string[]} strings The strings in the template literal
+ * @returns {string} The template literal, with spaces removed from all lines
+ */
+function unIndent(strings) {
+    const templateValue = strings[0];
+    const lines = templateValue.replace(/^\n/u, "").replace(/\n\s*$/u, "").split("\n");
+    const lineIndents = lines.filter(line => line.trim()).map(line => line.match(/ */u)[0].length);
+    const minLineIndent = Math.min(...lineIndents);
+
+    return lines.map(line => line.slice(minLineIndent)).join("\n");
+}
+
 ruleTester.run("implicit-arrow-linebreak", rule, {
 
     valid: [
@@ -48,7 +62,7 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
             bar => (
                 // another comment
                 baz
-            )       
+            )
         )
         `,
         `
@@ -59,7 +73,7 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
         `,
         `
         /* text */
-        () => bar; 
+        () => bar;
         `,
         `
         /* foo */
@@ -87,7 +101,7 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
         const foo = {
           id: 'bar',
           // comment
-          prop: (foo1) => 'returning this string', 
+          prop: (foo1) => 'returning this string',
         }
         `,
         `
@@ -104,7 +118,7 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
         {
             code: `
             // comment
-            async foo => 'string'        
+            async foo => 'string'
             `,
             parserOptions: { ecmaVersion: 8 }
         },
@@ -200,26 +214,20 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
             `,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
+            code: unIndent`
                 (foo) =>
                   // test comment
                   bar
             `,
-            output: `
-                // test comment
-                (foo) => bar
-            `,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
+            code: unIndent`
                 const foo = () =>
                 // comment
                 []
             `,
-            output: `
-                // comment
-                const foo = () => []
-            `,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
             code: `
@@ -243,83 +251,63 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
                         bar
                     //comment
                     )
-            
+
             `,
             output: `
                 (foo) => (
                         bar
                     //comment
                     )
-            
+
             `,
             errors: [UNEXPECTED_LINEBREAK]
 
         }, {
-            code: `
-            (foo) =>
-             // comment
-             // another comment
-                bar`,
-            output: `
-            // comment
-            // another comment
-            (foo) => bar`,
+            code: unIndent`
+                (foo) =>
+                 // comment
+                 // another comment
+                    bar`,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-            (foo) =>
-            // comment
-            (
-            // another comment
-            bar
-            )`,
-            output: `
-            // comment
-            (foo) => (
-            // another comment
-            bar
-            )`,
+            code: unIndent`
+                (foo) =>
+                // comment
+                (
+                // another comment
+                bar
+                )`,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK]
         },
         {
             code: "() => // comment \n bar",
-            output: "// comment \n() => bar",
+            output: null,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
             code: "(foo) => //comment \n bar",
-            output: "//comment \n(foo) => bar",
+            output: null,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
+            code: unIndent`
                 (foo) =>
                   /* test comment */
                   bar
             `,
-            output: `
-                /* test comment */
-                (foo) => bar
-            `,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
+            code: unIndent`
                 (foo) =>
                   // hi
                      bar =>
                        // there
-                         baz;
-            `,
-            output: `
-                (foo) => (
-                  // hi
-                     bar => (
-                       // there
-                         baz
-                     )
-                 );
-            `,
+                         baz;`,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK, UNEXPECTED_LINEBREAK]
         }, {
-            code: `
+            code: unIndent`
                 (foo) =>
                   // hi
                      bar => (
@@ -327,74 +315,48 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
                          baz
                      )
             `,
-            output: `
-                (foo) => (
-                  // hi
-                     bar => (
-                       // there
-                         baz
-                     )
-                 )
-            `,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-            const foo = {
-              id: 'bar',
-              prop: (foo1) =>
-                // comment
-                'returning this string', 
-            }
-            `,
-            output: `
-            const foo = {
-              id: 'bar',
-              // comment
-              prop: (foo1) => 'returning this string', 
-            }
+            code: unIndent`
+                const foo = {
+                  id: 'bar',
+                  prop: (foo1) =>
+                    // comment
+                    'returning this string',
+                }
             `,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-            [ foo => 
-              // comment
-              'bar'
-            ]
-            `,
-            output: `
-            [ // comment
-              foo => 'bar'
-            ]
+            code: unIndent`
+                [ foo =>
+                  // comment
+                  'bar'
+                ]
             `,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-             "foo".split('').map((char) =>
+            code: unIndent`
+                "foo".split('').map((char) =>
                 // comment
                 char
-             )
-            `,
-            output: `
-             // comment
-             "foo".split('').map((char) => char
-             )
+                )
             `,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
+            code: unIndent`
                 new Promise((resolve, reject) =>
                     // comment
                     resolve()
                 )
             `,
-            output: `
-                new Promise(// comment
-                            (resolve, reject) => resolve()
-                )
-            `,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
+            code: unIndent`
                 () =>
                 /*
                 succinct
@@ -403,17 +365,10 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
                 */
                 bar
             `,
-            output: `
-                /*
-                succinct
-                explanation
-                of code
-                */
-                () => bar
-            `,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
+            code: unIndent`
                 stepOne =>
                     /*
                     here is
@@ -423,147 +378,124 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
                     stepTwo =>
                         // then this happens
                         stepThree`,
-            output: `
-                stepOne => (
-                    /*
-                    here is
-                    what is
-                    happening
-                    */
-                    stepTwo => (
-                        // then this happens
-                        stepThree
-                    )
-                )`,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK, UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-            () =>
-                /*
-                multi
-                line
-                */
-                bar =>
-                    /*
-                    many
-                    lines
-                    */
-                    baz
-            `,
-            output: `
-            () => (
-                /*
-                multi
-                line
-                */
-                bar => (
+            code: unIndent`
+                () =>
                     /*
-                    many
-                    lines
+                    multi
+                    line
                     */
-                    baz
-                )
-            )
+                    bar =>
+                        /*
+                        many
+                        lines
+                        */
+                        baz
             `,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK, UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-               foo('', boo =>
+            code: unIndent`
+                foo('', boo =>
                   // comment
                   bar
-               )
-            `,
-            output: `
-               // comment
-               foo('', boo => bar
-               )
+                )
             `,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-            async foo =>
-                // comment
-                'string'
-            `,
-            output: `
-            // comment
-            async foo => 'string'
+            code: unIndent`
+                async foo =>
+                    // comment
+                    'string'
             `,
+            output: null,
             parserOptions: { ecmaVersion: 8 },
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-            async foo =>
-                // comment
-                // another
-                bar;
-            `,
-            output: `
-            // comment
-            // another
-            async foo => bar;
+            code: unIndent`
+                async foo =>
+                    // comment
+                    // another
+                    bar;
             `,
+            output: null,
             parserOptions: { ecmaVersion: 8 },
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-            async (foo) =>
-                // comment
-                'string'
-            `,
-            output: `
-            // comment
-            async (foo) => 'string'
+            code: unIndent`
+                async (foo) =>
+                    // comment
+                    'string'
             `,
+            output: null,
             parserOptions: { ecmaVersion: 8 },
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-              const foo = 1,
+            code: unIndent`
+                const foo = 1,
                   bar = 2,
                   baz = () => // comment
                     qux
             `,
-            output: `
-              const foo = 1,
-                  bar = 2,
-                  // comment
-                  baz = () => qux
-            `,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-              const foo = () =>
+            code: unIndent`
+                const foo = () =>
                   //comment
                   qux,
                   bar = 2,
                   baz = 3
             `,
-            output: `
-              //comment
-              const foo = () => qux,
-                  bar = 2,
-                  baz = 3
-            `,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-            const foo = () =>
-                //two
-                1,
-                boo = () => 
-                //comment
-                2,
-                bop = "what"
-            `,
-            output: `
-            //two
-            const foo = () => 1,
-                //comment
-                boo = () => 2,
-                bop = "what"
+            code: unIndent`
+                const foo = () =>
+                    //two
+                    1,
+                    boo = () =>
+                    //comment
+                    2,
+                    bop = "what"
             `,
+            output: null,
             errors: [UNEXPECTED_LINEBREAK, UNEXPECTED_LINEBREAK]
+        }, {
+            code: unIndent`
+                start()
+                    .then(() =>
+                        /* If I put a comment here, eslint --fix breaks badly */
+                        process && typeof process.send === 'function' && process.send('ready')
+                    )
+                    .catch(err => {
+                    /* catch seems to be needed here */
+                    console.log('Error: ', err)
+                    })`,
+            output: null,
+            errors: [UNEXPECTED_LINEBREAK]
+        }, {
+            code: unIndent`
+            hello(response =>
+                // comment
+                response, param => param)`,
+            output: null,
+            errors: [UNEXPECTED_LINEBREAK]
+        }, {
+            code: unIndent`
+            start(
+                arr =>
+                    // cometh
+                    bod => {
+                        // soon
+                        yyyy
+                    }
+            )`,
+            output: null,
+            errors: [UNEXPECTED_LINEBREAK]
         },
 
         // 'below' option
diff --git a/tests/lib/rules/indent.js b/tests/lib/rules/indent.js
index 45abc654d..7d5210b45 100644
--- a/tests/lib/rules/indent.js
+++ b/tests/lib/rules/indent.js
@@ -8686,8 +8686,8 @@ ruleTester.run("indent", rule, {
                     }
                 }
             `,
-            errors: expectedErrors([[3, 8, 4, "Identifier"], [6, 8, 4, "Keyword"]]),
-            parser: parser("unknown-nodes/namespace-invalid")
+            parser: parser("unknown-nodes/namespace-invalid"),
+            errors: expectedErrors([[3, 8, 4, "Identifier"], [6, 8, 4, "Keyword"]])
         },
         {
             code: unIndent`
@@ -8718,8 +8718,8 @@ ruleTester.run("indent", rule, {
                     }
                 }
             `,
-            errors: expectedErrors([[4, 12, 8, "Identifier"], [7, 12, 8, "Identifier"], [10, 8, 4, "Identifier"]]),
-            parser: parser("unknown-nodes/abstract-class-invalid")
+            parser: parser("unknown-nodes/abstract-class-invalid"),
+            errors: expectedErrors([[4, 12, 8, "Identifier"], [7, 12, 8, "Identifier"], [10, 8, 4, "Identifier"]])
         },
         {
             code: unIndent`
@@ -8748,14 +8748,14 @@ ruleTester.run("indent", rule, {
                     }
                 }
             `,
+            parser: parser("unknown-nodes/functions-with-abstract-class-invalid"),
             errors: expectedErrors([
                 [4, 12, 8, "Keyword"],
                 [5, 16, 8, "Keyword"],
                 [6, 20, 8, "Identifier"],
                 [7, 16, 8, "Punctuator"],
                 [8, 12, 8, "Punctuator"]
-            ]),
-            parser: parser("unknown-nodes/functions-with-abstract-class-invalid")
+            ])
         },
         {
             code: unIndent`
@@ -8788,11 +8788,11 @@ ruleTester.run("indent", rule, {
                     }
                 }
             `,
+            parser: parser("unknown-nodes/namespace-with-functions-with-abstract-class-invalid"),
             errors: expectedErrors([
                 [3, 8, 4, "Keyword"],
                 [7, 24, 20, "Identifier"]
-            ]),
-            parser: parser("unknown-nodes/namespace-with-functions-with-abstract-class-invalid")
+            ])
         },
 
         //----------------------------------------------------------------------
@@ -9369,8 +9369,8 @@ ruleTester.run("indent", rule, {
                     foo
                 }: bar) => baz
             `,
-            errors: expectedErrors([3, 0, 4, "Punctuator"]),
-            parser: require.resolve("../../fixtures/parsers/babel-eslint7/object-pattern-with-annotation")
+            parser: require.resolve("../../fixtures/parsers/babel-eslint7/object-pattern-with-annotation"),
+            errors: expectedErrors([3, 0, 4, "Punctuator"])
         },
         {
             code: unIndent`
@@ -9383,8 +9383,8 @@ ruleTester.run("indent", rule, {
                     foo
                 ]: bar) => baz
             `,
-            errors: expectedErrors([3, 0, 4, "Punctuator"]),
-            parser: require.resolve("../../fixtures/parsers/babel-eslint7/array-pattern-with-annotation")
+            parser: require.resolve("../../fixtures/parsers/babel-eslint7/array-pattern-with-annotation"),
+            errors: expectedErrors([3, 0, 4, "Punctuator"])
         },
         {
             code: unIndent`
@@ -9397,8 +9397,8 @@ ruleTester.run("indent", rule, {
                     foo
                 }: {}) => baz
             `,
-            errors: expectedErrors([3, 0, 4, "Punctuator"]),
-            parser: require.resolve("../../fixtures/parsers/babel-eslint7/object-pattern-with-object-annotation")
+            parser: require.resolve("../../fixtures/parsers/babel-eslint7/object-pattern-with-object-annotation"),
+            errors: expectedErrors([3, 0, 4, "Punctuator"])
         },
         {
             code: unIndent`
diff --git a/tests/lib/rules/keyword-spacing.js b/tests/lib/rules/keyword-spacing.js
index 5e6a0d837..a2b7d2f8a 100644
--- a/tests/lib/rules/keyword-spacing.js
+++ b/tests/lib/rules/keyword-spacing.js
@@ -3135,8 +3135,8 @@ ruleTester.run("keyword-spacing", rule, {
         {
             code: "class Foo { @desc({set a(value) {}, get a() {}, async c() {}}) async[foo]() {} }",
             output: "class Foo { @desc({set a(value) {}, get a() {}, async c() {}}) async [foo]() {} }",
-            errors: expectedAfter("async"),
-            parser: parser("typescript-parsers/decorator-with-keywords-class-method")
+            parser: parser("typescript-parsers/decorator-with-keywords-class-method"),
+            errors: expectedAfter("async")
         }
     ]
 });
diff --git a/tests/lib/rules/no-console.js b/tests/lib/rules/no-console.js
index 76a39227e..5241acc25 100644
--- a/tests/lib/rules/no-console.js
+++ b/tests/lib/rules/no-console.js
@@ -58,6 +58,6 @@ ruleTester.run("no-console", rule, {
         { code: "console.warn(foo)", options: [{ allow: ["info", "log"] }], errors: [{ messageId: "unexpected", type: "MemberExpression" }] },
 
         // In case that implicit global variable of 'console' exists
-        { code: "console.log(foo)", errors: [{ messageId: "unexpected", type: "MemberExpression" }], env: { node: true } }
+        { code: "console.log(foo)", env: { node: true }, errors: [{ messageId: "unexpected", type: "MemberExpression" }] }
     ]
 });
diff --git a/tests/lib/rules/no-eval.js b/tests/lib/rules/no-eval.js
index d31c726b9..5421bbcc8 100644
--- a/tests/lib/rules/no-eval.js
+++ b/tests/lib/rules/no-eval.js
@@ -72,17 +72,17 @@ ruleTester.run("no-eval", rule, {
 
         // Indirect eval
         { code: "(0, eval)('foo')", errors: [{ messageId: "unexpected", type: "Identifier" }] },
-        { code: "(0, window.eval)('foo')", errors: [{ messageId: "unexpected", type: "MemberExpression" }], env: { browser: true } },
-        { code: "(0, window['eval'])('foo')", errors: [{ messageId: "unexpected", type: "MemberExpression" }], env: { browser: true } },
+        { code: "(0, window.eval)('foo')", env: { browser: true }, errors: [{ messageId: "unexpected", type: "MemberExpression" }] },
+        { code: "(0, window['eval'])('foo')", env: { browser: true }, errors: [{ messageId: "unexpected", type: "MemberExpression" }] },
         { code: "var EVAL = eval; EVAL('foo')", errors: [{ messageId: "unexpected", type: "Identifier" }] },
         { code: "var EVAL = this.eval; EVAL('foo')", errors: [{ messageId: "unexpected", type: "MemberExpression" }] },
         { code: "(function(exe){ exe('foo') })(eval);", errors: [{ messageId: "unexpected", type: "Identifier" }] },
-        { code: "window.eval('foo')", errors: [{ messageId: "unexpected", type: "CallExpression" }], env: { browser: true } },
-        { code: "window.window.eval('foo')", errors: [{ messageId: "unexpected", type: "CallExpression" }], env: { browser: true } },
-        { code: "window.window['eval']('foo')", errors: [{ messageId: "unexpected", type: "CallExpression" }], env: { browser: true } },
-        { code: "global.eval('foo')", errors: [{ messageId: "unexpected", type: "CallExpression" }], env: { node: true } },
-        { code: "global.global.eval('foo')", errors: [{ messageId: "unexpected", type: "CallExpression" }], env: { node: true } },
-        { code: "global.global[`eval`]('foo')", parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpected", type: "CallExpression" }], env: { node: true } },
+        { code: "window.eval('foo')", env: { browser: true }, errors: [{ messageId: "unexpected", type: "CallExpression" }] },
+        { code: "window.window.eval('foo')", env: { browser: true }, errors: [{ messageId: "unexpected", type: "CallExpression" }] },
+        { code: "window.window['eval']('foo')", env: { browser: true }, errors: [{ messageId: "unexpected", type: "CallExpression" }] },
+        { code: "global.eval('foo')", env: { node: true }, errors: [{ messageId: "unexpected", type: "CallExpression" }] },
+        { code: "global.global.eval('foo')", env: { node: true }, errors: [{ messageId: "unexpected", type: "CallExpression" }] },
+        { code: "global.global[`eval`]('foo')", parserOptions: { ecmaVersion: 6 }, env: { node: true }, errors: [{ messageId: "unexpected", type: "CallExpression" }] },
         { code: "this.eval('foo')", errors: [{ messageId: "unexpected", type: "CallExpression" }] },
         { code: "function foo() { this.eval('foo') }", errors: [{ messageId: "unexpected", type: "CallExpression" }] }
     ]
diff --git a/tests/lib/rules/no-global-assign.js b/tests/lib/rules/no-global-assign.js
index 3cd792637..051752db0 100644
--- a/tests/lib/rules/no-global-assign.js
+++ b/tests/lib/rules/no-global-assign.js
@@ -42,18 +42,18 @@ ruleTester.run("no-global-assign", rule, {
         },
         {
             code: "top = 0;",
-            errors: [{ message: "Read-only global 'top' should not be modified.", type: "Identifier" }],
-            env: { browser: true }
+            env: { browser: true },
+            errors: [{ message: "Read-only global 'top' should not be modified.", type: "Identifier" }]
         },
         {
             code: "require = 0;",
-            errors: [{ message: "Read-only global 'require' should not be modified.", type: "Identifier" }],
-            env: { node: true }
+            env: { node: true },
+            errors: [{ message: "Read-only global 'require' should not be modified.", type: "Identifier" }]
         },
 
         // Notifications of readonly are moved from no-undef: https://github.com/eslint/eslint/issues/4504
         { code: "/*global b:false*/ function f() { b = 1; }", errors: [{ message: "Read-only global 'b' should not be modified.", type: "Identifier" }] },
-        { code: "function f() { b = 1; }", errors: [{ message: "Read-only global 'b' should not be modified.", type: "Identifier" }], globals: { b: false } },
+        { code: "function f() { b = 1; }", globals: { b: false }, errors: [{ message: "Read-only global 'b' should not be modified.", type: "Identifier" }] },
         { code: "/*global b:false*/ function f() { b++; }", errors: [{ message: "Read-only global 'b' should not be modified.", type: "Identifier" }] },
         { code: "/*global b*/ b = 1;", errors: [{ message: "Read-only global 'b' should not be modified.", type: "Identifier" }] },
         { code: "Array = 1;", errors: [{ message: "Read-only global 'Array' should not be modified.", type: "Identifier" }] }
diff --git a/tests/lib/rules/no-magic-numbers.js b/tests/lib/rules/no-magic-numbers.js
index 34b1e2f6a..beb0282db 100644
--- a/tests/lib/rules/no-magic-numbers.js
+++ b/tests/lib/rules/no-magic-numbers.js
@@ -83,8 +83,8 @@ ruleTester.run("no-magic-numbers", rule, {
             options: [{
                 enforceConst: true
             }],
-            errors: [{ messageId: "useConst" }],
-            env: { es6: true }
+            env: { es6: true },
+            errors: [{ messageId: "useConst" }]
         },
         {
             code: "var foo = 0 + 1;",
@@ -189,6 +189,7 @@ ruleTester.run("no-magic-numbers", rule, {
                 "function invokeInTen(func) {\n" +
                   "setTimeout(func, 10);\n" +
                 "}\n",
+            env: { es6: true },
             errors: [
                 { messageId: "noMagic", data: { raw: "10" }, line: 7 },
                 { messageId: "noMagic", data: { raw: "10" }, line: 7 },
@@ -196,8 +197,7 @@ ruleTester.run("no-magic-numbers", rule, {
                 { messageId: "noMagic", data: { raw: "1000" }, line: 15 },
                 { messageId: "noMagic", data: { raw: "0" }, line: 19 },
                 { messageId: "noMagic", data: { raw: "10" }, line: 22 }
-            ],
-            env: { es6: true }
+            ]
         },
         {
             code: "var data = ['foo', 'bar', 'baz']; var third = data[3];",
diff --git a/tests/lib/rules/no-mixed-spaces-and-tabs.js b/tests/lib/rules/no-mixed-spaces-and-tabs.js
index f427a6f1c..8badf704a 100644
--- a/tests/lib/rules/no-mixed-spaces-and-tabs.js
+++ b/tests/lib/rules/no-mixed-spaces-and-tabs.js
@@ -136,6 +136,7 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
         {
             code: "`foo${\n \t  5 }bar`;",
             options: ["smart-tabs"],
+            env: { es6: true },
             errors: [
                 {
                     message: "Mixed spaces and tabs.",
@@ -143,11 +144,11 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                     line: 2,
                     column: 2
                 }
-            ],
-            env: { es6: true }
+            ]
         },
         {
             code: "`foo${\n\t  5 }bar`;",
+            env: { es6: true },
             errors: [
                 {
                     message: "Mixed spaces and tabs.",
@@ -155,8 +156,7 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                     line: 2,
                     column: 2
                 }
-            ],
-            env: { es6: true }
+            ]
         }
     ]
 });
diff --git a/tests/lib/rules/no-native-reassign.js b/tests/lib/rules/no-native-reassign.js
index ce6f4756f..eaf763bb7 100644
--- a/tests/lib/rules/no-native-reassign.js
+++ b/tests/lib/rules/no-native-reassign.js
@@ -43,18 +43,18 @@ ruleTester.run("no-native-reassign", rule, {
         },
         {
             code: "top = 0;",
-            errors: [{ message: "Read-only global 'top' should not be modified.", type: "Identifier" }],
-            env: { browser: true }
+            env: { browser: true },
+            errors: [{ message: "Read-only global 'top' should not be modified.", type: "Identifier" }]
         },
         {
             code: "require = 0;",
-            errors: [{ message: "Read-only global 'require' should not be modified.", type: "Identifier" }],
-            env: { node: true }
+            env: { node: true },
+            errors: [{ message: "Read-only global 'require' should not be modified.", type: "Identifier" }]
         },
 
         // Notifications of readonly are moved from no-undef: https://github.com/eslint/eslint/issues/4504
         { code: "/*global b:false*/ function f() { b = 1; }", errors: [{ message: "Read-only global 'b' should not be modified.", type: "Identifier" }] },
-        { code: "function f() { b = 1; }", errors: [{ message: "Read-only global 'b' should not be modified.", type: "Identifier" }], globals: { b: false } },
+        { code: "function f() { b = 1; }", globals: { b: false }, errors: [{ message: "Read-only global 'b' should not be modified.", type: "Identifier" }] },
         { code: "/*global b:false*/ function f() { b++; }", errors: [{ message: "Read-only global 'b' should not be modified.", type: "Identifier" }] },
         { code: "/*global b*/ b = 1;", errors: [{ message: "Read-only global 'b' should not be modified.", type: "Identifier" }] },
         { code: "Array = 1;", errors: [{ message: "Read-only global 'Array' should not be modified.", type: "Identifier" }] }
diff --git a/tests/lib/rules/no-redeclare.js b/tests/lib/rules/no-redeclare.js
index 2cd0f8ef5..23a45f021 100644
--- a/tests/lib/rules/no-redeclare.js
+++ b/tests/lib/rules/no-redeclare.js
@@ -62,8 +62,8 @@ ruleTester.run("no-redeclare", rule, {
         {
             code: "var top = 0;",
             options: [{ builtinGlobals: true }],
-            errors: [{ message: "'top' is already defined.", type: "Identifier" }],
-            env: { browser: true }
+            env: { browser: true },
+            errors: [{ message: "'top' is already defined.", type: "Identifier" }]
         },
         {
             code: "var a; var {a = 0, b: Object = 0} = {};",
diff --git a/tests/lib/rules/no-restricted-globals.js b/tests/lib/rules/no-restricted-globals.js
index 8d4a69941..0e09be169 100644
--- a/tests/lib/rules/no-restricted-globals.js
+++ b/tests/lib/rules/no-restricted-globals.js
@@ -70,20 +70,20 @@ ruleTester.run("no-restricted-globals", rule, {
         {
             code: "function fn() { foo; }",
             options: ["foo"],
-            errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }],
-            globals: { foo: false }
+            globals: { foo: false },
+            errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }]
         },
         {
             code: "event",
             options: ["foo", "event"],
-            errors: [{ message: "Unexpected use of 'event'.", type: "Identifier" }],
-            env: { browser: true }
+            env: { browser: true },
+            errors: [{ message: "Unexpected use of 'event'.", type: "Identifier" }]
         },
         {
             code: "foo",
             options: ["foo"],
-            errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }],
-            globals: { foo: false }
+            globals: { foo: false },
+            errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }]
         },
         {
             code: "foo()",
@@ -108,20 +108,20 @@ ruleTester.run("no-restricted-globals", rule, {
         {
             code: "function fn() { foo; }",
             options: [{ name: "foo" }],
-            errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }],
-            globals: { foo: false }
+            globals: { foo: false },
+            errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }]
         },
         {
             code: "event",
             options: ["foo", { name: "event" }],
-            errors: [{ message: "Unexpected use of 'event'.", type: "Identifier" }],
-            env: { browser: true }
+            env: { browser: true },
+            errors: [{ message: "Unexpected use of 'event'.", type: "Identifier" }]
         },
         {
             code: "foo",
             options: [{ name: "foo" }],
-            errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }],
-            globals: { foo: false }
+            globals: { foo: false },
+            errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }]
         },
         {
             code: "foo()",
@@ -146,20 +146,20 @@ ruleTester.run("no-restricted-globals", rule, {
         {
             code: "function fn() { foo; }",
             options: [{ name: "foo", message: "Use bar instead." }],
-            errors: [{ message: "Unexpected use of 'foo'. Use bar instead.", type: "Identifier" }],
-            globals: { foo: false }
+            globals: { foo: false },
+            errors: [{ message: "Unexpected use of 'foo'. Use bar instead.", type: "Identifier" }]
         },
         {
             code: "event",
             options: ["foo", { name: "event", message: "Use local event parameter." }],
-            errors: [{ message: "Unexpected use of 'event'. Use local event parameter.", type: "Identifier" }],
-            env: { browser: true }
+            env: { browser: true },
+            errors: [{ message: "Unexpected use of 'event'. Use local event parameter.", type: "Identifier" }]
         },
         {
             code: "foo",
             options: [{ name: "foo", message: "Use bar instead." }],
-            errors: [{ message: "Unexpected use of 'foo'. Use bar instead.", type: "Identifier" }],
-            globals: { foo: false }
+            globals: { foo: false },
+            errors: [{ message: "Unexpected use of 'foo'. Use bar instead.", type: "Identifier" }]
         },
         {
             code: "foo()",
diff --git a/tests/lib/rules/no-sequences.js b/tests/lib/rules/no-sequences.js
index 1ab5ed42e..a32400b2f 100644
--- a/tests/lib/rules/no-sequences.js
+++ b/tests/lib/rules/no-sequences.js
@@ -61,6 +61,6 @@ ruleTester.run("no-sequences", rule, {
         { code: "switch (doSomething(), val) {}", errors: errors(22) },
         { code: "while (doSomething(), !!test);", errors: errors(21) },
         { code: "with (doSomething(), val) {}", errors: errors(20) },
-        { code: "a => (doSomething(), a)", errors: errors(20), env: { es6: true } }
+        { code: "a => (doSomething(), a)", env: { es6: true }, errors: errors(20) }
     ]
 });
diff --git a/tests/lib/rules/no-shadow.js b/tests/lib/rules/no-shadow.js
index 071eadd15..18ce5b161 100644
--- a/tests/lib/rules/no-shadow.js
+++ b/tests/lib/rules/no-shadow.js
@@ -299,8 +299,8 @@ ruleTester.run("no-shadow", rule, {
         {
             code: "function foo() { var top = 0; }",
             options: [{ builtinGlobals: true }],
-            errors: [{ message: "'top' is already declared in the upper scope.", type: "Identifier" }],
-            env: { browser: true }
+            env: { browser: true },
+            errors: [{ message: "'top' is already declared in the upper scope.", type: "Identifier" }]
         },
         {
             code: "var Object = 0;",
@@ -312,8 +312,8 @@ ruleTester.run("no-shadow", rule, {
             code: "var top = 0;",
             options: [{ builtinGlobals: true }],
             parserOptions: { sourceType: "module" },
-            errors: [{ message: "'top' is already declared in the upper scope.", type: "Identifier" }],
-            env: { browser: true }
+            env: { browser: true },
+            errors: [{ message: "'top' is already declared in the upper scope.", type: "Identifier" }]
         },
         {
             code: "var Object = 0;",
@@ -325,8 +325,8 @@ ruleTester.run("no-shadow", rule, {
             code: "var top = 0;",
             options: [{ builtinGlobals: true }],
             parserOptions: { ecmaFeatures: { globalReturn: true } },
-            errors: [{ message: "'top' is already declared in the upper scope.", type: "Identifier" }],
-            env: { browser: true }
+            env: { browser: true },
+            errors: [{ message: "'top' is already declared in the upper scope.", type: "Identifier" }]
         },
         {
             code: "function foo(cb) { (function (cb) { cb(42); })(cb); }",
diff --git a/tests/lib/rules/no-unused-vars.js b/tests/lib/rules/no-unused-vars.js
index 9b6733cac..3012dec63 100644
--- a/tests/lib/rules/no-unused-vars.js
+++ b/tests/lib/rules/no-unused-vars.js
@@ -477,10 +477,10 @@ ruleTester.run("no-unused-vars", rule, {
         // surrogate pair.
         {
             code: "/*global 𠮷𩸽, 𠮷*/\n\\u{20BB7}\\u{29E3D};",
+            env: { es6: true },
             errors: [
                 { line: 1, column: 16, message: "'𠮷' is defined but never used." }
-            ],
-            env: { es6: true }
+            ]
         },
 
         // https://github.com/eslint/eslint/issues/4047
diff --git a/tests/lib/rules/object-curly-newline.js b/tests/lib/rules/object-curly-newline.js
index 072ca1611..8cf75265a 100644
--- a/tests/lib/rules/object-curly-newline.js
+++ b/tests/lib/rules/object-curly-newline.js
@@ -670,11 +670,11 @@ ruleTester.run("object-curly-newline", rule, {
                 "} : MyType) {}"
             ].join("\n"),
             options: ["always"],
+            parser: resolvePath(__dirname, "../../fixtures/parsers/object-curly-newline/flow-stub-parser-singleline"),
             errors: [
                 { line: 1, column: 14, message: "Expected a line break after this opening brace." },
                 { line: 1, column: 21, message: "Expected a line break before this closing brace." }
-            ],
-            parser: resolvePath(__dirname, "../../fixtures/parsers/object-curly-newline/flow-stub-parser-singleline")
+            ]
         },
         {
             code: "function foo({ a, b } : { a : string, b : string }) {}",
@@ -684,11 +684,11 @@ ruleTester.run("object-curly-newline", rule, {
                 "} : { a : string, b : string }) {}"
             ].join("\n"),
             options: ["always"],
+            parser: resolvePath(__dirname, "../../fixtures/parsers/object-curly-newline/flow-stub-parser-singleline-type-literal"),
             errors: [
                 { line: 1, column: 14, message: "Expected a line break after this opening brace." },
                 { line: 1, column: 21, message: "Expected a line break before this closing brace." }
-            ],
-            parser: resolvePath(__dirname, "../../fixtures/parsers/object-curly-newline/flow-stub-parser-singleline-type-literal")
+            ]
         },
 
         // "never" ------------------------------------------------------------
@@ -784,11 +784,11 @@ ruleTester.run("object-curly-newline", rule, {
                 " b} : MyType) {}"
             ].join("\n"),
             options: ["never"],
+            parser: resolvePath(__dirname, "../../fixtures/parsers/object-curly-newline/flow-stub-parser-multiline"),
             errors: [
                 { line: 1, column: 14, message: "Unexpected line break after this opening brace." },
                 { line: 4, column: 1, message: "Unexpected line break before this closing brace." }
-            ],
-            parser: resolvePath(__dirname, "../../fixtures/parsers/object-curly-newline/flow-stub-parser-multiline")
+            ]
         },
         {
             code: [
@@ -802,11 +802,11 @@ ruleTester.run("object-curly-newline", rule, {
                 " b} : { a : string, b : string }) {}"
             ].join("\n"),
             options: ["never"],
+            parser: resolvePath(__dirname, "../../fixtures/parsers/object-curly-newline/flow-stub-parser-multiline-type-literal"),
             errors: [
                 { line: 1, column: 14, message: "Unexpected line break after this opening brace." },
                 { line: 4, column: 1, message: "Unexpected line break before this closing brace." }
-            ],
-            parser: resolvePath(__dirname, "../../fixtures/parsers/object-curly-newline/flow-stub-parser-multiline-type-literal")
+            ]
         },
 
         // "multiline" ---------------------------------------------------------
diff --git a/tests/lib/rules/object-curly-spacing.js b/tests/lib/rules/object-curly-spacing.js
index c016b731b..3595ff6b5 100644
--- a/tests/lib/rules/object-curly-spacing.js
+++ b/tests/lib/rules/object-curly-spacing.js
@@ -768,13 +768,13 @@ ruleTester.run("object-curly-spacing", rule, {
             code: "function foo ({a, b }: Props) {\n}",
             output: "function foo ({a, b}: Props) {\n}",
             options: ["never"],
+            parser: resolvePath(__dirname, "../../fixtures/parsers/object-curly-spacing/flow-stub-parser-never-invalid"),
             errors: [
                 {
                     message: "There should be no space before '}'.",
                     type: "ObjectPattern"
                 }
-            ],
-            parser: resolvePath(__dirname, "../../fixtures/parsers/object-curly-spacing/flow-stub-parser-never-invalid")
+            ]
         }
     ]
 });
diff --git a/tests/lib/rules/prefer-const.js b/tests/lib/rules/prefer-const.js
index 699feb6cf..66eec8c53 100644
--- a/tests/lib/rules/prefer-const.js
+++ b/tests/lib/rules/prefer-const.js
@@ -383,8 +383,8 @@ ruleTester.run("prefer-const", rule, {
             code: "let { name, ...otherStuff } = obj; otherStuff = {};",
             output: null,
             options: [{ destructuring: "any" }],
-            errors: [{ messageId: "useConst", data: { name: "name" }, type: "Identifier", column: 7 }],
-            parser: fixtureParser("babel-eslint5/destructuring-object-spread")
+            parser: fixtureParser("babel-eslint5/destructuring-object-spread"),
+            errors: [{ messageId: "useConst", data: { name: "name" }, type: "Identifier", column: 7 }]
         },
 
         // Warnings are located at declaration if there are reading references before assignments.
diff --git a/tests/lib/rules/quote-props.js b/tests/lib/rules/quote-props.js
index 6291960d3..fa8037b7c 100644
--- a/tests/lib/rules/quote-props.js
+++ b/tests/lib/rules/quote-props.js
@@ -148,18 +148,18 @@ ruleTester.run("quote-props", rule, {
         code: "({ 'a': 0, [x]: 0 })",
         output: "({ a: 0, [x]: 0 })",
         options: ["consistent-as-needed"],
+        env: { es6: true },
         errors: [
             { message: "Properties shouldn't be quoted as all quotes are redundant.", type: "Property" }
-        ],
-        env: { es6: true }
+        ]
     }, {
         code: "({ 'a': 0, x })",
         output: "({ a: 0, x })",
         options: ["consistent-as-needed"],
+        env: { es6: true },
         errors: [{
             message: "Properties shouldn't be quoted as all quotes are redundant.", type: "Property"
-        }],
-        env: { es6: true }
+        }]
     }, {
         code: "({ 'true': 0, 'null': 0 })",
         output: "({ true: 0, null: 0 })",
diff --git a/tests/lib/rules/require-unicode-regexp.js b/tests/lib/rules/require-unicode-regexp.js
index a261c86e3..b6ac758d1 100644
--- a/tests/lib/rules/require-unicode-regexp.js
+++ b/tests/lib/rules/require-unicode-regexp.js
@@ -78,13 +78,13 @@ ruleTester.run("require-unicode-regexp", rule, {
         },
         {
             code: "new window.RegExp('foo')",
-            errors: [{ messageId: "requireUFlag" }],
-            env: { browser: true }
+            env: { browser: true },
+            errors: [{ messageId: "requireUFlag" }]
         },
         {
             code: "new global.RegExp('foo')",
-            errors: [{ messageId: "requireUFlag" }],
-            env: { node: true }
+            env: { node: true },
+            errors: [{ messageId: "requireUFlag" }]
         }
     ]
 });
diff --git a/tests/lib/rules/space-infix-ops.js b/tests/lib/rules/space-infix-ops.js
index 76939f7fe..8932997e2 100644
--- a/tests/lib/rules/space-infix-ops.js
+++ b/tests/lib/rules/space-infix-ops.js
@@ -41,13 +41,13 @@ ruleTester.run("space-infix-ops", rule, {
         { code: "a |0", options: [{ int32Hint: true }] },
 
         // Type Annotations
-        { code: "function foo(a: number = 0) { }", parserOptions: { ecmaVersion: 6 }, parser: parser("type-annotations/function-parameter-type-annotation") },
-        { code: "function foo(): Bar { }", parserOptions: { ecmaVersion: 6 }, parser: parser("type-annotations/function-return-type-annotation") },
-        { code: "var foo: Bar = '';", parserOptions: { ecmaVersion: 6 }, parser: parser("type-annotations/variable-declaration-init-type-annotation") },
-        { code: "const foo = function(a: number = 0): Bar { };", parserOptions: { ecmaVersion: 6 }, parser: parser("type-annotations/function-expression-type-annotation") },
+        { code: "function foo(a: number = 0) { }", parser: parser("type-annotations/function-parameter-type-annotation"), parserOptions: { ecmaVersion: 6 } },
+        { code: "function foo(): Bar { }", parser: parser("type-annotations/function-return-type-annotation"), parserOptions: { ecmaVersion: 6 } },
+        { code: "var foo: Bar = '';", parser: parser("type-annotations/variable-declaration-init-type-annotation"), parserOptions: { ecmaVersion: 6 } },
+        { code: "const foo = function(a: number = 0): Bar { };", parser: parser("type-annotations/function-expression-type-annotation"), parserOptions: { ecmaVersion: 6 } },
 
         // TypeScript Type Aliases
-        { code: "type Foo<T> = T;", parserOptions: { ecmaVersion: 6 }, parser: parser("typescript-parsers/type-alias") }
+        { code: "type Foo<T> = T;", parser: parser("typescript-parsers/type-alias"), parserOptions: { ecmaVersion: 6 } }
     ],
     invalid: [
         {
@@ -368,25 +368,25 @@ ruleTester.run("space-infix-ops", rule, {
         {
             code: "var a: Foo= b;",
             output: "var a: Foo = b;",
+            parser: parser("type-annotations/variable-declaration-init-type-annotation-no-space"),
             errors: [{
                 message: "Operator '=' must be spaced.",
                 type: "VariableDeclarator",
                 line: 1,
                 column: 11
-            }],
-            parser: parser("type-annotations/variable-declaration-init-type-annotation-no-space")
+            }]
         },
         {
             code: "function foo(a: number=0): Foo { }",
             output: "function foo(a: number = 0): Foo { }",
+            parser: parser("type-annotations/function-declaration-type-annotation-no-space"),
             parserOptions: { ecmaVersion: 6 },
             errors: [{
                 message: "Operator '=' must be spaced.",
                 line: 1,
                 column: 23,
                 nodeType: "AssignmentPattern"
-            }],
-            parser: parser("type-annotations/function-declaration-type-annotation-no-space")
+            }]
         }
     ]
 });
diff --git a/tests/lib/util/glob-utils.js b/tests/lib/util/glob-utils.js
index 6b61f8b40..9bafcfa07 100644
--- a/tests/lib/util/glob-utils.js
+++ b/tests/lib/util/glob-utils.js
@@ -329,6 +329,13 @@ describe("globUtils", () => {
             }, `No files matching '${patterns[0]}' were found.`);
         });
 
+        it("should ignore empty patterns", () => {
+            const patterns = [""];
+            const result = globUtils.listFilesToProcess(patterns);
+
+            assert.deepStrictEqual(result, []);
+        });
+
         it("should return an ignored file, if ignore option is turned off", () => {
             const options = { ignore: false };
             const patterns = [getFixturePath("glob-util", "ignored", "**/*.js")];