Browse Source

chore: BlocksAnalyzer - raise exception on invalid index (#7819)

Dariusz Rumiński 1 year ago
parent
commit
c1a9344ce4

+ 1 - 1
phpstan.dist.neon

@@ -21,7 +21,7 @@ parameters:
         -
             message: '#^Method PhpCsFixer\\Tests\\.+::provide.+Cases\(\) return type has no value type specified in iterable type iterable\.$#'
             path: tests
-            count: 1023
+            count: 1021
 
         -
             message: '#Call to static method .+ with .+ will always evaluate to true.$#'

+ 3 - 7
src/Tokenizer/Analyzer/BlocksAnalyzer.php

@@ -24,18 +24,14 @@ use PhpCsFixer\Tokenizer\Tokens;
  */
 final class BlocksAnalyzer
 {
-    public function isBlock(Tokens $tokens, ?int $openIndex, ?int $closeIndex): bool
+    public function isBlock(Tokens $tokens, int $openIndex, int $closeIndex): bool
     {
-        if (null === $openIndex || null === $closeIndex) {
-            return false;
-        }
-
         if (!$tokens->offsetExists($openIndex)) {
-            return false;
+            throw new \InvalidArgumentException(sprintf('Tokex index %d for potential block opening does not exist.', $openIndex));
         }
 
         if (!$tokens->offsetExists($closeIndex)) {
-            return false;
+            throw new \InvalidArgumentException(sprintf('Token index %d for potential block closure does not exist.', $closeIndex));
         }
 
         $blockType = $this->getBlockType($tokens[$openIndex]);

+ 32 - 11
tests/Tokenizer/Analyzer/BlocksAnalyzerTest.php

@@ -38,6 +38,9 @@ final class BlocksAnalyzerTest extends TestCase
         self::assertTrue($analyzer->isBlock($tokens, $openIndex, $closeIndex));
     }
 
+    /**
+     * @return iterable<array{string, int, int}>
+     */
     public static function provideBlocksCases(): iterable
     {
         yield ['<?php foo(1);', 2, 4];
@@ -63,29 +66,26 @@ final class BlocksAnalyzerTest extends TestCase
         yield ['<?php list($a, $b, $c) = [1, 2, 3];', 14, 22];
 
         yield ['<?php list($a, $b, $c) = array(1, 2, 3);', 15, 23];
+
+        yield ['<?php $fn = fn($x) => $x + 10;', 6, 8];
     }
 
     /**
      * @dataProvider provideNonBlocksCases
      */
-    public function testNonBlocks(string $code, ?int $openIndex, ?int $closeIndex, bool $isBlock = false): void
+    public function testNonBlocks(string $code, int $openIndex, int $closeIndex): void
     {
         $tokens = Tokens::fromCode($code);
         $analyzer = new BlocksAnalyzer();
 
-        self::assertSame($isBlock, $analyzer->isBlock($tokens, $openIndex, $closeIndex));
+        self::assertFalse($analyzer->isBlock($tokens, $openIndex, $closeIndex));
     }
 
+    /**
+     * @return iterable<array{string, int, int}>
+     */
     public static function provideNonBlocksCases(): iterable
     {
-        yield ['<?php foo(1);', null, 4];
-
-        yield ['<?php foo(1);', 2, null];
-
-        yield ['<?php foo(1);', 1_000, 4];
-
-        yield ['<?php foo(1);', 2, 1_000];
-
         yield ['<?php foo(1);', 1, 4];
 
         yield ['<?php foo(1);', 3, 4];
@@ -95,7 +95,28 @@ final class BlocksAnalyzerTest extends TestCase
         yield ['<?php foo((1));', 2, 5];
 
         yield ['<?php foo((1));', 3, 6];
+    }
 
-        yield ['<?php $fn = fn($x) => $x + 10;', 6, 8, true];
+    /**
+     * @dataProvider provideInvalidIndexCases
+     */
+    public function testInvalidIndex(string $code, int $openIndex, int $closeIndex): void
+    {
+        $tokens = Tokens::fromCode($code);
+        $analyzer = new BlocksAnalyzer();
+
+        $this->expectException(\InvalidArgumentException::class);
+
+        $analyzer->isBlock($tokens, $openIndex, $closeIndex);
+    }
+
+    /**
+     * @return iterable<array{string, int, int}>
+     */
+    public static function provideInvalidIndexCases(): iterable
+    {
+        yield ['<?php foo(1);', 1_000, 4];
+
+        yield ['<?php foo(1);', 2, 1_000];
     }
 }