Repository: eslint/eslint (js)

Issue:
space-in-parens throws false positive inside if condition between closing parens
**Tell us about your environment**

* **ESLint Version: 5.6.1**
* **Node Version: 8.11.4**
* **npm Version: 5.6.0**

**What parser (default, Babel-ESLint, etc.) are you using?**
Default

**Please show your full configuration:**
```json
{
  "plugins": [
    "cypress",
    "chai-friendly"
  ],
  "env": {
    "cypress/globals": true
  },
  "extends": [
    "eslint:recommended",
    "standard"
  ],
  "parserOptions": {
    "ecmaVersion": 6,
    "sourceType": "module"
  },
  "globals": {
    "App": true
  },
  "rules": {
    "max-len": [
      "error", {
        "code": 80,
        "tabWidth": 2
      }
    ],
  "space-in-parens": ["error", "never", {
    "exceptions": ["()"]
    }],
  "no-unused-expressions": 0,
  "chai-friendly/no-unused-expressions": 2
  }
}
```

**What did you do? Please include the actual source code causing the issue, as well as the command that you used to run ESLint.**

Code which exhibits the bug:
```js
const theTrueFunc = () => true

// this will complain that there is no space after the function call and the closing if bracket
if (theTrueFunc()) {
  console.log('True dat')
}
```

**What did you expect to happen?**
Should not have to insert space after function

**What actually happened? Please include the actual, raw output from ESLint.**
```
/home/grayedfox/github/comgy/mh-tests/cypress/support/helpers.js
  8:32  error  There must be a space inside this paren  space-in-parens

✖ 1 problem (1 error, 0 warnings)
  1 error and 0 warnings potentially fixable with the `--fix` option.
```

Pull request:
Update: space-in-parens linting messages and report behaviour
<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**What is the purpose of this pull request? (put an "X" next to item)**

- [x] Documentation update
- [x] Changes an existing rule ([template]https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-change-proposal.md))
- [x] Bug fix ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/bug-report.md))

The current space-in-parens description is a little unclear. Technically empty parens can trigger an error if specified in the exceptions options. This PR updates that line in the docs and adds a paragraph that attempts to explain what exactly this rule does. [Current rule description](https://eslint.org/docs/rules/space-in-parens#rule-details).

The linting error messages are now more specific and inform whether the paren token is either rejecting an extra space or missing a required space. Previously the output did not specify if the space was required or missing (so it could be either).

The previous context/report behavior would sometimes report only the first error encountered within a node due to the token checks being nested inside `else if` blocks. This is a non-breaking change: it simply means all errors will be reported within a node instead of only one - it does not introduce a new error type. The fallout of this change is that there is now at least one interesting case: using the default settings `foo( )` technically contains two errors: that single space is both a rejected opening and closing space, so two errors will be reported despite the fact that removing the one space fixes both errors.

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->




Patch:
diff --git a/README.md b/README.md
index d4059d374..134c991d8 100644
--- a/README.md
+++ b/README.md
@@ -264,7 +264,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
 <h3>Gold Sponsors</h3>
 <p><a href="https://www.shopify.com"><img src="https://images.opencollective.com/shopify/eeb91aa/logo.png" alt="Shopify" height="96"></a> <a href="http://engineering.salesforce.com"><img src="https://images.opencollective.com/salesforce/d1b37c4/logo.png" alt="Salesforce" height="96"></a> <a href="https://badoo.com/team?utm_source=eslint"><img src="https://images.opencollective.com/badoo/2826a3b/logo.png" alt="Badoo" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/001a341/logo.png" alt="Airbnb" height="96"></a> <a href="https://code.facebook.com/projects/"><img src="https://images.opencollective.com/fbopensource/fbb8a5b/logo.png" alt="Facebook Open Source" height="96"></a></p><h3>Silver Sponsors</h3>
 <p><a href="https://www.ampproject.org/"><img src="https://images.opencollective.com/amp/c8a3b25/logo.png" alt="AMP Project" height="64"></a></p><h3>Bronze Sponsors</h3>
-<p><a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/0b37d14/logo.png" alt="Free Icons by Icons8" height="32"></a> <a href="https://uxplanet.org/top-ui-ux-design-agencies-user-experience-firms-8c54697e290"><img src="https://images.opencollective.com/ui-ux-design-agencies/cae5dfe/logo.png" alt="UI UX Design Agencies" height="32"></a> <a href="https://clay.global"><img src="https://images.opencollective.com/clayglobal/2468f34/logo.png" alt="clay" height="32"></a> <a href="https://discordapp.com"><img src="https://images.opencollective.com/discordapp/7e3d9a9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://tekhattan.com"><img src="https://images.opencollective.com/tekhattan/bc73c28/logo.png" alt="TekHattan" height="32"></a> <a href="https://www.marfeel.com/"><img src="https://images.opencollective.com/marfeel/4b88e30/logo.png" alt="Marfeel" height="32"></a> <a href="https://jsheroes.io/"><img src="https://images.opencollective.com/jsheroes1/9fedf0b/logo.png" alt="JSHeroes " height="32"></a></p>
+<p><a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/0b37d14/logo.png" alt="Free Icons by Icons8" height="32"></a> <a href="https://uxplanet.org/top-ui-ux-design-agencies-user-experience-firms-8c54697e290"><img src="https://images.opencollective.com/ui-ux-design-agencies/cae5dfe/logo.png" alt="UI UX Design Agencies" height="32"></a> <a href="https://clay.global"><img src="https://images.opencollective.com/clayglobal/2468f34/logo.png" alt="clay" height="32"></a> <a href="https://discordapp.com"><img src="https://images.opencollective.com/discordapp/7e3d9a9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://tekhattan.com"><img src="https://images.opencollective.com/tekhattan/bc73c28/logo.png" alt="TekHattan" height="32"></a> <a href="https://www.marfeel.com/"><img src="https://images.opencollective.com/marfeel/4b88e30/logo.png" alt="Marfeel" height="32"></a> <a href="http://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a> <a href="https://jsheroes.io/"><img src="https://images.opencollective.com/jsheroes1/9fedf0b/logo.png" alt="JSHeroes " height="32"></a></p>
 <!--sponsorsend-->
 
 ## <a name="technology-sponsors"></a>Technology Sponsors
diff --git a/docs/rules/space-in-parens.md b/docs/rules/space-in-parens.md
index 920fa026e..bfc0b46ed 100644
--- a/docs/rules/space-in-parens.md
+++ b/docs/rules/space-in-parens.md
@@ -12,7 +12,9 @@ var x = (1 + 2) * 3;
 
 ## Rule Details
 
-This rule will enforce consistency of spacing directly inside of parentheses, by disallowing or requiring one or more spaces to the right of `(` and to the left of `)`. In either case, `()` will still be allowed.
+This rule will enforce consistent spacing directly inside of parentheses, by disallowing or requiring one or more spaces to the right of `(` and to the left of `)`.
+
+As long as you do not explicitly disallow empty parentheses using the `"empty"` exception , `()` will be allowed.
 
 ## Options
 
@@ -87,8 +89,21 @@ var foo = ( 1 + 2 ) * 3;
 
 An object literal may be used as a third array item to specify exceptions, with the key `"exceptions"` and an array as the value. These exceptions work in the context of the first option. That is, if `"always"` is set to enforce spacing, then any "exception" will *disallow* spacing. Conversely, if `"never"` is set to disallow spacing, then any "exception" will *enforce* spacing.
 
+Note that this rule only enforces spacing within parentheses; it does not check spacing within curly or square brackets, but will enforce or disallow spacing of those brackets if and only if they are adjacent to an opening or closing parenthesis.
+
 The following exceptions are available: `["{}", "[]", "()", "empty"]`.
 
+### Empty Exception
+
+Empty parens exception and behavior:
+
+* `always` allows for both `()` and `( )`
+* `never` (default) requires `()`
+* `always` excepting `empty` requires `()`
+* `never` excepting `empty` requires `( )` (empty parens without a space is here forbidden)
+
+### Examples
+
 Examples of **incorrect** code for this rule with the `"never", { "exceptions": ["{}"] }` option:
 
 ```js
@@ -168,6 +183,7 @@ Examples of **incorrect** code for this rule with the `"never", { "exceptions":
 
 foo((1 + 2));
 foo((1 + 2), 1);
+foo(bar());
 ```
 
 Examples of **correct** code for this rule with the `"never", { "exceptions": ["()"] }]` option:
@@ -177,6 +193,7 @@ Examples of **correct** code for this rule with the `"never", { "exceptions": ["
 
 foo( (1 + 2) );
 foo( (1 + 2), 1);
+foo(bar() );
 ```
 
 Examples of **incorrect** code for this rule with the `"always", { "exceptions": ["()"] }]` option:
diff --git a/lib/rules/no-extra-boolean-cast.js b/lib/rules/no-extra-boolean-cast.js
index 9bbd5546e..e818cd448 100644
--- a/lib/rules/no-extra-boolean-cast.js
+++ b/lib/rules/no-extra-boolean-cast.js
@@ -96,7 +96,7 @@ module.exports = {
                         grandparent.callee.name === "Boolean")
                 ) {
                     context.report({
-                        node,
+                        node: parent,
                         messageId: "unexpectedNegation",
                         fix: fixer => {
                             if (hasCommentsInside(parent)) {
diff --git a/lib/rules/space-in-parens.js b/lib/rules/space-in-parens.js
index 4f97b1aa8..35ded5e78 100644
--- a/lib/rules/space-in-parens.js
+++ b/lib/rules/space-in-parens.js
@@ -40,23 +40,28 @@ module.exports = {
                 },
                 additionalProperties: false
             }
-        ]
+        ],
+
+        messages: {
+            missingOpeningSpace: "There must be a space after this paren.",
+            missingClosingSpace: "There must be a space before this paren.",
+            rejectedOpeningSpace: "There should be no space after this paren.",
+            rejectedClosingSpace: "There should be no space before this paren."
+        }
     },
 
     create(context) {
-
-        const MISSING_SPACE_MESSAGE = "There must be a space inside this paren.",
-            REJECTED_SPACE_MESSAGE = "There should be no spaces inside this paren.",
-            ALWAYS = context.options[0] === "always",
+        const ALWAYS = context.options[0] === "always",
             exceptionsArrayOptions = (context.options[1] && context.options[1].exceptions) || [],
             options = {};
+
         let exceptions;
 
         if (exceptionsArrayOptions.length) {
-            options.braceException = exceptionsArrayOptions.indexOf("{}") !== -1;
-            options.bracketException = exceptionsArrayOptions.indexOf("[]") !== -1;
-            options.parenException = exceptionsArrayOptions.indexOf("()") !== -1;
-            options.empty = exceptionsArrayOptions.indexOf("empty") !== -1;
+            options.braceException = exceptionsArrayOptions.includes("{}");
+            options.bracketException = exceptionsArrayOptions.includes("[]");
+            options.parenException = exceptionsArrayOptions.includes("()");
+            options.empty = exceptionsArrayOptions.includes("empty");
         }
 
         /**
@@ -105,7 +110,7 @@ module.exports = {
          * @returns {boolean} True if the token is one of the exceptions for the opener paren
          */
         function isOpenerException(token) {
-            return token.type === "Punctuator" && exceptions.openers.indexOf(token.value) >= 0;
+            return exceptions.openers.includes(token.value);
         }
 
         /**
@@ -114,102 +119,95 @@ module.exports = {
          * @returns {boolean} True if the token is one of the exceptions for the closer paren
          */
         function isCloserException(token) {
-            return token.type === "Punctuator" && exceptions.closers.indexOf(token.value) >= 0;
+            return exceptions.closers.includes(token.value);
         }
 
         /**
-         * Determines if an opener paren should have a missing space after it
-         * @param {Object} left The paren token
-         * @param {Object} right The token after it
-         * @returns {boolean} True if the paren should have a space
+         * Determines if an opening paren is immediately followed by a required space
+         * @param {Object} openingParenToken The paren token
+         * @param {Object} tokenAfterOpeningParen The token after it
+         * @returns {boolean} True if the opening paren is missing a required space
          */
-        function shouldOpenerHaveSpace(left, right) {
-            if (sourceCode.isSpaceBetweenTokens(left, right)) {
+        function openerMissingSpace(openingParenToken, tokenAfterOpeningParen) {
+            if (sourceCode.isSpaceBetweenTokens(openingParenToken, tokenAfterOpeningParen)) {
                 return false;
             }
 
-            if (ALWAYS) {
-                if (astUtils.isClosingParenToken(right)) {
-                    return false;
-                }
-                return !isOpenerException(right);
+            if (!options.empty && astUtils.isClosingParenToken(tokenAfterOpeningParen)) {
+                return false;
             }
-            return isOpenerException(right);
 
+            if (ALWAYS) {
+                return !isOpenerException(tokenAfterOpeningParen);
+            }
+            return isOpenerException(tokenAfterOpeningParen);
         }
 
         /**
-         * Determines if an closer paren should have a missing space after it
-         * @param {Object} left The token before the paren
-         * @param {Object} right The paren token
-         * @returns {boolean} True if the paren should have a space
+         * Determines if an opening paren is immediately followed by a disallowed space
+         * @param {Object} openingParenToken The paren token
+         * @param {Object} tokenAfterOpeningParen The token after it
+         * @returns {boolean} True if the opening paren has a disallowed space
          */
-        function shouldCloserHaveSpace(left, right) {
-            if (astUtils.isOpeningParenToken(left)) {
+        function openerRejectsSpace(openingParenToken, tokenAfterOpeningParen) {
+            if (!astUtils.isTokenOnSameLine(openingParenToken, tokenAfterOpeningParen)) {
                 return false;
             }
 
-            if (sourceCode.isSpaceBetweenTokens(left, right)) {
+            if (tokenAfterOpeningParen.type === "Line") {
                 return false;
             }
 
-            if (ALWAYS) {
-                return !isCloserException(left);
+            if (!sourceCode.isSpaceBetweenTokens(openingParenToken, tokenAfterOpeningParen)) {
+                return false;
             }
-            return isCloserException(left);
 
+            if (ALWAYS) {
+                return isOpenerException(tokenAfterOpeningParen);
+            }
+            return !isOpenerException(tokenAfterOpeningParen);
         }
 
         /**
-         * Determines if an opener paren should not have an existing space after it
-         * @param {Object} left The paren token
-         * @param {Object} right The token after it
-         * @returns {boolean} True if the paren should reject the space
+         * Determines if a closing paren is immediately preceeded by a required space
+         * @param {Object} tokenBeforeClosingParen The token before the paren
+         * @param {Object} closingParenToken The paren token
+         * @returns {boolean} True if the closing paren is missing a required space
          */
-        function shouldOpenerRejectSpace(left, right) {
-            if (right.type === "Line") {
-                return false;
-            }
-
-            if (!astUtils.isTokenOnSameLine(left, right)) {
+        function closerMissingSpace(tokenBeforeClosingParen, closingParenToken) {
+            if (sourceCode.isSpaceBetweenTokens(tokenBeforeClosingParen, closingParenToken)) {
                 return false;
             }
 
-            if (!sourceCode.isSpaceBetweenTokens(left, right)) {
+            if (!options.empty && astUtils.isOpeningParenToken(tokenBeforeClosingParen)) {
                 return false;
             }
 
             if (ALWAYS) {
-                return isOpenerException(right);
+                return !isCloserException(tokenBeforeClosingParen);
             }
-            return !isOpenerException(right);
-
+            return isCloserException(tokenBeforeClosingParen);
         }
 
         /**
-         * Determines if an closer paren should not have an existing space after it
-         * @param {Object} left The token before the paren
-         * @param {Object} right The paren token
-         * @returns {boolean} True if the paren should reject the space
+         * Determines if a closer paren is immediately preceeded by a disallowed space
+         * @param {Object} tokenBeforeClosingParen The token before the paren
+         * @param {Object} closingParenToken The paren token
+         * @returns {boolean} True if the closing paren has a disallowed space
          */
-        function shouldCloserRejectSpace(left, right) {
-            if (astUtils.isOpeningParenToken(left)) {
+        function closerRejectsSpace(tokenBeforeClosingParen, closingParenToken) {
+            if (!astUtils.isTokenOnSameLine(tokenBeforeClosingParen, closingParenToken)) {
                 return false;
             }
 
-            if (!astUtils.isTokenOnSameLine(left, right)) {
-                return false;
-            }
-
-            if (!sourceCode.isSpaceBetweenTokens(left, right)) {
+            if (!sourceCode.isSpaceBetweenTokens(tokenBeforeClosingParen, closingParenToken)) {
                 return false;
             }
 
             if (ALWAYS) {
-                return isCloserException(left);
+                return isCloserException(tokenBeforeClosingParen);
             }
-            return !isCloserException(left);
-
+            return !isCloserException(tokenBeforeClosingParen);
         }
 
         //--------------------------------------------------------------------------
@@ -225,44 +223,53 @@ module.exports = {
                     const prevToken = tokens[i - 1];
                     const nextToken = tokens[i + 1];
 
+                    // if token is not an opening or closing paren token, do nothing
                     if (!astUtils.isOpeningParenToken(token) && !astUtils.isClosingParenToken(token)) {
                         return;
                     }
 
-                    if (token.value === "(" && shouldOpenerHaveSpace(token, nextToken)) {
+                    // if token is an opening paren and is not followed by a required space
+                    if (token.value === "(" && openerMissingSpace(token, nextToken)) {
                         context.report({
                             node,
                             loc: token.loc.start,
-                            message: MISSING_SPACE_MESSAGE,
+                            messageId: "missingOpeningSpace",
                             fix(fixer) {
                                 return fixer.insertTextAfter(token, " ");
                             }
                         });
-                    } else if (token.value === "(" && shouldOpenerRejectSpace(token, nextToken)) {
+                    }
+
+                    // if token is an opening paren and is followed by a disallowed space
+                    if (token.value === "(" && openerRejectsSpace(token, nextToken)) {
                         context.report({
                             node,
                             loc: token.loc.start,
-                            message: REJECTED_SPACE_MESSAGE,
+                            messageId: "rejectedOpeningSpace",
                             fix(fixer) {
                                 return fixer.removeRange([token.range[1], nextToken.range[0]]);
                             }
                         });
-                    } else if (token.value === ")" && shouldCloserHaveSpace(prevToken, token)) {
+                    }
 
-                        // context.report(node, token.loc.start, MISSING_SPACE_MESSAGE);
+                    // if token is a closing paren and is not preceded by a required space
+                    if (token.value === ")" && closerMissingSpace(prevToken, token)) {
                         context.report({
                             node,
                             loc: token.loc.start,
-                            message: MISSING_SPACE_MESSAGE,
+                            messageId: "missingClosingSpace",
                             fix(fixer) {
                                 return fixer.insertTextBefore(token, " ");
                             }
                         });
-                    } else if (token.value === ")" && shouldCloserRejectSpace(prevToken, token)) {
+                    }
+
+                    // if token is a closing paren and is preceded by a disallowed space
+                    if (token.value === ")" && closerRejectsSpace(prevToken, token)) {
                         context.report({
                             node,
                             loc: token.loc.start,
-                            message: REJECTED_SPACE_MESSAGE,
+                            messageId: "rejectedClosingSpace",
                             fix(fixer) {
                                 return fixer.removeRange([prevToken.range[1], token.range[0]]);
                             }
@@ -271,6 +278,5 @@ module.exports = {
                 });
             }
         };
-
     }
 };


Test patch:
diff --git a/lib/cli-engine/config-array/override-tester.js b/lib/cli-engine/config-array/override-tester.js
index 6f61e4ff1..d6695423e 100644
--- a/lib/cli-engine/config-array/override-tester.js
+++ b/lib/cli-engine/config-array/override-tester.js
@@ -125,10 +125,10 @@ class OverrideTester {
      */
     static and(a, b) {
         if (!b) {
-            return a;
+            return a && new OverrideTester(a.patterns, a.basePath);
         }
         if (!a) {
-            return b;
+            return new OverrideTester(b.patterns, b.basePath);
         }
 
         assert.strictEqual(a.basePath, b.basePath);
diff --git a/tests/lib/cli-engine/cli-engine.js b/tests/lib/cli-engine/cli-engine.js
index d8591788f..0c6db3ff9 100644
--- a/tests/lib/cli-engine/cli-engine.js
+++ b/tests/lib/cli-engine/cli-engine.js
@@ -3592,6 +3592,36 @@ describe("CLIEngine", () => {
                 });
             });
         });
+
+        describe("with 'overrides[*].extends' setting on deep locations", () => {
+            const root = getFixturePath("cli-engine/deeply-overrides-i-extends");
+
+            it("should not throw.", () => {
+                CLIEngine = defineCLIEngineWithInMemoryFileSystem({
+                    cwd: () => root,
+                    files: {
+                        "node_modules/eslint-config-one/index.js": `module.exports = ${JSON.stringify({
+                            overrides: [{ files: ["*test*"], extends: "two" }]
+                        })}`,
+                        "node_modules/eslint-config-two/index.js": `module.exports = ${JSON.stringify({
+                            overrides: [{ files: ["*.js"], extends: "three" }]
+                        })}`,
+                        "node_modules/eslint-config-three/index.js": `module.exports = ${JSON.stringify({
+                            rules: { "no-console": "error" }
+                        })}`,
+                        "test.js": "console.log('hello')",
+                        ".eslintrc.yml": "extends: one"
+                    }
+                }).CLIEngine;
+                engine = new CLIEngine();
+
+                const { results } = engine.executeOnFiles(["test.js"]);
+                const messages = results[0].messages;
+
+                assert.strictEqual(messages.length, 1);
+                assert.strictEqual(messages[0].ruleId, "no-console");
+            });
+        });
     });
 
     describe("getConfigForFile", () => {
diff --git a/tests/lib/cli-engine/config-array/override-tester.js b/tests/lib/cli-engine/config-array/override-tester.js
index 554ebb421..31038b07e 100644
--- a/tests/lib/cli-engine/config-array/override-tester.js
+++ b/tests/lib/cli-engine/config-array/override-tester.js
@@ -58,16 +58,22 @@ describe("OverrideTester", () => {
             assert.strictEqual(OverrideTester.and(null, null), null);
         });
 
-        it("should return the first one if the second one was null.", () => {
-            const tester = OverrideTester.create("*.js");
+        it("should return a new tester with the the first one's properties if the second one was null.", () => {
+            const tester = OverrideTester.create("*.js", null, process.cwd());
+            const result = OverrideTester.and(tester, null);
 
-            assert.strictEqual(OverrideTester.and(tester, null), tester);
+            assert.notStrictEqual(result, tester);
+            assert.strictEqual(result.patterns, tester.patterns);
+            assert.strictEqual(result.basePath, tester.basePath);
         });
 
-        it("should return the second one if the first one was null.", () => {
-            const tester = OverrideTester.create("*.js");
+        it("should return a new tester with the the second one's properties if the first one was null.", () => {
+            const tester = OverrideTester.create("*.js", null, process.cwd());
+            const result = OverrideTester.and(null, tester);
 
-            assert.strictEqual(OverrideTester.and(null, tester), tester);
+            assert.notStrictEqual(result, tester);
+            assert.strictEqual(result.patterns, tester.patterns);
+            assert.strictEqual(result.basePath, tester.basePath);
         });
 
         it("should return another one what includes both patterns if both are testers.", () => {
diff --git a/tests/lib/rules/no-extra-boolean-cast.js b/tests/lib/rules/no-extra-boolean-cast.js
index 1de914ca5..a530f81f6 100644
--- a/tests/lib/rules/no-extra-boolean-cast.js
+++ b/tests/lib/rules/no-extra-boolean-cast.js
@@ -40,7 +40,9 @@ ruleTester.run("no-extra-boolean-cast", rule, {
             output: "if (foo) {}",
             errors: [{
                 messageId: "unexpectedNegation",
-                type: "UnaryExpression"
+                type: "UnaryExpression",
+                column: 5,
+                endColumn: 10
             }]
         },
         {
@@ -48,7 +50,8 @@ ruleTester.run("no-extra-boolean-cast", rule, {
             output: "do {} while (foo)",
             errors: [{
                 messageId: "unexpectedNegation",
-                type: "UnaryExpression"
+                type: "UnaryExpression",
+                column: 14
             }]
         },
         {
@@ -56,7 +59,8 @@ ruleTester.run("no-extra-boolean-cast", rule, {
             output: "while (foo) {}",
             errors: [{
                 messageId: "unexpectedNegation",
-                type: "UnaryExpression"
+                type: "UnaryExpression",
+                column: 8
             }]
         },
         {
@@ -64,7 +68,8 @@ ruleTester.run("no-extra-boolean-cast", rule, {
             output: "foo ? bar : baz",
             errors: [{
                 messageId: "unexpectedNegation",
-                type: "UnaryExpression"
+                type: "UnaryExpression",
+                column: 1
             }]
         },
         {
@@ -72,7 +77,8 @@ ruleTester.run("no-extra-boolean-cast", rule, {
             output: "for (; foo;) {}",
             errors: [{
                 messageId: "unexpectedNegation",
-                type: "UnaryExpression"
+                type: "UnaryExpression",
+                column: 8
             }]
         },
         {
@@ -80,7 +86,8 @@ ruleTester.run("no-extra-boolean-cast", rule, {
             output: "!foo",
             errors: [{
                 messageId: "unexpectedNegation",
-                type: "UnaryExpression"
+                type: "UnaryExpression",
+                column: 2
             }]
         },
         {
@@ -88,7 +95,8 @@ ruleTester.run("no-extra-boolean-cast", rule, {
             output: "Boolean(foo)",
             errors: [{
                 messageId: "unexpectedNegation",
-                type: "UnaryExpression"
+                type: "UnaryExpression",
+                column: 9
             }]
         },
         {
@@ -96,7 +104,8 @@ ruleTester.run("no-extra-boolean-cast", rule, {
             output: "new Boolean(foo)",
             errors: [{
                 messageId: "unexpectedNegation",
-                type: "UnaryExpression"
+                type: "UnaryExpression",
+                column: 13
             }]
         },
         {
diff --git a/tests/lib/rules/space-in-parens.js b/tests/lib/rules/space-in-parens.js
index f465f4f36..6f90da52b 100644
--- a/tests/lib/rules/space-in-parens.js
+++ b/tests/lib/rules/space-in-parens.js
@@ -11,9 +11,6 @@
 const rule = require("../../../lib/rules/space-in-parens"),
     { RuleTester } = require("../../../lib/rule-tester");
 
-const MISSING_SPACE_ERROR = "There must be a space inside this paren.",
-    REJECTED_SPACE_ERROR = "There should be no spaces inside this paren.";
-
 //------------------------------------------------------------------------------
 // Tests
 //------------------------------------------------------------------------------
@@ -23,6 +20,7 @@ const ruleTester = new RuleTester();
 ruleTester.run("space-in-parens", rule, {
 
     valid: [
+        { code: "foo()", options: ["never"] },
         { code: "foo()", options: ["always"] },
         { code: "foo( bar )", options: ["always"] },
         { code: "foo\n(\nbar\n)\n", options: ["always"] },
@@ -38,7 +36,6 @@ ruleTester.run("space-in-parens", rule, {
         { code: "var foo = `(bar)`;", options: ["always"], parserOptions: { ecmaVersion: 6 } },
         { code: "var foo = `(bar ${baz})`;", options: ["always"], parserOptions: { ecmaVersion: 6 } },
         { code: "var foo = `(bar ${( 1 + 2 )})`;", options: ["always"], parserOptions: { ecmaVersion: 6 } },
-        { code: "bar()", options: ["never"] },
         { code: "bar(baz)", options: ["never"] },
         { code: "var x = (4 + 5) * 6", options: ["never"] },
         { code: "foo\n(\nbar\n)\n", options: ["never"] },
@@ -64,6 +61,7 @@ ruleTester.run("space-in-parens", rule, {
         // exceptions
         { code: "foo({ bar: 'baz' })", options: ["always", { exceptions: ["{}"] }] },
         { code: "foo( { bar: 'baz' } )", options: ["always", { exceptions: ["[]", "()"] }] },
+        { code: "( (foo(bar() ) ) );", options: ["never", { exceptions: ["()"] }] },
         { code: "foo( 1, { bar: 'baz' })", options: ["always", { exceptions: ["{}"] }] },
         { code: "foo({ bar: 'baz' }, 1 )", options: ["always", { exceptions: ["{}"] }] },
         { code: "foo({\nbar: 'baz',\nbaz: 'bar'\n})", options: ["always", { exceptions: ["{}"] }] },
@@ -95,16 +93,18 @@ ruleTester.run("space-in-parens", rule, {
         { code: "foo( (1 + 2) / 1)", options: ["never", { exceptions: ["()"] }] },
         { code: "foo( (\n1 + 2\n) )", options: ["never", { exceptions: ["()"] }] },
 
-        { code: "foo()", options: ["always", { exceptions: ["empty"] }] },
-        { code: "foo( )", options: ["always", { exceptions: ["{}"] }] },
-        { code: "foo(\n1 + 2\n)", options: ["always", { exceptions: ["empty"] }] },
         { code: "foo()", options: ["never", { exceptions: ["{}"] }] },
         { code: "foo( )", options: ["never", { exceptions: ["empty"] }] },
+        { code: "foo()", options: ["always", { exceptions: ["empty"] }] },
+        { code: "foo( )", options: ["always", { exceptions: ["[]"] }] },
+        { code: "foo(( x, {bar:'baz'} ))", options: ["always", { exceptions: ["empty", "()"] }] },
+        { code: "foo( [1, 2], 1 )", options: ["always", { exceptions: ["empty", "()"] }] },
+        { code: "foo(\n1 + 2\n)", options: ["always", { exceptions: ["empty"] }] },
         { code: "foo( \n1 + 2\n )", options: ["never", { exceptions: ["empty"] }] },
 
         { code: "foo({ bar: 'baz' }, [ 1, 2 ])", options: ["always", { exceptions: ["{}", "[]"] }] },
         { code: "foo({\nbar: 'baz'\n}, [\n1,\n2\n])", options: ["always", { exceptions: ["{}", "[]"] }] },
-        { code: "foo(); bar({bar:'baz'}); baz([1,2])", options: ["always", { exceptions: ["{}", "[]", "()"] }] },
+        { code: "foo(); bar({bar:'baz'}); baz([1,2])", options: ["always", { exceptions: ["{}", "[]", "()", "empty"] }] },
         { code: "foo( { bar: 'baz' }, [ 1, 2 ] )", options: ["never", { exceptions: ["{}", "[]"] }] },
         { code: "foo( {\nbar: 'baz'\n}, [\n1,\n2\n] )", options: ["never", { exceptions: ["{}", "[]"] }] },
         { code: "foo( ); bar( {bar:'baz'} ); baz( [1,2] )", options: ["never", { exceptions: ["{}", "[]", "empty"] }] },
@@ -115,71 +115,90 @@ ruleTester.run("space-in-parens", rule, {
     ],
 
     invalid: [
+
+        // methods and functions
+        {
+            code: "bar(baz )",
+            output: "bar(baz)",
+            options: ["never"],
+            errors: [{ messageId: "rejectedClosingSpace" }]
+        },
+        {
+            code: "bar( baz )",
+            output: "bar(baz)",
+            options: ["never"],
+            errors: [
+                { messageId: "rejectedOpeningSpace", line: 1, column: 4 },
+                { messageId: "rejectedClosingSpace", line: 1, column: 10 }
+            ]
+        },
         {
             code: "foo( )",
             output: "foo()",
             options: ["never"],
-            errors: [{ message: REJECTED_SPACE_ERROR, line: 1, column: 4 }]
+            errors: [
+                { messageId: "rejectedOpeningSpace", line: 1, column: 4 },
+                { messageId: "rejectedClosingSpace", line: 1, column: 6 }
+            ]
+        },
+        {
+            code: "foo(bar() )",
+            output: "foo(bar())",
+            options: ["never"],
+            errors: [{ messageId: "rejectedClosingSpace" }]
+        },
+        {
+            code: "foo\n(\nbar )",
+            output: "foo\n(\nbar)",
+            options: ["never"],
+            errors: [{ messageId: "rejectedClosingSpace", line: 3, column: 5 }]
+        },
+        {
+            code: "foo\n(bar\n)\n",
+            output: "foo\n( bar\n)\n",
+            options: ["always"],
+            errors: [{ messageId: "missingOpeningSpace", line: 2, column: 1 }]
         },
         {
             code: "foo( bar)",
             output: "foo( bar )",
             options: ["always"],
-            errors: [{ message: MISSING_SPACE_ERROR, line: 1, column: 9 }]
+            errors: [{ messageId: "missingClosingSpace", line: 1, column: 9 }]
         },
         {
             code: "foo(bar)",
             output: "foo( bar )",
             options: ["always"],
             errors: [
-                { message: MISSING_SPACE_ERROR, line: 1, column: 4 },
-                { message: MISSING_SPACE_ERROR, line: 1, column: 8 }
+                { messageId: "missingOpeningSpace", line: 1, column: 4 },
+                { messageId: "missingClosingSpace", line: 1, column: 8 }
             ]
         },
+
+        // variable declaration and formulas
         {
             code: "var x = ( 1 + 2) * 3",
             output: "var x = ( 1 + 2 ) * 3",
             options: ["always"],
-            errors: [{ message: MISSING_SPACE_ERROR, line: 1, column: 16 }]
+            errors: [{ messageId: "missingClosingSpace", line: 1, column: 16 }]
         },
         {
             code: "var x = (1 + 2 ) * 3",
             output: "var x = ( 1 + 2 ) * 3",
             options: ["always"],
-            errors: [{ message: MISSING_SPACE_ERROR, line: 1, column: 9 }]
-        },
-        {
-            code: "foo\n(bar\n)\n",
-            output: "foo\n( bar\n)\n",
-            options: ["always"],
-            errors: [{ message: MISSING_SPACE_ERROR, line: 2, column: 1 }]
-        },
-        {
-            code: "bar(baz )",
-            output: "bar(baz)",
-            options: ["never"],
-            errors: [REJECTED_SPACE_ERROR]
-        },
-        {
-            code: "bar( baz )",
-            output: "bar(baz)",
-            options: ["never"],
-            errors: [
-                { message: REJECTED_SPACE_ERROR, line: 1, column: 4 },
-                { message: REJECTED_SPACE_ERROR, line: 1, column: 10 }
-            ]
+            errors: [{ messageId: "missingOpeningSpace", line: 1, column: 9 }]
         },
         {
             code: "var x = ( 4 + 5) * 6",
             output: "var x = (4 + 5) * 6",
             options: ["never"],
-            errors: [REJECTED_SPACE_ERROR]
+            errors: [{ messageId: "rejectedOpeningSpace" }]
         },
         {
             code: "var x = (4 + 5 ) * 6",
             output: "var x = (4 + 5) * 6",
             options: ["never"],
-            errors: [REJECTED_SPACE_ERROR]
+            errors: [{ messageId: "rejectedClosingSpace" }]
         },
 
         // comments
@@ -187,155 +206,251 @@ ruleTester.run("space-in-parens", rule, {
             code: "foo(/* bar */)",
             output: "foo( /* bar */ )",
             options: ["always"],
-            errors: [MISSING_SPACE_ERROR, MISSING_SPACE_ERROR]
+            errors: [
+                { messageId: "missingOpeningSpace" },
+                { messageId: "missingClosingSpace" }
+            ]
         },
         {
             code: "foo(/* bar */baz )",
             output: "foo( /* bar */baz )",
             options: ["always"],
-            errors: [MISSING_SPACE_ERROR]
+            errors: [{ messageId: "missingOpeningSpace" }]
         },
         {
             code: "foo(/* bar */ baz )",
             output: "foo( /* bar */ baz )",
             options: ["always"],
-            errors: [MISSING_SPACE_ERROR]
+            errors: [{ messageId: "missingOpeningSpace" }]
         },
         {
             code: "foo( baz/* bar */)",
             output: "foo( baz/* bar */ )",
             options: ["always"],
-            errors: [MISSING_SPACE_ERROR]
+            errors: [{ messageId: "missingClosingSpace" }]
         },
         {
             code: "foo( baz /* bar */)",
             output: "foo( baz /* bar */ )",
             options: ["always"],
-            errors: [MISSING_SPACE_ERROR]
+            errors: [{ messageId: "missingClosingSpace" }]
         },
         {
             code: "foo( /* bar */ )",
             output: "foo(/* bar */)",
             options: ["never"],
-            errors: [REJECTED_SPACE_ERROR, REJECTED_SPACE_ERROR]
+            errors: [
+                { messageId: "rejectedOpeningSpace" },
+                { messageId: "rejectedClosingSpace" }
+            ]
         },
         {
             code: "foo( /* bar */ baz)",
             output: "foo(/* bar */ baz)",
             options: ["never"],
-            errors: [{ message: REJECTED_SPACE_ERROR, line: 1, column: 4 }]
+            errors: [{ messageId: "rejectedOpeningSpace", line: 1, column: 4 }]
         },
 
         // exceptions
+        {
+            code: "foo()",
+            output: "foo( )",
+            options: ["never", { exceptions: ["empty"] }],
+            errors: [
+                { messageId: "missingOpeningSpace", line: 1, column: 4 },
+                { messageId: "missingClosingSpace", line: 1, column: 5 }
+            ]
+        },
+        {
+            code: "foo( )",
+            output: "foo()",
+            options: ["always", { exceptions: ["()", "empty"] }],
+            errors: [
+                { messageId: "rejectedOpeningSpace", line: 1, column: 4 },
+                { messageId: "rejectedClosingSpace", line: 1, column: 6 }
+            ]
+        },
+        {
+            code: "foo( )",
+            output: "foo()",
+            options: ["always", { exceptions: ["empty"] }],
+            errors: [
+                { messageId: "rejectedOpeningSpace", line: 1, column: 4 },
+                { messageId: "rejectedClosingSpace", line: 1, column: 6 }
+            ]
+        },
+        {
+            code: "foo( bar() )",
+            output: "foo( bar())",
+            options: ["always", { exceptions: ["()", "empty"] }],
+            errors: [
+                { messageId: "rejectedClosingSpace", line: 1, column: 12 }
+            ]
+        },
+        {
+            code: "foo(bar())",
+            output: "foo(bar() )",
+            options: ["never", { exceptions: ["()"] }],
+            errors: [
+                { messageId: "missingClosingSpace", line: 1, column: 10 }
+            ]
+        },
+        {
+            code: "foo( bar() )",
+            output: "foo(bar( ))",
+            options: ["never", { exceptions: ["empty"] }],
+            errors: [
+                { messageId: "rejectedOpeningSpace", line: 1, column: 4 },
+                { messageId: "missingOpeningSpace", line: 1, column: 9 },
+                { messageId: "missingClosingSpace", line: 1, column: 10 },
+                { messageId: "rejectedClosingSpace", line: 1, column: 12 }
+            ]
+        },
+        {
+            code: "foo([1,2], bar() )",
+            output: "foo( [1,2], bar())",
+            options: ["never", { exceptions: ["[]"] }],
+            errors: [
+                { messageId: "missingOpeningSpace", line: 1, column: 4 },
+                { messageId: "rejectedClosingSpace", line: 1, column: 18 }
+            ]
+        },
         {
             code: "foo({ bar: 'baz' })",
             output: "foo( { bar: 'baz' } )",
             options: ["always", { exceptions: ["[]"] }],
-            errors: [MISSING_SPACE_ERROR, MISSING_SPACE_ERROR]
+            errors: [
+                { messageId: "missingOpeningSpace" },
+                { messageId: "missingClosingSpace" }
+            ]
         },
         {
             code: "foo( { bar: 'baz' } )",
             output: "foo({ bar: 'baz' })",
             options: ["always", { exceptions: ["{}"] }],
-            errors: [REJECTED_SPACE_ERROR, REJECTED_SPACE_ERROR]
+            errors: [
+                { messageId: "rejectedOpeningSpace" },
+                { messageId: "rejectedClosingSpace" }
+            ]
         },
         {
             code: "foo({ bar: 'baz' })",
             output: "foo( { bar: 'baz' } )",
             options: ["never", { exceptions: ["{}"] }],
-            errors: [MISSING_SPACE_ERROR, MISSING_SPACE_ERROR]
+            errors: [
+                { messageId: "missingOpeningSpace" },
+                { messageId: "missingClosingSpace" }
+            ]
         },
         {
             code: "foo( { bar: 'baz' } )",
             output: "foo({ bar: 'baz' })",
             options: ["never", { exceptions: ["[]"] }],
-            errors: [REJECTED_SPACE_ERROR, REJECTED_SPACE_ERROR]
+            errors: [
+                { messageId: "rejectedOpeningSpace" },
+                { messageId: "rejectedClosingSpace" }
+            ]
         },
         {
             code: "foo( { bar: 'baz' })",
             output: "foo({ bar: 'baz' })",
             options: ["always", { exceptions: ["{}"] }],
-            errors: [REJECTED_SPACE_ERROR]
+            errors: [{ messageId: "rejectedOpeningSpace" }]
         },
         {
             code: "foo( { bar: 'baz' })",
             output: "foo( { bar: 'baz' } )",
             options: ["never", { exceptions: ["{}"] }],
-            errors: [MISSING_SPACE_ERROR]
+            errors: [{ messageId: "missingClosingSpace" }]
         },
         {
             code: "foo({ bar: 'baz' } )",
             output: "foo({ bar: 'baz' })",
             options: ["always", { exceptions: ["{}"] }],
-            errors: [REJECTED_SPACE_ERROR]
+            errors: [{ messageId: "rejectedClosingSpace" }]
         },
         {
             code: "foo({ bar: 'baz' } )",
             output: "foo( { bar: 'baz' } )",
             options: ["never", { exceptions: ["{}"] }],
-            errors: [MISSING_SPACE_ERROR]
+            errors: [{ messageId: "missingOpeningSpace" }]
         },
         {
             code: "foo([ 1, 2 ])",
             output: "foo( [ 1, 2 ] )",
             options: ["always", { exceptions: ["empty"] }],
-            errors: [MISSING_SPACE_ERROR, MISSING_SPACE_ERROR]
+            errors: [
+                { messageId: "missingOpeningSpace" },
+                { messageId: "missingClosingSpace" }
+            ]
         },
         {
             code: "foo( [ 1, 2 ] )",
             output: "foo([ 1, 2 ])",
             options: ["always", { exceptions: ["[]"] }],
-            errors: [REJECTED_SPACE_ERROR, REJECTED_SPACE_ERROR]
+            errors: [
+                { messageId: "rejectedOpeningSpace" },
+                { messageId: "rejectedClosingSpace" }
+            ]
         },
         {
             code: "foo([ 1, 2 ])",
             output: "foo( [ 1, 2 ] )",
             options: ["never", { exceptions: ["[]"] }],
-            errors: [MISSING_SPACE_ERROR, MISSING_SPACE_ERROR]
+            errors: [
+                { messageId: "missingOpeningSpace" },
+                { messageId: "missingClosingSpace" }
+            ]
         },
         {
             code: "foo( [ 1, 2 ] )",
             output: "foo([ 1, 2 ])",
             options: ["never", { exceptions: ["()"] }],
-            errors: [REJECTED_SPACE_ERROR, REJECTED_SPACE_ERROR]
+            errors: [
+                { messageId: "rejectedOpeningSpace" },
+                { messageId: "rejectedClosingSpace" }
+            ]
         },
         {
             code: "foo([ 1, 2 ] )",
             output: "foo([ 1, 2 ])",
             options: ["always", { exceptions: ["[]"] }],
-            errors: [REJECTED_SPACE_ERROR]
+            errors: [{ messageId: "rejectedClosingSpace" }]
         },
         {
             code: "foo([ 1, 2 ] )",
             output: "foo( [ 1, 2 ] )",
             options: ["never", { exceptions: ["[]"] }],
-            errors: [MISSING_SPACE_ERROR]
+            errors: [{ messageId: "missingOpeningSpace" }]
         },
         {
             code: "foo( [ 1, 2 ])",
             output: "foo([ 1, 2 ])",
             options: ["always", { exceptions: ["[]"] }],
-            errors: [REJECTED_SPACE_ERROR]
+            errors: [{ messageId: "rejectedOpeningSpace" }]
         },
         {
             code: "foo( [ 1, 2 ])",
             output: "foo( [ 1, 2 ] )",
             options: ["never", { exceptions: ["[]"] }],
-            errors: [MISSING_SPACE_ERROR]
+            errors: [{ messageId: "missingClosingSpace" }]
         },
         {
             code: "(( 1 + 2 ))",
             output: "( ( 1 + 2 ) )",
             options: ["always", { exceptions: ["[]"] }],
-            errors: [MISSING_SPACE_ERROR, MISSING_SPACE_ERROR]
+            errors: [
+                { messageId: "missingOpeningSpace" },
+                { messageId: "missingClosingSpace" }
+            ]
         },
         {
             code: "( ( 1 + 2 ) )",
             output: "(( 1 + 2 ))",
             options: ["always", { exceptions: ["()"] }],
             errors: [
-                { message: REJECTED_SPACE_ERROR, line: 1, column: 1 },
-                { message: REJECTED_SPACE_ERROR, line: 1, column: 13 }
+                { messageId: "rejectedOpeningSpace", line: 1, column: 1 },
+                { messageId: "rejectedClosingSpace", line: 1, column: 13 }
             ]
         },
         {
@@ -343,91 +458,93 @@ ruleTester.run("space-in-parens", rule, {
             output: "((1 + 2))",
             options: ["never"],
             errors: [
-                { message: REJECTED_SPACE_ERROR, line: 1, column: 1 },
-                { message: REJECTED_SPACE_ERROR, line: 1, column: 3 },
-                { message: REJECTED_SPACE_ERROR, line: 1, column: 11 },
-                { message: REJECTED_SPACE_ERROR, line: 1, column: 13 }
+                { messageId: "rejectedOpeningSpace", line: 1, column: 1 },
+                { messageId: "rejectedOpeningSpace", line: 1, column: 3 },
+                { messageId: "rejectedClosingSpace", line: 1, column: 11 },
+                { messageId: "rejectedClosingSpace", line: 1, column: 13 }
             ]
         },
         {
             code: "( ( 1 + 2 ) )",
             output: "((1 + 2))",
             options: ["never", { exceptions: ["[]"] }],
-            errors: [REJECTED_SPACE_ERROR, REJECTED_SPACE_ERROR, REJECTED_SPACE_ERROR, REJECTED_SPACE_ERROR]
+            errors: [
+                { messageId: "rejectedOpeningSpace" },
+                { messageId: "rejectedOpeningSpace" },
+                { messageId: "rejectedClosingSpace" },
+                { messageId: "rejectedClosingSpace" }
+            ]
         },
         {
-            code: "( ( 1 + 2 ))",
+            code: "((1 + 2))",
             output: "(( 1 + 2 ))",
             options: ["always", { exceptions: ["()"] }],
-            errors: [{ message: REJECTED_SPACE_ERROR, line: 1, column: 1 }]
+            errors: [
+                { messageId: "missingOpeningSpace", line: 1, column: 2 },
+                { messageId: "missingClosingSpace", line: 1, column: 8 }
+            ]
         },
         {
-            code: "( (1 + 2))",
+            code: "((1 + 2))",
             output: "( (1 + 2) )",
             options: ["never", { exceptions: ["()"] }],
-            errors: [MISSING_SPACE_ERROR]
-        },
-        {
-            code: "(( 1 + 2 ) )",
-            output: "(( 1 + 2 ))",
-            options: ["always", { exceptions: ["()"] }],
-            errors: [REJECTED_SPACE_ERROR]
+            errors: [
+                { messageId: "missingOpeningSpace", line: 1, column: 1 },
+                { messageId: "missingClosingSpace", line: 1, column: 9 }
+            ]
         },
         {
             code: "((1 + 2) )",
             output: "( (1 + 2) )",
             options: ["never", { exceptions: ["()"] }],
-            errors: [MISSING_SPACE_ERROR]
+            errors: [
+                { messageId: "missingOpeningSpace", line: 1, column: 1 }
+            ]
         },
         {
             code: "var result = ( 1 / ( 1 + 2 ) ) + 3",
             output: "var result = ( 1 / ( 1 + 2 )) + 3",
             options: ["always", { exceptions: ["()"] }],
-            errors: [REJECTED_SPACE_ERROR]
+            errors: [
+                { messageId: "rejectedClosingSpace", line: 1, column: 30 }
+            ]
         },
         {
             code: "var result = (1 / (1 + 2)) + 3",
             output: "var result = (1 / (1 + 2) ) + 3",
             options: ["never", { exceptions: ["()"] }],
-            errors: [MISSING_SPACE_ERROR]
+            errors: [
+                { messageId: "missingClosingSpace", line: 1, column: 26 }
+            ]
         },
         {
-            code: "var result = ( 1 / ( 1 + 2)) + 3",
+            code: "var result = (1 / ( 1 + 2) ) + 3",
             output: "var result = ( 1 / ( 1 + 2 )) + 3",
             options: ["always", { exceptions: ["()"] }],
-            errors: [MISSING_SPACE_ERROR]
-        },
-        {
-            code: "foo( )",
-            output: "foo()",
-            options: ["always", { exceptions: ["empty"] }],
-            errors: [{ message: REJECTED_SPACE_ERROR, line: 1, column: 4 }]
-        },
-        {
-            code: "foo()",
-            output: "foo( )",
-            options: ["never", { exceptions: ["empty"] }],
-            errors: [{ message: MISSING_SPACE_ERROR, line: 1, column: 4 }]
-        },
-        {
-            code: "foo\n(\nbar )\n",
-            output: "foo\n(\nbar)\n",
-            options: ["never"],
-            errors: [{ message: REJECTED_SPACE_ERROR, line: 3, column: 5 }]
+            errors: [
+                { messageId: "missingOpeningSpace", line: 1, column: 14 },
+                { messageId: "missingClosingSpace", line: 1, column: 26 },
+                { messageId: "rejectedClosingSpace", line: 1, column: 28 }
+            ]
         },
+
+        // ES6
         {
-            code: "var foo = `(bar ${(1 + 2 )})`;",
+            code: "var foo = `(bar ${( 1 + 2 )})`;",
             output: "var foo = `(bar ${(1 + 2)})`;",
             options: ["never"],
             parserOptions: { ecmaVersion: 6 },
-            errors: [{ message: REJECTED_SPACE_ERROR, line: 1, column: 26 }]
+            errors: [
+                { messageId: "rejectedOpeningSpace", line: 1, column: 19 },
+                { messageId: "rejectedClosingSpace", line: 1, column: 27 }
+            ]
         },
         {
             code: "var foo = `(bar ${(1 + 2 )})`;",
             output: "var foo = `(bar ${( 1 + 2 )})`;",
             options: ["always"],
             parserOptions: { ecmaVersion: 6 },
-            errors: [{ message: MISSING_SPACE_ERROR, line: 1, column: 19 }]
+            errors: [{ messageId: "missingOpeningSpace", line: 1, column: 19 }]
         }
     ]
 });