Skip to content

Commit 0fad4df

Browse files
authored
fix(prefer-equality-matcher): handle resolves and rejects modifiers correctly (#1146)
1 parent f85f647 commit 0fad4df

File tree

2 files changed

+149
-5
lines changed

2 files changed

+149
-5
lines changed

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

+130
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,32 @@ ruleTester.run('prefer-equality-matcher: ===', rule, {
6363
},
6464
],
6565
},
66+
{
67+
code: 'expect(a === b).resolves.toBe(true);',
68+
errors: [
69+
{
70+
messageId: 'useEqualityMatcher',
71+
suggestions: expectSuggestions(
72+
equalityMatcher => `expect(a).resolves.${equalityMatcher}(b);`,
73+
),
74+
column: 26,
75+
line: 1,
76+
},
77+
],
78+
},
79+
{
80+
code: 'expect(a === b).resolves.toBe(false);',
81+
errors: [
82+
{
83+
messageId: 'useEqualityMatcher',
84+
suggestions: expectSuggestions(
85+
equalityMatcher => `expect(a).resolves.not.${equalityMatcher}(b);`,
86+
),
87+
column: 26,
88+
line: 1,
89+
},
90+
],
91+
},
6692
{
6793
code: 'expect(a === b).not.toBe(true);',
6894
errors: [
@@ -89,6 +115,58 @@ ruleTester.run('prefer-equality-matcher: ===', rule, {
89115
},
90116
],
91117
},
118+
{
119+
code: 'expect(a === b).resolves.not.toBe(true);',
120+
errors: [
121+
{
122+
messageId: 'useEqualityMatcher',
123+
suggestions: expectSuggestions(
124+
equalityMatcher => `expect(a).resolves.not.${equalityMatcher}(b);`,
125+
),
126+
column: 26,
127+
line: 1,
128+
},
129+
],
130+
},
131+
{
132+
code: 'expect(a === b).resolves.not.toBe(false);',
133+
errors: [
134+
{
135+
messageId: 'useEqualityMatcher',
136+
suggestions: expectSuggestions(
137+
equalityMatcher => `expect(a).resolves.${equalityMatcher}(b);`,
138+
),
139+
column: 26,
140+
line: 1,
141+
},
142+
],
143+
},
144+
{
145+
code: 'expect(a === b)["resolves"].not.toBe(false);',
146+
errors: [
147+
{
148+
messageId: 'useEqualityMatcher',
149+
suggestions: expectSuggestions(
150+
equalityMatcher => `expect(a).resolves.${equalityMatcher}(b);`,
151+
),
152+
column: 29,
153+
line: 1,
154+
},
155+
],
156+
},
157+
{
158+
code: 'expect(a === b)["resolves"]["not"]["toBe"](false);',
159+
errors: [
160+
{
161+
messageId: 'useEqualityMatcher',
162+
suggestions: expectSuggestions(
163+
equalityMatcher => `expect(a).resolves.${equalityMatcher}(b);`,
164+
),
165+
column: 29,
166+
line: 1,
167+
},
168+
],
169+
},
92170
],
93171
});
94172

@@ -125,6 +203,32 @@ ruleTester.run('prefer-equality-matcher: !==', rule, {
125203
},
126204
],
127205
},
206+
{
207+
code: 'expect(a !== b).resolves.toBe(true);',
208+
errors: [
209+
{
210+
messageId: 'useEqualityMatcher',
211+
suggestions: expectSuggestions(
212+
equalityMatcher => `expect(a).resolves.not.${equalityMatcher}(b);`,
213+
),
214+
column: 26,
215+
line: 1,
216+
},
217+
],
218+
},
219+
{
220+
code: 'expect(a !== b).resolves.toBe(false);',
221+
errors: [
222+
{
223+
messageId: 'useEqualityMatcher',
224+
suggestions: expectSuggestions(
225+
equalityMatcher => `expect(a).resolves.${equalityMatcher}(b);`,
226+
),
227+
column: 26,
228+
line: 1,
229+
},
230+
],
231+
},
128232
{
129233
code: 'expect(a !== b).not.toBe(true);',
130234
errors: [
@@ -151,5 +255,31 @@ ruleTester.run('prefer-equality-matcher: !==', rule, {
151255
},
152256
],
153257
},
258+
{
259+
code: 'expect(a !== b).resolves.not.toBe(true);',
260+
errors: [
261+
{
262+
messageId: 'useEqualityMatcher',
263+
suggestions: expectSuggestions(
264+
equalityMatcher => `expect(a).resolves.${equalityMatcher}(b);`,
265+
),
266+
column: 26,
267+
line: 1,
268+
},
269+
],
270+
},
271+
{
272+
code: 'expect(a !== b).resolves.not.toBe(false);',
273+
errors: [
274+
{
275+
messageId: 'useEqualityMatcher',
276+
suggestions: expectSuggestions(
277+
equalityMatcher => `expect(a).resolves.not.${equalityMatcher}(b);`,
278+
),
279+
column: 26,
280+
line: 1,
281+
},
282+
],
283+
},
154284
],
155285
});

src/rules/prefer-equality-matcher.ts

+19-5
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,33 @@ export default createRule({
8585
matcher.arguments[0],
8686
).value;
8787

88+
const negation = modifier?.negation
89+
? { node: modifier.negation }
90+
: modifier?.name === ModifierName.not
91+
? modifier
92+
: null;
93+
8894
// we need to negate the expectation if the current expected
8995
// value is itself negated by the "not" modifier
9096
const addNotModifier =
9197
(comparison.operator === '!==' ? !matcherValue : matcherValue) ===
92-
!!modifier;
98+
!!negation;
9399

94100
const buildFixer =
95101
(equalityMatcher: string): TSESLint.ReportFixFunction =>
96102
fixer => {
97103
const sourceCode = context.getSourceCode();
98104

105+
// preserve the existing modifier if it's not a negation
106+
let modifierText =
107+
modifier && modifier?.node !== negation?.node
108+
? `.${modifier.name}`
109+
: '';
110+
111+
if (addNotModifier) {
112+
modifierText += `.${ModifierName.not}`;
113+
}
114+
99115
return [
100116
// replace the comparison argument with the left-hand side of the comparison
101117
fixer.replaceText(
@@ -105,9 +121,7 @@ export default createRule({
105121
// replace the current matcher & modifier with the preferred matcher
106122
fixer.replaceTextRange(
107123
[expectCallEnd, matcher.node.range[1]],
108-
addNotModifier
109-
? `.${ModifierName.not}.${equalityMatcher}`
110-
: `.${equalityMatcher}`,
124+
`${modifierText}.${equalityMatcher}`,
111125
),
112126
// replace the matcher argument with the right-hand side of the comparison
113127
fixer.replaceText(
@@ -126,7 +140,7 @@ export default createRule({
126140
fix: buildFixer(equalityMatcher),
127141
}),
128142
),
129-
node: (modifier || matcher).node.property,
143+
node: (negation || matcher).node.property,
130144
});
131145
},
132146
};

0 commit comments

Comments
 (0)