Repository: eslint/eslint
Pull request #9206 (2017-09-02 09:39:54)

Update: Add "consistent" option to array-bracket-newline (#9136)
<!--
    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))
[x] 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
[ ] Other, please explain:

<!--
    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.)
-->

https://github.com/eslint/eslint/issues/9136

**What changes did you make? (Give an overview)**
Added a "consistent" option to `array-bracket-newline`




eslintbot: LGTM
eslintbot: LGTM
EthanRutherford: #9136 was accepted, so this should be ready for some review now.
not-an-aardvark: It looks like there is a merge conflict.
eslintbot: LGTM
EthanRutherford: Merge conflict has been taken care of :)

Patch:
diff --git a/docs/rules/array-bracket-newline.md b/docs/rules/array-bracket-newline.md
index 0b381f3c9..72e0041d8 100644
--- a/docs/rules/array-bracket-newline.md
+++ b/docs/rules/array-bracket-newline.md
@@ -12,6 +12,7 @@ This rule has either a string option:
 
 * `"always"` requires line breaks inside brackets
 * `"never"` disallows line breaks inside brackets
+* `"consistent"` requires consistent usage of linebreaks for each pair of brackets. It reports an error if one bracket in the pair has a linebreak inside it and the other bracket does not.
 
 Or an object option (Requires line breaks if any of properties is satisfied. Otherwise, disallows line breaks):
 
@@ -100,6 +101,49 @@ var e = [function foo() {
 }];
 ```
 
+### consistent
+
+Examples of **incorrect** code for this rule with the `"consistent"` option:
+
+```js
+/*eslint array-bracket-newline: ["error", "consistent"]*/
+
+var a = [1
+];
+var b = [
+    1];
+var c = [function foo() {
+    dosomething();
+}
+]
+var d = [
+    function foo() {
+        dosomething();
+    }]
+```
+
+Examples of **correct** code for this rule with the `"consistent"` option:
+
+```js
+/*eslint array-bracket-newline: ["error", "consistent"]*/
+
+var a = [];
+var b = [
+];
+var c = [1];
+var d = [
+    1
+];
+var e = [function foo() {
+    dosomething();
+}];
+var f = [
+    function foo() {
+        dosomething();
+    }
+];
+```
+
 ### multiline
 
 Examples of **incorrect** code for this rule with the default `{ "multiline": true }` option:
diff --git a/docs/user-guide/getting-started.md b/docs/user-guide/getting-started.md
index 52513bb84..8286468ba 100644
--- a/docs/user-guide/getting-started.md
+++ b/docs/user-guide/getting-started.md
@@ -13,6 +13,8 @@ ESLint is a tool for identifying and reporting on patterns found in ECMAScript/J
 
 ## Installation and Usage
 
+Prerequisites: [Node.js](https://nodejs.org/en/) (>=4.x), npm version 2+.
+
 There are two ways to install ESLint: globally and locally.
 
 ### Local Installation and Usage
diff --git a/lib/rules/array-bracket-newline.js b/lib/rules/array-bracket-newline.js
index adfce985f..5115ef4b5 100644
--- a/lib/rules/array-bracket-newline.js
+++ b/lib/rules/array-bracket-newline.js
@@ -23,7 +23,7 @@ module.exports = {
             {
                 oneOf: [
                     {
-                        enum: ["always", "never"]
+                        enum: ["always", "never", "consistent"]
                     },
                     {
                         type: "object",
@@ -58,11 +58,15 @@ module.exports = {
          * @returns {{multiline: boolean, minItems: number}} Normalized option object.
          */
         function normalizeOptionValue(option) {
+            let consistent = false;
             let multiline = false;
             let minItems = 0;
 
             if (option) {
-                if (option === "always" || option.minItems === 0) {
+                if (option === "consistent") {
+                    consistent = true;
+                    minItems = Number.POSITIVE_INFINITY;
+                } else if (option === "always" || option.minItems === 0) {
                     minItems = 0;
                 } else if (option === "never") {
                     minItems = Number.POSITIVE_INFINITY;
@@ -71,11 +75,12 @@ module.exports = {
                     minItems = option.minItems || Number.POSITIVE_INFINITY;
                 }
             } else {
+                consistent = false;
                 multiline = true;
                 minItems = Number.POSITIVE_INFINITY;
             }
 
-            return { multiline, minItems };
+            return { consistent, multiline, minItems };
         }
 
         /**
@@ -173,8 +178,7 @@ module.exports = {
         /**
          * Reports a given node if it violated this rule.
          *
-         * @param {ASTNode} node - A node to check. This is an ObjectExpression node or an ObjectPattern node.
-         * @param {{multiline: boolean, minItems: number}} options - An option object.
+         * @param {ASTNode} node - A node to check. This is an ArrayExpression node or an ArrayPattern node.
          * @returns {void}
          */
         function check(node) {
@@ -200,6 +204,10 @@ module.exports = {
                     firstIncComment.type === "Block" &&
                     firstIncComment.loc.start.line !== lastIncComment.loc.end.line &&
                     firstIncComment === lastIncComment
+                ) ||
+                (
+                    options.consistent &&
+                    firstIncComment.loc.start.line !== openBracket.loc.end.line
                 )
             );
 


Test patch:
diff --git a/tests/lib/rules/array-bracket-newline.js b/tests/lib/rules/array-bracket-newline.js
index cf02cbdf6..1258dc18f 100644
--- a/tests/lib/rules/array-bracket-newline.js
+++ b/tests/lib/rules/array-bracket-newline.js
@@ -63,6 +63,12 @@ ruleTester.run("array-bracket-newline", rule, {
         { code: "var foo = [1,\n/* any comment */\n2];", options: ["never"] },
         { code: "var foo = [function foo() {\ndosomething();\n}];", options: ["never"] },
 
+        // "consistent"
+        { code: "var a = []", options: ["consistent"] },
+        { code: "var a = [\n]", options: ["consistent"] },
+        { code: "var a = [1]", options: ["consistent"] },
+        { code: "var a = [\n1\n]", options: ["consistent"] },
+
         // { multiline: true }
         { code: "var foo = [];", options: [{ multiline: true }] },
         { code: "var foo = [1];", options: [{ multiline: true }] },
@@ -146,6 +152,12 @@ ruleTester.run("array-bracket-newline", rule, {
         { code: "var [\na, b /* any comment */\n] = foo;", options: ["always"], parserOptions: { ecmaVersion: 6 } },
         { code: "var [\na,\nb\n] = foo;", options: ["always"], parserOptions: { ecmaVersion: 6 } },
 
+        // "consistent"
+        { code: "var [] = foo", options: ["consistent"], parserOptions: { ecmaVersion: 6 } },
+        { code: "var [\n] = foo", options: ["consistent"], parserOptions: { ecmaVersion: 6 } },
+        { code: "var [a] = foo", options: ["consistent"], parserOptions: { ecmaVersion: 6 } },
+        { code: "var [\na\n] = foo", options: ["consistent"], parserOptions: { ecmaVersion: 6 } },
+
         // { multiline: true }
         { code: "var [] = foo;", options: [{ multiline: true }], parserOptions: { ecmaVersion: 6 } },
         { code: "var [a] = foo;", options: [{ multiline: true }], parserOptions: { ecmaVersion: 6 } },
@@ -485,6 +497,38 @@ ruleTester.run("array-bracket-newline", rule, {
             ]
         },
 
+        // "consistent"
+        {
+            code: "var foo = [\n1]",
+            output: "var foo = [\n1\n]",
+            options: ["consistent"],
+            errors: [
+                {
+                    message: ERR_BREAK_BEFORE,
+                    type: "ArrayExpression",
+                    line: 2,
+                    column: 2,
+                    endLine: 2,
+                    endColumn: 3
+                }
+            ]
+        },
+        {
+            code: "var foo = [1\n]",
+            output: "var foo = [1]",
+            options: ["consistent"],
+            errors: [
+                {
+                    message: ERR_NO_BREAK_BEFORE,
+                    type: "ArrayExpression",
+                    line: 2,
+                    column: 1,
+                    endLine: 2,
+                    endColumn: 2
+                }
+            ]
+        },
+
         // { multiline: true }
         {
             code: "var foo = [\n];",
@@ -1377,6 +1421,40 @@ ruleTester.run("array-bracket-newline", rule, {
             ]
         },
 
+        // "consistent"
+        {
+            code: "var [\na] = foo",
+            output: "var [\na\n] = foo",
+            options: ["consistent"],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                {
+                    message: ERR_BREAK_BEFORE,
+                    type: "ArrayPattern",
+                    line: 2,
+                    column: 2,
+                    endLine: 2,
+                    endColumn: 3
+                }
+            ]
+        },
+        {
+            code: "var [a\n] = foo",
+            output: "var [a] = foo",
+            options: ["consistent"],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                {
+                    message: ERR_NO_BREAK_BEFORE,
+                    type: "ArrayPattern",
+                    line: 2,
+                    column: 1,
+                    endLine: 2,
+                    endColumn: 2
+                }
+            ]
+        },
+
         // { minItems: 2 }
         {
             code: "var [\n] = foo;",