parsertests.inc

来自「php 开发的内容管理系统」· INC 代码 · 共 792 行 · 第 1/2 页

INC
792
字号
<?php# Copyright (C) 2004 Brion Vibber <brion@pobox.com># http://www.mediawiki.org/## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License along# with this program; if not, write to the Free Software Foundation, Inc.,# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.# http://www.gnu.org/copyleft/gpl.html/** * @todo Make this more independent of the configuration (and if possible the database) * @todo document * @package MediaWiki * @subpackage Maintenance *//** */$options = array( 'quick', 'color', 'quiet', 'help' );$optionsWithArgs = array( 'regex' );require_once( 'commandLine.inc' );require_once( "$IP/includes/ObjectCache.php" );require_once( "$IP/includes/BagOStuff.php" );require_once( "$IP/languages/LanguageUtf8.php" );require_once( "$IP/includes/Hooks.php" );require_once( "$IP/maintenance/parserTestsParserHook.php" );require_once( "$IP/maintenance/parserTestsStaticParserHook.php" );require_once( "$IP/maintenance/parserTestsParserTime.php" );/** * @package MediaWiki * @subpackage Maintenance */class ParserTest {	/**	 * boolean $color whereas output should be colorized	 * @private	 */	var $color;	/**	 * boolean $lightcolor whereas output should use light colors	 * @private	 */	var $lightcolor;	/**	 * Sets terminal colorization and diff/quick modes depending on OS and	 * command-line options (--color and --quick).	 *	 * @public	 */	function ParserTest() {		global $options;		# Only colorize output if stdout is a terminal.		$this->lightcolor = false;		$this->color = !wfIsWindows() && posix_isatty(1);		if( isset( $options['color'] ) ) {			switch( $options['color'] ) {			case 'no':				$this->color = false;				break;			case 'light':				$this->lightcolor = true;				# Fall through			case 'yes':			default:				$this->color = true;				break;			}		}		$this->showDiffs = !isset( $options['quick'] );		$this->quiet = isset( $options['quiet'] );		if (isset($options['regex'])) {			$this->regex = $options['regex'];		} else {			# Matches anything			$this->regex = '';		}				$this->hooks = array();	}	/**	 * Remove last character if it is a newline	 * @private	 */	function chomp($s) {		if (substr($s, -1) === "\n") {			return substr($s, 0, -1);		}		else {			return $s;		}	}	/**	 * Run a series of tests listed in the given text file.	 * Each test consists of a brief description, wikitext input,	 * and the expected HTML output.	 *	 * Prints status updates on stdout and counts up the total	 * number and percentage of passed tests.	 *	 * @param string $filename	 * @return bool True if passed all tests, false if any tests failed.	 * @public	 */	function runTestsFromFile( $filename ) {		$infile = fopen( $filename, 'rt' );		if( !$infile ) {			wfDie( "Couldn't open $filename\n" );		}		$data = array();		$section = null;		$success = 0;		$total = 0;		$n = 0;		while( false !== ($line = fgets( $infile ) ) ) {			$n++;			if( preg_match( '/^!!\s*(\w+)/', $line, $matches ) ) {				$section = strtolower( $matches[1] );				if( $section == 'endarticle') {					if( !isset( $data['text'] ) ) {						wfDie( "'endarticle' without 'text' at line $n\n" );					}					if( !isset( $data['article'] ) ) {						wfDie( "'endarticle' without 'article' at line $n\n" );					}					$this->addArticle($this->chomp($data['article']), $this->chomp($data['text']), $n);					$data = array();					$section = null;					continue;				}				if( $section == 'endhooks' ) {					if( !isset( $data['hooks'] ) ) {						wfDie( "'endhooks' without 'hooks' at line $n\n" );					}					foreach( explode( "\n", $data['hooks'] ) as $line ) {						$line = trim( $line );						if( $line ) {							$this->requireHook( $line );						}					}					$data = array();					$section = null;					continue;				}				if( $section == 'end' ) {					if( !isset( $data['test'] ) ) {						wfDie( "'end' without 'test' at line $n\n" );					}					if( !isset( $data['input'] ) ) {						wfDie( "'end' without 'input' at line $n\n" );					}					if( !isset( $data['result'] ) ) {						wfDie( "'end' without 'result' at line $n\n" );					}					if( !isset( $data['options'] ) ) {						$data['options'] = '';					}					else {						$data['options'] = $this->chomp( $data['options'] );					}					if (preg_match('/\\bdisabled\\b/i', $data['options'])						|| !preg_match("/{$this->regex}/i", $data['test'])) {						# disabled test						$data = array();						$section = null;						continue;					}					if( $this->runTest(						$this->chomp( $data['test'] ),						$this->chomp( $data['input'] ),						$this->chomp( $data['result'] ),						$this->chomp( $data['options'] ) ) ) {						$success++;					}					$total++;					$data = array();					$section = null;					continue;				}				if ( isset ($data[$section] ) ) {					wfDie( "duplicate section '$section' at line $n\n" );				}				$data[$section] = '';				continue;			}			if( $section ) {				$data[$section] .= $line;			}		}		if( $total > 0 ) {			$ratio = wfPercent( 100 * $success / $total );			print $this->termColor( 1 ) . "\nPassed $success of $total tests ($ratio) ";			if( $success == $total ) {				print $this->termColor( 32 ) . "PASSED!";			} else {				print $this->termColor( 31 ) . "FAILED!";			}			print $this->termReset() . "\n";			return ($success == $total);		} else {			wfDie( "No tests found.\n" );		}	}	/**	 * Run a given wikitext input through a freshly-constructed wiki parser,	 * and compare the output against the expected results.	 * Prints status and explanatory messages to stdout.	 *	 * @param string $input Wikitext to try rendering	 * @param string $result Result to output	 * @return bool	 */	function runTest( $desc, $input, $result, $opts ) {		if( !$this->quiet ) {			$this->showTesting( $desc );		}		$this->setupGlobals($opts);		$user =& new User();		$options = ParserOptions::newFromUser( $user );		if (preg_match('/\\bmath\\b/i', $opts)) {			# XXX this should probably be done by the ParserOptions			$options->setUseTex(true);		}		if (preg_match('/title=\[\[(.*)\]\]/', $opts, $m)) {			$titleText = $m[1];		}		else {			$titleText = 'Parser test';		}		$noxml = (bool)preg_match( '~\\b noxml \\b~x', $opts );		$parser =& new Parser();		foreach( $this->hooks as $tag => $callback ) {			$parser->setHook( $tag, $callback );		}		wfRunHooks( 'ParserTestParser', array( &$parser ) );				$title =& Title::makeTitle( NS_MAIN, $titleText );		if (preg_match('/\\bpst\\b/i', $opts)) {			$out = $parser->preSaveTransform( $input, $title, $user, $options );		} elseif (preg_match('/\\bmsg\\b/i', $opts)) {			$out = $parser->transformMsg( $input, $options );		} elseif( preg_match( '/\\bsection=(\d+)\b/i', $opts, $matches ) ) {			$section = intval( $matches[1] );			$out = $parser->getSection( $input, $section );		} elseif( preg_match( '/\\breplace=(\d+),"(.*?)"/i', $opts, $matches ) ) {			$section = intval( $matches[1] );			$replace = $matches[2];			$out = $parser->replaceSection( $input, $section, $replace );		} else {			$output = $parser->parse( $input, $title, $options, true, true, 1337 );			$out = $output->getText();			if (preg_match('/\\bill\\b/i', $opts)) {				$out = $this->tidy( implode( ' ', $output->getLanguageLinks() ) );			} else if (preg_match('/\\bcat\\b/i', $opts)) {				global $wgOut;				$wgOut->addCategoryLinks($output->getCategories());				$out = $this->tidy ( implode( ' ', $wgOut->getCategoryLinks() ) );			}			$result = $this->tidy($result);		}		$this->teardownGlobals();		if( $result === $out && ( $noxml === true || $this->wellFormed( $out ) ) ) {			return $this->showSuccess( $desc );		} else {			return $this->showFailure( $desc, $result, $out );		}	}	/**	 * Set up the global variables for a consistent environment for each test.	 * Ideally this should replace the global configuration entirely.	 *	 * @private	 */	function setupGlobals($opts = '') {		# Save the prefixed / quoted table names for later use when we make the temporaries.		$db =& wfGetDB( DB_READ );		$this->oldTableNames = array();		foreach( $this->listTables() as $table ) {			$this->oldTableNames[$table] = $db->tableName( $table );		}		if( !isset( $this->uploadDir ) ) {			$this->uploadDir = $this->setupUploadDir();		}				if( preg_match( '/language=([a-z]+(?:_[a-z]+)?)/', $opts, $m ) ) {			$lang = $m[1];		} else {			$lang = 'en';		}		$settings = array(			'wgServer' => 'http://localhost',			'wgScript' => '/index.php',			'wgScriptPath' => '/',			'wgArticlePath' => '/wiki/$1',			'wgActionPaths' => array(),			'wgUploadPath' => 'http://example.com/images',			'wgUploadDirectory' => $this->uploadDir,			'wgStyleSheetPath' => '/skins',			'wgSitename' => 'MediaWiki',			'wgServerName' => 'Britney Spears',			'wgLanguageCode' => $lang,			'wgContLanguageCode' => $lang,			'wgDBprefix' => 'parsertest_',			'wgDefaultUserOptions' => array(),			'wgLang' => null,			'wgContLang' => null,			'wgNamespacesWithSubpages' => array( 0 => preg_match('/\\bsubpage\\b/i', $opts)),			'wgMaxTocLevel' => 999,			'wgCapitalLinks' => true,			'wgDefaultUserOptions' => array(),			'wgNoFollowLinks' => true,			'wgThumbnailScriptPath' => false,			'wgUseTeX' => false,			'wgLocaltimezone' => 'UTC',			'wgAllowExternalImages' => true,			);		$this->savedGlobals = array();		foreach( $settings as $var => $val ) {			$this->savedGlobals[$var] = $GLOBALS[$var];			$GLOBALS[$var] = $val;		}		$langClass = 'Language' . str_replace( '-', '_', ucfirst( $lang ) );		$langObj = setupLangObj( $langClass );		$GLOBALS['wgLang'] = $langObj;		$GLOBALS['wgContLang'] = $langObj;		$GLOBALS['wgLoadBalancer']->loadMasterPos();		$GLOBALS['wgMessageCache'] = new MessageCache( new BagOStuff(), false, 0, $GLOBALS['wgDBname'] );		$this->setupDatabase();		global $wgUser;		$wgUser = new User();	}	# List of temporary tables to create, without prefix	# Some of these probably aren't necessary	function listTables() {		$tables = array('user', 'page', 'revision', 'text',			'pagelinks', 'imagelinks', 'categorylinks',			'templatelinks', 'externallinks', 'langlinks',			'site_stats', 'hitcounter',			'ipblocks', 'image', 'oldimage',			'recentchanges',			'watchlist', 'math', 'searchindex',			'interwiki', 'querycache',			'objectcache', 'job'		);		// FIXME manually adding additional table for the tasks extension		// we probably need a better software wide system to register new		// tables.		global $wgExtensionFunctions;		if( in_array('wfTasksExtension' , $wgExtensionFunctions ) ) {			$tables[] = 'tasks';		}		return $tables;	}	/**	 * Set up a temporary set of wiki tables to work with for the tests.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?