MediaWiki  REL1_24
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(
00039             ContentHandler::makeContent( $text, $page->getTitle() ),
00040             $summary
00041         );
00042 
00043         if ( $status->isGood() ) {
00044             $value = $status->getValue();
00045             $revision = $value['revision'];
00046             $revision_id = $revision->getId();
00047             $text_id = $revision->getTextId();
00048 
00049             if ( ( $revision_id > 0 ) && ( $text_id > 0 ) ) {
00050                 return array( $revision_id, $text_id );
00051             }
00052         }
00053 
00054         throw new MWException( "Could not determine revision id (" . $status->getWikiText() . ")" );
00055     }
00056 
00063     protected function gunzip( $fname ) {
00064         $gzipped_contents = file_get_contents( $fname );
00065         if ( $gzipped_contents === false ) {
00066             $this->fail( "Could not get contents of $fname" );
00067         }
00068 
00069         $contents = gzdecode( $gzipped_contents );
00070 
00071         $this->assertEquals(
00072             strlen( $contents ),
00073             file_put_contents( $fname, $contents ),
00074             '# bytes written'
00075         );
00076     }
00077 
00083     protected function setUp() {
00084         parent::setUp();
00085 
00086         // Check if any Exception is stored for rethrowing from addDBData
00087         // @see self::exceptionFromAddDBData
00088         if ( $this->exceptionFromAddDBData !== null ) {
00089             throw $this->exceptionFromAddDBData;
00090         }
00091 
00092         $this->setMwGlobals( 'wgUser', new User() );
00093     }
00094 
00098     function expectETAOutput() {
00099         // Newer PHPUnits require assertion about the output using PHPUnit's own
00100         // expectOutput[...] functions. However, the PHPUnit shipped prediactes
00101         // do not allow to check /each/ line of the output using /readable/ REs.
00102         // So we ...
00103         //
00104         // 1. ... add a dummy output checking to make PHPUnit not complain
00105         //    about unchecked test output
00106         $this->expectOutputRegex( '//' );
00107 
00108         // 2. Do the real output checking on our own.
00109         $lines = explode( "\n", $this->getActualOutput() );
00110         $this->assertGreaterThan( 1, count( $lines ), "Minimal lines of produced output" );
00111         $this->assertEquals( '', array_pop( $lines ), "Output ends in LF" );
00112         $timestamp_re = "[0-9]{4}-[01][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-6][0-9]";
00113         foreach ( $lines as $line ) {
00114             $this->assertRegExp(
00115                 "/$timestamp_re: .* \(ID [0-9]+\) [0-9]* pages .*, [0-9]* revs .*, ETA/",
00116                 $line
00117             );
00118         }
00119     }
00120 
00129     protected function skipToNodeEnd( $name ) {
00130         while ( $this->xml->read() ) {
00131             if ( $this->xml->nodeType == XMLReader::END_ELEMENT &&
00132                 $this->xml->name == $name
00133             ) {
00134                 return true;
00135             }
00136         }
00137 
00138         return false;
00139     }
00140 
00151     protected function skipPastNodeEnd( $name ) {
00152         $this->assertTrue( $this->skipToNodeEnd( $name ),
00153             "Skipping to end of $name" );
00154         while ( $this->xml->read() ) {
00155             if ( $this->xml->nodeType == XMLReader::ELEMENT ) {
00156                 return true;
00157             }
00158         }
00159 
00160         return false;
00161     }
00162 
00170     protected function assertDumpStart( $fname, $skip_siteinfo = true ) {
00171         $this->xml = new XMLReader();
00172         $this->assertTrue( $this->xml->open( $fname ),
00173             "Opening temporary file $fname via XMLReader failed" );
00174         if ( $skip_siteinfo ) {
00175             $this->assertTrue( $this->skipPastNodeEnd( "siteinfo" ),
00176                 "Skipping past end of siteinfo" );
00177         }
00178     }
00179 
00187     protected function assertDumpEnd( $name = "mediawiki" ) {
00188         $this->assertNodeEnd( $name, false );
00189         if ( $this->xml->read() ) {
00190             $this->skipWhitespace();
00191         }
00192         $this->assertEquals( $this->xml->nodeType, XMLReader::NONE,
00193             "No proper entity left to parse" );
00194         $this->xml->close();
00195     }
00196 
00200     protected function skipWhitespace() {
00201         $cont = true;
00202         while ( $cont && ( ( $this->xml->nodeType == XMLReader::WHITESPACE )
00203             || ( $this->xml->nodeType == XMLReader::SIGNIFICANT_WHITESPACE ) ) ) {
00204             $cont = $this->xml->read();
00205         }
00206     }
00207 
00216     protected function assertNodeStart( $name, $skip = true ) {
00217         $this->assertEquals( $name, $this->xml->name, "Node name" );
00218         $this->assertEquals( XMLReader::ELEMENT, $this->xml->nodeType, "Node type" );
00219         if ( $skip ) {
00220             $this->assertTrue( $this->xml->read(), "Skipping past start tag" );
00221         }
00222     }
00223 
00232     protected function assertNodeEnd( $name, $skip = true ) {
00233         $this->assertEquals( $name, $this->xml->name, "Node name" );
00234         $this->assertEquals( XMLReader::END_ELEMENT, $this->xml->nodeType, "Node type" );
00235         if ( $skip ) {
00236             $this->assertTrue( $this->xml->read(), "Skipping past end tag" );
00237         }
00238     }
00239 
00251     protected function assertTextNode( $name, $text, $skip_ws = true ) {
00252         $this->assertNodeStart( $name );
00253 
00254         if ( $text !== false ) {
00255             $this->assertEquals( $text, $this->xml->value, "Text of node " . $name );
00256         }
00257         $this->assertTrue( $this->xml->read(), "Skipping past processed text of " . $name );
00258         $this->assertNodeEnd( $name );
00259 
00260         if ( $skip_ws ) {
00261             $this->skipWhitespace();
00262         }
00263     }
00264 
00277     protected function assertPageStart( $id, $ns, $name ) {
00278 
00279         $this->assertNodeStart( "page" );
00280         $this->skipWhitespace();
00281 
00282         $this->assertTextNode( "title", $name );
00283         $this->assertTextNode( "ns", $ns );
00284         $this->assertTextNode( "id", $id );
00285     }
00286 
00291     protected function assertPageEnd() {
00292         $this->assertNodeEnd( "page" );
00293         $this->skipWhitespace();
00294     }
00295 
00311     protected function assertRevision( $id, $summary, $text_id, $text_bytes,
00312         $text_sha1, $text = false, $parentid = false,
00313         $model = CONTENT_MODEL_WIKITEXT, $format = CONTENT_FORMAT_WIKITEXT
00314     ) {
00315         $this->assertNodeStart( "revision" );
00316         $this->skipWhitespace();
00317 
00318         $this->assertTextNode( "id", $id );
00319         if ( $parentid !== false ) {
00320             $this->assertTextNode( "parentid", $parentid );
00321         }
00322         $this->assertTextNode( "timestamp", false );
00323 
00324         $this->assertNodeStart( "contributor" );
00325         $this->skipWhitespace();
00326         $this->assertTextNode( "ip", false );
00327         $this->assertNodeEnd( "contributor" );
00328         $this->skipWhitespace();
00329 
00330         $this->assertTextNode( "comment", $summary );
00331         $this->skipWhitespace();
00332 
00333         if ( $this->xml->name == "text" ) {
00334             // note: <text> tag may occur here or at the very end.
00335             $text_found = true;
00336             $this->assertText( $id, $text_id, $text_bytes, $text );
00337         } else {
00338             $text_found = false;
00339         }
00340 
00341         $this->assertTextNode( "sha1", $text_sha1 );
00342 
00343         $this->assertTextNode( "model", $model );
00344         $this->skipWhitespace();
00345 
00346         $this->assertTextNode( "format", $format );
00347         $this->skipWhitespace();
00348 
00349         if ( !$text_found ) {
00350             $this->assertText( $id, $text_id, $text_bytes, $text );
00351         }
00352 
00353         $this->assertNodeEnd( "revision" );
00354         $this->skipWhitespace();
00355     }
00356 
00357     protected function assertText( $id, $text_id, $text_bytes, $text ) {
00358         $this->assertNodeStart( "text", false );
00359         if ( $text_bytes !== false ) {
00360             $this->assertEquals( $this->xml->getAttribute( "bytes" ), $text_bytes,
00361                 "Attribute 'bytes' of revision " . $id );
00362         }
00363 
00364         if ( $text === false ) {
00365             // Testing for a stub
00366             $this->assertEquals( $this->xml->getAttribute( "id" ), $text_id,
00367                 "Text id of revision " . $id );
00368             $this->assertFalse( $this->xml->hasValue, "Revision has text" );
00369             $this->assertTrue( $this->xml->read(), "Skipping text start tag" );
00370             if ( ( $this->xml->nodeType == XMLReader::END_ELEMENT )
00371                 && ( $this->xml->name == "text" )
00372             ) {
00373 
00374                 $this->xml->read();
00375             }
00376             $this->skipWhitespace();
00377         } else {
00378             // Testing for a real dump
00379             $this->assertTrue( $this->xml->read(), "Skipping text start tag" );
00380             $this->assertEquals( $text, $this->xml->value, "Text of revision " . $id );
00381             $this->assertTrue( $this->xml->read(), "Skipping past text" );
00382             $this->assertNodeEnd( "text" );
00383             $this->skipWhitespace();
00384         }
00385     }
00386 }