From 0fad4df6a342f6eebf57f7a9fd7f13a17fbc0d1b Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Mon, 6 Jun 2022 12:46:52 +1200 Subject: [PATCH] fix(prefer-equality-matcher): handle `resolves` and `rejects` modifiers correctly (#1146) --- .../__tests__/prefer-equality-matcher.test.ts | 130 ++++++++++++++++++ src/rules/prefer-equality-matcher.ts | 24 +++- 2 files changed, 149 insertions(+), 5 deletions(-) diff --git a/src/rules/__tests__/prefer-equality-matcher.test.ts b/src/rules/__tests__/prefer-equality-matcher.test.ts index 0f645c44e..310345e07 100644 --- a/src/rules/__tests__/prefer-equality-matcher.test.ts +++ b/src/rules/__tests__/prefer-equality-matcher.test.ts @@ -63,6 +63,32 @@ ruleTester.run('prefer-equality-matcher: ===', rule, { }, ], }, + { + code: 'expect(a === b).resolves.toBe(true);', + errors: [ + { + messageId: 'useEqualityMatcher', + suggestions: expectSuggestions( + equalityMatcher => `expect(a).resolves.${equalityMatcher}(b);`, + ), + column: 26, + line: 1, + }, + ], + }, + { + code: 'expect(a === b).resolves.toBe(false);', + errors: [ + { + messageId: 'useEqualityMatcher', + suggestions: expectSuggestions( + equalityMatcher => `expect(a).resolves.not.${equalityMatcher}(b);`, + ), + column: 26, + line: 1, + }, + ], + }, { code: 'expect(a === b).not.toBe(true);', errors: [ @@ -89,6 +115,58 @@ ruleTester.run('prefer-equality-matcher: ===', rule, { }, ], }, + { + code: 'expect(a === b).resolves.not.toBe(true);', + errors: [ + { + messageId: 'useEqualityMatcher', + suggestions: expectSuggestions( + equalityMatcher => `expect(a).resolves.not.${equalityMatcher}(b);`, + ), + column: 26, + line: 1, + }, + ], + }, + { + code: 'expect(a === b).resolves.not.toBe(false);', + errors: [ + { + messageId: 'useEqualityMatcher', + suggestions: expectSuggestions( + equalityMatcher => `expect(a).resolves.${equalityMatcher}(b);`, + ), + column: 26, + line: 1, + }, + ], + }, + { + code: 'expect(a === b)["resolves"].not.toBe(false);', + errors: [ + { + messageId: 'useEqualityMatcher', + suggestions: expectSuggestions( + equalityMatcher => `expect(a).resolves.${equalityMatcher}(b);`, + ), + column: 29, + line: 1, + }, + ], + }, + { + code: 'expect(a === b)["resolves"]["not"]["toBe"](false);', + errors: [ + { + messageId: 'useEqualityMatcher', + suggestions: expectSuggestions( + equalityMatcher => `expect(a).resolves.${equalityMatcher}(b);`, + ), + column: 29, + line: 1, + }, + ], + }, ], }); @@ -125,6 +203,32 @@ ruleTester.run('prefer-equality-matcher: !==', rule, { }, ], }, + { + code: 'expect(a !== b).resolves.toBe(true);', + errors: [ + { + messageId: 'useEqualityMatcher', + suggestions: expectSuggestions( + equalityMatcher => `expect(a).resolves.not.${equalityMatcher}(b);`, + ), + column: 26, + line: 1, + }, + ], + }, + { + code: 'expect(a !== b).resolves.toBe(false);', + errors: [ + { + messageId: 'useEqualityMatcher', + suggestions: expectSuggestions( + equalityMatcher => `expect(a).resolves.${equalityMatcher}(b);`, + ), + column: 26, + line: 1, + }, + ], + }, { code: 'expect(a !== b).not.toBe(true);', errors: [ @@ -151,5 +255,31 @@ ruleTester.run('prefer-equality-matcher: !==', rule, { }, ], }, + { + code: 'expect(a !== b).resolves.not.toBe(true);', + errors: [ + { + messageId: 'useEqualityMatcher', + suggestions: expectSuggestions( + equalityMatcher => `expect(a).resolves.${equalityMatcher}(b);`, + ), + column: 26, + line: 1, + }, + ], + }, + { + code: 'expect(a !== b).resolves.not.toBe(false);', + errors: [ + { + messageId: 'useEqualityMatcher', + suggestions: expectSuggestions( + equalityMatcher => `expect(a).resolves.not.${equalityMatcher}(b);`, + ), + column: 26, + line: 1, + }, + ], + }, ], }); diff --git a/src/rules/prefer-equality-matcher.ts b/src/rules/prefer-equality-matcher.ts index d0fb615e3..91dee6dc0 100644 --- a/src/rules/prefer-equality-matcher.ts +++ b/src/rules/prefer-equality-matcher.ts @@ -85,17 +85,33 @@ export default createRule({ matcher.arguments[0], ).value; + const negation = modifier?.negation + ? { node: modifier.negation } + : modifier?.name === ModifierName.not + ? modifier + : null; + // we need to negate the expectation if the current expected // value is itself negated by the "not" modifier const addNotModifier = (comparison.operator === '!==' ? !matcherValue : matcherValue) === - !!modifier; + !!negation; const buildFixer = (equalityMatcher: string): TSESLint.ReportFixFunction => fixer => { const sourceCode = context.getSourceCode(); + // preserve the existing modifier if it's not a negation + let modifierText = + modifier && modifier?.node !== negation?.node + ? `.${modifier.name}` + : ''; + + if (addNotModifier) { + modifierText += `.${ModifierName.not}`; + } + return [ // replace the comparison argument with the left-hand side of the comparison fixer.replaceText( @@ -105,9 +121,7 @@ export default createRule({ // replace the current matcher & modifier with the preferred matcher fixer.replaceTextRange( [expectCallEnd, matcher.node.range[1]], - addNotModifier - ? `.${ModifierName.not}.${equalityMatcher}` - : `.${equalityMatcher}`, + `${modifierText}.${equalityMatcher}`, ), // replace the matcher argument with the right-hand side of the comparison fixer.replaceText( @@ -126,7 +140,7 @@ export default createRule({ fix: buildFixer(equalityMatcher), }), ), - node: (modifier || matcher).node.property, + node: (negation || matcher).node.property, }); }, };