@@ -143,58 +143,71 @@ fn is_correct_place_to_call_expect<'a>(
143143 id_nodes_mapping : & FxHashMap < NodeId , & PossibleJestNode < ' a , ' _ > > ,
144144 ctx : & LintContext < ' a > ,
145145) -> Option < ( ) > {
146- let mut parent = ctx . nodes ( ) . parent_node ( node. id ( ) ) ;
146+ let mut current_node = node;
147147
148- // loop until find the closest function body
149- while !matches ! ( parent. kind( ) , AstKind :: FunctionBody ( _) | AstKind :: Program ( _) ) {
150- parent = ctx. nodes ( ) . parent_node ( parent. id ( ) ) ;
151- }
148+ // Walk up the tree, checking each function scope
149+ loop {
150+ let mut current = ctx. nodes ( ) . parent_node ( current_node. id ( ) ) ;
152151
153- let parent = ctx. nodes ( ) . parent_node ( parent. id ( ) ) ;
152+ // loop until find the closest function body
153+ while !matches ! ( current. kind( ) , AstKind :: FunctionBody ( _) | AstKind :: Program ( _) ) {
154+ current = ctx. nodes ( ) . parent_node ( current. id ( ) ) ;
155+ }
154156
155- match parent. kind ( ) {
156- AstKind :: Function ( function) => {
157- // `function foo() { expect(1).toBe(1); }`
158- if function. is_function_declaration ( ) {
159- return Some ( ( ) ) ;
160- }
157+ // If we reached the program root without finding a test block, it's invalid
158+ if matches ! ( current. kind( ) , AstKind :: Program ( _) ) {
159+ return None ;
160+ }
161161
162- if function. is_expression ( ) {
163- let grandparent = ctx. nodes ( ) . parent_node ( parent. id ( ) ) ;
162+ let parent = ctx. nodes ( ) . parent_node ( current. id ( ) ) ;
163+
164+ match parent. kind ( ) {
165+ AstKind :: Function ( function) => {
166+ // `function foo() { expect(1).toBe(1); }`
167+ if function. is_function_declaration ( ) {
168+ return Some ( ( ) ) ;
169+ }
170+
171+ if function. is_expression ( ) {
172+ let grandparent = ctx. nodes ( ) . parent_node ( parent. id ( ) ) ;
173+
174+ // `test('foo', function () { expect(1).toBe(1) })`
175+ // `const foo = function() {expect(1).toBe(1)}`
176+ if is_var_declarator_or_test_block (
177+ grandparent,
178+ additional_test_block_functions,
179+ id_nodes_mapping,
180+ ctx,
181+ ) {
182+ return Some ( ( ) ) ;
183+ }
164184
165- // `test('foo', function () { expect(1).toBe(1) })`
166- // `const foo = function() {expect(1).toBe(1)}`
167- return if is_var_declarator_or_test_block (
185+ // Continue checking parent scopes
186+ current_node = parent;
187+ } else {
188+ // Function that's neither a declaration nor expression - shouldn't reach here
189+ return None ;
190+ }
191+ }
192+ AstKind :: ArrowFunctionExpression ( _) => {
193+ let grandparent = ctx. nodes ( ) . parent_node ( parent. id ( ) ) ;
194+ // `test('foo', () => expect(1).toBe(1))`
195+ // `const foo = () => expect(1).toBe(1)`
196+ if is_var_declarator_or_test_block (
168197 grandparent,
169198 additional_test_block_functions,
170199 id_nodes_mapping,
171200 ctx,
172201 ) {
173- Some ( ( ) )
174- } else {
175- None
176- } ;
202+ return Some ( ( ) ) ;
203+ }
204+
205+ // Continue checking parent scopes
206+ current_node = parent;
177207 }
208+ _ => return None ,
178209 }
179- AstKind :: ArrowFunctionExpression ( _) => {
180- let grandparent = ctx. nodes ( ) . parent_node ( parent. id ( ) ) ;
181- // `test('foo', () => expect(1).toBe(1))`
182- // `const foo = () => expect(1).toBe(1)`
183- return if is_var_declarator_or_test_block (
184- grandparent,
185- additional_test_block_functions,
186- id_nodes_mapping,
187- ctx,
188- ) {
189- Some ( ( ) )
190- } else {
191- None
192- } ;
193- }
194- _ => { }
195210 }
196-
197- None
198211}
199212
200213fn is_var_declarator_or_test_block < ' a > (
0 commit comments