Skip to content

Commit 40e71ae

Browse files
jrfnlgsherwood
authored andcommitted
BackfillFnTokenTest: fix bug in the tests
The scope closers weren't being tested properly as the local `$closer` variable was looking for the wrong array index. Once that was enabled, it exposed another issue in the tests: nested arrow functions with a scope closer being shared with the "outer" arrow function did not have the correct expectations set. Fixed now by: * Selectively skipping the 'scope_condition' check for the scope closer in the `backfillHelper()` method. * Checking that the `scope_opener` for such shared `scope_closer`s actually points to the "outer" arrow function.
1 parent cd7bee2 commit 40e71ae

File tree

1 file changed

+36
-29
lines changed

1 file changed

+36
-29
lines changed

tests/Core/Tokenizer/BackfillFnTokenTest.php

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public function testSimple()
3737
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 5), 'Opener scope opener is not the arrow token');
3838
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 12), 'Opener scope closer is not the semicolon token');
3939

40-
$closer = $tokens[$token]['scope_opener'];
40+
$closer = $tokens[$token]['scope_closer'];
4141
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 5), 'Closer scope opener is not the arrow token');
4242
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 12), 'Closer scope closer is not the semicolon token');
4343
}
@@ -66,7 +66,7 @@ public function testWhitespace()
6666
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 6), 'Opener scope opener is not the arrow token');
6767
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 13), 'Opener scope closer is not the semicolon token');
6868

69-
$closer = $tokens[$token]['scope_opener'];
69+
$closer = $tokens[$token]['scope_closer'];
7070
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 6), 'Closer scope opener is not the arrow token');
7171
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 13), 'Closer scope closer is not the semicolon token');
7272

@@ -94,7 +94,7 @@ public function testComment()
9494
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 8), 'Opener scope opener is not the arrow token');
9595
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 15), 'Opener scope closer is not the semicolon token');
9696

97-
$closer = $tokens[$token]['scope_opener'];
97+
$closer = $tokens[$token]['scope_closer'];
9898
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 8), 'Closer scope opener is not the arrow token');
9999
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 15), 'Closer scope closer is not the semicolon token');
100100

@@ -122,7 +122,7 @@ public function testHeredoc()
122122
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 4), 'Opener scope opener is not the arrow token');
123123
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 9), 'Opener scope closer is not the semicolon token');
124124

125-
$closer = $tokens[$token]['scope_opener'];
125+
$closer = $tokens[$token]['scope_closer'];
126126
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 4), 'Closer scope opener is not the arrow token');
127127
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 9), 'Closer scope closer is not the semicolon token');
128128

@@ -150,7 +150,7 @@ public function testNestedOuter()
150150
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 5), 'Opener scope opener is not the arrow token');
151151
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 25), 'Opener scope closer is not the semicolon token');
152152

153-
$closer = $tokens[$token]['scope_opener'];
153+
$closer = $tokens[$token]['scope_closer'];
154154
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 5), 'Closer scope opener is not the arrow token');
155155
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 25), 'Closer scope closer is not the semicolon token');
156156

@@ -169,7 +169,7 @@ public function testNestedInner()
169169
$tokens = self::$phpcsFile->getTokens();
170170

171171
$token = $this->getTargetToken('/* testNestedInner */', T_FN);
172-
$this->backfillHelper($token);
172+
$this->backfillHelper($token, true);
173173

174174
$this->assertSame($tokens[$token]['scope_opener'], ($token + 5), 'Scope opener is not the arrow token');
175175
$this->assertSame($tokens[$token]['scope_closer'], ($token + 16), 'Scope closer is not the semicolon token');
@@ -178,8 +178,8 @@ public function testNestedInner()
178178
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 5), 'Opener scope opener is not the arrow token');
179179
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 16), 'Opener scope closer is not the semicolon token');
180180

181-
$closer = $tokens[$token]['scope_opener'];
182-
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 5), 'Closer scope opener is not the arrow token');
181+
$closer = $tokens[$token]['scope_closer'];
182+
$this->assertSame($tokens[$closer]['scope_opener'], ($token - 4), 'Closer scope opener is not the arrow token of the "outer" arrow function (shared scope closer)');
183183
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 16), 'Closer scope closer is not the semicolon token');
184184

185185
}//end testNestedInner()
@@ -206,7 +206,7 @@ public function testFunctionCall()
206206
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 5), 'Opener scope opener is not the arrow token');
207207
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 17), 'Opener scope closer is not the semicolon token');
208208

209-
$closer = $tokens[$token]['scope_opener'];
209+
$closer = $tokens[$token]['scope_closer'];
210210
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 5), 'Closer scope opener is not the arrow token');
211211
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 17), 'Closer scope closer is not the semicolon token');
212212

@@ -234,7 +234,7 @@ public function testChainedFunctionCall()
234234
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 5), 'Opener scope opener is not the arrow token');
235235
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 12), 'Opener scope closer is not the bracket token');
236236

237-
$closer = $tokens[$token]['scope_opener'];
237+
$closer = $tokens[$token]['scope_closer'];
238238
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 5), 'Closer scope opener is not the arrow token');
239239
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 12), 'Closer scope closer is not the bracket token');
240240

@@ -262,7 +262,7 @@ public function testFunctionArgument()
262262
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 8), 'Opener scope opener is not the arrow token');
263263
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 15), 'Opener scope closer is not the comma token');
264264

265-
$closer = $tokens[$token]['scope_opener'];
265+
$closer = $tokens[$token]['scope_closer'];
266266
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 8), 'Closer scope opener is not the arrow token');
267267
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 15), 'Closer scope closer is not the comma token');
268268

@@ -290,7 +290,7 @@ public function testClosure()
290290
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 5), 'Opener scope opener is not the arrow token');
291291
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 60), 'Opener scope closer is not the comma token');
292292

293-
$closer = $tokens[$token]['scope_opener'];
293+
$closer = $tokens[$token]['scope_closer'];
294294
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 5), 'Closer scope opener is not the arrow token');
295295
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 60), 'Closer scope closer is not the comma token');
296296

@@ -318,7 +318,7 @@ public function testReturnType()
318318
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 11), 'Opener scope opener is not the arrow token');
319319
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 18), 'Opener scope closer is not the comma token');
320320

321-
$closer = $tokens[$token]['scope_opener'];
321+
$closer = $tokens[$token]['scope_closer'];
322322
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 11), 'Closer scope opener is not the arrow token');
323323
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 18), 'Closer scope closer is not the comma token');
324324

@@ -346,7 +346,7 @@ public function testReference()
346346
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 6), 'Opener scope opener is not the arrow token');
347347
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 9), 'Opener scope closer is not the semicolon token');
348348

349-
$closer = $tokens[$token]['scope_opener'];
349+
$closer = $tokens[$token]['scope_closer'];
350350
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 6), 'Closer scope opener is not the arrow token');
351351
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 9), 'Closer scope closer is not the semicolon token');
352352

@@ -374,7 +374,7 @@ public function testGrouped()
374374
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 5), 'Opener scope opener is not the arrow token');
375375
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 8), 'Opener scope closer is not the semicolon token');
376376

377-
$closer = $tokens[$token]['scope_opener'];
377+
$closer = $tokens[$token]['scope_closer'];
378378
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 5), 'Closer scope opener is not the arrow token');
379379
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 8), 'Closer scope closer is not the semicolon token');
380380

@@ -402,7 +402,7 @@ public function testArrayValue()
402402
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 4), 'Opener scope opener is not the arrow token');
403403
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 9), 'Opener scope closer is not the comma token');
404404

405-
$closer = $tokens[$token]['scope_opener'];
405+
$closer = $tokens[$token]['scope_closer'];
406406
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 4), 'Closer scope opener is not the arrow token');
407407
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 9), 'Closer scope closer is not the comma token');
408408

@@ -430,7 +430,7 @@ public function testYield()
430430
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 5), 'Opener scope opener is not the arrow token');
431431
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 14), 'Opener scope closer is not the semicolon token');
432432

433-
$closer = $tokens[$token]['scope_opener'];
433+
$closer = $tokens[$token]['scope_closer'];
434434
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 5), 'Closer scope opener is not the arrow token');
435435
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 14), 'Closer scope closer is not the semicolon token');
436436

@@ -458,7 +458,7 @@ public function testNullableNamespace()
458458
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 15), 'Opener scope opener is not the arrow token');
459459
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 18), 'Opener scope closer is not the semicolon token');
460460

461-
$closer = $tokens[$token]['scope_opener'];
461+
$closer = $tokens[$token]['scope_closer'];
462462
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 15), 'Closer scope opener is not the arrow token');
463463
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 18), 'Closer scope closer is not the semicolon token');
464464

@@ -495,7 +495,7 @@ public function testKeywordReturnTypes()
495495
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 11), "Opener scope opener is not the arrow token(for $marker)");
496496
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 14), "Opener scope closer is not the semicolon token(for $marker)");
497497

498-
$closer = $tokens[$token]['scope_opener'];
498+
$closer = $tokens[$token]['scope_closer'];
499499
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 11), "Closer scope opener is not the arrow token(for $marker)");
500500
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 14), "Closer scope closer is not the semicolon token(for $marker)");
501501
}
@@ -524,7 +524,7 @@ public function testTernary()
524524
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 5), 'Opener scope opener is not the arrow token');
525525
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 40), 'Opener scope closer is not the semicolon token');
526526

527-
$closer = $tokens[$token]['scope_opener'];
527+
$closer = $tokens[$token]['scope_closer'];
528528
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 5), 'Closer scope opener is not the arrow token');
529529
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 40), 'Closer scope closer is not the semicolon token');
530530

@@ -538,12 +538,12 @@ public function testTernary()
538538
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 8), 'Opener scope opener for THEN is not the arrow token');
539539
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 12), 'Opener scope closer for THEN is not the semicolon token');
540540

541-
$closer = $tokens[$token]['scope_opener'];
541+
$closer = $tokens[$token]['scope_closer'];
542542
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 8), 'Closer scope opener for THEN is not the arrow token');
543543
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 12), 'Closer scope closer for THEN is not the semicolon token');
544544

545545
$token = $this->getTargetToken('/* testTernaryElse */', T_FN);
546-
$this->backfillHelper($token);
546+
$this->backfillHelper($token, true);
547547

548548
$this->assertSame($tokens[$token]['scope_opener'], ($token + 8), 'Scope opener for ELSE is not the arrow token');
549549
$this->assertSame($tokens[$token]['scope_closer'], ($token + 11), 'Scope closer for ELSE is not the semicolon token');
@@ -552,8 +552,8 @@ public function testTernary()
552552
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 8), 'Opener scope opener for ELSE is not the arrow token');
553553
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 11), 'Opener scope closer for ELSE is not the semicolon token');
554554

555-
$closer = $tokens[$token]['scope_opener'];
556-
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 8), 'Closer scope opener for ELSE is not the arrow token');
555+
$closer = $tokens[$token]['scope_closer'];
556+
$this->assertSame($tokens[$closer]['scope_opener'], ($token - 24), 'Closer scope opener for ELSE is not the arrow token of the "outer" arrow function (shared scope closer)');
557557
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 11), 'Closer scope closer for ELSE is not the semicolon token');
558558

559559
}//end testTernary()
@@ -580,7 +580,7 @@ public function testNestedInMethod()
580580
$this->assertSame($tokens[$opener]['scope_opener'], ($token + 5), 'Opener scope opener is not the arrow token');
581581
$this->assertSame($tokens[$opener]['scope_closer'], ($token + 17), 'Opener scope closer is not the semicolon token');
582582

583-
$closer = $tokens[$token]['scope_opener'];
583+
$closer = $tokens[$token]['scope_closer'];
584584
$this->assertSame($tokens[$closer]['scope_opener'], ($token + 5), 'Closer scope opener is not the arrow token');
585585
$this->assertSame($tokens[$closer]['scope_closer'], ($token + 17), 'Closer scope closer is not the semicolon token');
586586

@@ -671,11 +671,16 @@ public function dataNotAnArrowFunction()
671671
/**
672672
* Helper function to check that all token keys are correctly set for T_FN tokens.
673673
*
674-
* @param string $token The T_FN token to check.
674+
* @param string $token The T_FN token to check.
675+
* @param bool $skipScopeCloserCheck Whether to skip the scope closer check.
676+
* This should be set to "true" when testing nested arrow functions,
677+
* where the "inner" arrow function shares a scope closer with the
678+
* "outer" arrow function, as the 'scope_condition' for the scope closer
679+
* of the "inner" arrow function will point to the "outer" arrow function.
675680
*
676681
* @return void
677682
*/
678-
private function backfillHelper($token)
683+
private function backfillHelper($token, $skipScopeCloserCheck=false)
679684
{
680685
$tokens = self::$phpcsFile->getTokens();
681686

@@ -694,11 +699,13 @@ private function backfillHelper($token)
694699
$this->assertTrue(array_key_exists('scope_closer', $tokens[$opener]), 'Opener scope closer is not set');
695700
$this->assertSame($tokens[$opener]['scope_condition'], $token, 'Opener scope condition is not the T_FN token');
696701

697-
$closer = $tokens[$token]['scope_opener'];
702+
$closer = $tokens[$token]['scope_closer'];
698703
$this->assertTrue(array_key_exists('scope_condition', $tokens[$closer]), 'Closer scope condition is not set');
699704
$this->assertTrue(array_key_exists('scope_opener', $tokens[$closer]), 'Closer scope opener is not set');
700705
$this->assertTrue(array_key_exists('scope_closer', $tokens[$closer]), 'Closer scope closer is not set');
701-
$this->assertSame($tokens[$closer]['scope_condition'], $token, 'Closer scope condition is not the T_FN token');
706+
if ($skipScopeCloserCheck === false) {
707+
$this->assertSame($tokens[$closer]['scope_condition'], $token, 'Closer scope condition is not the T_FN token');
708+
}
702709

703710
$opener = $tokens[$token]['parenthesis_opener'];
704711
$this->assertTrue(array_key_exists('parenthesis_owner', $tokens[$opener]), 'Opening parenthesis owner is not set');

0 commit comments

Comments
 (0)