MediaWiki  REL1_23
DumpTestCase.php
Go to the documentation of this file.
00001 <?php
00002 
00006 abstract class DumpTestCase extends MediaWikiLangTestCase {
00007 
00019     protected $exceptionFromAddDBData = null;
00020 
00026     protected $xml = null;
00027 
00037     protected function addRevision( Page $page, $text, $summary ) {
00038         $status = $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), $summary );
00039         if ( $status->isGood() ) {
00040             $value = $status->getValue();
00041             $revision = $value['revision'];
00042             $revision_id = $revision->getId();
00043             $text_id = $revision->getTextId();
00044             if ( ( $revision_id > 0 ) && ( $text_id > 0 ) ) {
00045                 return array( $revision_id, $text_id );
00046             }
00047         }
00048         throw new MWException( "Could not determine revision id (" . $status->getWikiText() . ")" );
00049     }
00050 
00057     protected function gunzip( $fname ) {
00058         $gzipped_contents = file_get_contents( $fname );
00059         if ( $gzipped_contents === false ) {
00060             $this->fail( "Could not get contents of $fname" );
00061         }
00062 
00063         $contents = gzdecode( $gzipped_contents );
00064 
00065         $this->assertEquals(
00066             strlen( $contents ),
00067             file_put_contents( $fname, $contents ),
00068             '# bytes written'
00069         );
00070     }
00071 
00077     protected function setUp() {
00078         parent::setUp();
00079 
00080         // Check if any Exception is stored for rethrowing from addDBData
00081         // @see self::exceptionFromAddDBData
00082         if ( $this->exceptionFromAddDBData !== null ) {
00083             throw $this->exceptionFromAddDBData;
00084         }
00085 
00086         $this->setMwGlobals( 'wgUser', new User() );
00087     }
00088 
00092     function expectETAOutput() {
00093         // Newer PHPUnits require assertion about the output using PHPUnit's own
00094         // expectOutput[...] functions. However, the PHPUnit shipped prediactes
00095         // do not allow to check /each/ line of the output using /readable/ REs.
00096         // So we ...
00097         //
00098         // 1. ... add a dummy output checking to make PHPUnit not complain
00099         //    about unchecked test output
00100         $this->expectOutputRegex( '//' );
00101 
00102         // 2. Do the real output checking on our own.
00103         $lines = explode( "\n", $this->getActualOutput() );
00104         $this->assertGreaterThan( 1, count( $lines ), "Minimal lines of produced output" );
00105         $this->assertEquals( '', array_pop( $lines ), "Output ends in LF" );
00106         $timestamp_re = "[0-9]{4}-[01][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-6][0-9]";
00107         foreach ( $lines as $line ) {
00108             $this->assertRegExp( "/$timestamp_re: .* \(ID [0-9]+\) [0-9]* pages .*, [0-9]* revs .*, ETA/", $line );
00109         }
00110     }
00111 
00120     protected function skipToNodeEnd( $name ) {
00121         while ( $this->xml->read() ) {
00122             if ( $this->xml->nodeType == XMLReader::END_ELEMENT &&
00123                 $this->xml->name == $name
00124             ) {
00125                 return true;
00126             }
00127         }
00128 
00129         return false;
00130     }
00131 
00142     protected function skipPastNodeEnd( $name ) {
00143         $this->assertTrue( $this->skipToNodeEnd( $name ),
00144             "Skipping to end of $name" );
00145         while ( $this->xml->read() ) {
00146             if ( $this->xml->nodeType == XMLReader::ELEMENT ) {
00147                 return true;
00148             }
00149         }
00150 
00151         return false;
00152     }
00153 
00161     protected function assertDumpStart( $fname, $skip_siteinfo = true ) {
00162         $this->xml = new XMLReader();
00163         $this->assertTrue( $this->xml->open( $fname ),
00164             "Opening temporary file $fname via XMLReader failed" );
00165         if ( $skip_siteinfo ) {
00166             $this->assertTrue( $this->skipPastNodeEnd( "siteinfo" ),
00167                 "Skipping past end of siteinfo" );
00168         }
00169     }
00170 
00178     protected function assertDumpEnd( $name = "mediawiki" ) {
00179         $this->assertNodeEnd( $name, false );
00180         if ( $this->xml->read() ) {
00181             $this->skipWhitespace();
00182         }
00183         $this->assertEquals( $this->xml->nodeType, XMLReader::NONE,
00184             "No proper entity left to parse" );
00185         $this->xml->close();
00186     }
00187 
00191     protected function skipWhitespace() {
00192         $cont = true;
00193         while ( $cont && ( ( $this->xml->nodeType == XMLReader::WHITESPACE )
00194             || ( $this->xml->nodeType == XMLReader::SIGNIFICANT_WHITESPACE ) ) ) {
00195             $cont = $this->xml->read();
00196         }
00197     }
00198 
00207     protected function assertNodeStart( $name, $skip = true ) {
00208         $this->assertEquals( $name, $this->xml->name, "Node name" );
00209         $this->assertEquals( XMLReader::ELEMENT, $this->xml->nodeType, "Node type" );
00210         if ( $skip ) {
00211             $this->assertTrue( $this->xml->read(), "Skipping past start tag" );
00212         }
00213     }
00214 
00223     protected function assertNodeEnd( $name, $skip = true ) {
00224         $this->assertEquals( $name, $this->xml->name, "Node name" );
00225         $this->assertEquals( XMLReader::END_ELEMENT, $this->xml->nodeType, "Node type" );
00226         if ( $skip ) {
00227             $this->assertTrue( $this->xml->read(), "Skipping past end tag" );
00228         }
00229     }
00230 
00242     protected function assertTextNode( $name, $text, $skip_ws = true ) {
00243         $this->assertNodeStart( $name );
00244 
00245         if ( $text !== false ) {
00246             $this->assertEquals( $text, $this->xml->value, "Text of node " . $name );
00247         }
00248         $this->assertTrue( $this->xml->read(), "Skipping past processed text of " . $name );
00249         $this->assertNodeEnd( $name );
00250 
00251         if ( $skip_ws ) {
00252             $this->skipWhitespace();
00253         }
00254     }
00255 
00268     protected function assertPageStart( $id, $ns, $name ) {
00269 
00270         $this->assertNodeStart( "page" );
00271         $this->skipWhitespace();
00272 
00273         $this->assertTextNode( "title", $name );
00274         $this->assertTextNode( "ns", $ns );
00275         $this->assertTextNode( "id", $id );
00276     }
00277 
00282     protected function assertPageEnd() {
00283         $this->assertNodeEnd( "page" );
00284         $this->skipWhitespace();
00285     }
00286 
00302     protected function assertRevision( $id, $summary, $text_id, $text_bytes, $text_sha1, $text = false, $parentid = false,
00303         $model = CONTENT_MODEL_WIKITEXT, $format = CONTENT_FORMAT_WIKITEXT
00304     ) {
00305         $this->assertNodeStart( "revision" );
00306         $this->skipWhitespace();
00307 
00308         $this->assertTextNode( "id", $id );
00309         if ( $parentid !== false ) {
00310             $this->assertTextNode( "parentid", $parentid );
00311         }
00312         $this->assertTextNode( "timestamp", false );
00313 
00314         $this->assertNodeStart( "contributor" );
00315         $this->skipWhitespace();
00316         $this->assertTextNode( "ip", false );
00317         $this->assertNodeEnd( "contributor" );
00318         $this->skipWhitespace();
00319 
00320         $this->assertTextNode( "comment", $summary );
00321         $this->skipWhitespace();
00322 
00323         if ( $this->xml->name == "text" ) {
00324             // note: <text> tag may occur here or at the very end.
00325             $text_found = true;
00326             $this->assertText( $id, $text_id, $text_bytes, $text );
00327         } else {
00328             $text_found = false;
00329         }
00330 
00331         $this->assertTextNode( "sha1", $text_sha1 );
00332 
00333         $this->assertTextNode( "model", $model );
00334         $this->skipWhitespace();
00335 
00336         $this->assertTextNode( "format", $format );
00337         $this->skipWhitespace();
00338 
00339         if ( !$text_found ) {
00340             $this->assertText( $id, $text_id, $text_bytes, $text );
00341         }
00342 
00343         $this->assertNodeEnd( "revision" );
00344         $this->skipWhitespace();
00345     }
00346 
00347     protected function assertText( $id, $text_id, $text_bytes, $text ) {
00348         $this->assertNodeStart( "text", false );
00349         if ( $text_bytes !== false ) {
00350             $this->assertEquals( $this->xml->getAttribute( "bytes" ), $text_bytes,
00351                 "Attribute 'bytes' of revision " . $id );
00352         }
00353 
00354         if ( $text === false ) {
00355             // Testing for a stub
00356             $this->assertEquals( $this->xml->getAttribute( "id" ), $text_id,
00357                 "Text id of revision " . $id );
00358             $this->assertFalse( $this->xml->hasValue, "Revision has text" );
00359             $this->assertTrue( $this->xml->read(), "Skipping text start tag" );
00360             if ( ( $this->xml->nodeType == XMLReader::END_ELEMENT )
00361                 && ( $this->xml->name == "text" )
00362             ) {
00363 
00364                 $this->xml->read();
00365             }
00366             $this->skipWhitespace();
00367         } else {
00368             // Testing for a real dump
00369             $this->assertTrue( $this->xml->read(), "Skipping text start tag" );
00370             $this->assertEquals( $text, $this->xml->value, "Text of revision " . $id );
00371             $this->assertTrue( $this->xml->read(), "Skipping past text" );
00372             $this->assertNodeEnd( "text" );
00373             $this->skipWhitespace();
00374         }
00375     }
00376 }