/
prefer-to-be-truthy.ts
55 lines (49 loc) · 1.57 KB
/
prefer-to-be-truthy.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
import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils'
import { createEslintRule, getAccessorValue } from '../utils'
import { getFirstMatcherArg, parseVitestFnCall } from '../utils/parseVitestFnCall'
import { EqualityMatcher } from '../utils/types'
type MESSAGE_IDS = 'preferToBeTruthy'
export const RULE_NAME = 'prefer-to-be-truthy'
type Options = []
interface TrueLiteral extends TSESTree.BooleanLiteral {
value: true;
}
const isTrueLiteral = (node: TSESTree.Node): node is TrueLiteral =>
node.type === AST_NODE_TYPES.Literal && node.value === true
export default createEslintRule<Options, MESSAGE_IDS>({
name: RULE_NAME,
meta: {
type: 'suggestion',
docs: {
description: 'Suggest using `toBeTruthy`',
recommended: 'warn'
},
messages: {
preferToBeTruthy: 'Prefer using `toBeTruthy` to test value is `true`'
},
fixable: 'code',
schema: []
},
defaultOptions: [],
create(context) {
return {
CallExpression(node) {
const vitestFnCall = parseVitestFnCall(node, context)
if (!(vitestFnCall?.type === 'expect' || vitestFnCall?.type === 'expectTypeOf')) return
if (vitestFnCall.args.length === 1 &&
isTrueLiteral(getFirstMatcherArg(vitestFnCall)) &&
// eslint-disable-next-line no-prototype-builtins
EqualityMatcher.hasOwnProperty(getAccessorValue(vitestFnCall.matcher))) {
context.report({
node: vitestFnCall.matcher,
messageId: 'preferToBeTruthy',
fix: fixer => [
fixer.replaceText(vitestFnCall.matcher, 'toBeTruthy'),
fixer.remove(vitestFnCall.args[0])
]
})
}
}
}
}
})