Repository: eslint/eslint (js)

Issue:
Remove non-recommended rules from recommended config
**The version of ESLint you are using.**

5.6.0/master

**The problem you want to solve.**

The `eslint:recommended` config contains all ESLint rules. Non-recommended rules are explicitly set to "off", while recommended rules are set to "error".

This impacts users who might wish to extend eslint:recommended after having already extended a different configuration. The rules configured as "off" will override any rules configured as "warn" or "error" in the extended configuration.

In practice, this is pretty rare. However, it also seems that eslint:recommended should not explicitly turn off other rules.

Inspired by #10816.

**Your take on the correct solution to problem.**

Remove the "off" rules from eslint:recommended. This is technically a breaking change, so we should do this within a major release.

Pull request description:
Breaking: Remove extra rules from eslint:recommended (fixes #10873)
Only explicitly recommended rules will be exported in eslint:recommended configuration.

<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**What is the purpose of this pull request? (put an "X" next to item)**

[ ] Documentation update
[ ] Bug fix ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/bug-report.md))
[ ] New rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-proposal.md))
[ ] Changes an existing rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-change-proposal.md))
[ ] Add autofixing to a rule
[ ] Add a CLI option
[ ] Add something to the core
[x] Other, please explain: Ensure `eslint:recommended` config only configures recommended rules, without explicitly setting non-recommended rules to "off".

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

See #10873.

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

**What changes did you make? (Give an overview)**

Ensure only recommended rules are configured (as error).

**Is there anything you'd like reviewers to focus on?**

Had to change one CLIEngine test because the output order of deprecated rules has apparently changed. Does this matter? I'm thinking it doesn't matter, but want to be sure.

Patch:
diff --git a/.travis.yml b/.travis.yml
index baf4d28fd..03cd84ead 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,8 +1,6 @@
 language: node_js
 node_js:
-    - "6"
     - "8"
-    - "9"
     - "10"
     - "11"
 
diff --git a/README.md b/README.md
index 172c956ad..f5b23947b 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@ ESLint is a tool for identifying and reporting on patterns found in ECMAScript/J
 
 ## Installation and Usage
 
-Prerequisites: [Node.js](https://nodejs.org/en/) (>=6.14), npm version 3+.
+Prerequisites: [Node.js](https://nodejs.org/) (`^8.10.0`, `^10.13.0`, or `>=11.10.1`), npm version 3+.
 
 There are two ways to install ESLint: globally and locally.
 
@@ -243,18 +243,25 @@ Teddy Katz
 </td></tr></tbody></table>
 
 
+### Reviewers
 
-
-### Committers
-
-The people who review and fix bugs and help triage issues.
+The people who review and implement new features.
 
 <table><tbody><tr><td align="center" valign="top" width="11%">
 <a href="https://github.com/aladdin-add">
 <img src="https://github.com/aladdin-add.png?s=75" width="75" height="75"><br />
 薛定谔的猫
 </a>
-</td><td align="center" valign="top" width="11%">
+</td></tr></tbody></table>
+
+
+
+
+### Committers
+
+The people who review and fix bugs and help triage issues.
+
+<table><tbody><tr><td align="center" valign="top" width="11%">
 <a href="https://github.com/g-plane">
 <img src="https://github.com/g-plane.png?s=75" width="75" height="75"><br />
 Pig Fang
@@ -271,7 +278,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
 <!-- NOTE: This section is autogenerated. Do not manually edit.-->
 <!--sponsorsstart-->
 <h3>Gold Sponsors</h3>
-<p><a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2F098e3bd0-4d57-11e8-9324-0f6cc1f92bf1.png&height=96" alt="Airbnb" height="96"></a> <a href="https://code.facebook.com/projects/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fres.cloudinary.com%2Fopencollective%2Fimage%2Fupload%2Fv1508519428%2FS9gk78AS_400x400_fulq2l.jpg&height=96" alt="Facebook Open Source" height="96"></a> <a href="https://badoo.com/team?utm_source=eslint"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2Fbbdb9cc0-3b5d-11e9-9537-ad85092287b8.png&height=96" alt="Badoo" height="96"></a></p><h3>Silver Sponsors</h3>
+<p><a href="https://www.gitkraken.com/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Flogo.clearbit.com%2Fgitkraken.com&height=96" alt="GitKraken" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2F098e3bd0-4d57-11e8-9324-0f6cc1f92bf1.png&height=96" alt="Airbnb" height="96"></a> <a href="https://code.facebook.com/projects/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fres.cloudinary.com%2Fopencollective%2Fimage%2Fupload%2Fv1508519428%2FS9gk78AS_400x400_fulq2l.jpg&height=96" alt="Facebook Open Source" height="96"></a> <a href="https://badoo.com/team?utm_source=eslint"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2Fbbdb9cc0-3b5d-11e9-9537-ad85092287b8.png&height=96" alt="Badoo" height="96"></a></p><h3>Silver Sponsors</h3>
 <p><a href="https://www.ampproject.org/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2F68ed8b70-ebf2-11e6-9958-cb7e79408c56.png&height=96" alt="AMP Project" height="64"></a></p><h3>Bronze Sponsors</h3>
 <p><a href="http://faithlife.com/ref/about"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Flogo.clearbit.com%2Ffaithlife.com&height=96" alt="Faithlife" height="32"></a> <a href="https://jsheroes.io/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Flogo.clearbit.com%2Fjsheroes.io&height=96" alt="JSHeroes " height="32"></a></p>
 <!--sponsorsend-->
diff --git a/conf/eslint-recommended.js b/conf/eslint-recommended.js
index 447a99638..d6368000f 100644
--- a/conf/eslint-recommended.js
+++ b/conf/eslint-recommended.js
@@ -9,7 +9,10 @@
 const builtInRules = require("../lib/built-in-rules-index");
 
 module.exports = {
-    rules: Object.assign({}, ...Object.keys(builtInRules).map(ruleId => ({
-        [ruleId]: builtInRules[ruleId].meta.docs.recommended ? "error" : "off"
-    })))
+    rules: Object.assign(
+        {},
+        ...Object.keys(builtInRules)
+            .filter(ruleId => builtInRules[ruleId].meta.docs.recommended)
+            .map(ruleId => ({ [ruleId]: "error" }))
+    )
 };
diff --git a/docs/user-guide/configuring.md b/docs/user-guide/configuring.md
index ec91ed774..a9cbfa643 100644
--- a/docs/user-guide/configuring.md
+++ b/docs/user-guide/configuring.md
@@ -52,10 +52,6 @@ Here's an example `.eslintrc.json` file:
 
 Setting parser options helps ESLint determine what is a parsing error. All language options are `false` by default.
 
-### Deprecated
-
-* `ecmaFeatures.experimentalObjectRestSpread` - enable support for the experimental [object rest/spread properties](https://github.com/tc39/proposal-object-rest-spread). This syntax has been supported in `ecmaVersion: 2018`. This option will be removed in the future.
-
 ## Specifying Parser
 
 By default, ESLint uses [Espree](https://github.com/eslint/espree) as its parser. You can optionally specify that a different parser should be used in your configuration file so long as the parser meets the following requirements:
diff --git a/lib/config/config-ops.js b/lib/config/config-ops.js
index b38cdf7d7..65e9b9d07 100644
--- a/lib/config/config-ops.js
+++ b/lib/config/config-ops.js
@@ -366,7 +366,7 @@ module.exports = {
             }
         });
 
-        const opts = { matchBase: true };
+        const opts = { dot: true, matchBase: true };
 
         return patternList.some(pattern => minimatch(filePath, pattern, opts)) &&
             !excludedPatternList.some(excludedPattern => minimatch(filePath, excludedPattern, opts));
diff --git a/lib/config/config-validator.js b/lib/config/config-validator.js
index 386db7775..361af2b0b 100644
--- a/lib/config/config-validator.js
+++ b/lib/config/config-validator.js
@@ -238,15 +238,6 @@ function validateConfigSchema(config, source = null) {
     if (Object.hasOwnProperty.call(config, "ecmaFeatures")) {
         emitDeprecationWarning(source, "ESLINT_LEGACY_ECMAFEATURES");
     }
-
-    if (
-        (config.parser || "espree") === "espree" &&
-        config.parserOptions &&
-        config.parserOptions.ecmaFeatures &&
-        config.parserOptions.ecmaFeatures.experimentalObjectRestSpread
-    ) {
-        emitDeprecationWarning(source, "ESLINT_LEGACY_OBJECT_REST_SPREAD");
-    }
 }
 
 /**
diff --git a/lib/linter.js b/lib/linter.js
index be38b9908..b5199d208 100644
--- a/lib/linter.js
+++ b/lib/linter.js
@@ -336,16 +336,6 @@ function resolveParserOptions(parserName, providedOptions, enabledEnvironments)
 
     mergedParserOptions.ecmaVersion = normalizeEcmaVersion(mergedParserOptions.ecmaVersion, isModule);
 
-    // TODO: For backward compatibility. Will remove on v6.0.0.
-    if (
-        parserName === DEFAULT_PARSER_NAME &&
-        mergedParserOptions.ecmaFeatures &&
-        mergedParserOptions.ecmaFeatures.experimentalObjectRestSpread &&
-        (!mergedParserOptions.ecmaVersion || mergedParserOptions.ecmaVersion < 9)
-    ) {
-        mergedParserOptions.ecmaVersion = 9;
-    }
-
     return mergedParserOptions;
 }
 
diff --git a/lib/rules/camelcase.js b/lib/rules/camelcase.js
index 4647cc17e..cdc16fab9 100644
--- a/lib/rules/camelcase.js
+++ b/lib/rules/camelcase.js
@@ -90,7 +90,7 @@ module.exports = {
          */
         function isAllowed(name) {
             return allow.findIndex(
-                entry => name === entry || name.match(new RegExp(entry)) // eslint-disable-line require-unicode-regexp
+                entry => name === entry || name.match(new RegExp(entry, "u"))
             ) !== -1;
         }
 
diff --git a/lib/rules/capitalized-comments.js b/lib/rules/capitalized-comments.js
index 137be9e93..036616b33 100644
--- a/lib/rules/capitalized-comments.js
+++ b/lib/rules/capitalized-comments.js
@@ -91,7 +91,7 @@ function createRegExpForIgnorePatterns(normalizedOptions) {
         const ignorePatternStr = normalizedOptions[key].ignorePattern;
 
         if (ignorePatternStr) {
-            const regExp = RegExp(`^\\s*(?:${ignorePatternStr})`); // eslint-disable-line require-unicode-regexp
+            const regExp = RegExp(`^\\s*(?:${ignorePatternStr})`, "u");
 
             normalizedOptions[key].ignorePatternRegExp = regExp;
         }
diff --git a/lib/rules/default-case.js b/lib/rules/default-case.js
index c8d0af392..821e0d72b 100644
--- a/lib/rules/default-case.js
+++ b/lib/rules/default-case.js
@@ -39,7 +39,7 @@ module.exports = {
     create(context) {
         const options = context.options[0] || {};
         const commentPattern = options.commentPattern
-            ? new RegExp(options.commentPattern) // eslint-disable-line require-unicode-regexp
+            ? new RegExp(options.commentPattern, "u")
             : DEFAULT_COMMENT_PATTERN;
 
         const sourceCode = context.getSourceCode();
diff --git a/lib/rules/dot-notation.js b/lib/rules/dot-notation.js
index e25ab12b7..883c9090f 100644
--- a/lib/rules/dot-notation.js
+++ b/lib/rules/dot-notation.js
@@ -61,7 +61,7 @@ module.exports = {
         let allowPattern;
 
         if (options.allowPattern) {
-            allowPattern = new RegExp(options.allowPattern); // eslint-disable-line require-unicode-regexp
+            allowPattern = new RegExp(options.allowPattern, "u");
         }
 
         /**
diff --git a/lib/rules/handle-callback-err.js b/lib/rules/handle-callback-err.js
index 4d08e4fec..640946699 100644
--- a/lib/rules/handle-callback-err.js
+++ b/lib/rules/handle-callback-err.js
@@ -52,7 +52,7 @@ module.exports = {
          */
         function matchesConfiguredErrorName(name) {
             if (isPattern(errorArgument)) {
-                const regexp = new RegExp(errorArgument); // eslint-disable-line require-unicode-regexp
+                const regexp = new RegExp(errorArgument, "u");
 
                 return regexp.test(name);
             }
diff --git a/lib/rules/id-match.js b/lib/rules/id-match.js
index 48c108767..b97a497fd 100644
--- a/lib/rules/id-match.js
+++ b/lib/rules/id-match.js
@@ -53,7 +53,7 @@ module.exports = {
         // Options
         //--------------------------------------------------------------------------
         const pattern = context.options[0] || "^.+$",
-            regexp = new RegExp(pattern); // eslint-disable-line require-unicode-regexp
+            regexp = new RegExp(pattern, "u");
 
         const options = context.options[1] || {},
             properties = !!options.properties,
diff --git a/lib/rules/line-comment-position.js b/lib/rules/line-comment-position.js
index 0023a1f11..9a91d4302 100644
--- a/lib/rules/line-comment-position.js
+++ b/lib/rules/line-comment-position.js
@@ -78,7 +78,7 @@ module.exports = {
 
         const defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN;
         const fallThroughRegExp = /^\s*falls?\s?through/u;
-        const customIgnoreRegExp = new RegExp(ignorePattern); // eslint-disable-line require-unicode-regexp
+        const customIgnoreRegExp = new RegExp(ignorePattern, "u");
         const sourceCode = context.getSourceCode();
 
         //--------------------------------------------------------------------------
diff --git a/lib/rules/lines-around-comment.js b/lib/rules/lines-around-comment.js
index f2f9e3f9d..9d6ce4616 100644
--- a/lib/rules/lines-around-comment.js
+++ b/lib/rules/lines-around-comment.js
@@ -130,7 +130,7 @@ module.exports = {
         const options = Object.assign({}, context.options[0]);
         const ignorePattern = options.ignorePattern;
         const defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN;
-        const customIgnoreRegExp = new RegExp(ignorePattern); // eslint-disable-line require-unicode-regexp
+        const customIgnoreRegExp = new RegExp(ignorePattern, "u");
         const applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns !== false;
 
         options.beforeBlockComment = typeof options.beforeBlockComment !== "undefined" ? options.beforeBlockComment : true;
diff --git a/lib/rules/max-len.js b/lib/rules/max-len.js
index 6e7dd6f1a..438e38b0a 100644
--- a/lib/rules/max-len.js
+++ b/lib/rules/max-len.js
@@ -153,7 +153,7 @@ module.exports = {
         let ignorePattern = options.ignorePattern || null;
 
         if (ignorePattern) {
-            ignorePattern = new RegExp(ignorePattern); // eslint-disable-line require-unicode-regexp
+            ignorePattern = new RegExp(ignorePattern, "u");
         }
 
         //--------------------------------------------------------------------------
diff --git a/lib/rules/new-cap.js b/lib/rules/new-cap.js
index 9e88981ce..dcae238d9 100644
--- a/lib/rules/new-cap.js
+++ b/lib/rules/new-cap.js
@@ -136,10 +136,10 @@ module.exports = {
         const skipProperties = config.properties === false;
 
         const newIsCapExceptions = checkArray(config, "newIsCapExceptions", []).reduce(invert, {});
-        const newIsCapExceptionPattern = config.newIsCapExceptionPattern ? new RegExp(config.newIsCapExceptionPattern) : null; // eslint-disable-line require-unicode-regexp
+        const newIsCapExceptionPattern = config.newIsCapExceptionPattern ? new RegExp(config.newIsCapExceptionPattern, "u") : null;
 
         const capIsNewExceptions = calculateCapIsNewExceptions(config);
-        const capIsNewExceptionPattern = config.capIsNewExceptionPattern ? new RegExp(config.capIsNewExceptionPattern) : null; // eslint-disable-line require-unicode-regexp
+        const capIsNewExceptionPattern = config.capIsNewExceptionPattern ? new RegExp(config.capIsNewExceptionPattern, "u") : null;
 
         const listeners = {};
 
diff --git a/lib/rules/no-fallthrough.js b/lib/rules/no-fallthrough.js
index 241e07258..c6a71b6c8 100644
--- a/lib/rules/no-fallthrough.js
+++ b/lib/rules/no-fallthrough.js
@@ -95,7 +95,7 @@ module.exports = {
         let fallthroughCommentPattern = null;
 
         if (options.commentPattern) {
-            fallthroughCommentPattern = new RegExp(options.commentPattern); // eslint-disable-line require-unicode-regexp
+            fallthroughCommentPattern = new RegExp(options.commentPattern, "u");
         } else {
             fallthroughCommentPattern = DEFAULT_FALLTHROUGH_COMMENT;
         }
diff --git a/lib/rules/no-unused-vars.js b/lib/rules/no-unused-vars.js
index d4c4c6355..1482a0238 100644
--- a/lib/rules/no-unused-vars.js
+++ b/lib/rules/no-unused-vars.js
@@ -88,15 +88,15 @@ module.exports = {
                 config.caughtErrors = firstOption.caughtErrors || config.caughtErrors;
 
                 if (firstOption.varsIgnorePattern) {
-                    config.varsIgnorePattern = new RegExp(firstOption.varsIgnorePattern); // eslint-disable-line require-unicode-regexp
+                    config.varsIgnorePattern = new RegExp(firstOption.varsIgnorePattern, "u");
                 }
 
                 if (firstOption.argsIgnorePattern) {
-                    config.argsIgnorePattern = new RegExp(firstOption.argsIgnorePattern); // eslint-disable-line require-unicode-regexp
+                    config.argsIgnorePattern = new RegExp(firstOption.argsIgnorePattern, "u");
                 }
 
                 if (firstOption.caughtErrorsIgnorePattern) {
-                    config.caughtErrorsIgnorePattern = new RegExp(firstOption.caughtErrorsIgnorePattern); // eslint-disable-line require-unicode-regexp
+                    config.caughtErrorsIgnorePattern = new RegExp(firstOption.caughtErrorsIgnorePattern, "u");
                 }
             }
         }
diff --git a/lib/rules/no-warning-comments.js b/lib/rules/no-warning-comments.js
index 1d1b55460..0882f6126 100644
--- a/lib/rules/no-warning-comments.js
+++ b/lib/rules/no-warning-comments.js
@@ -5,6 +5,7 @@
 
 "use strict";
 
+const { escapeRegExp } = require("lodash");
 const astUtils = require("../util/ast-utils");
 
 //------------------------------------------------------------------------------
@@ -58,7 +59,7 @@ module.exports = {
          * @returns {RegExp} The term converted to a RegExp
          */
         function convertToRegExp(term) {
-            const escaped = term.replace(/[-/\\$^*+?.()|[\]{}]/gu, "\\$&");
+            const escaped = escapeRegExp(term);
             const wordBoundary = "\\b";
             const eitherOrWordBoundary = `|${wordBoundary}`;
             let prefix;
@@ -95,7 +96,7 @@ module.exports = {
                  * ^\s*TERM\b.  This checks the word boundary
                  * at the beginning of the comment.
                  */
-                return new RegExp(prefix + escaped + suffix, "i"); // eslint-disable-line require-unicode-regexp
+                return new RegExp(prefix + escaped + suffix, "iu");
             }
 
             /*
@@ -103,7 +104,7 @@ module.exports = {
              * \bTERM\b|\bTERM\b, this checks the entire comment
              * for the term.
              */
-            return new RegExp(prefix + escaped + suffix + eitherOrWordBoundary + term + wordBoundary, "i"); // eslint-disable-line require-unicode-regexp
+            return new RegExp(prefix + escaped + suffix + eitherOrWordBoundary + term + wordBoundary, "iu");
         }
 
         const warningRegExps = warningTerms.map(convertToRegExp);
diff --git a/lib/rules/spaced-comment.js b/lib/rules/spaced-comment.js
index 6e469ef94..e6b6e1b65 100644
--- a/lib/rules/spaced-comment.js
+++ b/lib/rules/spaced-comment.js
@@ -126,7 +126,7 @@ function createAlwaysStylePattern(markers, exceptions) {
     pattern += "?"; // or nothing.
     pattern += createExceptionsPattern(exceptions);
 
-    return new RegExp(pattern); // eslint-disable-line require-unicode-regexp
+    return new RegExp(pattern, "u");
 }
 
 /**
@@ -142,7 +142,7 @@ function createAlwaysStylePattern(markers, exceptions) {
 function createNeverStylePattern(markers) {
     const pattern = `^(${markers.map(escape).join("|")})?[ \t]+`;
 
-    return new RegExp(pattern); // eslint-disable-line require-unicode-regexp
+    return new RegExp(pattern, "u");
 }
 
 //------------------------------------------------------------------------------
@@ -250,9 +250,9 @@ module.exports = {
             // Create RegExp object for valid patterns.
             rule[type] = {
                 beginRegex: requireSpace ? createAlwaysStylePattern(markers, exceptions) : createNeverStylePattern(markers),
-                endRegex: balanced && requireSpace ? new RegExp(`${createExceptionsPattern(exceptions)}$`) : new RegExp(endNeverPattern), // eslint-disable-line require-unicode-regexp
+                endRegex: balanced && requireSpace ? new RegExp(`${createExceptionsPattern(exceptions)}$`, "u") : new RegExp(endNeverPattern, "u"),
                 hasExceptions: exceptions.length > 0,
-                markers: new RegExp(`^(${markers.map(escape).join("|")})`) // eslint-disable-line require-unicode-regexp
+                markers: new RegExp(`^(${markers.map(escape).join("|")})`, "u")
             };
 
             return rule;
diff --git a/lib/rules/valid-jsdoc.js b/lib/rules/valid-jsdoc.js
index 3250d9233..9ec6938e3 100644
--- a/lib/rules/valid-jsdoc.js
+++ b/lib/rules/valid-jsdoc.js
@@ -482,7 +482,7 @@ module.exports = {
                 }
 
                 if (options.matchDescription) {
-                    const regex = new RegExp(options.matchDescription); // eslint-disable-line require-unicode-regexp
+                    const regex = new RegExp(options.matchDescription, "u");
 
                     if (!regex.test(jsdoc.description)) {
                         context.report({ node: jsdocNode, messageId: "unsatisfiedDesc" });
diff --git a/package.json b/package.json
index c2c315d69..d6fc8788f 100644
--- a/package.json
+++ b/package.json
@@ -123,6 +123,6 @@
   ],
   "license": "MIT",
   "engines": {
-    "node": "^6.14.0 || ^8.10.0 || >=9.10.0"
+    "node": "^8.10.0 || ^10.13.0 || >=11.10.1"
   }
 }


Test patch:
diff --git a/tests/conf/eslint-recommended.js b/tests/conf/eslint-recommended.js
new file mode 100644
index 000000000..89d9f4447
--- /dev/null
+++ b/tests/conf/eslint-recommended.js
@@ -0,0 +1,24 @@
+/**
+ * @fileoverview Tests for eslint:recommended.
+ * @author Kevin Partington
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const assert = require("chai").assert;
+const eslintRecommended = require("../../conf/eslint-recommended");
+const rules = eslintRecommended.rules;
+
+describe("eslint-recommended", () => {
+    it("should configure recommended rules as error", () => {
+        assert.strictEqual(rules["no-undef"], "error");
+    });
+
+    it("should not configure non-recommended rules", () => {
+        assert.notProperty(rules, "camelcase");
+    });
+});
diff --git a/tests/fixtures/cli-engine/overrides-with-dot/.eslintrc.yml b/tests/fixtures/cli-engine/overrides-with-dot/.eslintrc.yml
new file mode 100644
index 000000000..5acdae3fd
--- /dev/null
+++ b/tests/fixtures/cli-engine/overrides-with-dot/.eslintrc.yml
@@ -0,0 +1,6 @@
+root: true
+
+overrides:
+  - files: "*.js"
+    rules:
+      no-unused-vars: error
diff --git a/tests/fixtures/cli-engine/overrides-with-dot/.test-target.js b/tests/fixtures/cli-engine/overrides-with-dot/.test-target.js
new file mode 100644
index 000000000..ac09549ac
--- /dev/null
+++ b/tests/fixtures/cli-engine/overrides-with-dot/.test-target.js
@@ -0,0 +1,1 @@
+var a = 0
diff --git a/tests/fixtures/config-file/experimental-object-rest-spread/another-parser/.eslintrc.yml b/tests/fixtures/config-file/experimental-object-rest-spread/another-parser/.eslintrc.yml
deleted file mode 100644
index c64b2c309..000000000
--- a/tests/fixtures/config-file/experimental-object-rest-spread/another-parser/.eslintrc.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-root: true
-
-parser: ./parser.js
-parserOptions:
-  ecmaFeatures:
-    experimentalObjectRestSpread: true
diff --git a/tests/fixtures/config-file/experimental-object-rest-spread/another-parser/parser.js b/tests/fixtures/config-file/experimental-object-rest-spread/another-parser/parser.js
deleted file mode 100644
index f193589ef..000000000
--- a/tests/fixtures/config-file/experimental-object-rest-spread/another-parser/parser.js
+++ /dev/null
@@ -1,1 +0,0 @@
-module.exports.parse = () => ({ type: "Program", body: [] })
diff --git a/tests/fixtures/config-file/experimental-object-rest-spread/basic/.eslintrc.yml b/tests/fixtures/config-file/experimental-object-rest-spread/basic/.eslintrc.yml
deleted file mode 100644
index a5c9e4ebf..000000000
--- a/tests/fixtures/config-file/experimental-object-rest-spread/basic/.eslintrc.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-root: true
-
-parserOptions:
-  ecmaFeatures:
-    experimentalObjectRestSpread: true
diff --git a/tests/fixtures/config-file/experimental-object-rest-spread/extends/.eslintrc.yml b/tests/fixtures/config-file/experimental-object-rest-spread/extends/.eslintrc.yml
deleted file mode 100644
index 2daef0dea..000000000
--- a/tests/fixtures/config-file/experimental-object-rest-spread/extends/.eslintrc.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-root: true
-
-extends:
-  - ./common.yml
diff --git a/tests/fixtures/config-file/experimental-object-rest-spread/extends/common.yml b/tests/fixtures/config-file/experimental-object-rest-spread/extends/common.yml
deleted file mode 100644
index 99975a7bd..000000000
--- a/tests/fixtures/config-file/experimental-object-rest-spread/extends/common.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-parserOptions:
-  ecmaFeatures:
-    experimentalObjectRestSpread: true
diff --git a/tests/fixtures/config-file/experimental-object-rest-spread/subdir/.eslintrc.yml b/tests/fixtures/config-file/experimental-object-rest-spread/subdir/.eslintrc.yml
deleted file mode 100644
index a5c9e4ebf..000000000
--- a/tests/fixtures/config-file/experimental-object-rest-spread/subdir/.eslintrc.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-root: true
-
-parserOptions:
-  ecmaFeatures:
-    experimentalObjectRestSpread: true
diff --git a/tests/fixtures/config-file/experimental-object-rest-spread/subdir/lib/.eslintrc.yml b/tests/fixtures/config-file/experimental-object-rest-spread/subdir/lib/.eslintrc.yml
deleted file mode 100644
index 78dc43786..000000000
--- a/tests/fixtures/config-file/experimental-object-rest-spread/subdir/lib/.eslintrc.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-rules:
-  no-undef: off
diff --git a/tests/lib/cli-engine.js b/tests/lib/cli-engine.js
index ee582c83a..ff5e041d3 100644
--- a/tests/lib/cli-engine.js
+++ b/tests/lib/cli-engine.js
@@ -1532,7 +1532,7 @@ describe("CLIEngine", () => {
 
             const report = engine.executeOnFiles(["lib/cli*.js"]);
 
-            assert.deepStrictEqual(
+            assert.sameDeepMembers(
                 report.usedDeprecatedRules,
                 [
                     { ruleId: "indent-legacy", replacedBy: ["indent"] },
@@ -2870,6 +2870,23 @@ describe("CLIEngine", () => {
                 }, "No files matching 'non-exist.js' were found.");
             });
         });
+
+        describe("overrides", () => {
+            beforeEach(() => {
+                engine = new CLIEngine({
+                    cwd: getFixturePath("cli-engine/overrides-with-dot"),
+                    ignore: false
+                });
+            });
+
+            it("should recognize dotfiles", () => {
+                const ret = engine.executeOnFiles([".test-target.js"]);
+
+                assert.strictEqual(ret.results.length, 1);
+                assert.strictEqual(ret.results[0].messages.length, 1);
+                assert.strictEqual(ret.results[0].messages[0].ruleId, "no-unused-vars");
+            });
+        });
     });
 
     describe("getConfigForFile", () => {
diff --git a/tests/lib/config.js b/tests/lib/config.js
index 5381ce1eb..6eaa2c2f1 100644
--- a/tests/lib/config.js
+++ b/tests/lib/config.js
@@ -1397,74 +1397,6 @@ describe("Config", () => {
                         `The 'ecmaFeatures' config file property is deprecated, and has no effect. (found in "tests${path.sep}fixtures${path.sep}config-file${path.sep}ecma-features${path.sep}.eslintrc.yml")`
                     );
                 }));
-
-            it("should emit a deprecation warning if 'parserOptions.ecmaFeatures.experimentalObjectRestSpread' is given.", () => Promise.resolve()
-                .then(() => {
-                    const cwd = path.resolve(__dirname, "../fixtures/config-file/experimental-object-rest-spread/basic/");
-                    const config = new Config({ cwd }, linter);
-
-                    config.getConfig("test.js");
-
-                    // Wait for "warning" event.
-                    return nextTick();
-                })
-                .then(() => {
-                    assert.notStrictEqual(warning, null);
-                    assert.strictEqual(
-                        warning.message,
-                        `The 'parserOptions.ecmaFeatures.experimentalObjectRestSpread' option is deprecated. Use 'parserOptions.ecmaVersion' instead. (found in "tests${path.sep}fixtures${path.sep}config-file${path.sep}experimental-object-rest-spread${path.sep}basic${path.sep}.eslintrc.yml")`
-                    );
-                }));
-
-            it("should emit a deprecation warning if 'parserOptions.ecmaFeatures.experimentalObjectRestSpread' is given in a parent config.", () => Promise.resolve()
-                .then(() => {
-                    const cwd = path.resolve(__dirname, "../fixtures/config-file/experimental-object-rest-spread/subdir/");
-                    const config = new Config({ cwd }, linter);
-
-                    config.getConfig("lib/test.js");
-
-                    // Wait for "warning" event.
-                    return nextTick();
-                })
-                .then(() => {
-                    assert.notStrictEqual(warning, null);
-                    assert.strictEqual(
-                        warning.message,
-                        `The 'parserOptions.ecmaFeatures.experimentalObjectRestSpread' option is deprecated. Use 'parserOptions.ecmaVersion' instead. (found in "tests${path.sep}fixtures${path.sep}config-file${path.sep}experimental-object-rest-spread${path.sep}subdir${path.sep}.eslintrc.yml")`
-                    );
-                }));
-
-            it("should emit a deprecation warning if 'parserOptions.ecmaFeatures.experimentalObjectRestSpread' is given in a shareable config.", () => Promise.resolve()
-                .then(() => {
-                    const cwd = path.resolve(__dirname, "../fixtures/config-file/experimental-object-rest-spread/extends/");
-                    const config = new Config({ cwd }, linter);
-
-                    config.getConfig("test.js");
-
-                    // Wait for "warning" event.
-                    return nextTick();
-                })
-                .then(() => {
-                    assert.notStrictEqual(warning, null);
-                    assert.strictEqual(
-                        warning.message,
-                        `The 'parserOptions.ecmaFeatures.experimentalObjectRestSpread' option is deprecated. Use 'parserOptions.ecmaVersion' instead. (found in "tests${path.sep}fixtures${path.sep}config-file${path.sep}experimental-object-rest-spread${path.sep}extends${path.sep}common.yml")`
-                    );
-                }));
-
-            it("should NOT emit a deprecation warning even if 'parserOptions.ecmaFeatures.experimentalObjectRestSpread' is given, if parser is not espree.", () => Promise.resolve()
-                .then(() => {
-                    const cwd = path.resolve(__dirname, "../fixtures/config-file/experimental-object-rest-spread/another-parser/");
-                    const config = new Config({ cwd }, linter);
-
-                    config.getConfig("test.js");
-
-                    // Wait for "warning" event.
-                    return nextTick();
-                })
-                .then(() => {
-                    assert.strictEqual(warning, null);
-                }));
         });
     });
 
diff --git a/tests/lib/linter.js b/tests/lib/linter.js
index e31b61d95..da6b97c4b 100644
--- a/tests/lib/linter.js
+++ b/tests/lib/linter.js
@@ -3545,15 +3545,6 @@ describe("Linter", () => {
             linter.verify("x", { rules: { "foo-bar-baz": "error" } });
             assert(spy.calledOnce);
         });
-
-        it("should parse ES2018 code for backward compatibility if 'parserOptions.ecmaFeatures.experimentalObjectRestSpread' is given.", () => {
-            const messages = linter.verify(
-                "async function* f() { let {a, ...rest} = { a, ...obj }; }",
-                { parserOptions: { ecmaFeatures: { experimentalObjectRestSpread: true } } }
-            );
-
-            assert(messages.length === 0);
-        });
     });
 
     describe("context.getScope()", () => {
diff --git a/tests/lib/rules/max-len.js b/tests/lib/rules/max-len.js
index a7080f477..41b0efe9b 100644
--- a/tests/lib/rules/max-len.js
+++ b/tests/lib/rules/max-len.js
@@ -178,6 +178,12 @@ ruleTester.run("max-len", rule, {
         {
             code: "'🙂😀😆😎😊😜😉👍'",
             options: [10]
+        },
+
+        // Astral symbols in pattern (only matched by unicode regexes)
+        {
+            code: "var longNameLongName = '𝌆𝌆'",
+            options: [5, { ignorePattern: "𝌆{2}" }]
         }
     ],
 
diff --git a/tests/lib/rules/no-unused-vars.js b/tests/lib/rules/no-unused-vars.js
index 3012dec63..ba8e57dcc 100644
--- a/tests/lib/rules/no-unused-vars.js
+++ b/tests/lib/rules/no-unused-vars.js
@@ -330,33 +330,33 @@ ruleTester.run("no-unused-vars", rule, {
         {
             code: "var _a; var b;",
             options: [{ vars: "all", varsIgnorePattern: "^_" }],
-            errors: [{ message: "'b' is defined but never used. Allowed unused vars must match /^_/.", line: 1, column: 13 }]
+            errors: [{ message: "'b' is defined but never used. Allowed unused vars must match /^_/u.", line: 1, column: 13 }]
         },
         {
             code: "var a; function foo() { var _b; var c_; } foo();",
             options: [{ vars: "local", varsIgnorePattern: "^_" }],
-            errors: [{ message: "'c_' is defined but never used. Allowed unused vars must match /^_/.", line: 1, column: 37 }]
+            errors: [{ message: "'c_' is defined but never used. Allowed unused vars must match /^_/u.", line: 1, column: 37 }]
         },
         {
             code: "function foo(a, _b) { } foo();",
             options: [{ args: "all", argsIgnorePattern: "^_" }],
-            errors: [{ message: "'a' is defined but never used. Allowed unused args must match /^_/.", line: 1, column: 14 }]
+            errors: [{ message: "'a' is defined but never used. Allowed unused args must match /^_/u.", line: 1, column: 14 }]
         },
         {
             code: "function foo(a, _b, c) { return a; } foo();",
             options: [{ args: "after-used", argsIgnorePattern: "^_" }],
-            errors: [{ message: "'c' is defined but never used. Allowed unused args must match /^_/.", line: 1, column: 21 }]
+            errors: [{ message: "'c' is defined but never used. Allowed unused args must match /^_/u.", line: 1, column: 21 }]
         },
         {
             code: "function foo(_a) { } foo();",
             options: [{ args: "all", argsIgnorePattern: "[iI]gnored" }],
-            errors: [{ message: "'_a' is defined but never used. Allowed unused args must match /[iI]gnored/.", line: 1, column: 14 }]
+            errors: [{ message: "'_a' is defined but never used. Allowed unused args must match /[iI]gnored/u.", line: 1, column: 14 }]
         },
         {
             code: "var [ firstItemIgnored, secondItem ] = items;",
             options: [{ vars: "all", varsIgnorePattern: "[iI]gnored" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [{ message: "'secondItem' is assigned a value but never used. Allowed unused vars must match /[iI]gnored/.", line: 1, column: 25 }]
+            errors: [{ message: "'secondItem' is assigned a value but never used. Allowed unused vars must match /[iI]gnored/u.", line: 1, column: 25 }]
         },
 
         // for-in loops (see #2342)
@@ -524,14 +524,14 @@ ruleTester.run("no-unused-vars", rule, {
         {
             code: "try{}catch(err){};",
             options: [{ caughtErrors: "all", caughtErrorsIgnorePattern: "^ignore" }],
-            errors: [{ message: "'err' is defined but never used. Allowed unused args must match /^ignore/." }]
+            errors: [{ message: "'err' is defined but never used. Allowed unused args must match /^ignore/u." }]
         },
 
         // multiple try catch with one success
         {
             code: "try{}catch(ignoreErr){}try{}catch(err){};",
             options: [{ caughtErrors: "all", caughtErrorsIgnorePattern: "^ignore" }],
-            errors: [{ message: "'err' is defined but never used. Allowed unused args must match /^ignore/." }]
+            errors: [{ message: "'err' is defined but never used. Allowed unused args must match /^ignore/u." }]
         },
 
         // multiple try catch both fail
@@ -539,8 +539,8 @@ ruleTester.run("no-unused-vars", rule, {
             code: "try{}catch(error){}try{}catch(err){};",
             options: [{ caughtErrors: "all", caughtErrorsIgnorePattern: "^ignore" }],
             errors: [
-                { message: "'error' is defined but never used. Allowed unused args must match /^ignore/." },
-                { message: "'err' is defined but never used. Allowed unused args must match /^ignore/." }
+                { message: "'error' is defined but never used. Allowed unused args must match /^ignore/u." },
+                { message: "'err' is defined but never used. Allowed unused args must match /^ignore/u." }
             ]
         },
 
@@ -613,10 +613,10 @@ ruleTester.run("no-unused-vars", rule, {
             options: [{ argsIgnorePattern: "c" }],
             errors: [
                 {
-                    message: "'a' is defined but never used. Allowed unused args must match /c/."
+                    message: "'a' is defined but never used. Allowed unused args must match /c/u."
                 },
                 {
-                    message: "'b' is defined but never used. Allowed unused args must match /c/."
+                    message: "'b' is defined but never used. Allowed unused args must match /c/u."
                 }
             ]
         },
@@ -626,10 +626,10 @@ ruleTester.run("no-unused-vars", rule, {
             parserOptions: { ecmaVersion: 6 },
             errors: [
                 {
-                    message: "'a' is defined but never used. Allowed unused args must match /[cd]/."
+                    message: "'a' is defined but never used. Allowed unused args must match /[cd]/u."
                 },
                 {
-                    message: "'b' is defined but never used. Allowed unused args must match /[cd]/."
+                    message: "'b' is defined but never used. Allowed unused args must match /[cd]/u."
                 }
             ]
         },
@@ -639,13 +639,13 @@ ruleTester.run("no-unused-vars", rule, {
             parserOptions: { ecmaVersion: 6 },
             errors: [
                 {
-                    message: "'a' is defined but never used. Allowed unused args must match /c/."
+                    message: "'a' is defined but never used. Allowed unused args must match /c/u."
                 },
                 {
-                    message: "'b' is defined but never used. Allowed unused args must match /c/."
+                    message: "'b' is defined but never used. Allowed unused args must match /c/u."
                 },
                 {
-                    message: "'d' is defined but never used. Allowed unused args must match /c/."
+                    message: "'d' is defined but never used. Allowed unused args must match /c/u."
                 }
             ]
         },
@@ -655,13 +655,13 @@ ruleTester.run("no-unused-vars", rule, {
             parserOptions: { ecmaVersion: 6 },
             errors: [
                 {
-                    message: "'a' is defined but never used. Allowed unused args must match /d/."
+                    message: "'a' is defined but never used. Allowed unused args must match /d/u."
                 },
                 {
-                    message: "'b' is defined but never used. Allowed unused args must match /d/."
+                    message: "'b' is defined but never used. Allowed unused args must match /d/u."
                 },
                 {
-                    message: "'c' is defined but never used. Allowed unused args must match /d/."
+                    message: "'c' is defined but never used. Allowed unused args must match /d/u."
                 }
             ]
         },