Repository: eslint/eslint
Pull request #11511 (2019-03-15 03:18:27)

Chore: make test-case-property-ordering reasonable
**What is the purpose of this pull request? (put an "X" next to item)**

[X] Other, please explain

**What changes did you make? (Give an overview)**

This PR changes the option of `eslint-plugin/test-case-property-ordering` rule in our `.eslintrc.js` to recognize the properties the rule tester is supporting.

**Is there anything you'd like reviewers to focus on?**

Is this order good?


mysticatea: That autofix was really useful. Thank you!
not-an-aardvark: Credit goes to @aladdin-add, I think he implemented the rule and the autofix.

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/CHANGELOG.md b/CHANGELOG.md
index 115a7c3c5..697ba09c4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,23 @@
+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..bd6f46524 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");
 
@@ -440,8 +441,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({
@@ -580,6 +580,19 @@ target.test = function() {
 
     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/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/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..50f645618 100644
--- a/lib/rules/implicit-arrow-linebreak.js
+++ b/lib/rules/implicit-arrow-linebreak.js
@@ -6,8 +6,7 @@
 
 const {
     isArrowToken,
-    isParenthesised,
-    isOpeningParenToken
+    isParenthesised
 } = require("../util/ast-utils");
 
 //------------------------------------------------------------------------------
@@ -57,8 +56,7 @@ module.exports = {
          * @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);
+        function formatComments(comments) {
 
             return `${comments.map(comment => {
 
@@ -67,12 +65,12 @@ module.exports = {
                 }
 
                 return `/*${comment.value}*/`;
-            }).join(`\n${whiteSpaces}`)}\n${whiteSpaces}`;
+            }).join("\n")}\n`;
         }
 
         /**
          * Finds the first token to prepend comments to depending on the parent type
-         * @param {Node} node The validated node
+         * @param {ASTNode} node The validated node
          * @returns {Token|Node} The node to prepend comments to
          */
         function findFirstToken(node) {
@@ -109,24 +107,19 @@ module.exports = {
             let followingBody = arrowBody;
             let currentArrow = arrow;
 
-            while (currentArrow) {
+            while (currentArrow && followingBody.type !== "BlockStatement") {
                 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}`;
+                    closingParentheses = `\n)${closingParentheses}`;
                 }
 
                 currentArrow = sourceCode.getTokenAfter(currentArrow, isArrowToken);
 
                 if (currentArrow) {
-                    followingBody = sourceCode.getTokenAfter(currentArrow, token => !isOpeningParenToken(token));
+                    followingBody = followingBody.body;
                 }
             }
 
@@ -137,10 +130,10 @@ module.exports = {
 
         /**
          * 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.
+         * If comments exist, checks if the function body contains arrow functions, and appends the body with parentheses.
+         * Otherwise, prepends the comments before the arrow function.
          * @param {Token} arrowToken The arrow token.
-         * @param {ASTNode} arrowBody the function body
+         * @param {ASTNode|Token} arrowBody the function body
          * @param {ASTNode} node The evaluated node
          * @returns {Function} autofixer -- validates the node to adhere to besides
          */
@@ -161,23 +154,18 @@ module.exports = {
                     ) {
 
                         // If any arrow functions follow, return the necessary parens fixes.
-                        if (sourceCode.getTokenAfter(arrowToken, isArrowToken) && arrowBody.parent.parent.type !== "VariableDeclarator") {
+                        if (node.body.type === "ArrowFunctionExpression" &&
+                            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
+                        formatComments(comments)
                     );
 
                     return [placeBesides, commentBeforeExpression];
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..9c6229ce6 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint",
-  "version": "5.15.1",
+  "version": "5.15.2",
   "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",
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/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..924455706 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: [
@@ -200,23 +214,23 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
             `,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
+            code: unIndent`
                 (foo) =>
                   // test comment
                   bar
             `,
-            output: `
+            output: unIndent`
                 // test comment
                 (foo) => bar
             `,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
+            code: unIndent`
                 const foo = () =>
                 // comment
                 []
             `,
-            output: `
+            output: unIndent`
                 // comment
                 const foo = () => []
             `,
@@ -255,30 +269,30 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
             errors: [UNEXPECTED_LINEBREAK]
 
         }, {
-            code: `
-            (foo) =>
-             // comment
-             // another comment
-                bar`,
-            output: `
-            // comment
-            // another comment
-            (foo) => bar`,
+            code: unIndent`
+                (foo) =>
+                 // comment
+                 // another comment
+                    bar`,
+            output: unIndent`
+                // comment
+                // another comment
+                (foo) => bar`,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-            (foo) =>
-            // comment
-            (
-            // another comment
-            bar
-            )`,
-            output: `
-            // comment
-            (foo) => (
-            // another comment
-            bar
-            )`,
+            code: unIndent`
+                (foo) =>
+                // comment
+                (
+                // another comment
+                bar
+                )`,
+            output: unIndent`
+                // comment
+                (foo) => (
+                // another comment
+                bar
+                )`,
             errors: [UNEXPECTED_LINEBREAK]
         },
         {
@@ -290,36 +304,34 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
             output: "//comment \n(foo) => bar",
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
+            code: unIndent`
                 (foo) =>
                   /* test comment */
                   bar
             `,
-            output: `
+            output: unIndent`
                 /* test comment */
                 (foo) => bar
             `,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
+            code: unIndent`
                 (foo) =>
                   // hi
                      bar =>
                        // there
-                         baz;
-            `,
-            output: `
+                         baz;`,
+            output: unIndent`
                 (foo) => (
                   // hi
                      bar => (
                        // there
                          baz
-                     )
-                 );
-            `,
+                )
+                );`,
             errors: [UNEXPECTED_LINEBREAK, UNEXPECTED_LINEBREAK]
         }, {
-            code: `
+            code: unIndent`
                 (foo) =>
                   // hi
                      bar => (
@@ -327,74 +339,74 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
                          baz
                      )
             `,
-            output: `
+            output: unIndent`
                 (foo) => (
                   // hi
                      bar => (
                        // there
                          baz
                      )
-                 )
+                )
             `,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-            const foo = {
-              id: 'bar',
-              prop: (foo1) =>
-                // comment
-                'returning this string', 
-            }
+            code: unIndent`
+                const foo = {
+                  id: 'bar',
+                  prop: (foo1) =>
+                    // comment
+                    'returning this string', 
+                }
             `,
-            output: `
-            const foo = {
-              id: 'bar',
-              // comment
-              prop: (foo1) => 'returning this string', 
-            }
+            output: unIndent`
+                const foo = {
+                  id: 'bar',
+                  // comment
+                prop: (foo1) => 'returning this string', 
+                }
             `,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-            [ foo => 
-              // comment
-              'bar'
-            ]
+            code: unIndent`
+                [ foo => 
+                  // comment
+                  'bar'
+                ]
             `,
-            output: `
-            [ // comment
-              foo => 'bar'
-            ]
+            output: unIndent`
+                [ // comment
+                foo => 'bar'
+                ]
             `,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-             "foo".split('').map((char) =>
+            code: unIndent`
+                "foo".split('').map((char) =>
                 // comment
                 char
-             )
+                )
             `,
-            output: `
-             // comment
-             "foo".split('').map((char) => char
-             )
+            output: unIndent`
+                // comment
+                "foo".split('').map((char) => char
+                )
             `,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
+            code: unIndent`
                 new Promise((resolve, reject) =>
                     // comment
                     resolve()
                 )
             `,
-            output: `
+            output: unIndent`
                 new Promise(// comment
-                            (resolve, reject) => resolve()
+                (resolve, reject) => resolve()
                 )
             `,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
+            code: unIndent`
                 () =>
                 /*
                 succinct
@@ -403,7 +415,7 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
                 */
                 bar
             `,
-            output: `
+            output: unIndent`
                 /*
                 succinct
                 explanation
@@ -413,7 +425,7 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
             `,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
+            code: unIndent`
                 stepOne =>
                     /*
                     here is
@@ -423,7 +435,7 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
                     stepTwo =>
                         // then this happens
                         stepThree`,
-            output: `
+            output: unIndent`
                 stepOne => (
                     /*
                     here is
@@ -433,137 +445,188 @@ ruleTester.run("implicit-arrow-linebreak", rule, {
                     stepTwo => (
                         // then this happens
                         stepThree
-                    )
+                )
                 )`,
             errors: [UNEXPECTED_LINEBREAK, UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-            () =>
-                /*
-                multi
-                line
-                */
-                bar =>
+            code: unIndent`
+                () =>
                     /*
-                    many
-                    lines
+                    multi
+                    line
                     */
-                    baz
-            `,
-            output: `
-            () => (
-                /*
-                multi
-                line
-                */
-                bar => (
+                    bar =>
+                        /*
+                        many
+                        lines
+                        */
+                        baz
+            `,
+            output: unIndent`
+                () => (
                     /*
-                    many
-                    lines
+                    multi
+                    line
                     */
-                    baz
+                    bar => (
+                        /*
+                        many
+                        lines
+                        */
+                        baz
+                )
                 )
-            )
             `,
             errors: [UNEXPECTED_LINEBREAK, UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-               foo('', boo =>
+            code: unIndent`
+                foo('', boo =>
                   // comment
                   bar
-               )
+                )
             `,
-            output: `
-               // comment
-               foo('', boo => bar
-               )
+            output: unIndent`
+                // comment
+                foo('', boo => bar
+                )
             `,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-            async foo =>
-                // comment
-                'string'
+            code: unIndent`
+                async foo =>
+                    // comment
+                    'string'
             `,
-            output: `
-            // comment
-            async foo => 'string'
+            output: unIndent`
+                // comment
+                async foo => 'string'
             `,
             parserOptions: { ecmaVersion: 8 },
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-            async foo =>
+            code: unIndent`
+                async foo =>
+                    // comment
+                    // another
+                    bar;
+            `,
+            output: unIndent`
                 // comment
                 // another
-                bar;
-            `,
-            output: `
-            // comment
-            // another
-            async foo => bar;
+                async foo => bar;
             `,
             parserOptions: { ecmaVersion: 8 },
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-            async (foo) =>
-                // comment
-                'string'
+            code: unIndent`
+                async (foo) =>
+                    // comment
+                    'string'
             `,
-            output: `
-            // comment
-            async (foo) => 'string'
+            output: unIndent`
+                // comment
+                async (foo) => 'string'
             `,
             parserOptions: { ecmaVersion: 8 },
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-              const foo = 1,
+            code: unIndent`
+                const foo = 1,
                   bar = 2,
                   baz = () => // comment
                     qux
             `,
-            output: `
-              const foo = 1,
+            output: unIndent`
+                const foo = 1,
                   bar = 2,
                   // comment
-                  baz = () => qux
+                baz = () => qux
             `,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-              const foo = () =>
+            code: unIndent`
+                const foo = () =>
                   //comment
                   qux,
                   bar = 2,
                   baz = 3
             `,
-            output: `
-              //comment
-              const foo = () => qux,
+            output: unIndent`
+                //comment
+                const foo = () => qux,
                   bar = 2,
                   baz = 3
             `,
             errors: [UNEXPECTED_LINEBREAK]
         }, {
-            code: `
-            const foo = () =>
-                //two
-                1,
-                boo = () => 
-                //comment
-                2,
-                bop = "what"
+            code: unIndent`
+                const foo = () =>
+                    //two
+                    1,
+                    boo = () => 
+                    //comment
+                    2,
+                    bop = "what"
             `,
-            output: `
-            //two
-            const foo = () => 1,
-                //comment
+            output: unIndent`
+                //two
+                const foo = () => 1,
+                    //comment
                 boo = () => 2,
-                bop = "what"
+                    bop = "what"
             `,
             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: unIndent`
+                /* If I put a comment here, eslint --fix breaks badly */
+                start()
+                    .then(() => process && typeof process.send === 'function' && process.send('ready')
+                    )
+                    .catch(err => {
+                    /* catch seems to be needed here */
+                    console.log('Error: ', err)
+                    })`,
+            errors: [UNEXPECTED_LINEBREAK]
+        }, {
+            code: unIndent`
+            hello(response =>
+                // comment
+                response, param => param)`,
+            output: unIndent`
+            // comment
+            hello(response => response, param => param)`,
+            errors: [UNEXPECTED_LINEBREAK]
+        }, {
+            code: unIndent`
+            start(
+                arr =>
+                    // cometh
+                    bod => {
+                        // soon
+                        yyyy
+                    }
+            )`,
+            output: unIndent`
+            start(
+                arr => (
+                    // cometh
+                    bod => {
+                        // soon
+                        yyyy
+                    }
+            )
+            )`,
+            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")];