155 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			155 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| namespace PhpParser;
 | |
| 
 | |
| use PhpParser\Comment;
 | |
| 
 | |
| require_once __DIR__ . '/CodeTestAbstract.php';
 | |
| 
 | |
| class ParserTest extends CodeTestAbstract
 | |
| {
 | |
|     /**
 | |
|      * @dataProvider provideTestParse
 | |
|      */
 | |
|     public function testParse($name, $code, $expected) {
 | |
|         $lexer = new Lexer\Emulative(array('usedAttributes' => array(
 | |
|             'startLine', 'endLine', 'startFilePos', 'endFilePos'
 | |
|         )));
 | |
|         $parser = new Parser($lexer, array(
 | |
|             'throwOnError' => false,
 | |
|         ));
 | |
| 
 | |
|         $stmts = $parser->parse($code);
 | |
|         $errors = $parser->getErrors();
 | |
| 
 | |
|         $output = '';
 | |
|         foreach ($errors as $error) {
 | |
|             $output .= $this->formatErrorMessage($error, $code) . "\n";
 | |
|         }
 | |
| 
 | |
|         if (null !== $stmts) {
 | |
|             $dumper = new NodeDumper;
 | |
|             $output .= $dumper->dump($stmts);
 | |
|         }
 | |
| 
 | |
|         $this->assertSame($this->canonicalize($expected), $this->canonicalize($output), $name);
 | |
|     }
 | |
| 
 | |
|     public function provideTestParse() {
 | |
|         return $this->getTests(__DIR__ . '/../code/parser', 'test');
 | |
|     }
 | |
| 
 | |
|     private function formatErrorMessage(Error $e, $code) {
 | |
|         if ($e->hasColumnInfo()) {
 | |
|             return $e->getRawMessage() . ' from ' . $e->getStartLine() . ':' . $e->getStartColumn($code)
 | |
|                 . ' to ' . $e->getEndLine() . ':' . $e->getEndColumn($code);
 | |
|         } else {
 | |
|             return $e->getMessage();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @expectedException \PhpParser\Error
 | |
|      * @expectedExceptionMessage Syntax error, unexpected EOF on line 1
 | |
|      */
 | |
|     public function testParserThrowsSyntaxError() {
 | |
|         $parser = new Parser(new Lexer());
 | |
|         $parser->parse('<?php foo');
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @expectedException \PhpParser\Error
 | |
|      * @expectedExceptionMessage Cannot use foo as self because 'self' is a special class name on line 1
 | |
|      */
 | |
|     public function testParserThrowsSpecialError() {
 | |
|         $parser = new Parser(new Lexer());
 | |
|         $parser->parse('<?php use foo as self;');
 | |
|     }
 | |
| 
 | |
|     public function testAttributeAssignment() {
 | |
|         $lexer = new Lexer(array(
 | |
|             'usedAttributes' => array(
 | |
|                 'comments', 'startLine', 'endLine',
 | |
|                 'startTokenPos', 'endTokenPos',
 | |
|             )
 | |
|         ));
 | |
| 
 | |
|         $code = <<<'EOC'
 | |
| <?php
 | |
| /** Doc comment */
 | |
| function test($a) {
 | |
|     // Line
 | |
|     // Comments
 | |
|     echo $a;
 | |
| }
 | |
| EOC;
 | |
|         $code = $this->canonicalize($code);
 | |
| 
 | |
|         $parser = new Parser($lexer);
 | |
|         $stmts = $parser->parse($code);
 | |
| 
 | |
|         /** @var \PhpParser\Node\Stmt\Function_ $fn */
 | |
|         $fn = $stmts[0];
 | |
|         $this->assertInstanceOf('PhpParser\Node\Stmt\Function_', $fn);
 | |
|         $this->assertEquals(array(
 | |
|             'comments' => array(
 | |
|                 new Comment\Doc('/** Doc comment */', 2),
 | |
|             ),
 | |
|             'startLine' => 3,
 | |
|             'endLine' => 7,
 | |
|             'startTokenPos' => 3,
 | |
|             'endTokenPos' => 21,
 | |
|         ), $fn->getAttributes());
 | |
| 
 | |
|         $param = $fn->params[0];
 | |
|         $this->assertInstanceOf('PhpParser\Node\Param', $param);
 | |
|         $this->assertEquals(array(
 | |
|             'startLine' => 3,
 | |
|             'endLine' => 3,
 | |
|             'startTokenPos' => 7,
 | |
|             'endTokenPos' => 7,
 | |
|         ), $param->getAttributes());
 | |
| 
 | |
|         /** @var \PhpParser\Node\Stmt\Echo_ $echo */
 | |
|         $echo = $fn->stmts[0];
 | |
|         $this->assertInstanceOf('PhpParser\Node\Stmt\Echo_', $echo);
 | |
|         $this->assertEquals(array(
 | |
|             'comments' => array(
 | |
|                 new Comment("// Line\n", 4),
 | |
|                 new Comment("// Comments\n", 5),
 | |
|             ),
 | |
|             'startLine' => 6,
 | |
|             'endLine' => 6,
 | |
|             'startTokenPos' => 16,
 | |
|             'endTokenPos' => 19,
 | |
|         ), $echo->getAttributes());
 | |
| 
 | |
|         /** @var \PhpParser\Node\Expr\Variable $var */
 | |
|         $var = $echo->exprs[0];
 | |
|         $this->assertInstanceOf('PhpParser\Node\Expr\Variable', $var);
 | |
|         $this->assertEquals(array(
 | |
|             'startLine' => 6,
 | |
|             'endLine' => 6,
 | |
|             'startTokenPos' => 18,
 | |
|             'endTokenPos' => 18,
 | |
|         ), $var->getAttributes());
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @expectedException \RangeException
 | |
|      * @expectedExceptionMessage The lexer returned an invalid token (id=999, value=foobar)
 | |
|      */
 | |
|     public function testInvalidToken() {
 | |
|         $lexer = new InvalidTokenLexer;
 | |
|         $parser = new Parser($lexer);
 | |
|         $parser->parse('dummy');
 | |
|     }
 | |
| }
 | |
| 
 | |
| class InvalidTokenLexer extends Lexer {
 | |
|     public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) {
 | |
|         $value = 'foobar';
 | |
|         return 999;
 | |
|     }
 | |
| }
 | 
