diff --git a/eslint/babel-eslint-plugin/README.md b/eslint/babel-eslint-plugin/README.md index d0b799a585..19cbf53899 100644 --- a/eslint/babel-eslint-plugin/README.md +++ b/eslint/babel-eslint-plugin/README.md @@ -26,6 +26,7 @@ original ones as well!). "rules": { "babel/generator-star-spacing": 1, "babel/new-cap": 1, + "babel/array-bracket-spacing": 1, "babel/object-curly-spacing": 1, "babel/object-shorthand": 1, "babel/arrow-parens": 1, @@ -39,6 +40,7 @@ Each rule corresponds to a core `eslint` rule, and has the same options. - `babel/generator-star-spacing`: Handles async/await functions correctly - `babel/new-cap`: Ignores capitalized decorators (`@Decorator`) +- `babel/array-bracket-spacing`: Handles destructuring arrays with flow type in function parametres - `babel/object-curly-spacing`: doesn't complain about `export x from "mod";` or `export * as x from "mod";` - `babel/object-shorthand`: doesn't fail when using object spread (`...obj`) - `babel/arrow-parens`: Handles async functions correctly diff --git a/eslint/babel-eslint-plugin/index.js b/eslint/babel-eslint-plugin/index.js index 9bb58310c1..43c631615e 100644 --- a/eslint/babel-eslint-plugin/index.js +++ b/eslint/babel-eslint-plugin/index.js @@ -5,6 +5,7 @@ module.exports = { 'generator-star-spacing': require('./rules/generator-star-spacing'), 'new-cap': require('./rules/new-cap'), 'object-curly-spacing': require('./rules/object-curly-spacing'), + 'array-bracket-spacing': require('./rules/array-bracket-spacing'), 'object-shorthand': require('./rules/object-shorthand'), 'arrow-parens': require('./rules/arrow-parens'), 'no-await-in-loop': require('./rules/no-await-in-loop'), @@ -13,6 +14,7 @@ module.exports = { 'generator-star-spacing': 0, 'new-cap': 0, 'object-curly-spacing': 0, + 'array-bracket-spacing': 0, 'object-shorthand': 0, 'arrow-parens': 0, 'no-await-in-loop': 0, diff --git a/eslint/babel-eslint-plugin/rules/array-bracket-spacing.js b/eslint/babel-eslint-plugin/rules/array-bracket-spacing.js new file mode 100644 index 0000000000..b67fbe92fb --- /dev/null +++ b/eslint/babel-eslint-plugin/rules/array-bracket-spacing.js @@ -0,0 +1,222 @@ +/** + * @fileoverview Disallows or enforces spaces inside of array brackets. + * @author Jamund Ferguson + * @copyright 2015 Jamund Ferguson. All rights reserved. + * @copyright 2014 Brandyn Bennett. All rights reserved. + * @copyright 2014 Michael Ficarra. No rights reserved. + * @copyright 2014 Vignesh Anand. All rights reserved. + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = function(context) { + var spaced = context.options[0] === "always", + sourceCode = context.getSourceCode(); + + /** + * Determines whether an option is set, relative to the spacing option. + * If spaced is "always", then check whether option is set to false. + * If spaced is "never", then check whether option is set to true. + * @param {Object} option - The option to exclude. + * @returns {boolean} Whether or not the property is excluded. + */ + function isOptionSet(option) { + return context.options[1] ? context.options[1][option] === !spaced : false; + } + + var options = { + spaced: spaced, + singleElementException: isOptionSet("singleValue"), + objectsInArraysException: isOptionSet("objectsInArrays"), + arraysInArraysException: isOptionSet("arraysInArrays") + }; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Determines whether two adjacent tokens are on the same line. + * @param {Object} left - The left token object. + * @param {Object} right - The right token object. + * @returns {boolean} Whether or not the tokens are on the same line. + */ + function isSameLine(left, right) { + return left.loc.start.line === right.loc.start.line; + } + + /** + * Reports that there shouldn't be a space after the first token + * @param {ASTNode} node - The node to report in the event of an error. + * @param {Token} token - The token to use for the report. + * @returns {void} + */ + function reportNoBeginningSpace(node, token) { + context.report({ + node: node, + loc: token.loc.start, + message: "There should be no space after '" + token.value + "'", + fix: function(fixer) { + var nextToken = sourceCode.getTokenAfter(token); + return fixer.removeRange([token.range[1], nextToken.range[0]]); + } + }); + } + + /** + * Reports that there shouldn't be a space before the last token + * @param {ASTNode} node - The node to report in the event of an error. + * @param {Token} token - The token to use for the report. + * @returns {void} + */ + function reportNoEndingSpace(node, token) { + context.report({ + node: node, + loc: token.loc.start, + message: "There should be no space before '" + token.value + "'", + fix: function(fixer) { + var previousToken = sourceCode.getTokenBefore(token); + return fixer.removeRange([previousToken.range[1], token.range[0]]); + } + }); + } + + /** + * Reports that there should be a space after the first token + * @param {ASTNode} node - The node to report in the event of an error. + * @param {Token} token - The token to use for the report. + * @returns {void} + */ + function reportRequiredBeginningSpace(node, token) { + context.report({ + node: node, + loc: token.loc.start, + message: "A space is required after '" + token.value + "'", + fix: function(fixer) { + return fixer.insertTextAfter(token, " "); + } + }); + } + + /** + * Reports that there should be a space before the last token + * @param {ASTNode} node - The node to report in the event of an error. + * @param {Token} token - The token to use for the report. + * @returns {void} + */ + function reportRequiredEndingSpace(node, token) { + context.report({ + node: node, + loc: token.loc.start, + message: "A space is required before '" + token.value + "'", + fix: function(fixer) { + return fixer.insertTextBefore(token, " "); + } + }); + } + + /** + * Determines if a node is an object type + * @param {ASTNode} node - The node to check. + * @returns {boolean} Whether or not the node is an object type. + */ + function isObjectType(node) { + return node && (node.type === "ObjectExpression" || node.type === "ObjectPattern"); + } + + /** + * Determines if a node is an array type + * @param {ASTNode} node - The node to check. + * @returns {boolean} Whether or not the node is an array type. + */ + function isArrayType(node) { + return node && (node.type === "ArrayExpression" || node.type === "ArrayPattern"); + } + + /** + * Validates the spacing around array brackets + * @param {ASTNode} node - The node we're checking for spacing + * @returns {void} + */ + function validateArraySpacing(node) { + if (options.spaced && node.elements.length === 0) { + return; + } + + var first = sourceCode.getFirstToken(node), + second = sourceCode.getFirstToken(node, 1), + last = sourceCode.getLastToken(node), + firstElement = node.elements[0], + lastElement = node.elements[node.elements.length - 1]; + + while (last.type !== "Punctuation" && last.value !== "]") { + last = sourceCode.getTokenBefore(last); + } + + var penultimate = sourceCode.getTokenBefore(last); + + var openingBracketMustBeSpaced = + options.objectsInArraysException && isObjectType(firstElement) || + options.arraysInArraysException && isArrayType(firstElement) || + options.singleElementException && node.elements.length === 1 + ? !options.spaced : options.spaced; + + var closingBracketMustBeSpaced = + options.objectsInArraysException && isObjectType(lastElement) || + options.arraysInArraysException && isArrayType(lastElement) || + options.singleElementException && node.elements.length === 1 + ? !options.spaced : options.spaced; + + if (isSameLine(first, second)) { + if (openingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(first, second)) { + reportRequiredBeginningSpace(node, first); + } + if (!openingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(first, second)) { + reportNoBeginningSpace(node, first); + } + } + + if (first !== penultimate && isSameLine(penultimate, last)) { + if (closingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(penultimate, last)) { + reportRequiredEndingSpace(node, last); + } + if (!closingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(penultimate, last)) { + reportNoEndingSpace(node, last); + } + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + ArrayPattern: validateArraySpacing, + ArrayExpression: validateArraySpacing + }; + +}; + +module.exports.schema = [ + { + "enum": ["always", "never"] + }, + { + "type": "object", + "properties": { + "singleValue": { + "type": "boolean" + }, + "objectsInArrays": { + "type": "boolean" + }, + "arraysInArrays": { + "type": "boolean" + } + }, + "additionalProperties": false + } +]; diff --git a/eslint/babel-eslint-plugin/tests/array-bracket-spacing.js b/eslint/babel-eslint-plugin/tests/array-bracket-spacing.js new file mode 100644 index 0000000000..e4d743d254 --- /dev/null +++ b/eslint/babel-eslint-plugin/tests/array-bracket-spacing.js @@ -0,0 +1,733 @@ +/** + * @fileoverview Disallows or enforces spaces inside of brackets. + * @author Ian Christian Myers + * @copyright 2014 Vignesh Anand. All rights reserved. + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +var rule = require('../rules/array-bracket-spacing'), + RuleTester = require('eslint').RuleTester; + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +var ruleTester = new RuleTester(); +ruleTester.run("array-bracket-spacing", rule, { + + valid: [ + { code: "var foo = obj[ 1 ]", options: ["always"] }, + { code: "var foo = obj[ 'foo' ];", options: ["always"] }, + { code: "var foo = obj[ [ 1, 1 ] ];", options: ["always"] }, + + // always - singleValue + { code: "var foo = ['foo']", options: ["always", {singleValue: false}] }, + { code: "var foo = [2]", options: ["always", {singleValue: false}] }, + { code: "var foo = [[ 1, 1 ]]", options: ["always", {singleValue: false}] }, + { code: "var foo = [{ 'foo': 'bar' }]", options: ["always", {singleValue: false}] }, + { code: "var foo = [bar]", options: ["always", {singleValue: false}] }, + + // always - objectsInArrays + { code: "var foo = [{ 'bar': 'baz' }, 1, 5 ];", options: ["always", {objectsInArrays: false}] }, + { code: "var foo = [ 1, 5, { 'bar': 'baz' }];", options: ["always", {objectsInArrays: false}] }, + { code: "var foo = [{\n'bar': 'baz', \n'qux': [{ 'bar': 'baz' }], \n'quxx': 1 \n}]", options: ["always", {objectsInArrays: false}] }, + { code: "var foo = [{ 'bar': 'baz' }]", options: ["always", {objectsInArrays: false}] }, + { code: "var foo = [{ 'bar': 'baz' }, 1, { 'bar': 'baz' }];", options: ["always", {objectsInArrays: false}] }, + { code: "var foo = [ 1, { 'bar': 'baz' }, 5 ];", options: ["always", {objectsInArrays: false}] }, + { code: "var foo = [ 1, { 'bar': 'baz' }, [{ 'bar': 'baz' }] ];", options: ["always", {objectsInArrays: false}] }, + { code: "var foo = [ function(){} ];", options: ["always", {objectsInArrays: false}] }, + + // always - arraysInArrays + { code: "var arr = [[ 1, 2 ], 2, 3, 4 ];", options: ["always", {"arraysInArrays": false}] }, + { code: "var arr = [[ 1, 2 ], [[[ 1 ]]], 3, 4 ];", options: ["always", {"arraysInArrays": false}] }, + { code: "var foo = [ arr[i], arr[j] ];", options: ["always", {"arraysInArrays": false}] }, + + // always - arraysInArrays, objectsInArrays + { code: "var arr = [[ 1, 2 ], 2, 3, { 'foo': 'bar' }];", options: ["always", {"arraysInArrays": false, objectsInArrays: false}] }, + + // always - arraysInArrays, objectsInArrays, singleValue + { code: "var arr = [[ 1, 2 ], [2], 3, { 'foo': 'bar' }];", options: ["always", {"arraysInArrays": false, objectsInArrays: false, singleValue: false}] }, + + // always + { code: "obj[ foo ]", options: ["always"] }, + { code: "obj[\nfoo\n]", options: ["always"] }, + { code: "obj[ 'foo' ]", options: ["always"] }, + { code: "obj[ 'foo' + 'bar' ]", options: ["always"] }, + { code: "obj[ obj2[ foo ] ]", options: ["always"] }, + { code: "obj.map(function(item) { return [\n1,\n2,\n3,\n4\n]; })", options: ["always"] }, + { code: "obj[ 'map' ](function(item) { return [\n1,\n2,\n3,\n4\n]; })", options: ["always"] }, + { code: "obj[ 'for' + 'Each' ](function(item) { return [\n1,\n2,\n3,\n4\n]; })", options: ["always"] }, + + { code: "var arr = [ 1, 2, 3, 4 ];", options: ["always"] }, + { code: "var arr = [ [ 1, 2 ], 2, 3, 4 ];", options: ["always"] }, + { code: "var arr = [\n1, 2, 3, 4\n];", options: ["always"] }, + { code: "var foo = [];", options: ["always"] }, + + // singleValue: false, objectsInArrays: true, arraysInArrays + { code: "this.db.mappings.insert([\n { alias: 'a', url: 'http://www.amazon.de' },\n { alias: 'g', url: 'http://www.google.de' }\n], function() {});", options: ["always", {singleValue: false, objectsInArrays: true, arraysInArrays: true}] }, + + // always - destructuring assignment + { code: "var [ x, y ] = z", ecmaFeatures: { destructuring: true }, options: ["always"] }, + { code: "var [ x,y ] = z", ecmaFeatures: { destructuring: true }, options: ["always"] }, + { code: "var [ x, y\n] = z", ecmaFeatures: { destructuring: true }, options: ["always"] }, + { code: "var [\nx, y ] = z", ecmaFeatures: { destructuring: true }, options: ["always"] }, + { code: "var [\nx, y\n] = z", ecmaFeatures: { destructuring: true }, options: ["always"] }, + { code: "var [\nx, y\n] = z", ecmaFeatures: { destructuring: true }, options: ["always"] }, + { code: "var [\nx,,,\n] = z", ecmaFeatures: { destructuring: true }, options: ["always"] }, + { code: "var [ ,x, ] = z", ecmaFeatures: { destructuring: true }, options: ["always"] }, + { code: "var [\nx, ...y\n] = z", ecmaFeatures: { destructuring: true, spread:true }, options: ["always"] }, + { code: "var [\nx, ...y ] = z", ecmaFeatures: { destructuring: true, spread:true }, options: ["always"] }, + { code: "var [[ x, y ], z ] = arr;", ecmaFeatures: { destructuring: true }, options: ["always", {"arraysInArrays": false}] }, + { code: "var [ x, [ y, z ]] = arr;", ecmaFeatures: { destructuring: true }, options: ["always", {"arraysInArrays": false}] }, + { code: "[{ x, y }, z ] = arr;", ecmaFeatures: { destructuring: true }, options: ["always", {objectsInArrays: false}] }, + { code: "[ x, { y, z }] = arr;", ecmaFeatures: { destructuring: true }, options: ["always", {objectsInArrays: false}] }, + + // never + { code: "obj[foo]", options: ["never"] }, + { code: "obj['foo']", options: ["never"] }, + { code: "obj['foo' + 'bar']", options: ["never"] }, + { code: "obj['foo'+'bar']", options: ["never"] }, + { code: "obj[obj2[foo]]", options: ["never"] }, + { code: "obj.map(function(item) { return [\n1,\n2,\n3,\n4\n]; })", options: ["never"] }, + { code: "obj['map'](function(item) { return [\n1,\n2,\n3,\n4\n]; })", options: ["never"] }, + { code: "obj['for' + 'Each'](function(item) { return [\n1,\n2,\n3,\n4\n]; })", options: ["never"] }, + { code: "obj['for' + 'Each'](function(item) { return [\n1,\n2,\n3,\n4\n]; })", options: ["never"] }, + { code: "var arr = [1, 2, 3, 4];", options: ["never"] }, + { code: "var arr = [[1, 2], 2, 3, 4];", options: ["never"] }, + { code: "var arr = [\n1, 2, 3, 4\n];", options: ["never"] }, + { code: "obj[\nfoo]", options: ["never"] }, + { code: "obj[foo\n]", options: ["never"] }, + { code: "var arr = [1,\n2,\n3,\n4\n];", options: ["never"] }, + { code: "var arr = [\n1,\n2,\n3,\n4];", options: ["never"] }, + + // never - destructuring assignment + { code: "var [x, y] = z", ecmaFeatures: { destructuring: true }, options: ["never"] }, + { code: "var [x,y] = z", ecmaFeatures: { destructuring: true }, options: ["never"] }, + { code: "var [x, y\n] = z", ecmaFeatures: { destructuring: true }, options: ["never"] }, + { code: "var [\nx, y] = z", ecmaFeatures: { destructuring: true }, options: ["never"] }, + { code: "var [\nx, y\n] = z", ecmaFeatures: { destructuring: true }, options: ["never"] }, + { code: "var [\nx, y\n] = z", ecmaFeatures: { destructuring: true }, options: ["never"] }, + { code: "var [\nx,,,\n] = z", ecmaFeatures: { destructuring: true }, options: ["never"] }, + { code: "var [,x,] = z", ecmaFeatures: { destructuring: true }, options: ["never"] }, + { code: "var [\nx, ...y\n] = z", ecmaFeatures: { destructuring: true, spread:true }, options: ["never"] }, + { code: "var [\nx, ...y] = z", ecmaFeatures: { destructuring: true, spread:true }, options: ["never"] }, + { code: "var [ [x, y], z] = arr;", ecmaFeatures: { destructuring: true }, options: ["never", {"arraysInArrays": true}] }, + { code: "var [x, [y, z] ] = arr;", ecmaFeatures: { destructuring: true }, options: ["never", {"arraysInArrays": true}] }, + { code: "[ { x, y }, z] = arr;", ecmaFeatures: { destructuring: true }, options: ["never", {objectsInArrays: true}] }, + { code: "[x, { y, z } ] = arr;", ecmaFeatures: { destructuring: true }, options: ["never", {objectsInArrays: true}] }, + + // never - singleValue + { code: "var foo = [ 'foo' ]", options: ["never", {singleValue: true}] }, + { code: "var foo = [ 2 ]", options: ["never", {singleValue: true}] }, + { code: "var foo = [ [1, 1] ]", options: ["never", {singleValue: true}] }, + { code: "var foo = [ {'foo': 'bar'} ]", options: ["never", {singleValue: true}] }, + { code: "var foo = [ bar ]", options: ["never", {singleValue: true}] }, + + // never - objectsInArrays + { code: "var foo = [ {'bar': 'baz'}, 1, 5];", options: ["never", {objectsInArrays: true}] }, + { code: "var foo = [1, 5, {'bar': 'baz'} ];", options: ["never", {objectsInArrays: true}] }, + { code: "var foo = [ {\n'bar': 'baz', \n'qux': [ {'bar': 'baz'} ], \n'quxx': 1 \n} ]", options: ["never", {objectsInArrays: true}] }, + { code: "var foo = [ {'bar': 'baz'} ]", options: ["never", {objectsInArrays: true}] }, + { code: "var foo = [ {'bar': 'baz'}, 1, {'bar': 'baz'} ];", options: ["never", {objectsInArrays: true}] }, + { code: "var foo = [1, {'bar': 'baz'} , 5];", options: ["never", {objectsInArrays: true}] }, + { code: "var foo = [1, {'bar': 'baz'}, [ {'bar': 'baz'} ]];", options: ["never", {objectsInArrays: true}] }, + { code: "var foo = [function(){}];", options: ["never", {objectsInArrays: true}] }, + { code: "var foo = [];", options: ["never", {objectsInArrays: true}] }, + + // never - arraysInArrays + { code: "var arr = [ [1, 2], 2, 3, 4];", options: ["never", {"arraysInArrays": true}] }, + { code: "var foo = [arr[i], arr[j]];", options: ["never", {"arraysInArrays": true}] }, + { code: "var foo = [];", options: ["never", {"arraysInArrays": true}] }, + + // never - arraysInArrays, singleValue + { code: "var arr = [ [1, 2], [ [ [ 1 ] ] ], 3, 4];", options: ["never", {"arraysInArrays": true, singleValue: true}] }, + + // never - arraysInArrays, objectsInArrays + { code: "var arr = [ [1, 2], 2, 3, {'foo': 'bar'} ];", options: ["never", {"arraysInArrays": true, objectsInArrays: true}] }, + + // should not warn + { code: "var foo = {};", options: ["never"] }, + { code: "var foo = [];", options: ["never"] }, + + { code: "var foo = [{'bar':'baz'}, 1, {'bar': 'baz'}];", options: ["never"] }, + { code: "var foo = [{'bar': 'baz'}];", options: ["never"] }, + { code: "var foo = [{\n'bar': 'baz', \n'qux': [{'bar': 'baz'}], \n'quxx': 1 \n}]", options: ["never"] }, + { code: "var foo = [1, {'bar': 'baz'}, 5];", options: ["never"] }, + { code: "var foo = [{'bar': 'baz'}, 1, 5];", options: ["never"] }, + { code: "var foo = [1, 5, {'bar': 'baz'}];", options: ["never"] }, + { code: "var obj = {'foo': [1, 2]}", options: ["never"] }, + + // Babel test cases. + // always - destructuring typed array param + { code: "function fn([ a,b ]: Array){}", options: ["always"], parser: "babel-eslint", ecmaFeatures: { destructuring: true } }, + + // never - destructuring typed array param + { code: "function fn([a,b]: Array){}", options: ["never"], parser: "babel-eslint", ecmaFeatures: { destructuring: true } }, + + ], + + invalid: [ + { + code: "var foo = [ ]", + output: "var foo = []", + options: ["never"], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression", + line: 1, + column: 11 + } + ] + }, + // objectsInArrays + { + code: "var foo = [ { 'bar': 'baz' }, 1, 5];", + output: "var foo = [{ 'bar': 'baz' }, 1, 5 ];", + options: ["always", {objectsInArrays: false}], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression", + line: 1, + column: 11 + }, + { + message: "A space is required before ']'", + type: "ArrayExpression", + line: 1, + column: 36 + } + ] + }, + { + code: "var foo = [1, 5, { 'bar': 'baz' } ];", + output: "var foo = [ 1, 5, { 'bar': 'baz' }];", + options: ["always", {objectsInArrays: false}], + errors: [ + { + message: "A space is required after '['", + type: "ArrayExpression", + line: 1, + column: 11 + }, + { + message: "There should be no space before ']'", + type: "ArrayExpression", + line: 1, + column: 35 + } + ] + }, + { + code: "var foo = [ { 'bar':'baz' }, 1, { 'bar': 'baz' } ];", + output: "var foo = [{ 'bar':'baz' }, 1, { 'bar': 'baz' }];", + options: ["always", {objectsInArrays: false}], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression", + line: 1, + column: 11 + }, + { + message: "There should be no space before ']'", + type: "ArrayExpression", + line: 1, + column: 50 + } + ] + }, + + // singleValue + { + code: "var obj = [ 'foo' ];", + output: "var obj = ['foo'];", + options: ["always", {singleValue: false}], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression", + line: 1, + column: 11 + }, + { + message: "There should be no space before ']'", + type: "ArrayExpression", + line: 1, + column: 19 + } + ] + }, + { + code: "var obj = ['foo' ];", + output: "var obj = ['foo'];", + options: ["always", {singleValue: false}], + errors: [ + { + message: "There should be no space before ']'", + type: "ArrayExpression", + line: 1, + column: 18 + } + ] + }, + { + code: "var obj = ['foo'];", + output: "var obj = [ 'foo' ];", + options: ["never", {singleValue: true}], + errors: [ + { + message: "A space is required after '['", + type: "ArrayExpression", + line: 1, + column: 11 + }, + { + message: "A space is required before ']'", + type: "ArrayExpression", + line: 1, + column: 17 + } + ] + }, + + // always - arraysInArrays + { + code: "var arr = [ [ 1, 2 ], 2, 3, 4 ];", + output: "var arr = [[ 1, 2 ], 2, 3, 4 ];", + options: ["always", {"arraysInArrays": false}], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression", + line: 1, + column: 11 + } + ] + }, + { + code: "var arr = [ 1, 2, 2, [ 3, 4 ] ];", + output: "var arr = [ 1, 2, 2, [ 3, 4 ]];", + options: ["always", {"arraysInArrays": false}], + errors: [ + { + message: "There should be no space before ']'", + type: "ArrayExpression", + line: 1, + column: 31 + } + ] + }, + { + code: "var arr = [[ 1, 2 ], 2, [ 3, 4 ] ];", + output: "var arr = [[ 1, 2 ], 2, [ 3, 4 ]];", + options: ["always", {"arraysInArrays": false}], + errors: [ + { + message: "There should be no space before ']'", + type: "ArrayExpression", + line: 1, + column: 34 + } + ] + }, + { + code: "var arr = [ [ 1, 2 ], 2, [ 3, 4 ]];", + output: "var arr = [[ 1, 2 ], 2, [ 3, 4 ]];", + options: ["always", {"arraysInArrays": false}], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression", + line: 1, + column: 11 + } + ] + }, + { + code: "var arr = [ [ 1, 2 ], 2, [ 3, 4 ] ];", + output: "var arr = [[ 1, 2 ], 2, [ 3, 4 ]];", + options: ["always", {"arraysInArrays": false}], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression", + line: 1, + column: 11 + }, + { + message: "There should be no space before ']'", + type: "ArrayExpression", + line: 1, + column: 35 + } + ] + }, + + // always - destructuring + { + code: "var [x,y] = y", + output: "var [ x,y ] = y", + options: ["always"], + ecmaFeatures: { destructuring: true }, + errors: [{ + message: "A space is required after '['", + type: "ArrayPattern", + line: 1, + column: 5 + }, + { + message: "A space is required before ']'", + type: "ArrayPattern", + line: 1, + column: 9 + }] + }, + { + code: "var [x,y ] = y", + output: "var [ x,y ] = y", + options: ["always"], + ecmaFeatures: { destructuring: true }, + errors: [{ + message: "A space is required after '['", + type: "ArrayPattern", + line: 1, + column: 5 + }] + }, + { + code: "var [,,,x,,] = y", + output: "var [ ,,,x,, ] = y", + options: ["always"], + ecmaFeatures: { destructuring: true }, + errors: [{ + message: "A space is required after '['", + type: "ArrayPattern", + line: 1, + column: 5 + }, + { + message: "A space is required before ']'", + type: "ArrayPattern", + line: 1, + column: 12 + }] + }, + { + code: "var [ ,,,x,,] = y", + output: "var [ ,,,x,, ] = y", + options: ["always"], + ecmaFeatures: { destructuring: true }, + errors: [{ + message: "A space is required before ']'", + type: "ArrayPattern", + line: 1, + column: 13 + }] + }, + { + code: "var [...horse] = y", + output: "var [ ...horse ] = y", + options: ["always"], + ecmaFeatures: { destructuring: true, spread:true }, + errors: [{ + message: "A space is required after '['", + type: "ArrayPattern", + line: 1, + column: 5 + }, + { + message: "A space is required before ']'", + type: "ArrayPattern", + line: 1, + column: 14 + }] + }, + { + code: "var [...horse ] = y", + output: "var [ ...horse ] = y", + options: ["always"], + ecmaFeatures: { destructuring: true, spread:true }, + errors: [{ + message: "A space is required after '['", + type: "ArrayPattern", + line: 1, + column: 5 + }] + }, + { + code: "var [ [ x, y ], z ] = arr;", + output: "var [[ x, y ], z ] = arr;", + options: ["always", {"arraysInArrays": false}], + ecmaFeatures: { destructuring: true }, + errors: [{ + message: "There should be no space after '['", + type: "ArrayPattern", + line: 1, + column: 5 + }] + }, + { + code: "[ { x, y }, z ] = arr;", + output: "[{ x, y }, z ] = arr;", + options: ["always", {"objectsInArrays": false}], + ecmaFeatures: { destructuring: true }, + errors: [{ + message: "There should be no space after '['", + type: "ArrayPattern", + line: 1, + column: 1 + }] + }, + { + code: "[ x, { y, z } ] = arr;", + output: "[ x, { y, z }] = arr;", + options: ["always", {"objectsInArrays": false}], + ecmaFeatures: { destructuring: true }, + errors: [{ + message: "There should be no space before ']'", + type: "ArrayPattern", + line: 1, + column: 15 + }] + }, + + // never - arraysInArrays + { + code: "var arr = [[1, 2], 2, [3, 4]];", + output: "var arr = [ [1, 2], 2, [3, 4] ];", + options: ["never", {"arraysInArrays": true}], + errors: [ + { + message: "A space is required after '['", + type: "ArrayExpression", + line: 1, + column: 11 + }, + { + message: "A space is required before ']'", + type: "ArrayExpression", + line: 1, + column: 29 + } + ] + }, + { + code: "var arr = [ ];", + output: "var arr = [];", + options: ["never", {"arraysInArrays": true}], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression", + line: 1, + column: 11 + } + ] + }, + + // never - objectsInArrays + { + code: "var arr = [ ];", + output: "var arr = [];", + options: ["never", {"objectsInArrays": true}], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression", + line: 1, + column: 11 + } + ] + }, + + // always + { + code: "var arr = [1, 2, 3, 4];", + output: "var arr = [ 1, 2, 3, 4 ];", + options: ["always"], + errors: [ + { + message: "A space is required after '['", + type: "ArrayExpression", + line: 1, + column: 11 + }, + { + message: "A space is required before ']'", + type: "ArrayExpression", + line: 1, + column: 22 + } + ] + }, + { + code: "var arr = [1, 2, 3, 4 ];", + output: "var arr = [ 1, 2, 3, 4 ];", + options: ["always"], + errors: [ + { + message: "A space is required after '['", + type: "ArrayExpression", + line: 1, + column: 11 + } + ] + }, + { + code: "var arr = [ 1, 2, 3, 4];", + output: "var arr = [ 1, 2, 3, 4 ];", + options: ["always"], + errors: [ + { + message: "A space is required before ']'", + type: "ArrayExpression", + line: 1, + column: 23 + } + ] + }, + + // never + { + code: "var arr = [ 1, 2, 3, 4 ];", + output: "var arr = [1, 2, 3, 4];", + options: ["never"], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression", + line: 1, + column: 11 + }, + { + message: "There should be no space before ']'", + type: "ArrayExpression", + line: 1, + column: 24 + } + ] + }, + { + code: "var arr = [1, 2, 3, 4 ];", + output: "var arr = [1, 2, 3, 4];", + options: ["never"], + errors: [ + { + message: "There should be no space before ']'", + type: "ArrayExpression", + line: 1, + column: 23 + } + ] + }, + { + code: "var arr = [ 1, 2, 3, 4];", + output: "var arr = [1, 2, 3, 4];", + options: ["never"], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression", + line: 1, + column: 11 + } + ] + }, + { + code: "var arr = [ [ 1], 2, 3, 4];", + output: "var arr = [[1], 2, 3, 4];", + options: ["never"], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression", + line: 1, + column: 11 + }, + { + message: "There should be no space after '['", + type: "ArrayExpression", + line: 1, + column: 13 + } + ] + }, + { + code: "var arr = [[1 ], 2, 3, 4 ];", + output: "var arr = [[1], 2, 3, 4];", + options: ["never"], + errors: [ + { + message: "There should be no space before ']'", + type: "ArrayExpression", + line: 1, + column: 15 + }, + { + message: "There should be no space before ']'", + type: "ArrayExpression", + line: 1, + column: 26 + } + ] + }, + + // Babel test cases. + + // always - destructuring typed array param + { + code: "function fn([a,b]: Array){}", + output: "function fn([ a,b ]: Array){}", + options: ["always"], + parser: "babel-eslint", + ecmaFeatures: { + destructuring: true + }, + errors: [ + { + message: "A space is required after '['", + type: "ArrayPattern", + line: 1, + column: 13 + }, + { + message: "A space is required before ']'", + type: "ArrayPattern", + line: 1, + column: 17 + } + ] + }, + + // never - destructuring typed array param + { + code: "function fn([ a,b ]: Array){}", + output: "function fn([a,b]: Array){}", + options: ["never"], + parser: "babel-eslint", + ecmaFeatures: { + destructuring: true + }, + errors: [ + { + message: "There should be no space after '['", + type: "ArrayPattern", + line: 1, + column: 13 + }, + { + message: "There should be no space before ']'", + type: "ArrayPattern", + line: 1, + column: 19 + } + ] + } + ] +});