* Create new DatabaseSqlite::checkForEnabledSearch() and use it from SearchSqlite...
[lhc/web/wiklou.git] / maintenance / tests / MediaWikiParserTest.php
1 <?php
2
3 global $IP;
4 define( "NO_COMMAND_LINE", 1 );
5 define( "PARSER_TESTS", "$IP/maintenance/parserTests.txt" );
6
7 require_once( "$IP/maintenance/parserTests.inc" );
8
9 class PHPUnitTestRecorder extends TestRecorder {
10
11 function record( $test, $result ) {
12 $this->total++;
13 $this->success += $result;
14
15 }
16
17 function reportPercentage( $success, $total ) { }
18 }
19
20 class MediaWikiParserTestSuite extends PHPUnit_Framework_TestSuite {
21 static private $count;
22 static public $parser;
23 static public $iter;
24
25 public static function addTables( &$tables ) {
26 $tables[] = 'user_properties';
27 $tables[] = 'filearchive';
28 $tables[] = 'logging';
29 $tables[] = 'updatelog';
30 $tables[] = 'iwlinks';
31 $tables[] = 'searchindex';
32 return true;
33 }
34
35 public static function suite() {
36 $suite = new PHPUnit_Framework_TestSuite();
37
38 global $wgHooks;
39 $wgHooks['ParserTestTables'][] = "MediaWikiParserTestSuite::addTables";
40
41 self::$iter = new TestFileIterator( PARSER_TESTS );
42
43 foreach ( self::$iter as $i => $test ) {
44 $suite->addTest( new ParserUnitTest( $i, $test['test'] ) );
45 self::$count++;
46 }
47 unset( $tests );
48
49 self::$parser = new PTShell;
50 self::$iter->setParser( self::$parser );
51 self::$parser->recorder->start();
52 self::$parser->setupDatabase();
53 self::$iter->rewind();
54 /* } */
55 /* function setUp() { */
56 global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, $wgDeferredUpdateList,
57 $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache,
58 $wgMessageCache, $wgUseDatabaseMessages, $wgMsgCacheExpiry, $parserMemc,
59 $wgNamespaceAliases, $wgNamespaceProtection, $wgLocalFileRepo,
60 $wgNamespacesWithSubpages, $wgThumbnailScriptPath, $wgScriptPath,
61 $wgArticlePath, $wgStyleSheetPath, $wgScript, $wgStylePath;
62
63 $wgScript = '/index.php';
64 $wgScriptPath = '/';
65 $wgArticlePath = '/wiki/$1';
66 $wgStyleSheetPath = '/skins';
67 $wgStylePath = '/skins';
68 $wgThumbnailScriptPath = false;
69 $wgLocalFileRepo = array(
70 'class' => 'LocalRepo',
71 'name' => 'local',
72 'directory' => 'test-repo',
73 'url' => 'http://example.com/images',
74 'hashLevels' => 2,
75 'transformVia404' => false,
76 );
77 $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface';
78 $wgNamespaceAliases['Image'] = NS_FILE;
79 $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK;
80
81
82 $wgEnableParserCache = false;
83 $wgDeferredUpdateList = array();
84 $wgMemc =& wfGetMainCache();
85 $messageMemc =& wfGetMessageCacheStorage();
86 $parserMemc =& wfGetParserCacheStorage();
87
88 $wgContLang = new StubContLang;
89 $wgUser = new StubUser;
90 $wgLang = new StubUserLang;
91 $wgOut = new StubObject( 'wgOut', 'OutputPage' );
92 $wgParser = new StubObject( 'wgParser', $wgParserConf['class'], array( $wgParserConf ) );
93 $wgRequest = new WebRequest;
94
95 $wgMessageCache = new StubObject( 'wgMessageCache', 'MessageCache',
96 array( $messageMemc, $wgUseDatabaseMessages,
97 $wgMsgCacheExpiry, wfWikiID() ) );
98 if ( $wgStyleDirectory === false ) $wgStyleDirectory = "$IP/skins";
99
100 return $suite;
101 }
102
103 public function tearDown() {
104 /* $this->teardownDatabase(); */
105 $this->recorder->report();
106 $this->recorder->end();
107 $this->teardownUploadDir( $this->uploadDir );
108 }
109
110 public function count() { return self::$count; }
111
112 public function toString() {
113 return "MediaWiki Parser Tests";
114 }
115
116
117 private $uploadDir;
118 private $keepUploads;
119 /**
120 * Remove the dummy uploads directory
121 */
122 private function teardownUploadDir( $dir ) {
123 if ( $this->keepUploads ) {
124 return;
125 }
126
127 // delete the files first, then the dirs.
128 self::deleteFiles(
129 array (
130 "$dir/3/3a/Foobar.jpg",
131 "$dir/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg",
132 "$dir/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg",
133 "$dir/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg",
134 "$dir/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg",
135
136 "$dir/0/09/Bad.jpg",
137 )
138 );
139
140 self::deleteDirs(
141 array (
142 "$dir/3/3a",
143 "$dir/3",
144 "$dir/thumb/6/65",
145 "$dir/thumb/6",
146 "$dir/thumb/3/3a/Foobar.jpg",
147 "$dir/thumb/3/3a",
148 "$dir/thumb/3",
149
150 "$dir/0/09/",
151 "$dir/0/",
152
153 "$dir/thumb",
154 "$dir",
155 )
156 );
157 }
158
159 /**
160 * Delete the specified files, if they exist.
161 * @param array $files full paths to files to delete.
162 */
163 private static function deleteFiles( $files ) {
164 foreach ( $files as $file ) {
165 if ( file_exists( $file ) ) {
166 unlink( $file );
167 }
168 }
169 }
170 /**
171 * Delete the specified directories, if they exist. Must be empty.
172 * @param array $dirs full paths to directories to delete.
173 */
174 private static function deleteDirs( $dirs ) {
175 foreach ( $dirs as $dir ) {
176 if ( is_dir( $dir ) ) {
177 rmdir( $dir );
178 }
179 }
180 }
181
182 /**
183 * Create a dummy uploads directory which will contain a couple
184 * of files in order to pass existence tests.
185 * @return string The directory
186 */
187 private function setupUploadDir() {
188 global $IP;
189 if ( $this->keepUploads ) {
190 $dir = wfTempDir() . '/mwParser-images';
191 if ( is_dir( $dir ) ) {
192 return $dir;
193 }
194 } else {
195 $dir = wfTempDir() . "/mwParser-" . mt_rand() . "-images";
196 }
197
198 wfDebug( "Creating upload directory $dir\n" );
199 if ( file_exists( $dir ) ) {
200 wfDebug( "Already exists!\n" );
201 return $dir;
202 }
203 wfMkdirParents( $dir . '/3/3a' );
204 copy( "$IP/skins/monobook/headbg.jpg", "$dir/3/3a/Foobar.jpg" );
205
206 wfMkdirParents( $dir . '/0/09' );
207 copy( "$IP/skins/monobook/headbg.jpg", "$dir/0/09/Bad.jpg" );
208 return $dir;
209 }
210 }
211
212 /**
213 * @group Stub
214 */
215 class ParserUnitTest extends PHPUnit_Framework_TestCase {
216 private $number = 0;
217 private $test = "";
218
219 public function testBogus() {
220 $this->markTestSkipped( "This is a stub" );
221 }
222
223 public function __construct( $number = null, $test = null ) {
224 $this->number = $number;
225 $this->test = $test;
226 }
227
228 function count() { return 1; }
229
230 public function run( PHPUnit_Framework_TestResult $result = NULL ) {
231 PHPUnit_Framework_Assert::resetCount();
232 if ( $result === NULL ) {
233 $result = new PHPUnit_Framework_TestResult;
234 }
235
236 $t = MediaWikiParserTestSuite::$iter->current();
237 $k = MediaWikiParserTestSuite::$iter->key();
238
239 if ( !MediaWikiParserTestSuite::$iter->valid() ) {
240 return;
241 }
242
243 // The only way this should happen is if the parserTest.txt
244 // file were modified while the script is running.
245 if ( $k != $this->number ) {
246 $i = $this->number;
247 wfDie( "I got confused!\n" );
248 }
249
250 $result->startTest( $this );
251 PHPUnit_Util_Timer::start();
252
253 $r = false;
254 try {
255 $r = MediaWikiParserTestSuite::$parser->runTest(
256 $t['test'], $t['input'], $t['result'], $t['options'], $t['config']
257 );
258 PHPUnit_Framework_Assert::assertTrue( true, $t['test'] );
259 }
260 catch ( PHPUnit_Framework_AssertionFailedError $e ) {
261 $result->addFailure( $this, $e, PHPUnit_Util_Timer::stop() );
262 }
263 catch ( Exception $e ) {
264 $result->addError( $this, $e, PHPUnit_Util_Timer::stop() );
265 }
266 PHPUnit_Framework_Assert::assertTrue( true, $t['test'] );
267
268 $result->endTest( $this, PHPUnit_Util_Timer::stop() );
269
270 MediaWikiParserTestSuite::$parser->recorder->record( $t['test'], $r );
271 MediaWikiParserTestSuite::$iter->next();
272 $this->addToAssertionCount( PHPUnit_Framework_Assert::getCount() );
273
274 return $result;
275 }
276
277 }
278
279 class PTShell extends ParserTest {
280 function showTesting( $desc ) {
281 }
282
283 function showRunFile( $path ) {
284 }
285
286 function showSuccess( $desc ) {
287 PHPUnit_Framework_Assert::assertTrue( true, $desc );
288 return true;
289 }
290
291 function showFailure( $desc, $expected, $got ) {
292 PHPUnit_Framework_Assert::assertEquals( $expected, $got, $desc );
293 }
294
295 }
296
297