Skip to content

Commit 703b006

Browse files
authored
fix(no-focused-tests): not all chainable APIs are reported (#878)
Closes #877
1 parent 99cd227 commit 703b006

File tree

2 files changed

+125
-81
lines changed

2 files changed

+125
-81
lines changed

src/rules/no-focused-tests.ts

Lines changed: 22 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { TSESTree } from '@typescript-eslint/utils'
2-
import { createEslintRule } from '../utils'
1+
import { createEslintRule, getAccessorValue } from '../utils'
2+
import { parseVitestFnCall } from '../utils/parse-vitest-fn-call'
33

44
export type MessageIds = 'noFocusedTests'
55
const RULE_NAME = 'no-focused-tests'
@@ -9,16 +9,6 @@ export type Options = [
99
}>,
1010
]
1111

12-
const isTestOrDescribe = (node: TSESTree.Expression) => {
13-
return (
14-
node.type === 'Identifier' && ['it', 'test', 'describe'].includes(node.name)
15-
)
16-
}
17-
18-
const isOnly = (node: TSESTree.Expression | TSESTree.PrivateIdentifier) => {
19-
return node.type === 'Identifier' && node.name === 'only'
20-
}
21-
2212
export default createEslintRule<Options, MessageIds>({
2313
name: RULE_NAME,
2414
meta: {
@@ -49,78 +39,30 @@ export default createEslintRule<Options, MessageIds>({
4939
const fixable = options[0].fixable!
5040

5141
return {
52-
ExpressionStatement(node) {
53-
if (node.expression.type === 'CallExpression') {
54-
const { callee } = node.expression
55-
if (
56-
callee.type === 'MemberExpression' &&
57-
isTestOrDescribe(callee.object) &&
58-
isOnly(callee.property)
59-
) {
60-
context.report({
61-
node: callee.property,
62-
messageId: 'noFocusedTests',
63-
fix: (fixer) =>
64-
fixable
65-
? fixer.removeRange([
66-
callee.property.range[0] - 1,
67-
callee.property.range[1],
68-
])
69-
: null,
70-
})
71-
}
72-
73-
if (callee.type === 'TaggedTemplateExpression') {
74-
const tagCall =
75-
callee.tag.type === 'MemberExpression' ? callee.tag.object : null
76-
if (!tagCall) return
42+
CallExpression(node) {
43+
const vitestFnCall = parseVitestFnCall(node, context)
7744

78-
if (
79-
tagCall.type === 'MemberExpression' &&
80-
isTestOrDescribe(tagCall.object) &&
81-
isOnly(tagCall.property)
82-
) {
83-
context.report({
84-
node: tagCall.property,
85-
messageId: 'noFocusedTests',
86-
fix: (fixer) =>
87-
fixable
88-
? fixer.removeRange([
89-
tagCall.property.range[0] - 1,
90-
tagCall.property.range[1],
91-
])
92-
: null,
93-
})
94-
}
95-
}
45+
if (!vitestFnCall) {
46+
return
9647
}
97-
},
98-
CallExpression(node) {
99-
if (node.callee.type === 'CallExpression') {
100-
const { callee } = node.callee
10148

102-
if (
103-
callee.type === 'MemberExpression' &&
104-
callee.object.type === 'MemberExpression' &&
105-
isTestOrDescribe(callee.object.object) &&
106-
isOnly(callee.object.property) &&
107-
callee.property.type === 'Identifier' &&
108-
callee.property.name === 'each'
109-
) {
110-
const onlyCallee = callee.object.property
49+
const isTestOrDescribe = ['it', 'test', 'describe'].includes(
50+
vitestFnCall.name,
51+
)
52+
53+
const onlyNode = vitestFnCall.members.find(
54+
(m) => getAccessorValue(m) === 'only',
55+
)
11156

112-
context.report({
113-
node: callee.object.property,
114-
messageId: 'noFocusedTests',
115-
fix: (fixer) =>
116-
fixable
117-
? fixer.removeRange([
118-
onlyCallee.range[0] - 1,
119-
onlyCallee.range[1],
120-
])
121-
: null,
122-
})
123-
}
57+
if (isTestOrDescribe && onlyNode) {
58+
context.report({
59+
node: onlyNode,
60+
messageId: 'noFocusedTests',
61+
fix: (fixer) =>
62+
fixable
63+
? fixer.removeRange([onlyNode.range[0] - 1, onlyNode.range[1]])
64+
: null,
65+
})
12466
}
12567
},
12668
}

tests/no-focused-tests.test.ts

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,19 @@ import rule from '../src/rules/no-focused-tests'
22
import { ruleTester } from './ruleTester'
33

44
ruleTester.run(rule.name, rule, {
5-
valid: ['it("test", () => {});', 'describe("test group", () => {});'],
5+
valid: [
6+
'it("test", () => {});',
7+
'it.each([])("test", () => {});',
8+
'it.for([])("test", () => {});',
9+
10+
'test("test", () => {});',
11+
'test.each([])("test", () => {});',
12+
'test.for([])("test", () => {});',
13+
14+
'describe("test group", () => {});',
15+
'describe.each([])("test group", () => {});',
16+
'describe.for([])("test group", () => {});',
17+
],
618
invalid: [
719
{
820
options: [
@@ -72,6 +84,57 @@ ruleTester.run(rule.name, rule, {
7284
},
7385
],
7486
},
87+
{
88+
options: [
89+
{
90+
fixable: false,
91+
},
92+
],
93+
code: 'it.only.for([])("test", () => {});',
94+
errors: [
95+
{
96+
column: 4,
97+
endColumn: 8,
98+
endLine: 1,
99+
line: 1,
100+
messageId: 'noFocusedTests',
101+
},
102+
],
103+
},
104+
{
105+
options: [
106+
{
107+
fixable: false,
108+
},
109+
],
110+
code: 'describe.only.each([])("test", () => {});',
111+
errors: [
112+
{
113+
column: 10,
114+
endColumn: 14,
115+
endLine: 1,
116+
line: 1,
117+
messageId: 'noFocusedTests',
118+
},
119+
],
120+
},
121+
{
122+
options: [
123+
{
124+
fixable: false,
125+
},
126+
],
127+
code: 'describe.only.for([])("test", () => {});',
128+
errors: [
129+
{
130+
column: 10,
131+
endColumn: 14,
132+
endLine: 1,
133+
line: 1,
134+
messageId: 'noFocusedTests',
135+
},
136+
],
137+
},
75138
{
76139
options: [
77140
{
@@ -164,6 +227,45 @@ ruleTester.run(rule.name, rule, {
164227
],
165228
output: 'it.each([])("test", () => {});',
166229
},
230+
{
231+
code: 'it.only.for([])("test", () => {});',
232+
output: 'it.for([])("test", () => {});',
233+
errors: [
234+
{
235+
column: 4,
236+
endColumn: 8,
237+
endLine: 1,
238+
line: 1,
239+
messageId: 'noFocusedTests',
240+
},
241+
],
242+
},
243+
{
244+
code: 'describe.only.each([])("test", () => {});',
245+
output: 'describe.each([])("test", () => {});',
246+
errors: [
247+
{
248+
column: 10,
249+
endColumn: 14,
250+
endLine: 1,
251+
line: 1,
252+
messageId: 'noFocusedTests',
253+
},
254+
],
255+
},
256+
{
257+
code: 'describe.only.for([])("test", () => {});',
258+
output: 'describe.for([])("test", () => {});',
259+
errors: [
260+
{
261+
column: 10,
262+
endColumn: 14,
263+
endLine: 1,
264+
line: 1,
265+
messageId: 'noFocusedTests',
266+
},
267+
],
268+
},
167269
{
168270
code: 'test.only.each``("test", () => {});',
169271
errors: [

0 commit comments

Comments
 (0)