2 # Copyright (C) 2004 Brion Vibber <brion@pobox.com>
3 # http://www.mediawiki.org/
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 # http://www.gnu.org/copyleft/gpl.html
21 * @todo Make this more independent of the configuration (and if possible the database)
24 * @subpackage Maintenance
28 require_once( 'commandLine.inc' );
29 include_once( 'InitialiseMessages.inc' );
31 $wgTitle = Title
::newFromText( 'Parser test script' );
34 function ParserTest() {
35 if( isset( $_SERVER['argv'] ) && in_array( '--color', $_SERVER['argv'] ) ) {
37 } elseif( isset( $_SERVER['argv'] ) && in_array( '--color=yes', $_SERVER['argv'] ) ) {
39 } elseif( isset( $_SERVER['argv'] ) && in_array( '--color=no', $_SERVER['argv'] ) ) {
41 } elseif( wfIsWindows() ) {
48 function runTestsFromFile( $filename ) {
49 $infile = fopen( $filename, 'rt' );
51 die( "Couldn't open parserTests.txt\n" );
59 while( false !== ($line = fgets( $infile ) ) ) {
61 if( preg_match( '/^!!\s*(\w+)/', $line, $matches ) ) {
62 $section = strtolower( $matches[1] );
63 if( $section == 'end' ) {
64 if (isset ($data['disabled'])) {
70 if( !isset( $data['test'] ) ) {
71 die( "'end' without 'test' at line $n\n" );
73 if( !isset( $data['input'] ) ) {
74 die( "'end' without 'input' at line $n\n" );
76 if( !isset( $data['result'] ) ) {
77 die( "'end' without 'result' at line $n\n" );
80 rtrim( $data['test'] ),
81 rtrim( $data['input'] ),
82 rtrim( $data['result'] ) ) ) {
94 $data[$section] .= $line;
98 $ratio = IntVal( 100.0 * $success / $total );
99 print "\nPassed $success of $total tests ($ratio%)\n";
100 return ($success == $total);
102 die( "No tests found.\n" );
107 * @param string $input Wikitext to try rendering
108 * @param string $result Result to output
111 function runTest( $desc, $input, $result ) {
112 print "Running test $desc... ";
114 $this->setupGlobals();
117 $options =& ParserOptions
::newFromUser( $user );
118 $parser =& new Parser();
119 $title =& Title
::makeTitle( NS_MAIN
, 'Parser_test' );
121 $output =& $parser->parse( $input, $title, $options );
123 $html = $output->getText();
124 # $languageLinks = $output->getLanguageLinks();
125 # $categoryLinks = $output->getCategoryLinks();
127 $op = new OutputPage();
128 $op->replaceLinkHolders($html);
132 # Using Parser here is probably theoretically
133 # wrong, because we shouldn't use Parser to
134 # validate itself, but this should be safe
136 $result = Parser
::tidy($result);
139 $this->teardownGlobals();
141 if( rtrim($result) === rtrim($html) ) {
142 return $this->showSuccess( $desc );
144 return $this->showFailure( $desc, $result, $html );
148 function setupGlobals() {
149 static $settings = array(
150 'wgServer' => 'http://localhost',
151 'wgScript' => '/index.php',
152 'wgScriptPath' => '/',
153 'wgArticlePath' => '/wiki/$1',
155 $this->savedGlobals
= array();
156 foreach( $settings as $var => $val ) {
157 $this->savedGlobals
[$var] = $GLOBALS[$var];
158 $GLOBALS[$var] = $val;
162 function teardownGlobals() {
163 foreach( $this->savedGlobals
as $var => $val ) {
164 $GLOBALS[$var] = $val;
168 function showSuccess( $desc ) {
169 print $this->termColor( '1;32' ) . 'PASSED' . $this->termReset() . "\n";
173 function showFailure( $desc, $result, $html ) {
174 print $this->termColor( '1;31' ) . 'FAILED!' . $this->termReset() . "\n";
175 #print "!! Expected:\n$result\n";
176 #print "!! Received:\n$html\n!!\n";
177 print $this->quickDiff( $result, $html );
181 function quickDiff( $input, $output ) {
182 $prefix = "/tmp/mwParser-" . mt_rand();
184 $infile = "$prefix-in";
185 $this->dumpToFile( $input, $infile );
187 $outfile = "$prefix-out";
188 $this->dumpToFile( $output, $outfile );
190 $diff = `diff
-u
$infile $outfile`
;
194 return $this->colorDiff( $diff );
197 function dumpToFile( $data, $filename ) {
198 $file = fopen( $filename, "wt" );
199 fwrite( $file, rtrim( $data ) . "\n" );
203 function termColor( $color ) {
204 return $this->color ?
"\x1b[{$color}m" : '';
207 function termReset() {
208 return $this->color ?
"\x1b[0m" : '';
211 function colorDiff( $text ) {
213 array( '/^(-.*)$/m', '/^(\+.*)$/m' ),
214 array( $this->termColor( 34 ) . '$1' . $this->termReset(),
215 $this->termColor( 31 ) . '$1' . $this->termReset() ),
220 $tester =& new ParserTest();
222 # Note: the command line setup changes the current working directory
223 # to the parent, which is why we have to put the subdir here:
224 $ok = $tester->runTestsFromFile( 'maintenance/parserTests.txt' );