Repository: eslint/eslint
Pull request #12553 (2019-11-10 23:27:40)

Docs: clarify ignoreDestructuring option in the camelcase rule
<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**What is the purpose of this pull request? (put an "X" next to item)**

[X] Documentation update

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

**What changes did you make? (Give an overview)**

Additional description and some common use cases for `ignoreDestructuring` option in `camelcase` docs.

**Is there anything you'd like reviewers to focus on?**





Patch:
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 102d47e83..fec55351f 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,1 +1,2 @@
+github: eslint
 open_collective: eslint
diff --git a/docs/rules/camelcase.md b/docs/rules/camelcase.md
index 5c4efcfe4..96135f8c9 100644
--- a/docs/rules/camelcase.md
+++ b/docs/rules/camelcase.md
@@ -13,7 +13,7 @@ This rule has an object option:
 * `"properties": "always"` (default) enforces camelcase style for property names
 * `"properties": "never"` does not check property names
 * `"ignoreDestructuring": false` (default) enforces camelcase style for destructured identifiers
-* `"ignoreDestructuring": true` does not check destructured identifiers
+* `"ignoreDestructuring": true` does not check destructured identifiers (but still checks any use of those identifiers later in the code)
 * `"ignoreImports": false` (default) enforces camelcase style for ES2015 imports
 * `"ignoreImports": true` does not check ES2015 imports (but still checks any use of the imports later in the code except function arguments)
 * `allow` (`string[]`) list of properties to accept. Accept regex.
@@ -154,6 +154,39 @@ var { category_id = 1 } = query;
 var { category_id: category_id } = query;
 ```
 
+Please note that this option applies only to identifiers inside destructuring patterns. It doesn't additionally allow any particular use of the created variables later in the code apart from the use that is already allowed by default or by other options.
+
+Examples of additional **incorrect** code for this rule with the `{ "ignoreDestructuring": true }` option:
+
+```js
+/*eslint camelcase: ["error", {ignoreDestructuring: true}]*/
+
+var { some_property } = obj; // allowed by {ignoreDestructuring: true}
+var foo = some_property + 1; // error, ignoreDestructuring does not apply to this statement
+```
+
+A common use case for this option is to avoid useless renaming when the identifier is not intended to be used later in the code.
+
+Examples of additional **correct** code for this rule with the `{ "ignoreDestructuring": true }` option:
+
+```js
+/*eslint camelcase: ["error", {ignoreDestructuring: true}]*/
+
+var { some_property, ...rest } = obj;
+// do something with 'rest', nothing with 'some_property'
+```
+
+Another common use case for this option is in combination with `{ "properties": "never" }`, when the identifier is intended to be used only as a property shorthand.
+
+Examples of additional **correct** code for this rule with the `{ "properties": "never", "ignoreDestructuring": true }` options:
+
+```js
+/*eslint camelcase: ["error", {"properties": "never", ignoreDestructuring: true}]*/
+
+var { some_property } = obj;
+doSomething({ some_property });
+```
+
 ### ignoreImports: false
 
 Examples of **incorrect** code for this rule with the default `{ "ignoreImports": false }` option:
diff --git a/lib/init/config-initializer.js b/lib/init/config-initializer.js
index 48e56ce52..28dfad194 100644
--- a/lib/init/config-initializer.js
+++ b/lib/init/config-initializer.js
@@ -291,6 +291,7 @@ function processAnswers(answers) {
             jsx: true
         };
         config.plugins = ["react"];
+        config.extends.push("plugin:react/recommended");
     } else if (answers.framework === "vue") {
         config.plugins = ["vue"];
         config.extends.push("plugin:vue/essential");
@@ -522,9 +523,9 @@ function promptUser() {
             name: "styleguide",
             message: "Which style guide do you want to follow?",
             choices: [
-                { name: "Airbnb (https://github.com/airbnb/javascript)", value: "airbnb" },
-                { name: "Standard (https://github.com/standard/standard)", value: "standard" },
-                { name: "Google (https://github.com/google/eslint-config-google)", value: "google" }
+                { name: "Airbnb: https://github.com/airbnb/javascript", value: "airbnb" },
+                { name: "Standard: https://github.com/standard/standard", value: "standard" },
+                { name: "Google: https://github.com/google/eslint-config-google", value: "google" }
             ],
             when(answers) {
                 answers.packageJsonExists = npmUtils.checkPackageJson();
diff --git a/lib/rules/no-octal-escape.js b/lib/rules/no-octal-escape.js
index 7f6845ec7..5b4c7b2eb 100644
--- a/lib/rules/no-octal-escape.js
+++ b/lib/rules/no-octal-escape.js
@@ -38,7 +38,7 @@ module.exports = {
 
                 // \0 represents a valid NULL character if it isn't followed by a digit.
                 const match = node.raw.match(
-                    /^(?:[^\\]|\\.)*?\\([0-3][0-7]{1,2}|[4-7][0-7]|[1-7])/u
+                    /^(?:[^\\]|\\.)*?\\([0-3][0-7]{1,2}|[4-7][0-7]|0(?=[89])|[1-7])/su
                 );
 
                 if (match) {


Test patch:
diff --git a/tests/lib/rules/no-octal-escape.js b/tests/lib/rules/no-octal-escape.js
index cd555ab60..d89910f86 100644
--- a/tests/lib/rules/no-octal-escape.js
+++ b/tests/lib/rules/no-octal-escape.js
@@ -25,33 +25,107 @@ ruleTester.run("no-octal-escape", rule, {
         "var foo = \"foo \\\\251 bar\";",
         "var foo = /([abc]) \\1/g;",
         "var foo = '\\0';",
+        "'\\0'",
+        "'\\8'",
+        "'\\9'",
         "'\\0 '",
+        "' \\0'",
+        "'a\\0'",
         "'\\0a'",
+        "'a\\8a'",
+        "'\\0\\8'",
+        "'\\8\\0'",
+        "'\\80'",
+        "'\\81'",
+        "'\\\\'",
+        "'\\\\0'",
+        "'\\\\08'",
         "'\\\\1'",
         "'\\\\01'",
-        "'\\08'",
-        "'\\09'"
+        "'\\\\12'",
+        "'\\\\\\0'",
+        "'\\\\\\8'",
+        "'\\0\\\\'",
+        "'0'",
+        "'1'",
+        "'8'",
+        "'01'",
+        "'08'",
+        "'80'",
+        "'12'",
+        "'\\a'",
+        "'\\n'"
     ],
     invalid: [
 
         // Test full message
         { code: "var foo = \"foo \\01 bar\";", errors: [{ message: "Don't use octal: '\\01'. Use '\\u....' instead.", type: "Literal" }] },
 
+        { code: "var foo = \"foo \\000 bar\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "000" }, type: "Literal" }] },
+        { code: "var foo = \"foo \\377 bar\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "377" }, type: "Literal" }] },
+        { code: "var foo = \"foo \\378 bar\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "37" }, type: "Literal" }] },
+        { code: "var foo = \"foo \\37a bar\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "37" }, type: "Literal" }] },
+        { code: "var foo = \"foo \\381 bar\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "3" }, type: "Literal" }] },
+        { code: "var foo = \"foo \\3a1 bar\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "3" }, type: "Literal" }] },
         { code: "var foo = \"foo \\251 bar\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "251" }, type: "Literal" }] },
-        { code: "var foo = \"\\751\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "75" }, type: "Literal" }] },
+        { code: "var foo = \"foo \\258 bar\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "25" }, type: "Literal" }] },
+        { code: "var foo = \"foo \\25a bar\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "25" }, type: "Literal" }] },
         { code: "var foo = \"\\3s51\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "3" }, type: "Literal" }] },
+        { code: "var foo = \"\\77\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "77" }, type: "Literal" }] },
+        { code: "var foo = \"\\78\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "7" }, type: "Literal" }] },
+        { code: "var foo = \"\\5a\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "5" }, type: "Literal" }] },
+        { code: "var foo = \"\\751\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "75" }, type: "Literal" }] },
+        { code: "var foo = \"foo \\400 bar\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "40" }, type: "Literal" }] },
+
+        { code: "var foo = \"\\t\\1\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "1" }, type: "Literal" }] },
         { code: "var foo = \"\\\\\\751\";", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "75" }, type: "Literal" }] },
+
         { code: "'\\0\\1'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "1" }, type: "Literal" }] },
         { code: "'\\0 \\1'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "1" }, type: "Literal" }] },
         { code: "'\\0\\01'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "01" }, type: "Literal" }] },
         { code: "'\\0 \\01'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "01" }, type: "Literal" }] },
-        { code: "'\\08\\1'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "1" }, type: "Literal" }] },
-        { code: "'\\08\\01'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "01" }, type: "Literal" }] },
+        { code: "'\\0a\\1'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "1" }, type: "Literal" }] },
+        { code: "'\\0a\\01'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "01" }, type: "Literal" }] },
+        { code: "'\\0\\08'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "0" }, type: "Literal" }] },
+
+        { code: "'\\1'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "1" }, type: "Literal" }] },
+        { code: "'\\2'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "2" }, type: "Literal" }] },
+        { code: "'\\7'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "7" }, type: "Literal" }] },
+        { code: "'\\00'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "00" }, type: "Literal" }] },
+        { code: "'\\01'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "01" }, type: "Literal" }] },
+        { code: "'\\02'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "02" }, type: "Literal" }] },
+        { code: "'\\07'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "07" }, type: "Literal" }] },
+        { code: "'\\08'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "0" }, type: "Literal" }] },
+        { code: "'\\09'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "0" }, type: "Literal" }] },
+        { code: "'\\10'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "10" }, type: "Literal" }] },
+        { code: "'\\12'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "12" }, type: "Literal" }] },
+        { code: "' \\1'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "1" }, type: "Literal" }] },
+        { code: "'\\1 '", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "1" }, type: "Literal" }] },
+        { code: "'a\\1'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "1" }, type: "Literal" }] },
+        { code: "'\\1a'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "1" }, type: "Literal" }] },
+        { code: "'a\\1a'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "1" }, type: "Literal" }] },
+        { code: "' \\01'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "01" }, type: "Literal" }] },
+        { code: "'\\01 '", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "01" }, type: "Literal" }] },
+        { code: "'a\\01'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "01" }, type: "Literal" }] },
+        { code: "'\\01a'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "01" }, type: "Literal" }] },
+        { code: "'a\\01a'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "01" }, type: "Literal" }] },
+        { code: "'a\\08a'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "0" }, type: "Literal" }] },
+        { code: "'\\n\\1'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "1" }, type: "Literal" }] },
+        { code: "'\\n\\01'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "01" }, type: "Literal" }] },
+        { code: "'\\n\\08'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "0" }, type: "Literal" }] },
+        { code: "'\\\\\\1'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "1" }, type: "Literal" }] },
+        { code: "'\\\\\\01'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "01" }, type: "Literal" }] },
+        { code: "'\\\\\\08'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "0" }, type: "Literal" }] },
+
+        // Multiline string
+        { code: "'\\\n\\1'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "1" }, type: "Literal" }] },
 
         // Only the first one is reported
         { code: "'\\01\\02'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "01" }, type: "Literal" }] },
         { code: "'\\02\\01'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "02" }, type: "Literal" }] },
         { code: "'\\01\\2'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "01" }, type: "Literal" }] },
-        { code: "'\\2\\01'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "2" }, type: "Literal" }] }
+        { code: "'\\2\\01'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "2" }, type: "Literal" }] },
+        { code: "'\\08\\1'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "0" }, type: "Literal" }] },
+        { code: "'foo \\1 bar \\2'", errors: [{ messageId: "octalEscapeSequence", data: { sequence: "1" }, type: "Literal" }] }
     ]
 });