annotate vendor/nikic/php-parser/test/PhpParser/ParserTest.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 5fb285c0d0e3
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace PhpParser;
Chris@0 4
Chris@0 5 use PhpParser\Comment;
Chris@0 6 use PhpParser\Node\Expr;
Chris@0 7 use PhpParser\Node\Scalar;
Chris@0 8 use PhpParser\Node\Scalar\String_;
Chris@0 9
Chris@0 10 abstract class ParserTest extends \PHPUnit_Framework_TestCase
Chris@0 11 {
Chris@0 12 /** @returns Parser */
Chris@0 13 abstract protected function getParser(Lexer $lexer);
Chris@0 14
Chris@0 15 /**
Chris@0 16 * @expectedException \PhpParser\Error
Chris@0 17 * @expectedExceptionMessage Syntax error, unexpected EOF on line 1
Chris@0 18 */
Chris@0 19 public function testParserThrowsSyntaxError() {
Chris@0 20 $parser = $this->getParser(new Lexer());
Chris@0 21 $parser->parse('<?php foo');
Chris@0 22 }
Chris@0 23
Chris@0 24 /**
Chris@0 25 * @expectedException \PhpParser\Error
Chris@0 26 * @expectedExceptionMessage Cannot use foo as self because 'self' is a special class name on line 1
Chris@0 27 */
Chris@0 28 public function testParserThrowsSpecialError() {
Chris@0 29 $parser = $this->getParser(new Lexer());
Chris@0 30 $parser->parse('<?php use foo as self;');
Chris@0 31 }
Chris@0 32
Chris@0 33 /**
Chris@0 34 * @expectedException \PhpParser\Error
Chris@0 35 * @expectedExceptionMessage Unterminated comment on line 1
Chris@0 36 */
Chris@0 37 public function testParserThrowsLexerError() {
Chris@0 38 $parser = $this->getParser(new Lexer());
Chris@0 39 $parser->parse('<?php /*');
Chris@0 40 }
Chris@0 41
Chris@0 42 public function testAttributeAssignment() {
Chris@0 43 $lexer = new Lexer(array(
Chris@0 44 'usedAttributes' => array(
Chris@0 45 'comments', 'startLine', 'endLine',
Chris@0 46 'startTokenPos', 'endTokenPos',
Chris@0 47 )
Chris@0 48 ));
Chris@0 49
Chris@0 50 $code = <<<'EOC'
Chris@0 51 <?php
Chris@0 52 /** Doc comment */
Chris@0 53 function test($a) {
Chris@0 54 // Line
Chris@0 55 // Comments
Chris@0 56 echo $a;
Chris@0 57 }
Chris@0 58 EOC;
Chris@0 59 $code = canonicalize($code);
Chris@0 60
Chris@0 61 $parser = $this->getParser($lexer);
Chris@0 62 $stmts = $parser->parse($code);
Chris@0 63
Chris@0 64 /** @var \PhpParser\Node\Stmt\Function_ $fn */
Chris@0 65 $fn = $stmts[0];
Chris@0 66 $this->assertInstanceOf('PhpParser\Node\Stmt\Function_', $fn);
Chris@0 67 $this->assertEquals(array(
Chris@0 68 'comments' => array(
Chris@0 69 new Comment\Doc('/** Doc comment */', 2, 6),
Chris@0 70 ),
Chris@0 71 'startLine' => 3,
Chris@0 72 'endLine' => 7,
Chris@0 73 'startTokenPos' => 3,
Chris@0 74 'endTokenPos' => 21,
Chris@0 75 ), $fn->getAttributes());
Chris@0 76
Chris@0 77 $param = $fn->params[0];
Chris@0 78 $this->assertInstanceOf('PhpParser\Node\Param', $param);
Chris@0 79 $this->assertEquals(array(
Chris@0 80 'startLine' => 3,
Chris@0 81 'endLine' => 3,
Chris@0 82 'startTokenPos' => 7,
Chris@0 83 'endTokenPos' => 7,
Chris@0 84 ), $param->getAttributes());
Chris@0 85
Chris@0 86 /** @var \PhpParser\Node\Stmt\Echo_ $echo */
Chris@0 87 $echo = $fn->stmts[0];
Chris@0 88 $this->assertInstanceOf('PhpParser\Node\Stmt\Echo_', $echo);
Chris@0 89 $this->assertEquals(array(
Chris@0 90 'comments' => array(
Chris@0 91 new Comment("// Line\n", 4, 49),
Chris@0 92 new Comment("// Comments\n", 5, 61),
Chris@0 93 ),
Chris@0 94 'startLine' => 6,
Chris@0 95 'endLine' => 6,
Chris@0 96 'startTokenPos' => 16,
Chris@0 97 'endTokenPos' => 19,
Chris@0 98 ), $echo->getAttributes());
Chris@0 99
Chris@0 100 /** @var \PhpParser\Node\Expr\Variable $var */
Chris@0 101 $var = $echo->exprs[0];
Chris@0 102 $this->assertInstanceOf('PhpParser\Node\Expr\Variable', $var);
Chris@0 103 $this->assertEquals(array(
Chris@0 104 'startLine' => 6,
Chris@0 105 'endLine' => 6,
Chris@0 106 'startTokenPos' => 18,
Chris@0 107 'endTokenPos' => 18,
Chris@0 108 ), $var->getAttributes());
Chris@0 109 }
Chris@0 110
Chris@0 111 /**
Chris@0 112 * @expectedException \RangeException
Chris@0 113 * @expectedExceptionMessage The lexer returned an invalid token (id=999, value=foobar)
Chris@0 114 */
Chris@0 115 public function testInvalidToken() {
Chris@0 116 $lexer = new InvalidTokenLexer;
Chris@0 117 $parser = $this->getParser($lexer);
Chris@0 118 $parser->parse('dummy');
Chris@0 119 }
Chris@0 120
Chris@0 121 /**
Chris@0 122 * @dataProvider provideTestExtraAttributes
Chris@0 123 */
Chris@0 124 public function testExtraAttributes($code, $expectedAttributes) {
Chris@0 125 $parser = $this->getParser(new Lexer);
Chris@0 126 $stmts = $parser->parse("<?php $code;");
Chris@0 127 $attributes = $stmts[0]->getAttributes();
Chris@0 128 foreach ($expectedAttributes as $name => $value) {
Chris@0 129 $this->assertSame($value, $attributes[$name]);
Chris@0 130 }
Chris@0 131 }
Chris@0 132
Chris@0 133 public function provideTestExtraAttributes() {
Chris@0 134 return array(
Chris@0 135 array('0', ['kind' => Scalar\LNumber::KIND_DEC]),
Chris@0 136 array('9', ['kind' => Scalar\LNumber::KIND_DEC]),
Chris@0 137 array('07', ['kind' => Scalar\LNumber::KIND_OCT]),
Chris@0 138 array('0xf', ['kind' => Scalar\LNumber::KIND_HEX]),
Chris@0 139 array('0XF', ['kind' => Scalar\LNumber::KIND_HEX]),
Chris@0 140 array('0b1', ['kind' => Scalar\LNumber::KIND_BIN]),
Chris@0 141 array('0B1', ['kind' => Scalar\LNumber::KIND_BIN]),
Chris@0 142 array('[]', ['kind' => Expr\Array_::KIND_SHORT]),
Chris@0 143 array('array()', ['kind' => Expr\Array_::KIND_LONG]),
Chris@0 144 array("'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]),
Chris@0 145 array("b'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]),
Chris@0 146 array("B'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]),
Chris@0 147 array('"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]),
Chris@0 148 array('b"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]),
Chris@0 149 array('B"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]),
Chris@0 150 array('"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]),
Chris@0 151 array('b"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]),
Chris@0 152 array('B"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]),
Chris@0 153 array("<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']),
Chris@0 154 array("<<<STR\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']),
Chris@0 155 array("<<<\"STR\"\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']),
Chris@0 156 array("b<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']),
Chris@0 157 array("B<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']),
Chris@0 158 array("<<< \t 'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']),
Chris@0 159 // HHVM doesn't support this due to a lexer bug
Chris@0 160 // (https://github.com/facebook/hhvm/issues/6970)
Chris@0 161 // array("<<<'\xff'\n\xff\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => "\xff"]),
Chris@0 162 array("<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']),
Chris@0 163 array("b<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']),
Chris@0 164 array("B<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']),
Chris@0 165 array("<<< \t \"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']),
Chris@0 166 array("die", ['kind' => Expr\Exit_::KIND_DIE]),
Chris@0 167 array("die('done')", ['kind' => Expr\Exit_::KIND_DIE]),
Chris@0 168 array("exit", ['kind' => Expr\Exit_::KIND_EXIT]),
Chris@0 169 array("exit(1)", ['kind' => Expr\Exit_::KIND_EXIT]),
Chris@0 170 array("?>Foo", ['hasLeadingNewline' => false]),
Chris@0 171 array("?>\nFoo", ['hasLeadingNewline' => true]),
Chris@0 172 array("namespace Foo;", ['kind' => Node\Stmt\Namespace_::KIND_SEMICOLON]),
Chris@0 173 array("namespace Foo {}", ['kind' => Node\Stmt\Namespace_::KIND_BRACED]),
Chris@0 174 array("namespace {}", ['kind' => Node\Stmt\Namespace_::KIND_BRACED]),
Chris@0 175 );
Chris@0 176 }
Chris@0 177 }
Chris@0 178
Chris@0 179 class InvalidTokenLexer extends Lexer {
Chris@0 180 public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) {
Chris@0 181 $value = 'foobar';
Chris@0 182 return 999;
Chris@0 183 }
Chris@0 184 }