Skip to content

Commit ccbe766

Browse files
G-RathSimenB
authored andcommitted
chore(prefer-strict-equal): migrate to TS (#329)
1 parent ee81058 commit ccbe766

File tree

4 files changed

+102
-37
lines changed

4 files changed

+102
-37
lines changed

src/rules/__tests__/prefer-strict-equal.test.js renamed to src/rules/__tests__/prefer-strict-equal.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { RuleTester } from 'eslint';
1+
import { TSESLint } from '@typescript-eslint/experimental-utils';
22
import rule from '../prefer-strict-equal';
33

4-
const ruleTester = new RuleTester();
4+
const ruleTester = new TSESLint.RuleTester();
55

66
ruleTester.run('prefer-strict-equal', rule, {
77
valid: [

src/rules/prefer-strict-equal.js

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/rules/prefer-strict-equal.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { createRule, isExpectCallWithParent } from './tsUtils';
2+
3+
export default createRule({
4+
name: __filename,
5+
meta: {
6+
docs: {
7+
category: 'Best Practices',
8+
description: 'Suggest using toStrictEqual()',
9+
recommended: false,
10+
},
11+
messages: {
12+
useToStrictEqual: 'Use toStrictEqual() instead',
13+
},
14+
fixable: 'code',
15+
schema: [],
16+
type: 'suggestion',
17+
},
18+
defaultOptions: [],
19+
create(context) {
20+
return {
21+
CallExpression(node) {
22+
if (!isExpectCallWithParent(node)) {
23+
return;
24+
}
25+
26+
const methodNode = node.parent.property;
27+
28+
if (methodNode && methodNode.name === 'toEqual') {
29+
context.report({
30+
fix(fixer) {
31+
return [fixer.replaceText(methodNode, 'toStrictEqual')];
32+
},
33+
messageId: 'useToStrictEqual',
34+
node: methodNode,
35+
});
36+
}
37+
},
38+
};
39+
},
40+
});

src/rules/tsUtils.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,66 @@ export const createRule = ESLintUtils.RuleCreator(name => {
1515
return `${REPO_URL}/blob/v${version}/docs/rules/${ruleName}.md`;
1616
});
1717

18+
interface JestExpectIdentifier extends TSESTree.Identifier {
19+
name: 'expect';
20+
}
21+
22+
/**
23+
* Checks if the given `node` is considered a {@link JestExpectIdentifier}.
24+
*
25+
* A `node` is considered to be as such if it is of type `Identifier`,
26+
* and `name`d `"expect"`.
27+
*
28+
* @param {Node} node
29+
*
30+
* @return {node is JestExpectIdentifier}
31+
*/
32+
const isExpectIdentifier = (
33+
node: TSESTree.Node,
34+
): node is JestExpectIdentifier =>
35+
node.type === AST_NODE_TYPES.Identifier && node.name === 'expect';
36+
37+
// represents "expect()" specifically
38+
interface JestExpectCallExpression extends TSESTree.CallExpression {
39+
callee: JestExpectIdentifier;
40+
}
41+
42+
// represents expect usage like "expect().toBe" & "expect().not.toBe"
43+
interface JestExpectCallMemberExpression extends TSESTree.MemberExpression {
44+
object: JestExpectCallMemberExpression | JestExpectCallExpression;
45+
property: TSESTree.Identifier;
46+
}
47+
48+
// represents expect usage like "expect.anything" & "expect.hasAssertions"
49+
interface JestExpectNamespaceMemberExpression
50+
extends TSESTree.MemberExpression {
51+
object: JestExpectIdentifier;
52+
property: TSESTree.Identifier;
53+
}
54+
55+
/**
56+
* Checks if the given `node` is a {@link JestExpectCallExpression}.
57+
*
58+
* @param {Node} node
59+
*
60+
* @return {node is JestExpectCallExpression}
61+
*/
62+
const isExpectCall = (node: TSESTree.Node): node is JestExpectCallExpression =>
63+
node.type === AST_NODE_TYPES.CallExpression &&
64+
isExpectIdentifier(node.callee);
65+
66+
interface JestExpectCallWithParent extends JestExpectCallExpression {
67+
parent: JestExpectCallMemberExpression;
68+
}
69+
70+
export const isExpectCallWithParent = (
71+
node: TSESTree.Node,
72+
): node is JestExpectCallWithParent =>
73+
isExpectCall(node) &&
74+
node.parent !== undefined &&
75+
node.parent.type === AST_NODE_TYPES.MemberExpression &&
76+
node.parent.property.type === AST_NODE_TYPES.Identifier;
77+
1878
export enum DescribeAlias {
1979
'describe' = 'describe',
2080
'fdescribe' = 'fdescribe',

0 commit comments

Comments
 (0)