@@ -2,6 +2,10 @@ import { TSESTree } from '@typescript-eslint/experimental-utils';
2
2
import {
3
3
getPropertyIdentifierNode ,
4
4
isExpressionStatement ,
5
+ isVariableDeclaration ,
6
+ isAssignmentExpression ,
7
+ isCallExpression ,
8
+ isSequenceExpression ,
5
9
} from '../node-utils' ;
6
10
import { createTestingLibraryRule } from '../create-testing-library-rule' ;
7
11
@@ -32,7 +36,11 @@ export default createTestingLibraryRule<Options, MessageIds>({
32
36
defaultOptions : [ ] ,
33
37
create : function ( context , _ , helpers ) {
34
38
function isCallerWaitFor (
35
- node : TSESTree . BlockStatement | TSESTree . CallExpression
39
+ node :
40
+ | TSESTree . BlockStatement
41
+ | TSESTree . CallExpression
42
+ | TSESTree . AssignmentExpression
43
+ | TSESTree . SequenceExpression
36
44
) : boolean {
37
45
if ( ! node . parent ) {
38
46
return false ;
@@ -48,22 +56,78 @@ export default createTestingLibraryRule<Options, MessageIds>({
48
56
) ;
49
57
}
50
58
59
+ function isRenderInVariableDeclaration ( node : TSESTree . Node ) {
60
+ return (
61
+ isVariableDeclaration ( node ) &&
62
+ node . declarations . some ( helpers . isRenderVariableDeclarator )
63
+ ) ;
64
+ }
65
+
66
+ function isRenderInExpressionStatement ( node : TSESTree . Node ) {
67
+ if (
68
+ ! isExpressionStatement ( node ) ||
69
+ ! isAssignmentExpression ( node . expression )
70
+ ) {
71
+ return false ;
72
+ }
73
+
74
+ const expressionIdentifier = getPropertyIdentifierNode (
75
+ node . expression . right
76
+ ) ;
77
+
78
+ if ( ! expressionIdentifier ) {
79
+ return false ;
80
+ }
81
+
82
+ return helpers . isRenderUtil ( expressionIdentifier ) ;
83
+ }
84
+
85
+ function isRenderInAssignmentExpression ( node : TSESTree . Node ) {
86
+ if ( ! isAssignmentExpression ( node ) ) {
87
+ return false ;
88
+ }
89
+
90
+ const expressionIdentifier = getPropertyIdentifierNode ( node . right ) ;
91
+ if ( ! expressionIdentifier ) {
92
+ return false ;
93
+ }
94
+
95
+ return helpers . isRenderUtil ( expressionIdentifier ) ;
96
+ }
97
+
98
+ function isRenderInSequenceAssignment ( node : TSESTree . Node ) {
99
+ if ( ! isSequenceExpression ( node ) ) {
100
+ return false ;
101
+ }
102
+
103
+ return node . expressions . some ( isRenderInAssignmentExpression ) ;
104
+ }
105
+
51
106
function getSideEffectNodes (
52
107
body : TSESTree . Node [ ]
53
108
) : TSESTree . ExpressionStatement [ ] {
54
109
return body . filter ( ( node ) => {
55
- if ( ! isExpressionStatement ( node ) ) {
110
+ if ( ! isExpressionStatement ( node ) && ! isVariableDeclaration ( node ) ) {
56
111
return false ;
57
112
}
58
113
114
+ if (
115
+ isRenderInVariableDeclaration ( node ) ||
116
+ isRenderInExpressionStatement ( node )
117
+ ) {
118
+ return true ;
119
+ }
120
+
59
121
const expressionIdentifier = getPropertyIdentifierNode ( node ) ;
122
+
60
123
if ( ! expressionIdentifier ) {
61
124
return false ;
62
125
}
63
126
64
127
return (
65
128
helpers . isFireEventUtil ( expressionIdentifier ) ||
66
- helpers . isUserEventUtil ( expressionIdentifier )
129
+ helpers . isUserEventUtil ( expressionIdentifier ) ||
130
+ helpers . isRenderUtil ( expressionIdentifier )
67
131
) ;
68
132
} ) as TSESTree . ExpressionStatement [ ] ;
69
133
}
@@ -81,19 +145,33 @@ export default createTestingLibraryRule<Options, MessageIds>({
81
145
) ;
82
146
}
83
147
84
- function reportImplicitReturnSideEffect ( node : TSESTree . CallExpression ) {
148
+ function reportImplicitReturnSideEffect (
149
+ node :
150
+ | TSESTree . CallExpression
151
+ | TSESTree . AssignmentExpression
152
+ | TSESTree . SequenceExpression
153
+ ) {
85
154
if ( ! isCallerWaitFor ( node ) ) {
86
155
return ;
87
156
}
88
157
89
- const expressionIdentifier = getPropertyIdentifierNode ( node . callee ) ;
90
- if ( ! expressionIdentifier ) {
158
+ const expressionIdentifier = isCallExpression ( node )
159
+ ? getPropertyIdentifierNode ( node . callee )
160
+ : null ;
161
+
162
+ if (
163
+ ! expressionIdentifier &&
164
+ ! isRenderInAssignmentExpression ( node ) &&
165
+ ! isRenderInSequenceAssignment ( node )
166
+ ) {
91
167
return ;
92
168
}
93
169
94
170
if (
171
+ expressionIdentifier &&
95
172
! helpers . isFireEventUtil ( expressionIdentifier ) &&
96
- ! helpers . isUserEventUtil ( expressionIdentifier )
173
+ ! helpers . isUserEventUtil ( expressionIdentifier ) &&
174
+ ! helpers . isRenderUtil ( expressionIdentifier )
97
175
) {
98
176
return ;
99
177
}
@@ -107,6 +185,8 @@ export default createTestingLibraryRule<Options, MessageIds>({
107
185
return {
108
186
'CallExpression > ArrowFunctionExpression > BlockStatement' : reportSideEffects ,
109
187
'CallExpression > ArrowFunctionExpression > CallExpression' : reportImplicitReturnSideEffect ,
188
+ 'CallExpression > ArrowFunctionExpression > AssignmentExpression' : reportImplicitReturnSideEffect ,
189
+ 'CallExpression > ArrowFunctionExpression > SequenceExpression' : reportImplicitReturnSideEffect ,
110
190
'CallExpression > FunctionExpression > BlockStatement' : reportSideEffects ,
111
191
} ;
112
192
} ,
0 commit comments