Skip to content

Commit b1795ff

Browse files
authored
fix(prefer-comparison-matcher): handle resolves and rejects modifiers correctly (#1145)
1 parent 7965a7c commit b1795ff

File tree

2 files changed

+102
-3
lines changed

2 files changed

+102
-3
lines changed

src/rules/__tests__/prefer-comparison-matcher.test.ts

+86
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ const generateInvalidCases = (
4040
},
4141
],
4242
},
43+
{
44+
code: `expect(value ${operator} 1).resolves.${equalityMatcher}(true);`,
45+
output: `expect(value).resolves.${preferredMatcher}(1);`,
46+
errors: [
47+
{
48+
messageId: 'useToBeComparison',
49+
data: { preferredMatcher },
50+
column: 27 + operator.length,
51+
line: 1,
52+
},
53+
],
54+
},
4355
{
4456
code: `expect(value ${operator} 1).${equalityMatcher}(false);`,
4557
output: `expect(value).${preferredMatcherWhenNegated}(1);`,
@@ -64,6 +76,18 @@ const generateInvalidCases = (
6476
},
6577
],
6678
},
79+
{
80+
code: `expect(value ${operator} 1).resolves.${equalityMatcher}(false);`,
81+
output: `expect(value).resolves.${preferredMatcherWhenNegated}(1);`,
82+
errors: [
83+
{
84+
messageId: 'useToBeComparison',
85+
data: { preferredMatcher: preferredMatcherWhenNegated },
86+
column: 27 + operator.length,
87+
line: 1,
88+
},
89+
],
90+
},
6791
{
6892
code: `expect(value ${operator} 1).not.${equalityMatcher}(true);`,
6993
output: `expect(value).${preferredMatcherWhenNegated}(1);`,
@@ -88,6 +112,18 @@ const generateInvalidCases = (
88112
},
89113
],
90114
},
115+
{
116+
code: `expect(value ${operator} 1).resolves.not.${equalityMatcher}(true);`,
117+
output: `expect(value).resolves.${preferredMatcherWhenNegated}(1);`,
118+
errors: [
119+
{
120+
messageId: 'useToBeComparison',
121+
data: { preferredMatcher: preferredMatcherWhenNegated },
122+
column: 27 + operator.length,
123+
line: 1,
124+
},
125+
],
126+
},
91127
{
92128
code: `expect(value ${operator} 1).not.${equalityMatcher}(false);`,
93129
output: `expect(value).${preferredMatcher}(1);`,
@@ -100,6 +136,54 @@ const generateInvalidCases = (
100136
},
101137
],
102138
},
139+
{
140+
code: `expect(value ${operator} 1).resolves.not.${equalityMatcher}(false);`,
141+
output: `expect(value).resolves.${preferredMatcher}(1);`,
142+
errors: [
143+
{
144+
messageId: 'useToBeComparison',
145+
data: { preferredMatcher },
146+
column: 27 + operator.length,
147+
line: 1,
148+
},
149+
],
150+
},
151+
{
152+
code: `expect(value ${operator} 1)["resolves"].not.${equalityMatcher}(false);`,
153+
output: `expect(value).resolves.${preferredMatcher}(1);`,
154+
errors: [
155+
{
156+
messageId: 'useToBeComparison',
157+
data: { preferredMatcher },
158+
column: 30 + operator.length,
159+
line: 1,
160+
},
161+
],
162+
},
163+
{
164+
code: `expect(value ${operator} 1)["resolves"]["not"].${equalityMatcher}(false);`,
165+
output: `expect(value).resolves.${preferredMatcher}(1);`,
166+
errors: [
167+
{
168+
messageId: 'useToBeComparison',
169+
data: { preferredMatcher },
170+
column: 30 + operator.length,
171+
line: 1,
172+
},
173+
],
174+
},
175+
{
176+
code: `expect(value ${operator} 1)["resolves"]["not"]['${equalityMatcher}'](false);`,
177+
output: `expect(value).resolves.${preferredMatcher}(1);`,
178+
errors: [
179+
{
180+
messageId: 'useToBeComparison',
181+
data: { preferredMatcher },
182+
column: 30 + operator.length,
183+
line: 1,
184+
},
185+
],
186+
},
103187
];
104188
};
105189

@@ -128,6 +212,8 @@ const generateValidStringLiteralCases = (operator: string, matcher: string) => {
128212
`expect(${b} ${operator} ${a}).not.${matcher}(true)`,
129213
`expect(${b} ${operator} ${a}).not.${matcher}(false)`,
130214
`expect(${b} ${operator} ${b}).not.${matcher}(false)`,
215+
`expect(${b} ${operator} ${b}).resolves.not.${matcher}(false)`,
216+
`expect(${b} ${operator} ${b}).resolves.${matcher}(false)`,
131217
],
132218
]);
133219
};

src/rules/prefer-comparison-matcher.ts

+16-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils';
22
import {
33
MaybeTypeCast,
4+
ModifierName,
45
ParsedEqualityMatcherCall,
56
ParsedExpectMatcher,
67
createRule,
@@ -122,9 +123,15 @@ export default createRule({
122123
return;
123124
}
124125

126+
const negation = modifier?.negation
127+
? { node: modifier.negation }
128+
: modifier?.name === ModifierName.not
129+
? modifier
130+
: null;
131+
125132
const preferredMatcher = determineMatcher(
126133
comparison.operator,
127-
followTypeAssertionChain(matcher.arguments[0]).value === !!modifier,
134+
followTypeAssertionChain(matcher.arguments[0]).value === !!negation,
128135
);
129136

130137
if (!preferredMatcher) {
@@ -135,6 +142,12 @@ export default createRule({
135142
fix(fixer) {
136143
const sourceCode = context.getSourceCode();
137144

145+
// preserve the existing modifier if it's not a negation
146+
const modifierText =
147+
modifier && modifier?.node !== negation?.node
148+
? `.${modifier.name}`
149+
: '';
150+
138151
return [
139152
// replace the comparison argument with the left-hand side of the comparison
140153
fixer.replaceText(
@@ -144,7 +157,7 @@ export default createRule({
144157
// replace the current matcher & modifier with the preferred matcher
145158
fixer.replaceTextRange(
146159
[expectCallEnd, matcher.node.range[1]],
147-
`.${preferredMatcher}`,
160+
`${modifierText}.${preferredMatcher}`,
148161
),
149162
// replace the matcher argument with the right-hand side of the comparison
150163
fixer.replaceText(
@@ -155,7 +168,7 @@ export default createRule({
155168
},
156169
messageId: 'useToBeComparison',
157170
data: { preferredMatcher },
158-
node: (modifier || matcher).node.property,
171+
node: (negation || matcher).node.property,
159172
});
160173
},
161174
};

0 commit comments

Comments
 (0)