Chris@13
|
1 <?php
|
Chris@13
|
2
|
Chris@13
|
3 /*
|
Chris@13
|
4 * This file is part of Psy Shell.
|
Chris@13
|
5 *
|
Chris@13
|
6 * (c) 2012-2018 Justin Hileman
|
Chris@13
|
7 *
|
Chris@13
|
8 * For the full copyright and license information, please view the LICENSE
|
Chris@13
|
9 * file that was distributed with this source code.
|
Chris@13
|
10 */
|
Chris@13
|
11
|
Chris@13
|
12 namespace Psy\Test;
|
Chris@13
|
13
|
Chris@13
|
14 use PhpParser\PrettyPrinter\Standard as Printer;
|
Chris@13
|
15 use Psy\Exception\ParseErrorException;
|
Chris@13
|
16 use Psy\ParserFactory;
|
Chris@13
|
17
|
Chris@13
|
18 class ParserTestCase extends \PHPUnit\Framework\TestCase
|
Chris@13
|
19 {
|
Chris@13
|
20 protected $traverser;
|
Chris@13
|
21 private $parser;
|
Chris@13
|
22 private $printer;
|
Chris@13
|
23
|
Chris@16
|
24 public function tearDown()
|
Chris@16
|
25 {
|
Chris@16
|
26 $this->traverser = null;
|
Chris@16
|
27 $this->parser = null;
|
Chris@16
|
28 $this->printer = null;
|
Chris@16
|
29 }
|
Chris@16
|
30
|
Chris@13
|
31 protected function parse($code, $prefix = '<?php ')
|
Chris@13
|
32 {
|
Chris@13
|
33 $code = $prefix . $code;
|
Chris@13
|
34 try {
|
Chris@13
|
35 return $this->getParser()->parse($code);
|
Chris@13
|
36 } catch (\PhpParser\Error $e) {
|
Chris@13
|
37 if (!$this->parseErrorIsEOF($e)) {
|
Chris@13
|
38 throw ParseErrorException::fromParseError($e);
|
Chris@13
|
39 }
|
Chris@13
|
40
|
Chris@13
|
41 try {
|
Chris@13
|
42 // Unexpected EOF, try again with an implicit semicolon
|
Chris@13
|
43 return $this->getParser()->parse($code . ';');
|
Chris@13
|
44 } catch (\PhpParser\Error $e) {
|
Chris@13
|
45 return false;
|
Chris@13
|
46 }
|
Chris@13
|
47 }
|
Chris@13
|
48 }
|
Chris@13
|
49
|
Chris@13
|
50 protected function traverse(array $stmts)
|
Chris@13
|
51 {
|
Chris@13
|
52 if (!isset($this->traverser)) {
|
Chris@13
|
53 throw new \RuntimeException('Test cases must provide a traverser');
|
Chris@13
|
54 }
|
Chris@13
|
55
|
Chris@13
|
56 return $this->traverser->traverse($stmts);
|
Chris@13
|
57 }
|
Chris@13
|
58
|
Chris@13
|
59 protected function prettyPrint(array $stmts)
|
Chris@13
|
60 {
|
Chris@13
|
61 return $this->getPrinter()->prettyPrint($stmts);
|
Chris@13
|
62 }
|
Chris@13
|
63
|
Chris@13
|
64 protected function assertProcessesAs($from, $to)
|
Chris@13
|
65 {
|
Chris@13
|
66 $stmts = $this->parse($from);
|
Chris@13
|
67 $stmts = $this->traverse($stmts);
|
Chris@16
|
68 $toStmts = $this->parse($to);
|
Chris@16
|
69 $this->assertSame($this->prettyPrint($toStmts), $this->prettyPrint($stmts));
|
Chris@13
|
70 }
|
Chris@13
|
71
|
Chris@13
|
72 private function getParser()
|
Chris@13
|
73 {
|
Chris@13
|
74 if (!isset($this->parser)) {
|
Chris@13
|
75 $parserFactory = new ParserFactory();
|
Chris@13
|
76 $this->parser = $parserFactory->createParser();
|
Chris@13
|
77 }
|
Chris@13
|
78
|
Chris@13
|
79 return $this->parser;
|
Chris@13
|
80 }
|
Chris@13
|
81
|
Chris@13
|
82 private function getPrinter()
|
Chris@13
|
83 {
|
Chris@13
|
84 if (!isset($this->printer)) {
|
Chris@13
|
85 $this->printer = new Printer();
|
Chris@13
|
86 }
|
Chris@13
|
87
|
Chris@13
|
88 return $this->printer;
|
Chris@13
|
89 }
|
Chris@13
|
90
|
Chris@13
|
91 private function parseErrorIsEOF(\PhpParser\Error $e)
|
Chris@13
|
92 {
|
Chris@13
|
93 $msg = $e->getRawMessage();
|
Chris@13
|
94
|
Chris@17
|
95 return ($msg === 'Unexpected token EOF') || (\strpos($msg, 'Syntax error, unexpected EOF') !== false);
|
Chris@13
|
96 }
|
Chris@13
|
97 }
|