@@ -94,18 +94,21 @@ export default createRule({
9494 ...( options . customMatchers || [ ] ) ,
9595 ] )
9696
97- function checkValidity ( node : ESTree . Node ) {
97+ function checkValidity ( node : ESTree . Node , visited : Set < ESTree . Node > ) {
9898 const parent = getParent ( node )
9999 if ( ! parent ) return false
100100
101+ if ( visited . has ( parent ) ) return false
102+ visited . add ( parent )
103+
101104 // If the parent is a valid type (e.g. return or await), we don't need to
102105 // check any further.
103106 if ( validTypes . has ( parent . type ) ) return true
104107
105108 // If the parent is an array, we need to check the grandparent to see if
106109 // it's a Promise.all, or a variable.
107110 if ( parent . type === 'ArrayExpression' ) {
108- return checkValidity ( parent )
111+ return checkValidity ( parent , visited )
109112 }
110113
111114 // If the parent is a call expression, we need to check the grandparent
@@ -127,12 +130,12 @@ export default createRule({
127130
128131 for ( const ref of scope . references ) {
129132 const refParent = ( ref . identifier as Rule . Node ) . parent
130-
133+ if ( visited . has ( refParent ) ) continue
131134 // If the parent of the reference is valid, we can immediately return
132135 // true. Otherwise, we'll check the validity of the parent to continue
133136 // the loop.
134137 if ( validTypes . has ( refParent . type ) ) return true
135- if ( checkValidity ( refParent ) ) return true
138+ if ( checkValidity ( refParent , visited ) ) return true
136139 }
137140 }
138141
@@ -145,7 +148,7 @@ export default createRule({
145148 if ( call ?. type !== 'step' && call ?. type !== 'expect' ) return
146149
147150 const result = getCallType ( call , awaitableMatchers )
148- const isValid = result ? checkValidity ( node ) : false
151+ const isValid = result ? checkValidity ( node , new Set ( ) ) : false
149152
150153 if ( result && ! isValid ) {
151154 context . report ( {
0 commit comments