MediaWiki  REL1_22
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 
00051 
00058     protected function gunzip( $fname ) {
00059         $gzipped_contents = file_get_contents( $fname );
00060         if ( $gzipped_contents === false ) {
00061             $this->fail( "Could not get contents of $fname" );
00062         }
00063 
00064         $contents = gzdecode( $gzipped_contents );
00065 
00066         $this->assertEquals(
00067             strlen( $contents ),
00068             file_put_contents( $fname, $contents ),
00069             '# bytes written'
00070         );
00071     }
00072 
00078     protected function setUp() {
00079         parent::setUp();
00080 
00081         // Check if any Exception is stored for rethrowing from addDBData
00082         // @see self::exceptionFromAddDBData
00083         if ( $this->exceptionFromAddDBData !== null ) {
00084             throw $this->exceptionFromAddDBData;
00085         }
00086 
00087         $this->setMwGlobals( 'wgUser', new User() );
00088     }
00089 
00093     function expectETAOutput() {
00094         // Newer PHPUnits require assertion about the output using PHPUnit's own
00095         // expectOutput[...] functions. However, the PHPUnit shipped prediactes
00096         // do not allow to check /each/ line of the output using /readable/ REs.
00097         // So we ...
00098         //
00099         // 1. ... add a dummy output checking to make PHPUnit not complain
00100         //    about unchecked test output
00101         $this->expectOutputRegex( '//' );
00102 
00103         // 2. Do the real output checking on our own.
00104         $lines = explode( "\n", $this->getActualOutput() );
00105         $this->assertGreaterThan( 1, count( $lines ), "Minimal lines of produced output" );
00106         $this->assertEquals( '', array_pop( $lines ), "Output ends in LF" );
00107         $timestamp_re = "[0-9]{4}-[01][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-6][0-9]";
00108         foreach ( $lines as $line ) {
00109             $this->assertRegExp( "/$timestamp_re: .* \(ID [0-9]+\) [0-9]* pages .*, [0-9]* revs .*, ETA/", $line );
00110         }
00111     }
00112 
00113 
00122     protected function skipToNodeEnd( $name ) {
00123         while ( $this->xml->read() ) {
00124             if ( $this->xml->nodeType == XMLReader::END_ELEMENT &&
00125                 $this->xml->name == $name
00126             ) {
00127                 return true;
00128             }
00129         }
00130 
00131         return false;
00132     }
00133 
00144     protected function skipPastNodeEnd( $name ) {
00145         $this->assertTrue( $this->skipToNodeEnd( $name ),
00146             "Skipping to end of $name" );
00147         while ( $this->xml->read() ) {
00148             if ( $this->xml->nodeType == XMLReader::ELEMENT ) {
00149                 return true;
00150             }
00151         }
00152 
00153         return false;
00154     }
00155 
00163     protected function assertDumpStart( $fname, $skip_siteinfo = true ) {
00164         $this->xml = new XMLReader();
00165         $this->assertTrue( $this->xml->open( $fname ),
00166             "Opening temporary file $fname via XMLReader failed" );
00167         if ( $skip_siteinfo ) {
00168             $this->assertTrue( $this->skipPastNodeEnd( "siteinfo" ),
00169                 "Skipping past end of siteinfo" );
00170         }
00171     }
00172 
00180     protected function assertDumpEnd( $name = "mediawiki" ) {
00181         $this->assertNodeEnd( $name, false );
00182         if ( $this->xml->read() ) {
00183             $this->skipWhitespace();
00184         }
00185         $this->assertEquals( $this->xml->nodeType, XMLReader::NONE,
00186             "No proper entity left to parse" );
00187         $this->xml->close();
00188     }
00189 
00193     protected function skipWhitespace() {
00194         $cont = true;
00195         while ( $cont && ( ( $this->xml->nodeType == XMLReader::WHITESPACE )
00196             || ( $this->xml->nodeType == XMLReader::SIGNIFICANT_WHITESPACE ) ) ) {
00197             $cont = $this->xml->read();
00198         }
00199     }
00200 
00209     protected function assertNodeStart( $name, $skip = true ) {
00210         $this->assertEquals( $name, $this->xml->name, "Node name" );
00211         $this->assertEquals( XMLReader::ELEMENT, $this->xml->nodeType, "Node type" );
00212         if ( $skip ) {
00213             $this->assertTrue( $this->xml->read(), "Skipping past start tag" );
00214         }
00215     }
00216 
00225     protected function assertNodeEnd( $name, $skip = true ) {
00226         $this->assertEquals( $name, $this->xml->name, "Node name" );
00227         $this->assertEquals( XMLReader::END_ELEMENT, $this->xml->nodeType, "Node type" );
00228         if ( $skip ) {
00229             $this->assertTrue( $this->xml->read(), "Skipping past end tag" );
00230         }
00231     }
00232 
00233 
00245     protected function assertTextNode( $name, $text, $skip_ws = true ) {
00246         $this->assertNodeStart( $name );
00247 
00248         if ( $text !== false ) {
00249             $this->assertEquals( $text, $this->xml->value, "Text of node " . $name );
00250         }
00251         $this->assertTrue( $this->xml->read(), "Skipping past processed text of " . $name );
00252         $this->assertNodeEnd( $name );
00253 
00254         if ( $skip_ws ) {
00255             $this->skipWhitespace();
00256         }
00257     }
00258 
00271     protected function assertPageStart( $id, $ns, $name ) {
00272 
00273         $this->assertNodeStart( "page" );
00274         $this->skipWhitespace();
00275 
00276         $this->assertTextNode( "title", $name );
00277         $this->assertTextNode( "ns", $ns );
00278         $this->assertTextNode( "id", $id );
00279     }
00280 
00285     protected function assertPageEnd() {
00286         $this->assertNodeEnd( "page" );
00287         $this->skipWhitespace();
00288     }
00289 
00305     protected function assertRevision( $id, $summary, $text_id, $text_bytes, $text_sha1, $text = false, $parentid = false,
00306         $model = CONTENT_MODEL_WIKITEXT, $format = CONTENT_FORMAT_WIKITEXT
00307     ) {
00308         $this->assertNodeStart( "revision" );
00309         $this->skipWhitespace();
00310 
00311         $this->assertTextNode( "id", $id );
00312         if ( $parentid !== false ) {
00313             $this->assertTextNode( "parentid", $parentid );
00314         }
00315         $this->assertTextNode( "timestamp", false );
00316 
00317         $this->assertNodeStart( "contributor" );
00318         $this->skipWhitespace();
00319         $this->assertTextNode( "ip", false );
00320         $this->assertNodeEnd( "contributor" );
00321         $this->skipWhitespace();
00322 
00323         $this->assertTextNode( "comment", $summary );
00324         $this->skipWhitespace();
00325 
00326         if ( $this->xml->name == "text" ) {
00327             // note: <text> tag may occur here or at the very end.
00328             $text_found = true;
00329             $this->assertText( $id, $text_id, $text_bytes, $text );
00330         } else {
00331             $text_found = false;
00332         }
00333 
00334         $this->assertTextNode( "sha1", $text_sha1 );
00335 
00336         $this->assertTextNode( "model", $model );
00337         $this->skipWhitespace();
00338 
00339         $this->assertTextNode( "format", $format );
00340         $this->skipWhitespace();
00341 
00342         if ( !$text_found ) {
00343             $this->assertText( $id, $text_id, $text_bytes, $text );
00344         }
00345 
00346         $this->assertNodeEnd( "revision" );
00347         $this->skipWhitespace();
00348     }
00349 
00350     protected function assertText( $id, $text_id, $text_bytes, $text ) {
00351         $this->assertNodeStart( "text", false );
00352         if ( $text_bytes !== false ) {
00353             $this->assertEquals( $this->xml->getAttribute( "bytes" ), $text_bytes,
00354                 "Attribute 'bytes' of revision " . $id );
00355         }
00356 
00357         if ( $text === false ) {
00358             // Testing for a stub
00359             $this->assertEquals( $this->xml->getAttribute( "id" ), $text_id,
00360                 "Text id of revision " . $id );
00361             $this->assertFalse( $this->xml->hasValue, "Revision has text" );
00362             $this->assertTrue( $this->xml->read(), "Skipping text start tag" );
00363             if ( ( $this->xml->nodeType == XMLReader::END_ELEMENT )
00364                 && ( $this->xml->name == "text" )
00365             ) {
00366 
00367                 $this->xml->read();
00368             }
00369             $this->skipWhitespace();
00370         } else {
00371             // Testing for a real dump
00372             $this->assertTrue( $this->xml->read(), "Skipping text start tag" );
00373             $this->assertEquals( $text, $this->xml->value, "Text of revision " . $id );
00374             $this->assertTrue( $this->xml->read(), "Skipping past text" );
00375             $this->assertNodeEnd( "text" );
00376             $this->skipWhitespace();
00377         }
00378     }
00379 }