1
1
import { TSESTree , ASTUtils } from '@typescript-eslint/utils' ;
2
2
3
3
import { createTestingLibraryRule } from '../create-testing-library-rule' ;
4
+ import { isCallExpression , isMemberExpression } from '../node-utils' ;
4
5
import {
5
6
ALL_RETURNING_NODES ,
6
7
EVENT_HANDLER_METHODS ,
7
- EVENTS_SIMULATORS ,
8
+ resolveToTestingLibraryFn ,
8
9
} from '../utils' ;
9
10
10
11
export const RULE_NAME = 'no-node-access' ;
11
12
export type MessageIds = 'noNodeAccess' ;
12
13
export type Options = [ { allowContainerFirstChild : boolean } ] ;
13
14
14
- const ALL_PROHIBITED_MEMBERS = [
15
- ...ALL_RETURNING_NODES ,
16
- ...EVENT_HANDLER_METHODS ,
17
- ] as const ;
15
+ const userEventInstanceNames = new Set < string > ( ) ;
18
16
19
17
export default createTestingLibraryRule < Options , MessageIds > ( {
20
18
name : RULE_NAME ,
@@ -65,20 +63,11 @@ export default createTestingLibraryRule<Options, MessageIds>({
65
63
? node . property . name
66
64
: null ;
67
65
68
- const objectName = ASTUtils . isIdentifier ( node . object )
69
- ? node . object . name
70
- : null ;
71
66
if (
72
67
propertyName &&
73
- ALL_PROHIBITED_MEMBERS . some (
68
+ ALL_RETURNING_NODES . some (
74
69
( allReturningNode ) => allReturningNode === propertyName
75
- ) &&
76
- ! [
77
- ...EVENTS_SIMULATORS ,
78
- // TODO: As discussed in https://github.com/testing-library/eslint-plugin-testing-library/issues/1024, this is just a temporary workaround.
79
- // We should address the root cause and implement a proper solution instead of explicitly excluding 'user' here.
80
- 'user' ,
81
- ] . some ( ( simulator ) => simulator === objectName )
70
+ )
82
71
) {
83
72
if ( allowContainerFirstChild && propertyName === 'firstChild' ) {
84
73
return ;
@@ -100,6 +89,51 @@ export default createTestingLibraryRule<Options, MessageIds>({
100
89
}
101
90
102
91
return {
92
+ CallExpression ( node : TSESTree . CallExpression ) {
93
+ const { callee } = node ;
94
+ const property = isMemberExpression ( callee ) ? callee . property : null ;
95
+ const object = isMemberExpression ( callee ) ? callee . object : null ;
96
+
97
+ const propertyName = ASTUtils . isIdentifier ( property )
98
+ ? property . name
99
+ : null ;
100
+ const objectName = ASTUtils . isIdentifier ( object ) ? object . name : null ;
101
+
102
+ const isEventHandlerMethod = EVENT_HANDLER_METHODS . some (
103
+ ( method ) => method === propertyName
104
+ ) ;
105
+ const hasUserEventInstanceName = userEventInstanceNames . has (
106
+ objectName ?? ''
107
+ ) ;
108
+ const testingLibraryFn = resolveToTestingLibraryFn ( node , context ) ;
109
+
110
+ if (
111
+ ! testingLibraryFn &&
112
+ isEventHandlerMethod &&
113
+ ! hasUserEventInstanceName
114
+ ) {
115
+ context . report ( {
116
+ node,
117
+ loc : property ?. loc . start ,
118
+ messageId : 'noNodeAccess' ,
119
+ } ) ;
120
+ }
121
+ } ,
122
+ VariableDeclarator ( node : TSESTree . VariableDeclarator ) {
123
+ const { init, id } = node ;
124
+ if (
125
+ init &&
126
+ isCallExpression ( init ) &&
127
+ isMemberExpression ( init . callee ) &&
128
+ ASTUtils . isIdentifier ( init . callee . object ) &&
129
+ init . callee . object . name === 'userEvent' &&
130
+ ASTUtils . isIdentifier ( init . callee . property ) &&
131
+ init . callee . property . name === 'setup' &&
132
+ ASTUtils . isIdentifier ( id )
133
+ ) {
134
+ userEventInstanceNames . add ( id . name ) ;
135
+ }
136
+ } ,
103
137
'ExpressionStatement MemberExpression' : showErrorForNodeAccess ,
104
138
'VariableDeclarator MemberExpression' : showErrorForNodeAccess ,
105
139
} ;
0 commit comments