diff --git a/.eslintrc.js b/.eslintrc.js index f25eb9271c8..8b4cfa2db36 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -19,7 +19,11 @@ module.exports = { ], parserOptions: { sourceType: 'module', - project: ['./tsconfig.eslint.json', './packages/*/tsconfig.json'], + project: [ + './tsconfig.eslint.json', + './tests/integration/utils/jsconfig.json', + './packages/*/tsconfig.json', + ], tsconfigRootDir: __dirname, warnOnUnsupportedTypeScriptVersion: false, }, diff --git a/package.json b/package.json index 5b00b8bb264..6010da4c5c8 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "all-contributors-cli": "^6.14.2", "cspell": "^4.0.61", "cz-conventional-changelog": "^3.2.0", - "eslint": "^6.7.0", + "eslint": "^7.0.0", "eslint-plugin-eslint-comments": "^3.1.2", "eslint-plugin-eslint-plugin": "^2.2.1", "eslint-plugin-import": "^2.20.2", diff --git a/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts b/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts index b769e05d926..e112b8205b2 100644 --- a/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts +++ b/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts @@ -94,6 +94,7 @@ export default createRule({ suggest: [ { messageId: 'suggestedFix', + data: banned, fix(fixer): TSESLint.RuleFix | null { if (banned.fixWith == null) { return null; 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 c2af09bec90..3b8bb47dafd 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 @@ -417,6 +417,27 @@ ruleTester.run({ ], }, ], +}); + `, + output: ` +ruleTester.run({ + valid: [], + invalid: [ + { + code: 'const x = 1;', + errors: [ + { + messageId: 'foo', + suggestions: [ + { + messageId: 'bar', + output: 'const x = 1;', + }, + ], + }, + ], + }, + ], }); `, errors: [ @@ -459,6 +480,40 @@ ruleTester.run({ foo\`, }, ], +}); + `, + output: ` +ruleTester.run({ + valid: [ + { + code: 'foo', + }, + { + code: \` +foo +\`, + }, + { + code: \` + foo +\`, + }, + ], + invalid: [ + { + code: 'foo', + }, + { + code: \` +foo +\`, + }, + { + code: \` + foo +\`, + }, + ], }); `, errors: [ @@ -508,6 +563,9 @@ ruleTester.run({ }, { code: wrap`\`const a = "1"; +${CODE_INDENT}\`.trimRight()`, + output: wrap`\` +const a = "1"; ${CODE_INDENT}\`.trimRight()`, errors: [ { diff --git a/packages/eslint-plugin-tslint/package.json b/packages/eslint-plugin-tslint/package.json index d56f9232de0..1f132c9aec2 100644 --- a/packages/eslint-plugin-tslint/package.json +++ b/packages/eslint-plugin-tslint/package.json @@ -35,7 +35,7 @@ "lodash": "^4.17.15" }, "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0", "tslint": "^5.0.0 || ^6.0.0", "typescript": "*" }, diff --git a/packages/eslint-plugin-tslint/tests/index.spec.ts b/packages/eslint-plugin-tslint/tests/index.spec.ts index 5241f8907ca..ab88970867e 100644 --- a/packages/eslint-plugin-tslint/tests/index.spec.ts +++ b/packages/eslint-plugin-tslint/tests/index.spec.ts @@ -13,6 +13,7 @@ const ruleTester = new TSESLint.RuleTester({ * within @typescript-eslint/parser */ project: './tests/fixture-project/tsconfig.json', + warnOnUnsupportedTypeScriptVersion: false, }, parser: require.resolve('@typescript-eslint/parser'), }); @@ -71,6 +72,7 @@ ruleTester.run('tslint/config', rule, { { options: [{ lintFile: './tests/test-project/tslint.json' }], code: 'throw "err" // no-string-throw', + output: 'throw new Error("err") // no-string-throw', filename: './tests/fixture-project/3.ts', errors: [ { diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 7cb77b22ab7..2fcdcfd8609 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -56,7 +56,7 @@ }, "peerDependencies": { "@typescript-eslint/parser": "^2.0.0", - "eslint": "^5.0.0 || ^6.0.0" + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" }, "peerDependenciesMeta": { "typescript": { diff --git a/packages/eslint-plugin/src/rules/func-call-spacing.ts b/packages/eslint-plugin/src/rules/func-call-spacing.ts index 53858ad18ab..21a62af1950 100644 --- a/packages/eslint-plugin/src/rules/func-call-spacing.ts +++ b/packages/eslint-plugin/src/rules/func-call-spacing.ts @@ -7,7 +7,10 @@ export type Options = [ allowNewlines?: boolean; }?, ]; -export type MessageIds = 'unexpected' | 'missing'; +export type MessageIds = + | 'unexpectedWhitespace' + | 'unexpectedNewline' + | 'missing'; export default util.createRule({ name: 'func-call-spacing', @@ -56,8 +59,9 @@ export default util.createRule({ }, messages: { - unexpected: - 'Unexpected space or newline between function name and paren.', + unexpectedWhitespace: + 'Unexpected whitespace between function name and paren.', + unexpectedNewline: 'Unexpected newline between function name and paren.', missing: 'Missing space between function name and paren.', }, }, @@ -110,7 +114,7 @@ export default util.createRule({ return context.report({ node, loc: lastCalleeToken.loc.start, - messageId: 'unexpected', + messageId: 'unexpectedWhitespace', fix(fixer) { /* * Only autofix if there is no newline @@ -140,7 +144,7 @@ export default util.createRule({ context.report({ node, loc: lastCalleeToken.loc.start, - messageId: 'unexpected', + messageId: 'unexpectedWhitespace', }); } } else { @@ -157,7 +161,7 @@ export default util.createRule({ context.report({ node, loc: lastCalleeToken.loc.start, - messageId: 'unexpected', + messageId: 'unexpectedNewline', fix(fixer) { return fixer.replaceTextRange( [lastCalleeToken.range[1], openingParenToken.range[0]], diff --git a/packages/eslint-plugin/src/rules/no-empty-function.ts b/packages/eslint-plugin/src/rules/no-empty-function.ts index 5d85dd306bb..e1bc1ed716b 100644 --- a/packages/eslint-plugin/src/rules/no-empty-function.ts +++ b/packages/eslint-plugin/src/rules/no-empty-function.ts @@ -27,6 +27,8 @@ const schema = util.deepMerge( 'constructors', 'private-constructors', 'protected-constructors', + 'asyncFunctions', + 'asyncMethods', ], }, }, diff --git a/packages/eslint-plugin/src/rules/no-implied-eval.ts b/packages/eslint-plugin/src/rules/no-implied-eval.ts index d983065d5b2..dd36fb73ec4 100644 --- a/packages/eslint-plugin/src/rules/no-implied-eval.ts +++ b/packages/eslint-plugin/src/rules/no-implied-eval.ts @@ -7,6 +7,7 @@ import * as tsutils from 'tsutils'; import * as util from '../util'; const FUNCTION_CONSTRUCTOR = 'Function'; +const GLOBAL_CANDIDATES = new Set(['global', 'window', 'globalThis']); const EVAL_LIKE_METHODS = new Set([ 'setImmediate', 'setInterval', @@ -46,7 +47,7 @@ export default util.createRule({ if ( node.type === AST_NODE_TYPES.MemberExpression && node.object.type === AST_NODE_TYPES.Identifier && - node.object.name === 'window' + GLOBAL_CANDIDATES.has(node.object.name) ) { if (node.property.type === AST_NODE_TYPES.Identifier) { return node.property.name; diff --git a/packages/eslint-plugin/src/rules/space-before-function-paren.ts b/packages/eslint-plugin/src/rules/space-before-function-paren.ts index bc2ad8b0d04..41a817938da 100644 --- a/packages/eslint-plugin/src/rules/space-before-function-paren.ts +++ b/packages/eslint-plugin/src/rules/space-before-function-paren.ts @@ -9,11 +9,11 @@ type FuncOption = Option | 'ignore'; export type Options = [ | Option - | Partial<{ - anonymous: FuncOption; - named: FuncOption; - asyncArrow: FuncOption; - }>, + | { + anonymous?: FuncOption; + named?: FuncOption; + asyncArrow?: FuncOption; + }, ]; export type MessageIds = 'unexpected' | 'missing'; @@ -150,7 +150,10 @@ export default util.createRule({ if (hasSpacing && functionConfig === 'never') { context.report({ node, - loc: leftToken.loc.end, + loc: { + start: leftToken.loc.end, + end: rightToken.loc.start, + }, messageId: 'unexpected', fix: fixer => fixer.removeRange([leftToken.range[1], rightToken.range[0]]), @@ -162,7 +165,7 @@ export default util.createRule({ ) { context.report({ node, - loc: leftToken.loc.end, + loc: rightToken.loc, messageId: 'missing', fix: fixer => fixer.insertTextAfter(leftToken, ' '), }); diff --git a/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts index 0cb6ec5d291..21e6369d1b2 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts @@ -64,10 +64,11 @@ fdescribe("foo", function() { options: ['event'], errors: [ { - message: "Unexpected use of 'event'.", - // the base rule doesn't use messageId - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } as any, + messageId: 'defaultMessage', + data: { + name: 'event', + }, + }, ], }, { @@ -77,10 +78,11 @@ confirm("TEST"); options: ['confirm'], errors: [ { - message: "Unexpected use of 'confirm'.", - // the base rule doesn't use messageId - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } as any, + messageId: 'defaultMessage', + data: { + name: 'confirm', + }, + }, ], }, { @@ -90,10 +92,11 @@ var a = confirm("TEST")?.a; options: ['confirm'], errors: [ { - message: "Unexpected use of 'confirm'.", - // the base rule doesn't use messageId - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } as any, + messageId: 'defaultMessage', + data: { + name: 'confirm', + }, + }, ], }, ], diff --git a/packages/eslint-plugin/tests/rules/array-type.test.ts b/packages/eslint-plugin/tests/rules/array-type.test.ts index 5f15ba5e822..ec6ad4ccf8f 100644 --- a/packages/eslint-plugin/tests/rules/array-type.test.ts +++ b/packages/eslint-plugin/tests/rules/array-type.test.ts @@ -717,6 +717,7 @@ function fooFunction(foo: ArrayClass[]) { }, { code: 'let fooVar: Array[];', + output: 'let fooVar: any[][];', options: [{ default: 'array' }], errors: [ { @@ -729,6 +730,7 @@ function fooFunction(foo: ArrayClass[]) { }, { code: 'let fooVar: Array[];', + output: 'let fooVar: any[][];', options: [{ default: 'array-simple' }], errors: [ { diff --git a/packages/eslint-plugin/tests/rules/ban-types.test.ts b/packages/eslint-plugin/tests/rules/ban-types.test.ts index 9f11202a07f..46e258f8e31 100644 --- a/packages/eslint-plugin/tests/rules/ban-types.test.ts +++ b/packages/eslint-plugin/tests/rules/ban-types.test.ts @@ -101,6 +101,7 @@ ruleTester.run('ban-types', rule, { invalid: [ { code: 'let a: String;', + output: 'let a: string;', errors: [ { messageId: 'bannedTypeMessage', 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 db884fd3cf1..2c5d0e57776 100644 --- a/packages/eslint-plugin/tests/rules/func-call-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/func-call-spacing.test.ts @@ -142,12 +142,22 @@ ruleTester.run('func-call-spacing', rule, { { code: 'f.b ();', output: 'f.b();', - errors: [{ messageId: 'unexpected', column: 3 }], + errors: [ + { + messageId: 'unexpectedWhitespace' as const, + column: 3, + }, + ], }, { code: 'f.b().c ();', output: 'f.b().c();', - errors: [{ messageId: 'unexpected', column: 7 }], + errors: [ + { + messageId: 'unexpectedWhitespace' as const, + column: 7, + }, + ], }, { code: 'f() ()', @@ -172,7 +182,14 @@ ruleTester.run('func-call-spacing', rule, { { code: 'f ();\n t ();', output: 'f();\n t();', - errors: [{ messageId: 'unexpected' }, { messageId: 'unexpected' }], + errors: [ + { + messageId: 'unexpectedWhitespace' as const, + }, + { + messageId: 'unexpectedWhitespace' as const, + }, + ], }, // https://github.com/eslint/eslint/issues/7787 @@ -189,7 +206,7 @@ this.decrement(request) output: null, // no change errors: [ { - messageId: 'unexpected', + messageId: 'unexpectedWhitespace' as const, line: 3, column: 23, }, @@ -203,7 +220,7 @@ var a = foo output: null, // no change errors: [ { - messageId: 'unexpected', + messageId: 'unexpectedWhitespace' as const, line: 2, column: 9, }, @@ -217,7 +234,7 @@ var a = foo output: null, // no change errors: [ { - messageId: 'unexpected', + messageId: 'unexpectedWhitespace' as const, line: 2, column: 9, }, @@ -239,14 +256,15 @@ var a = foo code: 'f\r\n();', output: null, // no change }, - ].map( - code => - ({ - options: ['never'], - errors: [{ messageId: 'unexpected' }], - ...code, - } as TSESLint.InvalidTestCase), - ), + ].map>(code => ({ + options: ['never'], + errors: [ + { + messageId: 'unexpectedWhitespace', + }, + ], + ...code, + })), // "always" ...[ @@ -274,14 +292,15 @@ var a = foo code: 'f(0) (1)', output: 'f (0) (1)', }, - ].map( - code => - ({ - options: ['always'], - errors: [{ messageId: 'missing' }], - ...code, - } as TSESLint.InvalidTestCase), - ), + ].map>(code => ({ + options: ['always'], + errors: [ + { + messageId: 'missing', + }, + ], + ...code, + })), ...[ { code: 'f\n();', @@ -294,7 +313,12 @@ var a = foo { code: 'f.b();', output: 'f.b ();', - errors: [{ messageId: 'missing' as MessageIds, column: 3 }], + errors: [ + { + messageId: 'missing' as const, + column: 3, + }, + ], }, { code: 'f.b\n();', @@ -303,7 +327,12 @@ var a = foo { code: 'f.b().c ();', output: 'f.b ().c ();', - errors: [{ messageId: 'missing' as MessageIds, column: 3 }], + errors: [ + { + messageId: 'missing' as const, + column: 3, + }, + ], }, { code: 'f.b\n().c ();', @@ -317,21 +346,33 @@ var a = foo code: 'f\n()()', output: 'f () ()', errors: [ - { messageId: 'unexpected' as MessageIds }, - { messageId: 'missing' as MessageIds }, + { + messageId: 'unexpectedNewline' as const, + }, + { + messageId: 'missing' as const, + }, ], }, { code: '(function() {}())', output: '(function() {} ())', - errors: [{ messageId: 'missing' }], + errors: [ + { + messageId: 'missing' as const, + }, + ], }, { code: 'f();\n t();', output: 'f ();\n t ();', errors: [ - { messageId: 'missing' as MessageIds }, - { messageId: 'missing' as MessageIds }, + { + messageId: 'missing' as const, + }, + { + messageId: 'missing' as const, + }, ], }, { @@ -341,23 +382,37 @@ var a = foo { code: 'f\u2028();', output: 'f ();', + errors: [ + { + messageId: 'unexpectedNewline' as const, + }, + ], }, { code: 'f\u2029();', output: 'f ();', + errors: [ + { + messageId: 'unexpectedNewline' as const, + }, + ], }, { code: 'f\r\n();', output: 'f ();', }, - ].map( - code => - ({ - options: ['always'], - errors: [{ messageId: 'unexpected' as MessageIds }], - ...code, - } as TSESLint.InvalidTestCase), - ), + ].map>(code => ({ + options: ['always'], + errors: [ + { + messageId: + code.code.includes('\n') || code.code.includes('\r') + ? 'unexpectedNewline' + : 'unexpectedWhitespace', + }, + ], + ...code, + })), // "always", "allowNewlines": true ...[ @@ -372,7 +427,12 @@ var a = foo { code: 'f.b();', output: 'f.b ();', - errors: [{ messageId: 'missing', column: 3 }], + errors: [ + { + messageId: 'missing' as const, + column: 3, + }, + ], }, { code: 'f.b().c ();', @@ -401,16 +461,24 @@ var a = foo { code: 'f();\n t();', output: 'f ();\n t ();', - errors: [{ messageId: 'missing' }, { messageId: 'missing' }], + errors: [ + { + messageId: 'missing' as const, + }, + { + messageId: 'missing' as const, + }, + ], }, - ].map( - code => - ({ - options: ['always', { allowNewlines: true }], - errors: [{ messageId: 'missing' }], - ...code, - } as TSESLint.InvalidTestCase), - ), + ].map>(code => ({ + options: ['always', { allowNewlines: true }], + errors: [ + { + messageId: 'missing', + }, + ], + ...code, + })), // optional chain ...[ @@ -424,21 +492,33 @@ var a = foo acc.push( { options: ['always', { allowNewlines: true }], - errors: [{ messageId: 'unexpected' }], + errors: [ + { + messageId: 'unexpectedWhitespace', + }, + ], code, // apply no fixers to it output: null, }, { options: ['always'], - errors: [{ messageId: 'unexpected' }], + errors: [ + { + messageId: 'unexpectedWhitespace', + }, + ], code, // apply no fixers to it output: null, }, { options: ['never'], - errors: [{ messageId: 'unexpected' }], + errors: [ + { + messageId: 'unexpectedWhitespace', + }, + ], code, // apply no fixers to it output: null, diff --git a/packages/eslint-plugin/tests/rules/keyword-spacing.test.ts b/packages/eslint-plugin/tests/rules/keyword-spacing.test.ts index 987caebb1e4..ec94928c1c5 100644 --- a/packages/eslint-plugin/tests/rules/keyword-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/keyword-spacing.test.ts @@ -145,6 +145,7 @@ ruleTester.run('keyword-spacing', rule, { }, { code: 'const foo = {} as{};', + output: 'const foo = {} as {};', options: [{ overrides: { as: {} } }], parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: expectedAfter('as'), diff --git a/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts b/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts index 0ace2662313..d0fa7895b9c 100644 --- a/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts +++ b/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts @@ -3236,6 +3236,12 @@ type Foo = { interface Foo { name: string; age: number; +} + `, + output: ` +interface Foo { + name: string; + age: number } `, options: [{ multiline: { delimiter: 'semi', requireLast: false } }], @@ -3252,6 +3258,12 @@ interface Foo { interface Foo { name: string; age: number; +} + `, + output: ` +interface Foo { + name: string; + age: number } `, options: [ @@ -3277,6 +3289,7 @@ interface Foo { }, { code: 'interface Foo { a: any, [key: string]: any }', + output: 'interface Foo { a: any; [key: string]: any }', errors: [ { messageId: 'expectedSemi', @@ -3290,6 +3303,12 @@ interface Foo { type Foo = { name: string; age: number; +} + `, + output: ` +type Foo = { + name: string; + age: number } `, options: [{ multiline: { delimiter: 'semi', requireLast: false } }], @@ -3306,6 +3325,12 @@ type Foo = { type Foo = { name: string; age: number; +} + `, + output: ` +type Foo = { + name: string; + age: number } `, options: [ @@ -3331,6 +3356,7 @@ type Foo = { }, { code: 'type Foo = { a: any, [key: string]: any }', + output: 'type Foo = { a: any; [key: string]: any }', errors: [ { messageId: 'expectedSemi', diff --git a/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts b/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts index d0281ec77a0..f974af09c18 100644 --- a/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts +++ b/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts @@ -63,6 +63,13 @@ interface Foo { } interface Bar extends Foo {} + `, + output: noFormat` +interface Foo { + name: string; +} + +type Bar = Foo `, options: [{ allowSingleExtends: false }], errors: [ diff --git a/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts b/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts index 03414b9bc49..45cdf1f99c1 100644 --- a/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts +++ b/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts @@ -233,6 +233,14 @@ for (a in (b, c)); for (a in (b)); for (a of (b)); typeof (a); + `, + output: ` +a = b * c; +a * b + c; +for (a in b, c); +for (a in b); +for (a of b); +typeof a; `, errors: [ { @@ -271,6 +279,10 @@ typeof (a); code: ` const Component = (
) const Component = (

) + `, + output: ` +const Component =
+const Component =

`, options: ['all', { ignoreJSX: 'multi-line' }], errors: [ @@ -298,6 +310,18 @@ const Component = ( prop={true} /> ) + `, + output: ` +const Component =${' '} +
+

+

+ +const Component =${' '} +
+ `, options: ['all', { ignoreJSX: 'single-line' }], errors: [ @@ -317,6 +341,10 @@ const Component = ( code: ` ((function foo() {}))(); var y = (function () {return 1;}); + `, + output: ` +(function foo() {})(); +var y = function () {return 1;}; `, options: ['functions'], errors: [ diff --git a/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts b/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts index 353a6300b45..818514c6b0b 100644 --- a/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts +++ b/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts @@ -651,6 +651,120 @@ window['execScript'](\`\`); }, ], }, + { + code: ` +global.setTimeout(\`\`, 0); +global['setTimeout'](\`\`, 0); + +global.setInterval(\`\`, 0); +global['setInterval'](\`\`, 0); + +global.setImmediate(\`\`); +global['setImmediate'](\`\`); + +global.execScript(\`\`); +global['execScript'](\`\`); + `, + errors: [ + { + messageId: 'noImpliedEvalError', + line: 2, + column: 19, + }, + { + messageId: 'noImpliedEvalError', + line: 3, + column: 22, + }, + { + messageId: 'noImpliedEvalError', + line: 5, + column: 20, + }, + { + messageId: 'noImpliedEvalError', + line: 6, + column: 23, + }, + { + messageId: 'noImpliedEvalError', + line: 8, + column: 21, + }, + { + messageId: 'noImpliedEvalError', + line: 9, + column: 24, + }, + { + messageId: 'noImpliedEvalError', + line: 11, + column: 19, + }, + { + messageId: 'noImpliedEvalError', + line: 12, + column: 22, + }, + ], + }, + { + code: ` +globalThis.setTimeout(\`\`, 0); +globalThis['setTimeout'](\`\`, 0); + +globalThis.setInterval(\`\`, 0); +globalThis['setInterval'](\`\`, 0); + +globalThis.setImmediate(\`\`); +globalThis['setImmediate'](\`\`); + +globalThis.execScript(\`\`); +globalThis['execScript'](\`\`); + `, + errors: [ + { + messageId: 'noImpliedEvalError', + line: 2, + column: 23, + }, + { + messageId: 'noImpliedEvalError', + line: 3, + column: 26, + }, + { + messageId: 'noImpliedEvalError', + line: 5, + column: 24, + }, + { + messageId: 'noImpliedEvalError', + line: 6, + column: 27, + }, + { + messageId: 'noImpliedEvalError', + line: 8, + column: 25, + }, + { + messageId: 'noImpliedEvalError', + line: 9, + column: 28, + }, + { + messageId: 'noImpliedEvalError', + line: 11, + column: 23, + }, + { + messageId: 'noImpliedEvalError', + line: 12, + column: 26, + }, + ], + }, { code: 'const fn = Function();', errors: [ diff --git a/packages/eslint-plugin/tests/rules/no-invalid-this.test.ts b/packages/eslint-plugin/tests/rules/no-invalid-this.test.ts index f3d339fe63e..0705ba1e9e8 100644 --- a/packages/eslint-plugin/tests/rules/no-invalid-this.test.ts +++ b/packages/eslint-plugin/tests/rules/no-invalid-this.test.ts @@ -8,10 +8,9 @@ const ruleTester = new RuleTester({ }, }); -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const errors: any = [ - { message: "Unexpected 'this'." }, - { message: "Unexpected 'this'." }, +const errors = [ + { messageId: 'unexpectedThis' as const }, + { messageId: 'unexpectedThis' as const }, ]; ruleTester.run('no-invalid-this', rule, { @@ -416,7 +415,7 @@ function foo() { this.prop; } `, - errors: [{ message: "Unexpected 'this'." }], + errors: [{ messageId: 'unexpectedThis' }], }, // Global. { diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts index 91deb63f58c..72bf643942f 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts @@ -499,6 +499,13 @@ const x = [{}] as [{ foo: string }]; if (x[0]) { } if (x[0]?.foo) { +} + `, + output: ` +const x = [{}] as [{ foo: string }]; +if (x[0]) { +} +if (x[0].foo) { } `, errors: [ diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts index d6febe39ea5..b197a96afe2 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts @@ -1,6 +1,6 @@ import path from 'path'; import rule from '../../src/rules/no-unnecessary-type-assertion'; -import { RuleTester } from '../RuleTester'; +import { RuleTester, noFormat } from '../RuleTester'; const rootDir = path.resolve(__dirname, '../fixtures/'); const ruleTester = new RuleTester({ @@ -183,6 +183,10 @@ const c = [...a, ...b]; code: ` const foo = 3; const bar = foo!; + `, + output: ` +const foo = 3; +const bar = foo; `, errors: [ { @@ -195,6 +199,9 @@ const bar = foo!; { code: ` const foo = (3 + 5) as number; + `, + output: noFormat` +const foo = (3 + 5); `, errors: [ { @@ -207,6 +214,9 @@ const foo = (3 + 5) as number; { code: ` const foo = (3 + 5); + `, + output: noFormat` +const foo = (3 + 5); `, errors: [ { @@ -220,6 +230,10 @@ const foo = (3 + 5); code: ` type Foo = number; const foo = (3 + 5) as Foo; + `, + output: noFormat` +type Foo = number; +const foo = (3 + 5); `, errors: [ { @@ -233,6 +247,10 @@ const foo = (3 + 5) as Foo; code: ` type Foo = number; const foo = (3 + 5); + `, + output: noFormat` +type Foo = number; +const foo = (3 + 5); `, errors: [ { diff --git a/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts b/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts index 6b0d7f4148b..73ad95d1f4d 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts @@ -10,14 +10,6 @@ const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', }); -// the base rule doesn't have messageIds -function error( - messages: { message: string; line: number; column: number }[], - // eslint-disable-next-line @typescript-eslint/no-explicit-any -): any[] { - return messages; -} - ruleTester.run('no-unused-vars', rule, { valid: [ ` @@ -632,13 +624,18 @@ export default class Foo { import { ClassDecoratorFactory } from 'decorators'; export class Foo {} `, - errors: error([ + errors: [ { - message: "'ClassDecoratorFactory' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'ClassDecoratorFactory', + action: 'defined', + additional: '', + }, line: 2, column: 10, }, - ]), + ], }, { code: ` @@ -646,13 +643,18 @@ import { Foo, Bar } from 'foo'; function baz() {} baz(); `, - errors: error([ + errors: [ { - message: "'Foo' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'Foo', + action: 'defined', + additional: '', + }, line: 2, column: 10, }, - ]), + ], }, { code: ` @@ -660,13 +662,18 @@ import { Nullable } from 'nullable'; const a: string = 'hello'; console.log(a); `, - errors: error([ + errors: [ { - message: "'Nullable' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'Nullable', + action: 'defined', + additional: '', + }, line: 2, column: 10, }, - ]), + ], }, { code: ` @@ -675,13 +682,18 @@ import { SomeOther } from 'other'; const a: Nullable = 'hello'; console.log(a); `, - errors: error([ + errors: [ { - message: "'SomeOther' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'SomeOther', + action: 'defined', + additional: '', + }, line: 3, column: 10, }, - ]), + ], }, { @@ -695,13 +707,18 @@ class A { } new A(); `, - errors: error([ + errors: [ { - message: "'Another' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'Another', + action: 'defined', + additional: '', + }, line: 3, column: 10, }, - ]), + ], }, { code: ` @@ -714,13 +731,18 @@ class A { } new A(); `, - errors: error([ + errors: [ { - message: "'Another' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'Another', + action: 'defined', + additional: '', + }, line: 3, column: 10, }, - ]), + ], }, { code: ` @@ -733,13 +755,18 @@ class A { } new A(); `, - errors: error([ + errors: [ { - message: "'Another' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'Another', + action: 'defined', + additional: '', + }, line: 3, column: 10, }, - ]), + ], }, { code: ` @@ -749,13 +776,18 @@ interface A { do(a: Nullable); } `, - errors: error([ + errors: [ { - message: "'Another' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'Another', + action: 'defined', + additional: '', + }, line: 3, column: 10, }, - ]), + ], }, { code: ` @@ -765,13 +797,18 @@ interface A { other: Nullable; } `, - errors: error([ + errors: [ { - message: "'Another' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'Another', + action: 'defined', + additional: '', + }, line: 3, column: 10, }, - ]), + ], }, { code: ` @@ -781,13 +818,18 @@ function foo(a: string) { } foo(); `, - errors: error([ + errors: [ { - message: "'Nullable' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'Nullable', + action: 'defined', + additional: '', + }, line: 2, column: 10, }, - ]), + ], }, { code: ` @@ -797,13 +839,18 @@ function foo(): string | null { } foo(); `, - errors: error([ + errors: [ { - message: "'Nullable' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'Nullable', + action: 'defined', + additional: '', + }, line: 2, column: 10, }, - ]), + ], }, { code: ` @@ -815,13 +862,18 @@ class A extends Nullable { } new A(); `, - errors: error([ + errors: [ { - message: "'SomeOther' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'SomeOther', + action: 'defined', + additional: '', + }, line: 3, column: 10, }, - ]), + ], }, { code: ` @@ -833,13 +885,18 @@ abstract class A extends Nullable { } new A(); `, - errors: error([ + errors: [ { - message: "'SomeOther' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'SomeOther', + action: 'defined', + additional: '', + }, line: 3, column: 10, }, - ]), + ], }, { code: ` @@ -848,13 +905,18 @@ enum FormFieldIds { EMAIL = 'email', } `, - errors: error([ + errors: [ { - message: "'FormFieldIds' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'FormFieldIds', + action: 'defined', + additional: '', + }, line: 2, column: 6, }, - ]), + ], }, { code: ` @@ -862,13 +924,18 @@ import test from 'test'; import baz from 'baz'; export interface Bar extends baz.test {} `, - errors: error([ + errors: [ { - message: "'test' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'test', + action: 'defined', + additional: '', + }, line: 2, column: 8, }, - ]), + ], }, { code: ` @@ -876,13 +943,18 @@ import test from 'test'; import baz from 'baz'; export interface Bar extends baz().test {} `, - errors: error([ + errors: [ { - message: "'test' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'test', + action: 'defined', + additional: '', + }, line: 2, column: 8, }, - ]), + ], }, { code: ` @@ -890,13 +962,18 @@ import test from 'test'; import baz from 'baz'; export class Bar implements baz.test {} `, - errors: error([ + errors: [ { - message: "'test' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'test', + action: 'defined', + additional: '', + }, line: 2, column: 8, }, - ]), + ], }, { code: ` @@ -904,13 +981,18 @@ import test from 'test'; import baz from 'baz'; export class Bar implements baz().test {} `, - errors: error([ + errors: [ { - message: "'test' is defined but never used.", + messageId: 'unusedVar', + data: { + varName: 'test', + action: 'defined', + additional: '', + }, line: 2, column: 8, }, - ]), + ], }, ], }); diff --git a/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts b/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts index 412aab3a1f1..0730f280dc2 100644 --- a/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts +++ b/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts @@ -10,10 +10,8 @@ const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', }); -// the base rule doesn't use a message id... -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const error: any = { - message: 'Useless constructor.', +const error = { + messageId: 'noUselessConstructor' as const, type: AST_NODE_TYPES.MethodDefinition, }; diff --git a/packages/eslint-plugin/tests/rules/quotes.test.ts b/packages/eslint-plugin/tests/rules/quotes.test.ts index f7b56a73ba3..847e27e81f5 100644 --- a/packages/eslint-plugin/tests/rules/quotes.test.ts +++ b/packages/eslint-plugin/tests/rules/quotes.test.ts @@ -15,22 +15,25 @@ const ruleTester = new RuleTester({ }, }); -/** - * the base rule `quotes` doesn't use a message id - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const useDoubleQuote: any = { - message: 'Strings must use doublequote.', +const useDoubleQuote = { + messageId: 'wrongQuotes' as const, + data: { + description: 'doublequote', + }, }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const useSingleQuote: any = { - message: 'Strings must use singlequote.', +const useSingleQuote = { + messageId: 'wrongQuotes' as const, + data: { + description: 'singlequote', + }, }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const useBacktick: any = { - message: 'Strings must use backtick.', +const useBacktick = { + messageId: 'wrongQuotes' as const, + data: { + description: 'backtick', + }, }; ruleTester.run('quotes', rule, { diff --git a/packages/eslint-plugin/tests/rules/return-await.test.ts b/packages/eslint-plugin/tests/rules/return-await.test.ts index f3e4169ad9d..5a98d22c917 100644 --- a/packages/eslint-plugin/tests/rules/return-await.test.ts +++ b/packages/eslint-plugin/tests/rules/return-await.test.ts @@ -592,6 +592,7 @@ ruleTester.run('return-await', rule, { { options: ['always'], code: 'const test = async () => Promise.resolve(1);', + output: 'const test = async () => await Promise.resolve(1);', errors: [ { line: 1, diff --git a/packages/eslint-plugin/tests/rules/semi.test.ts b/packages/eslint-plugin/tests/rules/semi.test.ts index c8a8ff7f479..d32e557eb58 100644 --- a/packages/eslint-plugin/tests/rules/semi.test.ts +++ b/packages/eslint-plugin/tests/rules/semi.test.ts @@ -1,3 +1,8 @@ +/* eslint-disable eslint-comments/no-use */ +// this rule tests the semis, 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/semi'; import { RuleTester } from '../RuleTester'; @@ -17,82 +22,249 @@ const neverOptionWithoutContinuationChars: Options = [ { beforeStatementContinuationChars: 'never' }, ]; -// the base rule doesn't use a message id... -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const missingSemicolon: any = { - message: 'Missing semicolon.', +const missingSemicolon = { + messageId: 'missingSemi' as const, }; -// the base rule doesn't use a message id... -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const extraSemicolon: any = { - message: 'Extra semicolon.', +const extraSemicolon = { + messageId: 'extraSemi' as const, }; ruleTester.run('semi', rule, { valid: [ - // https://github.com/typescript-eslint/typescript-eslint/issues/366 - 'export = Foo;', - 'import f = require("f");', - 'type Foo = {};', - // https://github.com/typescript-eslint/typescript-eslint/issues/409 - ` + { code: 'for (var i;;){}' }, + { code: 'for (var i;;){}', options: neverOption }, + + { + code: 'var foo = 0;export { foo };', + }, + + // https://github.com/eslint/eslint/issues/7782 + { code: 'var a = b;\n/foo/.test(c)', options: neverOption }, + { + code: 'var a = b;\n`foo`', + options: neverOption, + }, + { code: 'var a = b;\n+ c', options: neverOption }, + + { + code: '(function bar() {})\n;(function foo(){})', + options: neverOption, + }, + { code: ";/foo/.test('bar')", options: neverOption }, + { code: ';+5', options: neverOption }, + { code: ';-foo()', options: neverOption }, + { code: 'a++\nb++', options: neverOption }, + { code: 'a++; b++', options: neverOption }, + + // https://github.com/eslint/eslint/issues/9521 + { + code: ` + do; while(a); + [1,2,3].forEach(doSomething) + `, + options: ['never', { beforeStatementContinuationChars: 'any' }], + }, + { + code: ` + do; while(a) + [1,2,3].forEach(doSomething) + `, + options: ['never', { beforeStatementContinuationChars: 'any' }], + }, + { + code: ` + import a from "a"; + [1,2,3].forEach(doSomething) + `, + options: ['never', { beforeStatementContinuationChars: 'always' }], + }, + { + code: ` + var a = 0; export {a}; + [a] = b + `, + options: ['never', { beforeStatementContinuationChars: 'always' }], + }, + { + code: ` + function wrap() { + return; + ({a} = b) + } + `, + options: ['never', { beforeStatementContinuationChars: 'always' }], + parserOptions: { ecmaVersion: 2015 }, + }, + { + code: ` + while (true) { + break; + +i + } + `, + options: ['never', { beforeStatementContinuationChars: 'always' }], + }, + { + code: ` + while (true) { + continue; + [1,2,3].forEach(doSomething) + } + `, + options: ['never', { beforeStatementContinuationChars: 'always' }], + }, + { + code: ` + do; while(a); + [1,2,3].forEach(doSomething) + `, + options: ['never', { beforeStatementContinuationChars: 'always' }], + }, + { + code: ` + const f = () => {}; + [1,2,3].forEach(doSomething) + `, + options: ['never', { beforeStatementContinuationChars: 'always' }], + parserOptions: { ecmaVersion: 2015 }, + }, + { + code: ` + import a from "a" + [1,2,3].forEach(doSomething) + `, + options: neverOptionWithoutContinuationChars, + }, + { + code: ` + var a = 0; export {a} + [a] = b + `, + options: neverOptionWithoutContinuationChars, + }, + { + code: ` + function wrap() { + return + ({a} = b) + } + `, + options: neverOptionWithoutContinuationChars, + parserOptions: { ecmaVersion: 2015 }, + }, + { + code: ` + while (true) { + break + +i + } + `, + options: neverOptionWithoutContinuationChars, + }, + { + code: ` + while (true) { + continue + [1,2,3].forEach(doSomething) + } + `, + options: neverOptionWithoutContinuationChars, + }, + { + code: ` + do; while(a) + [1,2,3].forEach(doSomething) + `, + options: neverOptionWithoutContinuationChars, + }, + { + code: ` + const f = () => {} + [1,2,3].forEach(doSomething) + `, + options: neverOptionWithoutContinuationChars, + parserOptions: { ecmaVersion: 2015 }, + }, + + { + code: 'if (foo) { bar(); }', + options: ['always', { omitLastInOneLineBlock: false }], + }, + { + code: 'if (foo) { bar(); baz(); }', + options: ['always', { omitLastInOneLineBlock: false }], + }, + { + code: 'if (foo) { bar() }', + options: ['always', { omitLastInOneLineBlock: true }], + }, + { + code: 'if (foo) { bar(); baz() }', + options: ['always', { omitLastInOneLineBlock: true }], + }, + ...[ + // https://github.com/typescript-eslint/typescript-eslint/issues/366 + 'export = Foo;', + 'import f = require("f");', + 'type Foo = {};', + // https://github.com/typescript-eslint/typescript-eslint/issues/409 + ` class Class { prop: string; } `, - ` + ` abstract class AbsClass { abstract prop: string; abstract meth(): string; } `, - ` + ` class PanCamera extends FreeCamera { public invertY: boolean = false; } `, - // https://github.com/typescript-eslint/typescript-eslint/issues/123 - 'export default interface test {}', - `declare function declareFn(): string;`, - // ESLint - 'var x = 5;', - 'var x =5, y;', - 'foo();', - 'x = foo();', - 'setTimeout(function() {foo = "bar"; });', - 'setTimeout(function() {foo = "bar";});', - 'for (var a in b){}', - 'if (true) {}\n;[global, extended].forEach(function(){});', - "throw new Error('foo');", - 'debugger;', - '++\nfoo;', - 'for (let thing of {}) {\n console.log(thing);\n}', - 'do{}while(true);', + // https://github.com/typescript-eslint/typescript-eslint/issues/123 + 'export default interface test {}', + `declare function declareFn(): string;`, + // ESLint + 'var x = 5;', + 'var x =5, y;', + 'foo();', + 'x = foo();', + 'setTimeout(function() {foo = "bar"; });', + 'setTimeout(function() {foo = "bar";});', + 'for (var a in b){}', + 'if (true) {}\n;[global, extended].forEach(function(){});', + "throw new Error('foo');", + 'debugger;', + '++\nfoo;', + 'for (let thing of {}) {\n console.log(thing);\n}', + 'do{}while(true);', - // method definitions don't have a semicolon. - 'class A { a() {} b() {} }', - 'var A = class { a() {} b() {} };', - "import theDefault, { named1, named2 } from 'src/mylib';", + // method definitions don't have a semicolon. + 'class A { a() {} b() {} }', + 'var A = class { a() {} b() {} };', + "import theDefault, { named1, named2 } from 'src/mylib';", - // exports, "always" - "export * from 'foo';", - "export { foo } from 'foo';", - 'export var foo;', - 'export function foo () { }', - 'export function* foo () { }', - 'export class Foo { }', - 'export let foo;', - 'export const FOO = 42;', - 'export default function() { }', - 'export default function* () { }', - 'export default class { }', - 'export default foo || bar;', - 'export default (foo) => foo.bar();', - 'export default foo = 42;', - 'export default foo += 42;', - ].reduce[]>( - (acc, code) => { + // exports, "always" + "export * from 'foo';", + "export { foo } from 'foo';", + 'export var foo;', + 'export function foo () { }', + 'export function* foo () { }', + 'export class Foo { }', + 'export let foo;', + 'export const FOO = 42;', + 'export default function() { }', + 'export default function* () { }', + 'export default class { }', + 'export default foo || bar;', + 'export default (foo) => foo.bar();', + 'export default foo = 42;', + 'export default foo += 42;', + ].reduce[]>((acc, code) => { acc.push({ code, options: ['always'], @@ -103,604 +275,509 @@ class PanCamera extends FreeCamera { }); return acc; - }, - [ - { code: 'for (var i;;){}' }, - { code: 'for (var i;;){}', options: neverOption }, - - { - code: 'var foo = 0;export { foo };', - }, - - // https://github.com/eslint/eslint/issues/7782 - { code: 'var a = b;\n/foo/.test(c)', options: neverOption }, - { - code: 'var a = b;\n`foo`', - options: neverOption, - }, - { code: 'var a = b;\n+ c', options: neverOption }, - - { - code: '(function bar() {})\n;(function foo(){})', - options: neverOption, - }, - { code: ";/foo/.test('bar')", options: neverOption }, - { code: ';+5', options: neverOption }, - { code: ';-foo()', options: neverOption }, - { code: 'a++\nb++', options: neverOption }, - { code: 'a++; b++', options: neverOption }, - - // https://github.com/eslint/eslint/issues/9521 - { - code: ` - do; while(a); - [1,2,3].forEach(doSomething) - `, - options: ['never', { beforeStatementContinuationChars: 'any' }], - }, - { - code: ` - do; while(a) - [1,2,3].forEach(doSomething) - `, - options: ['never', { beforeStatementContinuationChars: 'any' }], - }, - { - code: ` - import a from "a"; - [1,2,3].forEach(doSomething) - `, - options: ['never', { beforeStatementContinuationChars: 'always' }], - }, - { - code: ` - var a = 0; export {a}; - [a] = b - `, - options: ['never', { beforeStatementContinuationChars: 'always' }], - }, - { - code: ` - function wrap() { - return; - ({a} = b) - } - `, - options: ['never', { beforeStatementContinuationChars: 'always' }], - parserOptions: { ecmaVersion: 2015 }, - }, - { - code: ` - while (true) { - break; - +i - } - `, - options: ['never', { beforeStatementContinuationChars: 'always' }], - }, - { - code: ` - while (true) { - continue; - [1,2,3].forEach(doSomething) - } - `, - options: ['never', { beforeStatementContinuationChars: 'always' }], - }, - { - code: ` - do; while(a); - [1,2,3].forEach(doSomething) - `, - options: ['never', { beforeStatementContinuationChars: 'always' }], - }, - { - code: ` - const f = () => {}; - [1,2,3].forEach(doSomething) - `, - options: ['never', { beforeStatementContinuationChars: 'always' }], - parserOptions: { ecmaVersion: 2015 }, - }, - { - code: ` - import a from "a" - [1,2,3].forEach(doSomething) - `, - options: neverOptionWithoutContinuationChars, - }, - { - code: ` - var a = 0; export {a} - [a] = b - `, - options: neverOptionWithoutContinuationChars, - }, - { - code: ` - function wrap() { - return - ({a} = b) - } - `, - options: neverOptionWithoutContinuationChars, - parserOptions: { ecmaVersion: 2015 }, - }, - { - code: ` - while (true) { - break - +i - } - `, - options: neverOptionWithoutContinuationChars, - }, - { - code: ` - while (true) { - continue - [1,2,3].forEach(doSomething) - } - `, - options: neverOptionWithoutContinuationChars, - }, - { - code: ` - do; while(a) - [1,2,3].forEach(doSomething) - `, - options: neverOptionWithoutContinuationChars, - }, - { - code: ` - const f = () => {} - [1,2,3].forEach(doSomething) - `, - options: neverOptionWithoutContinuationChars, - parserOptions: { ecmaVersion: 2015 }, - }, - - { - code: 'if (foo) { bar(); }', - options: ['always', { omitLastInOneLineBlock: false }], - }, - { - code: 'if (foo) { bar(); baz(); }', - options: ['always', { omitLastInOneLineBlock: false }], - }, - { - code: 'if (foo) { bar() }', - options: ['always', { omitLastInOneLineBlock: true }], - }, - { - code: 'if (foo) { bar(); baz() }', - options: ['always', { omitLastInOneLineBlock: true }], - }, - ], - ), + }, []), + ], invalid: [ { - code: `declare function declareFn(): string;`, - errors: [ - { - line: 1, - }, - ], + code: 'if (foo) { bar() }', + output: 'if (foo) { bar(); }', + options: ['always', { omitLastInOneLineBlock: false }], + errors: [missingSemicolon], }, - - // https://github.com/typescript-eslint/typescript-eslint/issues/366 { - code: 'export = Foo;', - errors: [ - { - line: 1, - }, - ], + code: 'if (foo) { bar(); baz() }', + output: 'if (foo) { bar(); baz(); }', + options: ['always', { omitLastInOneLineBlock: false }], + errors: [missingSemicolon], }, { - code: 'import f = require("f");', - errors: [ - { - line: 1, - }, - ], + code: 'if (foo) { bar(); }', + output: 'if (foo) { bar() }', + options: ['always', { omitLastInOneLineBlock: true }], + errors: [extraSemicolon], }, { - code: 'type Foo = {};', - errors: [ - { - line: 1, - }, - ], + code: 'if (foo) { bar(); baz(); }', + output: 'if (foo) { bar(); baz() }', + options: ['always', { omitLastInOneLineBlock: true }], + errors: [extraSemicolon], }, - // https://github.com/typescript-eslint/typescript-eslint/issues/409 { code: ` -class Class { - prop: string; -} + import a from "a" + (function() { + // ... + })() `, - errors: [ - { - line: 3, - }, - ], - }, - { - code: ` -abstract class AbsClass { - abstract prop: string; - abstract meth(): string; -} + output: ` + import a from "a"; + (function() { + // ... + })() `, - errors: [ - { - line: 3, - }, - { - line: 4, - }, - ], + options: ['never', { beforeStatementContinuationChars: 'always' }], + errors: [missingSemicolon], }, { code: ` -class PanCamera extends FreeCamera { - public invertY: boolean = false; -} - `, - errors: [ - { - line: 3, - }, - ], + import a from "a" + ;(function() { + // ... + })() + `, + output: ` + import a from "a" + (function() { + // ... + })() + `, + options: neverOptionWithoutContinuationChars, + errors: [extraSemicolon], }, - // // ESLint { - code: "throw new Error('foo');", - output: "throw new Error('foo')", - errors: [ - { - line: 1, - }, - ], + code: 'for (;;){var i;}', + output: 'for (;;){var i}', + options: neverOption, + errors: [extraSemicolon], }, { - code: 'function foo() { return []; }', - output: 'function foo() { return [] }', - errors: [ - { - line: 1, - }, - ], + code: 'for (;;) var i; ', + output: 'for (;;) var i ', + options: neverOption, + errors: [extraSemicolon], }, { - code: 'while(true) { break; }', - output: 'while(true) { break }', - errors: [ - { - line: 1, - }, - ], + code: 'for (var j;;) {var i;}', + output: 'for (var j;;) {var i}', + options: neverOption, + errors: [extraSemicolon], }, + { - code: 'while(true) { continue; }', - output: 'while(true) { continue }', - errors: [ - { - line: 1, - }, - ], + code: 'for (;;){var i}', + output: 'for (;;){var i;}', + errors: [missingSemicolon], }, { - code: 'let x = 5;', - output: 'let x = 5', - errors: [ - { - line: 1, - }, - ], + code: 'for (;;) var i ', + output: 'for (;;) var i; ', + errors: [missingSemicolon], }, { - code: 'var x = 5;', - output: 'var x = 5', - errors: [ - { - line: 1, - }, - ], + code: 'for (var j;;) {var i}', + output: 'for (var j;;) {var i;}', + errors: [missingSemicolon], }, { - code: 'var x = 5, y;', - output: 'var x = 5, y', - errors: [ - { - line: 1, - }, - ], + code: 'var foo = {\n bar: baz\n}', + output: 'var foo = {\n bar: baz\n};', + errors: [missingSemicolon], }, + { - code: 'debugger;', - output: 'debugger', - errors: [ - { - line: 1, - }, - ], + code: 'if (foo) { bar()\n }', + output: 'if (foo) { bar();\n }', + options: ['always', { omitLastInOneLineBlock: true }], + errors: [missingSemicolon], }, { - code: 'foo();', - output: 'foo()', - errors: [ - { - line: 1, - }, - ], + code: 'if (foo) {\n bar() }', + output: 'if (foo) {\n bar(); }', + options: ['always', { omitLastInOneLineBlock: true }], + errors: [missingSemicolon], }, { - code: 'for (var a in b) var i; ', - output: 'for (var a in b) var i ', - errors: [ - { - line: 1, - }, - ], + code: 'if (foo) {\n bar(); baz() }', + output: 'if (foo) {\n bar(); baz(); }', + options: ['always', { omitLastInOneLineBlock: true }], + errors: [missingSemicolon], }, + + // https://github.com/eslint/eslint/issues/9521 { - code: 'var foo = {\n bar: baz\n};', - output: 'var foo = {\n bar: baz\n}', - errors: [ - { - line: 3, - }, - ], + code: ` + import a from "a" + [1,2,3].forEach(doSomething) + `, + output: ` + import a from "a"; + [1,2,3].forEach(doSomething) + `, + options: ['never', { beforeStatementContinuationChars: 'always' }], + + errors: [missingSemicolon], }, { - code: "import theDefault, { named1, named2 } from 'src/mylib';", - output: "import theDefault, { named1, named2 } from 'src/mylib'", - errors: [ - { - line: 1, - }, - ], + code: ` + var a = 0; export {a} + [a] = b + `, + output: ` + var a = 0; export {a}; + [a] = b + `, + options: ['never', { beforeStatementContinuationChars: 'always' }], + + errors: [missingSemicolon], }, { - code: 'do{}while(true);', - output: 'do{}while(true)', - errors: [ - { - line: 1, - }, - ], + code: ` + function wrap() { + return + ({a} = b) + } + `, + output: ` + function wrap() { + return; + ({a} = b) + } + `, + options: ['never', { beforeStatementContinuationChars: 'always' }], + parserOptions: { ecmaVersion: 2015 }, + errors: [missingSemicolon], }, { - code: "import * as utils from './utils';", - output: "import * as utils from './utils'", - errors: [ - { - line: 1, - }, - ], + code: ` + while (true) { + break + +i + } + `, + output: ` + while (true) { + break; + +i + } + `, + options: ['never', { beforeStatementContinuationChars: 'always' }], + errors: [missingSemicolon], }, { - code: "import { square, diag } from 'lib';", - output: "import { square, diag } from 'lib'", - errors: [ - { - line: 1, - }, - ], + code: ` + while (true) { + continue + [1,2,3].forEach(doSomething) + } + `, + output: ` + while (true) { + continue; + [1,2,3].forEach(doSomething) + } + `, + options: ['never', { beforeStatementContinuationChars: 'always' }], + errors: [missingSemicolon], }, { - code: "import { default as foo } from 'lib';", - output: "import { default as foo } from 'lib'", - errors: [ - { - line: 1, - }, - ], + code: ` + do; while(a) + [1,2,3].forEach(doSomething) + `, + output: ` + do; while(a); + [1,2,3].forEach(doSomething) + `, + options: ['never', { beforeStatementContinuationChars: 'always' }], + errors: [missingSemicolon], }, { - code: "import 'src/mylib';", - output: "import 'src/mylib'", - errors: [ - { - line: 1, - }, - ], + code: ` + const f = () => {} + [1,2,3].forEach(doSomething) + `, + output: ` + const f = () => {}; + [1,2,3].forEach(doSomething) + `, + options: ['never', { beforeStatementContinuationChars: 'always' }], + parserOptions: { ecmaVersion: 2015 }, + errors: [missingSemicolon], }, { - code: 'var foo;\nvar bar;', - output: 'var foo\nvar bar', - errors: [ - { - line: 1, - }, - { - line: 2, - }, - ], + code: ` + import a from "a"; + [1,2,3].forEach(doSomething) + `, + output: ` + import a from "a" + [1,2,3].forEach(doSomething) + `, + options: neverOptionWithoutContinuationChars, + + errors: [extraSemicolon], }, + { + code: ` + var a = 0; export {a}; + [a] = b + `, + output: ` + var a = 0; export {a} + [a] = b + `, + options: neverOptionWithoutContinuationChars, - // exports, "never" + errors: [extraSemicolon], + }, { - code: "export * from 'foo';", - output: "export * from 'foo'", - errors: [ - { - line: 1, - }, - ], + code: ` + function wrap() { + return; + ({a} = b) + } + `, + output: ` + function wrap() { + return + ({a} = b) + } + `, + options: neverOptionWithoutContinuationChars, + parserOptions: { ecmaVersion: 2015 }, + errors: [extraSemicolon], }, { - code: "export { foo } from 'foo';", - output: "export { foo } from 'foo'", - errors: [ - { - line: 1, - }, - ], + code: ` + while (true) { + break; + +i + } + `, + output: ` + while (true) { + break + +i + } + `, + options: neverOptionWithoutContinuationChars, + errors: [extraSemicolon], }, { - code: 'var foo = 0;\nexport { foo };', - output: 'var foo = 0\nexport { foo }', - errors: [ - { - line: 1, - }, - { - line: 2, - }, - ], + code: ` + while (true) { + continue; + [1,2,3].forEach(doSomething) + } + `, + output: ` + while (true) { + continue + [1,2,3].forEach(doSomething) + } + `, + options: neverOptionWithoutContinuationChars, + errors: [extraSemicolon], }, { - code: 'export var foo;', - output: 'export var foo', - errors: [ - { - line: 1, - }, - ], + code: ` + do; while(a); + [1,2,3].forEach(doSomething) + `, + output: ` + do; while(a) + [1,2,3].forEach(doSomething) + `, + options: neverOptionWithoutContinuationChars, + errors: [extraSemicolon], }, { - code: 'export let foo;', - output: 'export let foo', - errors: [ - { - line: 1, - }, - ], + code: ` + const f = () => {}; + [1,2,3].forEach(doSomething) + `, + output: ` + const f = () => {} + [1,2,3].forEach(doSomething) + `, + options: neverOptionWithoutContinuationChars, + parserOptions: { ecmaVersion: 2015 }, + errors: [extraSemicolon], }, { - code: 'export const FOO = 42;', - output: 'export const FOO = 42', - errors: [ - { - line: 1, - }, - ], + code: ` + import a from "a" + ;[1,2,3].forEach(doSomething) + `, + output: ` + import a from "a" + [1,2,3].forEach(doSomething) + `, + options: neverOptionWithoutContinuationChars, + + errors: [extraSemicolon], }, { - code: 'export default foo || bar;', - output: 'export default foo || bar', - errors: [ - { - line: 1, - }, - ], + code: ` + var a = 0; export {a} + ;[1,2,3].forEach(doSomething) + `, + output: ` + var a = 0; export {a} + [1,2,3].forEach(doSomething) + `, + options: neverOptionWithoutContinuationChars, + + errors: [extraSemicolon], }, { - code: 'export default (foo) => foo.bar();', - output: 'export default (foo) => foo.bar()', - errors: [ - { - line: 1, - }, - ], + code: ` + function wrap() { + return + ;[1,2,3].forEach(doSomething) + } + `, + output: ` + function wrap() { + return + [1,2,3].forEach(doSomething) + } + `, + options: neverOptionWithoutContinuationChars, + errors: [extraSemicolon], }, { - code: 'export default foo = 42;', - output: 'export default foo = 42', - errors: [ - { - line: 1, - }, - ], + code: ` + while (true) { + break + ;[1,2,3].forEach(doSomething) + } + `, + output: ` + while (true) { + break + [1,2,3].forEach(doSomething) + } + `, + options: neverOptionWithoutContinuationChars, + errors: [extraSemicolon], }, { - code: 'a;\n++b;', - output: 'a\n++b', - errors: [ - { - line: 1, - }, - { - line: 2, - }, - ], + code: ` + while (true) { + continue + ;[1,2,3].forEach(doSomething) + } + `, + output: ` + while (true) { + continue + [1,2,3].forEach(doSomething) + } + `, + options: neverOptionWithoutContinuationChars, + errors: [extraSemicolon], }, - ].reduce[]>( - (acc, test) => { - acc.push({ - code: test.code.replace(/;/g, ''), - options: ['always'], - errors: test.errors.map(e => ({ - ...e, - ...missingSemicolon, - })), - }); - acc.push({ - code: test.code, - options: ['never'], - errors: test.errors.map(e => ({ - ...e, - ...extraSemicolon, - })), - }); - - return acc; + { + code: ` + do; while(a) + ;[1,2,3].forEach(doSomething) + `, + output: ` + do; while(a) + [1,2,3].forEach(doSomething) + `, + options: neverOptionWithoutContinuationChars, + errors: [extraSemicolon], + }, + { + code: ` + const f = () => {} + ;[1,2,3].forEach(doSomething) + `, + output: ` + const f = () => {} + [1,2,3].forEach(doSomething) + `, + options: neverOptionWithoutContinuationChars, + parserOptions: { ecmaVersion: 2015 }, + errors: [extraSemicolon], }, - [ + + ...[ { - code: 'if (foo) { bar() }', - options: ['always', { omitLastInOneLineBlock: false }] as Options, - errors: [missingSemicolon], + code: `declare function declareFn(): string;`, + errors: [ + { + line: 1, + }, + ], }, + + // https://github.com/typescript-eslint/typescript-eslint/issues/366 { - code: 'if (foo) { bar(); baz() }', - options: ['always', { omitLastInOneLineBlock: false }] as Options, - errors: [missingSemicolon], + code: 'export = Foo;', + errors: [ + { + line: 1, + }, + ], }, { - code: 'if (foo) { bar(); }', - options: ['always', { omitLastInOneLineBlock: true }] as Options, - errors: [extraSemicolon], + code: 'import f = require("f");', + errors: [ + { + line: 1, + }, + ], }, { - code: 'if (foo) { bar(); baz(); }', - options: ['always', { omitLastInOneLineBlock: true }] as Options, - errors: [extraSemicolon], + code: 'type Foo = {};', + errors: [ + { + line: 1, + }, + ], }, + // https://github.com/typescript-eslint/typescript-eslint/issues/409 { code: ` - import a from "a" - (function() { - // ... - })() - `, - options: [ - 'never', - { beforeStatementContinuationChars: 'always' }, - ] as Options, - errors: [missingSemicolon], +class Class { + prop: string; +} + `, + errors: [ + { + line: 3, + }, + ], }, { code: ` - import a from "a" - ;(function() { - // ... - })() - `, - options: neverOptionWithoutContinuationChars, - errors: [extraSemicolon], +abstract class AbsClass { + abstract prop: string; + abstract meth(): string; +} + `, + errors: [ + { + line: 3, + }, + { + line: 4, + }, + ], }, - { - code: 'for (;;){var i;}', - output: 'for (;;){var i}', - options: neverOption, + code: ` +class PanCamera extends FreeCamera { + public invertY: boolean = false; +} + `, errors: [ { - line: 1, + line: 3, }, ], }, + + // // ESLint { - code: 'for (;;) var i; ', - output: 'for (;;) var i ', - options: neverOption, + code: "throw new Error('foo');", + output: "throw new Error('foo')", errors: [ { line: 1, @@ -708,378 +785,280 @@ class PanCamera extends FreeCamera { ], }, { - code: 'for (var j;;) {var i;}', - output: 'for (var j;;) {var i}', - options: neverOption, + code: 'function foo() { return []; }', + output: 'function foo() { return [] }', errors: [ { line: 1, }, ], }, - { - code: 'for (;;){var i}', - output: 'for (;;){var i;}', - errors: [missingSemicolon], + code: 'while(true) { break; }', + output: 'while(true) { break }', + errors: [ + { + line: 1, + }, + ], }, { - code: 'for (;;) var i ', - output: 'for (;;) var i; ', - errors: [missingSemicolon], + code: 'while(true) { continue; }', + output: 'while(true) { continue }', + errors: [ + { + line: 1, + }, + ], }, { - code: 'for (var j;;) {var i}', - output: 'for (var j;;) {var i;}', - errors: [missingSemicolon], + code: 'let x = 5;', + output: 'let x = 5', + errors: [ + { + line: 1, + }, + ], }, { - code: 'var foo = {\n bar: baz\n}', - output: 'var foo = {\n bar: baz\n};', - errors: [missingSemicolon], + code: 'var x = 5;', + output: 'var x = 5', + errors: [ + { + line: 1, + }, + ], }, - { - code: 'if (foo) { bar()\n }', - output: 'if (foo) { bar();\n }', - options: ['always', { omitLastInOneLineBlock: true }], - errors: [missingSemicolon], + code: 'var x = 5, y;', + output: 'var x = 5, y', + errors: [ + { + line: 1, + }, + ], }, { - code: 'if (foo) {\n bar() }', - output: 'if (foo) {\n bar(); }', - options: ['always', { omitLastInOneLineBlock: true }], - errors: [missingSemicolon], + code: 'debugger;', + output: 'debugger', + errors: [ + { + line: 1, + }, + ], }, { - code: 'if (foo) {\n bar(); baz() }', - output: 'if (foo) {\n bar(); baz(); }', - options: ['always', { omitLastInOneLineBlock: true }], - errors: [missingSemicolon], + code: 'foo();', + output: 'foo()', + errors: [ + { + line: 1, + }, + ], }, { - code: 'if (foo) { bar(); }', - output: 'if (foo) { bar() }', - options: ['always', { omitLastInOneLineBlock: true }], - errors: [{ message: 'Extra semicolon.' }], + code: 'for (var a in b) var i; ', + output: 'for (var a in b) var i ', + errors: [ + { + line: 1, + }, + ], }, - - // https://github.com/eslint/eslint/issues/9521 { - code: ` - import a from "a" - [1,2,3].forEach(doSomething) - `, - output: ` - import a from "a"; - [1,2,3].forEach(doSomething) - `, - options: ['never', { beforeStatementContinuationChars: 'always' }], - - errors: ['Missing semicolon.'], + code: 'var foo = {\n bar: baz\n};', + output: 'var foo = {\n bar: baz\n}', + errors: [ + { + line: 3, + }, + ], }, { - code: ` - var a = 0; export {a} - [a] = b - `, - output: ` - var a = 0; export {a}; - [a] = b - `, - options: ['never', { beforeStatementContinuationChars: 'always' }], - - errors: ['Missing semicolon.'], + code: "import theDefault, { named1, named2 } from 'src/mylib';", + output: "import theDefault, { named1, named2 } from 'src/mylib'", + errors: [ + { + line: 1, + }, + ], }, { - code: ` - function wrap() { - return - ({a} = b) - } - `, - output: ` - function wrap() { - return; - ({a} = b) - } - `, - options: ['never', { beforeStatementContinuationChars: 'always' }], - parserOptions: { ecmaVersion: 2015 }, - errors: ['Missing semicolon.'], + code: 'do{}while(true);', + output: 'do{}while(true)', + errors: [ + { + line: 1, + }, + ], }, { - code: ` - while (true) { - break - +i - } - `, - output: ` - while (true) { - break; - +i - } - `, - options: ['never', { beforeStatementContinuationChars: 'always' }], - errors: ['Missing semicolon.'], + code: "import * as utils from './utils';", + output: "import * as utils from './utils'", + errors: [ + { + line: 1, + }, + ], }, { - code: ` - while (true) { - continue - [1,2,3].forEach(doSomething) - } - `, - output: ` - while (true) { - continue; - [1,2,3].forEach(doSomething) - } - `, - options: ['never', { beforeStatementContinuationChars: 'always' }], - errors: ['Missing semicolon.'], + code: "import { square, diag } from 'lib';", + output: "import { square, diag } from 'lib'", + errors: [ + { + line: 1, + }, + ], }, { - code: ` - do; while(a) - [1,2,3].forEach(doSomething) - `, - output: ` - do; while(a); - [1,2,3].forEach(doSomething) - `, - options: ['never', { beforeStatementContinuationChars: 'always' }], - errors: ['Missing semicolon.'], + code: "import { default as foo } from 'lib';", + output: "import { default as foo } from 'lib'", + errors: [ + { + line: 1, + }, + ], }, { - code: ` - const f = () => {} - [1,2,3].forEach(doSomething) - `, - output: ` - const f = () => {}; - [1,2,3].forEach(doSomething) - `, - options: ['never', { beforeStatementContinuationChars: 'always' }], - parserOptions: { ecmaVersion: 2015 }, - errors: ['Missing semicolon.'], + code: "import 'src/mylib';", + output: "import 'src/mylib'", + errors: [ + { + line: 1, + }, + ], }, { - code: ` - import a from "a"; - [1,2,3].forEach(doSomething) - `, - output: ` - import a from "a" - [1,2,3].forEach(doSomething) - `, - options: neverOptionWithoutContinuationChars, - - errors: [extraSemicolon], + code: 'var foo;\nvar bar;', + output: 'var foo\nvar bar', + errors: [ + { + line: 1, + }, + { + line: 2, + }, + ], }, - { - code: ` - var a = 0; export {a}; - [a] = b - `, - output: ` - var a = 0; export {a} - [a] = b - `, - options: neverOptionWithoutContinuationChars, - errors: [extraSemicolon], - }, - { - code: ` - function wrap() { - return; - ({a} = b) - } - `, - output: ` - function wrap() { - return - ({a} = b) - } - `, - options: neverOptionWithoutContinuationChars, - parserOptions: { ecmaVersion: 2015 }, - errors: [extraSemicolon], - }, - { - code: ` - while (true) { - break; - +i - } - `, - output: ` - while (true) { - break - +i - } - `, - options: neverOptionWithoutContinuationChars, - errors: [extraSemicolon], - }, + // exports, "never" { - code: ` - while (true) { - continue; - [1,2,3].forEach(doSomething) - } - `, - output: ` - while (true) { - continue - [1,2,3].forEach(doSomething) - } - `, - options: neverOptionWithoutContinuationChars, - errors: [extraSemicolon], + code: "export * from 'foo';", + output: "export * from 'foo'", + errors: [ + { + line: 1, + }, + ], }, { - code: ` - do; while(a); - [1,2,3].forEach(doSomething) - `, - output: ` - do; while(a) - [1,2,3].forEach(doSomething) - `, - options: neverOptionWithoutContinuationChars, - errors: [extraSemicolon], + code: "export { foo } from 'foo';", + output: "export { foo } from 'foo'", + errors: [ + { + line: 1, + }, + ], }, { - code: ` - const f = () => {}; - [1,2,3].forEach(doSomething) - `, - output: ` - const f = () => {} - [1,2,3].forEach(doSomething) - `, - options: neverOptionWithoutContinuationChars, - parserOptions: { ecmaVersion: 2015 }, - errors: [extraSemicolon], + code: 'var foo = 0;\nexport { foo };', + output: 'var foo = 0\nexport { foo }', + errors: [ + { + line: 1, + }, + { + line: 2, + }, + ], }, { - code: ` - import a from "a" - ;[1,2,3].forEach(doSomething) - `, - output: ` - import a from "a" - [1,2,3].forEach(doSomething) - `, - options: neverOptionWithoutContinuationChars, - - errors: [extraSemicolon], + code: 'export var foo;', + output: 'export var foo', + errors: [ + { + line: 1, + }, + ], }, { - code: ` - var a = 0; export {a} - ;[1,2,3].forEach(doSomething) - `, - output: ` - var a = 0; export {a} - [1,2,3].forEach(doSomething) - `, - options: neverOptionWithoutContinuationChars, - - errors: [extraSemicolon], + code: 'export let foo;', + output: 'export let foo', + errors: [ + { + line: 1, + }, + ], }, { - code: ` - function wrap() { - return - ;[1,2,3].forEach(doSomething) - } - `, - output: ` - function wrap() { - return - [1,2,3].forEach(doSomething) - } - `, - options: neverOptionWithoutContinuationChars, - errors: [extraSemicolon], + code: 'export const FOO = 42;', + output: 'export const FOO = 42', + errors: [ + { + line: 1, + }, + ], }, { - code: ` - while (true) { - break - ;[1,2,3].forEach(doSomething) - } - `, - output: ` - while (true) { - break - [1,2,3].forEach(doSomething) - } - `, - options: neverOptionWithoutContinuationChars, - errors: [extraSemicolon], + code: 'export default foo || bar;', + output: 'export default foo || bar', + errors: [ + { + line: 1, + }, + ], }, { - code: ` - while (true) { - continue - ;[1,2,3].forEach(doSomething) - } - `, - output: ` - while (true) { - continue - [1,2,3].forEach(doSomething) - } - `, - options: neverOptionWithoutContinuationChars, - errors: [extraSemicolon], + code: 'export default (foo) => foo.bar();', + output: 'export default (foo) => foo.bar()', + errors: [ + { + line: 1, + }, + ], }, { - code: ` - do; while(a) - ;[1,2,3].forEach(doSomething) - `, - output: ` - do; while(a) - [1,2,3].forEach(doSomething) - `, - options: neverOptionWithoutContinuationChars, - errors: [extraSemicolon], + code: 'export default foo = 42;', + output: 'export default foo = 42', + errors: [ + { + line: 1, + }, + ], }, { - code: ` - const f = () => {} - ;[1,2,3].forEach(doSomething) - `, - output: ` - const f = () => {} - [1,2,3].forEach(doSomething) - `, - options: neverOptionWithoutContinuationChars, - parserOptions: { ecmaVersion: 2015 }, - errors: [extraSemicolon], + code: 'a;\n++b;', + output: 'a\n++b;', + errors: [ + { + line: 1, + }, + { + line: 2, + }, + ], }, + ].reduce[]>((acc, test) => { + acc.push({ + code: test.code.replace(/;/g, ''), + output: test.code, + options: ['always'], + errors: test.errors.map(e => ({ + ...e, + ...missingSemicolon, + })), + }); + acc.push({ + code: test.code, + output: test.output ?? test.code.replace(/;/g, ''), + options: ['never'], + errors: test.errors.map(e => ({ + ...e, + ...extraSemicolon, + })), + }); - // https://github.com/eslint/eslint/issues/7928 - { - code: [ - '/*eslint no-extra-semi: error */', - 'foo();', - ';[0,1,2].forEach(bar)', - ].join('\n'), - output: [ - '/*eslint no-extra-semi: error */', - 'foo()', - ';[0,1,2].forEach(bar)', - ].join('\n'), - options: neverOption, - errors: ['Extra semicolon.', 'Unnecessary semicolon.'], - }, - ], - ), + return acc; + }, []), + ], }); diff --git a/packages/eslint-plugin/tests/rules/space-before-function-paren.test.ts b/packages/eslint-plugin/tests/rules/space-before-function-paren.test.ts index eb515c1617c..944ea672f1f 100644 --- a/packages/eslint-plugin/tests/rules/space-before-function-paren.test.ts +++ b/packages/eslint-plugin/tests/rules/space-before-function-paren.test.ts @@ -3,14 +3,8 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ -import { - TSESLint, - AST_NODE_TYPES, -} from '@typescript-eslint/experimental-utils'; -import rule, { - MessageIds, - Options, -} from '../../src/rules/space-before-function-paren'; +import { AST_NODE_TYPES } from '@typescript-eslint/experimental-utils'; +import rule from '../../src/rules/space-before-function-paren'; import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ @@ -189,7 +183,7 @@ ruleTester.run('space-before-function-paren', rule, { type: AST_NODE_TYPES.FunctionDeclaration, messageId: 'missing', line: 1, - column: 13, + column: 18, }, ], }, @@ -534,14 +528,14 @@ ruleTester.run('space-before-function-paren', rule, { output: 'async () => 1', options: [{ asyncArrow: 'always' }], parserOptions: { ecmaVersion: 8 }, - errors: ['Missing space before function parentheses.'], + errors: [{ messageId: 'missing' }], }, { code: 'async () => 1', output: 'async() => 1', options: [{ asyncArrow: 'never' }], parserOptions: { ecmaVersion: 8 }, - errors: ['Unexpected space before function parentheses.'], + errors: [{ messageId: 'unexpected' }], }, { code: 'async() => 1', @@ -578,5 +572,5 @@ ruleTester.run('space-before-function-paren', rule, { }, ], }, - ] as TSESLint.InvalidTestCase[], + ], }); diff --git a/packages/eslint-plugin/tools/generate-configs.ts b/packages/eslint-plugin/tools/generate-configs.ts index 6ef602cc881..6830d266e99 100644 --- a/packages/eslint-plugin/tools/generate-configs.ts +++ b/packages/eslint-plugin/tools/generate-configs.ts @@ -39,9 +39,10 @@ const BASE_RULES_TO_BE_OVERRIDDEN = new Map( ); const EXTENDS = ['./configs/base', './configs/eslint-recommended']; -const ruleEntries = Object.entries(rules).sort((a, b) => - a[0].localeCompare(b[0]), -); +const ruleEntries: [ + string, + TSESLint.RuleModule, +][] = Object.entries(rules).sort((a, b) => a[0].localeCompare(b[0])); /** * Helper function reduces records to key - value pairs. diff --git a/packages/eslint-plugin/typings/eslint-rules.d.ts b/packages/eslint-plugin/typings/eslint-rules.d.ts index b32a895404d..c27e620399e 100644 --- a/packages/eslint-plugin/typings/eslint-rules.d.ts +++ b/packages/eslint-plugin/typings/eslint-rules.d.ts @@ -273,7 +273,11 @@ declare module 'eslint/lib/rules/no-implicit-globals' { import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils'; const rule: TSESLint.RuleModule< - never, + | 'globalNonLexicalBinding' + | 'globalLexicalBinding' + | 'globalVariableLeak' + | 'assignmentToReadonlyGlobal' + | 'redeclarationOfReadonlyGlobal', [], { Program(node: TSESTree.Program): void; @@ -326,7 +330,7 @@ declare module 'eslint/lib/rules/no-restricted-globals' { import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils'; const rule: TSESLint.RuleModule< - never, + 'defaultMessage' | 'customMessage', ( | string | { @@ -345,7 +349,7 @@ declare module 'eslint/lib/rules/no-shadow' { import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils'; const rule: TSESLint.RuleModule< - never, + 'noShadow', [ { builtinGlobals?: boolean; @@ -381,7 +385,7 @@ declare module 'eslint/lib/rules/no-unused-vars' { import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils'; const rule: TSESLint.RuleModule< - never, + 'unusedVar', ( | 'all' | 'local' @@ -427,7 +431,7 @@ declare module 'eslint/lib/rules/no-use-before-define' { import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils'; const rule: TSESLint.RuleModule< - never, + 'usedBeforeDefine', ( | 'nofunc' | { @@ -469,7 +473,7 @@ declare module 'eslint/lib/rules/no-useless-constructor' { import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils'; const rule: TSESLint.RuleModule< - never, + 'noUselessConstructor', [], { MethodDefinition(node: TSESTree.MethodDefinition): void; @@ -535,7 +539,7 @@ declare module 'eslint/lib/rules/semi' { import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils'; const rule: TSESLint.RuleModule< - never, + 'missingSemi' | 'extraSemi', [ 'always' | 'never', { @@ -565,7 +569,7 @@ declare module 'eslint/lib/rules/quotes' { import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils'; const rule: TSESLint.RuleModule< - never, + 'wrongQuotes', [ 'single' | 'double' | 'backtick', { @@ -664,7 +668,7 @@ declare module 'eslint/lib/rules/no-invalid-this' { import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils'; const rule: TSESLint.RuleModule< - never, + 'unexpectedThis', [ { capIsConstructor?: boolean; diff --git a/packages/experimental-utils/src/eslint-utils/RuleTester.ts b/packages/experimental-utils/src/eslint-utils/RuleTester.ts index 07b3a4cf0cf..ed642c035ba 100644 --- a/packages/experimental-utils/src/eslint-utils/RuleTester.ts +++ b/packages/experimental-utils/src/eslint-utils/RuleTester.ts @@ -14,6 +14,11 @@ class RuleTester extends TSESLint.RuleTester { constructor(private readonly options: RuleTesterConfig) { super({ ...options, + parserOptions: { + ...options.parserOptions, + warnOnUnsupportedTypeScriptVersion: + options.parserOptions?.warnOnUnsupportedTypeScriptVersion ?? false, + }, parser: require.resolve(options.parser), }); diff --git a/packages/parser/package.json b/packages/parser/package.json index 630a0a61d14..3131dabaaf9 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -39,7 +39,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0" + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" }, "dependencies": { "@types/eslint-visitor-keys": "^1.0.0", diff --git a/tests/integration/fixtures/markdown/.eslintrc.js b/tests/integration/fixtures/markdown/.eslintrc.js new file mode 100644 index 00000000000..e248633774a --- /dev/null +++ b/tests/integration/fixtures/markdown/.eslintrc.js @@ -0,0 +1,25 @@ +module.exports = { + root: true, + // Local version of @typescript-eslint/parser + parser: '@typescript-eslint/parser', + env: { + es6: true, + node: true, + }, + parserOptions: { + sourceType: 'module', + extraFileExtensions: ['.vue'], + ecmaFeatures: { + jsx: true, + }, + }, + plugins: [ + 'markdown', + // Local version of @typescript-eslint/eslint-plugin + '@typescript-eslint', + ], + rules: { + '@typescript-eslint/no-explicit-any': 'error', + 'no-console': 'error', + }, +}; diff --git a/tests/integration/fixtures/markdown/.eslintrc.yml b/tests/integration/fixtures/markdown/.eslintrc.yml deleted file mode 100644 index 92575183cd9..00000000000 --- a/tests/integration/fixtures/markdown/.eslintrc.yml +++ /dev/null @@ -1,23 +0,0 @@ -root: true - -# Local version of @typescript-eslint/parser -parser: '@typescript-eslint/parser' - -env: - es6: true - node: true - -parserOptions: - sourceType: module - extraFileExtensions: ['.vue'] - ecmaFeatures: - jsx: true - -plugins: -- 'markdown' -# Local version of @typescript-eslint/eslint-plugin -- '@typescript-eslint' - -rules: - '@typescript-eslint/no-explicit-any': 'error' - 'no-console': 'error' diff --git a/tests/integration/fixtures/markdown/Dockerfile b/tests/integration/fixtures/markdown/Dockerfile index 3b281e624c8..027ff085a6c 100644 --- a/tests/integration/fixtures/markdown/Dockerfile +++ b/tests/integration/fixtures/markdown/Dockerfile @@ -1,4 +1,4 @@ -FROM node:carbon +FROM node:erbium # Copy the test.sh into the container. Every other file will be linked, rather # than copied to allow for changes without rebuilds wherever possible diff --git a/tests/integration/fixtures/markdown/test.js.snap b/tests/integration/fixtures/markdown/test.js.snap deleted file mode 100644 index 5f28d2474ea..00000000000 --- a/tests/integration/fixtures/markdown/test.js.snap +++ /dev/null @@ -1,293 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`it should produce the expected lint ouput 1`] = ` -Array [ - Object { - "errorCount": 10, - "filePath": "/usr/linked/Doc.md", - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "messages": Array [ - Object { - "column": 3, - "endColumn": 14, - "endLine": 8, - "line": 8, - "message": "Unexpected console statement.", - "messageId": "unexpected", - "nodeType": "MemberExpression", - "ruleId": "no-console", - "severity": 2, - }, - Object { - "column": 20, - "endColumn": 23, - "endLine": 26, - "line": 26, - "message": "Unexpected any. Specify a different type.", - "messageId": "unexpectedAny", - "nodeType": "TSAnyKeyword", - "ruleId": "@typescript-eslint/no-explicit-any", - "severity": 2, - "suggestions": Array [ - Object { - "desc": "Use \`unknown\` instead, this will force you to explicitly, and safely assert the type is correct.", - "fix": Object { - "range": Array [ - 51, - 54, - ], - "text": "unknown", - }, - "messageId": "suggestUnknown", - }, - Object { - "desc": "Use \`never\` instead, this is useful when instantiating generic type parameters that you don't need to know the type of.", - "fix": Object { - "range": Array [ - 51, - 54, - ], - "text": "never", - }, - "messageId": "suggestNever", - }, - ], - }, - Object { - "column": 3, - "endColumn": 14, - "endLine": 27, - "line": 27, - "message": "Unexpected console statement.", - "messageId": "unexpected", - "nodeType": "MemberExpression", - "ruleId": "no-console", - "severity": 2, - }, - Object { - "column": 3, - "endColumn": 14, - "endLine": 43, - "line": 43, - "message": "Unexpected console statement.", - "messageId": "unexpected", - "nodeType": "MemberExpression", - "ruleId": "no-console", - "severity": 2, - }, - Object { - "column": 17, - "endColumn": 20, - "endLine": 50, - "line": 50, - "message": "Unexpected any. Specify a different type.", - "messageId": "unexpectedAny", - "nodeType": "TSAnyKeyword", - "ruleId": "@typescript-eslint/no-explicit-any", - "severity": 2, - "suggestions": Array [ - Object { - "desc": "Use \`unknown\` instead, this will force you to explicitly, and safely assert the type is correct.", - "fix": Object { - "range": Array [ - 16, - 19, - ], - "text": "unknown", - }, - "messageId": "suggestUnknown", - }, - Object { - "desc": "Use \`never\` instead, this is useful when instantiating generic type parameters that you don't need to know the type of.", - "fix": Object { - "range": Array [ - 16, - 19, - ], - "text": "never", - }, - "messageId": "suggestNever", - }, - ], - }, - Object { - "column": 3, - "endColumn": 14, - "endLine": 51, - "line": 51, - "message": "Unexpected console statement.", - "messageId": "unexpected", - "nodeType": "MemberExpression", - "ruleId": "no-console", - "severity": 2, - }, - Object { - "column": 17, - "endColumn": 20, - "endLine": 59, - "line": 59, - "message": "Unexpected any. Specify a different type.", - "messageId": "unexpectedAny", - "nodeType": "TSAnyKeyword", - "ruleId": "@typescript-eslint/no-explicit-any", - "severity": 2, - "suggestions": Array [ - Object { - "desc": "Use \`unknown\` instead, this will force you to explicitly, and safely assert the type is correct.", - "fix": Object { - "range": Array [ - 16, - 19, - ], - "text": "unknown", - }, - "messageId": "suggestUnknown", - }, - Object { - "desc": "Use \`never\` instead, this is useful when instantiating generic type parameters that you don't need to know the type of.", - "fix": Object { - "range": Array [ - 16, - 19, - ], - "text": "never", - }, - "messageId": "suggestNever", - }, - ], - }, - Object { - "column": 3, - "endColumn": 14, - "endLine": 60, - "line": 60, - "message": "Unexpected console statement.", - "messageId": "unexpected", - "nodeType": "MemberExpression", - "ruleId": "no-console", - "severity": 2, - }, - Object { - "column": 17, - "endColumn": 20, - "endLine": 68, - "line": 68, - "message": "Unexpected any. Specify a different type.", - "messageId": "unexpectedAny", - "nodeType": "TSAnyKeyword", - "ruleId": "@typescript-eslint/no-explicit-any", - "severity": 2, - "suggestions": Array [ - Object { - "desc": "Use \`unknown\` instead, this will force you to explicitly, and safely assert the type is correct.", - "fix": Object { - "range": Array [ - 16, - 19, - ], - "text": "unknown", - }, - "messageId": "suggestUnknown", - }, - Object { - "desc": "Use \`never\` instead, this is useful when instantiating generic type parameters that you don't need to know the type of.", - "fix": Object { - "range": Array [ - 16, - 19, - ], - "text": "never", - }, - "messageId": "suggestNever", - }, - ], - }, - Object { - "column": 3, - "endColumn": 14, - "endLine": 69, - "line": 69, - "message": "Unexpected console statement.", - "messageId": "unexpected", - "nodeType": "MemberExpression", - "ruleId": "no-console", - "severity": 2, - }, - ], - "source": "Some extra text to verify that the markdown plugin is ignoring anything that is not a code block. - -expected no-console error: -\`\`\`jsx -import { Button } from 'antd'; - -function MyComp() { - console.log('test'); - return ( -
- - - - - -
- ); -} -\`\`\` - -expected no-explicit-any error: -expected no-console error: -\`\`\`jsx -import { Button } from 'antd'; - -function MyComp(): any { - console.log('test'); - return ( -
- - - - - -
- ); -} -\`\`\` - -expected no-console error: -\`\`\`js -function foo() { - console.log('test'); -} -\`\`\` - -expected no-explicit-any error: -expected no-console error: -\`\`\`js -function foo(): any { - console.log('test'); -} -\`\`\` - - -expected no-explicit-any error: -expected no-console error: -\`\`\`javascript -function foo(): any { - console.log('test'); -} -\`\`\` - - -expected no-explicit-any error: -expected no-console error: -\`\`\`node -function foo(): any { - console.log('test'); -} -\`\`\` -", - "warningCount": 0, - }, -] -`; diff --git a/tests/integration/fixtures/markdown/test.sh b/tests/integration/fixtures/markdown/test.sh index 6856a3f7c1b..356156f60f7 100755 --- a/tests/integration/fixtures/markdown/test.sh +++ b/tests/integration/fixtures/markdown/test.sh @@ -17,7 +17,7 @@ npm install eslint-plugin-markdown@latest # Run the linting # (the "|| true" helps make sure that we run our tests on failed linting runs as well) -npx eslint --format json --output-file /usr/lint-output.json --config /usr/linked/.eslintrc.yml /usr/linked/**/*.md || true +npx eslint --format json --output-file /usr/lint-output.json --config /usr/linked/.eslintrc.js /usr/linked/**/*.md || true # Run our assertions against the linting output npx jest /usr/test.js --snapshotResolver=/usr/utils/jest-snapshot-resolver.js diff --git a/tests/integration/fixtures/recommended-does-not-require-program/.eslintrc.js b/tests/integration/fixtures/recommended-does-not-require-program/.eslintrc.js new file mode 100644 index 00000000000..85a83dc6e91 --- /dev/null +++ b/tests/integration/fixtures/recommended-does-not-require-program/.eslintrc.js @@ -0,0 +1,18 @@ +// This integration test exists to make sure that the recommended config does +// not require a program to be specified to ensure a fast and simple initial +// setup. Users can add on one of our other configs if they want to opt in to +// more expensive checks. +module.exports = { + root: true, + // Local version of @typescript-eslint/parser + parser: '@typescript-eslint/parser', + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/eslint-recommended', + 'plugin:@typescript-eslint/recommended', + ], + plugins: [ + // Local version of @typescript-eslint/eslint-plugin + '@typescript-eslint', + ], +}; diff --git a/tests/integration/fixtures/recommended-does-not-require-program/.eslintrc.yml b/tests/integration/fixtures/recommended-does-not-require-program/.eslintrc.yml deleted file mode 100644 index 75de006c68d..00000000000 --- a/tests/integration/fixtures/recommended-does-not-require-program/.eslintrc.yml +++ /dev/null @@ -1,17 +0,0 @@ -# This integration test exists to make sure that the recommended config does -# not require a program to be specified to ensure a fast and simple initial -# setup. Users can add on one of our other configs if they want to opt in to -# more expensive checks. -root: true - -# Local version of @typescript-eslint/parser -parser: '@typescript-eslint/parser' - -extends: -- 'eslint:recommended' -- 'plugin:@typescript-eslint/eslint-recommended' -- 'plugin:@typescript-eslint/recommended' - -plugins: -# Local version of @typescript-eslint/eslint-plugin -- '@typescript-eslint' diff --git a/tests/integration/fixtures/recommended-does-not-require-program/Dockerfile b/tests/integration/fixtures/recommended-does-not-require-program/Dockerfile index 3b281e624c8..027ff085a6c 100644 --- a/tests/integration/fixtures/recommended-does-not-require-program/Dockerfile +++ b/tests/integration/fixtures/recommended-does-not-require-program/Dockerfile @@ -1,4 +1,4 @@ -FROM node:carbon +FROM node:erbium # Copy the test.sh into the container. Every other file will be linked, rather # than copied to allow for changes without rebuilds wherever possible diff --git a/tests/integration/fixtures/recommended-does-not-require-program/test.js.snap b/tests/integration/fixtures/recommended-does-not-require-program/test.js.snap deleted file mode 100644 index 36d059733d5..00000000000 --- a/tests/integration/fixtures/recommended-does-not-require-program/test.js.snap +++ /dev/null @@ -1,44 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`it should produce the expected lint ouput 1`] = ` -Array [ - Object { - "errorCount": 1, - "filePath": "/usr/linked/index.ts", - "fixableErrorCount": 1, - "fixableWarningCount": 0, - "messages": Array [ - Object { - "column": 1, - "endColumn": 15, - "endLine": 1, - "fix": Object { - "range": Array [ - 0, - 3, - ], - "text": "let", - }, - "line": 1, - "message": "Unexpected var, use let or const instead.", - "nodeType": "VariableDeclaration", - "ruleId": "no-var", - "severity": 2, - }, - Object { - "column": 5, - "endColumn": 8, - "endLine": 1, - "line": 1, - "message": "'foo' is assigned a value but never used.", - "nodeType": "Identifier", - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 1, - }, - ], - "source": "var foo = true -", - "warningCount": 1, - }, -] -`; diff --git a/tests/integration/fixtures/recommended-does-not-require-program/test.sh b/tests/integration/fixtures/recommended-does-not-require-program/test.sh index 4cf1ad5505e..9abb264733d 100755 --- a/tests/integration/fixtures/recommended-does-not-require-program/test.sh +++ b/tests/integration/fixtures/recommended-does-not-require-program/test.sh @@ -14,7 +14,7 @@ npm install $(npm pack /usr/eslint-plugin | tail -1) # Run the linting # (the "|| true" helps make sure that we run our tests on failed linting runs as well) -npx eslint --format json --output-file /usr/lint-output.json --config /usr/linked/.eslintrc.yml /usr/linked/**/*.ts || true +npx eslint --format json --output-file /usr/lint-output.json --config /usr/linked/.eslintrc.js /usr/linked/**/*.ts || true # Run our assertions against the linting output npx jest /usr/test.js --snapshotResolver=/usr/utils/jest-snapshot-resolver.js diff --git a/tests/integration/fixtures/typescript-and-tslint-plugins-together/.eslintrc.js b/tests/integration/fixtures/typescript-and-tslint-plugins-together/.eslintrc.js new file mode 100644 index 00000000000..3caad1ed427 --- /dev/null +++ b/tests/integration/fixtures/typescript-and-tslint-plugins-together/.eslintrc.js @@ -0,0 +1,38 @@ +module.exports = { + "root": true, + // Local version of @typescript-eslint/parser + "parser": "@typescript-eslint/parser", + "plugins": [ + // Local version of @typescript-eslint/eslint-plugin + "@typescript-eslint", + // Local version of @typescript-eslint/eslint-plugin-tslint + "@typescript-eslint/tslint" + ], + "env": { + "es6": true, + "node": true + }, + "extends": [ + "plugin:@typescript-eslint/recommended" + ], + "parserOptions": { + "sourceType": "module", + "ecmaFeatures": { + "jsx": false + }, + "project": "/usr/linked/tsconfig.json" + }, + "rules": { + "@typescript-eslint/tslint/config": [ + "error", + { + "rules": { + "semicolon": [ + true, + "always" + ] + } + } + ] + } +} diff --git a/tests/integration/fixtures/typescript-and-tslint-plugins-together/.eslintrc.yml b/tests/integration/fixtures/typescript-and-tslint-plugins-together/.eslintrc.yml deleted file mode 100644 index 1e7fd888874..00000000000 --- a/tests/integration/fixtures/typescript-and-tslint-plugins-together/.eslintrc.yml +++ /dev/null @@ -1,25 +0,0 @@ -root: true - -# Local version of @typescript-eslint/parser -parser: '@typescript-eslint/parser' - -plugins: -# Local version of @typescript-eslint/eslint-plugin -- '@typescript-eslint' -# Local version of @typescript-eslint/eslint-plugin-tslint -- '@typescript-eslint/tslint' -env: - es6: true - node: true -extends: -- plugin:@typescript-eslint/recommended -parserOptions: - sourceType: module - ecmaFeatures: - jsx: false - project: /usr/linked/tsconfig.json -rules: - '@typescript-eslint/tslint/config': - - error - - rules: - semicolon: [true, 'always'] diff --git a/tests/integration/fixtures/typescript-and-tslint-plugins-together/Dockerfile b/tests/integration/fixtures/typescript-and-tslint-plugins-together/Dockerfile index 3b281e624c8..027ff085a6c 100644 --- a/tests/integration/fixtures/typescript-and-tslint-plugins-together/Dockerfile +++ b/tests/integration/fixtures/typescript-and-tslint-plugins-together/Dockerfile @@ -1,4 +1,4 @@ -FROM node:carbon +FROM node:erbium # Copy the test.sh into the container. Every other file will be linked, rather # than copied to allow for changes without rebuilds wherever possible diff --git a/tests/integration/fixtures/typescript-and-tslint-plugins-together/test.js.snap b/tests/integration/fixtures/typescript-and-tslint-plugins-together/test.js.snap index e567daaa2f5..26482bf124b 100644 --- a/tests/integration/fixtures/typescript-and-tslint-plugins-together/test.js.snap +++ b/tests/integration/fixtures/typescript-and-tslint-plugins-together/test.js.snap @@ -14,6 +14,7 @@ Array [ "endLine": 1, "line": 1, "message": "'noSemi' is assigned a value but never used.", + "messageId": "unusedVar", "nodeType": "Identifier", "ruleId": "@typescript-eslint/no-unused-vars", "severity": 1, @@ -39,6 +40,7 @@ Array [ ], "source": "const noSemi = true ", + "usedDeprecatedRules": Array [], "warningCount": 1, }, ] diff --git a/tests/integration/fixtures/typescript-and-tslint-plugins-together/test.sh b/tests/integration/fixtures/typescript-and-tslint-plugins-together/test.sh index 4746867a40a..b634d531d5e 100755 --- a/tests/integration/fixtures/typescript-and-tslint-plugins-together/test.sh +++ b/tests/integration/fixtures/typescript-and-tslint-plugins-together/test.sh @@ -15,7 +15,7 @@ npm install $(npm pack /usr/eslint-plugin | tail -1) # Run the linting # (the "|| true" helps make sure that we run our tests on failed linting runs as well) -npx eslint --format json --output-file /usr/lint-output.json --config /usr/linked/.eslintrc.yml /usr/linked/**/*.ts || true +npx eslint --format json --output-file /usr/lint-output.json --config /usr/linked/.eslintrc.js /usr/linked/**/*.ts || true # Run our assertions against the linting output npx jest /usr/test.js --snapshotResolver=/usr/utils/jest-snapshot-resolver.js diff --git a/tests/integration/fixtures/vue-jsx/.eslintrc.js b/tests/integration/fixtures/vue-jsx/.eslintrc.js new file mode 100644 index 00000000000..c9d88fd01e9 --- /dev/null +++ b/tests/integration/fixtures/vue-jsx/.eslintrc.js @@ -0,0 +1,27 @@ +module.exports = { + root: true, + parser: 'vue-eslint-parser', + env: { + es6: true, + node: true, + }, + extends: [ + 'plugin:vue/essential', + ], + parserOptions: { + // Local version of @typescript-eslint/parser + parser: '@typescript-eslint/parser', + sourceType: 'module', + extraFileExtensions: ['.vue'], + ecmaFeatures: { + jsx: true, + }, + }, + plugins: [ + // Local version of @typescript-eslint/eslint-plugin + '@typescript-eslint', + ], + rules: { + '@typescript-eslint/no-explicit-any': 'error', + }, +}; diff --git a/tests/integration/fixtures/vue-jsx/.eslintrc.yml b/tests/integration/fixtures/vue-jsx/.eslintrc.yml deleted file mode 100644 index ea4319ac718..00000000000 --- a/tests/integration/fixtures/vue-jsx/.eslintrc.yml +++ /dev/null @@ -1,25 +0,0 @@ -root: true - -parser: 'vue-eslint-parser' - -env: - es6: true - node: true - -extends: - plugin:vue/essential - -parserOptions: - # Local version of @typescript-eslint/parser - parser: '@typescript-eslint/parser' - sourceType: module - extraFileExtensions: ['.vue'] - ecmaFeatures: - jsx: true - -plugins: -# Local version of @typescript-eslint/eslint-plugin -- '@typescript-eslint' - -rules: - '@typescript-eslint/no-explicit-any': 'error' diff --git a/tests/integration/fixtures/vue-jsx/Dockerfile b/tests/integration/fixtures/vue-jsx/Dockerfile index 3b281e624c8..027ff085a6c 100644 --- a/tests/integration/fixtures/vue-jsx/Dockerfile +++ b/tests/integration/fixtures/vue-jsx/Dockerfile @@ -1,4 +1,4 @@ -FROM node:carbon +FROM node:erbium # Copy the test.sh into the container. Every other file will be linked, rather # than copied to allow for changes without rebuilds wherever possible diff --git a/tests/integration/fixtures/vue-jsx/test.js.snap b/tests/integration/fixtures/vue-jsx/test.js.snap deleted file mode 100644 index e0fbff509d4..00000000000 --- a/tests/integration/fixtures/vue-jsx/test.js.snap +++ /dev/null @@ -1,87 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`it should produce the expected lint ouput 1`] = ` -Array [ - Object { - "errorCount": 1, - "filePath": "/usr/linked/Jsx.vue", - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "messages": Array [ - Object { - "column": 17, - "endColumn": 20, - "endLine": 17, - "line": 17, - "message": "Unexpected any. Specify a different type.", - "messageId": "unexpectedAny", - "nodeType": "TSAnyKeyword", - "ruleId": "@typescript-eslint/no-explicit-any", - "severity": 2, - "suggestions": Array [ - Object { - "desc": "Use \`unknown\` instead, this will force you to explicitly, and safely assert the type is correct.", - "fix": Object { - "range": Array [ - 390, - 393, - ], - "text": "unknown", - }, - "messageId": "suggestUnknown", - }, - Object { - "desc": "Use \`never\` instead, this is useful when instantiating generic type parameters that you don't need to know the type of.", - "fix": Object { - "range": Array [ - 390, - 393, - ], - "text": "never", - }, - "messageId": "suggestNever", - }, - ], - }, - ], - "source": " -", - "warningCount": 0, - }, -] -`; diff --git a/tests/integration/fixtures/vue-jsx/test.sh b/tests/integration/fixtures/vue-jsx/test.sh index 30ec8940d3c..a484c2625e7 100755 --- a/tests/integration/fixtures/vue-jsx/test.sh +++ b/tests/integration/fixtures/vue-jsx/test.sh @@ -24,7 +24,7 @@ npm install vue-property-decorator@latest # Run the linting # (the "|| true" helps make sure that we run our tests on failed linting runs as well) -npx eslint --format json --output-file /usr/lint-output.json --config /usr/linked/.eslintrc.yml /usr/linked/**/*.vue || true +npx eslint --format json --output-file /usr/lint-output.json --config /usr/linked/.eslintrc.js /usr/linked/**/*.vue || true # Run our assertions against the linting output npx jest /usr/test.js --snapshotResolver=/usr/utils/jest-snapshot-resolver.js diff --git a/tests/integration/fixtures/vue-sfc/.eslintrc.js b/tests/integration/fixtures/vue-sfc/.eslintrc.js new file mode 100644 index 00000000000..7be44347c59 --- /dev/null +++ b/tests/integration/fixtures/vue-sfc/.eslintrc.js @@ -0,0 +1,25 @@ +module.exports = { + root: true, + parser: 'vue-eslint-parser', + env: { + es6: true, + node: true, + }, + extends: [ + 'plugin:vue/essential', + ], + parserOptions: { + // Local version of @typescript-eslint/parser + parser: '@typescript-eslint/parser', + project: '/usr/linked/tsconfig.json', + sourceType: 'module', + extraFileExtensions: ['.vue'], + }, + plugins: [ + // Local version of @typescript-eslint/eslint-plugin + '@typescript-eslint', + ], + rules: { + '@typescript-eslint/no-explicit-any': 'error', + }, +}; diff --git a/tests/integration/fixtures/vue-sfc/.eslintrc.yml b/tests/integration/fixtures/vue-sfc/.eslintrc.yml deleted file mode 100644 index 7b9b183b59b..00000000000 --- a/tests/integration/fixtures/vue-sfc/.eslintrc.yml +++ /dev/null @@ -1,24 +0,0 @@ -root: true - -parser: 'vue-eslint-parser' - -env: - es6: true - node: true - -extends: - plugin:vue/essential - -parserOptions: - # Local version of @typescript-eslint/parser - parser: '@typescript-eslint/parser' - project: /usr/linked/tsconfig.json - sourceType: module - extraFileExtensions: ['.vue'] - -plugins: -# Local version of @typescript-eslint/eslint-plugin -- '@typescript-eslint' - -rules: - '@typescript-eslint/no-explicit-any': 'error' diff --git a/tests/integration/fixtures/vue-sfc/Dockerfile b/tests/integration/fixtures/vue-sfc/Dockerfile index 3b281e624c8..027ff085a6c 100644 --- a/tests/integration/fixtures/vue-sfc/Dockerfile +++ b/tests/integration/fixtures/vue-sfc/Dockerfile @@ -1,4 +1,4 @@ -FROM node:carbon +FROM node:erbium # Copy the test.sh into the container. Every other file will be linked, rather # than copied to allow for changes without rebuilds wherever possible diff --git a/tests/integration/fixtures/vue-sfc/test.js.snap b/tests/integration/fixtures/vue-sfc/test.js.snap deleted file mode 100644 index 37b5cb943cf..00000000000 --- a/tests/integration/fixtures/vue-sfc/test.js.snap +++ /dev/null @@ -1,95 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`it should produce the expected lint ouput 1`] = ` -Array [ - Object { - "errorCount": 1, - "filePath": "/usr/linked/Hello.vue", - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "messages": Array [ - Object { - "column": 29, - "endColumn": 32, - "endLine": 31, - "line": 31, - "message": "Unexpected any. Specify a different type.", - "messageId": "unexpectedAny", - "nodeType": "TSAnyKeyword", - "ruleId": "@typescript-eslint/no-explicit-any", - "severity": 2, - "suggestions": Array [ - Object { - "desc": "Use \`unknown\` instead, this will force you to explicitly, and safely assert the type is correct.", - "fix": Object { - "range": Array [ - 708, - 711, - ], - "text": "unknown", - }, - "messageId": "suggestUnknown", - }, - Object { - "desc": "Use \`never\` instead, this is useful when instantiating generic type parameters that you don't need to know the type of.", - "fix": Object { - "range": Array [ - 708, - 711, - ], - "text": "never", - }, - "messageId": "suggestNever", - }, - ], - }, - ], - "source": " - - - -", - "warningCount": 0, - }, - Object { - "errorCount": 0, - "filePath": "/usr/linked/World.vue", - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "messages": Array [], - "warningCount": 0, - }, -] -`; diff --git a/tests/integration/fixtures/vue-sfc/test.sh b/tests/integration/fixtures/vue-sfc/test.sh index 30ec8940d3c..a484c2625e7 100755 --- a/tests/integration/fixtures/vue-sfc/test.sh +++ b/tests/integration/fixtures/vue-sfc/test.sh @@ -24,7 +24,7 @@ npm install vue-property-decorator@latest # Run the linting # (the "|| true" helps make sure that we run our tests on failed linting runs as well) -npx eslint --format json --output-file /usr/lint-output.json --config /usr/linked/.eslintrc.yml /usr/linked/**/*.vue || true +npx eslint --format json --output-file /usr/lint-output.json --config /usr/linked/.eslintrc.js /usr/linked/**/*.vue || true # Run our assertions against the linting output npx jest /usr/test.js --snapshotResolver=/usr/utils/jest-snapshot-resolver.js diff --git a/tests/integration/utils/jsconfig.json b/tests/integration/utils/jsconfig.json index d53d21eadfb..984f1f4c078 100644 --- a/tests/integration/utils/jsconfig.json +++ b/tests/integration/utils/jsconfig.json @@ -1,3 +1,7 @@ { - "exclude": [".eslintrc.js"] + "include": [ + ".eslintrc.js", + "jest-snapshot-resolver.js", + "generate-package-json.js" + ] } diff --git a/yarn.lock b/yarn.lock index 397043be8f6..9ccd008ee13 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2356,7 +2356,7 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4.1, chalk@^2.4.2: +chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -2809,7 +2809,7 @@ cosmiconfig@^6.0.0: path-type "^4.0.0" yaml "^1.7.2" -cross-spawn@^6.0.0, cross-spawn@^6.0.5: +cross-spawn@^6.0.0: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -2820,7 +2820,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0: +cross-spawn@^7.0.0, cross-spawn@^7.0.2: version "7.0.2" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.2.tgz#d0d7dcfa74e89115c7619f4f721a94e1fdb716d6" integrity sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw== @@ -3226,7 +3226,7 @@ deep-extend@~0.5.1: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.5.1.tgz#b894a9dd90d3023fbf1c55a394fb858eb2066f1f" integrity sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w== -deep-is@~0.1.3: +deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= @@ -3583,13 +3583,6 @@ eslint-scope@^5.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-utils@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== - dependencies: - eslint-visitor-keys "^1.1.0" - eslint-utils@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.0.0.tgz#7be1cc70f27a72a76cd14aa698bcabed6890e1cd" @@ -3602,22 +3595,22 @@ eslint-visitor-keys@^1.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== -eslint@^6.7.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" - integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== +eslint@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.0.0.tgz#c35dfd04a4372110bd78c69a8d79864273919a08" + integrity sha512-qY1cwdOxMONHJfGqw52UOpZDeqXy8xmD0u8CT6jIstil72jkhURC704W8CFyTPDPllz4z4lu0Ql1+07PG/XdIg== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" - chalk "^2.1.0" - cross-spawn "^6.0.5" + chalk "^4.0.0" + cross-spawn "^7.0.2" debug "^4.0.1" doctrine "^3.0.0" eslint-scope "^5.0.0" - eslint-utils "^1.4.3" + eslint-utils "^2.0.0" eslint-visitor-keys "^1.1.0" - espree "^6.1.2" - esquery "^1.0.1" + espree "^7.0.0" + esquery "^1.2.0" esutils "^2.0.2" file-entry-cache "^5.0.1" functional-red-black-tree "^1.0.1" @@ -3630,25 +3623,24 @@ eslint@^6.7.0: is-glob "^4.0.0" js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" + levn "^0.4.1" lodash "^4.17.14" minimatch "^3.0.4" - mkdirp "^0.5.1" natural-compare "^1.4.0" - optionator "^0.8.3" + optionator "^0.9.1" progress "^2.0.0" - regexpp "^2.0.1" - semver "^6.1.2" - strip-ansi "^5.2.0" - strip-json-comments "^3.0.1" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" table "^5.2.3" text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" - integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== +espree@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.0.0.tgz#8a7a60f218e69f120a842dc24c5a88aa7748a74e" + integrity sha512-/r2XEx5Mw4pgKdyb7GNLQNsu++asx/dltf/CI8RFi9oGHxmQFgvLbc5Op4U6i8Oaj+kdslhJtVlEZeAqH5qOTw== dependencies: acorn "^7.1.1" acorn-jsx "^5.2.0" @@ -3664,7 +3656,7 @@ esprima@^4.0.0, esprima@^4.0.1: resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.0.1: +esquery@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== @@ -3859,7 +3851,7 @@ fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= @@ -5598,7 +5590,15 @@ leven@^3.1.0: resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== -levn@^0.3.0, levn@~0.3.0: +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= @@ -6569,7 +6569,7 @@ opencollective-postinstall@^2.0.2: resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89" integrity sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw== -optionator@^0.8.1, optionator@^0.8.3: +optionator@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== @@ -6581,6 +6581,18 @@ optionator@^0.8.1, optionator@^0.8.3: type-check "~0.3.2" word-wrap "~1.2.3" +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" @@ -6958,6 +6970,11 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -7292,12 +7309,7 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== - -regexpp@^3.0.0: +regexpp@^3.0.0, regexpp@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== @@ -7574,12 +7586,12 @@ semver-regex@^2.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@6.3.0, semver@6.x, semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: +semver@6.3.0, semver@6.x, semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.3.2: +semver@^7.2.1, semver@^7.3.2: version "7.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== @@ -8073,7 +8085,7 @@ strip-json-comments@3.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== -strip-json-comments@^3.0.1: +strip-json-comments@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.0.tgz#7638d31422129ecf4457440009fba03f9f9ac180" integrity sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w== @@ -8402,6 +8414,13 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -8722,7 +8741,7 @@ windows-release@^3.1.0: dependencies: execa "^1.0.0" -word-wrap@^1.0.3, word-wrap@~1.2.3: +word-wrap@^1.0.3, word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==