@@ -7,8 +7,10 @@ import {
77 getStatementCallExpression ,
88 isEmptyFunction ,
99 isExpressionStatement ,
10+ isMemberExpression ,
1011 isReturnStatement ,
1112} from '../node-utils' ;
13+ import { resolveToTestingLibraryFn } from '../utils' ;
1214
1315import type { TSESTree } from '@typescript-eslint/utils' ;
1416
@@ -58,6 +60,8 @@ export default createTestingLibraryRule<Options, MessageIds>({
5860 ] ,
5961
6062 create ( context , [ { isStrict = true } ] , helpers ) {
63+ const userEventInstanceNames = new Set < string > ( ) ;
64+
6165 function getStatementIdentifier ( statement : TSESTree . Statement ) {
6266 const callExpression = getStatementCallExpression ( statement ) ;
6367
@@ -87,11 +91,18 @@ export default createTestingLibraryRule<Options, MessageIds>({
8791 return null ;
8892 }
8993
90- /**
91- * Determines whether some call is non Testing Library related for a given list of statements.
92- */
93- function hasSomeNonTestingLibraryCall (
94- statements : TSESTree . Statement [ ]
94+ function hasUserEventInstanceName ( identifier : TSESTree . Identifier ) {
95+ if ( ! isMemberExpression ( identifier . parent ) ) {
96+ return false ;
97+ }
98+
99+ const propertyIdentifier = getPropertyIdentifierNode ( identifier . parent ) ;
100+ return userEventInstanceNames . has ( propertyIdentifier ?. name ?? '' ) ;
101+ }
102+
103+ function hasStatementReference (
104+ statements : TSESTree . Statement [ ] ,
105+ predicate : ( identifier : TSESTree . Identifier ) => boolean
95106 ) : boolean {
96107 return statements . some ( ( statement ) => {
97108 const identifier = getStatementIdentifier ( statement ) ;
@@ -100,20 +111,31 @@ export default createTestingLibraryRule<Options, MessageIds>({
100111 return false ;
101112 }
102113
103- return ! helpers . isTestingLibraryUtil ( identifier ) ;
114+ return predicate ( identifier ) ;
104115 } ) ;
105116 }
106117
107- function hasTestingLibraryCall ( statements : TSESTree . Statement [ ] ) {
108- return statements . some ( ( statement ) => {
109- const identifier = getStatementIdentifier ( statement ) ;
110-
111- if ( ! identifier ) {
112- return false ;
113- }
118+ /**
119+ * Determines whether some call is non Testing Library related for a given list of statements.
120+ */
121+ function hasSomeNonTestingLibraryCall (
122+ statements : TSESTree . Statement [ ]
123+ ) : boolean {
124+ return hasStatementReference (
125+ statements ,
126+ ( identifier ) =>
127+ ! helpers . isTestingLibraryUtil ( identifier ) &&
128+ ! hasUserEventInstanceName ( identifier )
129+ ) ;
130+ }
114131
115- return helpers . isTestingLibraryUtil ( identifier ) ;
116- } ) ;
132+ function hasTestingLibraryCall ( statements : TSESTree . Statement [ ] ) {
133+ return hasStatementReference (
134+ statements ,
135+ ( identifier ) =>
136+ helpers . isTestingLibraryUtil ( identifier ) ||
137+ hasUserEventInstanceName ( identifier )
138+ ) ;
117139 }
118140
119141 function checkNoUnnecessaryActFromBlockStatement (
@@ -196,7 +218,24 @@ export default createTestingLibraryRule<Options, MessageIds>({
196218 } ) ;
197219 }
198220
221+ function registerUserEventInstance (
222+ node : TSESTree . CallExpression & { parent : TSESTree . VariableDeclarator }
223+ ) {
224+ const propertyIdentifier = getPropertyIdentifierNode ( node ) ;
225+ const deepestIdentifier = getDeepestIdentifierNode ( node ) ;
226+ const testingLibraryFn = resolveToTestingLibraryFn ( node , context ) ;
227+
228+ if (
229+ propertyIdentifier ?. name === testingLibraryFn ?. local &&
230+ deepestIdentifier ?. name === 'setup' &&
231+ ASTUtils . isIdentifier ( node . parent ?. id )
232+ ) {
233+ userEventInstanceNames . add ( node . parent . id . name ) ;
234+ }
235+ }
236+
199237 return {
238+ 'VariableDeclarator > CallExpression' : registerUserEventInstance ,
200239 'CallExpression > ArrowFunctionExpression > BlockStatement' :
201240 checkNoUnnecessaryActFromBlockStatement ,
202241 'CallExpression > FunctionExpression > BlockStatement' :
0 commit comments