diff --git a/internal/config/config.go b/internal/config/config.go index 2fb18ab35..885d3b039 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -14,6 +14,7 @@ import ( "github.com/web-infra-dev/rslint/internal/plugins/typescript/rules/array_type" "github.com/web-infra-dev/rslint/internal/plugins/typescript/rules/await_thenable" "github.com/web-infra-dev/rslint/internal/plugins/typescript/rules/ban_ts_comment" + "github.com/web-infra-dev/rslint/internal/plugins/typescript/rules/ban_tslint_comment" "github.com/web-infra-dev/rslint/internal/plugins/typescript/rules/ban_types" "github.com/web-infra-dev/rslint/internal/plugins/typescript/rules/class_literal_property_style" "github.com/web-infra-dev/rslint/internal/plugins/typescript/rules/consistent_generic_constructors" @@ -380,6 +381,7 @@ func registerAllTypeScriptEslintPluginRules() { GlobalRuleRegistry.Register("@typescript-eslint/array-type", array_type.ArrayTypeRule) GlobalRuleRegistry.Register("@typescript-eslint/await-thenable", await_thenable.AwaitThenableRule) GlobalRuleRegistry.Register("@typescript-eslint/ban-ts-comment", ban_ts_comment.BanTsCommentRule) + GlobalRuleRegistry.Register("@typescript-eslint/ban-tslint-comment", ban_tslint_comment.BanTslintCommentRule) GlobalRuleRegistry.Register("@typescript-eslint/ban-types", ban_types.BanTypesRule) GlobalRuleRegistry.Register("@typescript-eslint/class-literal-property-style", class_literal_property_style.ClassLiteralPropertyStyleRule) GlobalRuleRegistry.Register("@typescript-eslint/consistent-generic-constructors", consistent_generic_constructors.ConsistentGenericConstructorsRule) diff --git a/internal/plugins/typescript/rules/ban_tslint_comment/ban_tslint_comment.go b/internal/plugins/typescript/rules/ban_tslint_comment/ban_tslint_comment.go new file mode 100644 index 000000000..3a0d22673 --- /dev/null +++ b/internal/plugins/typescript/rules/ban_tslint_comment/ban_tslint_comment.go @@ -0,0 +1,121 @@ +package ban_tslint_comment + +import ( + "regexp" + "strings" + + "github.com/microsoft/typescript-go/shim/ast" + "github.com/microsoft/typescript-go/shim/core" + "github.com/microsoft/typescript-go/shim/scanner" + "github.com/web-infra-dev/rslint/internal/rule" + "github.com/web-infra-dev/rslint/internal/utils" +) + +// tslint regex +// https://github.com/palantir/tslint/blob/95d9d958833fd9dc0002d18cbe34db20d0fbf437/src/enableDisableRules.ts#L32 +var enableDisableRegex = regexp.MustCompile(`^\s*tslint:(enable|disable)(?:-(line|next-line))?(:|\s|$)`) + +// BanTslintCommentRule implements the ban-tslint-comment rule. +// Disallows tslint directive comments like // tslint:disable +var BanTslintCommentRule = rule.CreateRule(rule.Rule{ + Name: "ban-tslint-comment", + Run: run, +}) + +func run(ctx rule.RuleContext, _ any) rule.RuleListeners { + text := ctx.SourceFile.Text() + + utils.ForEachComment(&ctx.SourceFile.Node, func(comment *ast.CommentRange) { + commentValue := extractCommentValue(text, comment) + if !enableDisableRegex.MatchString(commentValue) { + return + } + + commentText := extractCommentText(text, comment) + if commentText == "" { + commentText = commentValue + } + message := rule.RuleMessage{ + Id: "commentDetected", + Description: "tslint comment detected: " + commentText, + } + + fixRange := buildFixRange(ctx.SourceFile, comment, len(text)) + ctx.ReportRangeWithFixes( + core.NewTextRange(comment.Pos(), comment.End()), + message, + rule.RuleFixRemoveRange(fixRange), + ) + }, ctx.SourceFile) + + return rule.RuleListeners{} +} + +func extractCommentValue(text string, comment *ast.CommentRange) string { + if comment.Pos() < 0 || comment.End() > len(text) { + return "" + } + + switch comment.Kind { + case ast.KindSingleLineCommentTrivia: + if comment.End() <= comment.Pos()+2 { + return "" + } + return text[comment.Pos()+2 : comment.End()] + case ast.KindMultiLineCommentTrivia: + if comment.End() <= comment.Pos()+4 { + return "" + } + return text[comment.Pos()+2 : comment.End()-2] + default: + return "" + } +} + +func extractCommentText(text string, comment *ast.CommentRange) string { + if comment.End() <= comment.Pos() { + return "" + } + if comment.Pos() < 0 || comment.End() > len(text) { + return "" + } + return strings.TrimSpace(text[comment.Pos():comment.End()]) +} + +func buildFixRange(sourceFile *ast.SourceFile, comment *ast.CommentRange, textLen int) core.TextRange { + text := sourceFile.Text() + start := comment.Pos() + end := comment.End() + + startLine, _ := scanner.GetECMALineAndCharacterOfPosition(sourceFile, start) + lineStart := scanner.GetECMAPositionOfLineAndCharacter(sourceFile, startLine, 0) + + isStandalone := true + for i := lineStart; i < start; i++ { + if text[i] != ' ' && text[i] != '\t' { + isStandalone = false + break + } + } + + if isStandalone { + start = lineStart + if end < textLen { + switch text[end] { + case '\r': + end++ + if end < textLen && text[end] == '\n' { + end++ + } + case '\n': + end++ + } + } + } else { + for start > lineStart && (text[start-1] == ' ' || text[start-1] == '\t') { + start-- + } + } + + return core.NewTextRange(start, end) +} diff --git a/internal/plugins/typescript/rules/ban_tslint_comment/ban_tslint_comment.md b/internal/plugins/typescript/rules/ban_tslint_comment/ban_tslint_comment.md new file mode 100644 index 000000000..d1bd4858b --- /dev/null +++ b/internal/plugins/typescript/rules/ban_tslint_comment/ban_tslint_comment.md @@ -0,0 +1,27 @@ +# ban-tslint-comment + +## Rule Details + +Disallow TSLint directive comments such as `// tslint:disable` and +`// tslint:disable-next-line`. These directives are not used by ESLint and are +typically left behind when migrating from TSLint. + +Examples of **incorrect** code for this rule: + +```javascript +/* tslint:disable */ +/* tslint:enable */ +// tslint:disable-next-line +someCode(); // tslint:disable-line +``` + +Examples of **correct** code for this rule: + +```javascript +// some other comment +/* another comment that mentions tslint */ +``` + +## Original Documentation + +- [typescript-eslint ban-tslint-comment](https://typescript-eslint.io/rules/ban-tslint-comment) diff --git a/internal/plugins/typescript/rules/ban_tslint_comment/ban_tslint_comment_test.go b/internal/plugins/typescript/rules/ban_tslint_comment/ban_tslint_comment_test.go new file mode 100644 index 000000000..917e45813 --- /dev/null +++ b/internal/plugins/typescript/rules/ban_tslint_comment/ban_tslint_comment_test.go @@ -0,0 +1,75 @@ +package ban_tslint_comment + +import ( + "testing" + + "github.com/web-infra-dev/rslint/internal/plugins/typescript/rules/fixtures" + "github.com/web-infra-dev/rslint/internal/rule_tester" +) + +func TestBanTslintCommentRule(t *testing.T) { + rule_tester.RunRuleTester(fixtures.GetRootDir(), "tsconfig.json", t, &BanTslintCommentRule, []rule_tester.ValidTestCase{ + {Code: "let a: readonly any[] = [];"}, + {Code: "let a = new Array();"}, + {Code: "// some other comment"}, + {Code: "// TODO: this is a comment that mentions tslint"}, + {Code: "/* another comment that mentions tslint */"}, + }, []rule_tester.InvalidTestCase{ + { + Code: "/* tslint:disable */", + Errors: []rule_tester.InvalidTestCaseError{ + {MessageId: "commentDetected", Line: 1, Column: 1}, + }, + Output: []string{""}, + }, + { + Code: "/* tslint:enable */", + Errors: []rule_tester.InvalidTestCaseError{ + {MessageId: "commentDetected", Line: 1, Column: 1}, + }, + Output: []string{""}, + }, + { + Code: "/* tslint:disable:rule1 rule2 rule3... */", + Errors: []rule_tester.InvalidTestCaseError{ + {MessageId: "commentDetected", Line: 1, Column: 1}, + }, + Output: []string{""}, + }, + { + Code: "/* tslint:enable:rule1 rule2 rule3... */", + Errors: []rule_tester.InvalidTestCaseError{ + {MessageId: "commentDetected", Line: 1, Column: 1}, + }, + Output: []string{""}, + }, + { + Code: "// tslint:disable-next-line", + Errors: []rule_tester.InvalidTestCaseError{ + {MessageId: "commentDetected", Line: 1, Column: 1}, + }, + Output: []string{""}, + }, + { + Code: "someCode(); // tslint:disable-line", + Errors: []rule_tester.InvalidTestCaseError{ + {MessageId: "commentDetected", Line: 1, Column: 13}, + }, + Output: []string{"someCode();"}, + }, + { + Code: "// tslint:disable-next-line:rule1 rule2 rule3...", + Errors: []rule_tester.InvalidTestCaseError{ + {MessageId: "commentDetected", Line: 1, Column: 1}, + }, + Output: []string{""}, + }, + { + Code: "const whoa = doSomeStuff();\n// tslint:disable-line\nconsole.log(whoa);\n", + Errors: []rule_tester.InvalidTestCaseError{ + {MessageId: "commentDetected", Line: 2, Column: 1}, + }, + Output: []string{"const whoa = doSomeStuff();\nconsole.log(whoa);\n"}, + }, + }) +} diff --git a/internal/plugins/typescript/rules/prefer_string_starts_ends_with/prefer_string_starts_ends_with.go b/internal/plugins/typescript/rules/prefer_string_starts_ends_with/prefer_string_starts_ends_with.go index b7eb960bc..c28e21011 100644 --- a/internal/plugins/typescript/rules/prefer_string_starts_ends_with/prefer_string_starts_ends_with.go +++ b/internal/plugins/typescript/rules/prefer_string_starts_ends_with/prefer_string_starts_ends_with.go @@ -86,6 +86,9 @@ func isNumber(node *ast.Node, value int) bool { if unary == nil { return false } + if unary.Operator == ast.KindPlusToken { + return isNumber(unary.Operand, value) + } if unary.Operator == ast.KindMinusToken { return isNumber(unary.Operand, -value) } @@ -143,7 +146,8 @@ func getStringLength(node *ast.Node) int { if lit == nil { return -1 } - return len(lit.Text) + // Match JS semantics: string length is UTF-16 code units. + return jsStringLength(lit.Text) } return -1 } diff --git a/internal/plugins/typescript/rules/prefer_string_starts_ends_with/prefer_string_starts_ends_with_test.go b/internal/plugins/typescript/rules/prefer_string_starts_ends_with/prefer_string_starts_ends_with_test.go index 7bf1e64e1..e473d0f63 100644 --- a/internal/plugins/typescript/rules/prefer_string_starts_ends_with/prefer_string_starts_ends_with_test.go +++ b/internal/plugins/typescript/rules/prefer_string_starts_ends_with/prefer_string_starts_ends_with_test.go @@ -384,6 +384,22 @@ function f(s: string) { function f(s: string) { s.startsWith('a'); } +`}, + }, + // s[+0] === 'a' + { + Code: ` +function f(s: string) { + s[+0] === 'a'; +} +`, + Errors: []rule_tester.InvalidTestCaseError{ + {MessageId: "preferStartsWith"}, + }, + Output: []string{` +function f(s: string) { + s.startsWith('a'); +} `}, }, // s?.[0] === 'a' @@ -532,6 +548,22 @@ function f(s: string) { function f(s: string) { s.startsWith('a'); } +`}, + }, + // s.charAt(+0) === 'a' + { + Code: ` +function f(s: string) { + s.charAt(+0) === 'a'; +} +`, + Errors: []rule_tester.InvalidTestCaseError{ + {MessageId: "preferStartsWith"}, + }, + Output: []string{` +function f(s: string) { + s.startsWith('a'); +} `}, }, // s.charAt(0) !== 'a' @@ -1028,6 +1060,22 @@ function f(s: string) { function f(s: string) { s.startsWith('bar'); } +`}, + }, + // s.slice(0, 1) === 'あ' + { + Code: ` +function f(s: string) { + s.slice(0, 1) === 'あ'; +} +`, + Errors: []rule_tester.InvalidTestCaseError{ + {MessageId: "preferStartsWith"}, + }, + Output: []string{` +function f(s: string) { + s.startsWith('あ'); +} `}, }, // s?.slice(0, 3) === 'bar' diff --git a/packages/rslint-test-tools/rstest.config.mts b/packages/rslint-test-tools/rstest.config.mts index c1b8a03d5..c44605667 100644 --- a/packages/rslint-test-tools/rstest.config.mts +++ b/packages/rslint-test-tools/rstest.config.mts @@ -19,7 +19,7 @@ export default defineConfig({ './tests/typescript-eslint/rules/array-type.test.ts', './tests/typescript-eslint/rules/await-thenable.test.ts', // './tests/typescript-eslint/rules/ban-ts-comment.test.ts', - // './tests/typescript-eslint/rules/ban-tslint-comment.test.ts', + './tests/typescript-eslint/rules/ban-tslint-comment.test.ts', './tests/typescript-eslint/rules/class-literal-property-style.test.ts', // './tests/typescript-eslint/rules/class-methods-use-this/class-methods-use-this-core.test.ts', // './tests/typescript-eslint/rules/class-methods-use-this/class-methods-use-this.test.ts', diff --git a/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/ban-tslint-comment.test.ts.snap b/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/ban-tslint-comment.test.ts.snap new file mode 100644 index 000000000..a65576903 --- /dev/null +++ b/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/ban-tslint-comment.test.ts.snap @@ -0,0 +1,224 @@ +// Rstest Snapshot v1 + +exports[`ban-tslint-comment > invalid 1`] = ` +{ + "code": "/* tslint:disable */", + "diagnostics": [ + { + "message": "tslint comment detected: /* tslint:disable */", + "messageId": "commentDetected", + "range": { + "end": { + "column": 21, + "line": 1, + }, + "start": { + "column": 1, + "line": 1, + }, + }, + "ruleName": "@typescript-eslint/ban-tslint-comment", + }, + ], + "errorCount": 1, + "fileCount": 1, + "output": "", + "ruleCount": 1, +} +`; + +exports[`ban-tslint-comment > invalid 2`] = ` +{ + "code": "/* tslint:enable */", + "diagnostics": [ + { + "message": "tslint comment detected: /* tslint:enable */", + "messageId": "commentDetected", + "range": { + "end": { + "column": 20, + "line": 1, + }, + "start": { + "column": 1, + "line": 1, + }, + }, + "ruleName": "@typescript-eslint/ban-tslint-comment", + }, + ], + "errorCount": 1, + "fileCount": 1, + "output": "", + "ruleCount": 1, +} +`; + +exports[`ban-tslint-comment > invalid 3`] = ` +{ + "code": "/* tslint:disable:rule1 rule2 rule3... */", + "diagnostics": [ + { + "message": "tslint comment detected: /* tslint:disable:rule1 rule2 rule3... */", + "messageId": "commentDetected", + "range": { + "end": { + "column": 42, + "line": 1, + }, + "start": { + "column": 1, + "line": 1, + }, + }, + "ruleName": "@typescript-eslint/ban-tslint-comment", + }, + ], + "errorCount": 1, + "fileCount": 1, + "output": "", + "ruleCount": 1, +} +`; + +exports[`ban-tslint-comment > invalid 4`] = ` +{ + "code": "/* tslint:enable:rule1 rule2 rule3... */", + "diagnostics": [ + { + "message": "tslint comment detected: /* tslint:enable:rule1 rule2 rule3... */", + "messageId": "commentDetected", + "range": { + "end": { + "column": 41, + "line": 1, + }, + "start": { + "column": 1, + "line": 1, + }, + }, + "ruleName": "@typescript-eslint/ban-tslint-comment", + }, + ], + "errorCount": 1, + "fileCount": 1, + "output": "", + "ruleCount": 1, +} +`; + +exports[`ban-tslint-comment > invalid 5`] = ` +{ + "code": "// tslint:disable-next-line", + "diagnostics": [ + { + "message": "tslint comment detected: // tslint:disable-next-line", + "messageId": "commentDetected", + "range": { + "end": { + "column": 28, + "line": 1, + }, + "start": { + "column": 1, + "line": 1, + }, + }, + "ruleName": "@typescript-eslint/ban-tslint-comment", + }, + ], + "errorCount": 1, + "fileCount": 1, + "output": "", + "ruleCount": 1, +} +`; + +exports[`ban-tslint-comment > invalid 6`] = ` +{ + "code": "someCode(); // tslint:disable-line", + "diagnostics": [ + { + "message": "tslint comment detected: // tslint:disable-line", + "messageId": "commentDetected", + "range": { + "end": { + "column": 35, + "line": 1, + }, + "start": { + "column": 13, + "line": 1, + }, + }, + "ruleName": "@typescript-eslint/ban-tslint-comment", + }, + ], + "errorCount": 1, + "fileCount": 1, + "output": "someCode();", + "ruleCount": 1, +} +`; + +exports[`ban-tslint-comment > invalid 7`] = ` +{ + "code": "// tslint:disable-next-line:rule1 rule2 rule3...", + "diagnostics": [ + { + "message": "tslint comment detected: // tslint:disable-next-line:rule1 rule2 rule3...", + "messageId": "commentDetected", + "range": { + "end": { + "column": 49, + "line": 1, + }, + "start": { + "column": 1, + "line": 1, + }, + }, + "ruleName": "@typescript-eslint/ban-tslint-comment", + }, + ], + "errorCount": 1, + "fileCount": 1, + "output": "", + "ruleCount": 1, +} +`; + +exports[`ban-tslint-comment > invalid 8`] = ` +{ + "code": " +const whoa = doSomeStuff(); +// tslint:disable-line +console.log(whoa); + ", + "diagnostics": [ + { + "message": "tslint comment detected: // tslint:disable-line", + "messageId": "commentDetected", + "range": { + "end": { + "column": 23, + "line": 3, + }, + "start": { + "column": 1, + "line": 3, + }, + }, + "ruleName": "@typescript-eslint/ban-tslint-comment", + }, + ], + "errorCount": 1, + "fileCount": 1, + "output": " +const whoa = doSomeStuff(); +console.log(whoa); + ", + "ruleCount": 1, +} +`; diff --git a/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/dot-notation.test.ts.snap b/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/dot-notation.test.ts.snap index 3076b2d74..34955769a 100644 --- a/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/dot-notation.test.ts.snap +++ b/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/dot-notation.test.ts.snap @@ -463,6 +463,7 @@ exports[`dot-notation > invalid 15`] = ` ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; @@ -489,6 +490,7 @@ exports[`dot-notation > invalid 16`] = ` ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; @@ -542,6 +544,7 @@ exports[`dot-notation > invalid 18`] = ` ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; @@ -622,6 +625,7 @@ exports[`dot-notation > invalid 21`] = ` ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; diff --git a/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/no-empty-interface.test.ts.snap b/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/no-empty-interface.test.ts.snap index fd502c803..ed03ac4f7 100644 --- a/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/no-empty-interface.test.ts.snap +++ b/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/no-empty-interface.test.ts.snap @@ -22,6 +22,7 @@ exports[`no-empty-interface > invalid 1`] = ` ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; @@ -48,6 +49,7 @@ exports[`no-empty-interface > invalid 2`] = ` ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; @@ -125,6 +127,7 @@ class Bar {} ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; @@ -393,6 +396,7 @@ declare module FooBar { ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; diff --git a/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/prefer-as-const.test.ts.snap b/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/prefer-as-const.test.ts.snap index a2a4ab320..5870afba4 100644 --- a/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/prefer-as-const.test.ts.snap +++ b/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/prefer-as-const.test.ts.snap @@ -76,6 +76,7 @@ exports[`prefer-as-const > invalid 3`] = ` ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; @@ -102,6 +103,7 @@ exports[`prefer-as-const > invalid 4`] = ` ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; @@ -128,6 +130,7 @@ exports[`prefer-as-const > invalid 5`] = ` ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; @@ -293,6 +296,7 @@ class foo { ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; @@ -323,6 +327,7 @@ class foo { ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; diff --git a/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/prefer-string-starts-ends-with.test.ts.snap b/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/prefer-string-starts-ends-with.test.ts.snap index bff07dbf7..d40aace2b 100644 --- a/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/prefer-string-starts-ends-with.test.ts.snap +++ b/packages/rslint-test-tools/tests/typescript-eslint/rules/__snapshots__/prefer-string-starts-ends-with.test.ts.snap @@ -271,6 +271,7 @@ exports[`prefer-string-starts-ends-with > invalid 8`] = ` ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; @@ -301,6 +302,7 @@ exports[`prefer-string-starts-ends-with > invalid 9`] = ` ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; @@ -576,6 +578,7 @@ exports[`prefer-string-starts-ends-with > invalid 17`] = ` ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; @@ -606,6 +609,7 @@ exports[`prefer-string-starts-ends-with > invalid 18`] = ` ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; @@ -1727,6 +1731,7 @@ exports[`prefer-string-starts-ends-with > invalid 50`] = ` ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; @@ -1932,6 +1937,7 @@ exports[`prefer-string-starts-ends-with > invalid 56`] = ` ], "errorCount": 1, "fileCount": 1, + "output": null, "ruleCount": 1, } `; diff --git a/packages/rslint-test-tools/tests/typescript-eslint/rules/ban-tslint-comment.test.ts b/packages/rslint-test-tools/tests/typescript-eslint/rules/ban-tslint-comment.test.ts index f6332203f..f628a2fdb 100644 --- a/packages/rslint-test-tools/tests/typescript-eslint/rules/ban-tslint-comment.test.ts +++ b/packages/rslint-test-tools/tests/typescript-eslint/rules/ban-tslint-comment.test.ts @@ -121,9 +121,9 @@ ruleTester.run('ban-tslint-comment', { }, { code: ` -const woah = doSomeStuff(); +const whoa = doSomeStuff(); // tslint:disable-line -console.log(woah); +console.log(whoa); `, errors: [ { @@ -136,8 +136,8 @@ console.log(woah); }, ], output: ` -const woah = doSomeStuff(); -console.log(woah); +const whoa = doSomeStuff(); +console.log(whoa); `, }, ], diff --git a/packages/rule-tester/src/index.ts b/packages/rule-tester/src/index.ts index 7263abfc1..2f06ce95f 100644 --- a/packages/rule-tester/src/index.ts +++ b/packages/rule-tester/src/index.ts @@ -206,7 +206,7 @@ export class RuleTester { ruleOptions: { [ruleName]: options, }, - languageOptions, + languageOptions: languageOptions as any, }); assert( @@ -246,7 +246,7 @@ export class RuleTester { ruleOptions: { [ruleName]: options, }, - languageOptions, + languageOptions: languageOptions as any, }); assert( @@ -255,7 +255,11 @@ export class RuleTester { ); // eslint-disable-next-line checkDiagnosticEqual(diags.diagnostics, errors); - if (output) { + const hasOutput = Object.prototype.hasOwnProperty.call( + item, + 'output', + ); + if (hasOutput) { // check autofix const fixedCode = await applyFixes({ fileContent: code,