From 9b0023a4996ecdd7dfcb30abd1678091a78f3064 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 30 Mar 2020 11:42:21 -0700 Subject: [PATCH 01/14] feat(eslint-plugin-internal): add plugin-test-formatting rule (#1821) The strings that are used for eslint plugins will not be checked for formatting. This can lead to diff noise as one contributor adjusts formatting, uses different quotes, etc. This rule just enforces the following: - all code samples are formatted with prettier - all single line tests do not use backticks - all multiline tests have: - no code on the first line - no code on the last line - the closing backtick indentation === property indentation - one of the following indentations: - no indentation at all - indentation of 1 + object indent examples of enforced style: ```ts ruleTester.run('foo', rule, { valid: [ 'const a = 1;', ` const a = 1; `, ` const a = 1; `, { code: 'const a = 1;', }, { code: ` const a = 1; `, }, { code: ` const a = 1; `, }, ], invalid: [ { code: 'const a = 1;', }, { code: ` const a = 1; `, }, { code: ` const a = 1; `, }, ], }); ``` --- .prettierrc.json | 1 + packages/eslint-plugin-internal/package.json | 3 +- .../eslint-plugin-internal/src/rules/index.ts | 2 + .../src/rules/plugin-test-formatting.ts | 508 +++++++++++++++++ .../rules/plugin-test-formatting.test.ts | 518 ++++++++++++++++++ packages/eslint-plugin/tests/RuleTester.ts | 14 +- .../eslint-plugin/tools/generate-configs.ts | 2 +- 7 files changed, 1045 insertions(+), 3 deletions(-) create mode 100644 packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts create mode 100644 packages/eslint-plugin-internal/tests/rules/plugin-test-formatting.test.ts diff --git a/.prettierrc.json b/.prettierrc.json index bf357fbbc081..a20502b7f06d 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,3 +1,4 @@ { + "singleQuote": true, "trailingComma": "all" } diff --git a/packages/eslint-plugin-internal/package.json b/packages/eslint-plugin-internal/package.json index 2a66b0484926..8e250384428e 100644 --- a/packages/eslint-plugin-internal/package.json +++ b/packages/eslint-plugin-internal/package.json @@ -12,6 +12,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "2.26.0" + "@typescript-eslint/experimental-utils": "2.26.0", + "prettier": "*" } } diff --git a/packages/eslint-plugin-internal/src/rules/index.ts b/packages/eslint-plugin-internal/src/rules/index.ts index f781e01e6df1..eb8d8efe8520 100644 --- a/packages/eslint-plugin-internal/src/rules/index.ts +++ b/packages/eslint-plugin-internal/src/rules/index.ts @@ -1,9 +1,11 @@ import noTypescriptDefaultImport from './no-typescript-default-import'; import noTypescriptEstreeImport from './no-typescript-estree-import'; +import pluginTestFormatting from './plugin-test-formatting'; import preferASTTypesEnum from './prefer-ast-types-enum'; export default { 'no-typescript-default-import': noTypescriptDefaultImport, 'no-typescript-estree-import': noTypescriptEstreeImport, + 'plugin-test-formatting': pluginTestFormatting, 'prefer-ast-types-enum': preferASTTypesEnum, }; diff --git a/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts b/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts new file mode 100644 index 000000000000..bc26d9d9d9a1 --- /dev/null +++ b/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts @@ -0,0 +1,508 @@ +import { + AST_NODE_TYPES, + TSESTree, +} from '@typescript-eslint/experimental-utils'; +import { format, resolveConfig } from 'prettier'; +import { createRule } from '../util'; + +/* +The strings that are used for eslint plugins will not be checked for formatting. +This can lead to diff noise as one contributor adjusts formatting, uses different quotes, etc. + +This rule just enforces the following: +- all code samples are formatted with prettier +- all single line tests do not use backticks +- all multiline tests have: + - no code on the first line + - no code on the last line + - the closing backtick indentation === property indentation + - one of the following indentations: + - no indentation at all + - indentation of 1 + object indent + +eg: +[ + 'const a = 1;', + ` +const a = 1; + `, + ` + const a = 1; + `, + { + code: 'const a = 1', + } + { + code: ` +const a = 1; + `, + } + { + code: ` + const a = 1; + `, + } +] +*/ + +const prettierConfig = resolveConfig.sync(__dirname) ?? {}; +const START_OF_LINE_WHITESPACE_MATCHER = /^([ ]*)/; +const BACKTICK_REGEX = /`/g; +const TEMPLATE_EXPR_OPENER = /\$\{/g; + +function getExpectedIndentForNode( + node: TSESTree.Node, + sourceCodeLines: string[], +): number { + const lineIdx = node.loc.start.line - 1; + const indent = START_OF_LINE_WHITESPACE_MATCHER.exec( + sourceCodeLines[lineIdx], + )![1]; + return indent.length; +} +function doIndent(line: string, indent: number): string { + for (let i = 0; i < indent; i += 1) { + line = ' ' + line; + } + return line; +} + +function getQuote(code: string): "'" | '"' | null { + const hasSingleQuote = code.includes("'"); + const hasDoubleQuote = code.includes('"'); + if (hasSingleQuote && hasDoubleQuote) { + // be lazy and make them fix and escape the quotes manually + return null; + } + + return hasSingleQuote ? '"' : "'"; +} + +function escapeTemplateString(code: string): string { + let fixed = code; + fixed = fixed.replace(BACKTICK_REGEX, '\\`'); + fixed = fixed.replace(TEMPLATE_EXPR_OPENER, '\\${'); + return fixed; +} + +type Options = [ + { + // This option exists so that rules like type-annotation-spacing can exist without every test needing a prettier-ignore + formatWithPrettier?: boolean; + }, +]; + +type MessageIds = + | 'invalidFormatting' + | 'invalidFormattingErrorTest' + | 'singleLineQuotes' + | 'templateLiteralEmptyEnds' + | 'templateLiteralLastLineIndent' + | 'templateStringRequiresIndent' + | 'templateStringMinimumIndent' + | 'prettierException'; + +export default createRule({ + name: 'plugin-test-formatting', + meta: { + type: 'problem', + docs: { + description: `Enforces that eslint-plugin test snippets are correctly formatted`, + category: 'Stylistic Issues', + recommended: 'error', + }, + fixable: 'code', + schema: [ + { + type: 'object', + additionalProperties: false, + properties: { + formatWithPrettier: { + type: 'boolean', + }, + }, + }, + ], + messages: { + invalidFormatting: + 'This snippet should be formatted correctly. Use the fixer to format the code.', + invalidFormattingErrorTest: + 'This snippet should be formatted correctly. Use the fixer to format the code. Note that the automated fixer may break your test locations.', + singleLineQuotes: 'Use quotes (\' or ") for single line tests.', + templateLiteralEmptyEnds: + 'Template literals must start and end with an empty line.', + templateLiteralLastLineIndent: + 'The closing line of the template literal must be indented to align with its parent.', + templateStringRequiresIndent: + 'Test code should either have no indent, or be indented {{indent}} spaces.', + templateStringMinimumIndent: + 'Test code should be indented at least {{indent}} spaces.', + prettierException: + 'Prettier was unable to format this snippet: {{message}}', + }, + }, + defaultOptions: [ + { + formatWithPrettier: true, + }, + ], + create(context, [{ formatWithPrettier }]) { + const sourceCode = context.getSourceCode(); + + function prettierFormat( + code: string, + location: TSESTree.Node, + ): string | null { + if (formatWithPrettier === false) { + return null; + } + + try { + return format(code, { + ...prettierConfig, + parser: 'typescript', + }).trimRight(); // prettier will insert a new line at the end of the code + } catch (ex) { + // adapted from https://github.com/prettier/eslint-plugin-prettier/blob/185b1064d3dd674538456fb2fad97fbfcde49e0d/eslint-plugin-prettier.js#L242-L257 + if (!(ex instanceof SyntaxError)) { + throw ex; + } + const err = ex as Error & { + codeFrame: string; + loc?: unknown; + }; + + let message = err.message; + + if (err.codeFrame) { + message = message.replace(`\n${err.codeFrame}`, ''); + } + if (err.loc) { + message = message.replace(/ \(\d+:\d+\)$/, ''); + } + + context.report({ + node: location, + messageId: 'prettierException', + data: { + message, + }, + }); + return null; + } + } + + function checkExpression(node: TSESTree.Node, isErrorTest: boolean): void { + switch (node.type) { + case AST_NODE_TYPES.Literal: + checkLiteral(node, isErrorTest); + break; + + case AST_NODE_TYPES.TemplateLiteral: + checkTemplateLiteral(node, isErrorTest); + break; + + case AST_NODE_TYPES.TaggedTemplateExpression: + checkTaggedTemplateExpression(node, isErrorTest); + break; + + case AST_NODE_TYPES.CallExpression: + checkCallExpression(node, isErrorTest); + break; + } + } + + function checkLiteral( + literal: TSESTree.Literal, + isErrorTest: boolean, + quoteIn?: string, + ): void { + if (typeof literal.value === 'string') { + const output = prettierFormat(literal.value, literal); + if (output && output !== literal.value) { + context.report({ + node: literal, + messageId: isErrorTest + ? 'invalidFormattingErrorTest' + : 'invalidFormatting', + fix(fixer) { + if (output.includes('\n')) { + // formatted string is multiline, then have to use backticks + return fixer.replaceText( + literal, + `\`${escapeTemplateString(output)}\``, + ); + } + + const quote = quoteIn ?? getQuote(output); + if (quote == null) { + return null; + } + + return fixer.replaceText(literal, `${quote}${output}${quote}`); + }, + }); + } + } + } + + function checkTemplateLiteral( + literal: TSESTree.TemplateLiteral, + isErrorTest: boolean, + isNoFormatTagged = false, + ): void { + if (literal.quasis.length > 1) { + // ignore template literals with ${expressions} for simplicity + return; + } + + const text = literal.quasis[0].value.cooked; + + if (literal.loc.end.line === literal.loc.start.line) { + // don't use template strings for single line tests + return context.report({ + node: literal, + messageId: 'singleLineQuotes', + fix(fixer) { + const quote = getQuote(text); + if (quote == null) { + return null; + } + + return [ + fixer.replaceTextRange( + [literal.range[0], literal.range[0] + 1], + quote, + ), + fixer.replaceTextRange( + [literal.range[1] - 1, literal.range[1]], + quote, + ), + ]; + }, + }); + } + + const lines = text.split('\n'); + const lastLine = lines[lines.length - 1]; + // prettier will trim out the end of line on save, but eslint will check before then + const isStartEmpty = lines[0].trimRight() === ''; + // last line can be indented + const isEndEmpty = lastLine.trimLeft() === ''; + if (!isStartEmpty || !isEndEmpty) { + // multiline template strings must have an empty first/last line + return context.report({ + node: literal, + messageId: 'templateLiteralEmptyEnds', + *fix(fixer) { + if (!isStartEmpty) { + yield fixer.replaceTextRange( + [literal.range[0], literal.range[0] + 1], + '`\n', + ); + } + + if (!isEndEmpty) { + yield fixer.replaceTextRange( + [literal.range[1] - 1, literal.range[1]], + '\n`', + ); + } + }, + }); + } + + const parentIndent = getExpectedIndentForNode(literal, sourceCode.lines); + if (lastLine.length !== parentIndent) { + return context.report({ + node: literal, + messageId: 'templateLiteralLastLineIndent', + fix(fixer) { + return fixer.replaceTextRange( + [literal.range[1] - lastLine.length - 1, literal.range[1]], + doIndent('`', parentIndent), + ); + }, + }); + } + + // remove the empty lines + lines.pop(); + lines.shift(); + + // +2 because we expect the string contents are indented one level + const expectedIndent = parentIndent + 2; + + const firstLineIndent = START_OF_LINE_WHITESPACE_MATCHER.exec( + lines[0], + )![1]; + const requiresIndent = firstLineIndent.length > 0; + if (requiresIndent) { + if (firstLineIndent.length !== expectedIndent) { + return context.report({ + node: literal, + messageId: 'templateStringRequiresIndent', + data: { + indent: expectedIndent, + }, + }); + } + + // quick-and-dirty validation that lines are roughly indented correctly + for (const line of lines) { + if (line.length === 0) { + // empty lines are valid + continue; + } + + const matches = START_OF_LINE_WHITESPACE_MATCHER.exec(line)!; + + const indent = matches[1]; + if (indent.length < expectedIndent) { + return context.report({ + node: literal, + messageId: 'templateStringMinimumIndent', + data: { + indent: expectedIndent, + }, + }); + } + } + + // trim the lines to remove expectedIndent characters from the start + // this makes it easier to check formatting + for (let i = 0; i < lines.length; i += 1) { + lines[i] = lines[i].substring(expectedIndent); + } + } + + if (isNoFormatTagged) { + return; + } + + const code = lines.join('\n'); + const formatted = prettierFormat(code, literal); + if (formatted && formatted !== code) { + const formattedIndented = requiresIndent + ? formatted + .split('\n') + .map(l => doIndent(l, expectedIndent)) + .join('\n') + : formatted; + + return context.report({ + node: literal, + messageId: isErrorTest + ? 'invalidFormattingErrorTest' + : 'invalidFormatting', + fix(fixer) { + return fixer.replaceText( + literal, + `\`\n${escapeTemplateString(formattedIndented)}\n${doIndent( + '', + parentIndent, + )}\``, + ); + }, + }); + } + } + + function isNoFormatTemplateTag(tag: TSESTree.Expression): boolean { + return tag.type === AST_NODE_TYPES.Identifier && tag.name === 'noFormat'; + } + + function checkTaggedTemplateExpression( + expr: TSESTree.TaggedTemplateExpression, + isErrorTest: boolean, + ): void { + if (!isNoFormatTemplateTag(expr.tag)) { + return; + } + + if (expr.loc.start.line === expr.loc.end.line) { + // all we do on single line test cases is check format, but there's no formatting to do + return; + } + + checkTemplateLiteral( + expr.quasi, + isErrorTest, + isNoFormatTemplateTag(expr.tag), + ); + } + + function checkCallExpression( + callExpr: TSESTree.CallExpression, + isErrorTest: boolean, + ): void { + if (callExpr.callee.type !== AST_NODE_TYPES.MemberExpression) { + return; + } + const memberExpr = callExpr.callee; + // handle cases like 'aa'.trimRight and `aa`.trimRight() + checkExpression(memberExpr.object, isErrorTest); + } + + function checkInvalidTest( + test: TSESTree.ObjectExpression, + isErrorTest = true, + ): void { + for (const prop of test.properties) { + if ( + prop.type !== AST_NODE_TYPES.Property || + prop.computed || + prop.key.type !== AST_NODE_TYPES.Identifier + ) { + continue; + } + + if (prop.key.name === 'code' || prop.key.name === 'output') { + checkExpression(prop.value, isErrorTest); + } + } + } + + function checkValidTest(tests: TSESTree.ArrayExpression): void { + for (const test of tests.elements) { + switch (test.type) { + case AST_NODE_TYPES.ObjectExpression: + // delegate object-style tests to the invalid checker + checkInvalidTest(test, false); + break; + + default: + checkExpression(test, false); + break; + } + } + } + + const invalidTestsSelectorPath = [ + AST_NODE_TYPES.CallExpression, + AST_NODE_TYPES.ObjectExpression, + 'Property[key.name = "invalid"]', + AST_NODE_TYPES.ArrayExpression, + AST_NODE_TYPES.ObjectExpression, + ]; + + return { + // valid + 'CallExpression > ObjectExpression > Property[key.name = "valid"] > ArrayExpression': checkValidTest, + // invalid - errors + [invalidTestsSelectorPath.join(' > ')]: checkInvalidTest, + // invalid - suggestions + [[ + ...invalidTestsSelectorPath, + 'Property[key.name = "errors"]', + AST_NODE_TYPES.ArrayExpression, + AST_NODE_TYPES.ObjectExpression, + 'Property[key.name = "suggestions"]', + AST_NODE_TYPES.ArrayExpression, + AST_NODE_TYPES.ObjectExpression, + ].join(' > ')]: checkInvalidTest, + // special case for our batchedSingleLineTests utility + 'CallExpression[callee.name = "batchedSingleLineTests"] > ObjectExpression': checkInvalidTest, + }; + }, +}); diff --git a/packages/eslint-plugin-internal/tests/rules/plugin-test-formatting.test.ts b/packages/eslint-plugin-internal/tests/rules/plugin-test-formatting.test.ts new file mode 100644 index 000000000000..8d7e0b2c1d85 --- /dev/null +++ b/packages/eslint-plugin-internal/tests/rules/plugin-test-formatting.test.ts @@ -0,0 +1,518 @@ +import rule from '../../src/rules/plugin-test-formatting'; +import { RuleTester } from '../RuleTester'; + +const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', + parserOptions: { + sourceType: 'module', + }, +}); + +const CODE_INDENT = ' '; +const PARENT_INDENT = ' '; +function wrap(strings: TemplateStringsArray, ...keys: string[]): string { + const lastIndex = strings.length - 1; + const code = + strings.slice(0, lastIndex).reduce((p, s, i) => p + s + keys[i], '') + + strings[lastIndex]; + return ` +ruleTester.run({ + valid: [ + { + code: ${code}, + }, + ], +}); + `; +} +function wrapWithOutput( + strings: TemplateStringsArray, + ...keys: string[] +): string { + const lastIndex = strings.length - 1; + const code = + strings.slice(0, lastIndex).reduce((p, s, i) => p + s + keys[i], '') + + strings[lastIndex]; + return ` +ruleTester.run({ + invalid: [ + { + code: ${code}, + output: ${code}, + }, + ], +}); + `; +} + +ruleTester.run('plugin-test-formatting', rule, { + valid: [ + // sanity check for valid tests non-object style + ` +ruleTester.run({ + valid: [ + 'const a = 1;', + \` + const a = 1; + \`, + \` +const a = 1; + \`, + noFormat\`const x=1;\`, + ], +}); + `, + wrap`'const a = 1;'`, + wrap`\` +${CODE_INDENT}const a = 1; +${PARENT_INDENT}\``, + wrap`\` +const a = 1; +${PARENT_INDENT}\``, + wrap`noFormat\`const a = 1;\``, + // sanity check suggestion validation + ` + ruleTester.run({ + invalid: [ + { + code: 'const a = 1;', + output: 'const a = 1;', + errors: [ + { + messageId: 'foo', + suggestions: [ + { + messageId: 'bar', + output: 'const a = 1;', + }, + ], + } + ] + }, + { + code: \` + const a = 1; + \`, + output: \` + const a = 1; + \`, + errors: [ + { + messageId: 'foo', + suggestions: [ + { + messageId: 'bar', + output: \` + const a = 1; + \`, + }, + ], + } + ] + }, + { + code: \` +const a = 1; + \`, + output: \` +const a = 1; + \`, + errors: [ + { + messageId: 'foo', + suggestions: [ + { + messageId: 'bar', + output: \` +const a = 1; + \`, + }, + ], + } + ] + }, + ], + }); + `, + + // test the only option + { + code: wrap`'const x=1;'`, + options: [ + { + formatWithPrettier: false, + }, + ], + }, + + // empty linems are valid when everything else is indented + wrap`\` +${CODE_INDENT}const a = 1; + +${CODE_INDENT}const b = 1; +${PARENT_INDENT}\``, + ], + invalid: [ + // Literal + { + code: wrap`'const a=1;'`, + output: wrap`'const a = 1;'`, + errors: [ + { + messageId: 'invalidFormatting', + }, + ], + }, + { + code: wrap`'const a="1";'`, + output: wrap`"const a = '1';"`, + errors: [ + { + messageId: 'invalidFormatting', + }, + ], + }, + { + code: wrap`"const a='1';"`, + output: wrap`"const a = '1';"`, + errors: [ + { + messageId: 'invalidFormatting', + }, + ], + }, + { + code: wrap`'for (const x of y) {}'`, + output: wrap`\`for (const x of y) { +}\``, + errors: [ + { + messageId: 'invalidFormatting', + }, + ], + }, + { + code: wrap`'for (const x of \`asdf\`) {}'`, + // make sure it escapes the backticks + output: wrap`\`for (const x of \\\`asdf\\\`) { +}\``, + errors: [ + { + messageId: 'invalidFormatting', + }, + ], + }, + // TemplateLiteral + // singleLineQuotes + { + code: wrap`\`const a = 1;\``, + output: wrap`'const a = 1;'`, + errors: [ + { + messageId: 'singleLineQuotes', + }, + ], + }, + { + code: wrap`\`const a = '1'\``, + output: wrap`"const a = '1'"`, + errors: [ + { + messageId: 'singleLineQuotes', + }, + ], + }, + { + code: wrap`\`const a = "1";\``, + output: wrap`'const a = "1";'`, + errors: [ + { + messageId: 'singleLineQuotes', + }, + ], + }, + // templateLiteralEmptyEnds + { + code: wrap`\`const a = "1"; +${PARENT_INDENT}\``, + output: wrap`\` +const a = "1"; +${PARENT_INDENT}\``, + errors: [ + { + messageId: 'templateLiteralEmptyEnds', + }, + ], + }, + { + code: wrap`\` +${CODE_INDENT}const a = "1";\``, + output: wrap`\` +${CODE_INDENT}const a = "1"; +\``, + errors: [ + { + messageId: 'templateLiteralEmptyEnds', + }, + ], + }, + { + code: wrap`\`const a = "1"; +${CODE_INDENT}const b = "2";\``, + output: wrap`\` +const a = "1"; +${CODE_INDENT}const b = "2"; +\``, + errors: [ + { + messageId: 'templateLiteralEmptyEnds', + }, + ], + }, + // templateLiteralLastLineIndent + { + code: wrap`\` +${CODE_INDENT}const a = "1"; +\``, + output: wrap`\` +${CODE_INDENT}const a = "1"; +${PARENT_INDENT}\``, + errors: [ + { + messageId: 'templateLiteralLastLineIndent', + }, + ], + }, + { + code: wrap`\` +${CODE_INDENT}const a = "1"; + \``, + output: wrap`\` +${CODE_INDENT}const a = "1"; +${PARENT_INDENT}\``, + errors: [ + { + messageId: 'templateLiteralLastLineIndent', + }, + ], + }, + // templateStringRequiresIndent + { + code: wrap`\` + const a = "1"; +${PARENT_INDENT}\``, + errors: [ + { + messageId: 'templateStringRequiresIndent', + data: { + indent: CODE_INDENT.length, + }, + }, + ], + }, + { + code: ` +ruleTester.run({ + valid: [ + \` + const a = "1"; + \`, + ], +}); + `, + errors: [ + { + messageId: 'templateStringRequiresIndent', + data: { + indent: 6, + }, + }, + ], + }, + // templateStringMinimumIndent + { + code: wrap`\` +${CODE_INDENT}const a = "1"; + const b = "2"; +${PARENT_INDENT}\``, + errors: [ + { + messageId: 'templateStringMinimumIndent', + data: { + indent: CODE_INDENT.length, + }, + }, + ], + }, + // invalidFormatting + { + code: wrap`\` +${CODE_INDENT}const a="1"; +${CODE_INDENT} const b = "2"; +${PARENT_INDENT}\``, + output: wrap`\` +${CODE_INDENT}const a = '1'; +${CODE_INDENT}const b = '2'; +${PARENT_INDENT}\``, + errors: [ + { + messageId: 'invalidFormatting', + }, + ], + }, + { + code: wrap`\` +${CODE_INDENT}const a=\\\`\\\${a}\\\`; +${PARENT_INDENT}\``, + // make sure it escapes backticks + output: wrap`\` +${CODE_INDENT}const a = \\\`\\\${a}\\\`; +${PARENT_INDENT}\``, + errors: [ + { + messageId: 'invalidFormatting', + }, + ], + }, + + // sanity check that it runs on both output and code properties + { + code: wrapWithOutput`\` +${CODE_INDENT}const a="1"; +${CODE_INDENT} const b = "2"; +${PARENT_INDENT}\``, + output: wrapWithOutput`\` +${CODE_INDENT}const a = '1'; +${CODE_INDENT}const b = '2'; +${PARENT_INDENT}\``, + errors: [ + { + messageId: 'invalidFormattingErrorTest', + }, + { + messageId: 'invalidFormattingErrorTest', + }, + ], + }, + + // sanity check that it handles suggestion output + { + code: ` +ruleTester.run({ + valid: [], + invalid: [ + { + code: 'const x=1;', + errors: [ + { + messageId: 'foo', + suggestions: [ + { + messageId: 'bar', + output: 'const x=1;', + }, + ], + }, + ], + }, + ], +}); + `, + errors: [ + { + messageId: 'invalidFormattingErrorTest', + }, + { + messageId: 'invalidFormattingErrorTest', + }, + ], + }, + + // sanity check that it runs on all tests + { + code: ` +ruleTester.run({ + valid: [ + { + code: \`foo\`, + }, + { + code: \`foo +\`, + }, + { + code: \` + foo\`, + }, + ], + invalid: [ + { + code: \`foo\`, + }, + { + code: \`foo +\`, + }, + { + code: \` + foo\`, + }, + ], +}); + `, + errors: [ + { + messageId: 'singleLineQuotes', + }, + { + messageId: 'templateLiteralEmptyEnds', + }, + { + messageId: 'templateLiteralEmptyEnds', + }, + { + messageId: 'singleLineQuotes', + }, + { + messageId: 'templateLiteralEmptyEnds', + }, + { + messageId: 'templateLiteralEmptyEnds', + }, + ], + }, + + // handles prettier errors + { + code: wrap`'const x = ";'`, + errors: [ + { + messageId: 'prettierException', + data: { + message: 'Unterminated string literal.', + }, + }, + ], + }, + + // checks tests with .trimRight calls + { + code: wrap`'const a=1;'.trimRight()`, + output: wrap`'const a = 1;'.trimRight()`, + errors: [ + { + messageId: 'invalidFormatting', + }, + ], + }, + { + code: wrap`\`const a = "1"; +${CODE_INDENT}\`.trimRight()`, + errors: [ + { + messageId: 'templateLiteralEmptyEnds', + }, + ], + }, + ], +}); diff --git a/packages/eslint-plugin/tests/RuleTester.ts b/packages/eslint-plugin/tests/RuleTester.ts index c650c83449c4..1774200db322 100644 --- a/packages/eslint-plugin/tests/RuleTester.ts +++ b/packages/eslint-plugin/tests/RuleTester.ts @@ -89,4 +89,16 @@ afterAll(() => { clearCaches(); }); -export { RuleTester, getFixturesRootDir, batchedSingleLineTests }; +/** + * Simple no-op tag to mark code samples as "should not format with prettier" + * for the internal/plugin-test-formatting lint rule + */ +function noFormat(strings: TemplateStringsArray, ...keys: string[]): string { + const lastIndex = strings.length - 1; + return ( + strings.slice(0, lastIndex).reduce((p, s, i) => p + s + keys[i], '') + + strings[lastIndex] + ); +} + +export { batchedSingleLineTests, getFixturesRootDir, noFormat, RuleTester }; diff --git a/packages/eslint-plugin/tools/generate-configs.ts b/packages/eslint-plugin/tools/generate-configs.ts index d35fd7362bcd..e9d2a8be7625 100644 --- a/packages/eslint-plugin/tools/generate-configs.ts +++ b/packages/eslint-plugin/tools/generate-configs.ts @@ -5,7 +5,7 @@ import path from 'path'; import { format, resolveConfig } from 'prettier'; import rules from '../src/rules'; -const prettierConfig = resolveConfig(__dirname); +const prettierConfig = resolveConfig.sync(__dirname); interface LinterConfigRules { [name: string]: From 8ec53a3579fcb59cdffea0c60fbb755d056f4c8a Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 30 Mar 2020 17:04:10 -0700 Subject: [PATCH 02/14] fix(eslint-plugin): [no-unsafe-call] fix incorrect selector (#1826) --- packages/eslint-plugin/src/rules/no-unsafe-call.ts | 2 +- packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/no-unsafe-call.ts b/packages/eslint-plugin/src/rules/no-unsafe-call.ts index 13cabc87d924..66f66448c28b 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-call.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-call.ts @@ -41,7 +41,7 @@ export default util.createRule<[], MessageIds>({ } return { - ':matches(CallExpression, OptionalCallExpression) > :not(Import)'( + ':matches(CallExpression, OptionalCallExpression) > :not(Import).callee'( node: Exclude, ): void { checkCall(node, node, 'unsafeCall'); diff --git a/packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts b/packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts index a51273c9b9cf..bc7b6c7d0860 100644 --- a/packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts @@ -21,6 +21,11 @@ ruleTester.run('no-unsafe-call', rule, { 'new Map()', 'String.raw`foo`', 'const x = import("./foo");', + // https://github.com/typescript-eslint/typescript-eslint/issues/1825 + ` + let foo: any = 23; + String(foo); // ERROR: Unsafe call of an any typed value + `, ], invalid: [ ...batchedSingleLineTests({ From 9642d9dce693befac89a4e9d8bf8dd18f4361e2a Mon Sep 17 00:00:00 2001 From: Anix Date: Tue, 31 Mar 2020 09:53:23 +0530 Subject: [PATCH 03/14] fix(eslint-plugin): [require-await] handle async generators (#1782) Co-authored-by: Brad Zacher --- .../eslint-plugin/src/rules/require-await.ts | 38 ++- .../tests/rules/require-await.test.ts | 244 +++++++++++++----- 2 files changed, 217 insertions(+), 65 deletions(-) diff --git a/packages/eslint-plugin/src/rules/require-await.ts b/packages/eslint-plugin/src/rules/require-await.ts index e7b6a5f5959a..99c455cd0f6a 100644 --- a/packages/eslint-plugin/src/rules/require-await.ts +++ b/packages/eslint-plugin/src/rules/require-await.ts @@ -11,6 +11,8 @@ interface ScopeInfo { upper: ScopeInfo | null; hasAwait: boolean; hasAsync: boolean; + isGen: boolean; + isAsyncYield: boolean; } type FunctionNode = | TSESTree.FunctionDeclaration @@ -49,6 +51,8 @@ export default util.createRule({ upper: scopeInfo, hasAwait: false, hasAsync: node.async, + isGen: node.generator || false, + isAsyncYield: false, }; } @@ -62,7 +66,12 @@ export default util.createRule({ return; } - if (node.async && !scopeInfo.hasAwait && !isEmptyFunction(node)) { + if ( + node.async && + !scopeInfo.hasAwait && + !isEmptyFunction(node) && + !(scopeInfo.isGen && scopeInfo.isAsyncYield) + ) { context.report({ node, loc: getFunctionHeadLoc(node, sourceCode), @@ -92,10 +101,34 @@ export default util.createRule({ if (!scopeInfo) { return; } - scopeInfo.hasAwait = true; } + /** + * mark `scopeInfo.isAsyncYield` to `true` if its a generator + * function and the delegate is `true` + */ + function markAsHasDelegateGen(node: TSESTree.YieldExpression): void { + if (!scopeInfo || !scopeInfo.isGen || !node.argument) { + return; + } + + if (node?.argument?.type === AST_NODE_TYPES.Literal) { + // making this `false` as for literals we don't need to check the definition + // eg : async function* run() { yield* 1 } + scopeInfo.isAsyncYield = false; + } + + const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node?.argument); + const type = checker.getTypeAtLocation(tsNode); + const symbol = type.getSymbol(); + + // async function* test1() {yield* asyncGenerator() } + if (symbol?.getName() === 'AsyncGenerator') { + scopeInfo.isAsyncYield = true; + } + } + return { FunctionDeclaration: enterFunction, FunctionExpression: enterFunction, @@ -106,6 +139,7 @@ export default util.createRule({ AwaitExpression: markAsHasAwait, 'ForOfStatement[await = true]': markAsHasAwait, + 'YieldExpression[delegate = true]': markAsHasDelegateGen, // check body-less async arrow function. // ignore `async () => await foo` because it's obviously correct diff --git a/packages/eslint-plugin/tests/rules/require-await.test.ts b/packages/eslint-plugin/tests/rules/require-await.test.ts index 66db54979806..caea93fbfb95 100644 --- a/packages/eslint-plugin/tests/rules/require-await.test.ts +++ b/packages/eslint-plugin/tests/rules/require-await.test.ts @@ -16,102 +16,130 @@ ruleTester.run('require-await', rule, { valid: [ // Non-async function declaration `function numberOne(): number { - return 1; - }`, + return 1; + }`, // Non-async function expression `const numberOne = function(): number { - return 1; - }`, + return 1; + }`, // Non-async arrow function expression (concise-body) `const numberOne = (): number => 1;`, // Non-async arrow function expression (block-body) `const numberOne = (): number => { - return 1; - };`, + return 1; + };`, // Non-async function that returns a promise // https://github.com/typescript-eslint/typescript-eslint/issues/1226 ` -function delay() { - return Promise.resolve(); -} - `, + function delay() { + return Promise.resolve(); + } + `, ` -const delay = () => { - return Promise.resolve(); -} - `, + const delay = () => { + return Promise.resolve(); + } + `, `const delay = () => Promise.resolve();`, // Async function declaration with await `async function numberOne(): Promise { - return await 1; - }`, + return await 1; + }`, // Async function expression with await `const numberOne = async function(): Promise { - return await 1; - }`, + return await 1; + }`, // Async arrow function expression with await (concise-body) `const numberOne = async (): Promise => await 1;`, // Async arrow function expression with await (block-body) `const numberOne = async (): Promise => { - return await 1; - };`, + return await 1; + };`, // Async function declaration with promise return `async function numberOne(): Promise { - return Promise.resolve(1); - }`, + return Promise.resolve(1); + }`, // Async function expression with promise return `const numberOne = async function(): Promise { - return Promise.resolve(1); - }`, + return Promise.resolve(1); + }`, // Async arrow function with promise return (concise-body) `const numberOne = async (): Promise => Promise.resolve(1);`, // Async arrow function with promise return (block-body) `const numberOne = async (): Promise => { - return Promise.resolve(1); - };`, + return Promise.resolve(1); + };`, // Async function declaration with async function return `async function numberOne(): Promise { - return getAsyncNumber(1); - } - async function getAsyncNumber(x: number): Promise { - return Promise.resolve(x); - }`, + return getAsyncNumber(1); + } + async function getAsyncNumber(x: number): Promise { + return Promise.resolve(x); + }`, // Async function expression with async function return `const numberOne = async function(): Promise { - return getAsyncNumber(1); - } - const getAsyncNumber = async function(x: number): Promise { - return Promise.resolve(x); - }`, + return getAsyncNumber(1); + } + const getAsyncNumber = async function(x: number): Promise { + return Promise.resolve(x); + }`, // Async arrow function with async function return (concise-body) `const numberOne = async (): Promise => getAsyncNumber(1); - const getAsyncNumber = async function(x: number): Promise { - return Promise.resolve(x); - }`, + const getAsyncNumber = async function(x: number): Promise { + return Promise.resolve(x); + }`, // Async arrow function with async function return (block-body) `const numberOne = async (): Promise => { - return getAsyncNumber(1); - }; - const getAsyncNumber = async function(x: number): Promise { - return Promise.resolve(x); - }`, + return getAsyncNumber(1); + }; + const getAsyncNumber = async function(x: number): Promise { + return Promise.resolve(x); + }`, // https://github.com/typescript-eslint/typescript-eslint/issues/1188 ` -async function testFunction(): Promise { - await Promise.all([1, 2, 3].map( - // this should not trigger an error on the parent function - async value => Promise.resolve(value) - )) -} + async function testFunction(): Promise { + await Promise.all([1, 2, 3].map( + // this should not trigger an error on the parent function + async value => Promise.resolve(value) + )) + } + `, + ` + async function* run() { + await new Promise(resolve => setTimeout(resolve, 100)); + yield 'Hello'; + console.log('World'); + } + `, + 'async function* run() { }', + 'async function* asyncGenerator() { await Promise.resolve(); yield 1 }', + 'function* test6() { yield* syncGenerator() }', + 'function* test8() { yield syncGenerator() }', + 'function* syncGenerator() { yield 1 }', + ` + async function* asyncGenerator() { + await Promise.resolve() + yield 1 + } + async function* test1() {yield* asyncGenerator() } `, + `async function* foo() { + await Promise.resolve() + yield 1 + } + async function* bar() { + yield* foo() + }`, + 'const foo : () => void = async function *(){}', + 'async function* foo() : Promise { return new Promise((res) => res(`hello`)) }', ], invalid: [ { // Async function declaration with no await code: `async function numberOne(): Promise { - return 1; - }`, + return 1; + }`, errors: [ { messageId: 'missingAwait', @@ -124,8 +152,8 @@ async function testFunction(): Promise { { // Async function expression with no await code: `const numberOne = async function(): Promise { - return 1; - }`, + return 1; + }`, errors: [ { messageId: 'missingAwait', @@ -160,9 +188,85 @@ async function testFunction(): Promise { }, ], }, + { + code: 'async function* foo() : void { doSomething() }', + errors: [ + { + messageId: 'missingAwait', + data: { + name: "Async generator function 'foo'", + }, + }, + ], + }, + { + code: 'async function* foo() { yield 1 }', + errors: [ + { + messageId: 'missingAwait', + data: { + name: "Async generator function 'foo'", + }, + }, + ], + }, + { + code: 'async function* run() { console.log("bar") }', + errors: [ + { + messageId: 'missingAwait', + data: { + name: "Async generator function 'run'", + }, + }, + ], + }, + { + code: 'const foo = async function *(){ console.log("bar") }', + errors: [ + { + messageId: 'missingAwait', + data: { + name: 'Async generator function', + }, + }, + ], + }, + { + code: 'async function* syncGenerator() { yield 1 }', + errors: [ + { + messageId: 'missingAwait', + data: { + name: "Async generator function 'syncGenerator'", + }, + }, + ], + }, + { + code: 'async function* test3() { yield asyncGenerator() }', + errors: [ + { + messageId: 'missingAwait', + data: { + name: "Async generator function 'test3'", + }, + }, + ], + }, + { + code: 'async function* test7() { yield syncGenerator() }', + errors: [ + { + messageId: 'missingAwait', + data: { + name: "Async generator function 'test7'", + }, + }, + ], + }, ], }); - // base eslint tests // https://github.com/eslint/eslint/blob/03a69dbe86d5b5768a310105416ae726822e3c1c/tests/lib/rules/require-await.js#L25-L132 ruleTester.run('require-await', rule, { @@ -175,27 +279,23 @@ ruleTester.run('require-await', rule, { 'class A { async foo() { await doSomething() } }', '(class { async foo() { await doSomething() } })', 'async function foo() { await (async () => { await doSomething() }) }', - // empty functions are ok. 'async function foo() {}', 'async () => {}', - // normal functions are ok. 'function foo() { doSomething() }', - // for-await-of 'async function foo() { for await (x of xs); }', - // global await { code: 'await foo()', }, { code: ` - for await (let num of asyncIterable) { - console.log(num); - } - `, + for await (let num of asyncIterable) { + console.log(num); + } + `, }, ], invalid: [ @@ -289,5 +389,23 @@ ruleTester.run('require-await', rule, { }, ], }, + { + code: 'async function* run() { yield * anotherAsyncGenerator() }', + errors: [ + { + messageId: 'missingAwait', + data: { name: "Async generator function 'run'" }, + }, + ], + }, + { + code: 'async function* run() { yield* 1 }', + errors: [ + { + messageId: 'missingAwait', + data: { name: "Async generator function 'run'" }, + }, + ], + }, ], }); From 188b68979d114ba0957a076fe9c27d154223512c Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 30 Mar 2020 23:31:50 -0700 Subject: [PATCH 04/14] chore: turn on plugin-test-formatting rule (#1822) --- .eslintrc.js | 13 +- .../tests/rules/no-typescript-estree.test.ts | 18 +- .../rules/plugin-test-formatting.test.ts | 1 + .../tests/rules/prefer-ast-types-enum.test.ts | 28 +- .../adjacent-overload-signatures.test.ts | 640 ++++++------ .../tests/rules/array-type.test.ts | 430 +++++---- .../tests/rules/await-thenable.test.ts | 67 +- .../tests/rules/ban-ts-comment.test.ts | 50 +- .../tests/rules/ban-ts-ignore.test.ts | 16 +- .../tests/rules/ban-types.test.ts | 52 +- .../tests/rules/brace-style.test.ts | 352 +++---- .../tests/rules/camelcase.test.ts | 200 +++- .../class-literal-property-style.test.ts | 431 ++++++--- .../tests/rules/class-name-casing.test.ts | 21 +- .../tests/rules/comma-spacing.test.ts | 347 +++---- .../rules/consistent-type-definitions.test.ts | 86 +- .../tests/rules/default-param-last.test.ts | 96 +- .../explicit-function-return-type.test.ts | 303 +++--- .../explicit-member-accessibility.test.ts | 368 +++---- .../explicit-module-boundary-types.test.ts | 306 +++--- .../tests/rules/func-call-spacing.test.ts | 9 +- .../tests/rules/generic-type-naming.test.ts | 95 +- .../tests/rules/indent/indent-eslint.test.ts | 5 + .../tests/rules/indent/indent.test.ts | 108 ++- .../tests/rules/interface-name-prefix.test.ts | 56 +- .../rules/member-delimiter-style.test.ts | 407 ++++---- .../tests/rules/member-naming.test.ts | 186 ++-- .../tests/rules/member-ordering.test.ts | 3 + .../tests/rules/naming-convention.test.ts | 23 +- .../tests/rules/no-array-constructor.test.ts | 94 +- .../tests/rules/no-base-to-string.test.ts | 114 ++- .../tests/rules/no-dupe-class-members.test.ts | 153 ++- .../tests/rules/no-dynamic-delete.test.ts | 200 ++-- .../tests/rules/no-empty-function.test.ts | 65 +- .../tests/rules/no-empty-interface.test.ts | 42 +- .../tests/rules/no-explicit-any.test.ts | 185 ++-- .../rules/no-extra-non-null-assertion.test.ts | 21 +- .../tests/rules/no-extra-parens.test.ts | 9 +- .../tests/rules/no-extra-semi.test.ts | 5 + .../tests/rules/no-extraneous-class.test.ts | 94 +- .../tests/rules/no-floating-promises.test.ts | 284 ++++-- .../tests/rules/no-for-in-array.test.ts | 20 +- .../tests/rules/no-implied-eval.test.ts | 105 +- .../tests/rules/no-inferrable-types.test.ts | 68 +- .../tests/rules/no-magic-numbers.test.ts | 16 +- .../tests/rules/no-misused-new.test.ts | 117 ++- .../tests/rules/no-misused-promises.test.ts | 178 ++-- .../tests/rules/no-namespace.test.ts | 22 +- ...o-non-null-asserted-optional-chain.test.ts | 62 +- .../tests/rules/no-non-null-assertion.test.ts | 68 +- .../rules/no-parameter-properties.test.ts | 264 ++--- .../tests/rules/no-require-imports.test.ts | 46 +- .../tests/rules/no-this-alias.test.ts | 42 +- .../tests/rules/no-throw-literal.test.ts | 66 +- .../tests/rules/no-type-alias.test.ts | 384 ++++---- ...nnecessary-boolean-literal-compare.test.ts | 26 +- .../rules/no-unnecessary-condition.test.ts | 314 +++--- .../rules/no-unnecessary-qualifier.test.ts | 86 +- .../no-unnecessary-type-arguments.test.ts | 314 +++--- .../no-unnecessary-type-assertion.test.ts | 151 +-- .../tests/rules/no-unsafe-call.test.ts | 33 +- .../rules/no-unsafe-member-access.test.ts | 67 +- .../tests/rules/no-unsafe-return.test.ts | 85 +- .../rules/no-untyped-public-signature.test.ts | 203 ++-- .../tests/rules/no-unused-expressions.test.ts | 49 +- .../tests/rules/no-unused-vars.test.ts | 476 ++++----- .../tests/rules/no-use-before-define.test.ts | 324 ++++--- .../rules/no-useless-constructor.test.ts | 292 +++++- .../tests/rules/no-var-requires.test.ts | 24 +- .../tests/rules/prefer-as-const.test.ts | 38 +- .../tests/rules/prefer-for-of.test.ts | 156 ++- .../tests/rules/prefer-function-type.test.ts | 61 +- .../rules/prefer-namespace-keyword.test.ts | 28 +- .../tests/rules/prefer-optional-chain.test.ts | 74 +- .../prefer-readonly-parameter-types.test.ts | 129 +-- .../tests/rules/prefer-readonly.test.ts | 734 ++++++++------ .../tests/rules/prefer-regexp-exec.test.ts | 48 +- .../rules/promise-function-async.test.ts | 132 ++- .../eslint-plugin/tests/rules/quotes.test.ts | 123 +-- .../rules/require-array-sort-compare.test.ts | 55 +- .../tests/rules/require-await.test.ts | 469 +++++---- .../rules/restrict-plus-operands.test.ts | 171 ++-- .../restrict-template-expressions.test.ts | 16 +- .../tests/rules/return-await.test.ts | 599 +++++++----- .../eslint-plugin/tests/rules/semi.test.ts | 464 ++++----- .../rules/space-before-function-paren.test.ts | 5 + .../rules/strict-boolean-expressions.test.ts | 184 ++-- .../rules/switch-exhaustiveness-check.test.ts | 314 +++--- .../rules/triple-slash-reference.test.ts | 80 +- .../rules/type-annotation-spacing.test.ts | 909 +++++++++--------- .../eslint-plugin/tests/rules/typedef.test.ts | 412 +++++--- .../tests/rules/unbound-method.test.ts | 36 +- .../tests/rules/unified-signatures.test.ts | 307 +++--- 93 files changed, 8819 insertions(+), 6610 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 39ca61de5168..cee2ec901cca 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -174,7 +174,7 @@ module.exports = { '@typescript-eslint/internal/no-typescript-estree-import': 'error', }, }, - // rule source files + // plugin rule source files { files: [ 'packages/eslint-plugin-internal/src/rules/**/*.ts', @@ -187,6 +187,17 @@ module.exports = { 'import/no-default-export': 'off', }, }, + // plugin rule tests + { + files: [ + 'packages/eslint-plugin-internal/tests/rules/**/*.test.ts', + 'packages/eslint-plugin-tslint/tests/rules/**/*.test.ts', + 'packages/eslint-plugin/tests/rules/**/*.test.ts', + ], + rules: { + '@typescript-eslint/internal/plugin-test-formatting': 'error', + }, + }, // tools and tests { files: ['**/tools/**/*.ts', '**/tests/**/*.ts'], diff --git a/packages/eslint-plugin-internal/tests/rules/no-typescript-estree.test.ts b/packages/eslint-plugin-internal/tests/rules/no-typescript-estree.test.ts index a76e03b7c1d5..74b9478b58a1 100644 --- a/packages/eslint-plugin-internal/tests/rules/no-typescript-estree.test.ts +++ b/packages/eslint-plugin-internal/tests/rules/no-typescript-estree.test.ts @@ -10,20 +10,20 @@ const ruleTester = new RuleTester({ ruleTester.run('no-typescript-estree-import', rule, { valid: [ - 'import { foo } from "@typescript-eslint/experimental-utils";', - 'import foo from "@typescript-eslint/experimental-utils";', - 'import * as foo from "@typescript-eslint/experimental-utils";', + "import { foo } from '@typescript-eslint/experimental-utils';", + "import foo from '@typescript-eslint/experimental-utils';", + "import * as foo from '@typescript-eslint/experimental-utils';", ], invalid: batchedSingleLineTests({ code: ` -import { foo } from "@typescript-eslint/typescript-estree"; -import foo from "@typescript-eslint/typescript-estree"; -import * as foo from "@typescript-eslint/typescript-estree"; +import { foo } from '@typescript-eslint/typescript-estree'; +import foo from '@typescript-eslint/typescript-estree'; +import * as foo from '@typescript-eslint/typescript-estree'; `, output: ` -import { foo } from "@typescript-eslint/experimental-utils"; -import foo from "@typescript-eslint/experimental-utils"; -import * as foo from "@typescript-eslint/experimental-utils"; +import { foo } from '@typescript-eslint/experimental-utils'; +import foo from '@typescript-eslint/experimental-utils'; +import * as foo from '@typescript-eslint/experimental-utils'; `, errors: [ { diff --git a/packages/eslint-plugin-internal/tests/rules/plugin-test-formatting.test.ts b/packages/eslint-plugin-internal/tests/rules/plugin-test-formatting.test.ts index 8d7e0b2c1d85..c2af09bec90a 100644 --- a/packages/eslint-plugin-internal/tests/rules/plugin-test-formatting.test.ts +++ b/packages/eslint-plugin-internal/tests/rules/plugin-test-formatting.test.ts @@ -71,6 +71,7 @@ const a = 1; ${PARENT_INDENT}\``, wrap`noFormat\`const a = 1;\``, // sanity check suggestion validation + // eslint-disable-next-line @typescript-eslint/internal/plugin-test-formatting ` ruleTester.run({ invalid: [ diff --git a/packages/eslint-plugin-internal/tests/rules/prefer-ast-types-enum.test.ts b/packages/eslint-plugin-internal/tests/rules/prefer-ast-types-enum.test.ts index 2688e035b59c..c2ffd8e489e0 100644 --- a/packages/eslint-plugin-internal/tests/rules/prefer-ast-types-enum.test.ts +++ b/packages/eslint-plugin-internal/tests/rules/prefer-ast-types-enum.test.ts @@ -14,29 +14,29 @@ const ruleTester = new RuleTester({ ruleTester.run('prefer-ast-types-enum', rule, { valid: [ - 'node.type === "constructor"', - 'node.type === AST_NODE_TYPES.Literal', - 'node.type === AST_TOKEN_TYPES.Keyword', - 'node.type === 1', + "node.type === 'constructor';", + 'node.type === AST_NODE_TYPES.Literal;', + 'node.type === AST_TOKEN_TYPES.Keyword;', + 'node.type === 1;', ` - enum MY_ENUM { - Literal = 1 - } + enum MY_ENUM { + Literal = 1, + } `, ` - enum AST_NODE_TYPES { - Literal = 'Literal' - } + enum AST_NODE_TYPES { + Literal = 'Literal', + } `, ], invalid: batchedSingleLineTests({ code: ` -node.type === 'Literal' -node.type === 'Keyword' +node.type === 'Literal'; +node.type === 'Keyword'; `, output: ` -node.type === AST_NODE_TYPES.Literal -node.type === AST_TOKEN_TYPES.Keyword +node.type === AST_NODE_TYPES.Literal; +node.type === AST_TOKEN_TYPES.Keyword; `, errors: [ { diff --git a/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts b/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts index c040362a1286..8e844bb96bef 100644 --- a/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts +++ b/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts @@ -11,217 +11,224 @@ ruleTester.run('adjacent-overload-signatures', rule, { code: ` function error(a: string); function error(b: number); -function error(ab: string|number){ } +function error(ab: string | number) {} export { error }; - `, + `, parserOptions: { sourceType: 'module' }, }, { code: ` import { connect } from 'react-redux'; -export interface ErrorMessageModel { message: string; } -function mapStateToProps() { } -function mapDispatchToProps() { } +export interface ErrorMessageModel { + message: string; +} +function mapStateToProps() {} +function mapDispatchToProps() {} export default connect(mapStateToProps, mapDispatchToProps)(ErrorMessage); - `, + `, parserOptions: { sourceType: 'module' }, }, ` -export const foo = "a", bar = "b"; +export const foo = 'a', + bar = 'b'; export interface Foo {} export class Foo {} - `, + `, ` export interface Foo {} -export const foo = "a", bar = "b"; +export const foo = 'a', + bar = 'b'; export class Foo {} - `, + `, ` -const foo = "a", bar = "b"; +const foo = 'a', + bar = 'b'; interface Foo {} class Foo {} - `, + `, ` interface Foo {} -const foo = "a", bar = "b"; +const foo = 'a', + bar = 'b'; class Foo {} - `, + `, ` export class Foo {} export class Bar {} export type FooBar = Foo | Bar; - `, + `, ` export interface Foo {} export class Foo {} export class Bar {} export type FooBar = Foo | Bar; - `, + `, ` export function foo(s: string); export function foo(n: number); export function foo(sn: string | number) {} export function bar(): void {} export function baz(): void {} - `, + `, ` function foo(s: string); function foo(n: number); function foo(sn: string | number) {} function bar(): void {} function baz(): void {} - `, + `, ` declare function foo(s: string); declare function foo(n: number); declare function foo(sn: string | number); declare function bar(): void; declare function baz(): void; - `, + `, ` -declare module "Foo" { - export function foo(s: string): void; - export function foo(n: number): void; - export function foo(sn: string | number): void; - export function bar(): void; - export function baz(): void; -} - `, +declare module 'Foo' { + export function foo(s: string): void; + export function foo(n: number): void; + export function foo(sn: string | number): void; + export function bar(): void; + export function baz(): void; +} + `, ` declare namespace Foo { - export function foo(s: string): void; - export function foo(n: number): void; - export function foo(sn: string | number): void; - export function bar(): void; - export function baz(): void; + export function foo(s: string): void; + export function foo(n: number): void; + export function foo(sn: string | number): void; + export function bar(): void; + export function baz(): void; } - `, + `, ` type Foo = { - foo(s: string): void; - foo(n: number): void; - foo(sn: string | number): void; - bar(): void; - baz(): void; -} - `, + foo(s: string): void; + foo(n: number): void; + foo(sn: string | number): void; + bar(): void; + baz(): void; +}; + `, ` type Foo = { - foo(s: string): void; - ["foo"](n: number): void; - foo(sn: string | number): void; - bar(): void; - baz(): void; -} - `, + foo(s: string): void; + ['foo'](n: number): void; + foo(sn: string | number): void; + bar(): void; + baz(): void; +}; + `, ` interface Foo { - (s: string): void; - (n: number): void; - (sn: string | number): void; - foo(n: number): void; - bar(): void; - baz(): void; -} - `, + (s: string): void; + (n: number): void; + (sn: string | number): void; + foo(n: number): void; + bar(): void; + baz(): void; +} + `, ` interface Foo { - foo(s: string): void; - foo(n: number): void; - foo(sn: string | number): void; - bar(): void; - baz(): void; + foo(s: string): void; + foo(n: number): void; + foo(sn: string | number): void; + bar(): void; + baz(): void; } - `, + `, ` interface Foo { - foo(s: string): void; - ["foo"](n: number): void; - foo(sn: string | number): void; - bar(): void; - baz(): void; + foo(s: string): void; + ['foo'](n: number): void; + foo(sn: string | number): void; + bar(): void; + baz(): void; } - `, + `, ` interface Foo { - foo(): void; - bar: { - baz(s: string): void; - baz(n: number): void; - baz(sn: string | number): void; - } -} - `, + foo(): void; + bar: { + baz(s: string): void; + baz(n: number): void; + baz(sn: string | number): void; + }; +} + `, ` interface Foo { - new(s: string); - new(n: number); - new(sn: string | number); - foo(): void; + new (s: string); + new (n: number); + new (sn: string | number); + foo(): void; } - `, + `, ` class Foo { - constructor(s: string); - constructor(n: number); - constructor(sn: string | number) {} - bar(): void {} - baz(): void {} + constructor(s: string); + constructor(n: number); + constructor(sn: string | number) {} + bar(): void {} + baz(): void {} } - `, + `, ` class Foo { - foo(s: string): void; - foo(n: number): void; - foo(sn: string | number): void {} - bar(): void {} - baz(): void {} + foo(s: string): void; + foo(n: number): void; + foo(sn: string | number): void {} + bar(): void {} + baz(): void {} } - `, + `, ` class Foo { - foo(s: string): void; - ["foo"](n: number): void; - foo(sn: string | number): void {} - bar(): void {} - baz(): void {} + foo(s: string): void; + ['foo'](n: number): void; + foo(sn: string | number): void {} + bar(): void {} + baz(): void {} } - `, + `, ` class Foo { - name: string; - foo(s: string): void; - foo(n: number): void; - foo(sn: string | number): void {} - bar(): void {} - baz(): void {} -} - `, + name: string; + foo(s: string): void; + foo(n: number): void; + foo(sn: string | number): void {} + bar(): void {} + baz(): void {} +} + `, ` class Foo { - name: string; - static foo(s: string): void; - static foo(n: number): void; - static foo(sn: string | number): void {} - bar(): void {} - baz(): void {} -} - `, + name: string; + static foo(s: string): void; + static foo(n: number): void; + static foo(sn: string | number): void {} + bar(): void {} + baz(): void {} +} + `, ` class Test { static test() {} untest() {} test() {} } - `, + `, // examples from https://github.com/nzakas/eslint-plugin-typescript/issues/138 - 'export default function(foo : T) {}', - 'export default function named(foo : T) {}', + 'export default function(foo: T) {}', + 'export default function named(foo: T) {}', ` interface Foo { [Symbol.toStringTag](): void; [Symbol.iterator](): void; -}`, +} + `, ], invalid: [ { @@ -231,7 +238,7 @@ export function foo(n: number); export function bar(): void {} export function baz(): void {} export function foo(sn: string | number) {} - `, + `, errors: [ { messageId: 'adjacentSignature', @@ -248,7 +255,7 @@ export function foo(n: number); export type bar = number; export type baz = number | string; export function foo(sn: string | number) {} - `, + `, errors: [ { messageId: 'adjacentSignature', @@ -265,7 +272,7 @@ function foo(n: number); function bar(): void {} function baz(): void {} function foo(sn: string | number) {} - `, + `, errors: [ { messageId: 'adjacentSignature', @@ -282,7 +289,7 @@ function foo(n: number); type bar = number; type baz = number | string; function foo(sn: string | number) {} - `, + `, errors: [ { messageId: 'adjacentSignature', @@ -296,10 +303,10 @@ function foo(sn: string | number) {} code: ` function foo(s: string) {} function foo(n: number) {} -const a = ""; -const b = ""; +const a = ''; +const b = ''; function foo(sn: string | number) {} - `, + `, errors: [ { messageId: 'adjacentSignature', @@ -315,7 +322,7 @@ function foo(s: string) {} function foo(n: number) {} class Bar {} function foo(sn: string | number) {} - `, + `, errors: [ { messageId: 'adjacentSignature', @@ -331,18 +338,18 @@ function foo(s: string) {} function foo(n: number) {} function foo(sn: string | number) {} class Bar { - foo(s: string); - foo(n: number); - name: string; - foo(sn: string | number) { } + foo(s: string); + foo(n: number); + name: string; + foo(sn: string | number) {} } - `, + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'foo' }, line: 9, - column: 5, + column: 3, }, ], }, @@ -353,7 +360,7 @@ declare function foo(n: number); declare function bar(): void; declare function baz(): void; declare function foo(sn: string | number); - `, + `, errors: [ { messageId: 'adjacentSignature', @@ -367,10 +374,10 @@ declare function foo(sn: string | number); code: ` declare function foo(s: string); declare function foo(n: number); -const a = ""; -const b = ""; +const a = ''; +const b = ''; declare function foo(sn: string | number); - `, + `, errors: [ { messageId: 'adjacentSignature', @@ -382,437 +389,438 @@ declare function foo(sn: string | number); }, { code: ` -declare module "Foo" { - export function foo(s: string): void; - export function foo(n: number): void; - export function bar(): void; - export function baz(): void; - export function foo(sn: string | number): void; +declare module 'Foo' { + export function foo(s: string): void; + export function foo(n: number): void; + export function bar(): void; + export function baz(): void; + export function foo(sn: string | number): void; } - `, + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'foo' }, line: 7, - column: 5, + column: 3, }, ], }, { code: ` -declare module "Foo" { - export function foo(s: string): void; - export function foo(n: number): void; - export function foo(sn: string | number): void; - function baz(s: string): void; - export function bar(): void; - function baz(n: number): void; - function baz(sn: string | number): void; +declare module 'Foo' { + export function foo(s: string): void; + export function foo(n: number): void; + export function foo(sn: string | number): void; + function baz(s: string): void; + export function bar(): void; + function baz(n: number): void; + function baz(sn: string | number): void; } - `, + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'baz' }, line: 8, - column: 5, + column: 3, }, ], }, { code: ` declare namespace Foo { - export function foo(s: string): void; - export function foo(n: number): void; - export function bar(): void; - export function baz(): void; - export function foo(sn: string | number): void; + export function foo(s: string): void; + export function foo(n: number): void; + export function bar(): void; + export function baz(): void; + export function foo(sn: string | number): void; } - `, + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'foo' }, line: 7, - column: 5, + column: 3, }, ], }, { code: ` declare namespace Foo { - export function foo(s: string): void; - export function foo(n: number): void; - export function foo(sn: string | number): void; - function baz(s: string): void; - export function bar(): void; - function baz(n: number): void; - function baz(sn: string | number): void; -} - `, + export function foo(s: string): void; + export function foo(n: number): void; + export function foo(sn: string | number): void; + function baz(s: string): void; + export function bar(): void; + function baz(n: number): void; + function baz(sn: string | number): void; +} + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'baz' }, line: 8, - column: 5, + column: 3, }, ], }, { code: ` type Foo = { - foo(s: string): void; - foo(n: number): void; - bar(): void; - baz(): void; - foo(sn: string | number): void; -} - `, + foo(s: string): void; + foo(n: number): void; + bar(): void; + baz(): void; + foo(sn: string | number): void; +}; + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'foo' }, line: 7, - column: 5, + column: 3, }, ], }, { code: ` type Foo = { - foo(s: string): void; - ["foo"](n: number): void; - bar(): void; - baz(): void; - foo(sn: string | number): void; -} - `, + foo(s: string): void; + ['foo'](n: number): void; + bar(): void; + baz(): void; + foo(sn: string | number): void; +}; + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'foo' }, line: 7, - column: 5, + column: 3, }, ], }, { code: ` type Foo = { - foo(s: string): void; - name: string; - foo(n: number): void; - foo(sn: string | number): void; - bar(): void; - baz(): void; -} - `, + foo(s: string): void; + name: string; + foo(n: number): void; + foo(sn: string | number): void; + bar(): void; + baz(): void; +}; + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'foo' }, line: 5, - column: 5, + column: 3, }, ], }, { code: ` interface Foo { - (s: string): void; - foo(n: number): void; - (n: number): void; - (sn: string | number): void; - bar(): void; - baz(): void; -} - `, + (s: string): void; + foo(n: number): void; + (n: number): void; + (sn: string | number): void; + bar(): void; + baz(): void; +} + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'call' }, line: 5, - column: 5, + column: 3, }, ], }, { code: ` interface Foo { - foo(s: string): void; - foo(n: number): void; - bar(): void; - baz(): void; - foo(sn: string | number): void; + foo(s: string): void; + foo(n: number): void; + bar(): void; + baz(): void; + foo(sn: string | number): void; } - `, + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'foo' }, line: 7, - column: 5, + column: 3, }, ], }, { code: ` interface Foo { - foo(s: string): void; - ["foo"](n: number): void; - bar(): void; - baz(): void; - foo(sn: string | number): void; + foo(s: string): void; + ['foo'](n: number): void; + bar(): void; + baz(): void; + foo(sn: string | number): void; } - `, + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'foo' }, line: 7, - column: 5, + column: 3, }, ], }, { code: ` interface Foo { - foo(s: string): void; - "foo"(n: number): void; - bar(): void; - baz(): void; - foo(sn: string | number): void; + foo(s: string): void; + 'foo'(n: number): void; + bar(): void; + baz(): void; + foo(sn: string | number): void; } - `, + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'foo' }, line: 7, - column: 5, + column: 3, }, ], }, { code: ` interface Foo { - foo(s: string): void; - name: string; - foo(n: number): void; - foo(sn: string | number): void; - bar(): void; - baz(): void; -} - `, + foo(s: string): void; + name: string; + foo(n: number): void; + foo(sn: string | number): void; + bar(): void; + baz(): void; +} + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'foo' }, line: 5, - column: 5, + column: 3, }, ], }, { code: ` interface Foo { + foo(): void; + bar: { + baz(s: string): void; + baz(n: number): void; foo(): void; - bar: { - baz(s: string): void; - baz(n: number): void; - foo(): void; - baz(sn: string | number): void; - } -} - `, + baz(sn: string | number): void; + }; +} + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'baz' }, line: 8, - column: 9, + column: 5, }, ], }, { code: ` interface Foo { - new(s: string); - new(n: number); - foo(): void; - bar(): void; - new(sn: string | number); + new (s: string); + new (n: number); + foo(): void; + bar(): void; + new (sn: string | number); } - `, + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'new' }, line: 7, - column: 5, + column: 3, }, ], }, { code: ` interface Foo { - new(s: string); - foo(): void; - new(n: number); - bar(): void; - new(sn: string | number); + new (s: string); + foo(): void; + new (n: number); + bar(): void; + new (sn: string | number); } - `, + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'new' }, line: 5, - column: 5, + column: 3, }, { messageId: 'adjacentSignature', data: { name: 'new' }, line: 7, - column: 5, + column: 3, }, ], }, { code: ` class Foo { - constructor(s: string); - constructor(n: number); - bar(): void {} - baz(): void {} - constructor(sn: string | number) {} + constructor(s: string); + constructor(n: number); + bar(): void {} + baz(): void {} + constructor(sn: string | number) {} } - `, + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'constructor' }, line: 7, - column: 5, + column: 3, }, ], }, { code: ` class Foo { - foo(s: string): void; - foo(n: number): void; - bar(): void {} - baz(): void {} - foo(sn: string | number): void {} + foo(s: string): void; + foo(n: number): void; + bar(): void {} + baz(): void {} + foo(sn: string | number): void {} } - `, + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'foo' }, line: 7, - column: 5, + column: 3, }, ], }, { code: ` class Foo { - foo(s: string): void; - ["foo"](n: number): void; - bar(): void {} - baz(): void {} - foo(sn: string | number): void {} + foo(s: string): void; + ['foo'](n: number): void; + bar(): void {} + baz(): void {} + foo(sn: string | number): void {} } - `, + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'foo' }, line: 7, - column: 5, + column: 3, }, ], }, { code: ` class Foo { - foo(s: string): void; - "foo"(n: number): void; - bar(): void {} - baz(): void {} - foo(sn: string | number): void {} -} - `, + // prettier-ignore + "foo"(s: string): void; + foo(n: number): void; + bar(): void {} + baz(): void {} + foo(sn: string | number): void {} +} + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'foo' }, - line: 7, - column: 5, + line: 8, + column: 3, }, ], }, { code: ` class Foo { - constructor(s: string); - name: string; - constructor(n: number); - constructor(sn: string | number) {} - bar(): void {} - baz(): void {} -} - `, + constructor(s: string); + name: string; + constructor(n: number); + constructor(sn: string | number) {} + bar(): void {} + baz(): void {} +} + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'constructor' }, line: 5, - column: 5, + column: 3, }, ], }, { code: ` class Foo { - foo(s: string): void; - name: string; - foo(n: number): void; - foo(sn: string | number): void {} - bar(): void {} - baz(): void {} -} - `, + foo(s: string): void; + name: string; + foo(n: number): void; + foo(sn: string | number): void {} + bar(): void {} + baz(): void {} +} + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'foo' }, line: 5, - column: 5, + column: 3, }, ], }, { code: ` class Foo { - static foo(s: string): void; - name: string; - static foo(n: number): void; - static foo(sn: string | number): void {} - bar(): void {} - baz(): void {} -} - `, + static foo(s: string): void; + name: string; + static foo(n: number): void; + static foo(sn: string | number): void {} + bar(): void {} + baz(): void {} +} + `, errors: [ { messageId: 'adjacentSignature', data: { name: 'static foo' }, line: 5, - column: 5, + column: 3, }, ], }, diff --git a/packages/eslint-plugin/tests/rules/array-type.test.ts b/packages/eslint-plugin/tests/rules/array-type.test.ts index b74c06c09fd1..5f15ba5e8220 100644 --- a/packages/eslint-plugin/tests/rules/array-type.test.ts +++ b/packages/eslint-plugin/tests/rules/array-type.test.ts @@ -10,35 +10,35 @@ const ruleTester = new RuleTester({ ruleTester.run('array-type', rule, { valid: [ { - code: 'let a: readonly any[] = []', + code: 'let a: readonly any[] = [];', options: [{ default: 'array' }], }, { - code: 'let a = new Array()', + code: 'let a = new Array();', options: [{ default: 'array' }], }, { - code: 'let a: string[] = []', + code: 'let a: string[] = [];', options: [{ default: 'array' }], }, { - code: 'let a: (string | number)[] = []', + code: 'let a: (string | number)[] = [];', options: [{ default: 'array' }], }, { - code: 'let a: ({ foo: Bar[] })[] = []', + code: 'let a: { foo: Bar[] }[] = [];', options: [{ default: 'array' }], }, { - code: 'let a: Array = []', + code: 'let a: Array = [];', options: [{ default: 'generic' }], }, { - code: 'let a: Array = []', + code: 'let a: Array = [];', options: [{ default: 'generic' }], }, { - code: 'let a: Array<{ foo: Array }> = []', + code: 'let a: Array<{ foo: Array }> = [];', options: [{ default: 'generic' }], }, { @@ -46,7 +46,7 @@ ruleTester.run('array-type', rule, { options: [{ default: 'generic' }], }, { - code: 'function foo (a: Array): Array {}', + code: 'function foo(a: Array): Array {}', options: [{ default: 'generic' }], }, { @@ -54,15 +54,19 @@ ruleTester.run('array-type', rule, { options: [{ default: 'array-simple' }], }, { - code: `function fooFunction(foo: Array>) { - return foo.map(e => e.foo); -}`, + code: ` +function fooFunction(foo: Array>) { + return foo.map(e => e.foo); +} + `, options: [{ default: 'array-simple' }], }, { - code: `function bazFunction(baz: Arr>) { - return baz.map(e => e.baz); -}`, + code: ` +function bazFunction(baz: Arr>) { + return baz.map(e => e.baz); +} + `, options: [{ default: 'array-simple' }], }, { @@ -78,16 +82,20 @@ ruleTester.run('array-type', rule, { options: [{ default: 'array-simple' }], }, { - code: `namespace fooName { - type BarType = { bar: string }; - type BazType = Arr; -}`, + code: ` +namespace fooName { + type BarType = { bar: string }; + type BazType = Arr; +} + `, options: [{ default: 'array-simple' }], }, { - code: `interface FooInterface { - '.bar': {baz: string[];}; -}`, + code: ` +interface FooInterface { + '.bar': { baz: string[] }; +} + `, options: [{ default: 'array-simple' }], }, { @@ -95,19 +103,23 @@ ruleTester.run('array-type', rule, { options: [{ default: 'array' }], }, { - code: 'let ya = [[1, "2"]] as[number, string][];', + code: "let ya = [[1, '2']] as [number, string][];", options: [{ default: 'array' }], }, { - code: `function barFunction(bar: ArrayClass[]) { - return bar.map(e => e.bar); -}`, + code: ` +function barFunction(bar: ArrayClass[]) { + return bar.map(e => e.bar); +} + `, options: [{ default: 'array' }], }, { - code: `function bazFunction(baz: Arr>) { - return baz.map(e => e.baz); -}`, + code: ` +function bazFunction(baz: Arr>) { + return baz.map(e => e.baz); +} + `, options: [{ default: 'array' }], }, { @@ -115,7 +127,7 @@ ruleTester.run('array-type', rule, { options: [{ default: 'array' }], }, { - code: 'type barUnion = (string|number|boolean)[];', + code: 'type barUnion = (string | number | boolean)[];', options: [{ default: 'array' }], }, { @@ -123,18 +135,20 @@ ruleTester.run('array-type', rule, { options: [{ default: 'array' }], }, { - code: `interface FooInterface { - '.bar': {baz: string[];}; -}`, + code: ` +interface FooInterface { + '.bar': { baz: string[] }; +} + `, options: [{ default: 'array' }], }, { // https://github.com/typescript-eslint/typescript-eslint/issues/172 - code: 'type Unwrap = T extends (infer E)[] ? E : T', + code: 'type Unwrap = T extends (infer E)[] ? E : T;', options: [{ default: 'array' }], }, { - code: 'let z: Array = [3, "4"];', + code: "let z: Array = [3, '4'];", options: [{ default: 'generic' }], }, { @@ -146,15 +160,19 @@ ruleTester.run('array-type', rule, { options: [{ default: 'generic' }], }, { - code: `function fooFunction(foo: Array>) { - return foo.map(e => e.foo); -}`, + code: ` +function fooFunction(foo: Array>) { + return foo.map(e => e.foo); +} + `, options: [{ default: 'generic' }], }, { - code: `function bazFunction(baz: Arr>) { - return baz.map(e => e.baz); -}`, + code: ` +function bazFunction(baz: Arr>) { + return baz.map(e => e.baz); +} + `, options: [{ default: 'generic' }], }, { @@ -162,7 +180,7 @@ ruleTester.run('array-type', rule, { options: [{ default: 'generic' }], }, { - code: 'type fooUnion = Array;', + code: 'type fooUnion = Array;', options: [{ default: 'generic' }], }, { @@ -171,40 +189,40 @@ ruleTester.run('array-type', rule, { }, { // https://github.com/typescript-eslint/typescript-eslint/issues/172 - code: 'type Unwrap = T extends Array ? E : T', + code: 'type Unwrap = T extends Array ? E : T;', options: [{ default: 'generic' }], }, // readonly { - code: 'let a: string[] = []', + code: 'let a: string[] = [];', options: [{ default: 'array', readonly: 'generic' }], }, { - code: 'let a: ReadonlyArray = []', + code: 'let a: ReadonlyArray = [];', options: [{ default: 'array', readonly: 'generic' }], }, { - code: 'let a: ReadonlyArray = [[]]', + code: 'let a: ReadonlyArray = [[]];', options: [{ default: 'array', readonly: 'generic' }], }, { - code: 'let a: Array = []', + code: 'let a: Array = [];', options: [{ default: 'generic', readonly: 'array' }], }, { - code: 'let a: readonly number[] = []', + code: 'let a: readonly number[] = [];', options: [{ default: 'generic', readonly: 'array' }], }, { - code: 'let a: readonly Array[] = [[]]', + code: 'let a: readonly Array[] = [[]];', options: [{ default: 'generic', readonly: 'array' }], }, ], invalid: [ { - code: 'let a: Array = []', - output: 'let a: string[] = []', + code: 'let a: Array = [];', + output: 'let a: string[] = [];', options: [{ default: 'array' }], errors: [ { @@ -216,8 +234,8 @@ ruleTester.run('array-type', rule, { ], }, { - code: 'let a: Array = []', - output: 'let a: (string | number)[] = []', + code: 'let a: Array = [];', + output: 'let a: (string | number)[] = [];', options: [{ default: 'array' }], errors: [ { @@ -229,21 +247,21 @@ ruleTester.run('array-type', rule, { ], }, { - code: 'let a: ({ foo: Array })[] = []', - output: 'let a: ({ foo: Bar[] })[] = []', + code: 'let a: { foo: Array }[] = [];', + output: 'let a: { foo: Bar[] }[] = [];', options: [{ default: 'array' }], errors: [ { messageId: 'errorStringArray', data: { type: 'Bar' }, line: 1, - column: 16, + column: 15, }, ], }, { - code: 'let a: string[] = []', - output: 'let a: Array = []', + code: 'let a: string[] = [];', + output: 'let a: Array = [];', options: [{ default: 'generic' }], errors: [ { @@ -255,8 +273,8 @@ ruleTester.run('array-type', rule, { ], }, { - code: 'let a: (string | number)[] = []', - output: 'let a: Array = []', + code: 'let a: (string | number)[] = [];', + output: 'let a: Array = [];', options: [{ default: 'generic' }], errors: [ { @@ -268,8 +286,8 @@ ruleTester.run('array-type', rule, { ], }, { - code: 'let a: Array<{ foo: Bar[] }> = []', - output: 'let a: Array<{ foo: Array }> = []', + code: 'let a: Array<{ foo: Bar[] }> = [];', + output: 'let a: Array<{ foo: Array }> = [];', options: [{ default: 'generic' }], errors: [ { @@ -281,8 +299,8 @@ ruleTester.run('array-type', rule, { ], }, { - code: 'let a: Array<{ foo: Foo | Bar[] }> = []', - output: 'let a: Array<{ foo: Foo | Array }> = []', + code: 'let a: Array<{ foo: Foo | Bar[] }> = [];', + output: 'let a: Array<{ foo: Foo | Array }> = [];', options: [{ default: 'generic' }], errors: [ { @@ -294,27 +312,27 @@ ruleTester.run('array-type', rule, { ], }, { - code: 'function foo (a: Array): Array {}', - output: 'function foo (a: Bar[]): Bar[] {}', + code: 'function foo(a: Array): Array {}', + output: 'function foo(a: Bar[]): Bar[] {}', options: [{ default: 'array' }], errors: [ { messageId: 'errorStringArray', data: { type: 'Bar' }, line: 1, - column: 18, + column: 17, }, { messageId: 'errorStringArray', data: { type: 'Bar' }, line: 1, - column: 31, + column: 30, }, ], }, { - code: 'let a: Array<>[] = []', - output: 'let a: any[][] = []', + code: 'let a: Array<>[] = [];', + output: 'let a: any[][] = [];', options: [{ default: 'array-simple' }], errors: [ { @@ -358,8 +376,8 @@ ruleTester.run('array-type', rule, { ], }, { - code: 'let y: string[] = >["2"];', - output: 'let y: string[] = ["2"];', + code: "let y: string[] = >['2'];", + output: "let y: string[] = ['2'];", options: [{ default: 'array-simple' }], errors: [ { @@ -371,8 +389,8 @@ ruleTester.run('array-type', rule, { ], }, { - code: 'let z: Array = [3, "4"];', - output: 'let z: any[] = [3, "4"];', + code: "let z: Array = [3, '4'];", + output: "let z: any[] = [3, '4'];", options: [{ default: 'array-simple' }], errors: [ { @@ -384,15 +402,15 @@ ruleTester.run('array-type', rule, { ], }, { - code: 'let ya = [[1, "2"]] as[number, string][];', - output: 'let ya = [[1, "2"]] as Array<[number, string]>;', + code: "let ya = [[1, '2']] as [number, string][];", + output: "let ya = [[1, '2']] as Array<[number, string]>;", options: [{ default: 'array-simple' }], errors: [ { messageId: 'errorStringGenericSimple', data: { type: 'T' }, line: 1, - column: 23, + column: 24, }, ], }, @@ -410,56 +428,68 @@ ruleTester.run('array-type', rule, { ], }, { - code: `// Ignore user defined aliases -let yyyy: Arr>[]> = [[[["2"]]]];`, - output: `// Ignore user defined aliases -let yyyy: Arr>>> = [[[["2"]]]];`, + code: ` +// Ignore user defined aliases +let yyyy: Arr>[]> = [[[['2']]]]; + `, + output: ` +// Ignore user defined aliases +let yyyy: Arr>>> = [[[['2']]]]; + `, options: [{ default: 'array-simple' }], errors: [ { messageId: 'errorStringGenericSimple', data: { type: 'T' }, - line: 2, + line: 3, column: 15, }, ], }, { - code: `interface ArrayClass { - foo: Array; - bar: T[]; - baz: Arr; - xyz: this[]; -}`, - output: `interface ArrayClass { - foo: T[]; - bar: T[]; - baz: Arr; - xyz: this[]; -}`, + code: ` +interface ArrayClass { + foo: Array; + bar: T[]; + baz: Arr; + xyz: this[]; +} + `, + output: ` +interface ArrayClass { + foo: T[]; + bar: T[]; + baz: Arr; + xyz: this[]; +} + `, options: [{ default: 'array-simple' }], errors: [ { messageId: 'errorStringArraySimple', data: { type: 'T' }, - line: 2, - column: 10, + line: 3, + column: 8, }, ], }, { - code: `function barFunction(bar: ArrayClass[]) { - return bar.map(e => e.bar); -}`, - output: `function barFunction(bar: Array>) { - return bar.map(e => e.bar); -}`, + code: ` +function barFunction(bar: ArrayClass[]) { + return bar.map(e => e.bar); +} + `, + output: ` +function barFunction(bar: Array>) { + return bar.map(e => e.bar); +} + `, options: [{ default: 'array-simple' }], errors: [ { messageId: 'errorStringGenericSimple', data: { type: 'T' }, - line: 1, + line: 2, column: 27, }, ], @@ -478,8 +508,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: 'type barUnion = (string|number|boolean)[];', - output: 'type barUnion = Array;', + code: 'type barUnion = (string | number | boolean)[];', + output: 'type barUnion = Array;', options: [{ default: 'array-simple' }], errors: [ { @@ -504,8 +534,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: 'let v: Array = [{ bar: "bar" }];', - output: 'let v: fooName.BarType[] = [{ bar: "bar" }];', + code: "let v: Array = [{ bar: 'bar' }];", + output: "let v: fooName.BarType[] = [{ bar: 'bar' }];", options: [{ default: 'array-simple' }], errors: [ { @@ -517,8 +547,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: 'let w: fooName.BazType[] = [["baz"]];', - output: 'let w: Array> = [["baz"]];', + code: "let w: fooName.BazType[] = [['baz']];", + output: "let w: Array> = [['baz']];", options: [{ default: 'array-simple' }], errors: [ { @@ -543,8 +573,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: 'let y: string[] = >["2"];', - output: 'let y: string[] = ["2"];', + code: "let y: string[] = >['2'];", + output: "let y: string[] = ['2'];", options: [{ default: 'array' }], errors: [ { @@ -556,8 +586,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: 'let z: Array = [3, "4"];', - output: 'let z: any[] = [3, "4"];', + code: "let z: Array = [3, '4'];", + output: "let z: any[] = [3, '4'];", options: [{ default: 'array' }], errors: [ { @@ -582,54 +612,66 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: `// Ignore user defined aliases -let yyyy: Arr>[]> = [[[["2"]]]];`, - output: `// Ignore user defined aliases -let yyyy: Arr[][]> = [[[["2"]]]];`, + code: ` +// Ignore user defined aliases +let yyyy: Arr>[]> = [[[['2']]]]; + `, + output: ` +// Ignore user defined aliases +let yyyy: Arr[][]> = [[[['2']]]]; + `, options: [{ default: 'array' }], errors: [ { messageId: 'errorStringArray', data: { type: 'T' }, - line: 2, + line: 3, column: 15, }, ], }, { - code: `interface ArrayClass { - foo: Array; - bar: T[]; - baz: Arr; -}`, - output: `interface ArrayClass { - foo: T[]; - bar: T[]; - baz: Arr; -}`, + code: ` +interface ArrayClass { + foo: Array; + bar: T[]; + baz: Arr; +} + `, + output: ` +interface ArrayClass { + foo: T[]; + bar: T[]; + baz: Arr; +} + `, options: [{ default: 'array' }], errors: [ { messageId: 'errorStringArray', data: { type: 'T' }, - line: 2, - column: 10, + line: 3, + column: 8, }, ], }, { - code: `function fooFunction(foo: Array>) { - return foo.map(e => e.foo); -}`, - output: `function fooFunction(foo: ArrayClass[]) { - return foo.map(e => e.foo); -}`, + code: ` +function fooFunction(foo: Array>) { + return foo.map(e => e.foo); +} + `, + output: ` +function fooFunction(foo: ArrayClass[]) { + return foo.map(e => e.foo); +} + `, options: [{ default: 'array' }], errors: [ { messageId: 'errorStringArray', data: { type: 'T' }, - line: 1, + line: 2, column: 27, }, ], @@ -648,8 +690,8 @@ let yyyy: Arr[][]> = [[[["2"]]]];`, ], }, { - code: 'type fooUnion = Array;', - output: 'type fooUnion = (string|number|boolean)[];', + code: 'type fooUnion = Array;', + output: 'type fooUnion = (string | number | boolean)[];', options: [{ default: 'array' }], errors: [ { @@ -711,8 +753,8 @@ let yyyy: Arr[][]> = [[[["2"]]]];`, ], }, { - code: 'let y: string[] = >["2"];', - output: 'let y: Array = >["2"];', + code: "let y: string[] = >['2'];", + output: "let y: Array = >['2'];", options: [{ default: 'generic' }], errors: [ { @@ -724,67 +766,79 @@ let yyyy: Arr[][]> = [[[["2"]]]];`, ], }, { - code: 'let ya = [[1, "2"]] as[number, string][];', - output: 'let ya = [[1, "2"]] as Array<[number, string]>;', + code: "let ya = [[1, '2']] as [number, string][];", + output: "let ya = [[1, '2']] as Array<[number, string]>;", options: [{ default: 'generic' }], errors: [ { messageId: 'errorStringGeneric', data: { type: 'T' }, line: 1, - column: 23, + column: 24, }, ], }, { - code: `// Ignore user defined aliases -let yyyy: Arr>[]> = [[[["2"]]]];`, - output: `// Ignore user defined aliases -let yyyy: Arr>>> = [[[["2"]]]];`, + code: ` +// Ignore user defined aliases +let yyyy: Arr>[]> = [[[['2']]]]; + `, + output: ` +// Ignore user defined aliases +let yyyy: Arr>>> = [[[['2']]]]; + `, options: [{ default: 'generic' }], errors: [ { messageId: 'errorStringGeneric', data: { type: 'T' }, - line: 2, + line: 3, column: 15, }, ], }, { - code: `interface ArrayClass { - foo: Array; - bar: T[]; - baz: Arr; -}`, - output: `interface ArrayClass { - foo: Array; - bar: Array; - baz: Arr; -}`, + code: ` +interface ArrayClass { + foo: Array; + bar: T[]; + baz: Arr; +} + `, + output: ` +interface ArrayClass { + foo: Array; + bar: Array; + baz: Arr; +} + `, options: [{ default: 'generic' }], errors: [ { messageId: 'errorStringGeneric', data: { type: 'T' }, - line: 3, - column: 10, + line: 4, + column: 8, }, ], }, { - code: `function barFunction(bar: ArrayClass[]) { - return bar.map(e => e.bar); -}`, - output: `function barFunction(bar: Array>) { - return bar.map(e => e.bar); -}`, + code: ` +function barFunction(bar: ArrayClass[]) { + return bar.map(e => e.bar); +} + `, + output: ` +function barFunction(bar: Array>) { + return bar.map(e => e.bar); +} + `, options: [{ default: 'generic' }], errors: [ { messageId: 'errorStringGeneric', data: { type: 'T' }, - line: 1, + line: 2, column: 27, }, ], @@ -803,8 +857,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: 'type barUnion = (string|number|boolean)[];', - output: 'type barUnion = Array;', + code: 'type barUnion = (string | number | boolean)[];', + output: 'type barUnion = Array;', options: [{ default: 'generic' }], errors: [ { @@ -829,26 +883,30 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: `interface FooInterface { - '.bar': {baz: string[];}; -}`, - output: `interface FooInterface { - '.bar': {baz: Array;}; -}`, + code: ` +interface FooInterface { + '.bar': { baz: string[] }; +} + `, + output: ` +interface FooInterface { + '.bar': { baz: Array }; +} + `, options: [{ default: 'generic' }], errors: [ { messageId: 'errorStringGeneric', data: { type: 'string' }, - line: 2, - column: 19, + line: 3, + column: 18, }, ], }, { // https://github.com/typescript-eslint/typescript-eslint/issues/172 - code: 'type Unwrap = T extends Array ? E : T', - output: 'type Unwrap = T extends (infer E)[] ? E : T', + code: 'type Unwrap = T extends Array ? E : T;', + output: 'type Unwrap = T extends (infer E)[] ? E : T;', options: [{ default: 'array' }], errors: [ { @@ -861,8 +919,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, }, { // https://github.com/typescript-eslint/typescript-eslint/issues/172 - code: 'type Unwrap = T extends (infer E)[] ? E : T', - output: 'type Unwrap = T extends Array ? E : T', + code: 'type Unwrap = T extends (infer E)[] ? E : T;', + output: 'type Unwrap = T extends Array ? E : T;', options: [{ default: 'generic' }], errors: [ { @@ -928,8 +986,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: 'const x: readonly number[] = []', - output: 'const x: ReadonlyArray = []', + code: 'const x: readonly number[] = [];', + output: 'const x: ReadonlyArray = [];', options: [{ default: 'array', readonly: 'generic' }], errors: [ { @@ -941,8 +999,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: 'const x: readonly number[][] = []', - output: 'const x: readonly Array[] = []', + code: 'const x: readonly number[][] = [];', + output: 'const x: readonly Array[] = [];', options: [{ default: 'generic', readonly: 'array' }], errors: [ { diff --git a/packages/eslint-plugin/tests/rules/await-thenable.test.ts b/packages/eslint-plugin/tests/rules/await-thenable.test.ts index 5ee0f7d03410..52fc1ca23061 100644 --- a/packages/eslint-plugin/tests/rules/await-thenable.test.ts +++ b/packages/eslint-plugin/tests/rules/await-thenable.test.ts @@ -13,51 +13,51 @@ const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', }); -ruleTester.run('await-promise', rule, { +ruleTester.run('await-thenable', rule, { valid: [ ` async function test() { - await Promise.resolve("value"); - await Promise.reject(new Error("message")); + await Promise.resolve('value'); + await Promise.reject(new Error('message')); } -`, + `, ` async function test() { await (async () => true)(); } -`, + `, ` async function test() { function returnsPromise() { - return Promise.resolve("value"); + return Promise.resolve('value'); } await returnsPromise(); } -`, + `, ` async function test() { async function returnsPromiseAsync() {} await returnsPromiseAsync(); } -`, + `, ` async function test() { let anyValue: any; await anyValue; } -`, + `, ` async function test() { let unknownValue: unknown; await unknownValue; } -`, + `, ` async function test() { const numberPromise: Promise; await numberPromise; } -`, + `, ` async function test() { class Foo extends Promise {} @@ -68,7 +68,7 @@ async function test() { const bar: Bar = Bar.resolve(2); await bar; } -`, + `, ` async function test() { await (Math.random() > 0.5 ? numberPromise : 0); @@ -78,15 +78,17 @@ async function test() { const intersectionPromise: Promise & number; await intersectionPromise; } -`, + `, ` async function test() { - class Thenable { then(callback: () => {}) { } }; + class Thenable { + then(callback: () => {}) {} + } const thenable = new Thenable(); await thenable; } -`, + `, ` // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/promise-polyfill/index.d.ts // Type definitions for promise-polyfill 6.0 @@ -96,7 +98,7 @@ async function test() { // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped interface PromisePolyfillConstructor extends PromiseConstructor { - _immediateFn?: (handler: (() => void) | string) => void; + _immediateFn?: (handler: (() => void) | string) => void; } declare const PromisePolyfill: PromisePolyfillConstructor; @@ -106,7 +108,7 @@ async function test() { await promise; } -`, + `, ` // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/bluebird/index.d.ts // Type definitions for bluebird 3.5 @@ -151,14 +153,21 @@ type CatchFilter = ((error: E) => boolean) | (object & E); type IterableItem = R extends Iterable ? U : never; type IterableOrNever = Extract>; type Resolvable = R | PromiseLike; -type IterateFunction = (item: T, index: number, arrayLength: number) => Resolvable; +type IterateFunction = ( + item: T, + index: number, + arrayLength: number, +) => Resolvable; declare class Bluebird implements PromiseLike { - then(onFulfill?: (value: R) => Resolvable, onReject?: (error: any) => Resolvable): Bluebird; // For simpler signature help. + then( + onFulfill?: (value: R) => Resolvable, + onReject?: (error: any) => Resolvable, + ): Bluebird; // For simpler signature help. then( - onfulfilled?: ((value: R) => Resolvable) | null, - onrejected?: ((reason: any) => Resolvable) | null - ): Bluebird; + onfulfilled?: ((value: R) => Resolvable) | null, + onrejected?: ((reason: any) => Resolvable) | null, + ): Bluebird; } declare const bluebird: Bluebird; @@ -166,7 +175,7 @@ declare const bluebird: Bluebird; async function test() { await bluebird; } -`, + `, ], invalid: [ @@ -174,14 +183,14 @@ async function test() { code: ` async function test() { await 0; - await "value"; + await 'value'; - await (Math.random() > 0.5 ? "" : 0); + await (Math.random() > 0.5 ? '' : 0); class NonPromise extends Array {} await new NonPromise(); } -`, + `, errors: [ { line: 3, @@ -204,7 +213,9 @@ async function test() { { code: ` async function test() { - class IncorrectThenable { then() { } }; + class IncorrectThenable { + then() {} + } const thenable = new IncorrectThenable(); await thenable; @@ -212,7 +223,7 @@ async function test() { `, errors: [ { - line: 6, + line: 8, messageId, }, ], diff --git a/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts b/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts index c2226f7041a7..fcbb788a3082 100644 --- a/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts +++ b/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts @@ -5,14 +5,16 @@ const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', }); -ruleTester.run('ts-ignore', rule, { +ruleTester.run('ban-ts-comment', rule, { valid: [ - `// just a comment containing @ts-ignore somewhere`, - `/* @ts-ignore */`, - `/** @ts-ignore */`, - `/* + '// just a comment containing @ts-ignore somewhere', + '/* @ts-ignore */', + '/** @ts-ignore */', + ` +/* // @ts-ignore in a block -*/`, +*/ + `, { code: '// @ts-ignore', options: [{ 'ts-ignore': false }], @@ -68,9 +70,9 @@ ruleTester.run('ts-ignore', rule, { code: ` if (false) { // @ts-ignore: Unreachable code error - console.log("hello"); + console.log('hello'); } - `, + `, errors: [ { data: { directive: 'ignore' }, @@ -85,12 +87,14 @@ if (false) { ruleTester.run('ts-nocheck', rule, { valid: [ - `// just a comment containing @ts-nocheck somewhere`, - `/* @ts-nocheck */`, - `/** @ts-nocheck */`, - `/* + '// just a comment containing @ts-nocheck somewhere', + '/* @ts-nocheck */', + '/** @ts-nocheck */', + ` +/* // @ts-nocheck in a block -*/`, +*/ + `, { code: '// @ts-nocheck', options: [{ 'ts-nocheck': false }], @@ -146,9 +150,9 @@ ruleTester.run('ts-nocheck', rule, { code: ` if (false) { // @ts-nocheck: Unreachable code error - console.log("hello"); + console.log('hello'); } - `, + `, errors: [ { data: { directive: 'nocheck' }, @@ -163,12 +167,14 @@ if (false) { ruleTester.run('ts-check', rule, { valid: [ - `// just a comment containing @ts-check somewhere`, - `/* @ts-check */`, - `/** @ts-check */`, - `/* + '// just a comment containing @ts-check somewhere', + '/* @ts-check */', + '/** @ts-check */', + ` +/* // @ts-check in a block -*/`, +*/ + `, { code: '// @ts-check', options: [{ 'ts-check': false }], @@ -216,9 +222,9 @@ ruleTester.run('ts-check', rule, { code: ` if (false) { // @ts-check: Unreachable code error - console.log("hello"); + console.log('hello'); } - `, + `, options: [{ 'ts-check': true }], errors: [ { diff --git a/packages/eslint-plugin/tests/rules/ban-ts-ignore.test.ts b/packages/eslint-plugin/tests/rules/ban-ts-ignore.test.ts index d9132df2b0d4..e1471950f464 100644 --- a/packages/eslint-plugin/tests/rules/ban-ts-ignore.test.ts +++ b/packages/eslint-plugin/tests/rules/ban-ts-ignore.test.ts @@ -7,12 +7,14 @@ const ruleTester = new RuleTester({ ruleTester.run('ban-ts-ignore', rule, { valid: [ - `// just a comment containing @ts-ignore somewhere`, - `/* @ts-ignore */`, - `/** @ts-ignore */`, - `/* + '// just a comment containing @ts-ignore somewhere', + '/* @ts-ignore */', + '/** @ts-ignore */', + ` +/* // @ts-ignore in a block -*/`, +*/ + `, ], invalid: [ { @@ -49,9 +51,9 @@ ruleTester.run('ban-ts-ignore', rule, { code: ` if (false) { // @ts-ignore: Unreachable code error - console.log("hello"); + console.log('hello'); } - `, + `, errors: [ { messageId: 'tsIgnoreComment', diff --git a/packages/eslint-plugin/tests/rules/ban-types.test.ts b/packages/eslint-plugin/tests/rules/ban-types.test.ts index 0edeb74f8d1c..772fa7716f8f 100644 --- a/packages/eslint-plugin/tests/rules/ban-types.test.ts +++ b/packages/eslint-plugin/tests/rules/ban-types.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/ban-types'; -import { RuleTester } from '../RuleTester'; +import { RuleTester, noFormat } from '../RuleTester'; import { InferOptionsTypeFromRule } from '../../src/util'; const ruleTester = new RuleTester({ @@ -47,7 +47,7 @@ ruleTester.run('ban-types', rule, { valid: [ 'let f = Object();', // Should not fail if there is no options set 'let f: {} = {};', - 'let f: { x: number, y: number } = { x: 1, y: 1 };', + 'let f: { x: number; y: number } = { x: 1, y: 1 };', { code: 'let f = Object();', options, @@ -65,11 +65,11 @@ ruleTester.run('ban-types', rule, { options, }, { - code: 'let a: _.NS.Bad', + code: 'let a: _.NS.Bad;', options, }, { - code: 'let a: NS.Bad._', + code: 'let a: NS.Bad._;', options, }, // Replace default options instead of merging with extendDefaults: false @@ -88,11 +88,11 @@ ruleTester.run('ban-types', rule, { ], }, { - code: 'let a: undefined', + code: 'let a: undefined;', options: options2, }, { - code: 'let a: null', + code: 'let a: null;', options: options3, }, ], @@ -166,8 +166,8 @@ ruleTester.run('ban-types', rule, { ], }, { - code: 'let b: {c: String};', - output: 'let b: {c: string};', + code: 'let b: { c: String };', + output: 'let b: { c: string };', errors: [ { messageId: 'bannedTypeMessage', @@ -177,7 +177,7 @@ ruleTester.run('ban-types', rule, { customMessage: ' Use string instead.', }, line: 1, - column: 12, + column: 13, }, ], options, @@ -231,22 +231,22 @@ ruleTester.run('ban-types', rule, { { code: ` class Foo extends Bar implements Baz { - constructor (foo: String | Object) {} + constructor(foo: String | Object) {} - exit() : Array { - const foo: String = 1 as String + exit(): Array { + const foo: String = 1 as String; } } - `, + `, output: ` class Foo extends Bar implements Baz { - constructor (foo: string | Object) {} + constructor(foo: string | Object) {} - exit() : Array { - const foo: string = 1 as string + exit(): Array { + const foo: string = 1 as string; } } - `, + `, errors: [ { messageId: 'bannedTypeMessage', @@ -285,7 +285,7 @@ class Foo extends Bar implements Baz { customMessage: ' Use string instead.', }, line: 3, - column: 21, + column: 20, }, { messageId: 'bannedTypeMessage', @@ -294,13 +294,13 @@ class Foo extends Bar implements Baz { customMessage: " Use '{}' instead.", }, line: 3, - column: 30, + column: 29, }, { messageId: 'bannedTypeMessage', data: { name: 'Array', customMessage: '' }, line: 5, - column: 12, + column: 11, }, { messageId: 'bannedTypeMessage', @@ -310,7 +310,7 @@ class Foo extends Bar implements Baz { customMessage: ' Use string instead.', }, line: 5, - column: 18, + column: 17, }, { messageId: 'bannedTypeMessage', @@ -383,8 +383,8 @@ let b: Foo; options, }, { - code: `let foo: {} = {};`, - output: `let foo: object = {};`, + code: 'let foo: {} = {};', + output: 'let foo: object = {};', options: [ { types: { @@ -408,7 +408,7 @@ let b: Foo; ], }, { - code: ` + code: noFormat` let foo: {} = {}; let bar: { } = {}; `, @@ -473,8 +473,8 @@ let bar: object = {}; ], }, { - code: 'let a: Foo< F >;', - output: 'let a: Foo< T >;', + code: noFormat`let a: Foo< F >;`, + output: noFormat`let a: Foo< T >;`, errors: [ { messageId: 'bannedTypeMessage', diff --git a/packages/eslint-plugin/tests/rules/brace-style.test.ts b/packages/eslint-plugin/tests/rules/brace-style.test.ts index 21d10998eac1..28b9413795db 100644 --- a/packages/eslint-plugin/tests/rules/brace-style.test.ts +++ b/packages/eslint-plugin/tests/rules/brace-style.test.ts @@ -1,3 +1,8 @@ +/* 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/brace-style'; import { RuleTester } from '../RuleTester'; @@ -211,67 +216,67 @@ catch (e) options: ['allman'], }, { - code: `function foo () { return; }`, + code: 'function foo () { return; }', options: ['1tbs', { allowSingleLine: true }], }, { - code: `function foo () { a(); b(); return; }`, + code: 'function foo () { a(); b(); return; }', options: ['1tbs', { allowSingleLine: true }], }, { - code: `function a(b,c,d) { }`, + code: 'function a(b,c,d) { }', options: ['1tbs', { allowSingleLine: true }], }, { - code: `!function foo () { return; }`, + code: '!function foo () { return; }', options: ['1tbs', { allowSingleLine: true }], }, { - code: `!function a(b,c,d) { }`, + code: '!function a(b,c,d) { }', options: ['1tbs', { allowSingleLine: true }], }, { - code: `if (foo) { bar(); }`, + code: 'if (foo) { bar(); }', options: ['1tbs', { allowSingleLine: true }], }, { - code: `if (a) { b(); } else { c(); }`, + code: 'if (a) { b(); } else { c(); }', options: ['1tbs', { allowSingleLine: true }], }, { - code: `while (foo) { bar(); }`, + code: 'while (foo) { bar(); }', options: ['1tbs', { allowSingleLine: true }], }, { - code: `for (;;) { bar(); }`, + code: 'for (;;) { bar(); }', options: ['1tbs', { allowSingleLine: true }], }, { - code: `with (foo) { bar(); }`, + code: 'with (foo) { bar(); }', options: ['1tbs', { allowSingleLine: true }], }, { - code: `switch (foo) { case 'bar': break; }`, + code: "switch (foo) { case 'bar': break; }", options: ['1tbs', { allowSingleLine: true }], }, { - code: `try { bar(); } catch (e) { baz(); }`, + code: 'try { bar(); } catch (e) { baz(); }', options: ['1tbs', { allowSingleLine: true }], }, { - code: `do { bar(); } while (true)`, + code: 'do { bar(); } while (true)', options: ['1tbs', { allowSingleLine: true }], }, { - code: `for (foo in bar) { baz(); }`, + code: 'for (foo in bar) { baz(); }', options: ['1tbs', { allowSingleLine: true }], }, { - code: `if (a && b && c) { }`, + code: 'if (a && b && c) { }', options: ['1tbs', { allowSingleLine: true }], }, { - code: `switch(0) {}`, + code: 'switch(0) {}', options: ['1tbs', { allowSingleLine: true }], }, { @@ -289,7 +294,7 @@ catch (e) { baz(); } options: ['stroustrup', { allowSingleLine: true }], }, { - code: `var foo = () => { return; }`, + code: 'var foo = () => { return; }', options: ['stroustrup', { allowSingleLine: true }], parserOptions: { ecmaVersion: 6 }, }, @@ -308,7 +313,7 @@ catch (e) { baz(); } options: ['allman', { allowSingleLine: true }], }, { - code: `var foo = () => { return; }`, + code: 'var foo = () => { return; }', options: ['allman', { allowSingleLine: true }], parserOptions: { ecmaVersion: 6 }, }, @@ -345,7 +350,7 @@ switch(x) options: ['allman'], }, { - code: `switch(x) {}`, + code: 'switch(x) {}', options: ['allman', { allowSingleLine: true }], }, { @@ -388,25 +393,25 @@ Foo options: ['allman'], }, { - code: `class Foo {}`, + code: 'class Foo {}', options: ['1tbs', { allowSingleLine: true }], }, { - code: `class Foo {}`, + code: 'class Foo {}', options: ['allman', { allowSingleLine: true }], }, { - code: `(class {})`, + code: '(class {})', options: ['1tbs', { allowSingleLine: true }], }, { - code: `(class {})`, + code: '(class {})', options: ['allman', { allowSingleLine: true }], }, // https://github.com/eslint/eslint/issues/7908 { - code: `{}`, + code: '{}', }, { code: ` @@ -568,7 +573,7 @@ enum Foo { options: ['stroustrup'], }, { - code: `enum Foo { A, B }`, + code: 'enum Foo { A, B }', options: ['1tbs', { allowSingleLine: true }], }, ], @@ -591,8 +596,8 @@ if (f) { errors: [{ messageId: 'nextLineClose' }], }, { - code: `var foo = () => { return; }`, - output: `var foo = () => {\n return; \n}`, + code: 'var foo = () => { return; }', + output: 'var foo = () => {\n return; \n}', parserOptions: { ecmaVersion: 6 }, errors: [ { messageId: 'blockSameLine' }, @@ -600,31 +605,31 @@ if (f) { ], }, { - code: `function foo() { return; }`, - output: `function foo() {\n return; \n}`, + code: 'function foo() { return; }', + output: 'function foo() {\n return; \n}', errors: [ { messageId: 'blockSameLine' }, { messageId: 'singleLineClose' }, ], }, { - code: `function foo() \n { \n return; }`, - output: `function foo() { \n return; \n}`, + code: 'function foo() \n { \n return; }', + output: 'function foo() { \n return; \n}', errors: [{ messageId: 'nextLineOpen' }, { messageId: 'singleLineClose' }], }, { - code: `!function foo() \n { \n return; }`, - output: `!function foo() { \n return; \n}`, + code: '!function foo() \n { \n return; }', + output: '!function foo() { \n return; \n}', errors: [{ messageId: 'nextLineOpen' }, { messageId: 'singleLineClose' }], }, { - code: `if (foo) \n { \n bar(); }`, - output: `if (foo) { \n bar(); \n}`, + code: 'if (foo) \n { \n bar(); }', + output: 'if (foo) { \n bar(); \n}', errors: [{ messageId: 'nextLineOpen' }, { messageId: 'singleLineClose' }], }, { - code: `if (a) { \nb();\n } else \n { c(); }`, - output: `if (a) { \nb();\n } else {\n c(); \n}`, + code: 'if (a) { \nb();\n } else \n { c(); }', + output: 'if (a) { \nb();\n } else {\n c(); \n}', errors: [ { messageId: 'nextLineOpen' }, { messageId: 'blockSameLine' }, @@ -632,104 +637,108 @@ if (f) { ], }, { - code: `while (foo) \n { \n bar(); }`, - output: `while (foo) { \n bar(); \n}`, + code: 'while (foo) \n { \n bar(); }', + output: 'while (foo) { \n bar(); \n}', errors: [{ messageId: 'nextLineOpen' }, { messageId: 'singleLineClose' }], }, { - code: `for (;;) \n { \n bar(); }`, - output: `for (;;) { \n bar(); \n}`, + code: 'for (;;) \n { \n bar(); }', + output: 'for (;;) { \n bar(); \n}', errors: [{ messageId: 'nextLineOpen' }, { messageId: 'singleLineClose' }], }, { - code: `with (foo) \n { \n bar(); }`, - output: `with (foo) { \n bar(); \n}`, + code: 'with (foo) \n { \n bar(); }', + output: 'with (foo) { \n bar(); \n}', errors: [{ messageId: 'nextLineOpen' }, { messageId: 'singleLineClose' }], }, { - code: `switch (foo) \n { \n case 'bar': break; }`, - output: `switch (foo) { \n case 'bar': break; \n}`, + code: "switch (foo) \n { \n case 'bar': break; }", + output: "switch (foo) { \n case 'bar': break; \n}", errors: [{ messageId: 'nextLineOpen' }, { messageId: 'singleLineClose' }], }, { - code: `switch (foo) \n { }`, - output: `switch (foo) { }`, + code: 'switch (foo) \n { }', + output: 'switch (foo) { }', errors: [{ messageId: 'nextLineOpen' }], }, { - code: `try \n { \n bar(); \n } catch (e) {}`, - output: `try { \n bar(); \n } catch (e) {}`, + code: 'try \n { \n bar(); \n } catch (e) {}', + output: 'try { \n bar(); \n } catch (e) {}', errors: [{ messageId: 'nextLineOpen' }], }, { - code: `try { \n bar(); \n } catch (e) \n {}`, - output: `try { \n bar(); \n } catch (e) {}`, + code: 'try { \n bar(); \n } catch (e) \n {}', + output: 'try { \n bar(); \n } catch (e) {}', errors: [{ messageId: 'nextLineOpen' }], }, { - code: `do \n { \n bar(); \n} while (true)`, - output: `do { \n bar(); \n} while (true)`, + code: 'do \n { \n bar(); \n} while (true)', + output: 'do { \n bar(); \n} while (true)', errors: [{ messageId: 'nextLineOpen' }], }, { - code: `for (foo in bar) \n { \n baz(); \n }`, - output: `for (foo in bar) { \n baz(); \n }`, + code: 'for (foo in bar) \n { \n baz(); \n }', + output: 'for (foo in bar) { \n baz(); \n }', errors: [{ messageId: 'nextLineOpen' }], }, { - code: `for (foo of bar) \n { \n baz(); \n }`, - output: `for (foo of bar) { \n baz(); \n }`, + code: 'for (foo of bar) \n { \n baz(); \n }', + output: 'for (foo of bar) { \n baz(); \n }', parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: 'nextLineOpen' }], }, { - code: `try { \n bar(); \n }\ncatch (e) {\n}`, - output: `try { \n bar(); \n } catch (e) {\n}`, + code: 'try { \n bar(); \n }\ncatch (e) {\n}', + output: 'try { \n bar(); \n } catch (e) {\n}', errors: [{ messageId: 'nextLineClose' }], }, { - code: `try { \n bar(); \n } catch (e) {\n}\n finally {\n}`, - output: `try { \n bar(); \n } catch (e) {\n} finally {\n}`, + code: 'try { \n bar(); \n } catch (e) {\n}\n finally {\n}', + output: 'try { \n bar(); \n } catch (e) {\n} finally {\n}', errors: [{ messageId: 'nextLineClose' }], }, { - code: `if (a) { \nb();\n } \n else { \nc();\n }`, - output: `if (a) { \nb();\n } else { \nc();\n }`, + code: 'if (a) { \nb();\n } \n else { \nc();\n }', + output: 'if (a) { \nb();\n } else { \nc();\n }', errors: [{ messageId: 'nextLineClose' }], }, { - code: `try { \n bar(); \n }\ncatch (e) {\n} finally {\n}`, - output: `try { \n bar(); \n }\ncatch (e) {\n}\n finally {\n}`, + code: 'try { \n bar(); \n }\ncatch (e) {\n} finally {\n}', + output: 'try { \n bar(); \n }\ncatch (e) {\n}\n finally {\n}', options: ['stroustrup'], errors: [{ messageId: 'sameLineClose' }], }, { - code: `try { \n bar(); \n } catch (e) {\n}\n finally {\n}`, - output: `try { \n bar(); \n }\n catch (e) {\n}\n finally {\n}`, + code: 'try { \n bar(); \n } catch (e) {\n}\n finally {\n}', + output: 'try { \n bar(); \n }\n catch (e) {\n}\n finally {\n}', options: ['stroustrup'], errors: [{ messageId: 'sameLineClose' }], }, { - code: `if (a) { \nb();\n } else { \nc();\n }`, - output: `if (a) { \nb();\n }\n else { \nc();\n }`, + code: 'if (a) { \nb();\n } else { \nc();\n }', + output: 'if (a) { \nb();\n }\n else { \nc();\n }', options: ['stroustrup'], errors: [{ messageId: 'sameLineClose' }], }, { - code: `if (foo) {\nbaz();\n} else if (bar) {\nbaz();\n}\nelse {\nqux();\n}`, - output: `if (foo) {\nbaz();\n}\n else if (bar) {\nbaz();\n}\nelse {\nqux();\n}`, + code: + 'if (foo) {\nbaz();\n} else if (bar) {\nbaz();\n}\nelse {\nqux();\n}', + output: + 'if (foo) {\nbaz();\n}\n else if (bar) {\nbaz();\n}\nelse {\nqux();\n}', options: ['stroustrup'], errors: [{ messageId: 'sameLineClose' }], }, { - code: `if (foo) {\npoop();\n} \nelse if (bar) {\nbaz();\n} else if (thing) {\nboom();\n}\nelse {\nqux();\n}`, - output: `if (foo) {\npoop();\n} \nelse if (bar) {\nbaz();\n}\n else if (thing) {\nboom();\n}\nelse {\nqux();\n}`, + code: + 'if (foo) {\npoop();\n} \nelse if (bar) {\nbaz();\n} else if (thing) {\nboom();\n}\nelse {\nqux();\n}', + output: + 'if (foo) {\npoop();\n} \nelse if (bar) {\nbaz();\n}\n else if (thing) {\nboom();\n}\nelse {\nqux();\n}', options: ['stroustrup'], errors: [{ messageId: 'sameLineClose' }], }, { - code: `try { \n bar(); \n }\n catch (e) {\n}\n finally {\n}`, - output: `try \n{ \n bar(); \n }\n catch (e) \n{\n}\n finally \n{\n}`, + code: 'try { \n bar(); \n }\n catch (e) {\n}\n finally {\n}', + output: 'try \n{ \n bar(); \n }\n catch (e) \n{\n}\n finally \n{\n}', options: ['allman'], errors: [ { messageId: 'sameLineOpen', line: 1 }, @@ -738,8 +747,8 @@ if (f) { ], }, { - code: `switch(x) { case 1: \nbar(); }\n `, - output: `switch(x) \n{\n case 1: \nbar(); \n}\n `, + code: 'switch(x) { case 1: \nbar(); }\n ', + output: 'switch(x) \n{\n case 1: \nbar(); \n}\n ', options: ['allman'], errors: [ { messageId: 'sameLineOpen', line: 1 }, @@ -748,8 +757,8 @@ if (f) { ], }, { - code: `if (a) { \nb();\n } else { \nc();\n }`, - output: `if (a) \n{ \nb();\n }\n else \n{ \nc();\n }`, + code: 'if (a) { \nb();\n } else { \nc();\n }', + output: 'if (a) \n{ \nb();\n }\n else \n{ \nc();\n }', options: ['allman'], errors: [ { messageId: 'sameLineOpen' }, @@ -758,8 +767,10 @@ if (f) { ], }, { - code: `if (foo) {\nbaz();\n} else if (bar) {\nbaz();\n}\nelse {\nqux();\n}`, - output: `if (foo) \n{\nbaz();\n}\n else if (bar) \n{\nbaz();\n}\nelse \n{\nqux();\n}`, + code: + 'if (foo) {\nbaz();\n} else if (bar) {\nbaz();\n}\nelse {\nqux();\n}', + output: + 'if (foo) \n{\nbaz();\n}\n else if (bar) \n{\nbaz();\n}\nelse \n{\nqux();\n}', options: ['allman'], errors: [ { messageId: 'sameLineOpen' }, @@ -769,8 +780,10 @@ if (f) { ], }, { - code: `if (foo)\n{ poop();\n} \nelse if (bar) {\nbaz();\n} else if (thing) {\nboom();\n}\nelse {\nqux();\n}`, - output: `if (foo)\n{\n poop();\n} \nelse if (bar) \n{\nbaz();\n}\n else if (thing) \n{\nboom();\n}\nelse \n{\nqux();\n}`, + code: + 'if (foo)\n{ poop();\n} \nelse if (bar) {\nbaz();\n} else if (thing) {\nboom();\n}\nelse {\nqux();\n}', + output: + 'if (foo)\n{\n poop();\n} \nelse if (bar) \n{\nbaz();\n}\n else if (thing) \n{\nboom();\n}\nelse \n{\nqux();\n}', options: ['allman'], errors: [ { messageId: 'blockSameLine' }, @@ -781,159 +794,162 @@ if (f) { ], }, { - code: `if (foo)\n{\n bar(); }`, - output: `if (foo)\n{\n bar(); \n}`, + code: 'if (foo)\n{\n bar(); }', + output: 'if (foo)\n{\n bar(); \n}', options: ['allman'], errors: [{ messageId: 'singleLineClose' }], }, { - code: `try\n{\n somethingRisky();\n} catch (e)\n{\n handleError()\n}`, - output: `try\n{\n somethingRisky();\n}\n catch (e)\n{\n handleError()\n}`, + code: 'try\n{\n somethingRisky();\n} catch (e)\n{\n handleError()\n}', + output: + 'try\n{\n somethingRisky();\n}\n catch (e)\n{\n handleError()\n}', options: ['allman'], errors: [{ messageId: 'sameLineClose' }], }, // allowSingleLine: true { - code: `function foo() { return; \n}`, - output: `function foo() {\n return; \n}`, + code: 'function foo() { return; \n}', + output: 'function foo() {\n return; \n}', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'blockSameLine' }], }, { - code: `function foo() { a(); b(); return; \n}`, - output: `function foo() {\n a(); b(); return; \n}`, + code: 'function foo() { a(); b(); return; \n}', + output: 'function foo() {\n a(); b(); return; \n}', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'blockSameLine' }], }, { - code: `function foo() { \n return; }`, - output: `function foo() { \n return; \n}`, + code: 'function foo() { \n return; }', + output: 'function foo() { \n return; \n}', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'singleLineClose' }], }, { - code: `function foo() {\na();\nb();\nreturn; }`, - output: `function foo() {\na();\nb();\nreturn; \n}`, + code: 'function foo() {\na();\nb();\nreturn; }', + output: 'function foo() {\na();\nb();\nreturn; \n}', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'singleLineClose' }], }, { - code: `!function foo() { \n return; }`, - output: `!function foo() { \n return; \n}`, + code: '!function foo() { \n return; }', + output: '!function foo() { \n return; \n}', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'singleLineClose' }], }, { - code: `if (a) { b();\n } else { c(); }`, - output: `if (a) {\n b();\n } else { c(); }`, + code: 'if (a) { b();\n } else { c(); }', + output: 'if (a) {\n b();\n } else { c(); }', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'blockSameLine' }], }, { - code: `if (a) { b(); }\nelse { c(); }`, - output: `if (a) { b(); } else { c(); }`, + code: 'if (a) { b(); }\nelse { c(); }', + output: 'if (a) { b(); } else { c(); }', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'nextLineClose' }], }, { - code: `while (foo) { \n bar(); }`, - output: `while (foo) { \n bar(); \n}`, + code: 'while (foo) { \n bar(); }', + output: 'while (foo) { \n bar(); \n}', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'singleLineClose' }], }, { - code: `for (;;) { bar(); \n }`, - output: `for (;;) {\n bar(); \n }`, + code: 'for (;;) { bar(); \n }', + output: 'for (;;) {\n bar(); \n }', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'blockSameLine' }], }, { - code: `with (foo) { bar(); \n }`, - output: `with (foo) {\n bar(); \n }`, + code: 'with (foo) { bar(); \n }', + output: 'with (foo) {\n bar(); \n }', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'blockSameLine' }], }, { - code: `switch (foo) \n { \n case \`bar\`: break; }`, - output: `switch (foo) { \n case \`bar\`: break; \n}`, + code: 'switch (foo) \n { \n case `bar`: break; }', + output: 'switch (foo) { \n case `bar`: break; \n}', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'nextLineOpen' }, { messageId: 'singleLineClose' }], }, { - code: `switch (foo) \n { }`, - output: `switch (foo) { }`, + code: 'switch (foo) \n { }', + output: 'switch (foo) { }', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'nextLineOpen' }], }, { - code: `try { bar(); }\ncatch (e) { baz(); }`, - output: `try { bar(); } catch (e) { baz(); }`, + code: 'try { bar(); }\ncatch (e) { baz(); }', + output: 'try { bar(); } catch (e) { baz(); }', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'nextLineClose' }], }, { - code: `try \n { \n bar(); \n } catch (e) {}`, - output: `try { \n bar(); \n } catch (e) {}`, + code: 'try \n { \n bar(); \n } catch (e) {}', + output: 'try { \n bar(); \n } catch (e) {}', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'nextLineOpen' }], }, { - code: `try { \n bar(); \n } catch (e) \n {}`, - output: `try { \n bar(); \n } catch (e) {}`, + code: 'try { \n bar(); \n } catch (e) \n {}', + output: 'try { \n bar(); \n } catch (e) {}', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'nextLineOpen' }], }, { - code: `do \n { \n bar(); \n} while (true)`, - output: `do { \n bar(); \n} while (true)`, + code: 'do \n { \n bar(); \n} while (true)', + output: 'do { \n bar(); \n} while (true)', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'nextLineOpen' }], }, { - code: `for (foo in bar) \n { \n baz(); \n }`, - output: `for (foo in bar) { \n baz(); \n }`, + code: 'for (foo in bar) \n { \n baz(); \n }', + output: 'for (foo in bar) { \n baz(); \n }', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'nextLineOpen' }], }, { - code: `try { \n bar(); \n }\ncatch (e) {\n}`, - output: `try { \n bar(); \n } catch (e) {\n}`, + code: 'try { \n bar(); \n }\ncatch (e) {\n}', + output: 'try { \n bar(); \n } catch (e) {\n}', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'nextLineClose' }], }, { - code: `try { \n bar(); \n } catch (e) {\n}\n finally {\n}`, - output: `try { \n bar(); \n } catch (e) {\n} finally {\n}`, + code: 'try { \n bar(); \n } catch (e) {\n}\n finally {\n}', + output: 'try { \n bar(); \n } catch (e) {\n} finally {\n}', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'nextLineClose' }], }, { - code: `if (a) { \nb();\n } \n else { \nc();\n }`, - output: `if (a) { \nb();\n } else { \nc();\n }`, + code: 'if (a) { \nb();\n } \n else { \nc();\n }', + output: 'if (a) { \nb();\n } else { \nc();\n }', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'nextLineClose' }], }, { - code: `try { \n bar(); \n }\ncatch (e) {\n} finally {\n}`, - output: `try { \n bar(); \n }\ncatch (e) {\n}\n finally {\n}`, + code: 'try { \n bar(); \n }\ncatch (e) {\n} finally {\n}', + output: 'try { \n bar(); \n }\ncatch (e) {\n}\n finally {\n}', options: ['stroustrup', { allowSingleLine: true }], errors: [{ messageId: 'sameLineClose' }], }, { - code: `try { \n bar(); \n } catch (e) {\n}\n finally {\n}`, - output: `try { \n bar(); \n }\n catch (e) {\n}\n finally {\n}`, + code: 'try { \n bar(); \n } catch (e) {\n}\n finally {\n}', + output: 'try { \n bar(); \n }\n catch (e) {\n}\n finally {\n}', options: ['stroustrup', { allowSingleLine: true }], errors: [{ messageId: 'sameLineClose' }], }, { - code: `if (a) { \nb();\n } else { \nc();\n }`, - output: `if (a) { \nb();\n }\n else { \nc();\n }`, + code: 'if (a) { \nb();\n } else { \nc();\n }', + output: 'if (a) { \nb();\n }\n else { \nc();\n }', options: ['stroustrup', { allowSingleLine: true }], errors: [{ messageId: 'sameLineClose' }], }, { - code: `if (foo)\n{ poop();\n} \nelse if (bar) {\nbaz();\n} else if (thing) {\nboom();\n}\nelse {\nqux();\n}`, - output: `if (foo)\n{\n poop();\n} \nelse if (bar) \n{\nbaz();\n}\n else if (thing) \n{\nboom();\n}\nelse \n{\nqux();\n}`, + code: + 'if (foo)\n{ poop();\n} \nelse if (bar) {\nbaz();\n} else if (thing) {\nboom();\n}\nelse {\nqux();\n}', + output: + 'if (foo)\n{\n poop();\n} \nelse if (bar) \n{\nbaz();\n}\n else if (thing) \n{\nboom();\n}\nelse \n{\nqux();\n}', options: ['allman', { allowSingleLine: true }], errors: [ { messageId: 'blockSameLine' }, @@ -945,25 +961,25 @@ if (f) { }, // Comment interferes with fix { - code: `if (foo) // comment \n{\nbar();\n}`, + code: 'if (foo) // comment \n{\nbar();\n}', output: null, errors: [{ messageId: 'nextLineOpen' }], }, // https://github.com/eslint/eslint/issues/7493 { - code: `if (foo) {\n bar\n.baz }`, - output: `if (foo) {\n bar\n.baz \n}`, + code: 'if (foo) {\n bar\n.baz }', + output: 'if (foo) {\n bar\n.baz \n}', errors: [{ messageId: 'singleLineClose' }], }, { - code: `if (foo)\n{\n bar\n.baz }`, - output: `if (foo)\n{\n bar\n.baz \n}`, + code: 'if (foo)\n{\n bar\n.baz }', + output: 'if (foo)\n{\n bar\n.baz \n}', options: ['allman'], errors: [{ messageId: 'singleLineClose' }], }, { - code: `if (foo) { bar\n.baz }`, - output: `if (foo) {\n bar\n.baz \n}`, + code: 'if (foo) { bar\n.baz }', + output: 'if (foo) {\n bar\n.baz \n}', options: ['1tbs', { allowSingleLine: true }], errors: [ { messageId: 'blockSameLine' }, @@ -971,8 +987,8 @@ if (f) { ], }, { - code: `if (foo) { bar\n.baz }`, - output: `if (foo) \n{\n bar\n.baz \n}`, + code: 'if (foo) { bar\n.baz }', + output: 'if (foo) \n{\n bar\n.baz \n}', options: ['allman', { allowSingleLine: true }], errors: [ { messageId: 'sameLineOpen' }, @@ -981,46 +997,46 @@ if (f) { ], }, { - code: `switch (x) {\n case 1: foo() }`, - output: `switch (x) {\n case 1: foo() \n}`, + code: 'switch (x) {\n case 1: foo() }', + output: 'switch (x) {\n case 1: foo() \n}', options: ['1tbs', { allowSingleLine: true }], errors: [{ messageId: 'singleLineClose' }], }, { - code: `class Foo\n{\n}`, - output: `class Foo {\n}`, + code: 'class Foo\n{\n}', + output: 'class Foo {\n}', errors: [{ messageId: 'nextLineOpen' }], }, { - code: `(class\n{\n})`, - output: `(class {\n})`, + code: '(class\n{\n})', + output: '(class {\n})', errors: [{ messageId: 'nextLineOpen' }], }, { - code: `class Foo{\n}`, - output: `class Foo\n{\n}`, + code: 'class Foo{\n}', + output: 'class Foo\n{\n}', options: ['allman'], errors: [{ messageId: 'sameLineOpen' }], }, { - code: `(class {\n})`, - output: `(class \n{\n})`, + code: '(class {\n})', + output: '(class \n{\n})', options: ['allman'], errors: [{ messageId: 'sameLineOpen' }], }, { - code: `class Foo {\nbar() {\n}}`, - output: `class Foo {\nbar() {\n}\n}`, + code: 'class Foo {\nbar() {\n}}', + output: 'class Foo {\nbar() {\n}\n}', errors: [{ messageId: 'singleLineClose' }], }, { - code: `(class Foo {\nbar() {\n}})`, - output: `(class Foo {\nbar() {\n}\n})`, + code: '(class Foo {\nbar() {\n}})', + output: '(class Foo {\nbar() {\n}\n})', errors: [{ messageId: 'singleLineClose' }], }, { - code: `class\nFoo{}`, - output: `class\nFoo\n{}`, + code: 'class\nFoo{}', + output: 'class\nFoo\n{}', options: ['allman'], errors: [{ messageId: 'sameLineOpen' }], }, @@ -1070,8 +1086,8 @@ interface Foo { errors: [{ messageId: 'nextLineOpen' }], }, { - code: `interface Foo { \n }`, - output: `interface Foo \n{ \n }`, + code: 'interface Foo { \n }', + output: 'interface Foo \n{ \n }', options: ['allman'], errors: [{ messageId: 'sameLineOpen' }], }, @@ -1101,8 +1117,8 @@ module "Foo" { errors: [{ messageId: 'nextLineOpen' }], }, { - code: `module "Foo" { \n }`, - output: `module "Foo" \n{ \n }`, + code: 'module "Foo" { \n }', + output: 'module "Foo" \n{ \n }', options: ['allman'], errors: [{ messageId: 'sameLineOpen' }], }, @@ -1132,8 +1148,8 @@ namespace Foo { errors: [{ messageId: 'nextLineOpen' }], }, { - code: `namespace Foo { \n }`, - output: `namespace Foo \n{ \n }`, + code: 'namespace Foo { \n }', + output: 'namespace Foo \n{ \n }', options: ['allman'], errors: [{ messageId: 'sameLineOpen' }], }, @@ -1163,8 +1179,8 @@ enum Foo { errors: [{ messageId: 'nextLineOpen' }], }, { - code: `enum Foo { A }`, - output: `enum Foo \n{\n A \n}`, + code: 'enum Foo { A }', + output: 'enum Foo \n{\n A \n}', options: ['allman'], errors: [ { messageId: 'sameLineOpen' }, diff --git a/packages/eslint-plugin/tests/rules/camelcase.test.ts b/packages/eslint-plugin/tests/rules/camelcase.test.ts index 617cdf3e40f7..1a35ee87cc82 100644 --- a/packages/eslint-plugin/tests/rules/camelcase.test.ts +++ b/packages/eslint-plugin/tests/rules/camelcase.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/camelcase'; -import { RuleTester } from '../RuleTester'; +import { RuleTester, noFormat } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', @@ -8,75 +8,147 @@ const ruleTester = new RuleTester({ ruleTester.run('camelcase', rule, { valid: [ { - code: 'interface Foo { b_ar: number }', + code: ` +interface Foo { + b_ar: number; +} + `, options: [{ properties: 'never' }], }, { - code: 'interface Foo { bar: number }', + code: ` +interface Foo { + bar: number; +} + `, options: [{ properties: 'always' }], }, { - code: 'class Foo { b_ar: number; }', + code: ` +class Foo { + b_ar: number; +} + `, options: [{ properties: 'never' }], }, { - code: 'class Foo { bar: number; }', + code: ` +class Foo { + bar: number; +} + `, options: [{ properties: 'always' }], }, { - code: 'class Foo { b_ar: number = 0; }', + code: ` +class Foo { + b_ar: number = 0; +} + `, options: [{ properties: 'never' }], }, { - code: 'class Foo { bar: number = 0; }', + code: ` +class Foo { + bar: number = 0; +} + `, options: [{ properties: 'always' }], }, { - code: 'class Foo { constructor(private b_ar: number) {} }', + code: ` +class Foo { + constructor(private b_ar: number) {} +} + `, options: [{ properties: 'never' }], }, { - code: 'class Foo { constructor(private bar: number) {} }', + code: ` +class Foo { + constructor(private bar: number) {} +} + `, options: [{ properties: 'always' }], }, { - code: 'class Foo { constructor(private b_ar: number = 0) {} }', + code: ` +class Foo { + constructor(private b_ar: number = 0) {} +} + `, options: [{ properties: 'never' }], }, { - code: 'class Foo { constructor(private bar: number = 0) {} }', + code: ` +class Foo { + constructor(private bar: number = 0) {} +} + `, options: [{ properties: 'always' }], }, { - code: 'abstract class Foo { b_ar: number; }', + code: ` +abstract class Foo { + b_ar: number; +} + `, options: [{ properties: 'never' }], }, { - code: 'abstract class Foo { bar: number; }', + code: ` +abstract class Foo { + bar: number; +} + `, options: [{ properties: 'always' }], }, { - code: 'abstract class Foo { b_ar: number = 0; }', + code: ` +abstract class Foo { + b_ar: number = 0; +} + `, options: [{ properties: 'never' }], }, { - code: 'abstract class Foo { bar: number = 0; }', + code: ` +abstract class Foo { + bar: number = 0; +} + `, options: [{ properties: 'always' }], }, { - code: 'abstract class Foo { abstract b_ar: number; }', + code: ` +abstract class Foo { + abstract b_ar: number; +} + `, options: [{ properties: 'never' }], }, { - code: 'abstract class Foo { abstract bar: number; }', + code: ` +abstract class Foo { + abstract bar: number; +} + `, options: [{ properties: 'always' }], }, { - code: 'abstract class Foo { abstract b_ar: number = 0; }', + code: ` +abstract class Foo { + abstract b_ar: number = 0; +} + `, options: [{ properties: 'never' }], }, { - code: 'abstract class Foo { abstract bar: number = 0; }', + code: ` +abstract class Foo { + abstract bar: number = 0; +} + `, options: [{ properties: 'always' }], }, { @@ -141,19 +213,19 @@ class Foo { }, { code: ` -type Foo = {} +type Foo = {}; `, options: [{ genericType: 'always' }], }, { code: ` -type Foo = {} +type Foo = {}; `, options: [{ genericType: 'always' }], }, { code: ` -type Foo = {} +type Foo = {}; `, options: [{ genericType: 'never' }], }, @@ -183,7 +255,7 @@ class Foo { code: 'const foo = foo.bar?.foo_bar_baz;', }, { - code: 'const foo = (foo?.bar?.baz)?.foo_bar_baz;', + code: noFormat`const foo = (foo?.bar?.baz)?.foo_bar_baz;`, }, { code: 'const foo = foo_bar?.foo;', @@ -193,7 +265,11 @@ class Foo { invalid: [ { - code: 'interface Foo { b_ar: number }', + code: ` +interface Foo { + b_ar: number; +} + `, options: [{ properties: 'always' }], errors: [ { @@ -201,13 +277,17 @@ class Foo { data: { name: 'b_ar', }, - line: 1, - column: 17, + line: 3, + column: 3, }, ], }, { - code: 'class Foo { b_ar: number; }', + code: ` +class Foo { + b_ar: number; +} + `, options: [{ properties: 'always' }], errors: [ { @@ -215,13 +295,17 @@ class Foo { data: { name: 'b_ar', }, - line: 1, - column: 13, + line: 3, + column: 3, }, ], }, { - code: 'class Foo { constructor(private b_ar: number) {} }', + code: ` +class Foo { + constructor(private b_ar: number) {} +} + `, options: [{ properties: 'always' }], errors: [ { @@ -229,13 +313,17 @@ class Foo { data: { name: 'b_ar', }, - line: 1, - column: 33, + line: 3, + column: 23, }, ], }, { - code: 'class Foo { constructor(private b_ar: number = 0) {} }', + code: ` +class Foo { + constructor(private b_ar: number = 0) {} +} + `, options: [{ properties: 'always' }], errors: [ { @@ -243,13 +331,17 @@ class Foo { data: { name: 'b_ar', }, - line: 1, - column: 33, + line: 3, + column: 23, }, ], }, { - code: 'abstract class Foo { b_ar: number; }', + code: ` +abstract class Foo { + b_ar: number; +} + `, options: [{ properties: 'always' }], errors: [ { @@ -257,13 +349,17 @@ class Foo { data: { name: 'b_ar', }, - line: 1, - column: 22, + line: 3, + column: 3, }, ], }, { - code: 'abstract class Foo { b_ar: number = 0; }', + code: ` +abstract class Foo { + b_ar: number = 0; +} + `, options: [{ properties: 'always' }], errors: [ { @@ -271,13 +367,17 @@ class Foo { data: { name: 'b_ar', }, - line: 1, - column: 22, + line: 3, + column: 3, }, ], }, { - code: 'abstract class Foo { abstract b_ar: number; }', + code: ` +abstract class Foo { + abstract b_ar: number; +} + `, options: [{ properties: 'always' }], errors: [ { @@ -285,13 +385,17 @@ class Foo { data: { name: 'b_ar', }, - line: 1, - column: 31, + line: 3, + column: 12, }, ], }, { - code: 'abstract class Foo { abstract b_ar: number = 0; }', + code: ` +abstract class Foo { + abstract b_ar: number = 0; +} + `, options: [{ properties: 'always' }], errors: [ { @@ -299,8 +403,8 @@ class Foo { data: { name: 'b_ar', }, - line: 1, - column: 31, + line: 3, + column: 12, }, ], }, @@ -319,7 +423,7 @@ class Foo { ], }, { - code: 'const foo = (foo_test?.bar)?.baz;', + code: noFormat`const foo = (foo_test?.bar)?.baz;`, options: [{ properties: 'always' }], errors: [ { diff --git a/packages/eslint-plugin/tests/rules/class-literal-property-style.test.ts b/packages/eslint-plugin/tests/rules/class-literal-property-style.test.ts index f0c5f2afc055..19d5fb183b54 100644 --- a/packages/eslint-plugin/tests/rules/class-literal-property-style.test.ts +++ b/packages/eslint-plugin/tests/rules/class-literal-property-style.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/class-literal-property-style'; -import { RuleTester } from '../RuleTester'; +import { RuleTester, noFormat } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', @@ -7,18 +7,50 @@ const ruleTester = new RuleTester({ ruleTester.run('class-literal-property-style', rule, { valid: [ - 'class Mx { declare readonly p1 = 1; }', - 'class Mx { readonly p1 = "hello world"; }', - 'class Mx { p1 = "hello world"; }', - 'class Mx { static p1 = "hello world"; }', - 'class Mx { p1: string; }', - 'class Mx { get p1(); }', - 'class Mx { get p1() {} }', - 'abstract class Mx { abstract get p1(): string }', + ` +class Mx { + declare readonly p1 = 1; +} + `, + ` +class Mx { + readonly p1 = 'hello world'; +} + `, + ` +class Mx { + p1 = 'hello world'; +} + `, + ` +class Mx { + static p1 = 'hello world'; +} + `, + ` +class Mx { + p1: string; +} + `, + ` +class Mx { + get p1(); +} + `, + ` +class Mx { + get p1() {} +} + `, + ` +abstract class Mx { + abstract get p1(): string; +} + `, ` class Mx { get mySetting() { - if(this._aValue) { + if (this._aValue) { return 'on'; } @@ -29,14 +61,14 @@ ruleTester.run('class-literal-property-style', rule, { ` class Mx { get mySetting() { - return \`build-\${process.env.build}\` + return \`build-\${process.env.build}\`; } } `, ` class Mx { getMySetting() { - if(this._aValue) { + if (this._aValue) { return 'on'; } @@ -64,31 +96,63 @@ ruleTester.run('class-literal-property-style', rule, { options: ['fields'], }, { - code: 'class Mx { declare public readonly foo = 1; }', + code: ` +class Mx { + public declare readonly foo = 1; +} + `, options: ['getters'], }, { - code: 'class Mx { get p1() { return "hello world"; } }', + code: ` +class Mx { + get p1() { + return 'hello world'; + } +} + `, options: ['getters'], }, { - code: 'class Mx { p1 = "hello world"; }', + code: ` +class Mx { + p1 = 'hello world'; +} + `, options: ['getters'], }, { - code: 'class Mx { p1: string; }', + code: ` +class Mx { + p1: string; +} + `, options: ['getters'], }, { - code: 'class Mx { readonly p1 = [1, 2, 3]; }', + code: ` +class Mx { + readonly p1 = [1, 2, 3]; +} + `, options: ['getters'], }, { - code: 'class Mx { static p1: string; }', + code: ` +class Mx { + static p1: string; +} + `, options: ['getters'], }, { - code: 'class Mx { static get p1() { return "hello world"; } }', + code: ` +class Mx { + static get p1() { + return 'hello world'; + } +} + `, options: ['getters'], }, { @@ -116,259 +180,358 @@ ruleTester.run('class-literal-property-style', rule, { ], invalid: [ { - code: 'class Mx { get p1() { return "hello world"; } }', - output: 'class Mx { readonly p1 = "hello world"; }', + code: ` +class Mx { + get p1() { + return 'hello world'; + } +} + `, + output: ` +class Mx { + readonly p1 = 'hello world'; +} + `, errors: [ { messageId: 'preferFieldStyle', - column: 16, - line: 1, + column: 7, + line: 3, }, ], }, { - code: 'class Mx { get p1() { return `hello world`; } }', - output: 'class Mx { readonly p1 = `hello world`; }', + code: ` +class Mx { + get p1() { + return \`hello world\`; + } +} + `, + output: ` +class Mx { + readonly p1 = \`hello world\`; +} + `, errors: [ { messageId: 'preferFieldStyle', - column: 16, - line: 1, + column: 7, + line: 3, }, ], }, { - code: 'class Mx { static get p1() { return "hello world"; } }', - output: 'class Mx { static readonly p1 = "hello world"; }', + code: ` +class Mx { + static get p1() { + return 'hello world'; + } +} + `, + output: ` +class Mx { + static readonly p1 = 'hello world'; +} + `, errors: [ { messageId: 'preferFieldStyle', - column: 23, - line: 1, + column: 14, + line: 3, }, ], }, { - code: - 'class Mx { public static readonly static private public protected get foo() { return 1; } }', - output: 'class Mx { public static readonly foo = 1; }', + code: ` +class Mx { + public static get foo() { + return 1; + } +} + `, + output: ` +class Mx { + public static readonly foo = 1; +} + `, errors: [ { messageId: 'preferFieldStyle', - column: 71, - line: 1, + column: 21, + line: 3, }, ], }, { code: ` - class Mx { - public get [myValue]() { - return 'a literal value'; - } - } +class Mx { + public get [myValue]() { + return 'a literal value'; + } +} `, output: ` - class Mx { - public readonly [myValue] = 'a literal value'; - } +class Mx { + public readonly [myValue] = 'a literal value'; +} `, errors: [ { messageId: 'preferFieldStyle', - column: 23, + column: 15, line: 3, }, ], }, { code: ` - class Mx { - public get [myValue]() { - return 12345n; - } - } +class Mx { + public get [myValue]() { + return 12345n; + } +} `, output: ` - class Mx { - public readonly [myValue] = 12345n; - } +class Mx { + public readonly [myValue] = 12345n; +} `, errors: [ { messageId: 'preferFieldStyle', - column: 23, + column: 15, line: 3, }, ], }, { code: ` - class Mx { - public readonly [myValue] = 'a literal value'; - } +class Mx { + public readonly [myValue] = 'a literal value'; +} `, - output: ` - class Mx { - public get [myValue]() { return 'a literal value'; } - } + output: noFormat` +class Mx { + public get [myValue]() { return 'a literal value'; } +} `, errors: [ { messageId: 'preferGetterStyle', - column: 28, + column: 20, line: 3, }, ], options: ['getters'], }, { - code: 'class Mx { readonly p1 = "hello world"; }', - output: 'class Mx { get p1() { return "hello world"; } }', + code: ` +class Mx { + readonly p1 = 'hello world'; +} + `, + output: noFormat` +class Mx { + get p1() { return 'hello world'; } +} + `, errors: [ { messageId: 'preferGetterStyle', - column: 21, - line: 1, + column: 12, + line: 3, }, ], options: ['getters'], }, { - code: 'class Mx { readonly p1 = `hello world`; }', - output: 'class Mx { get p1() { return `hello world`; } }', + code: ` +class Mx { + readonly p1 = \`hello world\`; +} + `, + output: noFormat` +class Mx { + get p1() { return \`hello world\`; } +} + `, errors: [ { messageId: 'preferGetterStyle', - column: 21, - line: 1, + column: 12, + line: 3, }, ], options: ['getters'], }, { - code: 'class Mx { static readonly p1 = "hello world"; }', - output: 'class Mx { static get p1() { return "hello world"; } }', + code: ` +class Mx { + static readonly p1 = 'hello world'; +} + `, + output: noFormat` +class Mx { + static get p1() { return 'hello world'; } +} + `, errors: [ { messageId: 'preferGetterStyle', - column: 28, - line: 1, + column: 19, + line: 3, }, ], options: ['getters'], }, { - code: 'class Mx { protected get p1() { return "hello world"; } }', - output: 'class Mx { protected readonly p1 = "hello world"; }', + code: ` +class Mx { + protected get p1() { + return 'hello world'; + } +} + `, + output: ` +class Mx { + protected readonly p1 = 'hello world'; +} + `, errors: [ { messageId: 'preferFieldStyle', - column: 26, - line: 1, + column: 17, + line: 3, }, ], options: ['fields'], }, { - code: 'class Mx { protected readonly p1 = "hello world"; }', - output: 'class Mx { protected get p1() { return "hello world"; } }', + code: ` +class Mx { + protected readonly p1 = 'hello world'; +} + `, + output: noFormat` +class Mx { + protected get p1() { return 'hello world'; } +} + `, errors: [ { messageId: 'preferGetterStyle', - column: 31, - line: 1, + column: 22, + line: 3, }, ], options: ['getters'], }, { - code: 'class Mx { public static get p1() { return "hello world"; } }', - output: 'class Mx { public static readonly p1 = "hello world"; }', + code: ` +class Mx { + public static get p1() { + return 'hello world'; + } +} + `, + output: ` +class Mx { + public static readonly p1 = 'hello world'; +} + `, errors: [ { messageId: 'preferFieldStyle', - column: 30, - line: 1, + column: 21, + line: 3, }, ], }, { - code: 'class Mx { public static readonly p1 = "hello world"; }', - output: 'class Mx { public static get p1() { return "hello world"; } }', + code: ` +class Mx { + public static readonly p1 = 'hello world'; +} + `, + output: noFormat` +class Mx { + public static get p1() { return 'hello world'; } +} + `, errors: [ { messageId: 'preferGetterStyle', - column: 35, - line: 1, + column: 26, + line: 3, }, ], options: ['getters'], }, { code: ` - class Mx { - public get myValue() { - return gql\` - { - user(id: 5) { - firstName - lastName - } - } - \`; - } +class Mx { + public get myValue() { + return gql\` + { + user(id: 5) { + firstName + lastName } + } + \`; + } +} `, - output: ` - class Mx { - public readonly myValue = gql\` - { - user(id: 5) { - firstName - lastName - } - } - \`; + output: noFormat` +class Mx { + public readonly myValue = gql\` + { + user(id: 5) { + firstName + lastName } + } + \`; +} `, errors: [ { messageId: 'preferFieldStyle', - column: 22, + column: 14, line: 3, }, ], }, { code: ` - class Mx { - public readonly myValue = gql\` - { - user(id: 5) { - firstName - lastName - } - } - \`; - } +class Mx { + public readonly myValue = gql\` + { + user(id: 5) { + firstName + lastName + } + } + \`; +} `, - output: ` - class Mx { - public get myValue() { return gql\` - { - user(id: 5) { - firstName - lastName - } - } - \`; } - } + output: noFormat` +class Mx { + public get myValue() { return gql\` + { + user(id: 5) { + firstName + lastName + } + } + \`; } +} `, errors: [ { messageId: 'preferGetterStyle', - column: 27, + column: 19, line: 3, }, ], diff --git a/packages/eslint-plugin/tests/rules/class-name-casing.test.ts b/packages/eslint-plugin/tests/rules/class-name-casing.test.ts index 11f6dc8b8889..1977a36415da 100644 --- a/packages/eslint-plugin/tests/rules/class-name-casing.test.ts +++ b/packages/eslint-plugin/tests/rules/class-name-casing.test.ts @@ -35,12 +35,19 @@ ruleTester.run('class-name-casing', rule, { 'class ÈClassNameWithUnicode {}', 'class ClassNameWithæUnicode {}', // Following test cases are valid, but no one is going to write code like this - 'var { bar } = class { static bar() { return 2 } }', - `var [ bar ] = class { - static [Symbol.iterator]() { - return { next: () => ({ value: 1, done: false}) } - } - } + ` +var { bar } = class { + static bar() { + return 2; + } +}; + `, + ` +var [bar] = class { + static [Symbol.iterator]() { + return { next: () => ({ value: 1, done: false }) }; + } +}; `, ], @@ -116,7 +123,7 @@ ruleTester.run('class-name-casing', rule, { ], }, { - code: 'var bar = class invalidName {}', + code: 'var bar = class invalidName {};', errors: [ { messageId: 'notPascalCased', diff --git a/packages/eslint-plugin/tests/rules/comma-spacing.test.ts b/packages/eslint-plugin/tests/rules/comma-spacing.test.ts index 12a6e0219f8c..7147815b7595 100644 --- a/packages/eslint-plugin/tests/rules/comma-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/comma-spacing.test.ts @@ -1,3 +1,8 @@ +/* eslint-disable eslint-comments/no-use */ +// this rule tests the spacing, 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/comma-spacing'; import { RuleTester } from '../RuleTester'; @@ -7,280 +12,280 @@ const ruleTester = new RuleTester({ ruleTester.run('comma-spacing', rule, { valid: [ - `foo(1, true/* comment */, 'text');`, - `foo(1, true /* comment */, 'text');`, - `foo(1, true/* comment *//* comment */, 'text');`, - `foo(1, true/* comment */ /* comment */, 'text');`, - `foo(1, true, /* comment */ 'text');`, - `foo(1, // comment\n true, /* comment */ 'text');`, - { - code: `foo(1, // comment\n true,/* comment */ 'text');`, + "foo(1, true/* comment */, 'text');", + "foo(1, true /* comment */, 'text');", + "foo(1, true/* comment *//* comment */, 'text');", + "foo(1, true/* comment */ /* comment */, 'text');", + "foo(1, true, /* comment */ 'text');", + "foo(1, // comment\n true, /* comment */ 'text');", + { + code: "foo(1, // comment\n true,/* comment */ 'text');", options: [{ before: false, after: false }], }, - `const a = 1, b = 2;`, - `const foo = [, ];`, - `const foo = [1, ];`, - `const foo = [, 2];`, - `const foo = [1, 2];`, - `const foo = [, , ];`, - `const foo = [1, , ];`, - `const foo = [, 2, ];`, - `const foo = [, , 3];`, - `const foo = [1, 2, ];`, - `const foo = [, 2, 3];`, - `const foo = [1, , 3];`, - `const foo = [1, 2, 3];`, - `const foo = {'foo':'foo', 'baz':'baz'};`, - `const foo = {'foo':'foo', 'baz':\n'baz'};`, - `const foo = {'foo':\n'foo', 'baz':\n'baz'};`, - `function foo(a, b){}`, - `function foo(a, b = 1){}`, - `function foo(a = 1, b, c){}`, - `const foo = (a, b) => {}`, - `const foo = (a=1, b) => {}`, - `const foo = a => a + 2`, - `a, b`, - `const a = (1 + 2, 2)`, - `a(b, c)`, - `new A(b, c)`, - `foo((a), b)`, - `const b = ((1 + 2), 2)`, - `parseInt((a + b), 10)`, - `go.boom((a + b), 10)`, - `go.boom((a + b), 10, (4))`, - `const x = [ (a + c), (b + b) ]`, - `[' , ']`, + 'const a = 1, b = 2;', + 'const foo = [, ];', + 'const foo = [1, ];', + 'const foo = [, 2];', + 'const foo = [1, 2];', + 'const foo = [, , ];', + 'const foo = [1, , ];', + 'const foo = [, 2, ];', + 'const foo = [, , 3];', + 'const foo = [1, 2, ];', + 'const foo = [, 2, 3];', + 'const foo = [1, , 3];', + 'const foo = [1, 2, 3];', + "const foo = {'foo':'foo', 'baz':'baz'};", + "const foo = {'foo':'foo', 'baz':\n'baz'};", + "const foo = {'foo':\n'foo', 'baz':\n'baz'};", + 'function foo(a, b){}', + 'function foo(a, b = 1){}', + 'function foo(a = 1, b, c){}', + 'const foo = (a, b) => {}', + 'const foo = (a=1, b) => {}', + 'const foo = a => a + 2', + 'a, b', + 'const a = (1 + 2, 2)', + 'a(b, c)', + 'new A(b, c)', + 'foo((a), b)', + 'const b = ((1 + 2), 2)', + 'parseInt((a + b), 10)', + 'go.boom((a + b), 10)', + 'go.boom((a + b), 10, (4))', + 'const x = [ (a + c), (b + b) ]', + "[' , ']", '[` , `]', '`${[1, 2]}`', - `fn(a, b,)`, - `const fn = (a, b,) => {}`, - `const fn = function (a, b,) {}`, - `foo(/,/, 'a')`, - `const x = ',,,,,';`, - `const code = 'var foo = 1, bar = 3;'`, - `['apples', \n 'oranges'];`, - `{x: 'var x,y,z'}`, - { - code: `const foo = {'foo':\n'bar' ,'baz':\n'qur'};`, + 'fn(a, b,)', + 'const fn = (a, b,) => {}', + 'const fn = function (a, b,) {}', + "foo(/,/, 'a')", + "const x = ',,,,,';", + "const code = 'var foo = 1, bar = 3;'", + "['apples', \n 'oranges'];", + "{x: 'var x,y,z'}", + { + code: "const foo = {'foo':\n'bar' ,'baz':\n'qur'};", options: [{ before: true, after: false }], }, { - code: `const a = 1 ,b = 2;`, + code: 'const a = 1 ,b = 2;', options: [{ before: true, after: false }], }, { - code: `function foo(a ,b){}`, + code: 'function foo(a ,b){}', options: [{ before: true, after: false }], }, { - code: `const arr = [,];`, + code: 'const arr = [,];', options: [{ before: true, after: false }], }, { - code: `const arr = [1 ,];`, + code: 'const arr = [1 ,];', options: [{ before: true, after: false }], }, { - code: `const arr = [ ,2];`, + code: 'const arr = [ ,2];', options: [{ before: true, after: false }], }, { - code: `const arr = [1 ,2];`, + code: 'const arr = [1 ,2];', options: [{ before: true, after: false }], }, { - code: `const arr = [,,];`, + code: 'const arr = [,,];', options: [{ before: true, after: false }], }, { - code: `const arr = [1 , ,];`, + code: 'const arr = [1 , ,];', options: [{ before: true, after: false }], }, { - code: `const arr = [ ,2 ,];`, + code: 'const arr = [ ,2 ,];', options: [{ before: true, after: false }], }, { - code: `const arr = [ , ,3];`, + code: 'const arr = [ , ,3];', options: [{ before: true, after: false }], }, { - code: `const arr = [1 ,2 ,];`, + code: 'const arr = [1 ,2 ,];', options: [{ before: true, after: false }], }, { - code: `const arr = [ ,2 ,3];`, + code: 'const arr = [ ,2 ,3];', options: [{ before: true, after: false }], }, { - code: `const arr = [1 , ,3];`, + code: 'const arr = [1 , ,3];', options: [{ before: true, after: false }], }, { - code: `const arr = [1 ,2 ,3];`, + code: 'const arr = [1 ,2 ,3];', options: [{ before: true, after: false }], }, { - code: `const obj = {'foo':'bar' , 'baz':'qur'};`, + code: "const obj = {'foo':'bar' , 'baz':'qur'};", options: [{ before: true, after: true }], }, { - code: `const a = 1 , b = 2;`, + code: 'const a = 1 , b = 2;', options: [{ before: true, after: true }], }, { - code: `const arr = [, ];`, + code: 'const arr = [, ];', options: [{ before: true, after: true }], }, { - code: `const arr = [1 , ];`, + code: 'const arr = [1 , ];', options: [{ before: true, after: true }], }, { - code: `const arr = [ , 2];`, + code: 'const arr = [ , 2];', options: [{ before: true, after: true }], }, { - code: `const arr = [1 , 2];`, + code: 'const arr = [1 , 2];', options: [{ before: true, after: true }], }, { - code: `const arr = [, , ];`, + code: 'const arr = [, , ];', options: [{ before: true, after: true }], }, { - code: `const arr = [1 , , ];`, + code: 'const arr = [1 , , ];', options: [{ before: true, after: true }], }, { - code: `const arr = [ , 2 , ];`, + code: 'const arr = [ , 2 , ];', options: [{ before: true, after: true }], }, { - code: `const arr = [ , , 3];`, + code: 'const arr = [ , , 3];', options: [{ before: true, after: true }], }, { - code: `const arr = [1 , 2 , ];`, + code: 'const arr = [1 , 2 , ];', options: [{ before: true, after: true }], }, { - code: `const arr = [, 2 , 3];`, + code: 'const arr = [, 2 , 3];', options: [{ before: true, after: true }], }, { - code: `const arr = [1 , , 3];`, + code: 'const arr = [1 , , 3];', options: [{ before: true, after: true }], }, { - code: `const arr = [1 , 2 , 3];`, + code: 'const arr = [1 , 2 , 3];', options: [{ before: true, after: true }], }, { - code: `a , b`, + code: 'a , b', options: [{ before: true, after: true }], }, { - code: `const arr = [,];`, + code: 'const arr = [,];', options: [{ before: false, after: false }], }, { - code: `const arr = [ ,];`, + code: 'const arr = [ ,];', options: [{ before: false, after: false }], }, { - code: `const arr = [1,];`, + code: 'const arr = [1,];', options: [{ before: false, after: false }], }, { - code: `const arr = [,2];`, + code: 'const arr = [,2];', options: [{ before: false, after: false }], }, { - code: `const arr = [ ,2];`, + code: 'const arr = [ ,2];', options: [{ before: false, after: false }], }, { - code: `const arr = [1,2];`, + code: 'const arr = [1,2];', options: [{ before: false, after: false }], }, { - code: `const arr = [,,];`, + code: 'const arr = [,,];', options: [{ before: false, after: false }], }, { - code: `const arr = [ ,,];`, + code: 'const arr = [ ,,];', options: [{ before: false, after: false }], }, { - code: `const arr = [1,,];`, + code: 'const arr = [1,,];', options: [{ before: false, after: false }], }, { - code: `const arr = [,2,];`, + code: 'const arr = [,2,];', options: [{ before: false, after: false }], }, { - code: `const arr = [ ,2,];`, + code: 'const arr = [ ,2,];', options: [{ before: false, after: false }], }, { - code: `const arr = [,,3];`, + code: 'const arr = [,,3];', options: [{ before: false, after: false }], }, { - code: `const arr = [1,2,];`, + code: 'const arr = [1,2,];', options: [{ before: false, after: false }], }, { - code: `const arr = [,2,3];`, + code: 'const arr = [,2,3];', options: [{ before: false, after: false }], }, { - code: `const arr = [1,,3];`, + code: 'const arr = [1,,3];', options: [{ before: false, after: false }], }, { - code: `const arr = [1,2,3];`, + code: 'const arr = [1,2,3];', options: [{ before: false, after: false }], }, { - code: `const a = (1 + 2,2)`, + code: 'const a = (1 + 2,2)', options: [{ before: false, after: false }], }, 'const a; console.log(`${a}`, "a");', - `const [a, b] = [1, 2];`, - `const [a, b, ] = [1, 2];`, - `const [a, , b] = [1, 2, 3];`, - `const [ , b] = a;`, - `const [, b] = a;`, + 'const [a, b] = [1, 2];', + 'const [a, b, ] = [1, 2];', + 'const [a, , b] = [1, 2, 3];', + 'const [ , b] = a;', + 'const [, b] = a;', { - code: `,`, + code: ',', parserOptions: { ecmaFeatures: { jsx: true }, }, }, { - code: ` , `, + code: ' , ', parserOptions: { ecmaFeatures: { jsx: true }, }, }, { - code: `Hello, world`, + code: 'Hello, world', options: [{ before: true, after: false }], parserOptions: { ecmaFeatures: { jsx: true } }, }, - `const Foo = (foo: T) => {}`, - `function foo() {}`, - `class Foo {}`, - `interface Foo{}`, + 'const Foo = (foo: T) => {}', + 'function foo() {}', + 'class Foo {}', + 'interface Foo{}', ], invalid: [ { - code: `a(b,c)`, - output: `a(b , c)`, + code: 'a(b,c)', + output: 'a(b , c)', options: [{ before: true, after: true }], errors: [ { @@ -298,8 +303,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `new A(b,c)`, - output: `new A(b , c)`, + code: 'new A(b,c)', + output: 'new A(b , c)', options: [{ before: true, after: true }], errors: [ { @@ -317,8 +322,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const a = 1 ,b = 2;`, - output: `const a = 1, b = 2;`, + code: 'const a = 1 ,b = 2;', + output: 'const a = 1, b = 2;', errors: [ { messageId: 'unexpected', @@ -335,8 +340,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const arr = [1 , 2];`, - output: `const arr = [1, 2];`, + code: 'const arr = [1 , 2];', + output: 'const arr = [1, 2];', errors: [ { messageId: 'unexpected', @@ -359,8 +364,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const arr = [1 , ];`, - output: `const arr = [1 ,];`, + code: 'const arr = [1 , ];', + output: 'const arr = [1 ,];', options: [{ before: true, after: false }], errors: [ { @@ -372,8 +377,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const arr = [1 ,2];`, - output: `const arr = [1, 2];`, + code: 'const arr = [1 ,2];', + output: 'const arr = [1, 2];', errors: [ { messageId: 'unexpected', @@ -390,8 +395,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const arr = [(1) , 2];`, - output: `const arr = [(1), 2];`, + code: 'const arr = [(1) , 2];', + output: 'const arr = [(1), 2];', errors: [ { messageId: 'unexpected', @@ -402,8 +407,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const arr = [1, 2];`, - output: `const arr = [1 ,2];`, + code: 'const arr = [1, 2];', + output: 'const arr = [1 ,2];', options: [{ before: true, after: false }], errors: [ { @@ -421,8 +426,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const arr = [1\n , 2];`, - output: `const arr = [1\n ,2];`, + code: 'const arr = [1\n , 2];', + output: 'const arr = [1\n ,2];', options: [{ before: false, after: false }], errors: [ { @@ -434,8 +439,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const arr = [1,\n 2];`, - output: `const arr = [1 ,\n 2];`, + code: 'const arr = [1,\n 2];', + output: 'const arr = [1 ,\n 2];', options: [{ before: true, after: false }], errors: [ { @@ -447,8 +452,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const obj = {'foo':\n'bar', 'baz':\n'qur'};`, - output: `const obj = {'foo':\n'bar' ,'baz':\n'qur'};`, + code: "const obj = {'foo':\n'bar', 'baz':\n'qur'};", + output: "const obj = {'foo':\n'bar' ,'baz':\n'qur'};", options: [{ before: true, after: false }], errors: [ { @@ -466,8 +471,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const obj = {a: 1\n ,b: 2};`, - output: `const obj = {a: 1\n , b: 2};`, + code: 'const obj = {a: 1\n ,b: 2};', + output: 'const obj = {a: 1\n , b: 2};', options: [{ before: false, after: true }], errors: [ { @@ -479,8 +484,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const obj = {a: 1 ,\n b: 2};`, - output: `const obj = {a: 1,\n b: 2};`, + code: 'const obj = {a: 1 ,\n b: 2};', + output: 'const obj = {a: 1,\n b: 2};', options: [{ before: false, after: false }], errors: [ { @@ -492,8 +497,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const arr = [1 ,2];`, - output: `const arr = [1 , 2];`, + code: 'const arr = [1 ,2];', + output: 'const arr = [1 , 2];', options: [{ before: true, after: true }], errors: [ { @@ -505,8 +510,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const arr = [1,2];`, - output: `const arr = [1 , 2];`, + code: 'const arr = [1,2];', + output: 'const arr = [1 , 2];', options: [{ before: true, after: true }], errors: [ { @@ -524,8 +529,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const obj = {'foo':\n'bar','baz':\n'qur'};`, - output: `const obj = {'foo':\n'bar' , 'baz':\n'qur'};`, + code: "const obj = {'foo':\n'bar','baz':\n'qur'};", + output: "const obj = {'foo':\n'bar' , 'baz':\n'qur'};", options: [{ before: true, after: true }], errors: [ { @@ -543,8 +548,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const arr = [1 , 2];`, - output: `const arr = [1,2];`, + code: 'const arr = [1 , 2];', + output: 'const arr = [1,2];', options: [{ before: false, after: false }], errors: [ { @@ -562,8 +567,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `a ,b`, - output: `a, b`, + code: 'a ,b', + output: 'a, b', options: [{ before: false, after: true }], errors: [ { @@ -581,8 +586,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `function foo(a,b){}`, - output: `function foo(a , b){}`, + code: 'function foo(a,b){}', + output: 'function foo(a , b){}', options: [{ before: true, after: true }], errors: [ { @@ -600,8 +605,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const foo = (a,b) => {}`, - output: `const foo = (a , b) => {}`, + code: 'const foo = (a,b) => {}', + output: 'const foo = (a , b) => {}', options: [{ before: true, after: true }], errors: [ { @@ -619,8 +624,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `const foo = (a = 1,b) => {}`, - output: `const foo = (a = 1 , b) => {}`, + code: 'const foo = (a = 1,b) => {}', + output: 'const foo = (a = 1 , b) => {}', options: [{ before: true, after: true }], errors: [ { @@ -638,8 +643,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `function foo(a = 1 ,b = 2) {}`, - output: `function foo(a = 1, b = 2) {}`, + code: 'function foo(a = 1 ,b = 2) {}', + output: 'function foo(a = 1, b = 2) {}', options: [{ before: false, after: true }], errors: [ { @@ -657,8 +662,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `{foo(1 ,2)}`, - output: `{foo(1, 2)}`, + code: '{foo(1 ,2)}', + output: '{foo(1, 2)}', parserOptions: { ecmaFeatures: { jsx: true }, }, @@ -678,8 +683,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `foo(1, true/* comment */ , 'foo');`, - output: `foo(1, true/* comment */, 'foo');`, + code: "foo(1, true/* comment */ , 'foo');", + output: "foo(1, true/* comment */, 'foo');", errors: [ { messageId: 'unexpected', @@ -690,8 +695,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `foo(1, true,/* comment */ 'foo');`, - output: `foo(1, true, /* comment */ 'foo');`, + code: "foo(1, true,/* comment */ 'foo');", + output: "foo(1, true, /* comment */ 'foo');", errors: [ { messageId: 'missing', @@ -702,8 +707,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `foo(404,// comment\n true, 'hello');`, - output: `foo(404, // comment\n true, 'hello');`, + code: "foo(404,// comment\n true, 'hello');", + output: "foo(404, // comment\n true, 'hello');", errors: [ { messageId: 'missing', @@ -714,8 +719,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `function Foo() {}`, - output: `function Foo() {}`, + code: 'function Foo() {}', + output: 'function Foo() {}', errors: [ { messageId: 'missing', @@ -726,8 +731,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `function Foo() {}`, - output: `function Foo() {}`, + code: 'function Foo() {}', + output: 'function Foo() {}', errors: [ { messageId: 'unexpected', @@ -738,8 +743,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `function Foo() {}`, - output: `function Foo() {}`, + code: 'function Foo() {}', + output: 'function Foo() {}', errors: [ { messageId: 'unexpected', @@ -756,8 +761,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `function Foo() {}`, - output: `function Foo() {}`, + code: 'function Foo() {}', + output: 'function Foo() {}', options: [{ before: false, after: false }], errors: [ { @@ -769,8 +774,8 @@ ruleTester.run('comma-spacing', rule, { ], }, { - code: `function Foo() {}`, - output: `function Foo() {}`, + code: 'function Foo() {}', + output: 'function Foo() {}', options: [{ before: true, after: false }], errors: [ { diff --git a/packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts b/packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts index b777a1fc68f7..78e5d3ceb018 100644 --- a/packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/consistent-type-definitions'; -import { RuleTester } from '../RuleTester'; +import { RuleTester, noFormat } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', @@ -8,58 +8,62 @@ const ruleTester = new RuleTester({ ruleTester.run('consistent-type-definitions', rule, { valid: [ { - code: `var foo = { };`, + code: 'var foo = {};', options: ['interface'], }, { - code: `interface A {}`, + code: 'interface A {}', options: ['interface'], }, { - code: `interface A extends B { x: number; }`, + code: ` +interface A extends B { + x: number; +} + `, options: ['interface'], }, { - code: `type U = string;`, + code: 'type U = string;', options: ['interface'], }, { - code: `type V = { x: number; } | { y: string; };`, + code: 'type V = { x: number } | { y: string };', options: ['interface'], }, { code: ` type Record = { - [K in T]: U; -} -`, + [K in T]: U; +}; + `, options: ['interface'], }, { - code: `type T = { x: number; }`, + code: 'type T = { x: number };', options: ['type'], }, { - code: `type A = { x: number; } & B & C;`, + code: 'type A = { x: number } & B & C;', options: ['type'], }, { - code: `type A = { x: number; } & B & C;`, + code: 'type A = { x: number } & B & C;', options: ['type'], }, { code: ` export type W = { - x: T, + x: T; }; -`, + `, options: ['type'], }, ], invalid: [ { - code: `type T = { x: number; };`, - output: `interface T { x: number; }`, + code: noFormat`type T = { x: number; };`, + output: noFormat`interface T { x: number; }`, options: ['interface'], errors: [ { @@ -70,8 +74,8 @@ export type W = { ], }, { - code: `type T={ x: number; };`, - output: `interface T { x: number; }`, + code: noFormat`type T={ x: number; };`, + output: noFormat`interface T { x: number; }`, options: ['interface'], errors: [ { @@ -82,8 +86,8 @@ export type W = { ], }, { - code: `type T= { x: number; };`, - output: `interface T { x: number; }`, + code: noFormat`type T= { x: number; };`, + output: noFormat`interface T { x: number; }`, options: ['interface'], errors: [ { @@ -96,14 +100,14 @@ export type W = { { code: ` export type W = { - x: T, + x: T; }; -`, + `, output: ` export interface W { - x: T, + x: T; } -`, + `, options: ['interface'], errors: [ { @@ -114,8 +118,8 @@ export interface W { ], }, { - code: `interface T { x: number; }`, - output: `type T = { x: number; }`, + code: noFormat`interface T { x: number; }`, + output: noFormat`type T = { x: number; }`, options: ['type'], errors: [ { @@ -126,8 +130,8 @@ export interface W { ], }, { - code: `interface T{ x: number; }`, - output: `type T = { x: number; }`, + code: noFormat`interface T{ x: number; }`, + output: noFormat`type T = { x: number; }`, options: ['type'], errors: [ { @@ -138,8 +142,8 @@ export interface W { ], }, { - code: `interface T { x: number; }`, - output: `type T = { x: number; }`, + code: noFormat`interface T { x: number; }`, + output: noFormat`type T = { x: number; }`, options: ['type'], errors: [ { @@ -150,8 +154,8 @@ export interface W { ], }, { - code: `interface A extends B, C { x: number; };`, - output: `type A = { x: number; } & B & C;`, + code: noFormat`interface A extends B, C { x: number; };`, + output: noFormat`type A = { x: number; } & B & C;`, options: ['type'], errors: [ { @@ -162,8 +166,8 @@ export interface W { ], }, { - code: `interface A extends B, C { x: number; };`, - output: `type A = { x: number; } & B & C;`, + code: noFormat`interface A extends B, C { x: number; };`, + output: noFormat`type A = { x: number; } & B & C;`, options: ['type'], errors: [ { @@ -176,14 +180,14 @@ export interface W { { code: ` export interface W { - x: T, -}; -`, - output: ` + x: T; +} + `, + output: noFormat` export type W = { - x: T, -}; -`, + x: T; +} + `, options: ['type'], errors: [ { diff --git a/packages/eslint-plugin/tests/rules/default-param-last.test.ts b/packages/eslint-plugin/tests/rules/default-param-last.test.ts index d965df3c77fa..76e23bbe8a78 100644 --- a/packages/eslint-plugin/tests/rules/default-param-last.test.ts +++ b/packages/eslint-plugin/tests/rules/default-param-last.test.ts @@ -19,29 +19,29 @@ ruleTester.run('default-param-last', rule, { 'function foo(a: number, b?: number, c = 1) {}', 'function foo(a: number, b = 1, ...c) {}', - 'const foo = function () {}', - 'const foo = function (a: number) {}', - 'const foo = function (a = 1) {}', - 'const foo = function (a?: number) {}', - 'const foo = function (a: number, b: number) {}', - 'const foo = function (a: number, b: number, c?: number) {}', - 'const foo = function (a: number, b = 1) {}', - 'const foo = function (a: number, b = 1, c = 1) {}', - 'const foo = function (a: number, b = 1, c?: number) {}', - 'const foo = function (a: number, b?: number, c = 1) {}', - 'const foo = function (a: number, b = 1, ...c) {}', + 'const foo = function() {};', + 'const foo = function(a: number) {};', + 'const foo = function(a = 1) {};', + 'const foo = function(a?: number) {};', + 'const foo = function(a: number, b: number) {};', + 'const foo = function(a: number, b: number, c?: number) {};', + 'const foo = function(a: number, b = 1) {};', + 'const foo = function(a: number, b = 1, c = 1) {};', + 'const foo = function(a: number, b = 1, c?: number) {};', + 'const foo = function(a: number, b?: number, c = 1) {};', + 'const foo = function(a: number, b = 1, ...c) {};', - 'const foo = () => {}', - 'const foo = (a: number) => {}', - 'const foo = (a = 1) => {}', - 'const foo = (a?: number) => {}', - 'const foo = (a: number, b: number) => {}', - 'const foo = (a: number, b: number, c?: number) => {}', - 'const foo = (a: number, b = 1) => {}', - 'const foo = (a: number, b = 1, c = 1) => {}', - 'const foo = (a: number, b = 1, c?: number) => {}', - 'const foo = (a: number, b?: number, c = 1) => {}', - 'const foo = (a: number, b = 1, ...c) => {}', + 'const foo = () => {};', + 'const foo = (a: number) => {};', + 'const foo = (a = 1) => {};', + 'const foo = (a?: number) => {};', + 'const foo = (a: number, b: number) => {};', + 'const foo = (a: number, b: number, c?: number) => {};', + 'const foo = (a: number, b = 1) => {};', + 'const foo = (a: number, b = 1, c = 1) => {};', + 'const foo = (a: number, b = 1, c?: number) => {};', + 'const foo = (a: number, b?: number, c = 1) => {};', + 'const foo = (a: number, b = 1, ...c) => {};', ` class Foo { constructor(a: number, b: number, c: number) {} @@ -251,7 +251,7 @@ class Foo { ], }, { - code: 'const foo = function(a = 1, b: number) {}', + code: 'const foo = function(a = 1, b: number) {};', errors: [ { messageId: 'shouldBeLast', @@ -262,7 +262,7 @@ class Foo { ], }, { - code: 'const foo = function(a = 1, b = 2, c: number) {}', + code: 'const foo = function(a = 1, b = 2, c: number) {};', errors: [ { messageId: 'shouldBeLast', @@ -279,7 +279,7 @@ class Foo { ], }, { - code: 'const foo = function(a = 1, b: number, c = 2, d: number) {}', + code: 'const foo = function(a = 1, b: number, c = 2, d: number) {};', errors: [ { messageId: 'shouldBeLast', @@ -296,7 +296,7 @@ class Foo { ], }, { - code: 'const foo = function(a = 1, b: number, c = 2) {}', + code: 'const foo = function(a = 1, b: number, c = 2) {};', errors: [ { messageId: 'shouldBeLast', @@ -307,7 +307,7 @@ class Foo { ], }, { - code: 'const foo = function(a = 1, b: number, ...c) {}', + code: 'const foo = function(a = 1, b: number, ...c) {};', errors: [ { messageId: 'shouldBeLast', @@ -318,7 +318,7 @@ class Foo { ], }, { - code: 'const foo = function(a?: number, b: number) {}', + code: 'const foo = function(a?: number, b: number) {};', errors: [ { messageId: 'shouldBeLast', @@ -329,7 +329,7 @@ class Foo { ], }, { - code: 'const foo = function(a: number, b?: number, c: number) {}', + code: 'const foo = function(a: number, b?: number, c: number) {};', errors: [ { messageId: 'shouldBeLast', @@ -340,7 +340,7 @@ class Foo { ], }, { - code: 'const foo = function(a = 1, b?: number, c: number) {}', + code: 'const foo = function(a = 1, b?: number, c: number) {};', errors: [ { messageId: 'shouldBeLast', @@ -357,7 +357,7 @@ class Foo { ], }, { - code: 'const foo = function(a = 1, { b }) {}', + code: 'const foo = function(a = 1, { b }) {};', errors: [ { messageId: 'shouldBeLast', @@ -368,7 +368,7 @@ class Foo { ], }, { - code: 'const foo = function({ a } = {}, b) {}', + code: 'const foo = function({ a } = {}, b) {};', errors: [ { messageId: 'shouldBeLast', @@ -379,7 +379,7 @@ class Foo { ], }, { - code: 'const foo = function({ a, b } = { a: 1, b: 2 }, c) {}', + code: 'const foo = function({ a, b } = { a: 1, b: 2 }, c) {};', errors: [ { messageId: 'shouldBeLast', @@ -390,7 +390,7 @@ class Foo { ], }, { - code: 'const foo = function([a] = [], b) {}', + code: 'const foo = function([a] = [], b) {};', errors: [ { messageId: 'shouldBeLast', @@ -401,7 +401,7 @@ class Foo { ], }, { - code: 'const foo = function([a, b] = [1, 2], c) {}', + code: 'const foo = function([a, b] = [1, 2], c) {};', errors: [ { messageId: 'shouldBeLast', @@ -412,7 +412,7 @@ class Foo { ], }, { - code: 'const foo = (a = 1, b: number) => {}', + code: 'const foo = (a = 1, b: number) => {};', errors: [ { messageId: 'shouldBeLast', @@ -423,7 +423,7 @@ class Foo { ], }, { - code: 'const foo = (a = 1, b = 2, c: number) => {}', + code: 'const foo = (a = 1, b = 2, c: number) => {};', errors: [ { messageId: 'shouldBeLast', @@ -440,7 +440,7 @@ class Foo { ], }, { - code: 'const foo = (a = 1, b: number, c = 2, d: number) => {}', + code: 'const foo = (a = 1, b: number, c = 2, d: number) => {};', errors: [ { messageId: 'shouldBeLast', @@ -457,7 +457,7 @@ class Foo { ], }, { - code: 'const foo = (a = 1, b: number, c = 2) => {}', + code: 'const foo = (a = 1, b: number, c = 2) => {};', errors: [ { messageId: 'shouldBeLast', @@ -468,7 +468,7 @@ class Foo { ], }, { - code: 'const foo = (a = 1, b: number, ...c) => {}', + code: 'const foo = (a = 1, b: number, ...c) => {};', errors: [ { messageId: 'shouldBeLast', @@ -479,7 +479,7 @@ class Foo { ], }, { - code: 'const foo = (a?: number, b: number) => {}', + code: 'const foo = (a?: number, b: number) => {};', errors: [ { messageId: 'shouldBeLast', @@ -490,7 +490,7 @@ class Foo { ], }, { - code: 'const foo = (a: number, b?: number, c: number) => {}', + code: 'const foo = (a: number, b?: number, c: number) => {};', errors: [ { messageId: 'shouldBeLast', @@ -501,7 +501,7 @@ class Foo { ], }, { - code: 'const foo = (a = 1, b?: number, c: number) => {}', + code: 'const foo = (a = 1, b?: number, c: number) => {};', errors: [ { messageId: 'shouldBeLast', @@ -518,7 +518,7 @@ class Foo { ], }, { - code: 'const foo = (a = 1, { b }) => {}', + code: 'const foo = (a = 1, { b }) => {};', errors: [ { messageId: 'shouldBeLast', @@ -529,7 +529,7 @@ class Foo { ], }, { - code: 'const foo = ({ a } = {}, b) => {}', + code: 'const foo = ({ a } = {}, b) => {};', errors: [ { messageId: 'shouldBeLast', @@ -540,7 +540,7 @@ class Foo { ], }, { - code: 'const foo = ({ a, b } = { a: 1, b: 2 }, c) => {}', + code: 'const foo = ({ a, b } = { a: 1, b: 2 }, c) => {};', errors: [ { messageId: 'shouldBeLast', @@ -551,7 +551,7 @@ class Foo { ], }, { - code: 'const foo = ([a] = [], b) => {}', + code: 'const foo = ([a] = [], b) => {};', errors: [ { messageId: 'shouldBeLast', @@ -562,7 +562,7 @@ class Foo { ], }, { - code: 'const foo = ([a, b] = [1, 2], c) => {}', + code: 'const foo = ([a, b] = [1, 2], c) => {};', errors: [ { messageId: 'shouldBeLast', diff --git a/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts b/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts index fb353eec1a37..46ab49441858 100644 --- a/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts +++ b/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts @@ -11,23 +11,23 @@ ruleTester.run('explicit-function-return-type', rule, { filename: 'test.ts', code: ` function test(): void { - return; + return; } - `, + `, }, { filename: 'test.ts', code: ` var fn = function(): number { - return 1; + return 1; }; - `, + `, }, { filename: 'test.ts', code: ` var arrowFn = (): string => 'test'; - `, + `, }, { filename: 'test.ts', @@ -43,11 +43,11 @@ class Test { } arrow = (): string => 'arrow'; } - `, + `, }, { filename: 'test.ts', - code: `fn(() => {});`, + code: 'fn(() => {});', options: [ { allowExpressions: true, @@ -56,7 +56,7 @@ class Test { }, { filename: 'test.ts', - code: `fn(function() {});`, + code: 'fn(function() {});', options: [ { allowExpressions: true, @@ -65,7 +65,7 @@ class Test { }, { filename: 'test.ts', - code: `[function() {}, () => {}]`, + code: '[function() {}, () => {}];', options: [ { allowExpressions: true, @@ -74,7 +74,7 @@ class Test { }, { filename: 'test.ts', - code: `(function() {});`, + code: '(function() {});', options: [ { allowExpressions: true, @@ -83,7 +83,7 @@ class Test { }, { filename: 'test.ts', - code: `(() => {})();`, + code: '(() => {})();', options: [ { allowExpressions: true, @@ -92,7 +92,7 @@ class Test { }, { filename: 'test.ts', - code: `export default (): void => {}`, + code: 'export default (): void => {};', options: [ { allowExpressions: true, @@ -103,7 +103,7 @@ class Test { filename: 'test.ts', code: ` var arrowFn: Foo = () => 'test'; - `, + `, options: [ { allowTypedFunctionExpressions: true, @@ -113,8 +113,10 @@ var arrowFn: Foo = () => 'test'; { filename: 'test.ts', code: ` -var funcExpr: Foo = function() { return 'test'; }; - `, +var funcExpr: Foo = function() { + return 'test'; +}; + `, options: [ { allowTypedFunctionExpressions: true, @@ -123,12 +125,12 @@ var funcExpr: Foo = function() { return 'test'; }; }, { filename: 'test.ts', - code: `const x = (() => {}) as Foo`, + code: 'const x = (() => {}) as Foo;', options: [{ allowTypedFunctionExpressions: true }], }, { filename: 'test.ts', - code: `const x = (() => {})`, + code: 'const x = (() => {});', options: [{ allowTypedFunctionExpressions: true }], }, { @@ -136,7 +138,7 @@ var funcExpr: Foo = function() { return 'test'; }; code: ` const x = { foo: () => {}, -} as Foo +} as Foo; `, options: [{ allowTypedFunctionExpressions: true }], }, @@ -145,7 +147,7 @@ const x = { code: ` const x = { foo: () => {}, -} +}; `, options: [{ allowTypedFunctionExpressions: true }], }, @@ -154,7 +156,7 @@ const x = { code: ` const x: Foo = { foo: () => {}, -} +}; `, options: [{ allowTypedFunctionExpressions: true }], }, @@ -165,7 +167,7 @@ const x: Foo = { type MethodType = () => void; class App { - private method: MethodType = () => {} + private method: MethodType = () => {}; } `, options: [{ allowTypedFunctionExpressions: true }], @@ -185,42 +187,50 @@ const myObj = { filename: 'test.ts', code: ` () => (): void => {}; - `, + `, options: [{ allowHigherOrderFunctions: true }], }, { filename: 'test.ts', code: ` -() => function (): void {}; - `, +() => function(): void {}; + `, options: [{ allowHigherOrderFunctions: true }], }, { filename: 'test.ts', code: ` -() => { return (): void => {} }; - `, +() => { + return (): void => {}; +}; + `, options: [{ allowHigherOrderFunctions: true }], }, { filename: 'test.ts', code: ` -() => { return function (): void {} }; - `, +() => { + return function(): void {}; +}; + `, options: [{ allowHigherOrderFunctions: true }], }, { filename: 'test.ts', code: ` -function fn() { return (): void => {} }; - `, +function fn() { + return (): void => {}; +} + `, options: [{ allowHigherOrderFunctions: true }], }, { filename: 'test.ts', code: ` -function fn() { return function (): void {} }; - `, +function fn() { + return function(): void {}; +} + `, options: [{ allowHigherOrderFunctions: true }], }, { @@ -229,33 +239,39 @@ function fn() { return function (): void {} }; function FunctionDeclaration() { return function FunctionExpression_Within_FunctionDeclaration() { return function FunctionExpression_Within_FunctionExpression() { - return () => { // ArrowFunctionExpression_Within_FunctionExpression - return () => // ArrowFunctionExpression_Within_ArrowFunctionExpression - (): number => 1 // ArrowFunctionExpression_Within_ArrowFunctionExpression_WithNoBody - } - } - } + return () => { + // ArrowFunctionExpression_Within_FunctionExpression + return () => + // ArrowFunctionExpression_Within_ArrowFunctionExpression + (): number => 1; // ArrowFunctionExpression_Within_ArrowFunctionExpression_WithNoBody + }; + }; + }; } - `, + `, options: [{ allowHigherOrderFunctions: true }], }, { filename: 'test.ts', code: ` -() => () => { return (): void => { return; } }; - `, +() => () => { + return (): void => { + return; + }; +}; + `, options: [{ allowHigherOrderFunctions: true }], }, // https://github.com/typescript-eslint/typescript-eslint/issues/679 { filename: 'test.ts', code: ` -declare function foo(arg: () => void): void -foo(() => 1) -foo(() => {}) -foo(() => null) -foo(() => true) -foo(() => '') +declare function foo(arg: () => void): void; +foo(() => 1); +foo(() => {}); +foo(() => null); +foo(() => true); +foo(() => ''); `, options: [ { @@ -266,12 +282,12 @@ foo(() => '') { filename: 'test.ts', code: ` -declare function foo(arg: () => void): void -foo?.(() => 1) -foo?.bar(() => {}) -foo?.bar?.(() => null) -foo.bar?.(() => true) -foo?.(() => '') +declare function foo(arg: () => void): void; +foo?.(() => 1); +foo?.bar(() => {}); +foo?.bar?.(() => null); +foo.bar?.(() => true); +foo?.(() => ''); `, options: [ { @@ -301,22 +317,22 @@ new Accumulator().accumulate(() => 1); { filename: 'test.ts', code: ` -declare function foo(arg: { meth: () => number }): void +declare function foo(arg: { meth: () => number }): void; foo({ meth() { return 1; }, -}) +}); foo({ - meth: function () { + meth: function() { return 1; }, -}) +}); foo({ meth: () => { return 1; }, -}) +}); `, options: [ { @@ -327,9 +343,9 @@ foo({ { filename: 'test.ts', code: ` -const func = (value: number) => (({ type: "X", value }) as const); -const func = (value: number) => ({ type: "X", value } as const); -const func = (value: number) => (x as const); +const func = (value: number) => ({ type: 'X', value } as const); +const func = (value: number) => ({ type: 'X', value } as const); +const func = (value: number) => x as const; const func = (value: number) => x as const; `, options: [ @@ -355,10 +371,7 @@ new Foo(1, () => {}); { filename: 'test.ts', code: ` -function test( - a: number, - b: number, -) { +function test(a: number, b: number) { return; } `, @@ -366,9 +379,9 @@ function test( { messageId: 'missingReturnType', line: 2, - endLine: 5, + endLine: 2, column: 1, - endColumn: 2, + endColumn: 36, }, ], }, @@ -427,7 +440,7 @@ var arrowFn = () => 'test'; class Test { constructor() {} get prop() { - return 1; + return 1; } set prop() {} method() { @@ -532,7 +545,7 @@ function test() { }, { filename: 'test.ts', - code: 'export default function() {};', + code: 'export default function() {}', options: [{ allowExpressions: true }], errors: [ { @@ -549,11 +562,11 @@ function test() { code: ` class Foo { public a = () => {}; - public b = function () {}; + public b = function() {}; public c = function test() {}; static d = () => {}; - static e = function () {}; + static e = function() {}; } `, options: [{ allowExpressions: true }], @@ -570,7 +583,7 @@ class Foo { line: 4, endLine: 4, column: 14, - endColumn: 25, + endColumn: 24, }, { messageId: 'missingReturnType', @@ -591,7 +604,7 @@ class Foo { line: 8, endLine: 8, column: 14, - endColumn: 25, + endColumn: 24, }, ], }, @@ -611,13 +624,17 @@ class Foo { }, { filename: 'test.ts', - code: "var funcExpr = function() { return 'test'; };", + code: ` +var funcExpr = function() { + return 'test'; +}; + `, options: [{ allowTypedFunctionExpressions: true }], errors: [ { messageId: 'missingReturnType', - line: 1, - endLine: 1, + line: 2, + endLine: 2, column: 16, endColumn: 26, }, @@ -626,7 +643,7 @@ class Foo { { filename: 'test.ts', - code: 'const x = (() => {}) as Foo', + code: 'const x = (() => {}) as Foo;', options: [{ allowTypedFunctionExpressions: false }], errors: [ { @@ -644,7 +661,7 @@ class Foo { interface Foo {} const x = { foo: () => {}, -} as Foo +} as Foo; `, options: [{ allowTypedFunctionExpressions: false }], errors: [ @@ -663,7 +680,7 @@ const x = { interface Foo {} const x: Foo = { foo: () => {}, -} +}; `, options: [{ allowTypedFunctionExpressions: false }], errors: [ @@ -692,7 +709,7 @@ const x: Foo = { }, { filename: 'test.ts', - code: '() => function () {};', + code: '() => function() {};', options: [{ allowHigherOrderFunctions: true }], errors: [ { @@ -700,63 +717,79 @@ const x: Foo = { line: 1, endLine: 1, column: 7, - endColumn: 18, + endColumn: 17, }, ], }, { filename: 'test.ts', - code: '() => { return () => {} };', + code: ` +() => { + return () => {}; +}; + `, options: [{ allowHigherOrderFunctions: true }], errors: [ { messageId: 'missingReturnType', - line: 1, - endLine: 1, - column: 16, - endColumn: 21, + line: 3, + endLine: 3, + column: 10, + endColumn: 15, }, ], }, { filename: 'test.ts', - code: '() => { return function () {} };', + code: ` +() => { + return function() {}; +}; + `, options: [{ allowHigherOrderFunctions: true }], errors: [ { messageId: 'missingReturnType', - line: 1, - endLine: 1, - column: 16, - endColumn: 27, + line: 3, + endLine: 3, + column: 10, + endColumn: 20, }, ], }, { filename: 'test.ts', - code: 'function fn() { return () => {} };', + code: ` +function fn() { + return () => {}; +} + `, options: [{ allowHigherOrderFunctions: true }], errors: [ { messageId: 'missingReturnType', - line: 1, - endLine: 1, - column: 24, - endColumn: 29, + line: 3, + endLine: 3, + column: 10, + endColumn: 15, }, ], }, { filename: 'test.ts', - code: 'function fn() { return function () {} };', + code: ` +function fn() { + return function() {}; +} + `, options: [{ allowHigherOrderFunctions: true }], errors: [ { messageId: 'missingReturnType', - line: 1, - endLine: 1, - column: 24, - endColumn: 35, + line: 3, + endLine: 3, + column: 10, + endColumn: 20, }, ], }, @@ -766,20 +799,22 @@ const x: Foo = { function FunctionDeclaration() { return function FunctionExpression_Within_FunctionDeclaration() { return function FunctionExpression_Within_FunctionExpression() { - return () => { // ArrowFunctionExpression_Within_FunctionExpression - return () => // ArrowFunctionExpression_Within_ArrowFunctionExpression - () => 1 // ArrowFunctionExpression_Within_ArrowFunctionExpression_WithNoBody - } - } - } + return () => { + // ArrowFunctionExpression_Within_FunctionExpression + return () => + // ArrowFunctionExpression_Within_ArrowFunctionExpression + () => 1; // ArrowFunctionExpression_Within_ArrowFunctionExpression_WithNoBody + }; + }; + }; } - `, + `, options: [{ allowHigherOrderFunctions: true }], errors: [ { messageId: 'missingReturnType', - line: 7, - endLine: 7, + line: 9, + endLine: 9, column: 11, endColumn: 16, }, @@ -787,15 +822,21 @@ function FunctionDeclaration() { }, { filename: 'test.ts', - code: '() => () => { return () => { return; } };', + code: ` +() => () => { + return () => { + return; + }; +}; + `, options: [{ allowHigherOrderFunctions: true }], errors: [ { messageId: 'missingReturnType', - line: 1, - endLine: 1, - column: 22, - endColumn: 27, + line: 3, + endLine: 3, + column: 10, + endColumn: 15, }, ], }, @@ -803,12 +844,12 @@ function FunctionDeclaration() { { filename: 'test.ts', code: ` -declare function foo(arg: () => void): void -foo(() => 1) -foo(() => {}) -foo(() => null) -foo(() => true) -foo(() => '') +declare function foo(arg: () => void): void; +foo(() => 1); +foo(() => {}); +foo(() => null); +foo(() => true); +foo(() => ''); `, options: [ { @@ -883,7 +924,7 @@ new Accumulator().accumulate(() => 1); }, { filename: 'test.ts', - code: '(() => true)()', + code: '(() => true)();', options: [ { allowTypedFunctionExpressions: false, @@ -902,22 +943,22 @@ new Accumulator().accumulate(() => 1); { filename: 'test.ts', code: ` -declare function foo(arg: { meth: () => number }): void +declare function foo(arg: { meth: () => number }): void; foo({ meth() { return 1; }, -}) +}); foo({ - meth: function () { + meth: function() { return 1; }, -}) +}); foo({ meth: () => { return 1; }, -}) +}); `, options: [ { @@ -937,7 +978,7 @@ foo({ line: 9, endLine: 9, column: 9, - endColumn: 20, + endColumn: 19, }, { messageId: 'missingReturnType', @@ -951,8 +992,8 @@ foo({ { filename: 'test.ts', code: ` -const func = (value: number) => ({ type: "X", value } as any); -const func = (value: number) => ({ type: "X", value } as Action); +const func = (value: number) => ({ type: 'X', value } as any); +const func = (value: number) => ({ type: 'X', value } as Action); `, options: [ { @@ -979,7 +1020,7 @@ const func = (value: number) => ({ type: "X", value } as Action); { filename: 'test.ts', code: ` -const func = (value: number) => ({ type: "X", value } as const); +const func = (value: number) => ({ type: 'X', value } as const); `, options: [ { diff --git a/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts index fe0a09dd4c16..906f1b6cc600 100644 --- a/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts +++ b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/explicit-member-accessibility'; -import { RuleTester } from '../RuleTester'; +import { RuleTester, noFormat } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', @@ -109,72 +109,72 @@ class Test { filename: 'test.ts', code: ` class Test { - protected name: string - private x: number - public getX () { - return this.x + protected name: string; + private x: number; + public getX() { + return this.x; } } - `, + `, }, { filename: 'test.ts', code: ` class Test { - protected name: string - protected foo?: string - public "foo-bar"?: string + protected name: string; + protected foo?: string; + public 'foo-bar'?: string; } - `, + `, }, { filename: 'test.ts', code: ` class Test { - public constructor({x, y}: {x: number; y: number;}) {} + public constructor({ x, y }: { x: number; y: number }) {} } - `, + `, }, { filename: 'test.ts', code: ` class Test { - protected name: string - protected foo?: string - public getX () { - return this.x + protected name: string; + protected foo?: string; + public getX() { + return this.x; } } - `, + `, options: [{ accessibility: 'explicit' }], }, { filename: 'test.ts', code: ` class Test { - protected name: string - protected foo?: string - getX () { - return this.x + protected name: string; + protected foo?: string; + getX() { + return this.x; } } - `, + `, options: [{ accessibility: 'no-public' }], }, { filename: 'test.ts', code: ` class Test { - name: string - foo?: string - getX () { - return this.x + name: string; + foo?: string; + getX() { + return this.x; } get fooName(): string { - return this.foo + ' ' + this.name + return this.foo + ' ' + this.name; } } - `, + `, options: [{ accessibility: 'no-public' }], }, { @@ -182,7 +182,7 @@ class Test { code: ` class Test { private x: number; - constructor (x: number) { + constructor(x: number) { this.x = x; } get internalValue() { @@ -191,7 +191,7 @@ class Test { private set internalValue(value: number) { this.x = value; } - public square (): number { + public square(): number { return this.x * this.x; } } @@ -203,7 +203,7 @@ class Test { code: ` class Test { private x: number; - public constructor (x: number) { + public constructor(x: number) { this.x = x; } public get internalValue() { @@ -212,10 +212,10 @@ class Test { public set internalValue(value: number) { this.x = value; } - public square (): number { + public square(): number { return this.x * this.x; } - half (): number { + half(): number { return this.x / 2; } } @@ -226,7 +226,7 @@ class Test { filename: 'test.ts', code: ` class Test { - constructor(private x: number){} + constructor(private x: number) {} } `, options: [{ accessibility: 'no-public' }], @@ -235,7 +235,7 @@ class Test { filename: 'test.ts', code: ` class Test { - constructor(public x: number){} + constructor(public x: number) {} } `, options: [ @@ -249,7 +249,7 @@ class Test { filename: 'test.ts', code: ` class Test { - constructor(public foo: number){} + constructor(public foo: number) {} } `, options: [{ accessibility: 'no-public' }], @@ -258,8 +258,8 @@ class Test { filename: 'test.ts', code: ` class Test { - public getX () { - return this.x + public getX() { + return this.x; } } `, @@ -269,8 +269,8 @@ class Test { filename: 'test.ts', code: ` class Test { - public static getX () { - return this.x + public static getX() { + return this.x; } } `, @@ -280,8 +280,8 @@ class Test { filename: 'test.ts', code: ` class Test { - get getX () { - return this.x + get getX() { + return this.x; } } `, @@ -291,8 +291,8 @@ class Test { filename: 'test.ts', code: ` class Test { - getX () { - return this.x + getX() { + return this.x; } } `, @@ -300,24 +300,38 @@ class Test { }, { filename: 'test.ts', - code: 'class Test { x = 2 }', + code: ` +class Test { + x = 2; +} + `, options: [{ overrides: { properties: 'off' } }], }, { filename: 'test.ts', - code: 'class Test { private x = 2 }', + code: ` +class Test { + private x = 2; +} + `, options: [{ overrides: { properties: 'explicit' } }], }, { filename: 'test.ts', - code: `class Test { - x = 2 - private x = 2 - }`, + code: ` +class Test { + x = 2; + private x = 2; +} + `, options: [{ overrides: { properties: 'no-public' } }], }, { - code: 'class Test { constructor(private { x }: any[]) { }}', + code: ` +class Test { + constructor(private { x }: any[]) {} +} + `, options: [{ accessibility: 'no-public' }], }, ], @@ -412,12 +426,12 @@ class Test { filename: 'test.ts', code: ` class Test { - x: number - public getX () { - return this.x + x: number; + public getX() { + return this.x; } } - `, + `, errors: [ { messageId: 'missingAccessibility', @@ -431,23 +445,23 @@ class Test { ], output: ` class Test { - x: number - public getX () { - return this.x + x: number; + public getX() { + return this.x; } } - `, + `, }, { filename: 'test.ts', code: ` class Test { - private x: number - getX () { - return this.x + private x: number; + getX() { + return this.x; } } - `, + `, errors: [ { messageId: 'missingAccessibility', @@ -461,23 +475,23 @@ class Test { ], output: ` class Test { - private x: number - getX () { - return this.x + private x: number; + getX() { + return this.x; } } - `, + `, }, { filename: 'test.ts', code: ` class Test { - x?: number - getX? () { - return this.x + x?: number; + getX?() { + return this.x; } } - `, + `, errors: [ { messageId: 'missingAccessibility', @@ -500,24 +514,24 @@ class Test { ], output: ` class Test { - x?: number - getX? () { - return this.x + x?: number; + getX?() { + return this.x; } } - `, + `, }, { filename: 'test.ts', code: ` class Test { - protected name: string - protected foo?: string - public getX () { - return this.x + protected name: string; + protected foo?: string; + public getX() { + return this.x; } } - `, + `, options: [{ accessibility: 'no-public' }], errors: [ { @@ -532,25 +546,25 @@ class Test { ], output: ` class Test { - protected name: string - protected foo?: string - getX () { - return this.x + protected name: string; + protected foo?: string; + getX() { + return this.x; } } - `, + `, }, { filename: 'test.ts', code: ` class Test { - protected name: string - public foo?: string - getX () { - return this.x + protected name: string; + public foo?: string; + getX() { + return this.x; } } - `, + `, options: [{ accessibility: 'no-public' }], errors: [ { @@ -565,24 +579,24 @@ class Test { ], output: ` class Test { - protected name: string - foo?: string - getX () { - return this.x + protected name: string; + foo?: string; + getX() { + return this.x; } } - `, + `, }, { filename: 'test.ts', code: ` class Test { - public x: number - public getX () { - return this.x + public x: number; + public getX() { + return this.x; } } - `, + `, errors: [ { messageId: 'unwantedPublicAccessibility', @@ -598,19 +612,19 @@ class Test { options: [{ accessibility: 'no-public' }], output: ` class Test { - x: number - getX () { - return this.x + x: number; + getX() { + return this.x; } } - `, + `, }, { filename: 'test.ts', code: ` class Test { private x: number; - constructor (x: number) { + constructor(x: number) { this.x = x; } get internalValue() { @@ -637,7 +651,7 @@ class Test { output: ` class Test { private x: number; - constructor (x: number) { + constructor(x: number) { this.x = x; } get internalValue() { @@ -654,7 +668,7 @@ class Test { code: ` class Test { private x: number; - constructor (x: number) { + constructor(x: number) { this.x = x; } get internalValue() { @@ -685,7 +699,7 @@ class Test { output: ` class Test { private x: number; - constructor (x: number) { + constructor(x: number) { this.x = x; } get internalValue() { @@ -701,7 +715,7 @@ class Test { filename: 'test.ts', code: ` class Test { - constructor(public x: number){} + constructor(public x: number) {} public foo(): string { return 'foo'; } @@ -721,7 +735,7 @@ class Test { ], output: ` class Test { - constructor(public x: number){} + constructor(public x: number) {} public foo(): string { return 'foo'; } @@ -732,7 +746,7 @@ class Test { filename: 'test.ts', code: ` class Test { - constructor(public x: number){} + constructor(public x: number) {} } `, errors: [ @@ -744,7 +758,7 @@ class Test { ], output: ` class Test { - constructor(public x: number){} + constructor(public x: number) {} } `, }, @@ -752,7 +766,7 @@ class Test { filename: 'test.ts', code: ` class Test { - constructor(public readonly x: number){} + constructor(public readonly x: number) {} } `, options: [ @@ -770,13 +784,17 @@ class Test { ], output: ` class Test { - constructor(readonly x: number){} + constructor(readonly x: number) {} } `, }, { filename: 'test.ts', - code: 'class Test { x = 2 }', + code: ` +class Test { + x = 2; +} + `, options: [ { accessibility: 'off', @@ -786,18 +804,24 @@ class Test { errors: [ { messageId: 'missingAccessibility', - line: 1, - column: 14, + line: 3, + column: 3, }, ], - output: 'class Test { x = 2 }', + output: ` +class Test { + x = 2; +} + `, }, { filename: 'test.ts', - code: `class Test { - public x = 2 - private x = 2 - }`, + code: ` +class Test { + public x = 2; + private x = 2; +} + `, options: [ { accessibility: 'off', @@ -807,30 +831,40 @@ class Test { errors: [ { messageId: 'unwantedPublicAccessibility', - line: 2, - column: 9, + line: 3, + column: 3, }, ], - output: `class Test { - x = 2 - private x = 2 - }`, + output: ` +class Test { + x = 2; + private x = 2; +} + `, }, { - code: 'class Test { constructor(public ...x: any[]) { }}', + code: ` +class Test { + constructor(public ...x: any[]) {} +} + `, options: [{ accessibility: 'explicit' }], errors: [ { messageId: 'missingAccessibility', - line: 1, - column: 14, + line: 3, + column: 3, }, ], - output: 'class Test { constructor(public ...x: any[]) { }}', + output: ` +class Test { + constructor(public ...x: any[]) {} +} + `, }, { filename: 'test.ts', - code: ` + code: noFormat` class Test { @public public /*public*/constructor(private foo: string) {} @@ -848,7 +882,7 @@ class Test { column: 3, }, ], - output: ` + output: noFormat` class Test { @public /*public*/constructor(private foo: string) {} @@ -914,7 +948,7 @@ class Test { filename: 'test.ts', code: ` class Test { - public foo = ""; + public foo = ''; } `, options: [ @@ -931,16 +965,16 @@ class Test { ], output: ` class Test { - foo = ""; + foo = ''; } `, }, { filename: 'test.ts', - code: ` + code: noFormat` class Test { - contructor(public/* Hi there */ readonly foo) + contructor(public/* Hi there */ readonly foo); } `, options: [ @@ -958,7 +992,7 @@ class Test { ], output: ` class Test { - contructor(/* Hi there */ readonly foo) + contructor(/* Hi there */ readonly foo); } `, }, @@ -966,7 +1000,7 @@ class Test { filename: 'test.ts', code: ` class Test { - contructor(public readonly foo: string) + contructor(public readonly foo: string); } `, options: [ @@ -983,33 +1017,17 @@ class Test { ], output: ` class Test { - contructor(readonly foo: string) + contructor(readonly foo: string); } `, }, { filename: 'test.ts', - code: - 'class EnsureWhiteSPaceSpan { public constructor() {}}', - options: [ - { - accessibility: 'no-public', - overrides: { parameterProperties: 'no-public' }, - }, - ], - errors: [ - { - messageId: 'unwantedPublicAccessibility', - line: 1, - column: 30, - }, - ], - output: 'class EnsureWhiteSPaceSpan { constructor() {}}', - }, - { - filename: 'test.ts', - code: - 'class EnsureWhiteSPaceSpan { public /* */ constructor() {}}', + code: ` +class EnsureWhiteSPaceSpan { + public constructor() {} +} + `, options: [ { accessibility: 'no-public', @@ -1019,17 +1037,23 @@ class Test { errors: [ { messageId: 'unwantedPublicAccessibility', - line: 1, - column: 30, + line: 3, + column: 3, }, ], - output: - 'class EnsureWhiteSPaceSpan { /* */ constructor() {}}', + output: ` +class EnsureWhiteSPaceSpan { + constructor() {} +} + `, }, { filename: 'test.ts', - code: - 'class EnsureWhiteSPaceSpan { public /* */ constructor() {}}', + code: ` +class EnsureWhiteSPaceSpan { + public /* */ constructor() {} +} + `, options: [ { accessibility: 'no-public', @@ -1039,11 +1063,15 @@ class Test { errors: [ { messageId: 'unwantedPublicAccessibility', - line: 1, - column: 30, + line: 3, + column: 3, }, ], - output: 'class EnsureWhiteSPaceSpan { /* */ constructor() {}}', + output: ` +class EnsureWhiteSPaceSpan { + /* */ constructor() {} +} + `, }, ], }); diff --git a/packages/eslint-plugin/tests/rules/explicit-module-boundary-types.test.ts b/packages/eslint-plugin/tests/rules/explicit-module-boundary-types.test.ts index 388adb994315..cdff53533b73 100644 --- a/packages/eslint-plugin/tests/rules/explicit-module-boundary-types.test.ts +++ b/packages/eslint-plugin/tests/rules/explicit-module-boundary-types.test.ts @@ -10,28 +10,28 @@ ruleTester.run('explicit-module-boundary-types', rule, { { code: ` function test(): void { - return; + return; } - `, + `, }, { code: ` export function test(): void { - return; + return; } - `, + `, }, { code: ` export var fn = function(): number { - return 1; + return 1; }; - `, + `, }, { code: ` export var arrowFn = (): string => 'test'; - `, + `, }, { code: ` @@ -46,7 +46,7 @@ class Test { } arrow = (): string => 'arrow'; } - `, + `, }, { code: ` @@ -61,42 +61,42 @@ export class Test { } arrow = (): string => 'arrow'; } - `, + `, }, { code: ` export function test(): void { - nested(); - return; + nested(); + return; - function nested() {} + function nested() {} } - `, + `, }, { code: ` export function test(): string { - const nested = () => 'value'; - return nested(); + const nested = () => 'value'; + return nested(); } - `, + `, }, { code: ` export function test(): string { - class Nested { - public method() { - return 'value'; - } + class Nested { + public method() { + return 'value'; } - return new Nested().method(); + } + return new Nested().method(); } - `, + `, }, { code: ` export var arrowFn: Foo = () => 'test'; - `, + `, options: [ { allowTypedFunctionExpressions: true, @@ -105,8 +105,10 @@ export var arrowFn: Foo = () => 'test'; }, { code: ` -export var funcExpr: Foo = function() { return 'test'; }; - `, +export var funcExpr: Foo = function() { + return 'test'; +}; + `, options: [ { allowTypedFunctionExpressions: true, @@ -114,18 +116,18 @@ export var funcExpr: Foo = function() { return 'test'; }; ], }, { - code: `const x = (() => {}) as Foo`, + code: 'const x = (() => {}) as Foo;', options: [{ allowTypedFunctionExpressions: true }], }, { - code: `const x = (() => {})`, + code: 'const x = (() => {});', options: [{ allowTypedFunctionExpressions: true }], }, { code: ` export const x = { foo: () => {}, -} as Foo +} as Foo; `, options: [{ allowTypedFunctionExpressions: true }], }, @@ -133,7 +135,7 @@ export const x = { code: ` export const x = { foo: () => {}, -} +}; `, options: [{ allowTypedFunctionExpressions: true }], }, @@ -141,7 +143,7 @@ export const x = { code: ` export const x: Foo = { foo: () => {}, -} +}; `, options: [{ allowTypedFunctionExpressions: true }], }, @@ -151,7 +153,7 @@ export const x: Foo = { type MethodType = () => void; export class App { - public method: MethodType = () => {} + public method: MethodType = () => {}; } `, options: [{ allowTypedFunctionExpressions: true }], @@ -169,37 +171,45 @@ export const myObj = { { code: ` export default () => (): void => {}; - `, + `, options: [{ allowHigherOrderFunctions: true }], }, { code: ` -export default () => function (): void {}; - `, +export default () => function(): void {}; + `, options: [{ allowHigherOrderFunctions: true }], }, { code: ` -export default () => { return (): void => {} }; - `, +export default () => { + return (): void => {}; +}; + `, options: [{ allowHigherOrderFunctions: true }], }, { code: ` -export default () => { return function (): void {} }; - `, +export default () => { + return function(): void {}; +}; + `, options: [{ allowHigherOrderFunctions: true }], }, { code: ` -export function fn() { return (): void => {} }; - `, +export function fn() { + return (): void => {}; +} + `, options: [{ allowHigherOrderFunctions: true }], }, { code: ` -export function fn() { return function (): void {} }; - `, +export function fn() { + return function(): void {}; +} + `, options: [{ allowHigherOrderFunctions: true }], }, { @@ -207,20 +217,26 @@ export function fn() { return function (): void {} }; export function FunctionDeclaration() { return function FunctionExpression_Within_FunctionDeclaration() { return function FunctionExpression_Within_FunctionExpression() { - return () => { // ArrowFunctionExpression_Within_FunctionExpression - return () => // ArrowFunctionExpression_Within_ArrowFunctionExpression - (): number => 1 // ArrowFunctionExpression_Within_ArrowFunctionExpression_WithNoBody - } - } - } + return () => { + // ArrowFunctionExpression_Within_FunctionExpression + return () => + // ArrowFunctionExpression_Within_ArrowFunctionExpression + (): number => 1; // ArrowFunctionExpression_Within_ArrowFunctionExpression_WithNoBody + }; + }; + }; } - `, + `, options: [{ allowHigherOrderFunctions: true }], }, { code: ` -export default () => () => { return (): void => { return; } }; - `, +export default () => () => { + return (): void => { + return; + }; +}; + `, options: [{ allowHigherOrderFunctions: true }], }, { @@ -243,9 +259,9 @@ new Accumulator().accumulate(() => 1); }, { code: ` -export const func1 = (value: number) => (({ type: "X", value }) as const); -export const func2 = (value: number) => ({ type: "X", value } as const); -export const func3 = (value: number) => (x as const); +export const func1 = (value: number) => ({ type: 'X', value } as const); +export const func2 = (value: number) => ({ type: 'X', value } as const); +export const func3 = (value: number) => x as const; export const func4 = (value: number) => x as const; `, options: [ @@ -257,7 +273,7 @@ export const func4 = (value: number) => x as const; { code: ` export const func1 = (value: string) => value; -export const func2 = (value: number) => ({ type: "X", value }); +export const func2 = (value: number) => ({ type: 'X', value }); `, options: [ { @@ -315,13 +331,8 @@ export class Test { { code: ` export const Foo: FC = () => ( -
{}} - b={function (e) {}} - c={function foo(e) {}} - > -
-) +
{}} b={function(e) {}} c={function foo(e) {}}>
+); `, parserOptions: { ecmaFeatures: { jsx: true }, @@ -329,13 +340,9 @@ export const Foo: FC = () => ( }, { code: ` -export const Foo: JSX.Element = -
{}} - b={function (e) {}} - c={function foo(e) {}} - > -
+export const Foo: JSX.Element = ( +
{}} b={function(e) {}} c={function foo(e) {}}>
+); `, parserOptions: { ecmaFeatures: { jsx: true }, @@ -345,10 +352,7 @@ export const Foo: JSX.Element = invalid: [ { code: ` -export function test( - a: number, - b: number, -) { +export function test(a: number, b: number) { return; } `, @@ -356,9 +360,9 @@ export function test( { messageId: 'missingReturnType', line: 2, - endLine: 5, + endLine: 2, column: 8, - endColumn: 2, + endColumn: 43, }, ], }, @@ -413,13 +417,13 @@ export var arrowFn = () => 'test'; export class Test { constructor() {} get prop() { - return 1; + return 1; } set prop(value) {} method() { return; } - arrow = (arg) => 'arrow'; + arrow = arg => 'arrow'; private method() { return; } @@ -452,14 +456,14 @@ export class Test { line: 11, endLine: 11, column: 11, - endColumn: 19, + endColumn: 17, }, { messageId: 'missingArgType', line: 11, endLine: 11, column: 11, - endColumn: 27, + endColumn: 25, }, ], }, @@ -467,11 +471,11 @@ export class Test { code: ` export class Foo { public a = () => {}; - public b = function () {}; + public b = function() {}; public c = function test() {}; static d = () => {}; - static e = function () {}; + static e = function() {}; } `, errors: [ @@ -487,7 +491,7 @@ export class Foo { line: 4, endLine: 4, column: 14, - endColumn: 25, + endColumn: 24, }, { messageId: 'missingReturnType', @@ -508,12 +512,12 @@ export class Foo { line: 8, endLine: 8, column: 14, - endColumn: 25, + endColumn: 24, }, ], }, { - code: 'export default () => true ? (() => {}) : ((): void => {});', + code: 'export default () => (true ? () => {} : (): void => {});', errors: [ { messageId: 'missingReturnType', @@ -545,20 +549,24 @@ export class Foo { ], }, { - code: "export var funcExpr = function() { return 'test'; };", + code: ` +export var funcExpr = function() { + return 'test'; +}; + `, options: [{ allowTypedFunctionExpressions: true }], errors: [ { messageId: 'missingReturnType', - line: 1, - endLine: 1, + line: 2, + endLine: 2, column: 23, endColumn: 33, }, ], }, { - code: 'export const x = (() => {}) as Foo', + code: 'export const x = (() => {}) as Foo;', options: [{ allowTypedFunctionExpressions: false }], errors: [ { @@ -575,7 +583,7 @@ export class Foo { interface Foo {} export const x = { foo: () => {}, -} as Foo +} as Foo; `, options: [{ allowTypedFunctionExpressions: false }], errors: [ @@ -593,7 +601,7 @@ export const x = { interface Foo {} export const x: Foo = { foo: () => {}, -} +}; `, options: [{ allowTypedFunctionExpressions: false }], errors: [ @@ -620,7 +628,7 @@ export const x: Foo = { ], }, { - code: 'export default () => function () {};', + code: 'export default () => function() {};', options: [{ allowHigherOrderFunctions: true }], errors: [ { @@ -628,59 +636,75 @@ export const x: Foo = { line: 1, endLine: 1, column: 22, - endColumn: 33, + endColumn: 32, }, ], }, { - code: 'export default () => { return () => {} };', + code: ` +export default () => { + return () => {}; +}; + `, options: [{ allowHigherOrderFunctions: true }], errors: [ { messageId: 'missingReturnType', - line: 1, - endLine: 1, - column: 31, - endColumn: 36, + line: 3, + endLine: 3, + column: 10, + endColumn: 15, }, ], }, { - code: 'export default () => { return function () {} };', + code: ` +export default () => { + return function() {}; +}; + `, options: [{ allowHigherOrderFunctions: true }], errors: [ { messageId: 'missingReturnType', - line: 1, - endLine: 1, - column: 31, - endColumn: 42, + line: 3, + endLine: 3, + column: 10, + endColumn: 20, }, ], }, { - code: 'export function fn() { return () => {} };', + code: ` +export function fn() { + return () => {}; +} + `, options: [{ allowHigherOrderFunctions: true }], errors: [ { messageId: 'missingReturnType', - line: 1, - endLine: 1, - column: 31, - endColumn: 36, + line: 3, + endLine: 3, + column: 10, + endColumn: 15, }, ], }, { - code: 'export function fn() { return function () {} };', + code: ` +export function fn() { + return function() {}; +} + `, options: [{ allowHigherOrderFunctions: true }], errors: [ { messageId: 'missingReturnType', - line: 1, - endLine: 1, - column: 31, - endColumn: 42, + line: 3, + endLine: 3, + column: 10, + endColumn: 20, }, ], }, @@ -689,40 +713,48 @@ export const x: Foo = { export function FunctionDeclaration() { return function FunctionExpression_Within_FunctionDeclaration() { return function FunctionExpression_Within_FunctionExpression() { - return () => { // ArrowFunctionExpression_Within_FunctionExpression - return () => // ArrowFunctionExpression_Within_ArrowFunctionExpression - () => 1 // ArrowFunctionExpression_Within_ArrowFunctionExpression_WithNoBody - } - } - } + return () => { + // ArrowFunctionExpression_Within_FunctionExpression + return () => + // ArrowFunctionExpression_Within_ArrowFunctionExpression + () => 1; // ArrowFunctionExpression_Within_ArrowFunctionExpression_WithNoBody + }; + }; + }; } - `, + `, options: [{ allowHigherOrderFunctions: true }], errors: [ { messageId: 'missingReturnType', - line: 7, - endLine: 7, + line: 9, + endLine: 9, column: 11, endColumn: 16, }, ], }, { - code: 'export default () => () => { return () => { return; } };', + code: ` +export default () => () => { + return () => { + return; + }; +}; + `, options: [{ allowHigherOrderFunctions: true }], errors: [ { messageId: 'missingReturnType', - line: 1, - endLine: 1, - column: 37, - endColumn: 42, + line: 3, + endLine: 3, + column: 10, + endColumn: 15, }, ], }, { - code: 'export default (() => true)()', + code: 'export default (() => true)();', options: [ { allowTypedFunctionExpressions: false, @@ -740,8 +772,8 @@ export function FunctionDeclaration() { }, { code: ` -export const func1 = (value: number) => ({ type: "X", value } as any); -export const func2 = (value: number) => ({ type: "X", value } as Action); +export const func1 = (value: number) => ({ type: 'X', value } as any); +export const func2 = (value: number) => ({ type: 'X', value } as Action); `, options: [ { @@ -767,7 +799,7 @@ export const func2 = (value: number) => ({ type: "X", value } as Action); }, { code: ` -export const func = (value: number) => ({ type: "X", value } as const); +export const func = (value: number) => ({ type: 'X', value } as const); `, options: [ { @@ -834,19 +866,23 @@ export const func2 = (value: number) => value; ], }, { - code: 'export function fn(test): string { return "123" };', + code: ` +export function fn(test): string { + return '123'; +} + `, errors: [ { messageId: 'missingArgType', - line: 1, - endLine: 1, + line: 2, + endLine: 4, column: 8, - endColumn: 50, + endColumn: 2, }, ], }, { - code: 'export const fn = (one: number, two): string => "123";', + code: "export const fn = (one: number, two): string => '123';", errors: [ { messageId: 'missingArgType', diff --git a/packages/eslint-plugin/tests/rules/func-call-spacing.test.ts b/packages/eslint-plugin/tests/rules/func-call-spacing.test.ts index e2250716a075..db884fd3cf12 100644 --- a/packages/eslint-plugin/tests/rules/func-call-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/func-call-spacing.test.ts @@ -1,3 +1,8 @@ +/* eslint-disable eslint-comments/no-use */ +// this rule tests the spacing, 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 { TSESLint } from '@typescript-eslint/experimental-utils'; import rule, { MessageIds, Options } from '../../src/rules/func-call-spacing'; import { RuleTester } from '../RuleTester'; @@ -180,7 +185,7 @@ ruleTester.run('func-call-spacing', rule, { this.cancelled.add(request) this.decrement(request) (request.reject(new api.Cancel())) - `, + `, output: null, // no change errors: [ { @@ -208,7 +213,7 @@ var a = foo code: ` var a = foo (baz()) - `, + `, output: null, // no change errors: [ { diff --git a/packages/eslint-plugin/tests/rules/generic-type-naming.test.ts b/packages/eslint-plugin/tests/rules/generic-type-naming.test.ts index 11f7d1618bb2..da26e9675b64 100644 --- a/packages/eslint-plugin/tests/rules/generic-type-naming.test.ts +++ b/packages/eslint-plugin/tests/rules/generic-type-naming.test.ts @@ -7,35 +7,60 @@ const ruleTester = new RuleTester({ ruleTester.run('generic-type-naming', rule, { valid: [ - { code: 'class { }', options: [] }, - { code: 'type ReadOnly = {}', options: [] }, - { code: 'interface SimpleMap { }', options: [] }, - { code: 'function get() {}', options: [] }, - { code: 'interface GenericIdentityFn { (arg: T): T }', options: [] }, - { code: 'class { }', options: ['^x+$'] }, - { code: 'class { }', options: ['^[A-Z]$'] }, - { - code: 'class extends B implements Foo { }', + { + code: 'class {}', + options: [], + }, + { + code: 'type ReadOnly = {};', + options: [], + }, + { + code: 'interface SimpleMap {}', + options: [], + }, + { + code: 'function get() {}', + options: [], + }, + { + code: ` +interface GenericIdentityFn { + (arg: T): T; +} + `, + options: [], + }, + { + code: 'class {}', + options: ['^x+$'], + }, + { + code: 'class {}', + options: ['^[A-Z]$'], + }, + { + code: 'class extends B implements Foo {}', options: ['^[A-Z]$'], }, { code: ` class extends B implements Foo { - test () { - type Foo = Bar - } + test() { + type Foo = Bar; + } } - `, + `, options: ['^[A-Z]$'], }, { - code: 'class CounterContainer extends Container { }', + code: 'class CounterContainer extends Container {}', options: ['^T$'], }, ], invalid: [ { - code: 'class { }', + code: 'class {}', options: [], errors: [ { @@ -49,7 +74,7 @@ class extends B implements Foo { ], }, { - code: 'class { }', + code: 'class {}', options: ['^[A-Z]+$'], errors: [ { @@ -61,7 +86,7 @@ class extends B implements Foo { ], }, { - code: 'interface SimpleMap { }', + code: 'interface SimpleMap {}', options: ['^[A-Z]+$'], errors: [ { @@ -73,7 +98,7 @@ class extends B implements Foo { ], }, { - code: 'type R = {}', + code: 'type R = {};', options: ['^[A-Z]+$'], errors: [ { @@ -97,25 +122,29 @@ class extends B implements Foo { ], }, { - code: 'interface GenericIdentityFn { (arg: x): x }', + code: ` +interface GenericIdentityFn { + (arg: x): x; +} + `, options: ['^[A-Z]+$'], errors: [ { messageId: 'paramNotMatchRule', data: { name: 'x', rule: '^[A-Z]+$' }, - line: 1, - column: 32, + line: 3, + column: 4, }, ], }, { code: ` class extends B implements Foo { - test () { - type Foo = Bar - } + test() { + type Foo = Bar; + } } - `, + `, options: ['^[A-Z][0-9]$'], errors: [ { @@ -128,24 +157,24 @@ class extends B implements Foo { messageId: 'paramNotMatchRule', data: { name: 'Z', rule: '^[A-Z][0-9]$' }, line: 3, - column: 10, + column: 8, }, { messageId: 'paramNotMatchRule', data: { name: 'T', rule: '^[A-Z][0-9]$' }, line: 4, - column: 18, + column: 14, }, ], }, { code: ` abstract class extends B implements Foo { - test () { - type Foo = Bar - } + test() { + type Foo = Bar; + } } - `, + `, options: ['^[A-Z][0-9]$'], errors: [ { @@ -164,13 +193,13 @@ abstract class extends B implements Foo { messageId: 'paramNotMatchRule', data: { name: 'Z', rule: '^[A-Z][0-9]$' }, line: 3, - column: 10, + column: 8, }, { messageId: 'paramNotMatchRule', data: { name: 'T', rule: '^[A-Z][0-9]$' }, line: 4, - column: 18, + column: 14, }, ], }, diff --git a/packages/eslint-plugin/tests/rules/indent/indent-eslint.test.ts b/packages/eslint-plugin/tests/rules/indent/indent-eslint.test.ts index d726a5e2c95f..a9dfda6b127b 100644 --- a/packages/eslint-plugin/tests/rules/indent/indent-eslint.test.ts +++ b/packages/eslint-plugin/tests/rules/indent/indent-eslint.test.ts @@ -4,6 +4,11 @@ // NOTE - this test suite is intentionally kept in a separate file to our // custom tests. This is to keep a clear boundary between the two. +/* eslint-disable eslint-comments/no-use */ +// this rule tests the spacing, 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 { AST_TOKEN_TYPES, AST_NODE_TYPES, diff --git a/packages/eslint-plugin/tests/rules/indent/indent.test.ts b/packages/eslint-plugin/tests/rules/indent/indent.test.ts index fe88d3de17a0..6cec699c053e 100644 --- a/packages/eslint-plugin/tests/rules/indent/indent.test.ts +++ b/packages/eslint-plugin/tests/rules/indent/indent.test.ts @@ -1,3 +1,8 @@ +/* eslint-disable eslint-comments/no-use */ +// this rule tests the spacing, 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 { AST_NODE_TYPES, TSESLint, @@ -704,7 +709,7 @@ export default class App extends Vue return this.$store.state.errorHandler.error } } - `, + `, // https://github.com/eslint/typescript-eslint-parser/issues/474 ` /** @@ -713,7 +718,7 @@ export default class App extends Vue * @returns {string} */ function foo(name: string, age: number): string {} - `, + `, ` const firebaseApp = firebase.apps.length ? firebase.app() @@ -725,7 +730,7 @@ const firebaseApp = firebase.apps.length storageBucket: __FIREBASE_STORAGE_BUCKET__, messagingSenderId: __FIREBASE_MESSAGING_SENDER_ID__, }) - `, + `, // https://github.com/bradzacher/eslint-plugin-typescript/issues/271 { code: ` @@ -734,7 +739,7 @@ const foo = { b: 2 }, bar = 1; - `, + `, options: [4, { VariableDeclarator: { const: 3 } }], }, { @@ -744,7 +749,7 @@ const foo : Foo = { b: 2 }, bar = 1; - `, + `, options: [4, { VariableDeclarator: { const: 3 } }], }, { @@ -756,7 +761,7 @@ const name: string = ' Typescript ' greeting: string = (" Hello " + name) .toUpperCase() .trim(); - `, + `, options: [2, { VariableDeclarator: { const: 3 } }], }, { @@ -768,15 +773,15 @@ const div: JQuery = $('
') button: JQuery = $('