annotate vendor/nikic/php-parser/test_old/run.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 error_reporting(E_ALL | E_STRICT);
Chris@0 4 ini_set('short_open_tag', false);
Chris@0 5
Chris@0 6 if ('cli' !== php_sapi_name()) {
Chris@0 7 die('This script is designed for running on the command line.');
Chris@0 8 }
Chris@0 9
Chris@0 10 function showHelp($error) {
Chris@0 11 die($error . "\n\n" .
Chris@0 12 <<<OUTPUT
Chris@0 13 This script has to be called with the following signature:
Chris@0 14
Chris@0 15 php run.php [--no-progress] testType pathToTestFiles
Chris@0 16
Chris@0 17 The test type must be one of: PHP5, PHP7 or Symfony.
Chris@0 18
Chris@0 19 The following options are available:
Chris@0 20
Chris@0 21 --no-progress Disables showing which file is currently tested.
Chris@0 22
Chris@0 23 OUTPUT
Chris@0 24 );
Chris@0 25 }
Chris@0 26
Chris@0 27 $options = array();
Chris@0 28 $arguments = array();
Chris@0 29
Chris@0 30 // remove script name from argv
Chris@0 31 array_shift($argv);
Chris@0 32
Chris@0 33 foreach ($argv as $arg) {
Chris@0 34 if ('-' === $arg[0]) {
Chris@0 35 $options[] = $arg;
Chris@0 36 } else {
Chris@0 37 $arguments[] = $arg;
Chris@0 38 }
Chris@0 39 }
Chris@0 40
Chris@0 41 if (count($arguments) !== 2) {
Chris@0 42 showHelp('Too little arguments passed!');
Chris@0 43 }
Chris@0 44
Chris@0 45 $showProgress = true;
Chris@0 46 $verbose = false;
Chris@0 47 foreach ($options as $option) {
Chris@0 48 if ($option === '--no-progress') {
Chris@0 49 $showProgress = false;
Chris@0 50 } elseif ($option === '--verbose') {
Chris@0 51 $verbose = true;
Chris@0 52 } else {
Chris@0 53 showHelp('Invalid option passed!');
Chris@0 54 }
Chris@0 55 }
Chris@0 56
Chris@0 57 $testType = $arguments[0];
Chris@0 58 $dir = $arguments[1];
Chris@0 59
Chris@0 60 switch ($testType) {
Chris@0 61 case 'Symfony':
Chris@17 62 $version = 'Php7';
Chris@0 63 $fileFilter = function($path) {
Chris@17 64 if (!preg_match('~\.php$~', $path)) {
Chris@17 65 return false;
Chris@17 66 }
Chris@17 67
Chris@17 68 if (preg_match('~(?:
Chris@17 69 # invalid php code
Chris@17 70 dependency-injection.Tests.Fixtures.xml.xml_with_wrong_ext
Chris@17 71 # difference in nop statement
Chris@17 72 | framework-bundle.Resources.views.Form.choice_widget_options\.html
Chris@17 73 # difference due to INF
Chris@17 74 | yaml.Tests.InlineTest
Chris@17 75 )\.php$~x', $path)) {
Chris@17 76 return false;
Chris@17 77 }
Chris@17 78
Chris@17 79 return true;
Chris@0 80 };
Chris@0 81 $codeExtractor = function($file, $code) {
Chris@0 82 return $code;
Chris@0 83 };
Chris@0 84 break;
Chris@0 85 case 'PHP5':
Chris@0 86 case 'PHP7':
Chris@0 87 $version = $testType === 'PHP5' ? 'Php5' : 'Php7';
Chris@0 88 $fileFilter = function($path) {
Chris@0 89 return preg_match('~\.phpt$~', $path);
Chris@0 90 };
Chris@0 91 $codeExtractor = function($file, $code) {
Chris@0 92 if (preg_match('~(?:
Chris@0 93 # skeleton files
Chris@0 94 ext.gmp.tests.001
Chris@17 95 | ext.skeleton.tests.00\d
Chris@0 96 # multibyte encoded files
Chris@0 97 | ext.mbstring.tests.zend_multibyte-01
Chris@0 98 | Zend.tests.multibyte.multibyte_encoding_001
Chris@0 99 | Zend.tests.multibyte.multibyte_encoding_004
Chris@0 100 | Zend.tests.multibyte.multibyte_encoding_005
Chris@17 101 # invalid code due to missing WS after opening tag
Chris@17 102 | tests.run-test.bug75042-3
Chris@0 103 # pretty print difference due to INF vs 1e1000
Chris@0 104 | ext.standard.tests.general_functions.bug27678
Chris@0 105 | tests.lang.bug24640
Chris@17 106 | Zend.tests.bug74947
Chris@0 107 # pretty print differences due to negative LNumbers
Chris@0 108 | Zend.tests.neg_num_string
Chris@0 109 | Zend.tests.bug72918
Chris@0 110 # pretty print difference due to nop statements
Chris@0 111 | ext.mbstring.tests.htmlent
Chris@0 112 | ext.standard.tests.file.fread_basic
Chris@17 113 # its too hard to emulate these on old PHP versions
Chris@17 114 | Zend.tests.flexible-heredoc-complex-test[1-4]
Chris@0 115 )\.phpt$~x', $file)) {
Chris@0 116 return null;
Chris@0 117 }
Chris@0 118
Chris@17 119 if (!preg_match('~--FILE--\s*(.*?)\n--[A-Z]+--~s', $code, $matches)) {
Chris@0 120 return null;
Chris@0 121 }
Chris@0 122 if (preg_match('~--EXPECT(?:F|REGEX)?--\s*(?:Parse|Fatal) error~', $code)) {
Chris@0 123 return null;
Chris@0 124 }
Chris@0 125
Chris@0 126 return $matches[1];
Chris@0 127 };
Chris@0 128 break;
Chris@0 129 default:
Chris@0 130 showHelp('Test type must be one of: PHP5, PHP7 or Symfony');
Chris@0 131 }
Chris@0 132
Chris@13 133 require_once __DIR__ . '/../vendor/autoload.php';
Chris@0 134
Chris@13 135 $lexer = new PhpParser\Lexer\Emulative(['usedAttributes' => [
Chris@13 136 'comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos',
Chris@13 137 ]]);
Chris@13 138 $parserName = 'PhpParser\Parser\\' . $version;
Chris@13 139 /** @var PhpParser\Parser $parser */
Chris@13 140 $parser = new $parserName($lexer);
Chris@0 141 $prettyPrinter = new PhpParser\PrettyPrinter\Standard;
Chris@13 142 $nodeDumper = new PhpParser\NodeDumper;
Chris@0 143
Chris@13 144 $cloningTraverser = new PhpParser\NodeTraverser;
Chris@13 145 $cloningTraverser->addVisitor(new PhpParser\NodeVisitor\CloningVisitor);
Chris@0 146
Chris@13 147 $parseFail = $fpppFail = $ppFail = $compareFail = $count = 0;
Chris@13 148
Chris@13 149 $readTime = $parseTime = $cloneTime = 0;
Chris@13 150 $fpppTime = $ppTime = $reparseTime = $compareTime = 0;
Chris@0 151 $totalStartTime = microtime(true);
Chris@0 152
Chris@0 153 foreach (new RecursiveIteratorIterator(
Chris@0 154 new RecursiveDirectoryIterator($dir),
Chris@0 155 RecursiveIteratorIterator::LEAVES_ONLY)
Chris@0 156 as $file) {
Chris@0 157 if (!$fileFilter($file)) {
Chris@0 158 continue;
Chris@0 159 }
Chris@0 160
Chris@0 161 $startTime = microtime(true);
Chris@13 162 $origCode = file_get_contents($file);
Chris@0 163 $readTime += microtime(true) - $startTime;
Chris@0 164
Chris@13 165 if (null === $origCode = $codeExtractor($file, $origCode)) {
Chris@0 166 continue;
Chris@0 167 }
Chris@0 168
Chris@0 169 set_time_limit(10);
Chris@0 170
Chris@0 171 ++$count;
Chris@0 172
Chris@0 173 if ($showProgress) {
Chris@0 174 echo substr(str_pad('Testing file ' . $count . ': ' . substr($file, strlen($dir)), 79), 0, 79), "\r";
Chris@0 175 }
Chris@0 176
Chris@0 177 try {
Chris@0 178 $startTime = microtime(true);
Chris@13 179 $origStmts = $parser->parse($origCode);
Chris@0 180 $parseTime += microtime(true) - $startTime;
Chris@0 181
Chris@13 182 $origTokens = $lexer->getTokens();
Chris@13 183
Chris@0 184 $startTime = microtime(true);
Chris@13 185 $stmts = $cloningTraverser->traverse($origStmts);
Chris@13 186 $cloneTime += microtime(true) - $startTime;
Chris@13 187
Chris@13 188 $startTime = microtime(true);
Chris@13 189 $code = $prettyPrinter->printFormatPreserving($stmts, $origStmts, $origTokens);
Chris@13 190 $fpppTime += microtime(true) - $startTime;
Chris@13 191
Chris@13 192 if ($code !== $origCode) {
Chris@13 193 echo $file, ":\n Result of format-preserving pretty-print differs\n";
Chris@13 194 if ($verbose) {
Chris@13 195 echo "FPPP output:\n=====\n$code\n=====\n\n";
Chris@13 196 }
Chris@13 197
Chris@13 198 ++$fpppFail;
Chris@13 199 }
Chris@13 200
Chris@13 201 $startTime = microtime(true);
Chris@13 202 $code = "<?php\n" . $prettyPrinter->prettyPrint($stmts);
Chris@0 203 $ppTime += microtime(true) - $startTime;
Chris@0 204
Chris@0 205 try {
Chris@0 206 $startTime = microtime(true);
Chris@0 207 $ppStmts = $parser->parse($code);
Chris@0 208 $reparseTime += microtime(true) - $startTime;
Chris@0 209
Chris@0 210 $startTime = microtime(true);
Chris@0 211 $same = $nodeDumper->dump($stmts) == $nodeDumper->dump($ppStmts);
Chris@0 212 $compareTime += microtime(true) - $startTime;
Chris@0 213
Chris@0 214 if (!$same) {
Chris@0 215 echo $file, ":\n Result of initial parse and parse after pretty print differ\n";
Chris@0 216 if ($verbose) {
Chris@0 217 echo "Pretty printer output:\n=====\n$code\n=====\n\n";
Chris@0 218 }
Chris@0 219
Chris@0 220 ++$compareFail;
Chris@0 221 }
Chris@0 222 } catch (PhpParser\Error $e) {
Chris@0 223 echo $file, ":\n Parse of pretty print failed with message: {$e->getMessage()}\n";
Chris@0 224 if ($verbose) {
Chris@0 225 echo "Pretty printer output:\n=====\n$code\n=====\n\n";
Chris@0 226 }
Chris@0 227
Chris@0 228 ++$ppFail;
Chris@0 229 }
Chris@0 230 } catch (PhpParser\Error $e) {
Chris@0 231 echo $file, ":\n Parse failed with message: {$e->getMessage()}\n";
Chris@0 232
Chris@0 233 ++$parseFail;
Chris@0 234 }
Chris@0 235 }
Chris@0 236
Chris@0 237 if (0 === $parseFail && 0 === $ppFail && 0 === $compareFail) {
Chris@0 238 $exit = 0;
Chris@0 239 echo "\n\n", 'All tests passed.', "\n";
Chris@0 240 } else {
Chris@0 241 $exit = 1;
Chris@0 242 echo "\n\n", '==========', "\n\n", 'There were: ', "\n";
Chris@0 243 if (0 !== $parseFail) {
Chris@0 244 echo ' ', $parseFail, ' parse failures.', "\n";
Chris@0 245 }
Chris@0 246 if (0 !== $ppFail) {
Chris@0 247 echo ' ', $ppFail, ' pretty print failures.', "\n";
Chris@0 248 }
Chris@13 249 if (0 !== $fpppFail) {
Chris@13 250 echo ' ', $fpppFail, ' FPPP failures.', "\n";
Chris@13 251 }
Chris@0 252 if (0 !== $compareFail) {
Chris@0 253 echo ' ', $compareFail, ' compare failures.', "\n";
Chris@0 254 }
Chris@0 255 }
Chris@0 256
Chris@0 257 echo "\n",
Chris@0 258 'Tested files: ', $count, "\n",
Chris@0 259 "\n",
Chris@0 260 'Reading files took: ', $readTime, "\n",
Chris@0 261 'Parsing took: ', $parseTime, "\n",
Chris@13 262 'Cloning took: ', $cloneTime, "\n",
Chris@13 263 'FPPP took: ', $fpppTime, "\n",
Chris@0 264 'Pretty printing took: ', $ppTime, "\n",
Chris@0 265 'Reparsing took: ', $reparseTime, "\n",
Chris@0 266 'Comparing took: ', $compareTime, "\n",
Chris@0 267 "\n",
Chris@0 268 'Total time: ', microtime(true) - $totalStartTime, "\n",
Chris@0 269 'Maximum memory usage: ', memory_get_peak_usage(true), "\n";
Chris@0 270
Chris@0 271 exit($exit);