Import: Handle uploads with sha1 starting with 0 properly
[mediawiki.git] / tests / phpunit / includes / content / TextContentTest.php
blob06609d8fe53d9a2d29e3a4f6d02f90f29dc8da81
1 <?php
3 /**
4 * @group ContentHandler
5 * @group Database
6 * ^--- needed, because we do need the database to test link updates
7 */
8 class TextContentTest extends MediaWikiLangTestCase {
9 protected $context;
11 protected function setUp() {
12 parent::setUp();
14 // Anon user
15 $user = new User();
16 $user->setName( '127.0.0.1' );
18 $this->context = new RequestContext( new FauxRequest() );
19 $this->context->setTitle( Title::newFromText( 'Test' ) );
20 $this->context->setUser( $user );
22 $this->setMwGlobals( array(
23 'wgUser' => $user,
24 'wgTextModelsToParse' => array(
25 CONTENT_MODEL_WIKITEXT,
26 CONTENT_MODEL_CSS,
27 CONTENT_MODEL_JAVASCRIPT,
29 'wgUseTidy' => false,
30 'wgCapitalLinks' => true,
31 'wgHooks' => array(), // bypass hook ContentGetParserOutput that force custom rendering
32 ) );
34 MWTidy::destroySingleton();
37 protected function tearDown() {
38 MWTidy::destroySingleton();
39 parent::tearDown();
42 public function newContent( $text ) {
43 return new TextContent( $text );
46 public static function dataGetParserOutput() {
47 return array(
48 array(
49 'TextContentTest_testGetParserOutput',
50 CONTENT_MODEL_TEXT,
51 "hello ''world'' & [[stuff]]\n", "hello ''world'' &amp; [[stuff]]",
52 array(
53 'Links' => array()
56 // TODO: more...?
60 /**
61 * @dataProvider dataGetParserOutput
62 * @covers TextContent::getParserOutput
64 public function testGetParserOutput( $title, $model, $text, $expectedHtml,
65 $expectedFields = null
66 ) {
67 $title = Title::newFromText( $title );
68 $content = ContentHandler::makeContent( $text, $title, $model );
70 $po = $content->getParserOutput( $title );
72 $html = $po->getText();
73 $html = preg_replace( '#<!--.*?-->#sm', '', $html ); // strip comments
75 $this->assertEquals( $expectedHtml, trim( $html ) );
77 if ( $expectedFields ) {
78 foreach ( $expectedFields as $field => $exp ) {
79 $f = 'get' . ucfirst( $field );
80 $v = call_user_func( array( $po, $f ) );
82 if ( is_array( $exp ) ) {
83 $this->assertArrayEquals( $exp, $v );
84 } else {
85 $this->assertEquals( $exp, $v );
90 // TODO: assert more properties
93 public static function dataPreSaveTransform() {
94 return array(
95 array(
96 # 0: no signature resolution
97 'hello this is ~~~',
98 'hello this is ~~~',
100 array(
101 # 1: rtrim
102 " Foo \n ",
103 ' Foo',
109 * @dataProvider dataPreSaveTransform
110 * @covers TextContent::preSaveTransform
112 public function testPreSaveTransform( $text, $expected ) {
113 global $wgContLang;
115 $options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang );
117 $content = $this->newContent( $text );
118 $content = $content->preSaveTransform(
119 $this->context->getTitle(),
120 $this->context->getUser(),
121 $options
124 $this->assertEquals( $expected, $content->getNativeData() );
127 public static function dataPreloadTransform() {
128 return array(
129 array(
130 'hello this is ~~~',
131 'hello this is ~~~',
137 * @dataProvider dataPreloadTransform
138 * @covers TextContent::preloadTransform
140 public function testPreloadTransform( $text, $expected ) {
141 global $wgContLang;
142 $options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang );
144 $content = $this->newContent( $text );
145 $content = $content->preloadTransform( $this->context->getTitle(), $options );
147 $this->assertEquals( $expected, $content->getNativeData() );
150 public static function dataGetRedirectTarget() {
151 return array(
152 array( '#REDIRECT [[Test]]',
153 null,
159 * @dataProvider dataGetRedirectTarget
160 * @covers TextContent::getRedirectTarget
162 public function testGetRedirectTarget( $text, $expected ) {
163 $content = $this->newContent( $text );
164 $t = $content->getRedirectTarget();
166 if ( is_null( $expected ) ) {
167 $this->assertNull( $t, "text should not have generated a redirect target: $text" );
168 } else {
169 $this->assertEquals( $expected, $t->getPrefixedText() );
174 * @dataProvider dataGetRedirectTarget
175 * @covers TextContent::isRedirect
177 public function testIsRedirect( $text, $expected ) {
178 $content = $this->newContent( $text );
180 $this->assertEquals( !is_null( $expected ), $content->isRedirect() );
184 * @todo Test needs database! Should be done by a test class in the Database group.
187 public function getRedirectChain() {
188 $text = $this->getNativeData();
189 return Title::newFromRedirectArray( $text );
194 * @todo Test needs database! Should be done by a test class in the Database group.
197 public function getUltimateRedirectTarget() {
198 $text = $this->getNativeData();
199 return Title::newFromRedirectRecurse( $text );
203 public static function dataIsCountable() {
204 return array(
205 array( '',
206 null,
207 'any',
208 true
210 array( 'Foo',
211 null,
212 'any',
213 true
215 array( 'Foo',
216 null,
217 'comma',
218 false
220 array( 'Foo, bar',
221 null,
222 'comma',
223 false
229 * @dataProvider dataIsCountable
230 * @group Database
231 * @covers TextContent::isCountable
233 public function testIsCountable( $text, $hasLinks, $mode, $expected ) {
234 $this->setMwGlobals( 'wgArticleCountMethod', $mode );
236 $content = $this->newContent( $text );
238 $v = $content->isCountable( $hasLinks, $this->context->getTitle() );
240 $this->assertEquals(
241 $expected,
243 'isCountable() returned unexpected value ' . var_export( $v, true )
244 . ' instead of ' . var_export( $expected, true )
245 . " in mode `$mode` for text \"$text\""
249 public static function dataGetTextForSummary() {
250 return array(
251 array( "hello\nworld.",
253 'hello world.',
255 array( 'hello world.',
257 'hello...',
259 array( '[[hello world]].',
261 '[[hel...',
267 * @dataProvider dataGetTextForSummary
268 * @covers TextContent::getTextForSummary
270 public function testGetTextForSummary( $text, $maxlength, $expected ) {
271 $content = $this->newContent( $text );
273 $this->assertEquals( $expected, $content->getTextForSummary( $maxlength ) );
277 * @covers TextContent::getTextForSearchIndex
279 public function testGetTextForSearchIndex() {
280 $content = $this->newContent( 'hello world.' );
282 $this->assertEquals( 'hello world.', $content->getTextForSearchIndex() );
286 * @covers TextContent::copy
288 public function testCopy() {
289 $content = $this->newContent( 'hello world.' );
290 $copy = $content->copy();
292 $this->assertTrue( $content->equals( $copy ), 'copy must be equal to original' );
293 $this->assertEquals( 'hello world.', $copy->getNativeData() );
297 * @covers TextContent::getSize
299 public function testGetSize() {
300 $content = $this->newContent( 'hello world.' );
302 $this->assertEquals( 12, $content->getSize() );
306 * @covers TextContent::getNativeData
308 public function testGetNativeData() {
309 $content = $this->newContent( 'hello world.' );
311 $this->assertEquals( 'hello world.', $content->getNativeData() );
315 * @covers TextContent::getWikitextForTransclusion
317 public function testGetWikitextForTransclusion() {
318 $content = $this->newContent( 'hello world.' );
320 $this->assertEquals( 'hello world.', $content->getWikitextForTransclusion() );
324 * @covers TextContent::getModel
326 public function testGetModel() {
327 $content = $this->newContent( "hello world." );
329 $this->assertEquals( CONTENT_MODEL_TEXT, $content->getModel() );
333 * @covers TextContent::getContentHandler
335 public function testGetContentHandler() {
336 $content = $this->newContent( "hello world." );
338 $this->assertEquals( CONTENT_MODEL_TEXT, $content->getContentHandler()->getModelID() );
341 public static function dataIsEmpty() {
342 return array(
343 array( '', true ),
344 array( ' ', false ),
345 array( '0', false ),
346 array( 'hallo welt.', false ),
351 * @dataProvider dataIsEmpty
352 * @covers TextContent::isEmpty
354 public function testIsEmpty( $text, $empty ) {
355 $content = $this->newContent( $text );
357 $this->assertEquals( $empty, $content->isEmpty() );
360 public static function dataEquals() {
361 return array(
362 array( new TextContent( "hallo" ), null, false ),
363 array( new TextContent( "hallo" ), new TextContent( "hallo" ), true ),
364 array( new TextContent( "hallo" ), new JavaScriptContent( "hallo" ), false ),
365 array( new TextContent( "hallo" ), new WikitextContent( "hallo" ), false ),
366 array( new TextContent( "hallo" ), new TextContent( "HALLO" ), false ),
371 * @dataProvider dataEquals
372 * @covers TextContent::equals
374 public function testEquals( Content $a, Content $b = null, $equal = false ) {
375 $this->assertEquals( $equal, $a->equals( $b ) );
378 public static function dataGetDeletionUpdates() {
379 return array(
380 array( "TextContentTest_testGetSecondaryDataUpdates_1",
381 CONTENT_MODEL_TEXT, "hello ''world''\n",
382 array()
384 array( "TextContentTest_testGetSecondaryDataUpdates_2",
385 CONTENT_MODEL_TEXT, "hello [[world test 21344]]\n",
386 array()
388 // TODO: more...?
393 * @dataProvider dataGetDeletionUpdates
394 * @covers TextContent::getDeletionUpdates
396 public function testDeletionUpdates( $title, $model, $text, $expectedStuff ) {
397 $ns = $this->getDefaultWikitextNS();
398 $title = Title::newFromText( $title, $ns );
400 $content = ContentHandler::makeContent( $text, $title, $model );
402 $page = WikiPage::factory( $title );
403 $page->doEditContent( $content, '' );
405 $updates = $content->getDeletionUpdates( $page );
407 // make updates accessible by class name
408 foreach ( $updates as $update ) {
409 $class = get_class( $update );
410 $updates[$class] = $update;
413 if ( !$expectedStuff ) {
414 $this->assertTrue( true ); // make phpunit happy
415 return;
418 foreach ( $expectedStuff as $class => $fieldValues ) {
419 $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" );
421 $update = $updates[$class];
423 foreach ( $fieldValues as $field => $value ) {
424 $v = $update->$field; # if the field doesn't exist, just crash and burn
425 $this->assertEquals( $value, $v, "unexpected value for field $field in instance of $class" );
429 $page->doDeleteArticle( '' );
432 public static function provideConvert() {
433 return array(
434 array( // #0
435 'Hallo Welt',
436 CONTENT_MODEL_WIKITEXT,
437 'lossless',
438 'Hallo Welt'
440 array( // #1
441 'Hallo Welt',
442 CONTENT_MODEL_WIKITEXT,
443 'lossless',
444 'Hallo Welt'
446 array( // #1
447 'Hallo Welt',
448 CONTENT_MODEL_CSS,
449 'lossless',
450 'Hallo Welt'
452 array( // #1
453 'Hallo Welt',
454 CONTENT_MODEL_JAVASCRIPT,
455 'lossless',
456 'Hallo Welt'
462 * @dataProvider provideConvert
463 * @covers TextContent::convert
465 public function testConvert( $text, $model, $lossy, $expectedNative ) {
466 $content = $this->newContent( $text );
468 $converted = $content->convert( $model, $lossy );
470 if ( $expectedNative === false ) {
471 $this->assertFalse( $converted, "conversion to $model was expected to fail!" );
472 } else {
473 $this->assertInstanceOf( 'Content', $converted );
474 $this->assertEquals( $expectedNative, $converted->getNativeData() );