* 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; use PhpCsFixer\Tokenizer\Tokens; use PhpCsFixer\Tokenizer\TokensAnalyzer; /** * @author Dariusz Rumiński * @author Max Voloshin * @author Gregor Harlan * * @internal */ final class TokensAnalyzerTest extends \PHPUnit_Framework_TestCase { public function testGetClassyElements() { $source = <<<'PHP' getClassyElements()); $this->assertCount(8, $elements); $this->assertSame('property', $elements[0]['type']); $this->assertSame('property', $elements[1]['type']); $this->assertSame('property', $elements[2]['type']); $this->assertSame('property', $elements[3]['type']); $this->assertSame('const', $elements[4]['type']); $this->assertSame('method', $elements[5]['type']); $this->assertSame('method', $elements[6]['type']); $this->assertSame('const', $elements[7]['type']); } /** * @param string $source * * @dataProvider provideIsAnonymousClassCases */ public function testIsAnonymousClass($source, array $expected) { $tokensAnalyzer = new TokensAnalyzer(Tokens::fromCode($source)); foreach ($expected as $index => $expectedValue) { $this->assertSame($expectedValue, $tokensAnalyzer->isAnonymousClass($index)); } } public function provideIsAnonymousClassCases() { return array( array( ' false), ), array( ' true), ), array( ' true), ), array( ' false, 19 => true), ), array( 'a) implements B{}) extends C{};', array(7 => true, 11 => true), ), ); } /** * @param string $source * * @dataProvider provideIsLambdaCases */ public function testIsLambda($source, array $expected) { $tokensAnalyzer = new TokensAnalyzer(Tokens::fromCode($source)); foreach ($expected as $index => $isLambda) { $this->assertSame($isLambda, $tokensAnalyzer->isLambda($index)); } } public function provideIsLambdaCases() { return array( array( ' false), ), array( ' false), ), array( ' true), ), array( ' true), ), array( ' true), ), array( ' true), ), ); } /** * @param string $source * * @dataProvider provideIsLambdaCases70 * @requires PHP 7.0 */ public function testIsLambda70($source, array $expected) { $tokensAnalyzer = new TokensAnalyzer(Tokens::fromCode($source)); foreach ($expected as $index => $expectedValue) { $this->assertSame($expectedValue, $tokensAnalyzer->isLambda($index)); } } public function provideIsLambdaCases70() { return array( array( ' true), ), array( ' false), ), ); } /** * @param string $source * * @dataProvider provideIsLambdaCases71 * @requires PHP 7.1 */ public function testIsLambda71($source, array $expected) { $tokensAnalyzer = new TokensAnalyzer(Tokens::fromCode($source)); foreach ($expected as $index => $expectedValue) { $this->assertSame($expectedValue, $tokensAnalyzer->isLambda($index)); } } public function provideIsLambdaCases71() { return array( array( ' true), ), array( ' false), ), array( ' true), ), array( ' false), ), ); } /** * @param string $source * * @dataProvider provideIsUnarySuccessorOperator */ public function testIsUnarySuccessorOperator($source, array $expected) { $tokensAnalyzer = new TokensAnalyzer(Tokens::fromCode($source)); foreach ($expected as $index => $isUnary) { $this->assertSame($isUnary, $tokensAnalyzer->isUnarySuccessorOperator($index)); if ($isUnary) { $this->assertFalse($tokensAnalyzer->isUnaryPredecessorOperator($index)); $this->assertFalse($tokensAnalyzer->isBinaryOperator($index)); } } } public function provideIsUnarySuccessorOperator() { return array( array( ' true), ), array( ' true), ), array( ' true), ), array( ' true, 4 => false), ), array( ' true), ), array( 'bar++;', array(4 => true), ), array( '{"bar"}++;', array(6 => true), ), array( ' true), ), ); } /** * @param string $source * * @dataProvider provideIsUnaryPredecessorOperator */ public function testIsUnaryPredecessorOperator($source, array $expected) { $tokensAnalyzer = new TokensAnalyzer(Tokens::fromCode($source)); foreach ($expected as $index => $isUnary) { $this->assertSame($isUnary, $tokensAnalyzer->isUnaryPredecessorOperator($index)); if ($isUnary) { $this->assertFalse($tokensAnalyzer->isUnarySuccessorOperator($index)); $this->assertFalse($tokensAnalyzer->isBinaryOperator($index)); } } } public function provideIsUnaryPredecessorOperator() { return array( array( ' true), ), array( ' true), ), array( ' true), ), array( ' false, 5 => true), ), array( ' true, 2 => true), ), array( ' true), ), array( ' true), ), array( ' true), ), array( ' true, 8 => true), ), array( ' true, 11 => true, 17 => true), ), ); } /** * @param string $source * * @dataProvider provideIsUnaryPredecessorOperator56 * @requires PHP 5.6 */ public function testIsUnaryPredecessorOperator56($source, array $expected) { $tokensAnalyzer = new TokensAnalyzer(Tokens::fromCode($source)); foreach ($expected as $index => $isUnary) { $this->assertSame($isUnary, $tokensAnalyzer->isUnaryPredecessorOperator($index)); if ($isUnary) { $this->assertFalse($tokensAnalyzer->isUnarySuccessorOperator($index)); $this->assertFalse($tokensAnalyzer->isBinaryOperator($index)); } } } public function provideIsUnaryPredecessorOperator56() { return array( array( ' true), ), array( ' true, 6 => true), ), array( ' true), ), array( ' true), ), array( ' true), ), ); } /** * @param string $source * * @dataProvider provideIsBinaryOperator */ public function testIsBinaryOperator($source, array $expected) { $tokensAnalyzer = new TokensAnalyzer(Tokens::fromCode($source)); foreach ($expected as $index => $isBinary) { $this->assertSame($isBinary, $tokensAnalyzer->isBinaryOperator($index)); if ($isBinary) { $this->assertFalse($tokensAnalyzer->isUnarySuccessorOperator($index)); $this->assertFalse($tokensAnalyzer->isUnaryPredecessorOperator($index)); } } } public function provideIsBinaryOperator() { $cases = array( array( ' true), ), array( ' true), ), array( ' true), ), array( ' true), ), array( ' true), ), array( ' true), ), array( ' true), ), array( ' true), ), array( ' true), ), array( ' true), ), array( ' true), ), array( ' true), ), array( ' "c", );', array(3 => true, 9 => true, 12 => false), ), array( ' true, 5 => false), ), array( ' true, 5 => false, 8 => true, 10 => false), ), array( ' true, 5 => false), ), array( ' false, 4 => true), ), array( ' true), ), array( ' true), ), array( ' true), ), ); $operators = array( '+', '-', '*', '/', '%', '<', '>', '|', '^', '&=', '&&', '||', '.=', '/=', '==', '>=', '===', '!=', '<>', '!==', '<=', 'and', 'or', 'xor', '-=', '%=', '*=', '|=', '+=', '<<', '<<=', '>>', '>>=', '^', ); foreach ($operators as $operator) { $cases[] = array( ' true), ); } return $cases; } /** * @param string $source * * @dataProvider provideIsBinaryOperator56 * @requires PHP 5.6 */ public function testIsBinaryOperator56($source, array $expected) { $tokensAnalyzer = new TokensAnalyzer(Tokens::fromCode($source)); foreach ($expected as $index => $isBinary) { $this->assertSame($isBinary, $tokensAnalyzer->isBinaryOperator($index)); if ($isBinary) { $this->assertFalse($tokensAnalyzer->isUnarySuccessorOperator($index)); $this->assertFalse($tokensAnalyzer->isUnaryPredecessorOperator($index)); } } } public function provideIsBinaryOperator56() { return array( array( ' true), ), array( ' true), ), ); } /** * @param string $source * * @dataProvider provideIsBinaryOperator70 * @requires PHP 7.0 */ public function testIsBinaryOperator70($source, array $expected) { $tokensAnalyzer = new TokensAnalyzer(Tokens::fromCode($source)); foreach ($expected as $index => $isBinary) { $this->assertSame($isBinary, $tokensAnalyzer->isBinaryOperator($index)); if ($isBinary) { $this->assertFalse($tokensAnalyzer->isUnarySuccessorOperator($index)); $this->assertFalse($tokensAnalyzer->isUnaryPredecessorOperator($index)); } } } public function provideIsBinaryOperator70() { return array( array( ' $b;', array(3 => true), ), array( ' true), ), ); } /** * @param string $source * @param int $tokenIndex * @param bool $isMultilineArray * * @dataProvider provideIsArray * @requires PHP 5.4 */ public function testIsArray($source, $tokenIndex, $isMultilineArray = false) { $tokens = Tokens::fromCode($source); $tokensAnalyzer = new TokensAnalyzer($tokens); $this->assertTrue($tokensAnalyzer->isArray($tokenIndex), 'Expected to be an array.'); $this->assertSame($isMultilineArray, $tokensAnalyzer->isArrayMultiLine($tokenIndex), sprintf('Expected %sto be a multiline array', $isMultilineArray ? '' : 'not ')); } public function provideIsArray() { $cases = array( array( ' 1); ', 2, ), array( // short array PHP 5.4 single line ' 2]; ', 2, false, ), array( ' 3 ); ', 2, true, ), array( // short array PHP 5.4 multi line ' 4 ]; ', 2, true, ), array( ' array(5, 6, 7), 8 => new \Exception(\'Ellow\') ); ', 2, true, ), array( // mix short array syntax ' [9, 10, 11], 12 => new \Exception(\'Ellow\') ); ', 2, true, ), // Windows/Max EOL testing array( " 13);\r\n", 1, ), array( " 14,\r\n 'b' => 15\r\n );\r\n", 2, true, ), ); return $cases; } /** * @param string $source * @param int $tokenIndex * * @dataProvider provideArrayExceptions */ public function testIsNotArray($source, $tokenIndex) { $tokens = Tokens::fromCode($source); $tokensAnalyzer = new TokensAnalyzer($tokens); $this->assertFalse($tokensAnalyzer->isArray($tokenIndex)); } /** * @param string $source * @param int $tokenIndex * * @expectedException \InvalidArgumentException * @dataProvider provideArrayExceptions */ public function testIsMultiLineArrayException($source, $tokenIndex) { $tokens = Tokens::fromCode($source); $tokensAnalyzer = new TokensAnalyzer($tokens); $tokensAnalyzer->isArrayMultiLine($tokenIndex); } public function provideArrayExceptions() { $cases = array( array('getMethodAttributes($index); $this->assertSame($expected, $attributes); } public function provideGetFunctionProperties() { $defaultAttributes = array( 'visibility' => null, 'static' => false, 'abstract' => false, 'final' => false, ); $template = ' false, 12 => false, 19 => false, 34 => false, 47 => false, 53 => false, 59 => false, 66 => false, 91 => false, 112 => true, 123 => true, 139 => true, 153 => false, 162 => true, ); $tokens = Tokens::fromCode($source); $tokensAnalyzer = new TokensAnalyzer($tokens); foreach ($tokens as $index => $token) { if (!$token->isGivenKind(T_WHILE)) { continue; } $this->assertSame( $expected[$index], $tokensAnalyzer->isWhilePartOfDoWhile($index), sprintf('Expected token at index "%d" to be detected as %sa "do-while"-loop.', $index, true === $expected[$index] ? '' : 'not ') ); } } /** * @param string $input * @param bool $perNamespace * * @dataProvider getImportUseIndexesCases */ public function testGetImportUseIndexes(array $expected, $input, $perNamespace = false) { $tokens = Tokens::fromCode($input); $tokensAnalyzer = new TokensAnalyzer($tokens); $this->assertSame($expected, $tokensAnalyzer->getImportUseIndexes($perNamespace)); } public function getImportUseIndexesCases() { return array( array( array(1, 8), '', true, ), array( array(1, 8), '', ), array( array(7, 22), 'assertSame($expected, $tokensAnalyzer->getImportUseIndexes($perNamespace)); } public function getImportUseIndexesCasesPHP70() { return array( array( array(1, 22, 41), '