sonarrradarrplexorganizrnginxdashboardlandingpagestartpagelandinghtpcserverhomepagesabnzbdheimdallembycouchpotatonzbgetbookmarkapplication-dashboardmuximux
		
		
		
		
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							120 lines
						
					
					
						
							4.0 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							120 lines
						
					
					
						
							4.0 KiB
						
					
					
				| <?php declare(strict_types=1); | |
| 
 | |
| namespace PhpParser; | |
| 
 | |
| use PhpParser\Node\Expr; | |
| use PhpParser\Node\Stmt; | |
| 
 | |
| require_once __DIR__ . '/CodeTestAbstract.php'; | |
| 
 | |
| class CodeParsingTest extends CodeTestAbstract | |
| { | |
|     /** | |
|      * @dataProvider provideTestParse | |
|      */ | |
|     public function testParse($name, $code, $expected, $modeLine) { | |
|         if (null !== $modeLine) { | |
|             $modes = array_fill_keys(explode(',', $modeLine), true); | |
|         } else { | |
|             $modes = []; | |
|         } | |
| 
 | |
|         list($parser5, $parser7) = $this->createParsers($modes); | |
|         list($stmts5, $output5) = $this->getParseOutput($parser5, $code, $modes); | |
|         list($stmts7, $output7) = $this->getParseOutput($parser7, $code, $modes); | |
| 
 | |
|         if (isset($modes['php5'])) { | |
|             $this->assertSame($expected, $output5, $name); | |
|             $this->assertNotSame($expected, $output7, $name); | |
|         } elseif (isset($modes['php7'])) { | |
|             $this->assertNotSame($expected, $output5, $name); | |
|             $this->assertSame($expected, $output7, $name); | |
|         } else { | |
|             $this->assertSame($expected, $output5, $name); | |
|             $this->assertSame($expected, $output7, $name); | |
|         } | |
| 
 | |
|         $this->checkAttributes($stmts5); | |
|         $this->checkAttributes($stmts7); | |
|     } | |
| 
 | |
|     public function createParsers(array $modes) { | |
|         $lexer = new Lexer\Emulative(['usedAttributes' => [ | |
|             'startLine', 'endLine', | |
|             'startFilePos', 'endFilePos', | |
|             'startTokenPos', 'endTokenPos', | |
|             'comments' | |
|         ]]); | |
| 
 | |
|         return [ | |
|             new Parser\Php5($lexer), | |
|             new Parser\Php7($lexer), | |
|         ]; | |
|     } | |
| 
 | |
|     private function getParseOutput(Parser $parser, $code, array $modes) { | |
|         $dumpPositions = isset($modes['positions']); | |
| 
 | |
|         $errors = new ErrorHandler\Collecting; | |
|         $stmts = $parser->parse($code, $errors); | |
| 
 | |
|         $output = ''; | |
|         foreach ($errors->getErrors() as $error) { | |
|             $output .= $this->formatErrorMessage($error, $code) . "\n"; | |
|         } | |
| 
 | |
|         if (null !== $stmts) { | |
|             $dumper = new NodeDumper(['dumpComments' => true, 'dumpPositions' => $dumpPositions]); | |
|             $output .= $dumper->dump($stmts, $code); | |
|         } | |
| 
 | |
|         return [$stmts, canonicalize($output)]; | |
|     } | |
| 
 | |
|     public function provideTestParse() { | |
|         return $this->getTests(__DIR__ . '/../code/parser', 'test'); | |
|     } | |
| 
 | |
|     private function formatErrorMessage(Error $e, $code) { | |
|         if ($e->hasColumnInfo()) { | |
|             return $e->getMessageWithColumnInfo($code); | |
|         } else { | |
|             return $e->getMessage(); | |
|         } | |
|     } | |
| 
 | |
|     private function checkAttributes($stmts) { | |
|         if ($stmts === null) { | |
|             return; | |
|         } | |
| 
 | |
|         $traverser = new NodeTraverser(); | |
|         $traverser->addVisitor(new class extends NodeVisitorAbstract { | |
|             public function enterNode(Node $node) { | |
|                 $startLine = $node->getStartLine(); | |
|                 $endLine = $node->getEndLine(); | |
|                 $startFilePos = $node->getStartFilePos(); | |
|                 $endFilePos = $node->getEndFilePos(); | |
|                 $startTokenPos = $node->getStartTokenPos(); | |
|                 $endTokenPos = $node->getEndTokenPos(); | |
|                 if ($startLine < 0 || $endLine < 0 || | |
|                     $startFilePos < 0 || $endFilePos < 0 || | |
|                     $startTokenPos < 0 || $endTokenPos < 0 | |
|                 ) { | |
|                     throw new \Exception('Missing location information on ' . $node->getType()); | |
|                 } | |
| 
 | |
|                 if ($endLine < $startLine || | |
|                     $endFilePos < $startFilePos || | |
|                     $endTokenPos < $startTokenPos | |
|                 ) { | |
|                     // Nops and error can have inverted order, if they are empty | |
|                     if (!$node instanceof Stmt\Nop && !$node instanceof Expr\Error) { | |
|                         throw new \Exception('End < start on ' . $node->getType()); | |
|                     } | |
|                 } | |
|             } | |
|         }); | |
|         $traverser->traverse($stmts); | |
|     } | |
| }
 | |
| 
 |