diff --git a/packages/eslint-plugin/tests/RuleTester.ts b/packages/eslint-plugin/tests/RuleTester.ts index 20896e9d848b..3a7a01b8fd79 100644 --- a/packages/eslint-plugin/tests/RuleTester.ts +++ b/packages/eslint-plugin/tests/RuleTester.ts @@ -12,6 +12,9 @@ interface ValidTestCase> { settings?: Record; parser?: string; globals?: Record; + env?: { + browser?: boolean; + }; } interface InvalidTestCase< diff --git a/packages/eslint-plugin/tests/eslint-rules/no-redeclare.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-redeclare.test.ts index 51b56f72f6f2..33e536ad0e81 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-redeclare.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-redeclare.test.ts @@ -1,17 +1,55 @@ import rule from 'eslint/lib/rules/no-redeclare'; +import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { - ecmaVersion: 6, - sourceType: 'module', - ecmaFeatures: {} + ecmaVersion: 6 }, parser: '@typescript-eslint/parser' }); ruleTester.run('no-redeclare', rule, { valid: [ + 'var a = 3; var b = function() { var a = 10; };', + 'var a = 3; a = 10;', + { + code: 'if (true) {\n let b = 2;\n} else { \nlet b = 3;\n}', + parserOptions: { + ecmaVersion: 6 + } + }, + 'var Object = 0;', + { code: 'var Object = 0;', options: [{ builtinGlobals: false }] }, + { + code: 'var Object = 0;', + options: [{ builtinGlobals: true }], + parserOptions: { sourceType: 'module' } + }, + { + code: 'var Object = 0;', + options: [{ builtinGlobals: true }], + parserOptions: { ecmaFeatures: { globalReturn: true } } + }, + { code: 'var top = 0;', env: { browser: true } }, + { code: 'var top = 0;', options: [{ builtinGlobals: true }] }, + { + code: 'var top = 0;', + options: [{ builtinGlobals: true }], + parserOptions: { ecmaFeatures: { globalReturn: true } }, + env: { browser: true } + }, + { + code: 'var top = 0;', + options: [{ builtinGlobals: true }], + parserOptions: { sourceType: 'module' }, + env: { browser: true } + }, + { + code: 'var self = 1', + options: [{ builtinGlobals: true }], + env: { browser: false } + }, // https://github.com/eslint/typescript-eslint-parser/issues/443 ` const Foo = 1; @@ -22,7 +60,211 @@ type Foo = 1; function foo({ bar }: { bar: string }) { console.log(bar); } + `, + ` +type AST = TSESTree.Program & + (T['range'] extends true ? { range: [number, number] } : {}) & + (T['tokens'] extends true ? { tokens: TSESTree.Token[] } : {}) & + (T['comment'] extends true ? { comments: TSESTree.Comment[] } : {}); +interface ParseAndGenerateServicesResult { + ast: AST; + services: ParserServices; +} + `, + ` +function A() {} +interface B {} +type C = Array +class D {} ` ], - invalid: [] + invalid: [ + { + code: 'var a = 3; var a = 10;', + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + message: "'a' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + }, + { + code: 'switch(foo) { case a: var b = 3;\ncase b: var b = 4}', + errors: [ + { + message: "'b' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + }, + { + code: 'var a = 3; var a = 10;', + errors: [ + { + message: "'a' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + }, + { + code: 'var a = {}; var a = [];', + errors: [ + { + message: "'a' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + }, + { + code: 'var a; function a() {}', + errors: [ + { + message: "'a' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + }, + { + code: 'function a() {} function a() {}', + errors: [ + { + message: "'a' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + }, + { + code: 'var a = function() { }; var a = function() { }', + errors: [ + { + message: "'a' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + }, + { + code: 'var a = function() { }; var a = new Date();', + errors: [ + { + message: "'a' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + }, + { + code: 'var a = 3; var a = 10; var a = 15;', + errors: [ + { + message: "'a' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any, + { + message: "'a' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + }, + { + code: 'var a; var a;', + parserOptions: { sourceType: 'module' }, + errors: [ + { + message: "'a' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + }, + { + code: 'export var a; var a;', + parserOptions: { sourceType: 'module' }, + errors: [ + { + message: "'a' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + }, + { + code: 'var Object = 0;', + options: [{ builtinGlobals: true }], + errors: [ + { + message: "'Object' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + }, + { + code: 'var top = 0;', + options: [{ builtinGlobals: true }], + errors: [ + { + message: "'top' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ], + env: { browser: true } + }, + { + code: 'var a; var {a = 0, b: Object = 0} = {};', + options: [{ builtinGlobals: true }], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + message: "'a' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any, + { + message: "'Object' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + }, + { + code: 'var a; var {a = 0, b: Object = 0} = {};', + options: [{ builtinGlobals: true }], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [ + { + message: "'a' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + }, + { + code: 'var a; var {a = 0, b: Object = 0} = {};', + options: [{ builtinGlobals: true }], + parserOptions: { ecmaVersion: 6, ecmaFeatures: { globalReturn: true } }, + errors: [ + { + message: "'a' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + }, + { + code: 'var a; var {a = 0, b: Object = 0} = {};', + options: [{ builtinGlobals: false }], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + message: "'a' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + }, + + // Notifications of readonly are moved from no-undef: https://github.com/eslint/eslint/issues/4504 + { + code: '/*global b:false*/ var b = 1;', + options: [{ builtinGlobals: true }], + errors: [ + { + message: "'b' is already defined.", + type: AST_NODE_TYPES.Identifier + } as any + ] + } + ] }); diff --git a/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.test.ts deleted file mode 100644 index 8c8e33533823..000000000000 --- a/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.test.ts +++ /dev/null @@ -1,31 +0,0 @@ -import rule from 'eslint/lib/rules/no-use-before-define'; -import { RuleTester } from '../RuleTester'; - -const ruleTester = new RuleTester({ - parserOptions: { - ecmaVersion: 6, - sourceType: 'module' - }, - parser: '@typescript-eslint/parser' -}); - -ruleTester.run('no-undef', rule, { - valid: [ - // https://github.com/eslint/typescript-eslint-parser/issues/550 - ` -function test(file: Blob) { - const slice: typeof file.slice = - file.slice || (file as any).webkitSlice || (file as any).mozSlice - return slice -} - `, - // https://github.com/eslint/typescript-eslint-parser/issues/435 - ` -interface Foo { - bar: string -} -const bar = 'blah' - ` - ], - invalid: [] -}); diff --git a/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts b/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts index dc56199e5885..26cb25efbaf7 100644 --- a/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts +++ b/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts @@ -214,7 +214,22 @@ export namespace Third { `, parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: '@typescript-eslint/parser' - } + }, + // https://github.com/eslint/typescript-eslint-parser/issues/550 + ` +function test(file: Blob) { + const slice: typeof file.slice = + file.slice || (file as any).webkitSlice || (file as any).mozSlice + return slice +} + `, + // https://github.com/eslint/typescript-eslint-parser/issues/435 + ` +interface Foo { + bar: string +} +const bar = 'blah' + ` ], invalid: [ { @@ -813,7 +828,7 @@ function foo() { var bar = 1; } var bar; - `, + `, parserOptions, options: [{ variables: false }], errors: [