From 8d7bc10a49020a2531a0f3bfc14054c29f7547ed Mon Sep 17 00:00:00 2001 From: Kiikurage Date: Sun, 12 Apr 2020 07:05:48 +0900 Subject: [PATCH 1/6] feat(eslint-plugin): implement object-curly-spacing rule (#1784) --- packages/eslint-plugin/README.md | 1 + .../docs/rules/object-curly-spacing.md | 22 ++ packages/eslint-plugin/src/configs/all.ts | 2 + packages/eslint-plugin/src/rules/index.ts | 2 + .../src/rules/object-curly-spacing.ts | 273 ++++++++++++++++++ .../tests/rules/object-curly-spacing.test.ts | 199 +++++++++++++ .../eslint-plugin/typings/eslint-rules.d.ts | 25 ++ 7 files changed, 524 insertions(+) create mode 100644 packages/eslint-plugin/docs/rules/object-curly-spacing.md create mode 100644 packages/eslint-plugin/src/rules/object-curly-spacing.ts create mode 100644 packages/eslint-plugin/tests/rules/object-curly-spacing.test.ts diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index 7c55b54aca6..3a504fe7d83 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -218,6 +218,7 @@ In these cases, we create what we call an extension rule; a rule within our plug | [`@typescript-eslint/no-unused-vars`](./docs/rules/no-unused-vars.md) | Disallow unused variables | :heavy_check_mark: | | | | [`@typescript-eslint/no-use-before-define`](./docs/rules/no-use-before-define.md) | Disallow the use of variables before they are defined | | | | | [`@typescript-eslint/no-useless-constructor`](./docs/rules/no-useless-constructor.md) | Disallow unnecessary constructors | | | | +| [`@typescript-eslint/object-curly-spacing`](./docs/rules/object-curly-spacing.md) | Enforce consistent spacing inside braces | | :wrench: | | | [`@typescript-eslint/quotes`](./docs/rules/quotes.md) | Enforce the consistent use of either backticks, double, or single quotes | | :wrench: | | | [`@typescript-eslint/require-await`](./docs/rules/require-await.md) | Disallow async functions which have no `await` expression | :heavy_check_mark: | | :thought_balloon: | | [`@typescript-eslint/return-await`](./docs/rules/return-await.md) | Enforces consistent returning of awaited values | | :wrench: | :thought_balloon: | diff --git a/packages/eslint-plugin/docs/rules/object-curly-spacing.md b/packages/eslint-plugin/docs/rules/object-curly-spacing.md new file mode 100644 index 00000000000..f64b04dc6f5 --- /dev/null +++ b/packages/eslint-plugin/docs/rules/object-curly-spacing.md @@ -0,0 +1,22 @@ +# Enforce consistent spacing inside braces (`object-curly-spacing`) + +## Rule Details + +This rule extends the base [`eslint/object-curly-spacing`](https://eslint.org/docs/rules/object-curly-spacing) rule. +It supports all options and features of the base rule. + +## How to use + +```cjson +{ + // note you must disable the base rule as it can report incorrect errors + "object-curly-spacing": "off", + "@typescript-eslint/object-curly-spacing": ["error"] +} +``` + +## Options + +See [`eslint/object-curly-spacing` options](https://eslint.org/docs/rules/object-curly-spacing#options). + +Taken with ❤️ [from ESLint core](https://github.com/eslint/eslint/blob/master/docs/rules/object-curly-spacing.md) diff --git a/packages/eslint-plugin/src/configs/all.ts b/packages/eslint-plugin/src/configs/all.ts index 36cd690afa0..98afc4ae3a4 100644 --- a/packages/eslint-plugin/src/configs/all.ts +++ b/packages/eslint-plugin/src/configs/all.ts @@ -113,6 +113,8 @@ export = { '@typescript-eslint/no-useless-constructor': 'error', '@typescript-eslint/no-var-requires': 'error', '@typescript-eslint/non-nullable-type-assertion-style': 'error', + 'object-curly-spacing': 'off', + '@typescript-eslint/object-curly-spacing': 'error', '@typescript-eslint/prefer-as-const': 'error', '@typescript-eslint/prefer-enum-initializers': 'error', '@typescript-eslint/prefer-for-of': 'error', diff --git a/packages/eslint-plugin/src/rules/index.ts b/packages/eslint-plugin/src/rules/index.ts index 1be014e46c5..ffa70e57a29 100644 --- a/packages/eslint-plugin/src/rules/index.ts +++ b/packages/eslint-plugin/src/rules/index.ts @@ -79,6 +79,7 @@ import noUseBeforeDefine from './no-use-before-define'; import noUselessConstructor from './no-useless-constructor'; import noVarRequires from './no-var-requires'; import nonNullableTypeAssertionStyle from './non-nullable-type-assertion-style'; +import objectCurlySpacing from './object-curly-spacing'; import preferAsConst from './prefer-as-const'; import preferEnumInitializers from './prefer-enum-initializers'; import preferForOf from './prefer-for-of'; @@ -195,6 +196,7 @@ export default { 'no-useless-constructor': noUselessConstructor, 'no-var-requires': noVarRequires, 'non-nullable-type-assertion-style': nonNullableTypeAssertionStyle, + 'object-curly-spacing': objectCurlySpacing, 'prefer-as-const': preferAsConst, 'prefer-enum-initializers': preferEnumInitializers, 'prefer-for-of': preferForOf, diff --git a/packages/eslint-plugin/src/rules/object-curly-spacing.ts b/packages/eslint-plugin/src/rules/object-curly-spacing.ts new file mode 100644 index 00000000000..44dcd89c41f --- /dev/null +++ b/packages/eslint-plugin/src/rules/object-curly-spacing.ts @@ -0,0 +1,273 @@ +import { + AST_NODE_TYPES, + AST_TOKEN_TYPES, + TSESTree, +} from '@typescript-eslint/experimental-utils'; +import baseRule from 'eslint/lib/rules/object-curly-spacing'; +import { + createRule, + InferMessageIdsTypeFromRule, + InferOptionsTypeFromRule, + isClosingBraceToken, + isClosingBracketToken, + isTokenOnSameLine, +} from '../util'; + +export type Options = InferOptionsTypeFromRule; +export type MessageIds = InferMessageIdsTypeFromRule; + +export default createRule({ + name: 'object-curly-spacing', + meta: { + type: 'layout', + docs: { + description: 'Enforce consistent spacing inside braces', + category: 'Stylistic Issues', + recommended: false, + extendsBaseRule: true, + }, + messages: { + requireSpaceBefore: "A space is required before '{{token}}'.", + requireSpaceAfter: "A space is required after '{{token}}'.", + unexpectedSpaceBefore: "There should be no space before '{{token}}'.", + unexpectedSpaceAfter: "There should be no space after '{{token}}'.", + }, + fixable: baseRule.meta.fixable, + schema: baseRule.meta.schema, + }, + defaultOptions: ['never'], + create(context) { + const 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: 'arraysInObjects' | 'objectsInObjects', + ): boolean { + return context.options[1] + ? context.options[1][option] === !spaced + : false; + } + + const options = { + spaced, + arraysInObjectsException: isOptionSet('arraysInObjects'), + objectsInObjectsException: isOptionSet('objectsInObjects'), + }; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Reports that there shouldn't be a space after the first token + * @param node The node to report in the event of an error. + * @param token The token to use for the report. + */ + function reportNoBeginningSpace( + node: TSESTree.TSTypeLiteral, + token: TSESTree.Token, + ): void { + const nextToken = context + .getSourceCode() + .getTokenAfter(token, { includeComments: true })!; + + context.report({ + node, + loc: { start: token.loc.end, end: nextToken.loc.start }, + messageId: 'unexpectedSpaceAfter', + data: { + token: token.value, + }, + fix(fixer) { + return fixer.removeRange([token.range[1], nextToken.range[0]]); + }, + }); + } + + /** + * Reports that there shouldn't be a space before the last token + * @param node The node to report in the event of an error. + * @param token The token to use for the report. + */ + function reportNoEndingSpace( + node: TSESTree.TSTypeLiteral, + token: TSESTree.Token, + ): void { + const previousToken = context + .getSourceCode() + .getTokenBefore(token, { includeComments: true })!; + + context.report({ + node, + loc: { start: previousToken.loc.end, end: token.loc.start }, + messageId: 'unexpectedSpaceBefore', + data: { + token: token.value, + }, + fix(fixer) { + return fixer.removeRange([previousToken.range[1], token.range[0]]); + }, + }); + } + + /** + * Reports that there should be a space after the first token + * @param node The node to report in the event of an error. + * @param token The token to use for the report. + */ + function reportRequiredBeginningSpace( + node: TSESTree.TSTypeLiteral, + token: TSESTree.Token, + ): void { + context.report({ + node, + loc: token.loc, + messageId: 'requireSpaceAfter', + data: { + token: token.value, + }, + fix(fixer) { + return fixer.insertTextAfter(token, ' '); + }, + }); + } + + /** + * Reports that there should be a space before the last token + * @param node The node to report in the event of an error. + * @param token The token to use for the report. + */ + function reportRequiredEndingSpace( + node: TSESTree.TSTypeLiteral, + token: TSESTree.Token, + ): void { + context.report({ + node, + loc: token.loc, + messageId: 'requireSpaceBefore', + data: { + token: token.value, + }, + fix(fixer) { + return fixer.insertTextBefore(token, ' '); + }, + }); + } + + /** + * Determines if spacing in curly braces is valid. + * @param node The AST node to check. + * @param first The first token to check (should be the opening brace) + * @param second The second token to check (should be first after the opening brace) + * @param penultimate The penultimate token to check (should be last before closing brace) + * @param last The last token to check (should be closing brace) + */ + function validateBraceSpacing( + node: TSESTree.TSTypeLiteral, + first: TSESTree.Token, + second: TSESTree.Token | TSESTree.Comment, + penultimate: TSESTree.Token | TSESTree.Comment, + last: TSESTree.Token, + ): void { + if (isTokenOnSameLine(first, second)) { + const firstSpaced = sourceCode.isSpaceBetween(first, second); + const secondType = sourceCode.getNodeByRangeIndex(second.range[0])! + .type; + + const openingCurlyBraceMustBeSpaced = + options.arraysInObjectsException && + secondType === AST_NODE_TYPES.TSIndexSignature + ? !options.spaced + : options.spaced; + + if (openingCurlyBraceMustBeSpaced && !firstSpaced) { + reportRequiredBeginningSpace(node, first); + } + if ( + !openingCurlyBraceMustBeSpaced && + firstSpaced && + second.type !== AST_TOKEN_TYPES.Line + ) { + reportNoBeginningSpace(node, first); + } + } + + if (isTokenOnSameLine(penultimate, last)) { + const shouldCheckPenultimate = + (options.arraysInObjectsException && + isClosingBracketToken(penultimate)) || + (options.objectsInObjectsException && + isClosingBraceToken(penultimate)); + const penultimateType = + shouldCheckPenultimate && + sourceCode.getNodeByRangeIndex(penultimate.range[0])!.type; + + const closingCurlyBraceMustBeSpaced = + (options.arraysInObjectsException && + penultimateType === AST_NODE_TYPES.TSTupleType) || + (options.objectsInObjectsException && + penultimateType === AST_NODE_TYPES.TSTypeLiteral) + ? !options.spaced + : options.spaced; + + const lastSpaced = sourceCode.isSpaceBetween(penultimate, last); + + if (closingCurlyBraceMustBeSpaced && !lastSpaced) { + reportRequiredEndingSpace(node, last); + } + if (!closingCurlyBraceMustBeSpaced && lastSpaced) { + reportNoEndingSpace(node, last); + } + } + } + + /** + * Gets '}' token of an object node. + * + * Because the last token of object patterns might be a type annotation, + * this traverses tokens preceded by the last property, then returns the + * first '}' token. + * @param node The node to get. This node is an + * ObjectExpression or an ObjectPattern. And this node has one or + * more properties. + * @returns '}' token. + */ + function getClosingBraceOfObject( + node: TSESTree.TSTypeLiteral, + ): TSESTree.Token | null { + const lastProperty = node.members[node.members.length - 1]; + + return sourceCode.getTokenAfter(lastProperty, isClosingBraceToken); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + const rules = baseRule.create(context); + return { + ...rules, + TSTypeLiteral(node: TSESTree.TSTypeLiteral): void { + if (node.members.length === 0) { + return; + } + + const first = sourceCode.getFirstToken(node)!, + last = getClosingBraceOfObject(node)!, + second = sourceCode.getTokenAfter(first, { includeComments: true })!, + penultimate = sourceCode.getTokenBefore(last, { + includeComments: true, + })!; + + validateBraceSpacing(node, first, second, penultimate, last); + }, + }; + }, +}); diff --git a/packages/eslint-plugin/tests/rules/object-curly-spacing.test.ts b/packages/eslint-plugin/tests/rules/object-curly-spacing.test.ts new file mode 100644 index 00000000000..610a34f8691 --- /dev/null +++ b/packages/eslint-plugin/tests/rules/object-curly-spacing.test.ts @@ -0,0 +1,199 @@ +/* eslint-disable eslint-comments/no-use */ +// this rule tests the position of braces, which prettier will want to fix and break the tests +/* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ +/* eslint-enable eslint-comments/no-use */ + +import rule from '../../src/rules/object-curly-spacing'; +import { RuleTester } from '../RuleTester'; + +const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', +}); + +ruleTester.run('object-curly-spacing', rule, { + valid: [ + { + code: 'const x:{}', + }, + { + code: 'const x:{ }', + }, + { + code: 'const x:{f: number}', + }, + { + code: 'const x:{ // line-comment\nf: number\n}', + }, + { + code: 'const x:{// line-comment\nf: number\n}', + }, + { + code: 'const x:{/* inline-comment */f: number/* inline-comment */}', + }, + { + code: 'const x:{\nf: number\n}', + }, + { + code: 'const x:{f: {g: number}}', + }, + { + code: 'const x:{f: [number]}', + }, + { + code: 'const x:{[key: string]: value}', + }, + { + code: 'const x:{[key: string]: [number]}', + }, + { + code: 'const x:{f: {g: number} }', + options: ['never', { objectsInObjects: true }], + }, + { + code: 'const x:{f: {g: number}}', + options: ['never', { objectsInObjects: false }], + }, + { + code: 'const x:{f: () => {g: number} }', + options: ['never', { objectsInObjects: true }], + }, + { + code: 'const x:{f: () => {g: number}}', + options: ['never', { objectsInObjects: false }], + }, + { + code: 'const x:{f: [number] }', + options: ['never', { arraysInObjects: true }], + }, + { + code: 'const x:{f: [ number ]}', + options: ['never', { arraysInObjects: false }], + }, + { + code: 'const x:{ [key: string]: value}', + options: ['never', { arraysInObjects: true }], + }, + { + code: 'const x:{[key: string]: value}', + options: ['never', { arraysInObjects: false }], + }, + { + code: 'const x:{ [key: string]: [number] }', + options: ['never', { arraysInObjects: true }], + }, + { + code: 'const x:{[key: string]: [number]}', + options: ['never', { arraysInObjects: false }], + }, + { + code: 'const x:{}', + options: ['always'], + }, + { + code: 'const x:{ }', + options: ['always'], + }, + { + code: 'const x:{ f: number }', + options: ['always'], + }, + { + code: 'const x:{ // line-comment\nf: number\n}', + options: ['always'], + }, + { + code: 'const x:{ /* inline-comment */ f: number /* inline-comment */ }', + options: ['always'], + }, + { + code: 'const x:{\nf: number\n}', + options: ['always'], + }, + { + code: 'const x:{ f: [number] }', + options: ['always'], + }, + { + code: 'const x:{ f: { g: number } }', + options: ['always', { objectsInObjects: true }], + }, + { + code: 'const x:{ f: { g: number }}', + options: ['always', { objectsInObjects: false }], + }, + { + code: 'const x:{ f: () => { g: number } }', + options: ['always', { objectsInObjects: true }], + }, + { + code: 'const x:{ f: () => { g: number }}', + options: ['always', { objectsInObjects: false }], + }, + { + code: 'const x:{ f: [number] }', + options: ['always', { arraysInObjects: true }], + }, + { + code: 'const x:{ f: [ number ]}', + options: ['always', { arraysInObjects: false }], + }, + { + code: 'const x:{ [key: string]: value }', + options: ['always', { arraysInObjects: true }], + }, + { + code: 'const x:{[key: string]: value }', + options: ['always', { arraysInObjects: false }], + }, + { + code: 'const x:{ [key: string]: [number] }', + options: ['always', { arraysInObjects: true }], + }, + { + code: 'const x:{[key: string]: [number]}', + options: ['always', { arraysInObjects: false }], + }, + ], + + invalid: [ + { + code: 'type x = { f: number }', + output: 'type x = {f: number}', + errors: [ + { messageId: 'unexpectedSpaceAfter' }, + { messageId: 'unexpectedSpaceBefore' }, + ], + }, + { + code: 'type x = { f: number}', + output: 'type x = {f: number}', + errors: [{ messageId: 'unexpectedSpaceAfter' }], + }, + { + code: 'type x = {f: number }', + output: 'type x = {f: number}', + errors: [{ messageId: 'unexpectedSpaceBefore' }], + }, + { + code: 'type x = {f: number}', + output: 'type x = { f: number }', + options: ['always'], + errors: [ + { messageId: 'requireSpaceAfter' }, + { messageId: 'requireSpaceBefore' }, + ], + }, + { + code: 'type x = {f: number }', + output: 'type x = { f: number }', + options: ['always'], + errors: [{ messageId: 'requireSpaceAfter' }], + }, + { + code: 'type x = { f: number}', + output: 'type x = { f: number }', + options: ['always'], + errors: [{ messageId: 'requireSpaceBefore' }], + }, + ], +}); diff --git a/packages/eslint-plugin/typings/eslint-rules.d.ts b/packages/eslint-plugin/typings/eslint-rules.d.ts index ca726d6fb83..49e48541f87 100644 --- a/packages/eslint-plugin/typings/eslint-rules.d.ts +++ b/packages/eslint-plugin/typings/eslint-rules.d.ts @@ -830,3 +830,28 @@ declare module 'eslint/lib/rules/prefer-const' { >; export = rule; } + +declare module 'eslint/lib/rules/object-curly-spacing' { + import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils'; + + const rule: TSESLint.RuleModule< + | 'requireSpaceBefore' + | 'requireSpaceAfter' + | 'unexpectedSpaceBefore' + | 'unexpectedSpaceAfter', + [ + 'always' | 'never', + { + arraysInObjects?: boolean; + objectsInObjects?: boolean; + }?, + ], + { + ObjectPattern(node: TSESTree.ObjectPattern): void; + ObjectExpression(node: TSESTree.ObjectExpression): void; + ImportDeclaration(node: TSESTree.ImportDeclaration): void; + ExportNamedDeclaration(node: TSESTree.ExportNamedDeclaration): void; + } + >; + export = rule; +} From d4e50dc4f1455f98db863cde18b55bbb17928040 Mon Sep 17 00:00:00 2001 From: Maarten Sijm Date: Mon, 21 Dec 2020 16:10:40 +0100 Subject: [PATCH 2/6] Resolve bradzacher's comments --- .../docs/rules/object-curly-spacing.md | 2 +- .../src/rules/object-curly-spacing.ts | 29 +++++++++---------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/object-curly-spacing.md b/packages/eslint-plugin/docs/rules/object-curly-spacing.md index f64b04dc6f5..44bd35afb59 100644 --- a/packages/eslint-plugin/docs/rules/object-curly-spacing.md +++ b/packages/eslint-plugin/docs/rules/object-curly-spacing.md @@ -3,7 +3,7 @@ ## Rule Details This rule extends the base [`eslint/object-curly-spacing`](https://eslint.org/docs/rules/object-curly-spacing) rule. -It supports all options and features of the base rule. +It adds support for TypeScript's object types. ## How to use diff --git a/packages/eslint-plugin/src/rules/object-curly-spacing.ts b/packages/eslint-plugin/src/rules/object-curly-spacing.ts index 44dcd89c41f..2b90849b3e1 100644 --- a/packages/eslint-plugin/src/rules/object-curly-spacing.ts +++ b/packages/eslint-plugin/src/rules/object-curly-spacing.ts @@ -26,26 +26,21 @@ export default createRule({ recommended: false, extendsBaseRule: true, }, - messages: { - requireSpaceBefore: "A space is required before '{{token}}'.", - requireSpaceAfter: "A space is required after '{{token}}'.", - unexpectedSpaceBefore: "There should be no space before '{{token}}'.", - unexpectedSpaceAfter: "There should be no space after '{{token}}'.", - }, + messages: baseRule.messages, fixable: baseRule.meta.fixable, schema: baseRule.meta.schema, }, defaultOptions: ['never'], create(context) { - const spaced = context.options[0] === 'always', - sourceCode = context.getSourceCode(); + const spaced = context.options[0] === 'always'; + const 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. + * @param option The option to exclude. + * @returns Whether or not the property is excluded. */ function isOptionSet( option: 'arraysInObjects' | 'objectsInObjects', @@ -259,12 +254,14 @@ export default createRule({ return; } - const first = sourceCode.getFirstToken(node)!, - last = getClosingBraceOfObject(node)!, - second = sourceCode.getTokenAfter(first, { includeComments: true })!, - penultimate = sourceCode.getTokenBefore(last, { - includeComments: true, - })!; + const first = sourceCode.getFirstToken(node)!; + const last = getClosingBraceOfObject(node)!; + const second = sourceCode.getTokenAfter(first, { + includeComments: true, + })!; + const penultimate = sourceCode.getTokenBefore(last, { + includeComments: true, + })!; validateBraceSpacing(node, first, second, penultimate, last); }, From ca10e70c35671169cf1b0746128084141a24e1eb Mon Sep 17 00:00:00 2001 From: Maarten Sijm Date: Mon, 21 Dec 2020 17:10:32 +0100 Subject: [PATCH 3/6] Fix compile error in rule meta --- packages/eslint-plugin/src/rules/object-curly-spacing.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/eslint-plugin/src/rules/object-curly-spacing.ts b/packages/eslint-plugin/src/rules/object-curly-spacing.ts index 2b90849b3e1..bd4bd39294d 100644 --- a/packages/eslint-plugin/src/rules/object-curly-spacing.ts +++ b/packages/eslint-plugin/src/rules/object-curly-spacing.ts @@ -19,16 +19,13 @@ export type MessageIds = InferMessageIdsTypeFromRule; export default createRule({ name: 'object-curly-spacing', meta: { - type: 'layout', + ...baseRule.meta, docs: { description: 'Enforce consistent spacing inside braces', category: 'Stylistic Issues', recommended: false, extendsBaseRule: true, }, - messages: baseRule.messages, - fixable: baseRule.meta.fixable, - schema: baseRule.meta.schema, }, defaultOptions: ['never'], create(context) { From 740d74b30c6efc54b5c46d0eb9194e936306a9c4 Mon Sep 17 00:00:00 2001 From: Maarten Sijm Date: Mon, 21 Dec 2020 17:46:51 +0100 Subject: [PATCH 4/6] Copy tests from eslint rule --- .../tests/rules/object-curly-spacing.test.ts | 1755 +++++++++++++++++ 1 file changed, 1755 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/object-curly-spacing.test.ts b/packages/eslint-plugin/tests/rules/object-curly-spacing.test.ts index 610a34f8691..0cf9b142384 100644 --- a/packages/eslint-plugin/tests/rules/object-curly-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/object-curly-spacing.test.ts @@ -12,6 +12,529 @@ const ruleTester = new RuleTester({ ruleTester.run('object-curly-spacing', rule, { valid: [ + // always - object literals + { 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 obj = { /**/foo:bar/**/ };', options: ['always'] }, + { code: 'var obj = { //\nfoo:bar };', options: ['always'] }, + + // always - destructuring + { + code: 'var { x } = y', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var { x, y } = y', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var { x,y } = y', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {\nx,y } = y', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {\nx,y\n} = z', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var { /**/x/**/ } = y', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var { //\nx } = y', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var { x = 10, y } = y', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var { x: { z }, y } = y', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {\ny,\n} = x', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var { y, } = x', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var { y: x } = x', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + }, + + // always - import / export + { + code: "import door from 'room'", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import * as door from 'room'", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import { door } from 'room'", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import {\ndoor } from 'room'", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import { /**/door/**/ } from 'room'", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import { //\ndoor } from 'room'", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "export { door } from 'room'", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import { house, mouse } from 'caravan'", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import house, { mouse } from 'caravan'", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import door, { house, mouse } from 'caravan'", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: 'var door = 0;export { door }', + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import 'room'", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import { bar as x } from 'foo';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import { x, } from 'foo';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import {\nx,\n} from 'foo';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "export { x, } from 'foo';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "export {\nx,\n} from 'foo';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "export { /**/x/**/ } from 'foo';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "export { //\nx } from 'foo';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: 'var x = 1;\nexport { /**/x/**/ };', + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: 'var x = 1;\nexport { //\nx };', + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + + // always - empty object + { code: 'var foo = {};', options: ['always'] }, + + // always - objectsInObjects + { + code: "var obj = { 'foo': { 'bar': 1, 'baz': 2 }};", + options: ['always', { objectsInObjects: false }], + }, + { + code: 'var a = { noop: function () {} };', + options: ['always', { objectsInObjects: false }], + }, + { + code: 'var { y: { z }} = x', + options: ['always', { objectsInObjects: false }], + parserOptions: { ecmaVersion: 6 }, + }, + + // always - arraysInObjects + { + code: "var obj = { 'foo': [ 1, 2 ]};", + options: ['always', { arraysInObjects: false }], + }, + { + code: 'var a = { thingInList: list[0] };', + options: ['always', { arraysInObjects: 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 }], + }, + + // never + { code: 'var obj = {foo: bar,\nbaz: qux\n};', options: ['never'] }, + { code: 'var obj = {\nfoo: bar,\nbaz: qux};', options: ['never'] }, + + // never - object literals + { code: 'var obj = {foo: bar, baz: qux};', options: ['never'] }, + { code: 'var obj = {foo: {bar: quxx}, baz: qux};', options: ['never'] }, + { code: 'var obj = {foo: {\nbar: quxx}, baz: qux\n};', options: ['never'] }, + { code: 'var obj = {foo: {\nbar: quxx\n}, baz: qux};', options: ['never'] }, + { code: 'var obj = {\nfoo: bar,\nbaz: qux\n};', options: ['never'] }, + { code: 'var obj = {foo: bar, baz: qux /* */};', options: ['never'] }, + { code: 'var obj = {/* */ foo: bar, baz: qux};', options: ['never'] }, + { code: 'var obj = {//\n foo: bar};', options: ['never'] }, + { + code: 'var obj = { // line comment exception\n foo: bar};', + options: ['never'], + }, + + // never - destructuring + { + code: 'var {x} = y', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {x, y} = y', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {x,y} = y', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {\nx,y\n} = y', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {x = 10} = y', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {x = 10, y} = y', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {x: {z}, y} = y', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {\nx: {z\n}, y} = y', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {\ny,\n} = x', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {y,} = x', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {y:x} = x', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {/* */ y} = x', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {y /* */} = x', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {//\n y} = x', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var { // line comment exception\n y} = x', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + + // never - import / export + { + code: "import door from 'room'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import * as door from 'room'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import {door} from 'room'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "export {door} from 'room'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import {/* */ door} from 'room'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "export {/* */ door} from 'room'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import {door /* */} from 'room'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "export {door /* */} from 'room'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import {//\n door} from 'room'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "export {//\n door} from 'room'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: 'var door = foo;\nexport {//\n door}', + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import { // line comment exception\n door} from 'room'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "export { // line comment exception\n door} from 'room'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: 'var door = foo; export { // line comment exception\n door}', + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import {\ndoor} from 'room'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "export {\ndoor\n} from 'room'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import {house,mouse} from 'caravan'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import {house, mouse} from 'caravan'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: 'var door = 0;export {door}', + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import 'room'", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import x, {bar} from 'foo';", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import x, {bar, baz} from 'foo';", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import {bar as y} from 'foo';", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import {x,} from 'foo';", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import {\nx,\n} from 'foo';", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "export {x,} from 'foo';", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "export {\nx,\n} from 'foo';", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + + // never - empty object + { code: 'var foo = {};', options: ['never'] }, + + // never - objectsInObjects + { + code: "var obj = {'foo': {'bar': 1, 'baz': 2} };", + options: ['never', { objectsInObjects: true }], + }, + + /* + * https://github.com/eslint/eslint/issues/3658 + * Empty cases. + */ + { code: 'var {} = foo;', parserOptions: { ecmaVersion: 6 } }, + { code: 'var [] = foo;', parserOptions: { ecmaVersion: 6 } }, + { code: 'var {a: {}} = foo;', parserOptions: { ecmaVersion: 6 } }, + { code: 'var {a: []} = foo;', parserOptions: { ecmaVersion: 6 } }, + { + code: "import {} from 'foo';", + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "export {} from 'foo';", + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: 'export {};', + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: 'var {} = foo;', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var [] = foo;', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {a: {}} = foo;', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: 'var {a: []} = foo;', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + }, + { + code: "import {} from 'foo';", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "export {} from 'foo';", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: 'export {};', + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + + // https://github.com/eslint/eslint/issues/6940 + { + code: 'function foo ({a, b}: Props) {\n}', + options: ['never'], + }, + + // default - object literal types { code: 'const x:{}', }, @@ -45,6 +568,8 @@ ruleTester.run('object-curly-spacing', rule, { { code: 'const x:{[key: string]: [number]}', }, + + // never - object literal types { code: 'const x:{f: {g: number} }', options: ['never', { objectsInObjects: true }], @@ -85,6 +610,8 @@ ruleTester.run('object-curly-spacing', rule, { code: 'const x:{[key: string]: [number]}', options: ['never', { arraysInObjects: false }], }, + + // always - object literal types { code: 'const x:{}', options: ['always'], @@ -113,6 +640,8 @@ ruleTester.run('object-curly-spacing', rule, { code: 'const x:{ f: [number] }', options: ['always'], }, + + // always - objectsInObjects { code: 'const x:{ f: { g: number } }', options: ['always', { objectsInObjects: true }], @@ -129,6 +658,8 @@ ruleTester.run('object-curly-spacing', rule, { code: 'const x:{ f: () => { g: number }}', options: ['always', { objectsInObjects: false }], }, + + // always - arraysInObjects { code: 'const x:{ f: [number] }', options: ['always', { arraysInObjects: true }], @@ -156,6 +687,1230 @@ ruleTester.run('object-curly-spacing', rule, { ], invalid: [ + { + code: "import {bar} from 'foo.js';", + output: "import { bar } from 'foo.js';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ImportDeclaration', + line: 1, + column: 8, + endLine: 1, + endColumn: 9, + }, + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ImportDeclaration', + line: 1, + column: 12, + endLine: 1, + endColumn: 13, + }, + ], + }, + { + code: "import { bar as y} from 'foo.js';", + output: "import { bar as y } from 'foo.js';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ImportDeclaration', + line: 1, + column: 18, + endLine: 1, + endColumn: 19, + }, + ], + }, + { + code: "import {bar as y} from 'foo.js';", + output: "import { bar as y } from 'foo.js';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ImportDeclaration', + line: 1, + column: 8, + endLine: 1, + endColumn: 9, + }, + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ImportDeclaration', + line: 1, + column: 17, + endLine: 1, + endColumn: 18, + }, + ], + }, + { + code: "import { bar} from 'foo.js';", + output: "import { bar } from 'foo.js';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ImportDeclaration', + line: 1, + column: 13, + endLine: 1, + endColumn: 14, + }, + ], + }, + { + code: "import x, { bar} from 'foo';", + output: "import x, { bar } from 'foo';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ImportDeclaration', + line: 1, + column: 16, + endLine: 1, + endColumn: 17, + }, + ], + }, + { + code: "import x, { bar/* */} from 'foo';", + output: "import x, { bar/* */ } from 'foo';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ImportDeclaration', + line: 1, + column: 21, + endLine: 1, + endColumn: 22, + }, + ], + }, + { + code: "import x, {/* */bar } from 'foo';", + output: "import x, { /* */bar } from 'foo';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ImportDeclaration', + line: 1, + column: 11, + endLine: 1, + endColumn: 12, + }, + ], + }, + { + code: "import x, {//\n bar } from 'foo';", + output: "import x, { //\n bar } from 'foo';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ImportDeclaration', + line: 1, + column: 11, + endLine: 1, + endColumn: 12, + }, + ], + }, + { + code: "import x, { bar, baz} from 'foo';", + output: "import x, { bar, baz } from 'foo';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ImportDeclaration', + line: 1, + column: 21, + endLine: 1, + endColumn: 22, + }, + ], + }, + { + code: "import x, {bar} from 'foo';", + output: "import x, { bar } from 'foo';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ImportDeclaration', + line: 1, + column: 11, + endLine: 1, + endColumn: 12, + }, + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ImportDeclaration', + line: 1, + column: 15, + endLine: 1, + endColumn: 16, + }, + ], + }, + { + code: "import x, {bar, baz} from 'foo';", + output: "import x, { bar, baz } from 'foo';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ImportDeclaration', + line: 1, + column: 11, + endLine: 1, + endColumn: 12, + }, + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ImportDeclaration', + line: 1, + column: 20, + endLine: 1, + endColumn: 21, + }, + ], + }, + { + code: "import {bar,} from 'foo';", + output: "import { bar, } from 'foo';", + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ImportDeclaration', + line: 1, + column: 8, + endLine: 1, + endColumn: 9, + }, + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ImportDeclaration', + line: 1, + column: 13, + endLine: 1, + endColumn: 14, + }, + ], + }, + { + code: "import { bar, } from 'foo';", + output: "import {bar,} from 'foo';", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'unexpectedSpaceAfter', + data: { token: '{' }, + type: 'ImportDeclaration', + line: 1, + column: 9, + endLine: 1, + endColumn: 10, + }, + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ImportDeclaration', + line: 1, + column: 14, + endLine: 1, + endColumn: 15, + }, + ], + }, + { + code: "import { /* */ bar, /* */ } from 'foo';", + output: "import {/* */ bar, /* */} from 'foo';", + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'unexpectedSpaceAfter', + data: { token: '{' }, + type: 'ImportDeclaration', + line: 1, + column: 9, + endLine: 1, + endColumn: 10, + }, + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ImportDeclaration', + line: 1, + column: 26, + endLine: 1, + endColumn: 27, + }, + ], + }, + { + code: 'var bar = 0;\nexport {bar};', + output: 'var bar = 0;\nexport { bar };', + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ExportNamedDeclaration', + line: 2, + column: 8, + endLine: 2, + endColumn: 9, + }, + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ExportNamedDeclaration', + line: 2, + column: 12, + }, + ], + }, + { + code: 'var bar = 0;\nexport {/* */ bar /* */};', + output: 'var bar = 0;\nexport { /* */ bar /* */ };', + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ExportNamedDeclaration', + line: 2, + column: 8, + endLine: 2, + endColumn: 9, + }, + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ExportNamedDeclaration', + line: 2, + column: 24, + endLine: 2, + endColumn: 25, + }, + ], + }, + { + code: 'var bar = 0;\nexport {//\n bar };', + output: 'var bar = 0;\nexport { //\n bar };', + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ExportNamedDeclaration', + line: 2, + column: 8, + endLine: 2, + endColumn: 9, + }, + ], + }, + { + code: 'var bar = 0;\nexport { /* */ bar /* */ };', + output: 'var bar = 0;\nexport {/* */ bar /* */};', + options: ['never'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'unexpectedSpaceAfter', + data: { token: '{' }, + type: 'ExportNamedDeclaration', + line: 2, + column: 9, + endLine: 2, + endColumn: 10, + }, + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ExportNamedDeclaration', + line: 2, + column: 25, + endLine: 2, + endColumn: 26, + }, + ], + }, + + // always - arraysInObjects + { + code: "var obj = { 'foo': [ 1, 2 ] };", + output: "var obj = { 'foo': [ 1, 2 ]};", + options: ['always', { arraysInObjects: false }], + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 28, + endLine: 1, + endColumn: 29, + }, + ], + }, + { + code: "var obj = { 'foo': [ 1, 2 ] , 'bar': [ 'baz', 'qux' ] };", + output: "var obj = { 'foo': [ 1, 2 ] , 'bar': [ 'baz', 'qux' ]};", + options: ['always', { arraysInObjects: false }], + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 54, + endLine: 1, + endColumn: 55, + }, + ], + }, + + // always-objectsInObjects + { + code: "var obj = { 'foo': { 'bar': 1, 'baz': 2 } };", + output: "var obj = { 'foo': { 'bar': 1, 'baz': 2 }};", + options: ['always', { objectsInObjects: false }], + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 42, + endLine: 1, + endColumn: 43, + }, + ], + }, + { + code: "var obj = { 'foo': [ 1, 2 ] , 'bar': { 'baz': 1, 'qux': 2 } };", + output: "var obj = { 'foo': [ 1, 2 ] , 'bar': { 'baz': 1, 'qux': 2 }};", + options: ['always', { objectsInObjects: false }], + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 60, + endLine: 1, + endColumn: 61, + }, + ], + }, + + // always-destructuring trailing comma + { + code: 'var { a,} = x;', + output: 'var { a, } = x;', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ObjectPattern', + line: 1, + column: 9, + endLine: 1, + endColumn: 10, + }, + ], + }, + { + code: 'var {a, } = x;', + output: 'var {a,} = x;', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectPattern', + line: 1, + column: 8, + endLine: 1, + endColumn: 9, + }, + ], + }, + { + code: 'var {a:b } = x;', + output: 'var {a:b} = x;', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectPattern', + line: 1, + column: 9, + endLine: 1, + endColumn: 10, + }, + ], + }, + { + code: 'var { a:b } = x;', + output: 'var {a:b} = x;', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'unexpectedSpaceAfter', + data: { token: '{' }, + type: 'ObjectPattern', + line: 1, + column: 6, + endLine: 1, + endColumn: 7, + }, + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectPattern', + line: 1, + column: 10, + endLine: 1, + endColumn: 11, + }, + ], + }, + { + code: 'var { a:b } = x;', + output: 'var {a:b} = x;', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'unexpectedSpaceAfter', + data: { token: '{' }, + type: 'ObjectPattern', + line: 1, + column: 6, + endLine: 1, + endColumn: 8, + }, + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectPattern', + line: 1, + column: 11, + endLine: 1, + endColumn: 13, + }, + ], + }, + { + code: 'var { a:b } = x;', + output: 'var {a:b} = x;', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'unexpectedSpaceAfter', + data: { token: '{' }, + type: 'ObjectPattern', + line: 1, + column: 6, + endLine: 1, + endColumn: 9, + }, + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectPattern', + line: 1, + column: 12, + endLine: 1, + endColumn: 16, + }, + ], + }, + + // never-objectsInObjects + { + code: "var obj = {'foo': {'bar': 1, 'baz': 2}};", + output: "var obj = {'foo': {'bar': 1, 'baz': 2} };", + options: ['never', { objectsInObjects: true }], + errors: [ + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 39, + endLine: 1, + endColumn: 40, + }, + ], + }, + { + code: "var obj = {'foo': [1, 2] , 'bar': {'baz': 1, 'qux': 2}};", + output: "var obj = {'foo': [1, 2] , 'bar': {'baz': 1, 'qux': 2} };", + options: ['never', { objectsInObjects: true }], + errors: [ + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 55, + endLine: 1, + endColumn: 56, + }, + ], + }, + + // always & never + { + code: 'var obj = {foo: bar, baz: qux};', + output: 'var obj = { foo: bar, baz: qux };', + options: ['always'], + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ObjectExpression', + line: 1, + column: 11, + endLine: 1, + endColumn: 12, + }, + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 30, + endLine: 1, + endColumn: 31, + }, + ], + }, + { + code: 'var obj = {foo: bar, baz: qux };', + output: 'var obj = { foo: bar, baz: qux };', + options: ['always'], + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ObjectExpression', + line: 1, + column: 11, + endLine: 1, + endColumn: 12, + }, + ], + }, + { + code: 'var obj = {/* */foo: bar, baz: qux };', + output: 'var obj = { /* */foo: bar, baz: qux };', + options: ['always'], + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ObjectExpression', + line: 1, + column: 11, + endLine: 1, + endColumn: 12, + }, + ], + }, + { + code: 'var obj = {//\n foo: bar };', + output: 'var obj = { //\n foo: bar };', + options: ['always'], + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ObjectExpression', + line: 1, + column: 11, + endLine: 1, + endColumn: 12, + }, + ], + }, + { + code: 'var obj = { foo: bar, baz: qux};', + output: 'var obj = { foo: bar, baz: qux };', + options: ['always'], + errors: [ + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 31, + endLine: 1, + endColumn: 32, + }, + ], + }, + { + code: 'var obj = { foo: bar, baz: qux/* */};', + output: 'var obj = { foo: bar, baz: qux/* */ };', + options: ['always'], + errors: [ + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 36, + endLine: 1, + endColumn: 37, + }, + ], + }, + { + code: 'var obj = { foo: bar, baz: qux };', + output: 'var obj = {foo: bar, baz: qux};', + options: ['never'], + errors: [ + { + messageId: 'unexpectedSpaceAfter', + data: { token: '{' }, + type: 'ObjectExpression', + line: 1, + column: 12, + endLine: 1, + endColumn: 13, + }, + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 31, + endLine: 1, + endColumn: 32, + }, + ], + }, + { + code: 'var obj = { foo: bar, baz: qux };', + output: 'var obj = {foo: bar, baz: qux};', + options: ['never'], + errors: [ + { + messageId: 'unexpectedSpaceAfter', + data: { token: '{' }, + type: 'ObjectExpression', + line: 1, + column: 12, + endLine: 1, + endColumn: 14, + }, + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 32, + endLine: 1, + endColumn: 33, + }, + ], + }, + { + code: 'var obj = {foo: bar, baz: qux };', + output: 'var obj = {foo: bar, baz: qux};', + options: ['never'], + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 30, + endLine: 1, + endColumn: 31, + }, + ], + }, + { + code: 'var obj = {foo: bar, baz: qux };', + output: 'var obj = {foo: bar, baz: qux};', + options: ['never'], + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 30, + endLine: 1, + endColumn: 32, + }, + ], + }, + { + code: 'var obj = {foo: bar, baz: qux /* */ };', + output: 'var obj = {foo: bar, baz: qux /* */};', + options: ['never'], + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 36, + endLine: 1, + endColumn: 37, + }, + ], + }, + { + code: 'var obj = { foo: bar, baz: qux};', + output: 'var obj = {foo: bar, baz: qux};', + options: ['never'], + errors: [ + { + messageId: 'unexpectedSpaceAfter', + data: { token: '{' }, + type: 'ObjectExpression', + line: 1, + column: 12, + endLine: 1, + endColumn: 13, + }, + ], + }, + { + code: 'var obj = { foo: bar, baz: qux};', + output: 'var obj = {foo: bar, baz: qux};', + options: ['never'], + errors: [ + { + messageId: 'unexpectedSpaceAfter', + data: { token: '{' }, + type: 'ObjectExpression', + line: 1, + column: 12, + endLine: 1, + endColumn: 14, + }, + ], + }, + { + code: 'var obj = { /* */ foo: bar, baz: qux};', + output: 'var obj = {/* */ foo: bar, baz: qux};', + options: ['never'], + errors: [ + { + messageId: 'unexpectedSpaceAfter', + data: { token: '{' }, + type: 'ObjectExpression', + line: 1, + column: 12, + endLine: 1, + endColumn: 13, + }, + ], + }, + { + code: 'var obj = { // line comment exception\n foo: bar };', + output: 'var obj = { // line comment exception\n foo: bar};', + options: ['never'], + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 2, + column: 10, + endLine: 2, + endColumn: 11, + }, + ], + }, + { + code: 'var obj = { foo: { bar: quxx}, baz: qux};', + output: 'var obj = {foo: {bar: quxx}, baz: qux};', + options: ['never'], + errors: [ + { + messageId: 'unexpectedSpaceAfter', + data: { token: '{' }, + type: 'ObjectExpression', + line: 1, + column: 12, + endLine: 1, + endColumn: 13, + }, + { + messageId: 'unexpectedSpaceAfter', + data: { token: '{' }, + type: 'ObjectExpression', + line: 1, + column: 19, + endLine: 1, + endColumn: 20, + }, + ], + }, + { + code: 'var obj = {foo: {bar: quxx }, baz: qux };', + output: 'var obj = {foo: {bar: quxx}, baz: qux};', + options: ['never'], + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 27, + endLine: 1, + endColumn: 28, + }, + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 39, + endLine: 1, + endColumn: 40, + }, + ], + }, + { + code: 'export const thing = {value: 1 };', + output: 'export const thing = { value: 1 };', + options: ['always'], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ObjectExpression', + line: 1, + column: 22, + endLine: 1, + endColumn: 23, + }, + ], + }, + + // destructuring + { + code: 'var {x, y} = y', + output: 'var { x, y } = y', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ObjectPattern', + line: 1, + column: 5, + endLine: 1, + endColumn: 6, + }, + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ObjectPattern', + line: 1, + column: 10, + endLine: 1, + endColumn: 11, + }, + ], + }, + { + code: 'var { x, y} = y', + output: 'var { x, y } = y', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ObjectPattern', + line: 1, + column: 11, + endLine: 1, + endColumn: 12, + }, + ], + }, + { + code: 'var { x, y/* */} = y', + output: 'var { x, y/* */ } = y', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ObjectPattern', + line: 1, + column: 16, + endLine: 1, + endColumn: 17, + }, + ], + }, + { + code: 'var {/* */x, y } = y', + output: 'var { /* */x, y } = y', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ObjectPattern', + line: 1, + column: 5, + endLine: 1, + endColumn: 6, + }, + ], + }, + { + code: 'var {//\n x } = y', + output: 'var { //\n x } = y', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ObjectPattern', + line: 1, + column: 5, + endLine: 1, + endColumn: 6, + }, + ], + }, + { + code: 'var { x, y } = y', + output: 'var {x, y} = y', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'unexpectedSpaceAfter', + data: { token: '{' }, + type: 'ObjectPattern', + line: 1, + column: 6, + endLine: 1, + endColumn: 7, + }, + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectPattern', + line: 1, + column: 11, + endLine: 1, + endColumn: 12, + }, + ], + }, + { + code: 'var {x, y } = y', + output: 'var {x, y} = y', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectPattern', + line: 1, + column: 10, + endLine: 1, + endColumn: 11, + }, + ], + }, + { + code: 'var {x, y/* */ } = y', + output: 'var {x, y/* */} = y', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectPattern', + line: 1, + column: 15, + endLine: 1, + endColumn: 16, + }, + ], + }, + { + code: 'var { /* */x, y} = y', + output: 'var {/* */x, y} = y', + options: ['never'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'unexpectedSpaceAfter', + data: { token: '{' }, + type: 'ObjectPattern', + line: 1, + column: 6, + endLine: 1, + endColumn: 7, + }, + ], + }, + { + code: 'var { x=10} = y', + output: 'var { x=10 } = y', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ObjectPattern', + line: 1, + column: 11, + endLine: 1, + endColumn: 12, + }, + ], + }, + { + code: 'var {x=10 } = y', + output: 'var { x=10 } = y', + options: ['always'], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: 'requireSpaceAfter', + data: { token: '{' }, + type: 'ObjectPattern', + line: 1, + column: 5, + endLine: 1, + endColumn: 6, + }, + ], + }, + + // never - arraysInObjects + { + code: "var obj = {'foo': [1, 2]};", + output: "var obj = {'foo': [1, 2] };", + options: ['never', { arraysInObjects: true }], + errors: [ + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 25, + endLine: 1, + endColumn: 26, + }, + ], + }, + { + code: "var obj = {'foo': [1, 2] , 'bar': ['baz', 'qux']};", + output: "var obj = {'foo': [1, 2] , 'bar': ['baz', 'qux'] };", + options: ['never', { arraysInObjects: true }], + errors: [ + { + messageId: 'requireSpaceBefore', + data: { token: '}' }, + type: 'ObjectExpression', + line: 1, + column: 49, + endLine: 1, + endColumn: 50, + }, + ], + }, + + // https://github.com/eslint/eslint/issues/6940 + { + code: 'function foo ({a, b }: Props) {\n}', + output: 'function foo ({a, b}: Props) {\n}', + options: ['never'], + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { token: '}' }, + type: 'ObjectPattern', + line: 1, + column: 20, + endLine: 1, + endColumn: 21, + }, + ], + }, + + // object literal types { code: 'type x = { f: number }', output: 'type x = {f: number}', From 9971ec360f44224b05adf3aa386a071a203a314b Mon Sep 17 00:00:00 2001 From: Maarten Sijm Date: Mon, 21 Dec 2020 18:16:53 +0100 Subject: [PATCH 5/6] Fix build error: assert sourceCode.isSpaceBetween is non-null --- packages/eslint-plugin/src/rules/object-curly-spacing.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/src/rules/object-curly-spacing.ts b/packages/eslint-plugin/src/rules/object-curly-spacing.ts index bd4bd39294d..581e7ac1555 100644 --- a/packages/eslint-plugin/src/rules/object-curly-spacing.ts +++ b/packages/eslint-plugin/src/rules/object-curly-spacing.ts @@ -169,7 +169,7 @@ export default createRule({ last: TSESTree.Token, ): void { if (isTokenOnSameLine(first, second)) { - const firstSpaced = sourceCode.isSpaceBetween(first, second); + const firstSpaced = sourceCode.isSpaceBetween!(first, second); const secondType = sourceCode.getNodeByRangeIndex(second.range[0])! .type; @@ -209,7 +209,7 @@ export default createRule({ ? !options.spaced : options.spaced; - const lastSpaced = sourceCode.isSpaceBetween(penultimate, last); + const lastSpaced = sourceCode.isSpaceBetween!(penultimate, last); if (closingCurlyBraceMustBeSpaced && !lastSpaced) { reportRequiredEndingSpace(node, last); From 1a1f3a112154fccea9394bd4dfb6efd5c690684a Mon Sep 17 00:00:00 2001 From: Maarten Sijm Date: Mon, 21 Dec 2020 18:44:42 +0100 Subject: [PATCH 6/6] Prefer AST_NODE_TYPES enum over string literal --- .../tests/rules/object-curly-spacing.test.ts | 165 +++++++++--------- 1 file changed, 83 insertions(+), 82 deletions(-) diff --git a/packages/eslint-plugin/tests/rules/object-curly-spacing.test.ts b/packages/eslint-plugin/tests/rules/object-curly-spacing.test.ts index 0cf9b142384..5c28cbef7ed 100644 --- a/packages/eslint-plugin/tests/rules/object-curly-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/object-curly-spacing.test.ts @@ -3,6 +3,7 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { AST_NODE_TYPES } from '@typescript-eslint/experimental-utils'; import rule from '../../src/rules/object-curly-spacing'; import { RuleTester } from '../RuleTester'; @@ -696,7 +697,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 8, endLine: 1, @@ -705,7 +706,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 12, endLine: 1, @@ -722,7 +723,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 18, endLine: 1, @@ -739,7 +740,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 8, endLine: 1, @@ -748,7 +749,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 17, endLine: 1, @@ -765,7 +766,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 13, endLine: 1, @@ -782,7 +783,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 16, endLine: 1, @@ -799,7 +800,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 21, endLine: 1, @@ -816,7 +817,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 11, endLine: 1, @@ -833,7 +834,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 11, endLine: 1, @@ -850,7 +851,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 21, endLine: 1, @@ -867,7 +868,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 11, endLine: 1, @@ -876,7 +877,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 15, endLine: 1, @@ -893,7 +894,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 11, endLine: 1, @@ -902,7 +903,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 20, endLine: 1, @@ -919,7 +920,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 8, endLine: 1, @@ -928,7 +929,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 13, endLine: 1, @@ -945,7 +946,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceAfter', data: { token: '{' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 9, endLine: 1, @@ -954,7 +955,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 14, endLine: 1, @@ -971,7 +972,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceAfter', data: { token: '{' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 9, endLine: 1, @@ -980,7 +981,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ImportDeclaration', + type: AST_NODE_TYPES.ImportDeclaration, line: 1, column: 26, endLine: 1, @@ -997,7 +998,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ExportNamedDeclaration', + type: AST_NODE_TYPES.ExportNamedDeclaration, line: 2, column: 8, endLine: 2, @@ -1006,7 +1007,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ExportNamedDeclaration', + type: AST_NODE_TYPES.ExportNamedDeclaration, line: 2, column: 12, }, @@ -1021,7 +1022,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ExportNamedDeclaration', + type: AST_NODE_TYPES.ExportNamedDeclaration, line: 2, column: 8, endLine: 2, @@ -1030,7 +1031,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ExportNamedDeclaration', + type: AST_NODE_TYPES.ExportNamedDeclaration, line: 2, column: 24, endLine: 2, @@ -1047,7 +1048,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ExportNamedDeclaration', + type: AST_NODE_TYPES.ExportNamedDeclaration, line: 2, column: 8, endLine: 2, @@ -1064,7 +1065,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceAfter', data: { token: '{' }, - type: 'ExportNamedDeclaration', + type: AST_NODE_TYPES.ExportNamedDeclaration, line: 2, column: 9, endLine: 2, @@ -1073,7 +1074,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ExportNamedDeclaration', + type: AST_NODE_TYPES.ExportNamedDeclaration, line: 2, column: 25, endLine: 2, @@ -1091,7 +1092,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 28, endLine: 1, @@ -1107,7 +1108,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 54, endLine: 1, @@ -1125,7 +1126,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 42, endLine: 1, @@ -1141,7 +1142,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 60, endLine: 1, @@ -1160,7 +1161,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 9, endLine: 1, @@ -1177,7 +1178,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 8, endLine: 1, @@ -1194,7 +1195,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 9, endLine: 1, @@ -1211,7 +1212,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceAfter', data: { token: '{' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 6, endLine: 1, @@ -1220,7 +1221,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 10, endLine: 1, @@ -1237,7 +1238,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceAfter', data: { token: '{' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 6, endLine: 1, @@ -1246,7 +1247,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 11, endLine: 1, @@ -1263,7 +1264,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceAfter', data: { token: '{' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 6, endLine: 1, @@ -1272,7 +1273,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 12, endLine: 1, @@ -1290,7 +1291,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 39, endLine: 1, @@ -1306,7 +1307,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 55, endLine: 1, @@ -1324,7 +1325,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 11, endLine: 1, @@ -1333,7 +1334,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 30, endLine: 1, @@ -1349,7 +1350,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 11, endLine: 1, @@ -1365,7 +1366,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 11, endLine: 1, @@ -1381,7 +1382,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 11, endLine: 1, @@ -1397,7 +1398,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 31, endLine: 1, @@ -1413,7 +1414,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 36, endLine: 1, @@ -1429,7 +1430,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceAfter', data: { token: '{' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 12, endLine: 1, @@ -1438,7 +1439,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 31, endLine: 1, @@ -1454,7 +1455,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceAfter', data: { token: '{' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 12, endLine: 1, @@ -1463,7 +1464,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 32, endLine: 1, @@ -1479,7 +1480,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 30, endLine: 1, @@ -1495,7 +1496,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 30, endLine: 1, @@ -1511,7 +1512,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 36, endLine: 1, @@ -1527,7 +1528,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceAfter', data: { token: '{' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 12, endLine: 1, @@ -1543,7 +1544,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceAfter', data: { token: '{' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 12, endLine: 1, @@ -1559,7 +1560,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceAfter', data: { token: '{' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 12, endLine: 1, @@ -1575,7 +1576,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 2, column: 10, endLine: 2, @@ -1591,7 +1592,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceAfter', data: { token: '{' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 12, endLine: 1, @@ -1600,7 +1601,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceAfter', data: { token: '{' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 19, endLine: 1, @@ -1616,7 +1617,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 27, endLine: 1, @@ -1625,7 +1626,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 39, endLine: 1, @@ -1642,7 +1643,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 22, endLine: 1, @@ -1661,7 +1662,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 5, endLine: 1, @@ -1670,7 +1671,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 10, endLine: 1, @@ -1687,7 +1688,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 11, endLine: 1, @@ -1704,7 +1705,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 16, endLine: 1, @@ -1721,7 +1722,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 5, endLine: 1, @@ -1738,7 +1739,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 5, endLine: 1, @@ -1755,7 +1756,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceAfter', data: { token: '{' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 6, endLine: 1, @@ -1764,7 +1765,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 11, endLine: 1, @@ -1781,7 +1782,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 10, endLine: 1, @@ -1798,7 +1799,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 15, endLine: 1, @@ -1815,7 +1816,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceAfter', data: { token: '{' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 6, endLine: 1, @@ -1832,7 +1833,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 11, endLine: 1, @@ -1849,7 +1850,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceAfter', data: { token: '{' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 5, endLine: 1, @@ -1867,7 +1868,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 25, endLine: 1, @@ -1883,7 +1884,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'requireSpaceBefore', data: { token: '}' }, - type: 'ObjectExpression', + type: AST_NODE_TYPES.ObjectExpression, line: 1, column: 49, endLine: 1, @@ -1901,7 +1902,7 @@ ruleTester.run('object-curly-spacing', rule, { { messageId: 'unexpectedSpaceBefore', data: { token: '}' }, - type: 'ObjectPattern', + type: AST_NODE_TYPES.ObjectPattern, line: 1, column: 20, endLine: 1,