Repository: eslint/eslint
Pull request #12693 (2019-12-20 09:24:45)

Build: update browser build
**What is the purpose of this pull request? (put an "X" next to item)**

[X] Other, please explain: update the webpack configuration of browser tests and the online demo.

**What changes did you make? (Give an overview)**

This PR update our webpack configuration to not use `regjsparser` package as a follow up of #12662. 

After this change, `@babel/preset-env` prints below:

```
Using targets:
{
  "chrome": "76",
  "edge": "18",
  "firefox": "69",
  "ios": "12.2",
  "safari": "12.1",
  "samsung": "10.1"
}

Using modules transform: auto

Using plugins:
  transform-template-literals { "ios":"12.2", "safari":"12.1" }
  transform-function-name { "edge":"18" }
  transform-dotall-regex { "edge":"18", "firefox":"69" }
  proposal-async-generator-functions { "edge":"18" }
  proposal-object-rest-spread { "edge":"18" }
  proposal-unicode-property-regex { "edge":"18", "firefox":"69" }
  proposal-json-strings { "edge":"18" }
  transform-named-capturing-groups-regex { "edge":"18", "firefox":"69" }
  syntax-dynamic-import { "chrome":"76", "edge":"18", "firefox":"69", "ios":"12.2", "opera":"63", "safari":"12.1", "samsung":"10.1" }

Using polyfills: No polyfills were added, since the `useBuiltIns` option was not set.
```

**Is there anything you'd like reviewers to focus on?**

Are the versions OK?


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d02601b7a..645258a56 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,33 @@
+v6.8.0 - December 20, 2019
+
+* [`c5c7086`](https://github.com/eslint/eslint/commit/c5c708666b450fb69522a55aa375626f9297dc6f) Fix: ignore aligning single line in key-spacing (fixes #11414) (#12652) (YeonJuan)
+* [`9986d9e`](https://github.com/eslint/eslint/commit/9986d9e0baed0d3586bbee472fe2fae2ed625f5d) Chore: add object option test cases in yield-star-spacing (#12679) (YeonJuan)
+* [`1713d07`](https://github.com/eslint/eslint/commit/1713d0758b083f3840d724505f997a7cb20ff384) New: Add no-error-on-unmatched-pattern flag (fixes #10587) (#12377) (ncraley)
+* [`5c25a26`](https://github.com/eslint/eslint/commit/5c25a26608fbd9a1d0127c9a3653609aa4b63e86) Update: autofix bug in lines-between-class-members (fixes #12391) (#12632) (YeonJuan)
+* [`4b3cc5c`](https://github.com/eslint/eslint/commit/4b3cc5cd2459f04eae149faea0651785d7f9db0b) Chore: enable prefer-regex-literals in eslint codebase (#12268) (薛定谔的猫)
+* [`05faebb`](https://github.com/eslint/eslint/commit/05faebb943456ad2b20117f3c8b3eccbe2e2fb03) Update: improve suggestion testing experience (#12602) (Brad Zacher)
+* [`05f7dd5`](https://github.com/eslint/eslint/commit/05f7dd53ed91a6e3be9eb40825fb6d2207f82209) Update: Add suggestions for no-unsafe-negation (fixes #12591) (#12609) (Milos Djermanovic)
+* [`d3e43f1`](https://github.com/eslint/eslint/commit/d3e43f1c10c5e19f40e7b3d3944b87f1b0c9c075) Docs: Update no-multi-assign explanation (#12615) (Yuping Zuo)
+* [`272e4db`](https://github.com/eslint/eslint/commit/272e4db6074283bc01cc6ec72c9e396bb3c110e6) Fix: no-multiple-empty-lines: Adjust reported `loc` (#12594) (Tobias Bieniek)
+* [`a258039`](https://github.com/eslint/eslint/commit/a258039e556075d7d1f955a79d094ea103ec165a) Fix: no-restricted-imports schema allows multiple paths/patterns objects (#12639) (Milos Djermanovic)
+* [`51f9620`](https://github.com/eslint/eslint/commit/51f9620cc55cc091fe38dbe68e4633de06297b8c) Fix: improve report location for array-bracket-spacing (#12653) (Milos Djermanovic)
+* [`45364af`](https://github.com/eslint/eslint/commit/45364afc9c7f0251348cd1a7a13656c3816435d7) Fix: prefer-numeric-literals doesn't check types of literal arguments (#12655) (Milos Djermanovic)
+* [`e3c570e`](https://github.com/eslint/eslint/commit/e3c570eaf3d1d44fb57bf42f1870887856e4c5a0) Docs: Add example for expression option (#12694) (Arnaud Barré)
+* [`6b774ef`](https://github.com/eslint/eslint/commit/6b774ef0d849ccf5c1127b25e1fe7c3e438d586b) Docs: Add spacing in comments for no-console rule (#12696) (Nikki Nikkhoui)
+* [`7171fca`](https://github.com/eslint/eslint/commit/7171fca6ef4e0e8f267658fc7d8f603f00eddd84) Chore: refactor regex in config comment parser (#12662) (Milos Djermanovic)
+* [`1600648`](https://github.com/eslint/eslint/commit/1600648d2880ffb1e9e414b31ff0f66ead7167f9) Update: Allow $schema in config (#12612) (Yordis Prieto)
+* [`acc0e47`](https://github.com/eslint/eslint/commit/acc0e47572a9390292b4e313b4a4bf360d236358) Update: support .eslintrc.cjs (refs eslint/rfcs#43) (#12321) (Evan Plaice)
+* [`49c1658`](https://github.com/eslint/eslint/commit/49c1658544ace24b9aaaa301af0fc07a2ef3bf30) Chore: remove bundling of ESLint during release (#12676) (Kai Cataldo)
+* [`257f3d6`](https://github.com/eslint/eslint/commit/257f3d67905a52bf8602a5a5707c893cc90d7ca7) Chore: complete to move to GitHub Actions (#12625) (Toru Nagashima)
+* [`ab912f0`](https://github.com/eslint/eslint/commit/ab912f0ef709a916ab9a27ea09d9d7adf046fb2d) Docs: 1tbs with allowSingleLine edge cases (refs #12284) (#12314) (Ari Kardasis)
+* [`dd1c30e`](https://github.com/eslint/eslint/commit/dd1c30e35f05ed332e2abbd3d4d53635efde74b8) Sponsors: Sync README with website (ESLint Jenkins)
+* [`a230f84`](https://github.com/eslint/eslint/commit/a230f8404e4f2423dd79378b065d24c12776775b) Update: include node version in cache (#12582) (Eric Wang)
+* [`8b65f17`](https://github.com/eslint/eslint/commit/8b65f175dfb4fac11ed7184537be400ed14996fb) Chore: remove references to parser demo (#12644) (Kai Cataldo)
+* [`e9cef99`](https://github.com/eslint/eslint/commit/e9cef99e6ebec1faefdb576ca597e81ae4f04afd) Docs: wrap {{}} in raw liquid tags to prevent interpolation (#12643) (Kai Cataldo)
+* [`e707453`](https://github.com/eslint/eslint/commit/e70745325ff9e085acc6843dd8bfae5550645d4f) Docs: Fix configuration example in no-restricted-imports (fixes #11717) (#12638) (Milos Djermanovic)
+* [`19194ce`](https://github.com/eslint/eslint/commit/19194cec724e016df02376bbeae31171be6f0bdf) Chore: Add tests to cover default object options in comma-dangle (#12627) (YeonJuan)
+* [`6e36d12`](https://github.com/eslint/eslint/commit/6e36d12d95e76022172fd0ec8a5e85c22fde6a8a) Update: do not recommend require-atomic-updates (refs #11899) (#12599) (Kai Cataldo)
+
 v6.7.2 - November 30, 2019
 
 * [`bc435a9`](https://github.com/eslint/eslint/commit/bc435a93afd6ba4def1b53993ef7cf8220f3f070) Fix: isSpaceBetweenTokens() recognizes spaces in JSXText (fixes #12614) (#12616) (Toru Nagashima)
diff --git a/Makefile.js b/Makefile.js
index 2dc8547f3..a574f25d9 100644
--- a/Makefile.js
+++ b/Makefile.js
@@ -562,19 +562,6 @@ target.karma = () => {
 
     target.webpack("production");
 
-    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));
-        exit(1);
-    }
-
     const lastReturn = exec(`${getBinFile("karma")} start karma.conf.js`);
 
     if (lastReturn.code !== 0) {
diff --git a/docs/rules/func-style.md b/docs/rules/func-style.md
index 14f01b0c4..e17fecf8f 100644
--- a/docs/rules/func-style.md
+++ b/docs/rules/func-style.md
@@ -77,6 +77,8 @@ Examples of **correct** code for this rule with the default `"expression"` optio
 var foo = function() {
     // ...
 };
+
+var foo = () => {};
 ```
 
 ### declaration
diff --git a/docs/rules/indent.md b/docs/rules/indent.md
index 0e58352fc..8d7f9d059 100644
--- a/docs/rules/indent.md
+++ b/docs/rules/indent.md
@@ -84,6 +84,7 @@ This rule has an object option:
 * `"ObjectExpression"` (default: 1) enforces indentation level for properties in objects. It can be set to the string `"first"`, indicating that all properties in the object should be aligned with the first property. This can also be set to `"off"` to disable checking for object properties.
 * `"ImportDeclaration"` (default: 1) enforces indentation level for import statements. It can be set to the string `"first"`, indicating that all imported members from a module should be aligned with the first member in the list. This can also be set to `"off"` to disable checking for imported module members.
 * `"flatTernaryExpressions": true` (`false` by default) requires no indentation for ternary expressions which are nested in other ternary expressions.
+* `"offsetTernaryExpressions": true` (`false` by default) requires indentation for values of ternary expressions.
 * `"ignoredNodes"` accepts an array of [selectors](/docs/developer-guide/selectors.md). If an AST node is matched by any of the selectors, the indentation of tokens which are direct children of that node will be ignored. This can be used as an escape hatch to relax the rule if you disagree with the indentation that it enforces for a particular syntactic pattern.
 * `"ignoreComments"` (default: false) can be used when comments do not need to be aligned with nodes on the previous or next line.
 
@@ -643,6 +644,76 @@ var a =
     boop;
 ```
 
+### offsetTernaryExpressions
+
+Examples of **incorrect** code for this rule with the default `2, { "offsetTernaryExpressions": false }` option:
+
+```js
+/*eslint indent: ["error", 2, { "offsetTernaryExpressions": false }]*/
+
+condition
+  ? () => {
+      return true
+    }
+  : () => {
+      false
+    }
+```
+
+Examples of **correct** code for this rule with the default `2, { "offsetTernaryExpressions": false }` option:
+
+```js
+/*eslint indent: ["error", 2, { "offsetTernaryExpressions": false }]*/
+
+condition
+  ? () => {
+    return true
+  }
+  : condition2
+    ? () => {
+      return true
+    }
+    : () => {
+      return false
+    }
+```
+
+Examples of **incorrect** code for this rule with the `2, { "offsetTernaryExpressions": true }` option:
+
+```js
+/*eslint indent: ["error", 2, { "offsetTernaryExpressions": true }]*/
+
+condition
+  ? () => {
+    return true
+  }
+  : condition2
+    ? () => {
+      return true
+    }
+    : () => {
+      return false
+    }
+```
+
+Examples of **correct** code for this rule with the `2, { "offsetTernaryExpressions": true }` option:
+
+```js
+/*eslint indent: ["error", 2, { "offsetTernaryExpressions": true }]*/
+
+condition
+  ? () => {
+      return true
+    }
+  : condition2
+    ? () => {
+        return true
+      }
+    : () => {
+        return false
+      }
+```
+
 ### ignoredNodes
 
 The following configuration ignores the indentation of `ConditionalExpression` ("ternary expression") nodes:
diff --git a/docs/rules/no-console.md b/docs/rules/no-console.md
index bc163b937..f2fb79ec4 100644
--- a/docs/rules/no-console.md
+++ b/docs/rules/no-console.md
@@ -14,7 +14,7 @@ This rule disallows calls to methods of the `console` object.
 Examples of **incorrect** code for this rule:
 
 ```js
-/*eslint no-console: "error"*/
+/* eslint no-console: "error" */
 
 console.log("Log a debug level message.");
 console.warn("Log a warn level message.");
@@ -24,7 +24,7 @@ console.error("Log an error level message.");
 Examples of **correct** code for this rule:
 
 ```js
-/*eslint no-console: "error"*/
+/* eslint no-console: "error" */
 
 // custom console
 Console.log("Hello world!");
@@ -39,7 +39,7 @@ This rule has an object option for exceptions:
 Examples of additional **correct** code for this rule with a sample `{ "allow": ["warn", "error"] }` option:
 
 ```js
-/*eslint no-console: ["error", { allow: ["warn", "error"] }] */
+/* eslint no-console: ["error", { allow: ["warn", "error"] }] */
 
 console.warn("Log a warn level message.");
 console.error("Log an error level message.");
@@ -52,7 +52,7 @@ If you're using Node.js, however, `console` is used to output information to the
 Another case where you might not use this rule is if you want to enforce console calls and not console overwrites. For example:
 
 ```js
-/*eslint no-console: ["error", { allow: ["warn"] }] */
+/* eslint no-console: ["error", { allow: ["warn"] }] */
 console.error = function (message) {
   throw new Error(message);
 };
diff --git a/docs/rules/no-multi-assign.md b/docs/rules/no-multi-assign.md
index 2da09ba07..41bba9ad6 100644
--- a/docs/rules/no-multi-assign.md
+++ b/docs/rules/no-multi-assign.md
@@ -3,7 +3,11 @@
 Chaining the assignment of variables can lead to unexpected results and be difficult to read.
 
 ```js
-a = b = c = d;
+(function() {
+    const foo = bar = 0; // Did you mean `foo = bar == 0`?
+    bar = 1;             // This will not fail since `bar` is not constant.
+})();
+console.log(bar);        // This will output 1 since `bar` is not scoped.
 ```
 
 ## Rule Details
@@ -17,9 +21,9 @@ Examples of **incorrect** code for this rule:
 
 var a = b = c = 5;
 
-var foo = bar = "baz";
+const foo = bar = "baz";
 
-var a =
+let a =
     b =
     c;
 ```
@@ -32,11 +36,11 @@ var a = 5;
 var b = 5;
 var c = 5;
 
-var foo = "baz";
-var bar = "baz";
+const foo = "baz";
+const bar = "baz";
 
-var a = c;
-var b = c;
+let a = c;
+let b = c;
 ```
 
 ## Related Rules
diff --git a/docs/rules/no-param-reassign.md b/docs/rules/no-param-reassign.md
index 2ee312c2b..47a7af3cb 100644
--- a/docs/rules/no-param-reassign.md
+++ b/docs/rules/no-param-reassign.md
@@ -129,17 +129,25 @@ Examples of **correct** code for the `{ "props": true }` option with `"ignorePro
 ```js
 /*eslint no-param-reassign: ["error", { "props": true, "ignorePropertyModificationsForRegex": ["^bar"] }]*/
 
-function foo(bar) {
+function foo(barVar) {
     barVar.prop = "value";
 }
 
-function foo(bar) {
+function foo(barrito) {
     delete barrito.aaa;
 }
 
-function foo(bar) {
+function foo(bar_) {
     bar_.aaa++;
 }
+
+function foo(barBaz) {
+    for (barBaz.aaa in baz) {}
+}
+
+function foo(barBaz) {
+    for (barBaz.aaa of baz) {}
+}
 ```
 
 
diff --git a/docs/rules/no-restricted-exports.md b/docs/rules/no-restricted-exports.md
new file mode 100644
index 000000000..29938579d
--- /dev/null
+++ b/docs/rules/no-restricted-exports.md
@@ -0,0 +1,106 @@
+# Disallow specified names in exports (no-restricted-exports)
+
+In a project, certain names may be disallowed from being used as exported names for various reasons.
+
+## Rule Details
+
+This rule disallows specified names from being used as exported names.
+
+## Options
+
+By default, this rule doesn't disallow any names. Only the names you specify in the configuration will be disallowed.
+
+This rule has an object option:
+
+* `"restrictedNamedExports"` is an array of strings, where each string is a name to be restricted.
+
+Examples of **incorrect** code for this rule:
+
+```js
+/*eslint no-restricted-exports: ["error", {
+    "restrictedNamedExports": ["foo", "bar", "Baz", "a", "b", "c", "d"]
+}]*/
+
+export const foo = 1;
+
+export function bar() {}
+
+export class Baz {}
+
+const a = {};
+export { a };
+
+function someFunction() {}
+export { someFunction as b };
+
+export { c } from 'some_module';
+
+export { something as d } from 'some_module';
+```
+
+Examples of **correct** code for this rule:
+
+```js
+/*eslint no-restricted-exports: ["error", {
+    "restrictedNamedExports": ["foo", "bar", "Baz", "a", "b", "c", "d"]
+}]*/
+
+export const quux = 1;
+
+export function myFunction() {}
+
+export class MyClass {}
+
+const a = {};
+export { a as myObject };
+
+function someFunction() {}
+export { someFunction };
+
+export { c as someName } from 'some_module';
+
+export { something } from 'some_module';
+```
+
+### Default exports
+
+By design, this rule doesn't disallow `export default` declarations. If you configure `"default"` as a restricted name, that restriction will apply only to named export declarations.
+
+Examples of additional **incorrect** code for this rule:
+
+```js
+/*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["default"] }]*/
+
+function foo() {}
+
+export { foo as default };
+```
+
+```js
+/*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["default"] }]*/
+
+export { default } from 'some_module';
+```
+
+Examples of additional **correct** code for this rule:
+
+```js
+/*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["default", "foo"] }]*/
+
+export default function foo() {}
+```
+
+## Known Limitations
+
+This rule doesn't inspect the content of source modules in re-export declarations. In particular, if you are re-exporting everything from another module's export, that export may include a restricted name. This rule cannot detect such cases.
+
+```js
+
+//----- some_module.js -----
+export function foo() {}
+
+//----- my_module.js -----
+/*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["foo"] }]*/
+
+export * from 'some_module'; // allowed, although this declaration exports "foo" from my_module
+```
diff --git a/docs/rules/no-void.md b/docs/rules/no-void.md
index 856c934c6..6b7774805 100644
--- a/docs/rules/no-void.md
+++ b/docs/rules/no-void.md
@@ -54,8 +54,42 @@ Examples of **incorrect** code for this rule:
 /*eslint no-void: "error"*/
 
 void foo
+void someFunction();
 
 var foo = void bar();
+function baz() {
+    return void 0;
+}
+```
+
+## Options
+
+This rule has an object option:
+
+* `allowAsStatement` set to `true` allows the void operator to be used as a statement (Default `false`).
+
+### allowAsStatement
+
+When `allowAsStatement` is set to true, the rule will not error on cases that the void operator is used as a statement, i.e. when it's not used in an expression position, like in a variable assignment or a function return.
+
+Examples of **incorrect** code for `{ "allowAsStatement": true }`:
+
+```js
+/*eslint no-void: ["error", { "allowAsStatement": true }]*/
+
+var foo = void bar();
+function baz() {
+    return void 0;
+}
+```
+
+Examples of **correct** code for `{ "allowAsStatement": true }`:
+
+```js
+/*eslint no-void: ["error", { "allowAsStatement": true }]*/
+
+void foo;
+void someFunction();
 ```
 
 ## When Not To Use It
diff --git a/docs/user-guide/command-line-interface.md b/docs/user-guide/command-line-interface.md
index c8871b07d..89f42744e 100644
--- a/docs/user-guide/command-line-interface.md
+++ b/docs/user-guide/command-line-interface.md
@@ -79,6 +79,7 @@ Caching:
 Miscellaneous:
   --init                         Run config initialization wizard - default: false
   --env-info                     Output execution environment information - default: false
+  --no-error-on-unmatched-pattern  Prevent errors when pattern is unmatched - default: false
   --debug                        Output debugging information
   -h, --help                     Show help
   -v, --version                  Output the version number
@@ -451,6 +452,10 @@ The resulting configuration file will be created in the current directory.
 
 This option outputs information about the execution environment, including the version of Node, npm, and local and global installations of ESLint. The ESLint team may ask for this information to help solve bugs.
 
+#### `--no-error-on-unmatched-pattern`
+
+This option prevents errors when a quoted glob pattern or `--ext` is unmatched. This will not prevent errors when your shell can't match a glob.
+
 #### `--debug`
 
 This option outputs debugging information to the console. This information is useful when you're seeing a problem and having a hard time pinpointing it. The ESLint team may ask for this debugging information to help solve bugs.
diff --git a/lib/cli-engine/cli-engine.js b/lib/cli-engine/cli-engine.js
index 0b1c76bac..22336a91d 100644
--- a/lib/cli-engine/cli-engine.js
+++ b/lib/cli-engine/cli-engine.js
@@ -576,6 +576,7 @@ class CLIEngine {
             cwd: options.cwd,
             extensions: options.extensions,
             globInputPaths: options.globInputPaths,
+            errorOnUnmatchedPattern: options.errorOnUnmatchedPattern,
             ignore: options.ignore
         });
         const lintResultCache =
diff --git a/lib/cli-engine/file-enumerator.js b/lib/cli-engine/file-enumerator.js
index b5a082b71..c67e01aef 100644
--- a/lib/cli-engine/file-enumerator.js
+++ b/lib/cli-engine/file-enumerator.js
@@ -190,6 +190,7 @@ class FileEnumerator {
         configArrayFactory = new CascadingConfigArrayFactory({ cwd }),
         extensions = [".js"],
         globInputPaths = true,
+        errorOnUnmatchedPattern = true,
         ignore = true
     } = {}) {
         internalSlotsMap.set(this, {
@@ -208,6 +209,7 @@ class FileEnumerator {
                 "u"
             ),
             globInputPaths,
+            errorOnUnmatchedPattern,
             ignoreFlag: ignore
         });
     }
@@ -226,7 +228,7 @@ class FileEnumerator {
      * @returns {IterableIterator<FileAndConfig>} The found files.
      */
     *iterateFiles(patternOrPatterns) {
-        const { globInputPaths } = internalSlotsMap.get(this);
+        const { globInputPaths, errorOnUnmatchedPattern } = internalSlotsMap.get(this);
         const patterns = Array.isArray(patternOrPatterns)
             ? patternOrPatterns
             : [patternOrPatterns];
@@ -265,14 +267,16 @@ class FileEnumerator {
             }
 
             // Raise an error if any files were not found.
-            if (!foundRegardlessOfIgnored) {
-                throw new NoFilesFoundError(
-                    pattern,
-                    !globInputPaths && isGlob(pattern)
-                );
-            }
-            if (!found) {
-                throw new AllFilesIgnoredError(pattern);
+            if (errorOnUnmatchedPattern) {
+                if (!foundRegardlessOfIgnored) {
+                    throw new NoFilesFoundError(
+                        pattern,
+                        !globInputPaths && isGlob(pattern)
+                    );
+                }
+                if (!found) {
+                    throw new AllFilesIgnoredError(pattern);
+                }
             }
         }
 
diff --git a/lib/cli-engine/formatters/junit.js b/lib/cli-engine/formatters/junit.js
index c32425883..a994b4b19 100644
--- a/lib/cli-engine/formatters/junit.js
+++ b/lib/cli-engine/formatters/junit.js
@@ -32,7 +32,7 @@ function getMessageType(message) {
  * @private
  */
 function pathWithoutExt(filePath) {
-    return path.posix.join(path.posix.dirname(filePath), path.basename(filePath, path.extname(filePath)));
+    return path.join(path.dirname(filePath), path.basename(filePath, path.extname(filePath)));
 }
 
 //------------------------------------------------------------------------------
diff --git a/lib/cli.js b/lib/cli.js
index 18a917cf0..944b4b793 100644
--- a/lib/cli.js
+++ b/lib/cli.js
@@ -68,7 +68,8 @@ function translateOptions(cliOptions) {
         fixTypes: cliOptions.fixType,
         allowInlineConfig: cliOptions.inlineConfig,
         reportUnusedDisableDirectives: cliOptions.reportUnusedDisableDirectives,
-        resolvePluginsRelativeTo: cliOptions.resolvePluginsRelativeTo
+        resolvePluginsRelativeTo: cliOptions.resolvePluginsRelativeTo,
+        errorOnUnmatchedPattern: cliOptions.errorOnUnmatchedPattern
     };
 }
 
diff --git a/lib/options.js b/lib/options.js
index 83bf9afc2..98dc04b6e 100644
--- a/lib/options.js
+++ b/lib/options.js
@@ -230,6 +230,12 @@ module.exports = optionator({
             default: "false",
             description: "Output execution environment information"
         },
+        {
+            option: "error-on-unmatched-pattern",
+            type: "Boolean",
+            default: "true",
+            description: "Prevent errors when pattern is unmatched"
+        },
         {
             option: "debug",
             type: "Boolean",
diff --git a/lib/rules/array-bracket-spacing.js b/lib/rules/array-bracket-spacing.js
index 2510159ee..c2b77a641 100644
--- a/lib/rules/array-bracket-spacing.js
+++ b/lib/rules/array-bracket-spacing.js
@@ -84,16 +84,16 @@ module.exports = {
          * @returns {void}
          */
         function reportNoBeginningSpace(node, token) {
+            const nextToken = sourceCode.getTokenAfter(token);
+
             context.report({
                 node,
-                loc: token.loc.start,
+                loc: { start: token.loc.end, end: nextToken.loc.start },
                 messageId: "unexpectedSpaceAfter",
                 data: {
                     tokenValue: token.value
                 },
                 fix(fixer) {
-                    const nextToken = sourceCode.getTokenAfter(token);
-
                     return fixer.removeRange([token.range[1], nextToken.range[0]]);
                 }
             });
@@ -106,16 +106,16 @@ module.exports = {
          * @returns {void}
          */
         function reportNoEndingSpace(node, token) {
+            const previousToken = sourceCode.getTokenBefore(token);
+
             context.report({
                 node,
-                loc: token.loc.start,
+                loc: { start: previousToken.loc.end, end: token.loc.start },
                 messageId: "unexpectedSpaceBefore",
                 data: {
                     tokenValue: token.value
                 },
                 fix(fixer) {
-                    const previousToken = sourceCode.getTokenBefore(token);
-
                     return fixer.removeRange([previousToken.range[1], token.range[0]]);
                 }
             });
@@ -130,7 +130,7 @@ module.exports = {
         function reportRequiredBeginningSpace(node, token) {
             context.report({
                 node,
-                loc: token.loc.start,
+                loc: token.loc,
                 messageId: "missingSpaceAfter",
                 data: {
                     tokenValue: token.value
@@ -150,7 +150,7 @@ module.exports = {
         function reportRequiredEndingSpace(node, token) {
             context.report({
                 node,
-                loc: token.loc.start,
+                loc: token.loc,
                 messageId: "missingSpaceBefore",
                 data: {
                     tokenValue: token.value
diff --git a/lib/rules/indent.js b/lib/rules/indent.js
index 694cf7d9e..9fa62c84a 100644
--- a/lib/rules/indent.js
+++ b/lib/rules/indent.js
@@ -590,6 +590,10 @@ module.exports = {
                         type: "boolean",
                         default: false
                     },
+                    offsetTernaryExpressions: {
+                        type: "boolean",
+                        default: false
+                    },
                     ignoredNodes: {
                         type: "array",
                         items: {
@@ -1142,7 +1146,8 @@ module.exports = {
                     offsets.setDesiredOffset(questionMarkToken, firstToken, 1);
                     offsets.setDesiredOffset(colonToken, firstToken, 1);
 
-                    offsets.setDesiredOffset(firstConsequentToken, firstToken, 1);
+                    offsets.setDesiredOffset(firstConsequentToken, firstToken,
+                        options.offsetTernaryExpressions ? 2 : 1);
 
                     /*
                      * The alternate and the consequent should usually have the same indentation.
@@ -1167,7 +1172,9 @@ module.exports = {
                          * If `baz` were aligned with `bar` rather than being offset by 1 from `foo`, `baz` would end up
                          * having no expected indentation.
                          */
-                        offsets.setDesiredOffset(firstAlternateToken, firstToken, 1);
+                        offsets.setDesiredOffset(firstAlternateToken, firstToken,
+                            firstAlternateToken.type === "Punctuator" &&
+                            options.offsetTernaryExpressions ? 2 : 1);
                     }
                 }
             },
diff --git a/lib/rules/index.js b/lib/rules/index.js
index d3fbe4120..494c650e4 100644
--- a/lib/rules/index.js
+++ b/lib/rules/index.js
@@ -178,6 +178,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
     "no-prototype-builtins": () => require("./no-prototype-builtins"),
     "no-redeclare": () => require("./no-redeclare"),
     "no-regex-spaces": () => require("./no-regex-spaces"),
+    "no-restricted-exports": () => require("./no-restricted-exports"),
     "no-restricted-globals": () => require("./no-restricted-globals"),
     "no-restricted-imports": () => require("./no-restricted-imports"),
     "no-restricted-modules": () => require("./no-restricted-modules"),
diff --git a/lib/rules/key-spacing.js b/lib/rules/key-spacing.js
index 994c35627..6d1b9121c 100644
--- a/lib/rules/key-spacing.js
+++ b/lib/rules/key-spacing.js
@@ -42,6 +42,18 @@ function isSingleLine(node) {
     return (node.loc.end.line === node.loc.start.line);
 }
 
+/**
+ * Checks whether the properties on a single line.
+ * @param {ASTNode[]} properties List of Property AST nodes.
+ * @returns {boolean} True if all properies is on a single line.
+ */
+function isSingleLineProperties(properties) {
+    const [firstProp] = properties,
+        lastProp = last(properties);
+
+    return firstProp.loc.start.line === lastProp.loc.end.line;
+}
+
 /**
  * Initializes a single option property from the configuration with defaults for undefined values
  * @param {Object} toOptions Object to be initialized
@@ -583,17 +595,6 @@ module.exports = {
             }
         }
 
-        /**
-         * Verifies vertical alignment, taking into account groups of properties.
-         * @param  {ASTNode} node ObjectExpression node being evaluated.
-         * @returns {void}
-         */
-        function verifyAlignment(node) {
-            createGroups(node).forEach(group => {
-                verifyGroupAlignment(group.filter(isKeyValueProperty));
-            });
-        }
-
         /**
          * Verifies spacing of property conforms to specified options.
          * @param  {ASTNode} node Property node being evaluated.
@@ -611,17 +612,35 @@ module.exports = {
 
         /**
          * Verifies spacing of each property in a list.
-         * @param  {ASTNode[]} properties List of Property AST nodes.
+         * @param {ASTNode[]} properties List of Property AST nodes.
+         * @param {Object} lineOptions Configured singleLine or multiLine options
          * @returns {void}
          */
-        function verifyListSpacing(properties) {
+        function verifyListSpacing(properties, lineOptions) {
             const length = properties.length;
 
             for (let i = 0; i < length; i++) {
-                verifySpacing(properties[i], singleLineOptions);
+                verifySpacing(properties[i], lineOptions);
             }
         }
 
+        /**
+         * Verifies vertical alignment, taking into account groups of properties.
+         * @param  {ASTNode} node ObjectExpression node being evaluated.
+         * @returns {void}
+         */
+        function verifyAlignment(node) {
+            createGroups(node).forEach(group => {
+                const properties = group.filter(isKeyValueProperty);
+
+                if (properties.length > 0 && isSingleLineProperties(properties)) {
+                    verifyListSpacing(properties, multiLineOptions);
+                } else {
+                    verifyGroupAlignment(properties);
+                }
+            });
+        }
+
         //--------------------------------------------------------------------------
         // Public API
         //--------------------------------------------------------------------------
@@ -631,7 +650,7 @@ module.exports = {
             return {
                 ObjectExpression(node) {
                     if (isSingleLine(node)) {
-                        verifyListSpacing(node.properties.filter(isKeyValueProperty));
+                        verifyListSpacing(node.properties.filter(isKeyValueProperty), singleLineOptions);
                     } else {
                         verifyAlignment(node);
                     }
diff --git a/lib/rules/lines-between-class-members.js b/lib/rules/lines-between-class-members.js
index 60332a1b3..972353036 100644
--- a/lib/rules/lines-between-class-members.js
+++ b/lib/rules/lines-between-class-members.js
@@ -54,62 +54,45 @@ module.exports = {
         const sourceCode = context.getSourceCode();
 
         /**
-         * Checks if there is padding between two tokens
-         * @param {Token} first The first token
-         * @param {Token} second The second token
-         * @returns {boolean} True if there is at least a line between the tokens
+         * Return the last token among the consecutive tokens that have no exceed max line difference in between, before the first token in the next member.
+         * @param {Token} prevLastToken The last token in the previous member node.
+         * @param {Token} nextFirstToken The first token in the next member node.
+         * @param {number} maxLine The maximum number of allowed line difference between consecutive tokens.
+         * @returns {Token} The last token among the consecutive tokens.
          */
-        function isPaddingBetweenTokens(first, second) {
-            const comments = sourceCode.getCommentsBefore(second);
-            const len = comments.length;
+        function findLastConsecutiveTokenAfter(prevLastToken, nextFirstToken, maxLine) {
+            const after = sourceCode.getTokenAfter(prevLastToken, { includeComments: true });
 
-            // If there is no comments
-            if (len === 0) {
-                const linesBetweenFstAndSnd = second.loc.start.line - first.loc.end.line - 1;
-
-                return linesBetweenFstAndSnd >= 1;
-            }
-
-
-            // If there are comments
-            let sumOfCommentLines = 0; // the numbers of lines of comments
-            let prevCommentLineNum = -1; // line number of the end of the previous comment
-
-            for (let i = 0; i < len; i++) {
-                const commentLinesOfThisComment = comments[i].loc.end.line - comments[i].loc.start.line + 1;
-
-                sumOfCommentLines += commentLinesOfThisComment;
-
-                /*
-                 * If this comment and the previous comment are in the same line,
-                 * the count of comment lines is duplicated. So decrement sumOfCommentLines.
-                 */
-                if (prevCommentLineNum === comments[i].loc.start.line) {
-                    sumOfCommentLines -= 1;
-                }
-
-                prevCommentLineNum = comments[i].loc.end.line;
+            if (after !== nextFirstToken && after.loc.start.line - prevLastToken.loc.end.line <= maxLine) {
+                return findLastConsecutiveTokenAfter(after, nextFirstToken, maxLine);
             }
+            return prevLastToken;
+        }
 
-            /*
-             * If the first block and the first comment are in the same line,
-             * the count of comment lines is duplicated. So decrement sumOfCommentLines.
-             */
-            if (first.loc.end.line === comments[0].loc.start.line) {
-                sumOfCommentLines -= 1;
-            }
+        /**
+         * Return the first token among the consecutive tokens that have no exceed max line difference in between, after the last token in the previous member.
+         * @param {Token} nextFirstToken The first token in the next member node.
+         * @param {Token} prevLastToken The last token in the previous member node.
+         * @param {number} maxLine The maximum number of allowed line difference between consecutive tokens.
+         * @returns {Token} The first token among the consecutive tokens.
+         */
+        function findFirstConsecutiveTokenBefore(nextFirstToken, prevLastToken, maxLine) {
+            const before = sourceCode.getTokenBefore(nextFirstToken, { includeComments: true });
 
-            /*
-             * If the last comment and the second block are in the same line,
-             * the count of comment lines is duplicated. So decrement sumOfCommentLines.
-             */
-            if (comments[len - 1].loc.end.line === second.loc.start.line) {
-                sumOfCommentLines -= 1;
+            if (before !== prevLastToken && nextFirstToken.loc.start.line - before.loc.end.line <= maxLine) {
+                return findFirstConsecutiveTokenBefore(before, prevLastToken, maxLine);
             }
+            return nextFirstToken;
+        }
 
-            const linesBetweenFstAndSnd = second.loc.start.line - first.loc.end.line - 1;
-
-            return linesBetweenFstAndSnd - sumOfCommentLines >= 1;
+        /**
+         * Checks if there is a token or comment between two tokens.
+         * @param {Token} before The token before.
+         * @param {Token} after The token after.
+         * @returns {boolean} True if there is a token or comment between two tokens.
+         */
+        function hasTokenOrCommentBetween(before, after) {
+            return sourceCode.getTokensBetween(before, after, { includeComments: true }).length !== 0;
         }
 
         return {
@@ -120,10 +103,13 @@ module.exports = {
                     const curFirst = sourceCode.getFirstToken(body[i]);
                     const curLast = sourceCode.getLastToken(body[i]);
                     const nextFirst = sourceCode.getFirstToken(body[i + 1]);
-                    const isPadded = isPaddingBetweenTokens(curLast, nextFirst);
                     const isMulti = !astUtils.isTokenOnSameLine(curFirst, curLast);
                     const skip = !isMulti && options[1].exceptAfterSingleLine;
-
+                    const beforePadding = findLastConsecutiveTokenAfter(curLast, nextFirst, 1);
+                    const afterPadding = findFirstConsecutiveTokenBefore(nextFirst, curLast, 1);
+                    const isPadded = afterPadding.loc.start.line - beforePadding.loc.end.line > 1;
+                    const hasTokenInPadding = hasTokenOrCommentBetween(beforePadding, afterPadding);
+                    const curLineLastToken = findLastConsecutiveTokenAfter(curLast, nextFirst, 0);
 
                     if ((options[0] === "always" && !skip && !isPadded) ||
                         (options[0] === "never" && isPadded)) {
@@ -131,9 +117,12 @@ module.exports = {
                             node: body[i + 1],
                             messageId: isPadded ? "never" : "always",
                             fix(fixer) {
+                                if (hasTokenInPadding) {
+                                    return null;
+                                }
                                 return isPadded
-                                    ? fixer.replaceTextRange([curLast.range[1], nextFirst.range[0]], "\n")
-                                    : fixer.insertTextAfter(curLast, "\n");
+                                    ? fixer.replaceTextRange([beforePadding.range[1], afterPadding.range[0]], "\n")
+                                    : fixer.insertTextAfter(curLineLastToken, "\n");
                             }
                         });
                     }
diff --git a/lib/rules/no-mixed-spaces-and-tabs.js b/lib/rules/no-mixed-spaces-and-tabs.js
index 7b1e2c4a2..5bbc35287 100644
--- a/lib/rules/no-mixed-spaces-and-tabs.js
+++ b/lib/rules/no-mixed-spaces-and-tabs.js
@@ -30,7 +30,6 @@ module.exports = {
         const sourceCode = context.getSourceCode();
 
         let smartTabs;
-        const ignoredLocs = [];
 
         switch (context.options[0]) {
             case true: // Support old syntax, maybe add deprecation warning here
@@ -41,47 +40,23 @@ module.exports = {
                 smartTabs = false;
         }
 
-        /**
-         * Determines if a given line and column are before a location.
-         * @param {Location} loc The location object from an AST node.
-         * @param {int} line The line to check.
-         * @param {int} column The column to check.
-         * @returns {boolean} True if the line and column are before the location, false if not.
-         * @private
-         */
-        function beforeLoc(loc, line, column) {
-            if (line < loc.start.line) {
-                return true;
-            }
-            return line === loc.start.line && column < loc.start.column;
-        }
-
-        /**
-         * Determines if a given line and column are after a location.
-         * @param {Location} loc The location object from an AST node.
-         * @param {int} line The line to check.
-         * @param {int} column The column to check.
-         * @returns {boolean} True if the line and column are after the location, false if not.
-         * @private
-         */
-        function afterLoc(loc, line, column) {
-            if (line > loc.end.line) {
-                return true;
-            }
-            return line === loc.end.line && column > loc.end.column;
-        }
-
         //--------------------------------------------------------------------------
         // Public
         //--------------------------------------------------------------------------
 
         return {
 
-            TemplateElement(node) {
-                ignoredLocs.push(node.loc);
-            },
-
             "Program:exit"(node) {
+                const lines = sourceCode.lines,
+                    comments = sourceCode.getAllComments(),
+                    ignoredCommentLines = new Set();
+
+                // Add all lines except the first ones.
+                comments.forEach(comment => {
+                    for (let i = comment.loc.start.line + 1; i <= comment.loc.end.line; i++) {
+                        ignoredCommentLines.add(i);
+                    }
+                });
 
                 /*
                  * At least one space followed by a tab
@@ -89,24 +64,6 @@ module.exports = {
                  * characters begin.
                  */
                 let regex = /^(?=[\t ]*(\t | \t))/u;
-                const lines = sourceCode.lines,
-                    comments = sourceCode.getAllComments();
-
-                comments.forEach(comment => {
-                    ignoredLocs.push(comment.loc);
-                });
-
-                ignoredLocs.sort((first, second) => {
-                    if (beforeLoc(first, second.start.line, second.start.column)) {
-                        return 1;
-                    }
-
-                    if (beforeLoc(second, first.start.line, second.start.column)) {
-                        return -1;
-                    }
-
-                    return 0;
-                });
 
                 if (smartTabs) {
 
@@ -122,25 +79,19 @@ module.exports = {
 
                     if (match) {
                         const lineNumber = i + 1,
-                            column = match.index + 1;
+                            column = match.index + 1,
+                            loc = { line: lineNumber, column };
 
-                        for (let j = 0; j < ignoredLocs.length; j++) {
-                            if (beforeLoc(ignoredLocs[j], lineNumber, column)) {
-                                continue;
-                            }
-                            if (afterLoc(ignoredLocs[j], lineNumber, column)) {
-                                continue;
-                            }
+                        if (!ignoredCommentLines.has(lineNumber)) {
+                            const containingNode = sourceCode.getNodeByRangeIndex(sourceCode.getIndexFromLoc(loc));
 
-                            return;
+                            if (!(containingNode && ["Literal", "TemplateElement"].includes(containingNode.type))) {
+                                context.report({ node, loc, message: "Mixed spaces and tabs." });
+                            }
                         }
-
-                        context.report({ node, loc: { line: lineNumber, column }, message: "Mixed spaces and tabs." });
                     }
                 });
             }
-
         };
-
     }
 };
diff --git a/lib/rules/no-multiple-empty-lines.js b/lib/rules/no-multiple-empty-lines.js
index f945cfeff..41e6be3a2 100644
--- a/lib/rules/no-multiple-empty-lines.js
+++ b/lib/rules/no-multiple-empty-lines.js
@@ -110,7 +110,7 @@ module.exports = {
                         if (lineNumber - lastLineNumber - 1 > maxAllowed) {
                             context.report({
                                 node,
-                                loc: { start: { line: lastLineNumber + 1, column: 0 }, end: { line: lineNumber, column: 0 } },
+                                loc: { start: { line: lastLineNumber + maxAllowed + 1, column: 0 }, end: { line: lineNumber, column: 0 } },
                                 message,
                                 data: { max: maxAllowed, pluralizedLines: maxAllowed === 1 ? "line" : "lines" },
                                 fix(fixer) {
diff --git a/lib/rules/no-restricted-exports.js b/lib/rules/no-restricted-exports.js
new file mode 100644
index 000000000..5b5c7d9bf
--- /dev/null
+++ b/lib/rules/no-restricted-exports.js
@@ -0,0 +1,84 @@
+/**
+ * @fileoverview Rule to disallow specified names in exports
+ * @author Milos Djermanovic
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = {
+    meta: {
+        type: "suggestion",
+
+        docs: {
+            description: "disallow specified names in exports",
+            category: "ECMAScript 6",
+            recommended: false,
+            url: "https://eslint.org/docs/rules/no-restricted-exports"
+        },
+
+        schema: [{
+            type: "object",
+            properties: {
+                restrictedNamedExports: {
+                    type: "array",
+                    items: {
+                        type: "string"
+                    },
+                    uniqueItems: true
+                }
+            },
+            additionalProperties: false
+        }],
+
+        messages: {
+            restrictedNamed: "'{{name}}' is restricted from being used as an exported name."
+        }
+    },
+
+    create(context) {
+
+        const restrictedNames = new Set(context.options[0] && context.options[0].restrictedNamedExports);
+
+        /**
+         * Checks and reports given exported identifier.
+         * @param {ASTNode} node exported `Identifer` node to check.
+         * @returns {void}
+         */
+        function checkExportedName(node) {
+            const name = node.name;
+
+            if (restrictedNames.has(name)) {
+                context.report({
+                    node,
+                    messageId: "restrictedNamed",
+                    data: { name }
+                });
+            }
+        }
+
+        return {
+            ExportNamedDeclaration(node) {
+                const declaration = node.declaration;
+
+                if (declaration) {
+                    if (declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") {
+                        checkExportedName(declaration.id);
+                    } else if (declaration.type === "VariableDeclaration") {
+                        context.getDeclaredVariables(declaration)
+                            .map(v => v.defs.find(d => d.parent === declaration))
+                            .map(d => d.name) // Identifier nodes
+                            .forEach(checkExportedName);
+                    }
+                } else {
+                    node.specifiers
+                        .map(s => s.exported)
+                        .forEach(checkExportedName);
+                }
+            }
+        };
+    }
+};
diff --git a/lib/rules/no-restricted-imports.js b/lib/rules/no-restricted-imports.js
index bed9c2432..ec0696f99 100644
--- a/lib/rules/no-restricted-imports.js
+++ b/lib/rules/no-restricted-imports.js
@@ -72,14 +72,14 @@ module.exports = {
                 arrayOfStringsOrObjects,
                 {
                     type: "array",
-                    items: {
+                    items: [{
                         type: "object",
                         properties: {
                             paths: arrayOfStringsOrObjects,
                             patterns: arrayOfStrings
                         },
                         additionalProperties: false
-                    },
+                    }],
                     additionalItems: false
                 }
             ]
diff --git a/lib/rules/no-unsafe-negation.js b/lib/rules/no-unsafe-negation.js
index 5c8f569d7..a9c2ee74f 100644
--- a/lib/rules/no-unsafe-negation.js
+++ b/lib/rules/no-unsafe-negation.js
@@ -54,7 +54,8 @@ module.exports = {
             description: "disallow negating the left operand of relational operators",
             category: "Possible Errors",
             recommended: true,
-            url: "https://eslint.org/docs/rules/no-unsafe-negation"
+            url: "https://eslint.org/docs/rules/no-unsafe-negation",
+            suggestion: true
         },
 
         schema: [
@@ -69,9 +70,13 @@ module.exports = {
                 additionalProperties: false
             }
         ],
+
         fixable: null,
+
         messages: {
-            unexpected: "Unexpected negating the left operand of '{{operator}}' operator."
+            unexpected: "Unexpected negating the left operand of '{{operator}}' operator.",
+            suggestNegatedExpression: "Negate '{{operator}}' expression instead of its left operand. This changes the current behavior.",
+            suggestParenthesisedNegation: "Wrap negation in '()' to make the intention explicit. This preserves the current behavior."
         }
     },
 
@@ -82,10 +87,11 @@ module.exports = {
 
         return {
             BinaryExpression(node) {
-                const orderingRelationRuleApplies = enforceForOrderingRelations && isOrderingRelationalOperator(node.operator);
+                const operator = node.operator;
+                const orderingRelationRuleApplies = enforceForOrderingRelations && isOrderingRelationalOperator(operator);
 
                 if (
-                    (isInOrInstanceOfOperator(node.operator) || orderingRelationRuleApplies) &&
+                    (isInOrInstanceOfOperator(operator) || orderingRelationRuleApplies) &&
                     isNegation(node.left) &&
                     !astUtils.isParenthesised(sourceCode, node.left)
                 ) {
@@ -93,7 +99,26 @@ module.exports = {
                         node,
                         loc: node.left.loc,
                         messageId: "unexpected",
-                        data: { operator: node.operator }
+                        data: { operator },
+                        suggest: [
+                            {
+                                messageId: "suggestNegatedExpression",
+                                data: { operator },
+                                fix(fixer) {
+                                    const negationToken = sourceCode.getFirstToken(node.left);
+                                    const fixRange = [negationToken.range[1], node.range[1]];
+                                    const text = sourceCode.text.slice(fixRange[0], fixRange[1]);
+
+                                    return fixer.replaceTextRange(fixRange, `(${text})`);
+                                }
+                            },
+                            {
+                                messageId: "suggestParenthesisedNegation",
+                                fix(fixer) {
+                                    return fixer.replaceText(node.left, `(${sourceCode.getText(node.left)})`);
+                                }
+                            }
+                        ]
                     });
                 }
             }
diff --git a/lib/rules/no-void.js b/lib/rules/no-void.js
index d2b5d2f96..99c837855 100644
--- a/lib/rules/no-void.js
+++ b/lib/rules/no-void.js
@@ -19,22 +19,46 @@ module.exports = {
             url: "https://eslint.org/docs/rules/no-void"
         },
 
-        schema: []
+        messages: {
+            noVoid: "Expected 'undefined' and instead saw 'void'."
+        },
+
+        schema: [
+            {
+                type: "object",
+                properties: {
+                    allowAsStatement: {
+                        type: "boolean",
+                        default: false
+                    }
+                },
+                additionalProperties: false
+            }
+        ]
     },
 
     create(context) {
+        const allowAsStatement =
+            context.options[0] && context.options[0].allowAsStatement;
 
         //--------------------------------------------------------------------------
         // Public
         //--------------------------------------------------------------------------
 
         return {
-            UnaryExpression(node) {
-                if (node.operator === "void") {
-                    context.report({ node, message: "Expected 'undefined' and instead saw 'void'." });
+            'UnaryExpression[operator="void"]'(node) {
+                if (
+                    allowAsStatement &&
+                    node.parent &&
+                    node.parent.type === "ExpressionStatement"
+                ) {
+                    return;
                 }
+                context.report({
+                    node,
+                    messageId: "noVoid"
+                });
             }
         };
-
     }
 };
diff --git a/lib/rules/prefer-numeric-literals.js b/lib/rules/prefer-numeric-literals.js
index 672d9bcaa..c352d88dc 100644
--- a/lib/rules/prefer-numeric-literals.js
+++ b/lib/rules/prefer-numeric-literals.js
@@ -15,6 +15,12 @@ const astUtils = require("./utils/ast-utils");
 // Helpers
 //------------------------------------------------------------------------------
 
+const radixMap = new Map([
+    [2, { system: "binary", literalPrefix: "0b" }],
+    [8, { system: "octal", literalPrefix: "0o" }],
+    [16, { system: "hexadecimal", literalPrefix: "0x" }]
+]);
+
 /**
  * Checks to see if a CallExpression's callee node is `parseInt` or
  * `Number.parseInt`.
@@ -54,49 +60,44 @@ module.exports = {
         },
 
         schema: [],
+
+        messages: {
+            useLiteral: "Use {{system}} literals instead of {{functionName}}()."
+        },
+
         fixable: "code"
     },
 
     create(context) {
         const sourceCode = context.getSourceCode();
 
-        const radixMap = {
-            2: "binary",
-            8: "octal",
-            16: "hexadecimal"
-        };
-
-        const prefixMap = {
-            2: "0b",
-            8: "0o",
-            16: "0x"
-        };
-
         //----------------------------------------------------------------------
         // Public
         //----------------------------------------------------------------------
 
         return {
 
-            CallExpression(node) {
-
-                // doesn't check parseInt() if it doesn't have a radix argument
-                if (node.arguments.length !== 2) {
-                    return;
-                }
+            "CallExpression[arguments.length=2]"(node) {
+                const [strNode, radixNode] = node.arguments,
+                    str = strNode.value,
+                    radix = radixNode.value;
+
+                if (
+                    strNode.type === "Literal" &&
+                    radixNode.type === "Literal" &&
+                    typeof str === "string" &&
+                    typeof radix === "number" &&
+                    radixMap.has(radix) &&
+                    isParseInt(node.callee)
+                ) {
 
-                // only error if the radix is 2, 8, or 16
-                const radixName = radixMap[node.arguments[1].value];
+                    const { system, literalPrefix } = radixMap.get(radix);
 
-                if (isParseInt(node.callee) &&
-                    radixName &&
-                    node.arguments[0].type === "Literal"
-                ) {
                     context.report({
                         node,
-                        message: "Use {{radixName}} literals instead of {{functionName}}().",
+                        messageId: "useLiteral",
                         data: {
-                            radixName,
+                            system,
                             functionName: sourceCode.getText(node.callee)
                         },
                         fix(fixer) {
@@ -104,9 +105,9 @@ module.exports = {
                                 return null;
                             }
 
-                            const replacement = `${prefixMap[node.arguments[1].value]}${node.arguments[0].value}`;
+                            const replacement = `${literalPrefix}${str}`;
 
-                            if (+replacement !== parseInt(node.arguments[0].value, node.arguments[1].value)) {
+                            if (+replacement !== parseInt(str, radix)) {
 
                                 /*
                                  * If the newly-produced literal would be invalid, (e.g. 0b1234),
diff --git a/package.json b/package.json
index 5d0c0ba4a..ccb76c18b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint",
-  "version": "6.7.2",
+  "version": "6.8.0",
   "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
   "description": "An AST-based pattern checker for JavaScript.",
   "bin": {
diff --git a/packages/eslint-config-eslint/default.yml b/packages/eslint-config-eslint/default.yml
index a1fd92ff9..8f3ed3125 100644
--- a/packages/eslint-config-eslint/default.yml
+++ b/packages/eslint-config-eslint/default.yml
@@ -175,6 +175,7 @@ rules:
     prefer-const: "error"
     prefer-numeric-literals: "error"
     prefer-promise-reject-errors: "error"
+    prefer-regex-literals: "error"
     prefer-rest-params: "error"
     prefer-spread: "error"
     prefer-template: "error"
diff --git a/packages/eslint-config-eslint/package.json b/packages/eslint-config-eslint/package.json
index 48bfb65f5..afbe4f558 100644
--- a/packages/eslint-config-eslint/package.json
+++ b/packages/eslint-config-eslint/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint-config-eslint",
-  "version": "5.0.1",
+  "version": "6.0.0",
   "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
   "description": "Default ESLint configuration for ESLint projects.",
   "scripts": {
diff --git a/tools/rule-types.json b/tools/rule-types.json
index 7b5789fbe..d78abfdfd 100644
--- a/tools/rule-types.json
+++ b/tools/rule-types.json
@@ -165,6 +165,7 @@
     "no-prototype-builtins": "problem",
     "no-redeclare": "suggestion",
     "no-regex-spaces": "suggestion",
+    "no-restricted-exports": "suggestion",
     "no-restricted-globals": "suggestion",
     "no-restricted-imports": "suggestion",
     "no-restricted-modules": "suggestion",
diff --git a/webpack.config.js b/webpack.config.js
index 6a43ac755..0c8a0b905 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -17,9 +17,28 @@ module.exports = {
                 test: /\.m?js$/u,
                 loader: "babel-loader",
                 options: {
-                    presets: ["@babel/preset-env"]
+                    presets: [
+                        ["@babel/preset-env", {
+                            debug: true, // ← to print actual browser versions
+
+                            /*
+                             * We want to remove `transform-unicode-regex` convert because of https://github.com/eslint/eslint/pull/12662.
+                             *
+                             * With `>0.5%`, `@babel/preset-env@7.7.6` prints below:
+                             *
+                             *     transform-unicode-regex { "chrome":"49", "ie":"11", "safari":"5.1" }
+                             *
+                             * So this excludes those versions:
+                             *
+                             * - IE 11
+                             * - Chrome 49 (2016; the last version on Windows XP)
+                             * - Safari 5.1 (2011-2013; the last version on Windows)
+                             */
+                            targets: ">0.5%, not chrome 49, not ie 11, not safari 5.1"
+                        }]
+                    ]
                 },
-                exclude: /node_modules\/lodash/u
+                exclude: /node_modules[\\/]lodash/u
             }
         ]
     },


Test patch:
diff --git a/lib/rule-tester/rule-tester.js b/lib/rule-tester/rule-tester.js
index b4b3b2bec..44e01dadf 100644
--- a/lib/rule-tester/rule-tester.js
+++ b/lib/rule-tester/rule-tester.js
@@ -596,8 +596,10 @@ class RuleTester {
                         if (hasOwnProperty(error, "suggestions")) {
 
                             // Support asserting there are no suggestions
-                            if (!error.suggestions) {
-                                assert.strictEqual(message.suggestions, error.suggestions, `Error should have no suggestions on error with message: "${message.message}"`);
+                            if (!error.suggestions || (Array.isArray(error.suggestions) && error.suggestions.length === 0)) {
+                                if (Array.isArray(message.suggestions) && message.suggestions.length > 0) {
+                                    assert.fail(`Error should have no suggestions on error with message: "${message.message}"`);
+                                }
                             } else {
                                 assert.strictEqual(Array.isArray(message.suggestions), true, `Error should have an array of suggestions. Instead received "${message.suggestions}" on error with message: "${message.message}"`);
                                 assert.strictEqual(message.suggestions.length, error.suggestions.length, `Error should have ${error.suggestions.length} suggestions. Instead found ${message.suggestions.length} suggestions`);
diff --git a/tests/fixtures/unmatched-patterns/failing.js b/tests/fixtures/unmatched-patterns/failing.js
new file mode 100644
index 000000000..e24993ff6
--- /dev/null
+++ b/tests/fixtures/unmatched-patterns/failing.js
@@ -0,0 +1,3 @@
+var foo = "bar";
+if (foo) {
+    foo = "bar2";
diff --git a/tests/fixtures/unmatched-patterns/passing.js2 b/tests/fixtures/unmatched-patterns/passing.js2
new file mode 100644
index 000000000..425be7cea
--- /dev/null
+++ b/tests/fixtures/unmatched-patterns/passing.js2
@@ -0,0 +1,5 @@
+let foo = "bar";
+
+if (foo) {
+    foo = "bar2";
+}
diff --git a/tests/lib/cli-engine/formatters/junit.js b/tests/lib/cli-engine/formatters/junit.js
index e52b63a42..b77c17788 100644
--- a/tests/lib/cli-engine/formatters/junit.js
+++ b/tests/lib/cli-engine/formatters/junit.js
@@ -12,12 +12,16 @@
 //------------------------------------------------------------------------------
 
 const assert = require("chai").assert,
-    formatter = require("../../../../lib/cli-engine/formatters/junit");
+    formatter = require("../../../../lib/cli-engine/formatters/junit"),
+    process = require("process");
 
 //------------------------------------------------------------------------------
 // Tests
 //------------------------------------------------------------------------------
 
+const suppliedFilePath = (process.platform === "win32") ? "C:\\path\\to\\foo.js" : "/path/to/foo.js";
+const expectedClassName = (process.platform === "win32") ? "C:\\path\\to\\foo" : "/path/to/foo";
+
 describe("formatter:junit", () => {
     describe("when there are no problems", () => {
         const code = [];
@@ -31,7 +35,7 @@ describe("formatter:junit", () => {
 
     describe("when passed a single message", () => {
         const code = [{
-            filePath: "/path/to/foo.js",
+            filePath: suppliedFilePath,
             messages: [{
                 message: "Unexpected foo.",
                 severity: 2,
@@ -44,20 +48,20 @@ describe("formatter:junit", () => {
         it("should return a single <testcase> with a message and the line and col number in the body (error)", () => {
             const result = formatter(code);
 
-            assert.strictEqual(result.replace(/\n/gu, ""), "<?xml version=\"1.0\" encoding=\"utf-8\"?><testsuites><testsuite package=\"org.eslint\" time=\"0\" tests=\"1\" errors=\"1\" name=\"/path/to/foo.js\"><testcase time=\"0\" name=\"org.eslint.foo\" classname=\"/path/to/foo\"><failure message=\"Unexpected foo.\"><![CDATA[line 5, col 10, Error - Unexpected foo. (foo)]]></failure></testcase></testsuite></testsuites>");
+            assert.strictEqual(result.replace(/\n/gu, ""), `<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite package="org.eslint" time="0" tests="1" errors="1" name="${suppliedFilePath}"><testcase time="0" name="org.eslint.foo" classname="${expectedClassName}"><failure message="Unexpected foo."><![CDATA[line 5, col 10, Error - Unexpected foo. (foo)]]></failure></testcase></testsuite></testsuites>`);
         });
 
         it("should return a single <testcase> with a message and the line and col number in the body (warning)", () => {
             code[0].messages[0].severity = 1;
             const result = formatter(code);
 
-            assert.strictEqual(result.replace(/\n/gu, ""), "<?xml version=\"1.0\" encoding=\"utf-8\"?><testsuites><testsuite package=\"org.eslint\" time=\"0\" tests=\"1\" errors=\"1\" name=\"/path/to/foo.js\"><testcase time=\"0\" name=\"org.eslint.foo\" classname=\"/path/to/foo\"><failure message=\"Unexpected foo.\"><![CDATA[line 5, col 10, Warning - Unexpected foo. (foo)]]></failure></testcase></testsuite></testsuites>");
+            assert.strictEqual(result.replace(/\n/gu, ""), `<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite package="org.eslint" time="0" tests="1" errors="1" name="${suppliedFilePath}"><testcase time="0" name="org.eslint.foo" classname="${expectedClassName}"><failure message="Unexpected foo."><![CDATA[line 5, col 10, Warning - Unexpected foo. (foo)]]></failure></testcase></testsuite></testsuites>`);
         });
     });
 
     describe("when passed a fatal error message", () => {
         const code = [{
-            filePath: "foo.js",
+            filePath: suppliedFilePath,
             messages: [{
                 fatal: true,
                 message: "Unexpected foo.",
@@ -70,13 +74,13 @@ describe("formatter:junit", () => {
         it("should return a single <testcase> and an <error>", () => {
             const result = formatter(code);
 
-            assert.strictEqual(result.replace(/\n/gu, ""), "<?xml version=\"1.0\" encoding=\"utf-8\"?><testsuites><testsuite package=\"org.eslint\" time=\"0\" tests=\"1\" errors=\"1\" name=\"foo.js\"><testcase time=\"0\" name=\"org.eslint.foo\" classname=\"foo\"><error message=\"Unexpected foo.\"><![CDATA[line 5, col 10, Error - Unexpected foo. (foo)]]></error></testcase></testsuite></testsuites>");
+            assert.strictEqual(result.replace(/\n/gu, ""), `<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite package="org.eslint" time="0" tests="1" errors="1" name="${suppliedFilePath}"><testcase time="0" name="org.eslint.foo" classname="${expectedClassName}"><error message="Unexpected foo."><![CDATA[line 5, col 10, Error - Unexpected foo. (foo)]]></error></testcase></testsuite></testsuites>`);
         });
     });
 
     describe("when passed a fatal error message with no line or column", () => {
         const code = [{
-            filePath: "foo.js",
+            filePath: suppliedFilePath,
             messages: [{
                 fatal: true,
                 message: "Unexpected foo."
@@ -86,13 +90,13 @@ describe("formatter:junit", () => {
         it("should return a single <testcase> and an <error>", () => {
             const result = formatter(code);
 
-            assert.strictEqual(result.replace(/\n/gu, ""), "<?xml version=\"1.0\" encoding=\"utf-8\"?><testsuites><testsuite package=\"org.eslint\" time=\"0\" tests=\"1\" errors=\"1\" name=\"foo.js\"><testcase time=\"0\" name=\"org.eslint.unknown\" classname=\"foo\"><error message=\"Unexpected foo.\"><![CDATA[line 0, col 0, Error - Unexpected foo.]]></error></testcase></testsuite></testsuites>");
+            assert.strictEqual(result.replace(/\n/gu, ""), `<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite package="org.eslint" time="0" tests="1" errors="1" name="${suppliedFilePath}"><testcase time="0" name="org.eslint.unknown" classname="${expectedClassName}"><error message="Unexpected foo."><![CDATA[line 0, col 0, Error - Unexpected foo.]]></error></testcase></testsuite></testsuites>`);
         });
     });
 
     describe("when passed a fatal error message with no line, column, or message text", () => {
         const code = [{
-            filePath: "foo.js",
+            filePath: suppliedFilePath,
             messages: [{
                 fatal: true
             }]
@@ -101,13 +105,13 @@ describe("formatter:junit", () => {
         it("should return a single <testcase> and an <error>", () => {
             const result = formatter(code);
 
-            assert.strictEqual(result.replace(/\n/gu, ""), "<?xml version=\"1.0\" encoding=\"utf-8\"?><testsuites><testsuite package=\"org.eslint\" time=\"0\" tests=\"1\" errors=\"1\" name=\"foo.js\"><testcase time=\"0\" name=\"org.eslint.unknown\" classname=\"foo\"><error message=\"\"><![CDATA[line 0, col 0, Error - ]]></error></testcase></testsuite></testsuites>");
+            assert.strictEqual(result.replace(/\n/gu, ""), `<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite package="org.eslint" time="0" tests="1" errors="1" name="${suppliedFilePath}"><testcase time="0" name="org.eslint.unknown" classname="${expectedClassName}"><error message=""><![CDATA[line 0, col 0, Error - ]]></error></testcase></testsuite></testsuites>`);
         });
     });
 
     describe("when passed multiple messages", () => {
         const code = [{
-            filePath: "foo.js",
+            filePath: suppliedFilePath,
             messages: [{
                 message: "Unexpected foo.",
                 severity: 2,
@@ -126,13 +130,13 @@ describe("formatter:junit", () => {
         it("should return a multiple <testcase>'s", () => {
             const result = formatter(code);
 
-            assert.strictEqual(result.replace(/\n/gu, ""), "<?xml version=\"1.0\" encoding=\"utf-8\"?><testsuites><testsuite package=\"org.eslint\" time=\"0\" tests=\"2\" errors=\"2\" name=\"foo.js\"><testcase time=\"0\" name=\"org.eslint.foo\" classname=\"foo\"><failure message=\"Unexpected foo.\"><![CDATA[line 5, col 10, Error - Unexpected foo. (foo)]]></failure></testcase><testcase time=\"0\" name=\"org.eslint.bar\" classname=\"foo\"><failure message=\"Unexpected bar.\"><![CDATA[line 6, col 11, Warning - Unexpected bar. (bar)]]></failure></testcase></testsuite></testsuites>");
+            assert.strictEqual(result.replace(/\n/gu, ""), `<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite package="org.eslint" time="0" tests="2" errors="2" name="${suppliedFilePath}"><testcase time="0" name="org.eslint.foo" classname="${expectedClassName}"><failure message="Unexpected foo."><![CDATA[line 5, col 10, Error - Unexpected foo. (foo)]]></failure></testcase><testcase time="0" name="org.eslint.bar" classname="${expectedClassName}"><failure message="Unexpected bar."><![CDATA[line 6, col 11, Warning - Unexpected bar. (bar)]]></failure></testcase></testsuite></testsuites>`);
         });
     });
 
     describe("when passed special characters", () => {
         const code = [{
-            filePath: "foo.js",
+            filePath: suppliedFilePath,
             messages: [{
                 message: "Unexpected <foo></foo>\b\t\n\f\r牛逼.",
                 severity: 1,
@@ -145,13 +149,13 @@ describe("formatter:junit", () => {
         it("should make them go away", () => {
             const result = formatter(code);
 
-            assert.strictEqual(result.replace(/\n/gu, ""), "<?xml version=\"1.0\" encoding=\"utf-8\"?><testsuites><testsuite package=\"org.eslint\" time=\"0\" tests=\"1\" errors=\"1\" name=\"foo.js\"><testcase time=\"0\" name=\"org.eslint.foo\" classname=\"foo\"><failure message=\"Unexpected &lt;foo&gt;&lt;/foo&gt;&#8;&#9;&#10;&#12;&#13;&#29275;&#36924;.\"><![CDATA[line 5, col 10, Warning - Unexpected &lt;foo&gt;&lt;/foo&gt;&#8;&#9;&#10;&#12;&#13;&#29275;&#36924;. (foo)]]></failure></testcase></testsuite></testsuites>");
+            assert.strictEqual(result.replace(/\n/gu, ""), `<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite package="org.eslint" time="0" tests="1" errors="1" name="${suppliedFilePath}"><testcase time="0" name="org.eslint.foo" classname="${expectedClassName}"><failure message="Unexpected &lt;foo&gt;&lt;/foo&gt;&#8;&#9;&#10;&#12;&#13;&#29275;&#36924;."><![CDATA[line 5, col 10, Warning - Unexpected &lt;foo&gt;&lt;/foo&gt;&#8;&#9;&#10;&#12;&#13;&#29275;&#36924;. (foo)]]></failure></testcase></testsuite></testsuites>`);
         });
     });
 
     describe("when passed multiple files with 1 message each", () => {
         const code = [{
-            filePath: "foo.js",
+            filePath: suppliedFilePath,
             messages: [{
                 message: "Unexpected foo.",
                 severity: 1,
@@ -173,13 +177,13 @@ describe("formatter:junit", () => {
         it("should return 2 <testsuite>'s", () => {
             const result = formatter(code);
 
-            assert.strictEqual(result.replace(/\n/gu, ""), "<?xml version=\"1.0\" encoding=\"utf-8\"?><testsuites><testsuite package=\"org.eslint\" time=\"0\" tests=\"1\" errors=\"1\" name=\"foo.js\"><testcase time=\"0\" name=\"org.eslint.foo\" classname=\"foo\"><failure message=\"Unexpected foo.\"><![CDATA[line 5, col 10, Warning - Unexpected foo. (foo)]]></failure></testcase></testsuite><testsuite package=\"org.eslint\" time=\"0\" tests=\"1\" errors=\"1\" name=\"bar.js\"><testcase time=\"0\" name=\"org.eslint.bar\" classname=\"bar\"><failure message=\"Unexpected bar.\"><![CDATA[line 6, col 11, Error - Unexpected bar. (bar)]]></failure></testcase></testsuite></testsuites>");
+            assert.strictEqual(result.replace(/\n/gu, ""), `<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite package="org.eslint" time="0" tests="1" errors="1" name="${suppliedFilePath}"><testcase time="0" name="org.eslint.foo" classname="${expectedClassName}"><failure message="Unexpected foo."><![CDATA[line 5, col 10, Warning - Unexpected foo. (foo)]]></failure></testcase></testsuite><testsuite package="org.eslint" time="0" tests="1" errors="1" name="bar.js"><testcase time="0" name="org.eslint.bar" classname="bar"><failure message="Unexpected bar."><![CDATA[line 6, col 11, Error - Unexpected bar. (bar)]]></failure></testcase></testsuite></testsuites>`);
         });
     });
 
     describe("when passed multiple files should print even if no errors", () => {
         const code = [{
-            filePath: "foo.js",
+            filePath: suppliedFilePath,
             messages: [{
                 message: "Unexpected foo.",
                 severity: 1,
@@ -195,20 +199,20 @@ describe("formatter:junit", () => {
         it("should return 2 <testsuite>", () => {
             const result = formatter(code);
 
-            assert.strictEqual(result.replace(/\n/gu, ""), "<?xml version=\"1.0\" encoding=\"utf-8\"?><testsuites><testsuite package=\"org.eslint\" time=\"0\" tests=\"1\" errors=\"1\" name=\"foo.js\"><testcase time=\"0\" name=\"org.eslint.foo\" classname=\"foo\"><failure message=\"Unexpected foo.\"><![CDATA[line 5, col 10, Warning - Unexpected foo. (foo)]]></failure></testcase></testsuite><testsuite package=\"org.eslint\" time=\"0\" tests=\"1\" errors=\"0\" name=\"bar.js\"><testcase time=\"0\" name=\"bar.js\" classname=\"bar\" /></testsuite></testsuites>");
+            assert.strictEqual(result.replace(/\n/gu, ""), `<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite package="org.eslint" time="0" tests="1" errors="1" name="${suppliedFilePath}"><testcase time="0" name="org.eslint.foo" classname="${expectedClassName}"><failure message="Unexpected foo."><![CDATA[line 5, col 10, Warning - Unexpected foo. (foo)]]></failure></testcase></testsuite><testsuite package="org.eslint" time="0" tests="1" errors="0" name="bar.js"><testcase time="0" name="bar.js" classname="bar" /></testsuite></testsuites>`);
         });
     });
 
     describe("when passed a file with no errors", () => {
         const code = [{
-            filePath: "foo.js",
+            filePath: suppliedFilePath,
             messages: []
         }];
 
         it("should print a passing <testcase>", () => {
             const result = formatter(code);
 
-            assert.strictEqual(result.replace(/\n/gu, ""), "<?xml version=\"1.0\" encoding=\"utf-8\"?><testsuites><testsuite package=\"org.eslint\" time=\"0\" tests=\"1\" errors=\"0\" name=\"foo.js\"><testcase time=\"0\" name=\"foo.js\" classname=\"foo\" /></testsuite></testsuites>");
+            assert.strictEqual(result.replace(/\n/gu, ""), `<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite package="org.eslint" time="0" tests="1" errors="0" name="${suppliedFilePath}"><testcase time="0" name="${suppliedFilePath}" classname="${expectedClassName}" /></testsuite></testsuites>`);
         });
     });
 });
diff --git a/tests/lib/cli.js b/tests/lib/cli.js
index e0f10d5ae..6af3b5c83 100644
--- a/tests/lib/cli.js
+++ b/tests/lib/cli.js
@@ -347,6 +347,74 @@ describe("cli", () => {
         });
     });
 
+    describe("when executing without no-error-on-unmatched-pattern flag", () => {
+        it("should throw an error on unmatched glob pattern", () => {
+            const filePath = getFixturePath("unmatched-patterns");
+            const globPattern = "*.js3";
+
+            assert.throws(() => {
+                cli.execute(`"${filePath}/${globPattern}"`);
+            }, `No files matching '${filePath}/${globPattern}' were found.`);
+        });
+
+        it("should throw an error on unmatched --ext", () => {
+            const filePath = getFixturePath("unmatched-patterns");
+            const extension = ".js3";
+
+            assert.throws(() => {
+                cli.execute(`--ext ${extension} ${filePath}`);
+            }, `No files matching '${filePath}' were found`);
+        });
+    });
+
+    describe("when executing with no-error-on-unmatched-pattern flag", () => {
+        it("should not throw an error on unmatched node glob syntax patterns", () => {
+            const filePath = getFixturePath("unmatched-patterns");
+            const exit = cli.execute(`--no-error-on-unmatched-pattern "${filePath}/*.js3"`);
+
+            assert.strictEqual(exit, 0);
+        });
+
+        it("should not throw an error on unmatched --ext", () => {
+            const filePath = getFixturePath("unmatched-patterns");
+            const exit = cli.execute(`--no-error-on-unmatched-pattern --ext .js3 ${filePath}`);
+
+            assert.strictEqual(exit, 0);
+        });
+    });
+
+    describe("when executing with no-error-on-unmatched-pattern flag and multiple patterns", () => {
+        it("should not throw an error on multiple unmatched node glob syntax patterns", () => {
+            const filePath = getFixturePath("unmatched-patterns");
+            const exit = cli.execute(`--no-error-on-unmatched-pattern ${filePath}/*.js3 ${filePath}/*.js4`);
+
+            assert.strictEqual(exit, 0);
+        });
+
+        it("should still throw an error on when a matched pattern has lint errors", () => {
+            const filePath = getFixturePath("unmatched-patterns");
+            const exit = cli.execute(`--no-error-on-unmatched-pattern ${filePath}/*.js3 ${filePath}/*.js`);
+
+            assert.strictEqual(exit, 1);
+        });
+    });
+
+    describe("when executing with no-error-on-unmatched-pattern flag and multiple --ext arguments", () => {
+        it("should not throw an error on multiple unmatched --ext arguments", () => {
+            const filePath = getFixturePath("unmatched-patterns");
+            const exit = cli.execute(`--no-error-on-unmatched-pattern --ext .js3 --ext .js4 ${filePath}`);
+
+            assert.strictEqual(exit, 0);
+        });
+
+        it("should still throw an error on when a matched pattern has lint errors", () => {
+            const filePath = getFixturePath("unmatched-patterns");
+            const exit = cli.execute(`--no-error-on-unmatched-pattern --ext .js3 --ext .js ${filePath}`);
+
+            assert.strictEqual(exit, 1);
+        });
+    });
+
     describe("when executing with help flag", () => {
         it("should print out help", () => {
             assert.strictEqual(cli.execute("-h"), 0);
diff --git a/tests/lib/rule-tester/rule-tester.js b/tests/lib/rule-tester/rule-tester.js
index 6ab341ccc..4abb053ab 100644
--- a/tests/lib/rule-tester/rule-tester.js
+++ b/tests/lib/rule-tester/rule-tester.js
@@ -1018,29 +1018,33 @@ describe("RuleTester", () => {
         });
 
         it("should support explicitly expecting no suggestions", () => {
-            ruleTester.run("suggestions-basic", require("../../fixtures/testers/rule-tester/no-eval"), {
-                valid: [],
-                invalid: [{
-                    code: "eval('var foo');",
-                    errors: [{
-                        suggestions: void 0
-                    }]
-                }]
-            });
-        });
-
-        it("should fail when expecting no suggestions and there are suggestions", () => {
-            assert.throws(() => {
-                ruleTester.run("suggestions-basic", require("../../fixtures/testers/rule-tester/suggestions").basic, {
+            [void 0, null, false, []].forEach(suggestions => {
+                ruleTester.run("suggestions-basic", require("../../fixtures/testers/rule-tester/no-eval"), {
                     valid: [],
                     invalid: [{
-                        code: "var foo;",
+                        code: "eval('var foo');",
                         errors: [{
-                            suggestions: void 0
+                            suggestions
                         }]
                     }]
                 });
-            }, "Error should have no suggestions on error with message: \"Avoid using identifiers named 'foo'.\"");
+            });
+        });
+
+        it("should fail when expecting no suggestions and there are suggestions", () => {
+            [void 0, null, false, []].forEach(suggestions => {
+                assert.throws(() => {
+                    ruleTester.run("suggestions-basic", require("../../fixtures/testers/rule-tester/suggestions").basic, {
+                        valid: [],
+                        invalid: [{
+                            code: "var foo;",
+                            errors: [{
+                                suggestions
+                            }]
+                        }]
+                    });
+                }, "Error should have no suggestions on error with message: \"Avoid using identifiers named 'foo'.\"");
+            });
         });
 
         it("should fail when testing for suggestions that don't exist", () => {
diff --git a/tests/lib/rules/array-bracket-spacing.js b/tests/lib/rules/array-bracket-spacing.js
index 120c90501..33caf0889 100644
--- a/tests/lib/rules/array-bracket-spacing.js
+++ b/tests/lib/rules/array-bracket-spacing.js
@@ -190,7 +190,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 }
             ]
         },
@@ -208,7 +210,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 },
                 {
                     messageId: "missingSpaceBefore",
@@ -217,7 +221,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 36
+                    column: 36,
+                    endLine: 1,
+                    endColumn: 37
                 }
             ]
         },
@@ -233,7 +239,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 11,
+                    endLine: 1,
+                    endColumn: 12
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
@@ -242,7 +250,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 35
+                    column: 34,
+                    endLine: 1,
+                    endColumn: 35
                 }
             ]
         },
@@ -258,7 +268,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
@@ -267,7 +279,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 50
+                    column: 49,
+                    endLine: 1,
+                    endColumn: 50
                 }
             ]
         },
@@ -285,7 +299,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
@@ -294,7 +310,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 19
+                    column: 18,
+                    endLine: 1,
+                    endColumn: 19
                 }
             ]
         },
@@ -310,7 +328,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 18
+                    column: 17,
+                    endLine: 1,
+                    endColumn: 18
                 }
             ]
         },
@@ -326,7 +346,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 11,
+                    endLine: 1,
+                    endColumn: 12
                 },
                 {
                     messageId: "missingSpaceBefore",
@@ -335,7 +357,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 17
+                    column: 17,
+                    endLine: 1,
+                    endColumn: 18
                 }
             ]
         },
@@ -353,7 +377,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 }
             ]
         },
@@ -369,7 +395,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 31
+                    column: 30,
+                    endLine: 1,
+                    endColumn: 31
                 }
             ]
         },
@@ -385,7 +413,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 34
+                    column: 33,
+                    endLine: 1,
+                    endColumn: 34
                 }
             ]
         },
@@ -401,7 +431,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 }
             ]
         },
@@ -417,7 +449,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
@@ -426,7 +460,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 35
+                    column: 34,
+                    endLine: 1,
+                    endColumn: 35
                 }
             ]
         },
@@ -444,7 +480,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 5
+                column: 5,
+                endLine: 1,
+                endColumn: 6
             },
             {
                 messageId: "missingSpaceBefore",
@@ -453,7 +491,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 9
+                column: 9,
+                endLine: 1,
+                endColumn: 10
             }]
         },
         {
@@ -468,7 +508,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 5
+                column: 5,
+                endLine: 1,
+                endColumn: 6
             }]
         },
         {
@@ -483,7 +525,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 5
+                column: 5,
+                endLine: 1,
+                endColumn: 6
             },
             {
                 messageId: "missingSpaceBefore",
@@ -492,7 +536,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 12
+                column: 12,
+                endLine: 1,
+                endColumn: 13
             }]
         },
         {
@@ -507,7 +553,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 13
+                column: 13,
+                endLine: 1,
+                endColumn: 14
             }]
         },
         {
@@ -522,7 +570,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 5
+                column: 5,
+                endLine: 1,
+                endColumn: 6
             },
             {
                 messageId: "missingSpaceBefore",
@@ -531,7 +581,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 14
+                column: 14,
+                endLine: 1,
+                endColumn: 15
             }]
         },
         {
@@ -546,7 +598,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 5
+                column: 5,
+                endLine: 1,
+                endColumn: 6
             }]
         },
         {
@@ -561,7 +615,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 5
+                column: 6,
+                endLine: 1,
+                endColumn: 7
             }]
         },
         {
@@ -576,7 +632,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 1
+                column: 2,
+                endLine: 1,
+                endColumn: 3
             }]
         },
         {
@@ -591,7 +649,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 15
+                column: 14,
+                endLine: 1,
+                endColumn: 15
             }]
         },
 
@@ -608,7 +668,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 11,
+                    endLine: 1,
+                    endColumn: 12
                 },
                 {
                     messageId: "missingSpaceBefore",
@@ -617,7 +679,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 29
+                    column: 29,
+                    endLine: 1,
+                    endColumn: 30
                 }
             ]
         },
@@ -633,7 +697,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 }
             ]
         },
@@ -651,7 +717,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 }
             ]
         },
@@ -669,7 +737,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 11,
+                    endLine: 1,
+                    endColumn: 12
                 },
                 {
                     messageId: "missingSpaceBefore",
@@ -678,7 +748,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 22
+                    column: 22,
+                    endLine: 1,
+                    endColumn: 23
                 }
             ]
         },
@@ -694,7 +766,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 11,
+                    endLine: 1,
+                    endColumn: 12
                 }
             ]
         },
@@ -710,7 +784,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 23
+                    column: 23,
+                    endLine: 1,
+                    endColumn: 24
                 }
             ]
         },
@@ -728,7 +804,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
@@ -737,7 +815,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 24
+                    column: 23,
+                    endLine: 1,
+                    endColumn: 24
                 }
             ]
         },
@@ -753,7 +833,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 23
+                    column: 22,
+                    endLine: 1,
+                    endColumn: 23
                 }
             ]
         },
@@ -769,7 +851,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 }
             ]
         },
@@ -785,7 +869,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 },
                 {
                     messageId: "unexpectedSpaceAfter",
@@ -794,7 +880,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 13
+                    column: 14,
+                    endLine: 1,
+                    endColumn: 15
                 }
             ]
         },
@@ -810,7 +898,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 15
+                    column: 14,
+                    endLine: 1,
+                    endColumn: 15
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
@@ -819,7 +909,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 26
+                    column: 25,
+                    endLine: 1,
+                    endColumn: 26
                 }
             ]
         },
@@ -841,7 +933,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayPattern",
                     line: 1,
-                    column: 2
+                    column: 3,
+                    endLine: 1,
+                    endColumn: 4
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
@@ -850,7 +944,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayPattern",
                     line: 1,
-                    column: 9
+                    column: 8,
+                    endLine: 1,
+                    endColumn: 9
                 }
             ]
         },
@@ -870,7 +966,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayPattern",
                     line: 1,
-                    column: 2
+                    column: 2,
+                    endLine: 1,
+                    endColumn: 3
                 },
                 {
                     messageId: "missingSpaceBefore",
@@ -879,7 +977,152 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayPattern",
                     line: 1,
-                    column: 7
+                    column: 7,
+                    endLine: 1,
+                    endColumn: 8
+                }
+            ]
+        },
+
+        // multiple spaces
+        {
+            code: "var arr = [  1, 2   ];",
+            output: "var arr = [1, 2];",
+            options: ["never"],
+            errors: [
+                {
+                    messageId: "unexpectedSpaceAfter",
+                    data: {
+                        tokenValue: "["
+                    },
+                    type: "ArrayExpression",
+                    line: 1,
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 14
+                },
+                {
+                    messageId: "unexpectedSpaceBefore",
+                    data: {
+                        tokenValue: "]"
+                    },
+                    type: "ArrayExpression",
+                    line: 1,
+                    column: 18,
+                    endLine: 1,
+                    endColumn: 21
+                }
+            ]
+        },
+        {
+            code: "function f( [   a, b  ] ) {}",
+            output: "function f( [a, b] ) {}",
+            options: ["never"],
+            parserOptions: {
+                ecmaVersion: 6
+            },
+            errors: [
+                {
+                    messageId: "unexpectedSpaceAfter",
+                    data: {
+                        tokenValue: "["
+                    },
+                    type: "ArrayPattern",
+                    line: 1,
+                    column: 14,
+                    endLine: 1,
+                    endColumn: 17
+                },
+                {
+                    messageId: "unexpectedSpaceBefore",
+                    data: {
+                        tokenValue: "]"
+                    },
+                    type: "ArrayPattern",
+                    line: 1,
+                    column: 21,
+                    endLine: 1,
+                    endColumn: 23
+                }
+            ]
+        },
+        {
+            code: "var arr = [ 1,\n   2   ];",
+            output: "var arr = [1,\n   2];",
+            options: ["never"],
+            errors: [
+                {
+                    messageId: "unexpectedSpaceAfter",
+                    data: {
+                        tokenValue: "["
+                    },
+                    type: "ArrayExpression",
+                    line: 1,
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
+                },
+                {
+                    messageId: "unexpectedSpaceBefore",
+                    data: {
+                        tokenValue: "]"
+                    },
+                    type: "ArrayExpression",
+                    line: 2,
+                    column: 5,
+                    endLine: 2,
+                    endColumn: 8
+                }
+            ]
+        },
+        {
+            code: "var arr = [  1, [ 2, 3  ] ];",
+            output: "var arr = [1, [2, 3]];",
+            options: ["never"],
+            errors: [
+                {
+                    messageId: "unexpectedSpaceAfter",
+                    data: {
+                        tokenValue: "["
+                    },
+                    type: "ArrayExpression",
+                    line: 1,
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 14
+                },
+                {
+                    messageId: "unexpectedSpaceAfter",
+                    data: {
+                        tokenValue: "["
+                    },
+                    type: "ArrayExpression",
+                    line: 1,
+                    column: 18,
+                    endLine: 1,
+                    endColumn: 19
+                },
+                {
+                    messageId: "unexpectedSpaceBefore",
+                    data: {
+                        tokenValue: "]"
+                    },
+                    type: "ArrayExpression",
+                    line: 1,
+                    column: 23,
+                    endLine: 1,
+                    endColumn: 25
+                },
+                {
+                    messageId: "unexpectedSpaceBefore",
+                    data: {
+                        tokenValue: "]"
+                    },
+                    type: "ArrayExpression",
+                    line: 1,
+                    column: 26,
+                    endLine: 1,
+                    endColumn: 27
                 }
             ]
         }
diff --git a/tests/lib/rules/for-direction.js b/tests/lib/rules/for-direction.js
index 4dd4f8a99..a04b10e11 100644
--- a/tests/lib/rules/for-direction.js
+++ b/tests/lib/rules/for-direction.js
@@ -53,7 +53,13 @@ ruleTester.run("for-direction", rule, {
         "for(var i = 10; i >= 0; i %= 2){}",
         "for(var i = 0; i < MAX; i += STEP_SIZE);",
         "for(var i = 0; i < MAX; i -= STEP_SIZE);",
-        "for(var i = 10; i > 0; i += STEP_SIZE);"
+        "for(var i = 10; i > 0; i += STEP_SIZE);",
+
+        // other cond-expressions.
+        "for(var i = 0; i !== 10; i+=1){}",
+        "for(var i = 0; i === 10; i+=1){}",
+        "for(var i = 0; i == 10; i+=1){}",
+        "for(var i = 0; i != 10; i+=1){}"
     ],
     invalid: [
 
diff --git a/tests/lib/rules/indent.js b/tests/lib/rules/indent.js
index 249f9bc91..93ebb2824 100644
--- a/tests/lib/rules/indent.js
+++ b/tests/lib/rules/indent.js
@@ -2097,6 +2097,86 @@ ruleTester.run("indent", rule, {
             `,
             options: [2]
         },
+        {
+            code: unIndent`
+              condition
+                ? () => {
+                  return true
+                }
+                : condition2
+                  ? () => {
+                    return true
+                  }
+                  : () => {
+                    return false
+                  }
+            `,
+            options: [2]
+        },
+        {
+            code: unIndent`
+              condition
+                ? () => {
+                  return true
+                }
+                : condition2
+                  ? () => {
+                    return true
+                  }
+                  : () => {
+                    return false
+                  }
+            `,
+            options: [2, { offsetTernaryExpressions: false }]
+        },
+        {
+            code: unIndent`
+              condition
+                ? () => {
+                    return true
+                  }
+                : condition2
+                  ? () => {
+                      return true
+                    }
+                  : () => {
+                      return false
+                    }
+            `,
+            options: [2, { offsetTernaryExpressions: true }]
+        },
+        {
+            code: unIndent`
+              condition
+                  ? () => {
+                          return true
+                      }
+                  : condition2
+                      ? () => {
+                              return true
+                          }
+                      : () => {
+                              return false
+                          }
+            `,
+            options: [4, { offsetTernaryExpressions: true }]
+        },
+        {
+            code: unIndent`
+              condition
+              \t? () => {
+              \t\t\treturn true
+              \t\t}
+              \t: condition2
+              \t\t? () => {
+              \t\t\t\treturn true
+              \t\t\t}
+              \t\t: () => {
+              \t\t\t\treturn false
+              \t\t\t}
+            `,
+            options: ["tab", { offsetTernaryExpressions: true }]
+        },
         unIndent`
             [
                 foo ?
@@ -7705,6 +7785,88 @@ ruleTester.run("indent", rule, {
             `,
             errors: expectedErrors([5, 4, 8, "Identifier"])
         },
+        {
+            code: unIndent`
+              condition
+              ? () => {
+              return true
+              }
+              : condition2
+              ? () => {
+              return true
+              }
+              : () => {
+              return false
+              }
+            `,
+            output: unIndent`
+              condition
+                ? () => {
+                    return true
+                  }
+                : condition2
+                  ? () => {
+                      return true
+                    }
+                  : () => {
+                      return false
+                    }
+            `,
+            options: [2, { offsetTernaryExpressions: true }],
+            errors: expectedErrors([
+                [2, 2, 0, "Punctuator"],
+                [3, 6, 0, "Keyword"],
+                [4, 4, 0, "Punctuator"],
+                [5, 2, 0, "Punctuator"],
+                [6, 4, 0, "Punctuator"],
+                [7, 8, 0, "Keyword"],
+                [8, 6, 0, "Punctuator"],
+                [9, 4, 0, "Punctuator"],
+                [10, 8, 0, "Keyword"],
+                [11, 6, 0, "Punctuator"]
+            ])
+        },
+        {
+            code: unIndent`
+              condition
+              ? () => {
+              return true
+              }
+              : condition2
+              ? () => {
+              return true
+              }
+              : () => {
+              return false
+              }
+            `,
+            output: unIndent`
+              condition
+                ? () => {
+                  return true
+                }
+                : condition2
+                  ? () => {
+                    return true
+                  }
+                  : () => {
+                    return false
+                  }
+            `,
+            options: [2, { offsetTernaryExpressions: false }],
+            errors: expectedErrors([
+                [2, 2, 0, "Punctuator"],
+                [3, 4, 0, "Keyword"],
+                [4, 2, 0, "Punctuator"],
+                [5, 2, 0, "Punctuator"],
+                [6, 4, 0, "Punctuator"],
+                [7, 6, 0, "Keyword"],
+                [8, 4, 0, "Punctuator"],
+                [9, 4, 0, "Punctuator"],
+                [10, 6, 0, "Keyword"],
+                [11, 4, 0, "Punctuator"]
+            ])
+        },
         {
 
             /*
diff --git a/tests/lib/rules/key-spacing.js b/tests/lib/rules/key-spacing.js
index a9ed53374..29bbbe857 100644
--- a/tests/lib/rules/key-spacing.js
+++ b/tests/lib/rules/key-spacing.js
@@ -757,6 +757,141 @@ ruleTester.run("key-spacing", rule, {
             }
         }],
         parserOptions: { ecmaVersion: 6 }
+    }, {
+        code: [
+            "var obj = {",
+            "    foo : 1, 'bar' : 2, baz : 3, longlonglong : 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            multiLine: {
+                beforeColon: true,
+                afterColon: true,
+                align: "colon"
+            }
+        }]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo: 1, 'bar': 2, baz: 3",
+            "}"
+        ].join("\n"),
+        options: [{
+            multiLine: {
+                align: "value"
+            }
+        }]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo: 1",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            multiLine: {
+                align: "value"
+            }
+        }]
+    }, {
+        code: [
+            "foo({",
+            "    bar: 1",
+            "})"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "colon"
+            }
+        }]
+    }, {
+        code: "var obj = { foo:1, 'bar':2, baz:3, longlonglong:4 }",
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "colon"
+            }
+        }]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo         : 1,",
+            "    'bar'       : 2, baz         : 3, longlonglong: 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "colon"
+            }
+        }]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo:          1,",
+            "    'bar':        2, baz:          3, longlonglong: 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "value"
+            }
+        }]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo         : 1,",
+            "    'bar'       : 2, baz         : 3,",
+            "    longlonglong: 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "colon"
+            }
+        }]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo:          1,",
+            "    'bar':        2, baz:          3,",
+            "    longlonglong: 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "value"
+            }
+        }]
     }],
 
     invalid: [{
@@ -1769,5 +1904,206 @@ ruleTester.run("key-spacing", rule, {
             { messageId: "missingKey", data: { computed: "", key: "foo" }, line: 1, column: 7, type: "Identifier" },
             { messageId: "missingValue", data: { computed: "", key: "foo" }, line: 1, column: 19, type: "Identifier" }
         ]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo:1, 'bar':2, baz:3",
+            "}"
+        ].join("\n"),
+        output: [
+            "var obj = {",
+            "    foo : 1, 'bar' : 2, baz : 3",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            multiLine: {
+                beforeColon: true,
+                afterColon: true,
+                align: "colon"
+            }
+        }],
+        errors: [
+            { messageId: "missingKey", data: { computed: "", key: "foo" }, line: 2, column: 5, type: "Identifier" },
+            { messageId: "missingValue", data: { computed: "", key: "foo" }, line: 2, column: 9, type: "Literal" },
+            { messageId: "missingKey", data: { computed: "", key: "bar" }, line: 2, column: 12, type: "Literal" },
+            { messageId: "missingValue", data: { computed: "", key: "bar" }, line: 2, column: 18, type: "Literal" },
+            { messageId: "missingKey", data: { computed: "", key: "baz" }, line: 2, column: 21, type: "Identifier" },
+            { messageId: "missingValue", data: { computed: "", key: "baz" }, line: 2, column: 25, type: "Literal" }
+        ]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo : 1, 'bar' : 2, baz : 3, longlonglong : 4",
+            "}"
+        ].join("\n"),
+        output: [
+            "var obj = {",
+            "    foo: 1, 'bar': 2, baz: 3, longlonglong: 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            multiLine: {
+                align: "value"
+            }
+        }],
+        errors: [
+            { messageId: "extraKey", data: { computed: "", key: "foo" }, line: 2, column: 5, type: "Identifier" },
+            { messageId: "extraKey", data: { computed: "", key: "bar" }, line: 2, column: 14, type: "Literal" },
+            { messageId: "extraKey", data: { computed: "", key: "baz" }, line: 2, column: 25, type: "Identifier" },
+            { messageId: "extraKey", data: { computed: "", key: "longlonglong" }, line: 2, column: 34, type: "Identifier" }
+        ]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo:1",
+            "}"
+        ].join("\n"),
+        output: [
+            "var obj = {",
+            "    foo: 1",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            multiLine: {
+                align: "value"
+            }
+        }],
+        errors: [
+            { messageId: "missingValue", data: { computed: "", key: "foo" }, line: 2, column: 9, type: "Literal" }
+        ]
+    }, {
+        code: [
+            "foo({",
+            "    bar:1",
+            "})"
+        ].join("\n"),
+        output: [
+            "foo({",
+            "    bar: 1",
+            "})"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "colon"
+            }
+        }],
+        errors: [
+            { messageId: "missingValue", data: { computed: "", key: "bar" }, line: 2, column: 9, type: "Literal" }
+        ]
+    }, {
+        code: "var obj = { foo: 1, 'bar': 2, baz :3, longlonglong :4 }",
+        output: "var obj = { foo:1, 'bar':2, baz:3, longlonglong:4 }",
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "colon"
+            }
+        }],
+        errors: [
+            { messageId: "extraValue", data: { computed: "", key: "foo" }, line: 1, column: 18, type: "Literal" },
+            { messageId: "extraValue", data: { computed: "", key: "bar" }, line: 1, column: 28, type: "Literal" },
+            { messageId: "extraKey", data: { computed: "", key: "baz" }, line: 1, column: 31, type: "Identifier" },
+            { messageId: "extraKey", data: { computed: "", key: "longlonglong" }, line: 1, column: 39, type: "Identifier" }
+        ]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo: 1,",
+            "    'bar': 2, baz: 3, longlonglong: 4",
+            "}"
+        ].join("\n"),
+        output: [
+            "var obj = {",
+            "    foo         : 1,",
+            "    'bar'       : 2, baz         : 3, longlonglong: 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "colon"
+            }
+        }],
+        errors: [
+            { messageId: "missingKey", data: { computed: "", key: "foo" }, line: 2, column: 5, type: "Identifier" },
+            { messageId: "missingKey", data: { computed: "", key: "bar" }, line: 3, column: 5, type: "Literal" },
+            { messageId: "missingKey", data: { computed: "", key: "baz" }, line: 3, column: 15, type: "Identifier" }
+        ]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo : 1,",
+            "    'bar' : 2, baz : 3,",
+            "    longlonglong: 4",
+            "}"
+        ].join("\n"),
+        output: [
+            "var obj = {",
+            "    foo         : 1,",
+            "    'bar'       : 2, baz         : 3,",
+            "    longlonglong: 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "colon"
+            }
+        }],
+        errors: [
+            { messageId: "missingKey", data: { computed: "", key: "foo" }, line: 2, column: 5, type: "Identifier" },
+            { messageId: "missingKey", data: { computed: "", key: "bar" }, line: 3, column: 5, type: "Literal" },
+            { messageId: "missingKey", data: { computed: "", key: "baz" }, line: 3, column: 16, type: "Identifier" }
+        ]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo: 1,",
+            "    'bar': 2, baz: 3,",
+            "    longlonglong: 4",
+            "}"
+        ].join("\n"),
+        output: [
+            "var obj = {",
+            "    foo:          1,",
+            "    'bar':        2, baz:          3,",
+            "    longlonglong: 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "value"
+            }
+        }],
+        errors: [
+            { messageId: "missingValue", data: { computed: "", key: "foo" }, line: 2, column: 10, type: "Literal" },
+            { messageId: "missingValue", data: { computed: "", key: "bar" }, line: 3, column: 12, type: "Literal" },
+            { messageId: "missingValue", data: { computed: "", key: "baz" }, line: 3, column: 20, type: "Literal" }
+        ]
     }]
 });
diff --git a/tests/lib/rules/lines-between-class-members.js b/tests/lib/rules/lines-between-class-members.js
index d1aa8607c..e4b1c0c09 100644
--- a/tests/lib/rules/lines-between-class-members.js
+++ b/tests/lib/rules/lines-between-class-members.js
@@ -40,6 +40,9 @@ ruleTester.run("lines-between-class-members", rule, {
         "class A{ foo() {}\n/* a */ /* b */\n\nbar() {}}",
         "class A{ foo() {}/* a */ \n\n /* b */bar() {}}",
 
+        "class A {\nfoo() {}\n/* comment */;\n;\n\nbar() {}\n}",
+        "class A {\nfoo() {}\n// comment\n\n;\n;\nbar() {}\n}",
+
         "class foo{ bar(){}\n\n;;baz(){}}",
         "class foo{ bar(){};\n\nbaz(){}}",
 
@@ -73,6 +76,71 @@ ruleTester.run("lines-between-class-members", rule, {
             output: "class foo{ bar(){\n}\n\nbaz(){}}",
             options: ["always", { exceptAfterSingleLine: true }],
             errors: [alwaysError]
+        }, {
+            code: "class foo{ bar(){\n}\n/* comment */\nbaz(){}}",
+            output: "class foo{ bar(){\n}\n\n/* comment */\nbaz(){}}",
+            options: ["always", { exceptAfterSingleLine: true }],
+            errors: [alwaysError]
+        }, {
+            code: "class foo{ bar(){}\n\n// comment\nbaz(){}}",
+            output: "class foo{ bar(){}\n// comment\nbaz(){}}",
+            options: ["never"],
+            errors: [neverError]
+        }, {
+            code: "class foo{ bar(){}\n\n/* comment */\nbaz(){}}",
+            output: "class foo{ bar(){}\n/* comment */\nbaz(){}}",
+            options: ["never"],
+            errors: [neverError]
+        }, {
+            code: "class foo{ bar(){}\n/* comment-1 */\n\n/* comment-2 */\nbaz(){}}",
+            output: "class foo{ bar(){}\n/* comment-1 */\n/* comment-2 */\nbaz(){}}",
+            options: ["never"],
+            errors: [neverError]
+        }, {
+            code: "class foo{ bar(){}\n\n/* comment */\n\nbaz(){}}",
+            output: null,
+            options: ["never"],
+            errors: [neverError]
+        }, {
+            code: "class foo{ bar(){}\n\n// comment\n\nbaz(){}}",
+            output: null,
+            options: ["never"],
+            errors: [neverError]
+        }, {
+            code: "class foo{ bar(){}\n/* comment-1 */\n\n/* comment-2 */\n\n/* comment-3 */\nbaz(){}}",
+            output: null,
+            options: ["never"],
+            errors: [neverError]
+        }, {
+            code: "class foo{ bar(){}\n/* comment-1 */\n\n;\n\n/* comment-3 */\nbaz(){}}",
+            output: null,
+            options: ["never"],
+            errors: [neverError]
+        }, {
+            code: "class A {\nfoo() {}// comment\n;\n/* comment */\nbar() {}\n}",
+            output: "class A {\nfoo() {}// comment\n\n;\n/* comment */\nbar() {}\n}",
+            options: ["always"],
+            errors: [alwaysError]
+        }, {
+            code: "class A {\nfoo() {}\n/* comment */;\n;\n/* comment */\nbar() {}\n}",
+            output: "class A {\nfoo() {}\n\n/* comment */;\n;\n/* comment */\nbar() {}\n}",
+            options: ["always"],
+            errors: [alwaysError]
+        }, {
+            code: "class foo{ bar(){};\nbaz(){}}",
+            output: "class foo{ bar(){};\n\nbaz(){}}",
+            options: ["always"],
+            errors: [alwaysError]
+        }, {
+            code: "class foo{ bar(){} // comment \nbaz(){}}",
+            output: "class foo{ bar(){} // comment \n\nbaz(){}}",
+            options: ["always"],
+            errors: [alwaysError]
+        }, {
+            code: "class A {\nfoo() {}\n/* comment */;\n;\nbar() {}\n}",
+            output: "class A {\nfoo() {}\n\n/* comment */;\n;\nbar() {}\n}",
+            options: ["always"],
+            errors: [alwaysError]
         }
     ]
 });
diff --git a/tests/lib/rules/no-mixed-spaces-and-tabs.js b/tests/lib/rules/no-mixed-spaces-and-tabs.js
index d1333b2db..3e39c51dc 100644
--- a/tests/lib/rules/no-mixed-spaces-and-tabs.js
+++ b/tests/lib/rules/no-mixed-spaces-and-tabs.js
@@ -25,6 +25,12 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
         "\t/*\n\t * Hello\n\t */",
         "// foo\n\t/**\n\t * Hello\n\t */",
         "/*\n\n \t \n*/",
+        "/*\t */ //",
+        "/*\n \t*/ //",
+        "/*\n\t *//*\n \t*/",
+        "// \t",
+        "/*\n*/\t ",
+        "/* \t\n\t \n \t\n\t */ \t",
         {
             code: "\tvar x = 5,\n\t    y = 2;",
             options: [true]
@@ -69,6 +75,8 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
             code: "`foo${ 5 }\t    `;",
             env: { es6: true }
         },
+        "' \t\\\n\t multiline string';",
+        "'\t \\\n \tmultiline string';",
         {
             code: "\tvar x = 5,\n\t    y = 2;",
             options: ["smart-tabs"]
@@ -96,6 +104,56 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                 }
             ]
         },
+        {
+            code: " \t/* comment */",
+            errors: [
+                {
+                    message: "Mixed spaces and tabs.",
+                    type: "Program",
+                    line: 1
+                }
+            ]
+        },
+        {
+            code: "\t // comment",
+            errors: [
+                {
+                    message: "Mixed spaces and tabs.",
+                    type: "Program",
+                    line: 1
+                }
+            ]
+        },
+        {
+            code: "\t var a /* comment */ = 1;",
+            errors: [
+                {
+                    message: "Mixed spaces and tabs.",
+                    type: "Program",
+                    line: 1
+                }
+            ]
+        },
+        {
+            code: " \tvar b = 1; // comment",
+            errors: [
+                {
+                    message: "Mixed spaces and tabs.",
+                    type: "Program",
+                    line: 1
+                }
+            ]
+        },
+        {
+            code: "/**/\n \t/*\n \t*/",
+            errors: [
+                {
+                    message: "Mixed spaces and tabs.",
+                    type: "Program",
+                    line: 2
+                }
+            ]
+        },
         {
             code: "\t var x = 5, y = 2, z = 5;\n\n\t \tvar j =\t x + y;\nz *= j;",
             errors: [
@@ -157,6 +215,26 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                     column: 2
                 }
             ]
+        },
+        {
+            code: "  \t'';",
+            errors: [
+                {
+                    message: "Mixed spaces and tabs.",
+                    type: "Program",
+                    line: 1
+                }
+            ]
+        },
+        {
+            code: "''\n\t ",
+            errors: [
+                {
+                    message: "Mixed spaces and tabs.",
+                    type: "Program",
+                    line: 2
+                }
+            ]
         }
     ]
 });
diff --git a/tests/lib/rules/no-multiple-empty-lines.js b/tests/lib/rules/no-multiple-empty-lines.js
index 5c51dd811..7b14f75ae 100644
--- a/tests/lib/rules/no-multiple-empty-lines.js
+++ b/tests/lib/rules/no-multiple-empty-lines.js
@@ -316,6 +316,32 @@ ruleTester.run("no-multiple-empty-lines", rule, {
             output: "foo\n",
             options: [{ max: 1, maxEOF: 0 }],
             errors: [getExpectedErrorEOF(0)]
+        },
+        {
+
+            // https://github.com/eslint/eslint/pull/12594
+            code: "var a;\n\n\n\n\nvar b;",
+            output: "var a;\n\nvar b;",
+            options: [{ max: 1 }],
+            errors: [{
+                message: "More than 1 blank line not allowed.",
+                type: "Program",
+                line: 3,
+                column: 1
+            }]
+        },
+        {
+
+            // https://github.com/eslint/eslint/pull/12594
+            code: "var a;\n\n\n\n\nvar b;",
+            output: "var a;\n\n\nvar b;",
+            options: [{ max: 2 }],
+            errors: [{
+                message: "More than 2 blank lines not allowed.",
+                type: "Program",
+                line: 4,
+                column: 1
+            }]
         }
     ]
 });
diff --git a/tests/lib/rules/no-param-reassign.js b/tests/lib/rules/no-param-reassign.js
index 5bb70e6aa..6985cabb8 100644
--- a/tests/lib/rules/no-param-reassign.js
+++ b/tests/lib/rules/no-param-reassign.js
@@ -91,6 +91,14 @@ ruleTester.run("no-param-reassign", rule, {
             code: "function foo(a) { for (bar of baz) a.b; }",
             options: [{ props: true }],
             parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "function foo(bar, baz) { bar.a = true; baz.b = false; }",
+            options: [{
+                props: true,
+                ignorePropertyModificationsForRegex: ["^(foo|bar)$"],
+                ignorePropertyModificationsFor: ["baz"]
+            }]
         }
     ],
 
diff --git a/tests/lib/rules/no-restricted-exports.js b/tests/lib/rules/no-restricted-exports.js
new file mode 100644
index 000000000..d8ae6e9c7
--- /dev/null
+++ b/tests/lib/rules/no-restricted-exports.js
@@ -0,0 +1,459 @@
+/**
+ * @fileoverview Tests for the no-restricted-exports rule
+ * @author Milos Djermanovic
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const rule = require("../../../lib/rules/no-restricted-exports");
+const { RuleTester } = require("../../../lib/rule-tester");
+
+//------------------------------------------------------------------------------
+// Tests
+//------------------------------------------------------------------------------
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: "module" } });
+
+ruleTester.run("no-restricted-exports", rule, {
+    valid: [
+
+        // nothing configured
+        "export var a;",
+        "export function a() {}",
+        "export class A {}",
+        "var a; export { a };",
+        "var b; export { b as a };",
+        "export { a } from 'foo';",
+        "export { b as a } from 'foo';",
+        { code: "export var a;", options: [{}] },
+        { code: "export function a() {}", options: [{}] },
+        { code: "export class A {}", options: [{}] },
+        { code: "var a; export { a };", options: [{}] },
+        { code: "var b; export { b as a };", options: [{}] },
+        { code: "export { a } from 'foo';", options: [{}] },
+        { code: "export { b as a } from 'foo';", options: [{}] },
+        { code: "export var a;", options: [{ restrictedNamedExports: [] }] },
+        { code: "export function a() {}", options: [{ restrictedNamedExports: [] }] },
+        { code: "export class A {}", options: [{ restrictedNamedExports: [] }] },
+        { code: "var a; export { a };", options: [{ restrictedNamedExports: [] }] },
+        { code: "var b; export { b as a };", options: [{ restrictedNamedExports: [] }] },
+        { code: "export { a } from 'foo';", options: [{ restrictedNamedExports: [] }] },
+        { code: "export { b as a } from 'foo';", options: [{ restrictedNamedExports: [] }] },
+
+        // not a restricted name
+        { code: "export var a;", options: [{ restrictedNamedExports: ["x"] }] },
+        { code: "export let a;", options: [{ restrictedNamedExports: ["x"] }] },
+        { code: "export const a = 1;", options: [{ restrictedNamedExports: ["x"] }] },
+        { code: "export function a() {}", options: [{ restrictedNamedExports: ["x"] }] },
+        { code: "export function *a() {}", options: [{ restrictedNamedExports: ["x"] }] },
+        { code: "export async function a() {}", options: [{ restrictedNamedExports: ["x"] }] },
+        { code: "export async function *a() {}", options: [{ restrictedNamedExports: ["x"] }] },
+        { code: "export class A {}", options: [{ restrictedNamedExports: ["x"] }] },
+        { code: "var a; export { a };", options: [{ restrictedNamedExports: ["x"] }] },
+        { code: "var b; export { b as a };", options: [{ restrictedNamedExports: ["x"] }] },
+        { code: "export { a } from 'foo';", options: [{ restrictedNamedExports: ["x"] }] },
+        { code: "export { b as a } from 'foo';", options: [{ restrictedNamedExports: ["x"] }] },
+
+        // does not mistakenly disallow non-exported identifers that appear in named export declarations
+        { code: "export var b = a;", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "export let [b = a] = [];", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "export const [b] = [a];", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "export var { a: b } = {};", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "export let { b = a } = {};", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "export const { c: b = a } = {};", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "export function b(a) {}", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "export class A { a(){} }", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "export class A extends B {}", options: [{ restrictedNamedExports: ["B"] }] },
+        { code: "var a; export { a as b };", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "export { a as b } from 'foo';", options: [{ restrictedNamedExports: ["a"] }] },
+
+        // does not check source in re-export declarations
+        { code: "export { b } from 'a';", options: [{ restrictedNamedExports: ["a"] }] },
+
+        // does not check non-export declarations
+        { code: "var a;", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "let a;", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "const a = 1;", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "function a() {}", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "class A {}", options: [{ restrictedNamedExports: ["A"] }] },
+        { code: "import a from 'foo';", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "import { a } from 'foo';", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "import { b as a } from 'foo';", options: [{ restrictedNamedExports: ["a"] }] },
+
+        // does not check re-export all declarations
+        { code: "export * from 'foo';", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "export * from 'a';", options: [{ restrictedNamedExports: ["a"] }] },
+
+        // does not mistakenly disallow identifiers in export default declarations (a default export will export "default" name)
+        { code: "export default a;", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "export default function a() {}", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "export default class A {}", options: [{ restrictedNamedExports: ["A"] }] },
+        { code: "export default (function a() {});", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "export default (class A {});", options: [{ restrictedNamedExports: ["A"] }] },
+
+        // by design, restricted name "default" does not apply to default export declarations, although they do export the "default" name.
+        { code: "export default 1;", options: [{ restrictedNamedExports: ["default"] }] },
+
+        // "default" does not disallow re-exporting a renamed default export from another module
+        { code: "export { default as a } from 'foo';", options: [{ restrictedNamedExports: ["default"] }] }
+    ],
+
+    invalid: [
+
+        // full message test
+        {
+            code: "export function someFunction() {}",
+            options: [{ restrictedNamedExports: ["someFunction"] }],
+            errors: [{ message: "'someFunction' is restricted from being used as an exported name.", type: "Identifier" }]
+        },
+
+        // basic tests
+        {
+            code: "export var a;",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export var a = 1;",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export let a;",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export let a = 1;",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export const a = 1;",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export function a() {}",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export function *a() {}",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export async function a() {}",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export async function *a() {}",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export class A {}",
+            options: [{ restrictedNamedExports: ["A"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "A" }, type: "Identifier" }]
+        },
+        {
+            code: "let a; export { a };",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 17 }]
+        },
+        {
+            code: "export { a }; var a;",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 10 }]
+        },
+        {
+            code: "let b; export { b as a };",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export { a } from 'foo';",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export { b as a } from 'foo';",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+
+        // destructuring
+        {
+            code: "export var [a] = [];",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export let { a } = {};",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export const { b: a } = {};",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export var [{ a }] = [];",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export let { b: { c: a = d } = e } = {};",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+
+        // reports the correct identifier node in the case of a redeclaration. Note: functions cannot be redeclared in a module.
+        {
+            code: "var a; export var a;",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 19 }]
+        },
+        {
+            code: "export var a; var a;",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 12 }]
+        },
+
+        // reports the correct identifier node when the same identifier appears elsewhere in the declaration
+        {
+            code: "export var a = a;",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 12 }]
+        },
+        {
+            code: "export let b = a, a;",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 19 }]
+        },
+        {
+            code: "export const a = 1, b = a;",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 14 }]
+        },
+        {
+            code: "export var [a] = a;",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 13 }]
+        },
+        {
+            code: "export let { a: a } = {};",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 17 }]
+        },
+        {
+            code: "export const { a: b, b: a } = {};",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 25 }]
+        },
+        {
+            code: "export var { b: a, a: b } = {};",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 17 }]
+        },
+        {
+            code: "export let a, { a: b } = {};",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 12 }]
+        },
+        {
+            code: "export const { a: b } = {}, a = 1;",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 29 }]
+        },
+        {
+            code: "export var [a = a] = [];",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 13 }]
+        },
+        {
+            code: "export var { a: a = a } = {};",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 17 }]
+        },
+        {
+            code: "export let { a } = { a };",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 14 }]
+        },
+        {
+            code: "export function a(a) {};",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 17 }]
+        },
+        {
+            code: "export class A { A(){} };",
+            options: [{ restrictedNamedExports: ["A"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "A" }, type: "Identifier", column: 14 }]
+        },
+        {
+            code: "var a; export { a as a };",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 22 }]
+        },
+        {
+            code: "let a, b; export { a as b, b as a };",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 33 }]
+        },
+        {
+            code: "const a = 1, b = 2; export { b as a, a as b };",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 35 }]
+        },
+        {
+            code: "var a; export { a as b, a };",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 25 }]
+        },
+        {
+            code: "export { a as a } from 'a';",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 15 }]
+        },
+        {
+            code: "export { a as b, b as a } from 'foo';",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 23 }]
+        },
+        {
+            code: "export { b as a, a as b } from 'foo';",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 15 }]
+        },
+
+        // Note: duplicate identifiers in the same export declaration are a 'duplicate export' syntax error. Example: export var a, a;
+
+        // invalid and valid or multiple ivalid in the same declaration
+        {
+            code: "export var a, b;",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export let b, a;",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export const b = 1, a = 2;",
+            options: [{ restrictedNamedExports: ["a", "b"] }],
+            errors: [
+                { messageId: "restrictedNamed", data: { name: "b" }, type: "Identifier" },
+                { messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }
+            ]
+        },
+        {
+            code: "export var a, b, c;",
+            options: [{ restrictedNamedExports: ["a", "c"] }],
+            errors: [
+                { messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" },
+                { messageId: "restrictedNamed", data: { name: "c" }, type: "Identifier" }
+            ]
+        },
+        {
+            code: "export let { a, b, c } = {};",
+            options: [{ restrictedNamedExports: ["b", "c"] }],
+            errors: [
+                { messageId: "restrictedNamed", data: { name: "b" }, type: "Identifier" },
+                { messageId: "restrictedNamed", data: { name: "c" }, type: "Identifier" }
+            ]
+        },
+        {
+            code: "export const [a, b, c, d] = {};",
+            options: [{ restrictedNamedExports: ["b", "c"] }],
+            errors: [
+                { messageId: "restrictedNamed", data: { name: "b" }, type: "Identifier" },
+                { messageId: "restrictedNamed", data: { name: "c" }, type: "Identifier" }
+            ]
+        },
+        {
+            code: "export var { a, x: b, c, d, e: y } = {}, e, f = {};",
+            options: [{ restrictedNamedExports: ["foo", "a", "b", "bar", "d", "e", "baz"] }],
+            errors: [
+                { messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" },
+                { messageId: "restrictedNamed", data: { name: "b" }, type: "Identifier" },
+                { messageId: "restrictedNamed", data: { name: "d" }, type: "Identifier" },
+                { messageId: "restrictedNamed", data: { name: "e" }, type: "Identifier", column: 42 }
+            ]
+        },
+        {
+            code: "var a, b; export { a, b };",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "let a, b; export { b, a };",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "const a = 1, b = 1; export { a, b };",
+            options: [{ restrictedNamedExports: ["a", "b"] }],
+            errors: [
+                { messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" },
+                { messageId: "restrictedNamed", data: { name: "b" }, type: "Identifier" }
+            ]
+        },
+        {
+            code: "export { a, b, c }; var a, b, c;",
+            options: [{ restrictedNamedExports: ["a", "c"] }],
+            errors: [
+                { messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" },
+                { messageId: "restrictedNamed", data: { name: "c" }, type: "Identifier" }
+            ]
+        },
+        {
+            code: "export { b as a, b } from 'foo';",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" }]
+        },
+        {
+            code: "export { b as a, b } from 'foo';",
+            options: [{ restrictedNamedExports: ["b"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "b" }, type: "Identifier", column: 18 }]
+        },
+        {
+            code: "export { b as a, b } from 'foo';",
+            options: [{ restrictedNamedExports: ["a", "b"] }],
+            errors: [
+                { messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" },
+                { messageId: "restrictedNamed", data: { name: "b" }, type: "Identifier", column: 18 }
+            ]
+        },
+        {
+            code: "export { a, b, c, d, x as e, f, g } from 'foo';",
+            options: [{ restrictedNamedExports: ["foo", "b", "bar", "d", "e", "f", "baz"] }],
+            errors: [
+                { messageId: "restrictedNamed", data: { name: "b" }, type: "Identifier" },
+                { messageId: "restrictedNamed", data: { name: "d" }, type: "Identifier" },
+                { messageId: "restrictedNamed", data: { name: "e" }, type: "Identifier" },
+                { messageId: "restrictedNamed", data: { name: "f" }, type: "Identifier" }
+            ]
+        },
+
+        // reports "default" in named export declarations (when configured)
+        {
+            code: "var a; export { a as default };",
+            options: [{ restrictedNamedExports: ["default"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "default" }, type: "Identifier", column: 22 }]
+        },
+        {
+            code: "export { default } from 'foo';",
+            options: [{ restrictedNamedExports: ["default"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "default" }, type: "Identifier", column: 10 }]
+        }
+    ]
+});
diff --git a/tests/lib/rules/no-restricted-imports.js b/tests/lib/rules/no-restricted-imports.js
index ac97bc137..15ee089b2 100644
--- a/tests/lib/rules/no-restricted-imports.js
+++ b/tests/lib/rules/no-restricted-imports.js
@@ -20,6 +20,7 @@ const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6, sourceType:
 
 ruleTester.run("no-restricted-imports", rule, {
     valid: [
+        "import os from \"os\";",
         { code: "import os from \"os\";", options: ["osx"] },
         { code: "import fs from \"fs\";", options: ["crypto"] },
         { code: "import path from \"path\";", options: ["crypto", "stream", "os"] },
diff --git a/tests/lib/rules/no-unsafe-negation.js b/tests/lib/rules/no-unsafe-negation.js
index 9493bbb72..23e6cd5ce 100644
--- a/tests/lib/rules/no-unsafe-negation.js
+++ b/tests/lib/rules/no-unsafe-negation.js
@@ -17,27 +17,6 @@ const rule = require("../../../lib/rules/no-unsafe-negation"),
 //------------------------------------------------------------------------------
 
 const ruleTester = new RuleTester();
-const unexpectedInError = { messageId: "unexpected", data: { operator: "in" } };
-const unexpectedInstanceofError = {
-    messageId: "unexpected",
-    data: { operator: "instanceof" }
-};
-const unexpectedLessThanOperatorError = {
-    messageId: "unexpected",
-    data: { operator: "<" }
-};
-const unexpectedMoreThanOperatorError = {
-    messageId: "unexpected",
-    data: { operator: ">" }
-};
-const unexpectedMoreThanOrEqualOperatorError = {
-    messageId: "unexpected",
-    data: { operator: ">=" }
-};
-const unexpectedLessThanOrEqualOperatorError = {
-    messageId: "unexpected",
-    data: { operator: "<=" }
-};
 
 ruleTester.run("no-unsafe-negation", rule, {
     valid: [
@@ -83,52 +62,194 @@ ruleTester.run("no-unsafe-negation", rule, {
     invalid: [
         {
             code: "!a in b",
-            errors: [unexpectedInError]
+            errors: [{
+                message: "Unexpected negating the left operand of 'in' operator.",
+                suggestions: [
+                    {
+                        desc: "Negate 'in' expression instead of its left operand. This changes the current behavior.",
+                        output: "!(a in b)"
+                    },
+                    {
+                        desc: "Wrap negation in '()' to make the intention explicit. This preserves the current behavior.",
+                        output: "(!a) in b"
+                    }
+                ]
+            }]
         },
         {
             code: "(!a in b)",
-            errors: [unexpectedInError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: "in" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "(!(a in b))"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "((!a) in b)"
+                    }
+                ]
+            }]
         },
         {
             code: "!(a) in b",
-            errors: [unexpectedInError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: "in" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "!((a) in b)"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "(!(a)) in b"
+                    }
+                ]
+            }]
         },
         {
             code: "!a instanceof b",
-            errors: [unexpectedInstanceofError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: "instanceof" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "!(a instanceof b)"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "(!a) instanceof b"
+                    }
+                ]
+            }]
         },
         {
             code: "(!a instanceof b)",
-            errors: [unexpectedInstanceofError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: "instanceof" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "(!(a instanceof b))"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "((!a) instanceof b)"
+                    }
+                ]
+            }]
         },
         {
             code: "!(a) instanceof b",
-            errors: [unexpectedInstanceofError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: "instanceof" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "!((a) instanceof b)"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "(!(a)) instanceof b"
+                    }
+                ]
+            }]
         },
         {
             code: "if (! a < b) {}",
             options: [{ enforceForOrderingRelations: true }],
-            errors: [unexpectedLessThanOperatorError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: "<" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "if (!( a < b)) {}"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "if ((! a) < b) {}"
+                    }
+                ]
+            }]
         },
         {
             code: "while (! a > b) {}",
             options: [{ enforceForOrderingRelations: true }],
-            errors: [unexpectedMoreThanOperatorError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: ">" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "while (!( a > b)) {}"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "while ((! a) > b) {}"
+                    }
+                ]
+            }]
         },
         {
             code: "foo = ! a <= b;",
             options: [{ enforceForOrderingRelations: true }],
-            errors: [unexpectedLessThanOrEqualOperatorError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: "<=" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "foo = !( a <= b);"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "foo = (! a) <= b;"
+                    }
+                ]
+            }]
         },
         {
             code: "foo = ! a >= b;",
             options: [{ enforceForOrderingRelations: true }],
-            errors: [unexpectedMoreThanOrEqualOperatorError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: ">=" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "foo = !( a >= b);"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "foo = (! a) >= b;"
+                    }
+                ]
+            }]
         },
         {
             code: "! a <= b",
             options: [{ enforceForOrderingRelations: true }],
-            errors: [unexpectedLessThanOrEqualOperatorError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: "<=" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "!( a <= b)"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "(! a) <= b"
+                    }
+                ]
+            }]
         }
     ]
 });
diff --git a/tests/lib/rules/no-void.js b/tests/lib/rules/no-void.js
index 2d12718d8..2a1ee1d9a 100644
--- a/tests/lib/rules/no-void.js
+++ b/tests/lib/rules/no-void.js
@@ -8,8 +8,8 @@
 // Requirements
 //------------------------------------------------------------------------------
 
-const rule = require("../../../lib/rules/no-void"),
-    { RuleTester } = require("../../../lib/rule-tester");
+const rule = require("../../../lib/rules/no-void");
+const { RuleTester } = require("../../../lib/rule-tester");
 
 //------------------------------------------------------------------------------
 // Tests
@@ -18,32 +18,48 @@ const rule = require("../../../lib/rules/no-void"),
 const ruleTester = new RuleTester();
 
 ruleTester.run("no-void", rule, {
-
     valid: [
         "var foo = bar()",
         "foo.void()",
         "foo.void = bar",
-        "delete foo;"
+        "delete foo;",
+        {
+            code: "void 0",
+            options: [{ allowAsStatement: true }]
+        },
+        {
+            code: "void(0)",
+            options: [{ allowAsStatement: true }]
+        }
     ],
 
     invalid: [
         {
             code: "void 0",
-            errors: [{
-                message: "Expected 'undefined' and instead saw 'void'."
-            }]
+            errors: [{ messageId: "noVoid" }]
+        },
+        {
+            code: "void 0",
+            options: [{}],
+            errors: [{ messageId: "noVoid" }]
+        },
+        {
+            code: "void 0",
+            options: [{ allowAsStatement: false }],
+            errors: [{ messageId: "noVoid" }]
         },
         {
             code: "void(0)",
-            errors: [{
-                message: "Expected 'undefined' and instead saw 'void'."
-            }]
+            errors: [{ messageId: "noVoid" }]
+        },
+        {
+            code: "var foo = void 0",
+            errors: [{ messageId: "noVoid" }]
         },
         {
             code: "var foo = void 0",
-            errors: [{
-                message: "Expected 'undefined' and instead saw 'void'."
-            }]
+            options: [{ allowAsStatement: true }],
+            errors: [{ messageId: "noVoid" }]
         }
     ]
 });
diff --git a/tests/lib/rules/prefer-numeric-literals.js b/tests/lib/rules/prefer-numeric-literals.js
index ddd6e36c8..4d3037f44 100644
--- a/tests/lib/rules/prefer-numeric-literals.js
+++ b/tests/lib/rules/prefer-numeric-literals.js
@@ -31,7 +31,28 @@ ruleTester.run("prefer-numeric-literals", rule, {
         "parseInt(foo);",
         "parseInt(foo, 2);",
         "Number.parseInt(foo);",
-        "Number.parseInt(foo, 2);"
+        "Number.parseInt(foo, 2);",
+        "parseInt(11, 2);",
+        "Number.parseInt(1, 8);",
+        "parseInt(1e5, 16);",
+        "parseInt('11', '2');",
+        "Number.parseInt('11', '8');",
+        {
+            code: "parseInt('11', 2n);",
+            parserOptions: { ecmaVersion: 2020 }
+        },
+        {
+            code: "Number.parseInt('11', 8n);",
+            parserOptions: { ecmaVersion: 2020 }
+        },
+        {
+            code: "parseInt('11', 16n);",
+            parserOptions: { ecmaVersion: 2020 }
+        },
+        {
+            code: "parseInt(1n, 2);",
+            parserOptions: { ecmaVersion: 2020 }
+        }
     ],
     invalid: [
         {
diff --git a/tests/lib/rules/yield-star-spacing.js b/tests/lib/rules/yield-star-spacing.js
index 0665f648e..9c8aaff95 100644
--- a/tests/lib/rules/yield-star-spacing.js
+++ b/tests/lib/rules/yield-star-spacing.js
@@ -137,6 +137,24 @@ ruleTester.run("yield-star-spacing", rule, {
         {
             code: "function *foo(){ var result = yield*foo(); }",
             options: ["neither"]
+        },
+
+        // object option
+        {
+            code: "function *foo(){ yield* foo; }",
+            options: [{ before: false, after: true }]
+        },
+        {
+            code: "function *foo(){ yield *foo; }",
+            options: [{ before: true, after: false }]
+        },
+        {
+            code: "function *foo(){ yield * foo; }",
+            options: [{ before: true, after: true }]
+        },
+        {
+            code: "function *foo(){ yield*foo; }",
+            options: [{ before: false, after: false }]
         }
     ],
 
@@ -227,6 +245,32 @@ ruleTester.run("yield-star-spacing", rule, {
             output: "function *foo(){ yield*foo; }",
             options: ["neither"],
             errors: [unexpectedBeforeError, unexpectedAfterError]
+        },
+
+        // object option
+        {
+            code: "function *foo(){ yield*foo; }",
+            output: "function *foo(){ yield* foo; }",
+            options: [{ before: false, after: true }],
+            errors: [missingAfterError]
+        },
+        {
+            code: "function *foo(){ yield * foo; }",
+            output: "function *foo(){ yield *foo; }",
+            options: [{ before: true, after: false }],
+            errors: [unexpectedAfterError]
+        },
+        {
+            code: "function *foo(){ yield*foo; }",
+            output: "function *foo(){ yield * foo; }",
+            options: [{ before: true, after: true }],
+            errors: [missingBeforeError, missingAfterError]
+        },
+        {
+            code: "function *foo(){ yield * foo; }",
+            output: "function *foo(){ yield*foo; }",
+            options: [{ before: false, after: false }],
+            errors: [unexpectedBeforeError, unexpectedAfterError]
         }
     ]