-
Notifications
You must be signed in to change notification settings - Fork 27
/
no-identical-title.ts
86 lines (71 loc) · 2.04 KB
/
no-identical-title.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { createEslintRule, getStringValue, isStringNode, isSupportedAccessor } from '../utils'
import { isTypeOfVitestFnCall, parseVitestFnCall } from '../utils/parseVitestFnCall'
export const RULE_NAME = 'no-identical-title'
export type MESSAGE_ID = 'multipleTestTitle' | 'multipleDescribeTitle';
export type Options = [];
interface DescribeContext {
describeTitles: string[];
testTitles: string[];
}
const newDescribeContext = (): DescribeContext => ({
describeTitles: [],
testTitles: []
})
export default createEslintRule<Options, MESSAGE_ID>({
name: RULE_NAME,
meta: {
type: 'problem',
docs: {
description: 'Disallow identical titles',
recommended: 'strict'
},
fixable: 'code',
schema: [],
messages: {
multipleTestTitle: 'Test is used multiple times in the same describe block',
multipleDescribeTitle: 'Describe is used multiple times in the same describe block'
}
},
defaultOptions: [],
create(context) {
const stack = [newDescribeContext()]
return {
CallExpression(node) {
const currentStack = stack[stack.length - 1]
const vitestFnCall = parseVitestFnCall(node, context)
if (!vitestFnCall)
return
if (vitestFnCall.name === 'describe')
stack.push(newDescribeContext())
if (vitestFnCall.members.find(s => isSupportedAccessor(s, 'each')))
return
const [argument] = node.arguments
if (!argument || !isStringNode(argument))
return
const title = getStringValue(argument)
if (vitestFnCall.type === 'test') {
if (currentStack?.testTitles.includes(title)) {
context.report({
node,
messageId: 'multipleTestTitle'
})
}
currentStack?.testTitles.push(title)
}
if (vitestFnCall.type !== 'describe')
return
if (currentStack?.describeTitles.includes(title)) {
context.report({
node,
messageId: 'multipleDescribeTitle'
})
}
currentStack?.describeTitles.push(title)
},
'CallExpression:exit'(node) {
if (isTypeOfVitestFnCall(node, context, ['describe']))
stack.pop()
}
}
}
})