Set language to en for tests.
[lhc/web/wiklou.git] / maintenance / parserTests.php
1 <?php
2 # Copyright (C) 2004 Brion Vibber <brion@pobox.com>
3 # http://www.mediawiki.org/
4 #
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.
9 #
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.
14 #
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
19
20 /**
21 * @todo Make this more independent of the configuration (and if possible the database)
22 * @todo document
23 * @package MediaWiki
24 * @subpackage Maintenance
25 */
26
27 /** */
28 require_once( 'commandLine.inc' );
29 include_once( 'InitialiseMessages.inc' );
30
31 $wgTitle = Title::newFromText( 'Parser test script' );
32
33 class ParserTest {
34 function ParserTest() {
35 if( isset( $_SERVER['argv'] ) && in_array( '--color', $_SERVER['argv'] ) ) {
36 $this->color = true;
37 } elseif( isset( $_SERVER['argv'] ) && in_array( '--color=yes', $_SERVER['argv'] ) ) {
38 $this->color = true;
39 } elseif( isset( $_SERVER['argv'] ) && in_array( '--color=no', $_SERVER['argv'] ) ) {
40 $this->color = false;
41 } elseif( wfIsWindows() ) {
42 $this->color = false;
43 } else {
44 $this->color = true;
45 }
46
47 if( isset( $_SERVER['argv'] ) && in_array( '--quick', $_SERVER['argv'] ) ) {
48 $this->showDiffs = false;
49 } else {
50 $this->showDiffs = true;
51 }
52 }
53
54 function runTestsFromFile( $filename ) {
55 $infile = fopen( $filename, 'rt' );
56 if( !$infile ) {
57 die( "Couldn't open parserTests.txt\n" );
58 }
59
60 $data = array();
61 $section = null;
62 $success = 0;
63 $total = 0;
64 $n = 0;
65 while( false !== ($line = fgets( $infile ) ) ) {
66 $n++;
67 if( preg_match( '/^!!\s*(\w+)/', $line, $matches ) ) {
68 $section = strtolower( $matches[1] );
69 if( $section == 'end' ) {
70 if (isset ($data['disabled'])) {
71 # disabled test
72 $data = array();
73 $section = null;
74 continue;
75 }
76 if( !isset( $data['test'] ) ) {
77 die( "'end' without 'test' at line $n\n" );
78 }
79 if( !isset( $data['input'] ) ) {
80 die( "'end' without 'input' at line $n\n" );
81 }
82 if( !isset( $data['result'] ) ) {
83 die( "'end' without 'result' at line $n\n" );
84 }
85 if( $this->runTest(
86 rtrim( $data['test'] ),
87 rtrim( $data['input'] ),
88 rtrim( $data['result'] ) ) ) {
89 $success++;
90 }
91 $total++;
92 $data = array();
93 $section = null;
94 continue;
95 }
96 $data[$section] = '';
97 continue;
98 }
99 if( $section ) {
100 $data[$section] .= $line;
101 }
102 }
103 if( $total > 0 ) {
104 $ratio = IntVal( 100.0 * $success / $total );
105 print "\nPassed $success of $total tests ($ratio%)\n";
106 return ($success == $total);
107 } else {
108 die( "No tests found.\n" );
109 }
110 }
111
112 /**
113 * @param string $input Wikitext to try rendering
114 * @param string $result Result to output
115 * @return bool
116 */
117 function runTest( $desc, $input, $result ) {
118 print "Running test $desc... ";
119
120 $this->setupGlobals();
121
122 $user =& new User();
123 $options =& ParserOptions::newFromUser( $user );
124 $parser =& new Parser();
125 $title =& Title::makeTitle( NS_MAIN, 'Parser_test' );
126
127 $output =& $parser->parse( $input, $title, $options );
128
129 $html = $output->getText();
130 # $languageLinks = $output->getLanguageLinks();
131 # $categoryLinks = $output->getCategoryLinks();
132
133 $op = new OutputPage();
134 $op->replaceLinkHolders($html);
135
136 global $wgUseTidy;
137 if ($wgUseTidy) {
138 # Using Parser here is probably theoretically
139 # wrong, because we shouldn't use Parser to
140 # validate itself, but this should be safe
141 # in practice.
142 $result = Parser::tidy($result);
143 }
144
145 $this->teardownGlobals();
146
147 if( rtrim($result) === rtrim($html) ) {
148 return $this->showSuccess( $desc );
149 } else {
150 return $this->showFailure( $desc, $result, $html );
151 }
152 }
153
154 function setupGlobals() {
155 $settings = array(
156 'wgServer' => 'http://localhost',
157 'wgScript' => '/index.php',
158 'wgScriptPath' => '/',
159 'wgArticlePath' => '/wiki/$1',
160 'wgSitename' => 'MediaWiki',
161 'wgLanguageCode' => 'en',
162 'wgLang' => new LanguageUtf8(),
163 );
164 $this->savedGlobals = array();
165 foreach( $settings as $var => $val ) {
166 $this->savedGlobals[$var] = $GLOBALS[$var];
167 $GLOBALS[$var] = $val;
168 }
169 }
170
171 function teardownGlobals() {
172 foreach( $this->savedGlobals as $var => $val ) {
173 $GLOBALS[$var] = $val;
174 }
175 }
176
177 function showSuccess( $desc ) {
178 print $this->termColor( '1;32' ) . 'PASSED' . $this->termReset() . "\n";
179 return true;
180 }
181
182 function showFailure( $desc, $result, $html ) {
183 print $this->termColor( '1;31' ) . 'FAILED!' . $this->termReset() . "\n";
184 if( $this->showDiffs ) {
185 print $this->quickDiff( $result, $html );
186 }
187 return false;
188 }
189
190 function quickDiff( $input, $output ) {
191 $prefix = "/tmp/mwParser-" . mt_rand();
192
193 $infile = "$prefix-in";
194 $this->dumpToFile( $input, $infile );
195
196 $outfile = "$prefix-out";
197 $this->dumpToFile( $output, $outfile );
198
199 $diff = `diff -u $infile $outfile`;
200 unlink( $infile );
201 unlink( $outfile );
202
203 return $this->colorDiff( $diff );
204 }
205
206 function dumpToFile( $data, $filename ) {
207 $file = fopen( $filename, "wt" );
208 fwrite( $file, rtrim( $data ) . "\n" );
209 fclose( $file );
210 }
211
212 function termColor( $color ) {
213 return $this->color ? "\x1b[{$color}m" : '';
214 }
215
216 function termReset() {
217 return $this->color ? "\x1b[0m" : '';
218 }
219
220 function colorDiff( $text ) {
221 return preg_replace(
222 array( '/^(-.*)$/m', '/^(\+.*)$/m' ),
223 array( $this->termColor( 34 ) . '$1' . $this->termReset(),
224 $this->termColor( 31 ) . '$1' . $this->termReset() ),
225 $text );
226 }
227 }
228
229 $tester =& new ParserTest();
230
231 # Note: the command line setup changes the current working directory
232 # to the parent, which is why we have to put the subdir here:
233 $ok = $tester->runTestsFromFile( 'maintenance/parserTests.txt' );
234
235 exit ($ok ? 0 : -1);
236
237 ?>