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@13
|
24 protected function parse($code, $prefix = '<?php ')
|
Chris@13
|
25 {
|
Chris@13
|
26 $code = $prefix . $code;
|
Chris@13
|
27 try {
|
Chris@13
|
28 return $this->getParser()->parse($code);
|
Chris@13
|
29 } catch (\PhpParser\Error $e) {
|
Chris@13
|
30 if (!$this->parseErrorIsEOF($e)) {
|
Chris@13
|
31 throw ParseErrorException::fromParseError($e);
|
Chris@13
|
32 }
|
Chris@13
|
33
|
Chris@13
|
34 try {
|
Chris@13
|
35 // Unexpected EOF, try again with an implicit semicolon
|
Chris@13
|
36 return $this->getParser()->parse($code . ';');
|
Chris@13
|
37 } catch (\PhpParser\Error $e) {
|
Chris@13
|
38 return false;
|
Chris@13
|
39 }
|
Chris@13
|
40 }
|
Chris@13
|
41 }
|
Chris@13
|
42
|
Chris@13
|
43 protected function traverse(array $stmts)
|
Chris@13
|
44 {
|
Chris@13
|
45 if (!isset($this->traverser)) {
|
Chris@13
|
46 throw new \RuntimeException('Test cases must provide a traverser');
|
Chris@13
|
47 }
|
Chris@13
|
48
|
Chris@13
|
49 return $this->traverser->traverse($stmts);
|
Chris@13
|
50 }
|
Chris@13
|
51
|
Chris@13
|
52 protected function prettyPrint(array $stmts)
|
Chris@13
|
53 {
|
Chris@13
|
54 return $this->getPrinter()->prettyPrint($stmts);
|
Chris@13
|
55 }
|
Chris@13
|
56
|
Chris@13
|
57 protected function assertProcessesAs($from, $to)
|
Chris@13
|
58 {
|
Chris@13
|
59 $stmts = $this->parse($from);
|
Chris@13
|
60 $stmts = $this->traverse($stmts);
|
Chris@13
|
61 $this->assertSame($to, $this->prettyPrint($stmts));
|
Chris@13
|
62 }
|
Chris@13
|
63
|
Chris@13
|
64 private function getParser()
|
Chris@13
|
65 {
|
Chris@13
|
66 if (!isset($this->parser)) {
|
Chris@13
|
67 $parserFactory = new ParserFactory();
|
Chris@13
|
68 $this->parser = $parserFactory->createParser();
|
Chris@13
|
69 }
|
Chris@13
|
70
|
Chris@13
|
71 return $this->parser;
|
Chris@13
|
72 }
|
Chris@13
|
73
|
Chris@13
|
74 private function getPrinter()
|
Chris@13
|
75 {
|
Chris@13
|
76 if (!isset($this->printer)) {
|
Chris@13
|
77 $this->printer = new Printer();
|
Chris@13
|
78 }
|
Chris@13
|
79
|
Chris@13
|
80 return $this->printer;
|
Chris@13
|
81 }
|
Chris@13
|
82
|
Chris@13
|
83 private function parseErrorIsEOF(\PhpParser\Error $e)
|
Chris@13
|
84 {
|
Chris@13
|
85 $msg = $e->getRawMessage();
|
Chris@13
|
86
|
Chris@13
|
87 return ($msg === 'Unexpected token EOF') || (strpos($msg, 'Syntax error, unexpected EOF') !== false);
|
Chris@13
|
88 }
|
Chris@13
|
89 }
|