���ѧۧݧ�ӧ�� �ާ֧ߧ֧էا֧� - ���֧էѧܧ�ڧ��ӧѧ�� - /home/rickpfrv/wiki.craftaro.com/vendor/wikimedia/parsoid/bin/parserTests.php
���ѧ٧ѧ�
<?php // phpcs:disable Generic.Files.LineLength.TooLong require_once __DIR__ . '/../tools/Maintenance.php'; use SebastianBergmann\Diff\Differ; use Wikimedia\Parsoid\ParserTests\Stats; use Wikimedia\Parsoid\ParserTests\Test; use Wikimedia\Parsoid\ParserTests\TestRunner; use Wikimedia\Parsoid\ParserTests\TestUtils; use Wikimedia\Parsoid\Tools\ScriptUtils; // phpcs:ignore MediaWiki.Files.ClassMatchesFilename.WrongCase class ParserTests extends \Wikimedia\Parsoid\Tools\Maintenance { use \Wikimedia\Parsoid\Tools\ExtendedOptsProcessor; /** @var array */ public $processedOptions; // PORT-FIXME: Used to be colors::mode in all the use sites public static $colors_mode; /** @var Differ */ private static $differ; public function __construct() { parent::__construct(); self::setupOpts( $this ); $this->setAllowUnregisteredOptions( false ); } public function finalSetup() { parent::finalSetup(); self::requireTestsAutoloader(); } public function execute(): bool { $this->processedOptions = self::processOptions( $this ); $testFile = $this->getArg( 0 ); if ( $testFile ) { $testFilePaths = [ realpath( $testFile ) ]; } else { $testFilePaths = []; $testFiles = json_decode( file_get_contents( __DIR__ . '/../tests/parserTests.json' ), true ); foreach ( $testFiles as $f => $info ) { $testFilePaths[] = realpath( __DIR__ . '/../tests/parser/' . $f ); } } $globalStats = new Stats(); $knownFailuresChanged = false; $exitCode = 0; if ( $this->processedOptions['integrated'] ?? false ) { // Some methods which are discouraged for normal code throw // exceptions unless we declare this is just a test. define( 'MW_PARSER_TEST', true ); // See Ifaf53862b96e9127d8f375ad8dd0cc362cba9f5b in gerrit; // this should use the \ParserTestRunner::runParsoidTest() // method from core. throw new \MWException( "Not yet implemented" ); } else { foreach ( $testFilePaths as $testFile ) { $testRunner = new TestRunner( $testFile, 'standalone', $this->processedOptions['modes'] ); $result = $testRunner->run( $this->processedOptions ); $globalStats->accum( $result['stats'] ); // Sum all stats $knownFailuresChanged = $knownFailuresChanged || $result['knownFailuresChanged']; $exitCode = $exitCode ?: $result['exitCode']; if ( $exitCode !== 0 && $this->processedOptions['exit-unexpected'] ) { break; } } } $this->processedOptions['reportSummary']( [], $globalStats, null, null, $knownFailuresChanged, $this->processedOptions ); return $exitCode === 0; } /** * Process CLI opts and return * * @param \Wikimedia\Parsoid\Tools\Maintenance $script */ public static function setupOpts( \Wikimedia\Parsoid\Tools\Maintenance $script ): void { $opts = ScriptUtils::addStandardOptions( [ 'wt2html' => [ 'description' => 'Wikitext -> HTML(DOM)', 'default' => false, 'boolean' => true ], 'html2wt' => [ 'description' => 'HTML(DOM) -> Wikitext', 'default' => false, 'boolean' => true ], 'wt2wt' => [ 'description' => 'Roundtrip testing: Wikitext -> DOM(HTML) -> Wikitext', 'default' => false, 'boolean' => true ], 'html2html' => [ 'description' => 'Roundtrip testing: HTML(DOM) -> Wikitext -> HTML(DOM)', 'default' => false, 'boolean' => true ], 'selser' => [ 'description' => 'Roundtrip testing: Wikitext -> DOM(HTML) -> Wikitext (with selective serialization). ' . 'Set to "noauto" to just run the tests with manual selser changes.', 'boolean' => false ], 'changetree' => [ 'description' => 'Changes to apply to parsed HTML to generate new HTML to be serialized (useful with selser)', 'default' => null, 'boolean' => false ], 'numchanges' => [ 'description' => 'Make multiple different changes to the DOM, run a selser test for each one.', 'default' => 20, 'boolean' => false ], 'cache' => [ 'description' => 'Get tests cases from cache file', 'boolean' => true, 'default' => false ], 'filter' => [ 'description' => 'Only run tests whose descriptions match given string' ], 'regex' => [ 'description' => 'Only run tests whose descriptions match given regex', 'alias' => [ 'regexp', 're' ] ], 'run-disabled' => [ 'description' => 'Run disabled tests', 'default' => false, 'boolean' => true ], 'run-php' => [ 'description' => 'Run php-only tests', 'default' => false, 'boolean' => true ], 'maxtests' => [ 'description' => 'Maximum number of tests to run', 'boolean' => false ], 'quick' => [ 'description' => 'Suppress diff output of failed tests', 'boolean' => true, 'default' => false ], 'quiet' => [ 'description' => 'Suppress notification of passed tests (shows only failed tests)', 'boolean' => true, 'default' => false ], 'quieter' => [ 'description' => 'Suppress per-file summary and failed test diffs. ' . 'Implies --quick and --quiet.', 'boolean' => true, 'default' => false ], 'offsetType' => [ 'description' => 'Test DSR offset conversion code while running tests.', 'boolean' => false, 'default' => 'byte', ], 'knownFailures' => [ 'description' => 'Compare against known failures', 'default' => true, 'boolean' => false ], 'updateKnownFailures' => [ 'description' => 'Update parserTests-knownFailures.json with failing tests.', 'default' => false, 'boolean' => true ], 'exit-zero' => [ 'description' => "Don't exit with nonzero status if failures are found.", 'default' => false, 'boolean' => true ], 'xml' => [ 'description' => 'Print output in JUnit XML format.', 'default' => false, 'boolean' => true ], 'exit-unexpected' => [ 'description' => 'Exit after the first unexpected result.', 'default' => false, 'boolean' => true ], 'update-tests' => [ 'description' => 'Update parserTests.txt with results from wt2html fails.' ], 'update-unexpected' => [ 'description' => 'Update parserTests.txt with results from wt2html unexpected fails.', 'default' => false, 'boolean' => true ] ], [ // override defaults for standard options 'fetchTemplates' => false, 'usePHPPreProcessor' => false, 'fetchConfig' => false ] ); foreach ( $opts as $opt => $optInfo ) { $script->addOption( $opt, $optInfo['description'], false, empty( $optInfo['boolean'] ), false ); if ( isset( $optInfo['default'] ) ) { $script->setOptionDefault( $opt, $optInfo['default'] ); } } } /** * @param \Wikimedia\Parsoid\Tools\Maintenance $script * @return array */ public static function processOptions( \Wikimedia\Parsoid\Tools\Maintenance $script ): array { $options = $script->optionsToArray(); if ( $options['help'] ) { $script->maybeHelp(); print "Additional dump options specific to parserTests script:\n" . "* dom:post-changes : Dumps DOM after applying selser changetree\n" . "Examples\n" . "\$ php parserTests.php --selser --filter '...' --dump dom:post-changes\n" . "\$ php parserTests.php --selser --filter '...' --changetree '...' --dump dom:post-changes\n"; die( 0 ); } ScriptUtils::setColorFlags( $options ); if ( !( $options['wt2wt'] || $options['wt2html'] || $options['html2wt'] || $options['html2html'] || isset( $options['selser'] ) ) ) { $options['wt2wt'] = true; $options['wt2html'] = true; $options['html2html'] = true; $options['html2wt'] = true; if ( ScriptUtils::booleanOption( $options['updateKnownFailures'] ?? null ) ) { // turn on all modes by default for --updateKnownFailures $options['selser'] = true; // double checking options are valid (T53448 asks to be able to use --filter here) if ( isset( $options['filter'] ) || isset( $options['regex'] ) || isset( $options['maxtests'] ) || $options['exit-unexpected'] ) { print "\nERROR: can't combine --updateKnownFailures with --filter, --maxtests or --exit-unexpected"; die( 1 ); } } } if ( $options['xml'] ) { $options['reportResult'] = [ self::class, 'reportResultXML' ]; $options['reportStart'] = [ self::class, 'reportStartXML' ]; $options['reportSummary'] = [ self::class, 'reportSummaryXML' ]; $options['reportFailure'] = [ self::class, 'reportFailureXML' ]; self::$colors_mode = 'none'; } if ( !is_callable( $options['reportFailure'] ?? null ) ) { // default failure reporting is standard out, // see printFailure for documentation of the default. $options['reportFailure'] = [ self::class, 'printFailure' ]; } if ( !is_callable( $options['reportSuccess'] ?? null ) ) { // default success reporting is standard out, // see printSuccess for documentation of the default. $options['reportSuccess'] = [ self::class, 'printSuccess' ]; } if ( !is_callable( $options['reportStart'] ?? null ) ) { // default summary reporting is standard out, // see reportStart for documentation of the default. $options['reportStart'] = [ self::class, 'reportStartOfTests' ]; } if ( !is_callable( $options['reportSummary'] ?? null ) ) { // default summary reporting is standard out, // see reportSummary for documentation of the default. $options['reportSummary'] = [ self::class, 'reportSummary' ]; } if ( !is_callable( $options['reportResult'] ?? null ) ) { // default result reporting is standard out, // see printResult for documentation of the default. $options['reportResult'] = function ( ...$args ) use ( &$options ) { return self::printResult( $options['reportFailure'], $options['reportSuccess'], ...$args ); }; } if ( !is_callable( $options['getDiff'] ?? null ) ) { // this is the default for diff-getting, but it can be overridden // see doDiff for documentation of the default. $options['getDiff'] = [ self::class, 'doDiff' ]; } if ( !is_callable( $options['getActualExpected'] ?? null ) ) { // this is the default for getting the actual and expected // outputs, but it can be overridden // see getActualExpected for documentation of the default. $options['getActualExpected'] = [ self::class, 'getActualExpected' ]; } $options['modes'] = []; foreach ( Test::ALL_TEST_MODES as $m ) { if ( ( $m !== 'selser' && $options[$m] ) || ( $m === 'selser' && isset( $options[$m] ) ) ) { $options['modes'][] = $m; } } return $options; } /** * Colorize given number if <> 0. * * @param int $count * @param string $color * @return string Colorized count */ private static function colorizeCount( int $count, string $color ): string { $s = (string)$count; return TestUtils::colorString( $s, $color ); } /** * @param array $modesRan * @param Stats $stats * - failedTests int Number of failed tests due to differences in output. * - passedTests int Number of tests passed without any special consideration. * - modes array All of the stats (failedTests, passedTests) per-mode. * @param ?string $file * @param ?array $testFilter * @param bool $knownFailuresChanged * @param array $options */ public static function reportSummary( array $modesRan, Stats $stats, ?string $file, ?array $testFilter, bool $knownFailuresChanged, array $options ): void { $curStr = null; $mode = null; $thisMode = null; $failTotalTests = $stats->failedTests; $happiness = $stats->passedTestsUnexpected === 0 && $stats->failedTestsUnexpected === 0; $filename = $file === null ? 'ALL TESTS' : $file; $quieter = ScriptUtils::booleanOption( $options['quieter'] ?? '' ); if ( $quieter && $file !== null ) { return; } if ( !$quieter ) { print "==========================================================\n"; print 'SUMMARY:' . TestUtils::colorString( $filename, $happiness ? 'green' : 'red' ) . "\n"; } if ( $file !== null ) { print 'Execution time: ' . round( 1000 * ( microtime( true ) - $stats->startTime ), 3 ) . "ms\n"; } if ( $failTotalTests !== 0 ) { foreach ( $modesRan as $mode ) { $curStr = $mode . ': '; $thisMode = $stats->modes[$mode]; $curStr .= self::colorizeCount( $thisMode->passedTests, 'green' ) . ' passed ('; $curStr .= self::colorizeCount( $thisMode->passedTestsUnexpected, 'red' ) . ' unexpected) / '; $curStr .= self::colorizeCount( $thisMode->failedTests, 'red' ) . ' failed ('; $curStr .= self::colorizeCount( $thisMode->failedTestsUnexpected, 'red' ) . ' unexpected)'; print $curStr . "\n"; } $curStr = 'TOTAL' . ': '; $curStr .= self::colorizeCount( $stats->passedTests, 'green' ) . ' passed ('; $curStr .= self::colorizeCount( $stats->passedTestsUnexpected, 'red' ) . ' unexpected) / '; $curStr .= self::colorizeCount( $stats->failedTests, 'red' ) . ' failed ('; $curStr .= self::colorizeCount( $stats->failedTestsUnexpected, 'red' ) . ' unexpected)'; print $curStr . "\n"; if ( $file === null ) { $buf = self::colorizeCount( $stats->passedTests, 'green' ); $buf .= ' total passed tests (expected '; $buf .= (string)( $stats->passedTests - $stats->passedTestsUnexpected + $stats->failedTestsUnexpected ); $buf .= '), '; $buf .= self::colorizeCount( $failTotalTests, 'red' ) . ' total failures (expected '; $buf .= (string)( $stats->failedTests - $stats->failedTestsUnexpected + $stats->passedTestsUnexpected ); $buf .= ")\n"; print $buf; } } else { if ( $testFilter !== null ) { $buf = 'Passed ' . $stats->passedTests . ' of ' . $stats->passedTests . ' tests matching ' . $testFilter['raw']; } else { // Should not happen if it does: Champagne! $buf = 'Passed ' . $stats->passedTests . ' of ' . $stats->passedTests . ' tests'; } print $buf . '... ' . TestUtils::colorString( 'ALL TESTS PASSED!', 'green' ) . "\n"; } // If we logged error messages, complain about it. $logMsg = TestUtils::colorString( 'No errors logged.', 'green' ); if ( $stats->loggedErrorCount > 0 ) { $logMsg = TestUtils::colorString( $stats->loggedErrorCount . ' errors logged.', 'red' ); } if ( $file === null ) { if ( $stats->loggedErrorCount > 0 ) { $logMsg = TestUtils::colorString( '' . $stats->loggedErrorCount, 'red' ); } else { $logMsg = TestUtils::colorString( '' . $stats->loggedErrorCount, 'green' ); } $logMsg .= ' errors logged.'; } print $logMsg . "\n"; $failures = $stats->allFailures(); // If the knownFailures changed, complain about it. if ( $knownFailuresChanged ) { print TestUtils::colorString( 'Known failures changed!', 'red' ) . "\n"; } if ( $file === null ) { if ( $failures === 0 ) { print '--> ' . TestUtils::colorString( 'NO UNEXPECTED RESULTS', 'green' ) . " <--\n"; if ( $knownFailuresChanged ) { print "Perhaps some tests were deleted or renamed.\n"; print "Use `php bin/parserTests.php --updateKnownFailures` to update knownFailures list.\n"; } } else { print TestUtils::colorString( '--> ' . $failures . ' UNEXPECTED RESULTS. <--', 'red' ) . "\n"; } } } /** * @param ?array $iopts * @return string */ private static function prettyPrintIOptions( ?array $iopts = null ): string { if ( !$iopts ) { return ''; } $ppValue = null; // Forward declaration $ppValue = static function ( $v ) use ( &$ppValue ) { if ( is_array( $v ) ) { return implode( ',', array_map( $ppValue, $v ) ); } if ( is_string( $v ) && ( preg_match( '/^\[\[[^\]]*\]\]$/D', $v ) || preg_match( '/^[-\w]+$/D', $v ) ) ) { return $v; } return json_encode( $v ); }; $strPieces = array_map( static function ( $k ) use ( $iopts, $ppValue ) { if ( $iopts[$k] === '' ) { return $k; } return $k . '=' . $ppValue( $iopts[$k] ); }, array_keys( $iopts ) ); return implode( ' ', $strPieces ); } /** * @param Stats $stats * @param Test $item * @param array $options * @param string $mode * @param string $title * @param array $actual * @param array $expected * @param ?string $expectFail If this test was expected to fail (on knownFailures list), then the expected failure output; otherwise null. * @return bool true if the failure was expected. */ public static function printFailure( Stats $stats, Test $item, array $options, string $mode, string $title, array $actual, array $expected, ?string $expectFail ): bool { $quiet = ScriptUtils::booleanOption( $options['quiet'] ?? null ); $quieter = ScriptUtils::booleanOption( $options['quieter'] ?? null ); $quick = ScriptUtils::booleanOption( $options['quick'] ?? null ); $failureOnly = $quieter || $quick; $extTitle = str_replace( "\n", ' ', "$title ($mode)" ); $knownFailures = false; if ( ScriptUtils::booleanOption( $options['knownFailures'] ?? null ) && $expectFail !== null ) { // compare with remembered output $offsetType = $options['offsetType'] ?? 'byte'; if ( TestUtils::normalizeAbout( $expectFail ) !== TestUtils::normalizeAbout( $actual['raw'] ) && $offsetType === 'byte' ) { $knownFailures = true; } else { if ( !$quiet && !$quieter ) { print TestUtils::colorString( 'EXPECTED FAIL', 'red' ) . ': ' . TestUtils::colorString( $extTitle, 'yellow' ) . "\n"; } return true; } } if ( !$failureOnly ) { print "=====================================================\n"; } if ( $knownFailures ) { print TestUtils::colorString( 'UNEXPECTED CHANGE TO KNOWN FAILURE OUTPUT', 'red', true ) . ': ' . TestUtils::colorString( $extTitle, 'yellow' ) . "\n"; print TestUtils::colorString( 'Known failure, but the output changed!', 'red' ) . "\n"; } else { print TestUtils::colorString( 'UNEXPECTED FAIL', 'red', true ) . ': ' . TestUtils::colorString( $extTitle, 'yellow' ) . "\n"; } if ( $mode === 'selser' ) { if ( $item->wt2wtPassed ) { print TestUtils::colorString( 'Even worse, the non-selser wt2wt test passed!', 'red' ) . "\n"; } elseif ( $actual && $item->wt2wtResult !== $actual['raw'] ) { print TestUtils::colorString( 'Even worse, the non-selser wt2wt test had a different result!', 'red' ) . "\n"; } } if ( !$failureOnly ) { // PORT-FIXME: Removed comments .. maybe need to put it back // print implode( "\n", $item->comments ) . "\n"; if ( $options ) { print TestUtils::colorString( 'OPTIONS', 'cyan' ) . ':' . "\n"; print self::prettyPrintIOptions( $item->options ) . "\n"; } print TestUtils::colorString( 'INPUT', 'cyan' ) . ':' . "\n"; print $actual['input'] . "\n"; print $options['getActualExpected']( $actual, $expected, $options['getDiff'] ) . "\n"; } return false; } /** * @param Stats $stats * @param Test $item * @param array $options * @param string $mode * @param string $title * @param bool $expectSuccess Whether this success was expected (or was it a known failure). * @return bool true if the success was expected. */ public static function printSuccess( Stats $stats, Test $item, array $options, string $mode, string $title, bool $expectSuccess ): bool { $quiet = ScriptUtils::booleanOption( $options['quiet'] ?? null ); $quieter = ScriptUtils::booleanOption( $options['quieter'] ?? null ); $extTitle = str_replace( "\n", ' ', "$title ($mode)" ); if ( ScriptUtils::booleanOption( $options['knownFailures'] ?? null ) && !$expectSuccess ) { print TestUtils::colorString( 'UNEXPECTED PASS', 'green', true ) . ': ' . TestUtils::colorString( $extTitle, 'yellow' ) . "\n"; return false; } if ( !$quiet && !$quieter ) { $outStr = 'EXPECTED PASS'; $outStr = TestUtils::colorString( $outStr, 'green' ) . ': ' . TestUtils::colorString( $extTitle, 'yellow' ); print $outStr . "\n"; if ( $mode === 'selser' && isset( $item->wt2wtPassed ) && !$item->wt2wtPassed ) { print TestUtils::colorString( 'Even better, the non-selser wt2wt test failed!', 'red' ) . "\n"; } } return true; } /** * Print the actual and expected outputs. * * @param array $actual * - string raw * - string normal * @param array $expected * - string raw * - string normal * @param callable $getDiff Returns a string showing the diff(s) for the test. * - array actual * - array expected * @return string */ public static function getActualExpected( array $actual, array $expected, callable $getDiff ): string { if ( self::$colors_mode === 'none' ) { $mkVisible = static function ( $s ) { return $s; }; } else { $mkVisible = static function ( $s ) { return preg_replace( '/\xA0/', TestUtils::colorString( "␣", "white" ), preg_replace( '/\n/', TestUtils::colorString( "↵\n", "white" ), $s ) ); }; } $returnStr = ''; $returnStr .= TestUtils::colorString( 'RAW EXPECTED', 'cyan' ) . ":\n"; $returnStr .= $expected['raw'] . "\n"; $returnStr .= TestUtils::colorString( 'RAW RENDERED', 'cyan' ) . ":\n"; $returnStr .= $actual['raw'] . "\n"; $returnStr .= TestUtils::colorString( 'NORMALIZED EXPECTED', 'magenta' ) . ":\n"; $returnStr .= $mkVisible( $expected['normal'] ) . "\n"; $returnStr .= TestUtils::colorString( 'NORMALIZED RENDERED', 'magenta' ) . ":\n"; $returnStr .= $mkVisible( $actual['normal'] ) . "\n"; $returnStr .= TestUtils::colorString( 'DIFF', 'cyan' ) . ":\n"; $returnStr .= $getDiff( $actual, $expected ); return $returnStr; } /** * @param array $actual * - string normal * @param array $expected * - string normal * @return string Colorized diff */ public static function doDiff( array $actual, array $expected ): string { // safe to always request color diff, because we set color mode='none' // if colors are turned off. $e = preg_replace( '/\xA0/', "␣", $expected['normal'] ); $a = preg_replace( '/\xA0/', "␣", $actual['normal'] ); // PORT_FIXME: if ( !self::$differ ) { self::$differ = new Differ(); } $diffs = self::$differ->diff( $e, $a ); $diffs = preg_replace_callback( '/^(-.*)/m', static function ( $m ) { return TestUtils::colorString( $m[0], 'green' ); }, $diffs ); $diffs = preg_replace_callback( '/^(\+.*)/m', static function ( $m ) { return TestUtils::colorString( $m[0], 'red' ); }, $diffs ); return $diffs; } /** * @param callable $reportFailure * @param callable $reportSuccess * @param Stats $stats * @param Test $item * @param array $options * @param string $mode * @param array $expected * @param array $actual * @param ?callable $pre * @param ?callable $post * @return bool True if the result was as expected. */ public static function printResult( callable $reportFailure, callable $reportSuccess, Stats $stats, Test $item, array $options, string $mode, array $expected, array $actual, ?callable $pre = null, ?callable $post = null ): bool { $title = $item->testName; // Title may be modified here, so pass it on. $changeTree = $item->changetree; $suffix = ''; if ( $mode === 'selser' ) { $suffix = ' ' . ( $changeTree === [ 'manual' ] ? '[manual]' : json_encode( $changeTree ) ); } elseif ( $mode === 'wt2html' && isset( $item->options['langconv'] ) ) { $title .= ' [langconv]'; } $title .= $suffix; $expectFail = $item->knownFailures[$mode . $suffix] ?? null; $fail = $expected['normal'] !== $actual['normal']; // Return whether the test was as expected, independent of pass/fail $asExpected = null; if ( $mode === 'wt2wt' ) { $item->wt2wtPassed = !$fail; $item->wt2wtResult = $actual['raw']; } // don't report selser fails when nothing was changed or it's a dup if ( $mode === 'selser' && $changeTree !== [ 'manual' ] && ( $changeTree === [] || $item->duplicateChange ) ) { return true; } if ( is_callable( $pre ) ) { $pre( $stats, $mode, $title, $item->time ); } if ( $fail ) { $stats->failedTests++; $stats->modes[$mode]->failedTests++; $asExpected = $reportFailure( $stats, $item, $options, $mode, $title, $actual, $expected, $expectFail ); if ( !$asExpected ) { $stats->failedTestsUnexpected++; $stats->modes[$mode]->failedTestsUnexpected++; } $stats->modes[$mode]->failList[] = [ 'testName' => $item->testName, 'suffix' => $suffix, 'raw' => $actual['raw'] ?? null, 'expected' => $expected['raw'] ?? null, 'actualNormalized' => $actual['normal'] ?? null, 'unexpected' => !$asExpected, ]; } else { $stats->passedTests++; $stats->modes[$mode]->passedTests++; $asExpected = $reportSuccess( $stats, $item, $options, $mode, $title, $expectFail === null ); if ( !$asExpected ) { $stats->passedTestsUnexpected++; $stats->modes[$mode]->passedTestsUnexpected++; } } if ( is_callable( $post ) ) { $post( $stats, $mode ); } return $asExpected; } /** * Simple function for reporting the start of the tests. * * This method can be reimplemented in the options of the ParserTests object. */ public static function reportStartOfTests() { } /** * Get the actual and expected outputs encoded for XML output. * * @inheritDoc getActualExpected * * @return string $The XML representation of the actual and expected outputs. */ public static function getActualExpectedXML( array $actual, array $expected, callable $getDiff ) { $returnStr = ''; $returnStr .= "RAW EXPECTED:\n"; $returnStr .= self::encodeXml( $expected['raw'] ) . "\n\n"; $returnStr .= "RAW RENDERED:\n"; $returnStr .= self::encodeXml( $actual['raw'] ) . "\n\n"; $returnStr .= "NORMALIZED EXPECTED:\n"; $returnStr .= self::encodeXml( $expected['normal'] ) . "\n\n"; $returnStr .= "NORMALIZED RENDERED:\n"; $returnStr .= self::encodeXml( $actual['normal'] ) . "\n\n"; $returnStr .= "DIFF:\n"; $returnStr .= self::encodeXml( $getDiff( $actual, $expected, false ) ); return $returnStr; } /** * Report the start of the tests output. * * @inheritDoc reportStart */ public static function reportStartXML(): void { } /** * Report the end of the tests output. * * @inheritDoc reportSummary */ public static function reportSummaryXML( array $modesRan, Stats $stats, ?string $file, ?array $testFilter, bool $knownFailuresChanged, array $options ): void { if ( $file === null ) { /* Summary for all tests; not included in XML format output. */ return; } print '<testsuites file="' . $file . '">'; for ( $i = 0; $i < count( $modesRan ); $i++ ) { $mode = $modesRan[$i]; print '<testsuite name="parserTests-' . $mode . '">'; print $stats->modes[$mode]->result; print '</testsuite>'; } print '</testsuites>'; } /** * Print a failure message for a test in XML. * * @inheritDoc printFailure */ public static function reportFailureXML( Stats $stats, Test $item, array $options, string $mode, string $title, array $actual, array $expected, ?string $expectFail, bool $failureOnly ): bool { $failEle = ''; $knownFailures = false; if ( ScriptUtils::booleanOption( $options['knownFailures'] ) && $expectFail !== null ) { // compare with remembered output $knownFailures = $expectFail === $actual['raw']; } if ( !$knownFailures ) { $failEle .= "<failure type=\"parserTestsDifferenceInOutputFailure\">\n"; $failEle .= self::getActualExpectedXML( $actual, $expected, $options['getDiff'] ); $failEle .= "\n</failure>"; $stats->modes[$mode]->result .= $failEle; return false; } return true; } /** * Print a success method for a test in XML. * * @inheritDoc printSuccess */ public static function reportSuccessXML( Stats $stats, Test $item, array $options, string $mode, string $title, bool $expectSuccess ): bool { return ScriptUtils::booleanOption( $options['knownFailures'] ?? null ) && !$expectSuccess; } /** * @param Stats $stats * @param string $mode * @param string $title * @param array $time */ private static function pre( Stats $stats, string $mode, string $title, array $time ): void { $testcaseEle = '<testcase name="' . self::encodeXml( $title ) . '" '; $testcaseEle .= 'assertions="1" '; $timeTotal = null; if ( $time && $time['end'] && $time['start'] ) { $timeTotal = $time['end'] - $time['start']; if ( !is_nan( $timeTotal ) ) { $testcaseEle .= 'time="' . ( ( $time['end'] - $time['start'] ) / 1000.0 ) . '"'; } } $testcaseEle .= '>'; $stats->modes[$mode]->result .= $testcaseEle; } /** * @param Stats $stats * @param string $mode */ private static function post( Stats $stats, string $mode ): void { $stats->modes[$mode]->result .= '</testcase>'; } /** * Print the result of a test in XML. * * @inheritDoc printResult */ public static function reportResultXML( ...$args ) { $args[] = [ self::class, 'pre' ]; $args[] = [ self::class, 'post' ]; self::printResult( [ self::class, 'reportFailureXML' ], [ self::class, 'reportSuccessXML' ], ...$args ); // In xml, test all cases always return true; } } $maintClass = ParserTests::class; require_once PARSOID_RUN_MAINTENANCE_IF_MAIN;
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | ���֧ߧ֧�ѧ�ڧ� ����ѧߧڧ��: 0.29 |
proxy
|
phpinfo
|
���ѧ����ۧܧ�