Skip to content

Commit 5c4bb45

Browse files
committed
refactor(no-unnecessary-act): detect act from React DOM test utils
1 parent 25809e3 commit 5c4bb45

File tree

3 files changed

+216
-55
lines changed

3 files changed

+216
-55
lines changed

lib/create-testing-library-rule/detect-testing-library-utils.ts

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,9 @@ import {
1717
isCallExpression,
1818
isImportDeclaration,
1919
isImportDefaultSpecifier,
20-
isImportNamespaceSpecifier,
2120
isImportSpecifier,
2221
isLiteral,
2322
isMemberExpression,
24-
isObjectPattern,
25-
isProperty,
2623
} from '../node-utils';
2724
import {
2825
ABSENCE_MATCHERS,
@@ -627,8 +624,15 @@ export function detectTestingLibraryUtils<
627624
);
628625
};
629626

627+
/**
628+
* Determines whether a given node is some reportable `act` util.
629+
*
630+
* An `act` is reportable if some of these conditions is met:
631+
* - it's related to Testing Library module (this depends on Aggressive Reporting)
632+
* - it's related to React DOM Test Utils
633+
*/
630634
const isActUtil = (node: TSESTree.Identifier): boolean => {
631-
return isPotentialTestingLibraryFunction(
635+
const isTestingLibraryAct = isPotentialTestingLibraryFunction(
632636
node,
633637
(identifierNodeName, originalNodeName) => {
634638
return [identifierNodeName, originalNodeName]
@@ -637,7 +641,65 @@ export function detectTestingLibraryUtils<
637641
}
638642
);
639643

640-
// TODO: check if `act` coming from 'react-dom/test-utils'
644+
const isReactDomTestUtilsAct = (() => {
645+
if (!importedReactDomTestUtilsNode) {
646+
return false;
647+
}
648+
const referenceNode = getReferenceNode(node);
649+
const referenceNodeIdentifier = getPropertyIdentifierNode(
650+
referenceNode
651+
);
652+
if (!referenceNodeIdentifier) {
653+
return false;
654+
}
655+
656+
const importedUtilSpecifier = findImportSpecifier(
657+
node.name,
658+
importedReactDomTestUtilsNode
659+
);
660+
if (!importedUtilSpecifier) {
661+
return false;
662+
}
663+
664+
const importDeclaration = (() => {
665+
if (isImportDeclaration(importedUtilSpecifier.parent)) {
666+
return importedUtilSpecifier.parent;
667+
}
668+
669+
const variableDeclarator = findClosestVariableDeclaratorNode(
670+
importedUtilSpecifier
671+
);
672+
673+
if (isCallExpression(variableDeclarator?.init)) {
674+
return variableDeclarator?.init;
675+
}
676+
677+
return undefined;
678+
})();
679+
if (!importDeclaration) {
680+
return false;
681+
}
682+
683+
const importDeclarationName = getImportModuleName(importDeclaration);
684+
if (!importDeclarationName) {
685+
return false;
686+
}
687+
688+
if (importDeclarationName !== REACT_DOM_TEST_UTILS_PACKAGE) {
689+
return false;
690+
}
691+
692+
const originalNodeName =
693+
isImportSpecifier(importedUtilSpecifier) &&
694+
importedUtilSpecifier.local.name !==
695+
importedUtilSpecifier.imported.name
696+
? importedUtilSpecifier.imported.name
697+
: undefined;
698+
699+
return [node.name, originalNodeName].filter(Boolean).includes('act');
700+
})();
701+
702+
return isTestingLibraryAct || isReactDomTestUtilsAct;
641703
};
642704

643705
const isTestingLibraryUtil = (node: TSESTree.Identifier): boolean => {
@@ -938,6 +1000,18 @@ export function detectTestingLibraryUtils<
9381000
) {
9391001
importedUserEventLibraryNode = callExpression;
9401002
}
1003+
1004+
if (
1005+
!importedReactDomTestUtilsNode &&
1006+
args.some(
1007+
(arg) =>
1008+
isLiteral(arg) &&
1009+
typeof arg.value === 'string' &&
1010+
arg.value === REACT_DOM_TEST_UTILS_PACKAGE
1011+
)
1012+
) {
1013+
importedReactDomTestUtilsNode = callExpression;
1014+
}
9411015
},
9421016
};
9431017

lib/node-utils/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ export function findImportSpecifier(
589589
);
590590
});
591591

592-
// it is "import { foo [as alias] } from 'baz'""
592+
// it is "import { foo [as alias] } from 'baz'"
593593
if (namedExport) {
594594
return namedExport;
595595
}

0 commit comments

Comments
 (0)