* Dariusz Rumiński * * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. */ namespace PhpCsFixer\Tests\Tokenizer\Transformer; use PhpCsFixer\Tests\Test\AbstractTransformerTestCase; use PhpCsFixer\Tokenizer\CT; use PhpCsFixer\Tokenizer\Tokens; use PhpCsFixer\Tokenizer\Transformer\SquareBraceTransformer; /** * @author Dariusz Rumiński * * @internal * * @covers \PhpCsFixer\Tokenizer\Transformer\SquareBraceTransformer * * @phpstan-import-type _TransformerTestExpectedTokens from AbstractTransformerTestCase */ final class SquareBraceTransformerTest extends AbstractTransformerTestCase { /** * @param list $inspectIndexes * * @dataProvider provideIsShortArrayCases */ public function testIsShortArray(string $source, array $inspectIndexes, bool $expected): void { $transformer = new SquareBraceTransformer(); $tokens = Tokens::fromCode($source); foreach ($inspectIndexes as $index) { self::assertTrue($tokens->offsetExists($index), \sprintf('Index %d does not exist.', $index)); } foreach ($tokens as $index => $token) { if (\in_array($index, $inspectIndexes, true)) { self::assertSame('[', $tokens[$index]->getContent(), \sprintf('Token @ index %d must have content \']\'', $index)); $exp = $expected; } elseif ('[' === $tokens[$index]->getContent()) { $exp = !$expected; } else { continue; } self::assertSame( $expected, \Closure::bind(static fn (SquareBraceTransformer $transformer): bool => $transformer->isShortArray($tokens, $index), null, SquareBraceTransformer::class)($transformer), \sprintf('Excepted token "%s" @ index %d %sto be detected as short array.', $tokens[$index]->toJson(), $index, $exp ? '' : 'not ') ); } } public static function provideIsShortArrayCases(): iterable { yield [' $a, "b" => $b, "c" => $c] = $array;', [1], false]; yield ['doTest( $source, $expectedTokens, [ CT::T_ARRAY_SQUARE_BRACE_OPEN, CT::T_ARRAY_SQUARE_BRACE_CLOSE, CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ] ); } public static function provideProcessCases(): iterable { yield 'Array offset only.' => [ ' [ ' CT::T_ARRAY_SQUARE_BRACE_OPEN, 13 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_ARRAY_SQUARE_BRACE_OPEN, 13 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_ARRAY_SQUARE_BRACE_OPEN, 2 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_ARRAY_SQUARE_BRACE_OPEN, 6 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_ARRAY_SQUARE_BRACE_OPEN, 2 => CT::T_ARRAY_SQUARE_BRACE_OPEN, 3 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, 4 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_ARRAY_SQUARE_BRACE_OPEN, 5 => CT::T_ARRAY_SQUARE_BRACE_OPEN, 10 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, 11 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_ARRAY_SQUARE_BRACE_OPEN, 8 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_ARRAY_SQUARE_BRACE_OPEN, 5 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, ], ]; yield [ '', [ 7 => CT::T_ARRAY_SQUARE_BRACE_OPEN, 8 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_ARRAY_SQUARE_BRACE_OPEN, 7 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, ], ]; yield [ '', ]; yield [ ' CT::T_ARRAY_SQUARE_BRACE_OPEN, 6 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, ], ]; yield [ '{camel_case($attributes)}[$key] = $value; } }', ]; yield [ ' CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 9 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, 13 => CT::T_ARRAY_SQUARE_BRACE_OPEN, 21 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, ], ]; yield [ ' $a, "b" => $b, "c" => $c] = $array;', [ 1 => CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 21 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 3 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, 17 => CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 22 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 7 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, 11 => CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 13 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, 17 => CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 19 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, 23 => CT::T_ARRAY_SQUARE_BRACE_OPEN, 24 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 7 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 9 => CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 14 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, 15 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ], ]; yield 'nested I' => [ ' CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 5 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ], ]; yield 'nested II (with array offset)' => [ ' CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 6 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ], ]; yield 'nested III' => [ ' CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 8 => CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 10 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, 17 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 2 => CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 3 => CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 5 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, 7 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, 16 => CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 18 => CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 20 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, 21 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, 25 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 13 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ], ]; yield [ ' [$x, $y]) {}', [ 12 => CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 17 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ], ]; yield [ ' [$x, $y]];', [ 1 => CT::T_ARRAY_SQUARE_BRACE_OPEN, 6 => CT::T_ARRAY_SQUARE_BRACE_OPEN, 11 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, 12 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, ], ]; yield [ ' [$x, $y]);', [ 7 => CT::T_ARRAY_SQUARE_BRACE_OPEN, 12 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, ], ]; yield [ ' [$x, $y] = foo()];', [ 1 => CT::T_ARRAY_SQUARE_BRACE_OPEN, 6 => CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 11 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, 18 => CT::T_ARRAY_SQUARE_BRACE_CLOSE, ], ]; } /** * @param _TransformerTestExpectedTokens $expectedTokens * * @dataProvider provideProcess72Cases */ public function testProcess72(string $source, array $expectedTokens): void { $this->doTest( $source, $expectedTokens, [ CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ] ); } public static function provideProcess72Cases(): iterable { yield [ ' CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 7 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 7 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 8 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ], ]; yield [ ' CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 2 => CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 4 => CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 11 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, 14 => CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 17 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, 19 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, 22 => CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, 26 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, 27 => CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ], ]; } }