diff --git a/eslint/babel-eslint-plugin/README.md b/eslint/babel-eslint-plugin/README.md index e291617388..997a6148aa 100644 --- a/eslint/babel-eslint-plugin/README.md +++ b/eslint/babel-eslint-plugin/README.md @@ -28,6 +28,7 @@ Finally enable all the rules you like to use (remember to disable the originals "babel/generator-star": 1, "babel/generator-star-spacing": 1, "babel/new-cap": 1, + "babel/space-in-brackets": 1, } } ``` @@ -40,3 +41,4 @@ Each rule cooresponds to a core eslint rule, and has the same options. - `babel/generator-star`: Handles async/await functions correctly - `babel/generator-star-spacing`: Handles async/await functions correctly - `babel/new-cap`: Ignores capitalized decorators (`@Decorator`) +- `babel/space-in-brackets`: doesn't complain about `export x from "mod";` or `export * as x from "mod";` diff --git a/eslint/babel-eslint-plugin/index.js b/eslint/babel-eslint-plugin/index.js index 8bfde48f91..a486a4c120 100644 --- a/eslint/babel-eslint-plugin/index.js +++ b/eslint/babel-eslint-plugin/index.js @@ -6,13 +6,15 @@ module.exports = { 'object-shorthand': require('./rules/object-shorthand'), 'generator-star-spacing': require('./rules/generator-star-spacing'), 'generator-star': require('./rules/generator-star'), - 'new-cap': require('./rules/new-cap') + 'new-cap': require('./rules/new-cap'), + 'space-in-brackets': require('./rules/space-in-brackets'), }, rulesConfig: { 'block-scoped-var': 0, 'generator-star-spacing': 0, 'generator-star': 0, 'object-shorthand': 0, - 'new-cap': 0 + 'new-cap': 0, + 'space-in-brackets': 0 } }; diff --git a/eslint/babel-eslint-plugin/rules/space-in-brackets.js b/eslint/babel-eslint-plugin/rules/space-in-brackets.js new file mode 100644 index 0000000000..566ac351e8 --- /dev/null +++ b/eslint/babel-eslint-plugin/rules/space-in-brackets.js @@ -0,0 +1,309 @@ +/** + * @fileoverview Disallows or enforces spaces inside of brackets. + * @author Ian Christian Myers + * @copyright 2015 Mathieu M-Gosselin. 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"; + + /** + * 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] != null ? context.options[1][option] === !spaced : false; + } + + var options = { + spaced: spaced, + singleElementException: isOptionSet("singleValue"), + objectsInArraysException: isOptionSet("objectsInArrays"), + arraysInArraysException: isOptionSet("arraysInArrays"), + arraysInObjectsException: isOptionSet("arraysInObjects"), + objectsInObjectsException: isOptionSet("objectsInObjects"), + propertyNameException: isOptionSet("propertyName") + }; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Determines whether two adjacent tokens are have whitespace between them. + * @param {Object} left - The left token object. + * @param {Object} right - The right token object. + * @returns {boolean} Whether or not there is space between the tokens. + */ + function isSpaced(left, right) { + return left.range[1] < right.range[0]; + } + + /** + * 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, token.loc.start, + "There should be no space after '" + token.value + "'"); + } + + /** + * 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, token.loc.start, + "There should be no space before '" + token.value + "'"); + } + + /** + * 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, token.loc.start, + "A space is required after '" + token.value + "'"); + } + + /** + * 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, token.loc.start, + "A space is required before '" + token.value + "'"); + } + + + /** + * Determines if spacing in curly braces is valid. + * @param {ASTNode} node The AST node to check. + * @param {Token} first The first token to check (should be the opening brace) + * @param {Token} second The second token to check (should be first after the opening brace) + * @param {Token} penultimate The penultimate token to check (should be last before closing brace) + * @param {Token} last The last token to check (should be closing brace) + * @returns {void} + */ + function validateBraceSpacing(node, first, second, penultimate, last) { + var closingCurlyBraceMustBeSpaced = + options.arraysInObjectsException && penultimate.value === "]" || + options.objectsInObjectsException && penultimate.value === "}" + ? !options.spaced : options.spaced; + + if (isSameLine(first, second)) { + if (options.spaced && !isSpaced(first, second)) { + reportRequiredBeginningSpace(node, first); + } + if (!options.spaced && isSpaced(first, second)) { + reportNoBeginningSpace(node, first); + } + } + + if (isSameLine(penultimate, last)) { + if (closingCurlyBraceMustBeSpaced && !isSpaced(penultimate, last)) { + reportRequiredEndingSpace(node, last); + } + if (!closingCurlyBraceMustBeSpaced && isSpaced(penultimate, last)) { + reportNoEndingSpace(node, last); + } + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + MemberExpression: function(node) { + if (!node.computed) { + return; + } + + var property = node.property, + before = context.getTokenBefore(property), + first = context.getFirstToken(property), + last = context.getLastToken(property), + after = context.getTokenAfter(property); + + var propertyNameMustBeSpaced = options.propertyNameException ? + !options.spaced : options.spaced; + + if (isSameLine(before, first)) { + if (propertyNameMustBeSpaced) { + if (!isSpaced(before, first) && isSameLine(before, first)) { + reportRequiredBeginningSpace(node, before); + } + } else { + if (isSpaced(before, first)) { + reportNoBeginningSpace(node, before); + } + } + } + + if (isSameLine(last, after)) { + if (propertyNameMustBeSpaced) { + if (!isSpaced(last, after) && isSameLine(last, after)) { + reportRequiredEndingSpace(node, after); + } + } else { + if (isSpaced(last, after)) { + reportNoEndingSpace(node, after); + } + } + } + }, + + ArrayExpression: function(node) { + if (node.elements.length === 0) { + return; + } + + var first = context.getFirstToken(node), + second = context.getFirstToken(node, 1), + penultimate = context.getLastToken(node, 1), + last = context.getLastToken(node); + + var openingBracketMustBeSpaced = + options.objectsInArraysException && second.value === "{" || + options.arraysInArraysException && second.value === "[" || + options.singleElementException && node.elements.length === 1 + ? !options.spaced : options.spaced; + + var closingBracketMustBeSpaced = + options.objectsInArraysException && penultimate.value === "}" || + options.arraysInArraysException && penultimate.value === "]" || + options.singleElementException && node.elements.length === 1 + ? !options.spaced : options.spaced; + + if (isSameLine(first, second)) { + if (openingBracketMustBeSpaced && !isSpaced(first, second)) { + reportRequiredBeginningSpace(node, first); + } + if (!openingBracketMustBeSpaced && isSpaced(first, second)) { + reportNoBeginningSpace(node, first); + } + } + + if (isSameLine(penultimate, last)) { + if (closingBracketMustBeSpaced && !isSpaced(penultimate, last)) { + reportRequiredEndingSpace(node, last); + } + if (!closingBracketMustBeSpaced && isSpaced(penultimate, last)) { + reportNoEndingSpace(node, last); + } + } + }, + + ImportDeclaration: function(node) { + + var firstSpecifier = node.specifiers[0], + lastSpecifier = node.specifiers[node.specifiers.length - 1]; + + // don't do anything for namespace or default imports + if (firstSpecifier && lastSpecifier && firstSpecifier.type === "ImportSpecifier" && lastSpecifier.type === "ImportSpecifier") { + var first = context.getTokenBefore(firstSpecifier), + second = context.getFirstToken(firstSpecifier), + penultimate = context.getLastToken(lastSpecifier), + last = context.getTokenAfter(lastSpecifier); + + validateBraceSpacing(node, first, second, penultimate, last); + } + + }, + + ExportNamedDeclaration: function(node) { + if (!node.specifiers.length) { + return; + } + + var firstSpecifier = node.specifiers[0], + lastSpecifier = node.specifiers[node.specifiers.length - 1], + first = context.getTokenBefore(firstSpecifier), + second = context.getFirstToken(firstSpecifier), + penultimate = context.getLastToken(lastSpecifier), + last = context.getTokenAfter(lastSpecifier); + + if (first.value === "export") { + return; + } + + validateBraceSpacing(node, first, second, penultimate, last); + }, + + ObjectExpression: function(node) { + if (node.properties.length === 0) { + return; + } + + var first = context.getFirstToken(node), + second = context.getFirstToken(node, 1), + penultimate = context.getLastToken(node, 1), + last = context.getLastToken(node); + + validateBraceSpacing(node, first, second, penultimate, last); + } + + }; + +}; + +module.exports.schema = [ + { + "enum": ["always", "never"] + }, + { + "type": "object", + "properties": { + "singleValue": { + "type": "boolean" + }, + "objectsInArrays": { + "type": "boolean" + }, + "arraysInArrays": { + "type": "boolean" + }, + "arraysInObjects": { + "type": "boolean" + }, + "objectsInObjects": { + "type": "boolean" + }, + "propertyName": { + "type": "boolean" + } + }, + "additionalProperties": false + } +]; diff --git a/eslint/babel-eslint-plugin/tests/space-in-brackets.js b/eslint/babel-eslint-plugin/tests/space-in-brackets.js new file mode 100644 index 0000000000..106120dd80 --- /dev/null +++ b/eslint/babel-eslint-plugin/tests/space-in-brackets.js @@ -0,0 +1,761 @@ +/* eslint-disable */ + +/** + * @fileoverview Disallows or enforces spaces inside of brackets. + * @author Ian Christian Myers + * @copyright 2014 Vignesh Anand. All rights reserved. + */ + +var linter = require('eslint').linter + , ESLintTester = require('eslint-tester') + , eslintTester = new ESLintTester(linter); + +eslintTester.addRuleTest("rules/space-in-brackets", { + + 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}] }, + + // 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}] }, + + // 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 - arraysInObjects + { code: "var obj = { 'foo': [ 1, 2 ]};", options: ["always", {"arraysInObjects": false}] }, + + // always - objectsInObjects + { code: "var obj = { 'foo': { 'bar': 1, 'baz': 2 }};", options: ["always", {"objectsInObjects": false}] }, + + // always - arraysInObjects, objectsInObjects + { code: "var obj = { 'qux': [ 1, 2 ], 'foo': { 'bar': 1, 'baz': 2 }};", options: ["always", {"arraysInObjects": false, "objectsInObjects": false}] }, + + // always - arraysInObjects, objectsInObjects (reverse) + { code: "var obj = { 'foo': { 'bar': 1, 'baz': 2 }, 'qux': [ 1, 2 ]};", options: ["always", {"arraysInObjects": false, "objectsInObjects": 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 obj = { foo: bar, baz: qux };", options: ["always"] }, + { code: "var obj = { foo: { bar: quxx }, baz: qux };", options: ["always"] }, + { code: "var obj = {\nfoo: bar,\nbaz: qux\n};", options: ["always"] }, + + { code: "var foo = {};", options: ["always"] }, + { code: "var foo = [];", options: ["always"] }, + + { 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}] }, + + // 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[ obj2[ foo ] ]", options: ["never", {"propertyName": true}] }, + { code: "obj['for' + 'Each'](function (item) { return [\n1,\n2,\n3,\n4\n]; })", options: ["never"] }, + + + { code: "obj[\nfoo]", options: ["never"] }, + { code: "obj[foo\n]", options: ["never"] }, + { code: "var obj = {foo: bar,\nbaz: qux\n};", options: ["never"] }, + { code: "var obj = {\nfoo: bar,\nbaz: qux};", options: ["never"] }, + { code: "var arr = [1,\n2,\n3,\n4\n];", options: ["never"] }, + { code: "var arr = [\n1,\n2,\n3,\n4];", options: ["never"] }, + + // 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}] }, + + // never - arraysInArrays + { code: "var arr = [ [1, 2], 2, 3, 4];", 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}] }, + + { 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: "var obj = {foo: bar, baz: qux};", options: ["never"] }, + { code: "var obj = {foo: {bar: quxx}, baz: qux};", options: ["never"] }, + { code: "var obj = {\nfoo: bar,\nbaz: qux\n};", options: ["never"] }, + + { 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"] }, + + // propertyName: false + { code: "var foo = obj[1]", options: ["always", {propertyName: false}] }, + { code: "var foo = obj['foo'];", options: ["always", {propertyName: false}] }, + { code: "var foo = obj[[ 1, 1 ]];", options: ["always", {propertyName: false}] }, + + { code: "var foo = obj[ 1 ]", options: ["never", {propertyName: true}] }, + { code: "var foo = obj[ 'foo' ];", options: ["never", {propertyName: true}] }, + { code: "var foo = obj[ [1, 1] ];", options: ["never", {propertyName: true}] }, + { code: "import 'test.js';", ecmaFeatures: { modules: true } }, + { code: "export const thing = {\n value: 1 \n};", ecmaFeatures: { modules: true, blockBindings: true } }, + { code: "export const thing = {};", ecmaFeatures: { modules: true, blockBindings: true } }, + { code: "export let thing = {};", ecmaFeatures: { modules: true, blockBindings: true } }, + { code: "export var thing = {};", ecmaFeatures: { modules: true } }, + + // Babel test cases. + { code: "export * as x from \"mod\";", parser: "babel-eslint", ecmaFeatures: { modules: true } }, + { code: "export x from \"mod\";", parser: "babel-eslint", ecmaFeatures: { modules: true } }, + ], + + invalid: [ + // objectsInArrays + { + code: "var foo = [ { 'bar': 'baz' }, 1, 5];", + options: ["always", {objectsInArrays: false}], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression" + }, + { + message: "A space is required before ']'", + type: "ArrayExpression" + } + ] + }, + { + code: "import {bar} from 'foo.js';", + options: ["always"], + ecmaFeatures: { + modules: true + }, + errors: [ + { + message: "A space is required after '{'", + type: "ImportDeclaration" + }, + { + message: "A space is required before '}'", + type: "ImportDeclaration" + } + ] + }, + { + code: "export {bar};", + options: ["always"], + ecmaFeatures: { + modules: true + }, + errors: [ + { + message: "A space is required after '{'", + type: "ExportNamedDeclaration" + }, + { + message: "A space is required before '}'", + type: "ExportNamedDeclaration" + } + ] + }, + { + code: "var foo = [1, 5, { 'bar': 'baz' } ];", + options: ["always", {objectsInArrays: false}], + errors: [ + { + message: "A space is required after '['", + type: "ArrayExpression" + }, + { + message: "There should be no space before ']'", + type: "ArrayExpression" + } + ] + }, + { + code: "var foo = [ { 'bar':'baz' }, 1, { 'bar': 'baz' } ];", + options: ["always", {objectsInArrays: false}], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression" + }, + { + message: "There should be no space before ']'", + type: "ArrayExpression" + } + ] + }, + + // singleValue + { + code: "var obj = [ 'foo' ];", + options: ["always", {singleValue: false}], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression" + }, + { + message: "There should be no space before ']'", + type: "ArrayExpression" + } + ] + }, + { + code: "var obj = ['foo' ];", + options: ["always", {singleValue: false}], + errors: [ + { + message: "There should be no space before ']'", + type: "ArrayExpression" + } + ] + }, + // singleValue + { + code: "var obj = ['foo'];", + options: ["never", {singleValue: true}], + errors: [ + { + message: "A space is required after '['", + type: "ArrayExpression" + }, + { + message: "A space is required before ']'", + type: "ArrayExpression" + } + ] + }, + { + code: "var foo = obj[ 1];", + options: ["always"], + errors: [ + { + message: "A space is required before ']'", + type: "MemberExpression" + } + ] + }, + { + code: "var foo = obj[1 ];", + options: ["always"], + errors: [ + { + message: "A space is required after '['", + type: "MemberExpression" + } + ] + }, + // propertyName + { + code: "var foo = obj[ 1];", + options: ["always", {propertyName: false}], + errors: [ + { + message: "There should be no space after '['", + type: "MemberExpression" + } + ] + }, + { + code: "var foo = obj[1 ];", + options: ["always", {propertyName: false}], + errors: [ + { + message: "There should be no space before ']'", + type: "MemberExpression" + } + ] + }, + { + code: "var foo = obj[ 1];", + options: ["never", {propertyName: true}], + errors: [ + { + message: "A space is required before ']'", + type: "MemberExpression" + } + ] + }, + { + code: "var foo = obj[1 ];", + options: ["never", {propertyName: true}], + errors: [ + { + message: "A space is required after '['", + type: "MemberExpression" + } + ] + }, + + // always - arraysInArrays + { + code: "var arr = [ [ 1, 2 ], 2, 3, 4 ];", + options: ["always", {"arraysInArrays": false}], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression" + } + ] + }, + { + code: "var arr = [ 1, 2, 2, [ 3, 4 ] ];", + options: ["always", {"arraysInArrays": false}], + errors: [ + { + message: "There should be no space before ']'", + type: "ArrayExpression" + } + ] + }, + { + code: "var arr = [[ 1, 2 ], 2, [ 3, 4 ] ];", + options: ["always", {"arraysInArrays": false}], + errors: [ + { + message: "There should be no space before ']'", + type: "ArrayExpression" + } + ] + }, + { + code: "var arr = [ [ 1, 2 ], 2, [ 3, 4 ]];", + options: ["always", {"arraysInArrays": false}], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression" + } + ] + }, + { + code: "var arr = [ [ 1, 2 ], 2, [ 3, 4 ] ];", + options: ["always", {"arraysInArrays": false}], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression" + }, + { + message: "There should be no space before ']'", + type: "ArrayExpression" + } + ] + }, + + // never - arraysInArrays + { + code: "var arr = [[1, 2], 2, [3, 4]];", + options: ["never", {"arraysInArrays": true}], + errors: [ + { + message: "A space is required after '['", + type: "ArrayExpression" + }, + { + message: "A space is required before ']'", + type: "ArrayExpression" + } + ] + }, + + // always - arraysInObjects + { + code: "var obj = { 'foo': [ 1, 2 ] };", + options: ["always", {"arraysInObjects": false}], + errors: [ + { + message: "There should be no space before '}'", + type: "ObjectExpression" + } + ] + }, + { + code: "var obj = { 'foo': [ 1, 2 ] , 'bar': [ 'baz', 'qux' ] };", + options: ["always", {"arraysInObjects": false}], + errors: [ + { + message: "There should be no space before '}'", + type: "ObjectExpression" + } + ] + }, + + // never - arraysInObjects + { + code: "var obj = {'foo': [1, 2]};", + options: ["never", {"arraysInObjects": true}], + errors: [ + { + message: "A space is required before '}'", + type: "ObjectExpression" + } + ] + }, + { + code: "var obj = {'foo': [1, 2] , 'bar': ['baz', 'qux']};", + options: ["never", {"arraysInObjects": true}], + errors: [ + { + message: "A space is required before '}'", + type: "ObjectExpression" + } + ] + }, + + // always-objectsInObjects + { + code: "var obj = { 'foo': { 'bar': 1, 'baz': 2 } };", + options: ["always", {"objectsInObjects": false}], + errors: [ + { + message: "There should be no space before '}'", + type: "ObjectExpression" + } + ] + }, + { + code: "var obj = { 'foo': [ 1, 2 ] , 'bar': { 'baz': 1, 'qux': 2 } };", + options: ["always", {"objectsInObjects": false}], + errors: [ + { + message: "There should be no space before '}'", + type: "ObjectExpression" + } + ] + }, + + // never-objectsInObjects + { + code: "var obj = {'foo': {'bar': 1, 'baz': 2}};", + options: ["never", {"objectsInObjects": true}], + errors: [ + { + message: "A space is required before '}'", + type: "ObjectExpression" + } + ] + }, + { + code: "var obj = {'foo': [1, 2] , 'bar': {'baz': 1, 'qux': 2}};", + options: ["never", {"objectsInObjects": true}], + errors: [ + { + message: "A space is required before '}'", + type: "ObjectExpression" + } + ] + }, + + // always & never + { + code: "var obj = {foo: bar, baz: qux};", + options: ["always"], + errors: [ + { + message: "A space is required after '{'", + type: "ObjectExpression" + }, + { + message: "A space is required before '}'", + type: "ObjectExpression" + } + ] + }, + { + code: "var obj = {foo: bar, baz: qux };", + options: ["always"], + errors: [ + { + message: "A space is required after '{'", + type: "ObjectExpression" + } + ] + }, + { + code: "var obj = { foo: bar, baz: qux};", + options: ["always"], + errors: [ + { + message: "A space is required before '}'", + type: "ObjectExpression" + } + ] + }, + { + code: "var obj = { foo: bar, baz: qux };", + options: ["never"], + errors: [ + { + message: "There should be no space after '{'", + type: "ObjectExpression" + }, + { + message: "There should be no space before '}'", + type: "ObjectExpression" + } + ] + }, + { + code: "var obj = {foo: bar, baz: qux };", + options: ["never"], + errors: [ + { + message: "There should be no space before '}'", + type: "ObjectExpression" + } + ] + }, + { + code: "var obj = { foo: bar, baz: qux};", + options: ["never"], + errors: [ + { + message: "There should be no space after '{'", + type: "ObjectExpression" + } + ] + }, + { + code: "var obj = { foo: { bar: quxx}, baz: qux};", + options: ["never"], + errors: [ + { + message: "There should be no space after '{'", + type: "ObjectExpression" + }, + { + message: "There should be no space after '{'", + type: "ObjectExpression" + } + ] + }, + { + code: "var obj = {foo: {bar: quxx }, baz: qux };", + options: ["never"], + errors: [ + { + message: "There should be no space before '}'", + type: "ObjectExpression" + }, + { + message: "There should be no space before '}'", + type: "ObjectExpression" + } + ] + }, + { + code: "var arr = [1, 2, 3, 4];", + options: ["always"], + errors: [ + { + message: "A space is required after '['", + type: "ArrayExpression" + }, + { + message: "A space is required before ']'", + type: "ArrayExpression" + } + ] + }, + { + code: "var arr = [1, 2, 3, 4 ];", + options: ["always"], + errors: [ + { + message: "A space is required after '['", + type: "ArrayExpression" + } + ] + }, + { + code: "var arr = [ 1, 2, 3, 4];", + options: ["always"], + errors: [ + { + message: "A space is required before ']'", + type: "ArrayExpression" + } + ] + }, + { + code: "var arr = [ 1, 2, 3, 4 ];", + options: ["never"], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression" + }, + { + message: "There should be no space before ']'", + type: "ArrayExpression" + } + ] + }, + { + code: "var arr = [1, 2, 3, 4 ];", + options: ["never"], + errors: [ + { + message: "There should be no space before ']'", + type: "ArrayExpression" + } + ] + }, + { + code: "var arr = [ 1, 2, 3, 4];", + options: ["never"], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression" + } + ] + }, + { + code: "var arr = [ [ 1], 2, 3, 4];", + options: ["never"], + errors: [ + { + message: "There should be no space after '['", + type: "ArrayExpression" + }, + { + message: "There should be no space after '['", + type: "ArrayExpression" + } + ] + }, + { + code: "var arr = [[1 ], 2, 3, 4 ];", + options: ["never"], + errors: [ + { + message: "There should be no space before ']'", + type: "ArrayExpression" + }, + { + message: "There should be no space before ']'", + type: "ArrayExpression" + } + ] + }, + { + code: "obj[ foo ]", + options: ["never"], + errors: [ + { + message: "There should be no space after '['", + type: "MemberExpression" + }, + { + message: "There should be no space before ']'", + type: "MemberExpression" + } + ] + }, + { + code: "obj[foo ]", + options: ["never"], + errors: [ + { + message: "There should be no space before ']'", + type: "MemberExpression" + } + ] + }, + { + code: "obj[ foo]", + options: ["never"], + errors: [ + { + message: "There should be no space after '['", + type: "MemberExpression" + } + ] + }, + { + code: "var foo = obj[1]", + options: ["always"], + errors: [ + { + message: "A space is required after '['", + type: "MemberExpression" + }, + { + message: "A space is required before ']'", + type: "MemberExpression" + } + ] + }, + { + code: "export const thing = {value: 1 };", + ecmaFeatures: { + modules: true, + blockBindings: true + }, + options: ["always"], + errors: [ + { + message: "A space is required after '{'", + type: "ObjectExpression" + } + ] + } + ] +});