MediaWiki
REL1_24
|
00001 <?php 00002 00008 class TextContentTest extends MediaWikiLangTestCase { 00009 protected $context; 00010 protected $savedContentGetParserOutput; 00011 00012 protected function setUp() { 00013 global $wgHooks; 00014 00015 parent::setUp(); 00016 00017 // Anon user 00018 $user = new User(); 00019 $user->setName( '127.0.0.1' ); 00020 00021 $this->context = new RequestContext( new FauxRequest() ); 00022 $this->context->setTitle( Title::newFromText( 'Test' ) ); 00023 $this->context->setUser( $user ); 00024 00025 $this->setMwGlobals( array( 00026 'wgUser' => $user, 00027 'wgTextModelsToParse' => array( 00028 CONTENT_MODEL_WIKITEXT, 00029 CONTENT_MODEL_CSS, 00030 CONTENT_MODEL_JAVASCRIPT, 00031 ), 00032 'wgUseTidy' => false, 00033 'wgAlwaysUseTidy' => false, 00034 'wgCapitalLinks' => true, 00035 ) ); 00036 00037 // bypass hooks that force custom rendering 00038 if ( isset( $wgHooks['ContentGetParserOutput'] ) ) { 00039 $this->savedContentGetParserOutput = $wgHooks['ContentGetParserOutput']; 00040 unset( $wgHooks['ContentGetParserOutput'] ); 00041 } 00042 } 00043 00044 public function teardown() { 00045 global $wgHooks; 00046 00047 // restore hooks that force custom rendering 00048 if ( $this->savedContentGetParserOutput !== null ) { 00049 $wgHooks['ContentGetParserOutput'] = $this->savedContentGetParserOutput; 00050 } 00051 00052 parent::teardown(); 00053 } 00054 00055 public function newContent( $text ) { 00056 return new TextContent( $text ); 00057 } 00058 00059 public static function dataGetParserOutput() { 00060 return array( 00061 array( 00062 'TextContentTest_testGetParserOutput', 00063 CONTENT_MODEL_TEXT, 00064 "hello ''world'' & [[stuff]]\n", "hello ''world'' & [[stuff]]", 00065 array( 00066 'Links' => array() 00067 ) 00068 ), 00069 // TODO: more...? 00070 ); 00071 } 00072 00077 public function testGetParserOutput( $title, $model, $text, $expectedHtml, 00078 $expectedFields = null 00079 ) { 00080 $title = Title::newFromText( $title ); 00081 $content = ContentHandler::makeContent( $text, $title, $model ); 00082 00083 $po = $content->getParserOutput( $title ); 00084 00085 $html = $po->getText(); 00086 $html = preg_replace( '#<!--.*?-->#sm', '', $html ); // strip comments 00087 00088 $this->assertEquals( $expectedHtml, trim( $html ) ); 00089 00090 if ( $expectedFields ) { 00091 foreach ( $expectedFields as $field => $exp ) { 00092 $f = 'get' . ucfirst( $field ); 00093 $v = call_user_func( array( $po, $f ) ); 00094 00095 if ( is_array( $exp ) ) { 00096 $this->assertArrayEquals( $exp, $v ); 00097 } else { 00098 $this->assertEquals( $exp, $v ); 00099 } 00100 } 00101 } 00102 00103 // TODO: assert more properties 00104 } 00105 00106 public static function dataPreSaveTransform() { 00107 return array( 00108 array( 00109 #0: no signature resolution 00110 'hello this is ~~~', 00111 'hello this is ~~~', 00112 ), 00113 array( 00114 #1: rtrim 00115 " Foo \n ", 00116 ' Foo', 00117 ), 00118 ); 00119 } 00120 00125 public function testPreSaveTransform( $text, $expected ) { 00126 global $wgContLang; 00127 00128 $options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang ); 00129 00130 $content = $this->newContent( $text ); 00131 $content = $content->preSaveTransform( 00132 $this->context->getTitle(), 00133 $this->context->getUser(), 00134 $options 00135 ); 00136 00137 $this->assertEquals( $expected, $content->getNativeData() ); 00138 } 00139 00140 public static function dataPreloadTransform() { 00141 return array( 00142 array( 00143 'hello this is ~~~', 00144 'hello this is ~~~', 00145 ), 00146 ); 00147 } 00148 00153 public function testPreloadTransform( $text, $expected ) { 00154 global $wgContLang; 00155 $options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang ); 00156 00157 $content = $this->newContent( $text ); 00158 $content = $content->preloadTransform( $this->context->getTitle(), $options ); 00159 00160 $this->assertEquals( $expected, $content->getNativeData() ); 00161 } 00162 00163 public static function dataGetRedirectTarget() { 00164 return array( 00165 array( '#REDIRECT [[Test]]', 00166 null, 00167 ), 00168 ); 00169 } 00170 00175 public function testGetRedirectTarget( $text, $expected ) { 00176 $content = $this->newContent( $text ); 00177 $t = $content->getRedirectTarget(); 00178 00179 if ( is_null( $expected ) ) { 00180 $this->assertNull( $t, "text should not have generated a redirect target: $text" ); 00181 } else { 00182 $this->assertEquals( $expected, $t->getPrefixedText() ); 00183 } 00184 } 00185 00190 public function testIsRedirect( $text, $expected ) { 00191 $content = $this->newContent( $text ); 00192 00193 $this->assertEquals( !is_null( $expected ), $content->isRedirect() ); 00194 } 00195 00199 /* 00200 public function getRedirectChain() { 00201 $text = $this->getNativeData(); 00202 return Title::newFromRedirectArray( $text ); 00203 } 00204 */ 00205 00209 /* 00210 public function getUltimateRedirectTarget() { 00211 $text = $this->getNativeData(); 00212 return Title::newFromRedirectRecurse( $text ); 00213 } 00214 */ 00215 00216 public static function dataIsCountable() { 00217 return array( 00218 array( '', 00219 null, 00220 'any', 00221 true 00222 ), 00223 array( 'Foo', 00224 null, 00225 'any', 00226 true 00227 ), 00228 array( 'Foo', 00229 null, 00230 'comma', 00231 false 00232 ), 00233 array( 'Foo, bar', 00234 null, 00235 'comma', 00236 false 00237 ), 00238 ); 00239 } 00240 00246 public function testIsCountable( $text, $hasLinks, $mode, $expected ) { 00247 $this->setMwGlobals( 'wgArticleCountMethod', $mode ); 00248 00249 $content = $this->newContent( $text ); 00250 00251 $v = $content->isCountable( $hasLinks, $this->context->getTitle() ); 00252 00253 $this->assertEquals( 00254 $expected, 00255 $v, 00256 'isCountable() returned unexpected value ' . var_export( $v, true ) 00257 . ' instead of ' . var_export( $expected, true ) 00258 . " in mode `$mode` for text \"$text\"" 00259 ); 00260 } 00261 00262 public static function dataGetTextForSummary() { 00263 return array( 00264 array( "hello\nworld.", 00265 16, 00266 'hello world.', 00267 ), 00268 array( 'hello world.', 00269 8, 00270 'hello...', 00271 ), 00272 array( '[[hello world]].', 00273 8, 00274 '[[hel...', 00275 ), 00276 ); 00277 } 00278 00283 public function testGetTextForSummary( $text, $maxlength, $expected ) { 00284 $content = $this->newContent( $text ); 00285 00286 $this->assertEquals( $expected, $content->getTextForSummary( $maxlength ) ); 00287 } 00288 00292 public function testGetTextForSearchIndex() { 00293 $content = $this->newContent( 'hello world.' ); 00294 00295 $this->assertEquals( 'hello world.', $content->getTextForSearchIndex() ); 00296 } 00297 00301 public function testCopy() { 00302 $content = $this->newContent( 'hello world.' ); 00303 $copy = $content->copy(); 00304 00305 $this->assertTrue( $content->equals( $copy ), 'copy must be equal to original' ); 00306 $this->assertEquals( 'hello world.', $copy->getNativeData() ); 00307 } 00308 00312 public function testGetSize() { 00313 $content = $this->newContent( 'hello world.' ); 00314 00315 $this->assertEquals( 12, $content->getSize() ); 00316 } 00317 00321 public function testGetNativeData() { 00322 $content = $this->newContent( 'hello world.' ); 00323 00324 $this->assertEquals( 'hello world.', $content->getNativeData() ); 00325 } 00326 00330 public function testGetWikitextForTransclusion() { 00331 $content = $this->newContent( 'hello world.' ); 00332 00333 $this->assertEquals( 'hello world.', $content->getWikitextForTransclusion() ); 00334 } 00335 00339 public function testGetModel() { 00340 $content = $this->newContent( "hello world." ); 00341 00342 $this->assertEquals( CONTENT_MODEL_TEXT, $content->getModel() ); 00343 } 00344 00348 public function testGetContentHandler() { 00349 $content = $this->newContent( "hello world." ); 00350 00351 $this->assertEquals( CONTENT_MODEL_TEXT, $content->getContentHandler()->getModelID() ); 00352 } 00353 00354 public static function dataIsEmpty() { 00355 return array( 00356 array( '', true ), 00357 array( ' ', false ), 00358 array( '0', false ), 00359 array( 'hallo welt.', false ), 00360 ); 00361 } 00362 00367 public function testIsEmpty( $text, $empty ) { 00368 $content = $this->newContent( $text ); 00369 00370 $this->assertEquals( $empty, $content->isEmpty() ); 00371 } 00372 00373 public static function dataEquals() { 00374 return array( 00375 array( new TextContent( "hallo" ), null, false ), 00376 array( new TextContent( "hallo" ), new TextContent( "hallo" ), true ), 00377 array( new TextContent( "hallo" ), new JavaScriptContent( "hallo" ), false ), 00378 array( new TextContent( "hallo" ), new WikitextContent( "hallo" ), false ), 00379 array( new TextContent( "hallo" ), new TextContent( "HALLO" ), false ), 00380 ); 00381 } 00382 00387 public function testEquals( Content $a, Content $b = null, $equal = false ) { 00388 $this->assertEquals( $equal, $a->equals( $b ) ); 00389 } 00390 00391 public static function dataGetDeletionUpdates() { 00392 return array( 00393 array( "TextContentTest_testGetSecondaryDataUpdates_1", 00394 CONTENT_MODEL_TEXT, "hello ''world''\n", 00395 array() 00396 ), 00397 array( "TextContentTest_testGetSecondaryDataUpdates_2", 00398 CONTENT_MODEL_TEXT, "hello [[world test 21344]]\n", 00399 array() 00400 ), 00401 // TODO: more...? 00402 ); 00403 } 00404 00409 public function testDeletionUpdates( $title, $model, $text, $expectedStuff ) { 00410 $ns = $this->getDefaultWikitextNS(); 00411 $title = Title::newFromText( $title, $ns ); 00412 00413 $content = ContentHandler::makeContent( $text, $title, $model ); 00414 00415 $page = WikiPage::factory( $title ); 00416 $page->doEditContent( $content, '' ); 00417 00418 $updates = $content->getDeletionUpdates( $page ); 00419 00420 // make updates accessible by class name 00421 foreach ( $updates as $update ) { 00422 $class = get_class( $update ); 00423 $updates[$class] = $update; 00424 } 00425 00426 if ( !$expectedStuff ) { 00427 $this->assertTrue( true ); // make phpunit happy 00428 return; 00429 } 00430 00431 foreach ( $expectedStuff as $class => $fieldValues ) { 00432 $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" ); 00433 00434 $update = $updates[$class]; 00435 00436 foreach ( $fieldValues as $field => $value ) { 00437 $v = $update->$field; #if the field doesn't exist, just crash and burn 00438 $this->assertEquals( $value, $v, "unexpected value for field $field in instance of $class" ); 00439 } 00440 } 00441 00442 $page->doDeleteArticle( '' ); 00443 } 00444 00445 public static function provideConvert() { 00446 return array( 00447 array( // #0 00448 'Hallo Welt', 00449 CONTENT_MODEL_WIKITEXT, 00450 'lossless', 00451 'Hallo Welt' 00452 ), 00453 array( // #1 00454 'Hallo Welt', 00455 CONTENT_MODEL_WIKITEXT, 00456 'lossless', 00457 'Hallo Welt' 00458 ), 00459 array( // #1 00460 'Hallo Welt', 00461 CONTENT_MODEL_CSS, 00462 'lossless', 00463 'Hallo Welt' 00464 ), 00465 array( // #1 00466 'Hallo Welt', 00467 CONTENT_MODEL_JAVASCRIPT, 00468 'lossless', 00469 'Hallo Welt' 00470 ), 00471 ); 00472 } 00473 00478 public function testConvert( $text, $model, $lossy, $expectedNative ) { 00479 $content = $this->newContent( $text ); 00480 00481 $converted = $content->convert( $model, $lossy ); 00482 00483 if ( $expectedNative === false ) { 00484 $this->assertFalse( $converted, "conversion to $model was expected to fail!" ); 00485 } else { 00486 $this->assertInstanceOf( 'Content', $converted ); 00487 $this->assertEquals( $expectedNative, $converted->getNativeData() ); 00488 } 00489 } 00490 }