4 * @group ContentHandler
7 * ^--- needed, because we do need the database to test link updates
9 class WikitextContentTest extends TextContentTest {
10 public static $sections = "Intro
22 public function newContent( $text ) {
23 return new WikitextContent( $text );
26 public static function dataGetParserOutput() {
29 "WikitextContentTest_testGetParserOutput",
30 CONTENT_MODEL_WIKITEXT,
32 "<div class=\"mw-parser-output\"><p>hello <i>world</i>\n</p>\n\n\n</div>"
38 public static function dataGetSecondaryDataUpdates() {
40 [ "WikitextContentTest_testGetSecondaryDataUpdates_1",
41 CONTENT_MODEL_WIKITEXT, "hello ''world''\n",
49 [ "WikitextContentTest_testGetSecondaryDataUpdates_2",
50 CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n",
55 [ 'World_test_21344' => 0 ]
65 * @dataProvider dataGetSecondaryDataUpdates
67 * @covers WikitextContent::getSecondaryDataUpdates
69 public function testGetSecondaryDataUpdates( $title, $model, $text, $expectedStuff ) {
70 $ns = $this->getDefaultWikitextNS();
71 $title = Title::newFromText( $title, $ns );
73 $content = ContentHandler::makeContent( $text, $title, $model );
75 $page = WikiPage::factory( $title );
76 $page->doEditContent( $content, '' );
78 $updates = $content->getSecondaryDataUpdates( $title );
80 // make updates accessible by class name
81 foreach ( $updates as $update ) {
82 $class = get_class( $update );
83 $updates[$class] = $update;
86 foreach ( $expectedStuff as $class => $fieldValues ) {
87 $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" );
89 $update = $updates[$class];
91 foreach ( $fieldValues as $field => $value ) {
92 $v = $update->$field; # if the field doesn't exist, just crash and burn
96 "unexpected value for field $field in instance of $class"
101 $page->doDeleteArticle( '' );
104 public static function dataGetSection() {
123 * @dataProvider dataGetSection
124 * @covers WikitextContent::getSection
126 public function testGetSection( $text, $sectionId, $expectedText ) {
127 $content = $this->newContent( $text );
129 $sectionContent = $content->getSection( $sectionId );
130 if ( is_object( $sectionContent ) ) {
131 $sectionText = $sectionContent->getNativeData();
133 $sectionText = $sectionContent;
136 $this->assertEquals( $expectedText, $sectionText );
139 public static function dataReplaceSection() {
145 trim( preg_replace( '/^Intro/sm', 'No more', self::$sections ) )
155 "== TEST ==\nmore fun",
158 '/^== test ==.*== foo ==/sm', "== TEST ==\nmore fun\n\n== foo ==",
172 trim( self::$sections ) . "\n\n\n== New ==\n\nNo more"
178 * @dataProvider dataReplaceSection
179 * @covers WikitextContent::replaceSection
181 public function testReplaceSection( $text, $section, $with, $sectionTitle, $expected ) {
182 $content = $this->newContent( $text );
183 $c = $content->replaceSection( $section, $this->newContent( $with ), $sectionTitle );
185 $this->assertEquals( $expected, is_null( $c ) ? null : $c->getNativeData() );
189 * @covers WikitextContent::addSectionHeader
191 public function testAddSectionHeader() {
192 $content = $this->newContent( 'hello world' );
193 $content = $content->addSectionHeader( 'test' );
195 $this->assertEquals( "== test ==\n\nhello world", $content->getNativeData() );
198 public static function dataPreSaveTransform() {
200 [ 'hello this is ~~~',
201 "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
203 [ 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
204 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
213 public static function dataPreloadTransform() {
220 'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>',
221 'hello \'\'this\'\' is bar',
226 public static function dataGetRedirectTarget() {
228 [ '#REDIRECT [[Test]]',
234 [ '* #REDIRECT [[Test]]',
240 public static function dataGetTextForSummary() {
250 [ '[[hello world]].',
257 public static function dataIsCountable() {
299 [ '#REDIRECT [[bar]]',
304 [ '#REDIRECT [[bar]]',
309 [ '#REDIRECT [[bar]]',
318 * @covers WikitextContent::matchMagicWord
320 public function testMatchMagicWord() {
321 $mw = MagicWord::get( "staticredirect" );
323 $content = $this->newContent( "#REDIRECT [[FOO]]\n__STATICREDIRECT__" );
324 $this->assertTrue( $content->matchMagicWord( $mw ), "should have matched magic word" );
326 $content = $this->newContent( "#REDIRECT [[FOO]]" );
328 $content->matchMagicWord( $mw ),
329 "should not have matched magic word"
334 * @covers WikitextContent::updateRedirect
336 public function testUpdateRedirect() {
337 $target = Title::newFromText( "testUpdateRedirect_target" );
339 // test with non-redirect page
340 $content = $this->newContent( "hello world." );
341 $newContent = $content->updateRedirect( $target );
343 $this->assertTrue( $content->equals( $newContent ), "content should be unchanged" );
345 // test with actual redirect
346 $content = $this->newContent( "#REDIRECT [[Someplace]]" );
347 $newContent = $content->updateRedirect( $target );
349 $this->assertFalse( $content->equals( $newContent ), "content should have changed" );
350 $this->assertTrue( $newContent->isRedirect(), "new content should be a redirect" );
353 $target->getFullText(),
354 $newContent->getRedirectTarget()->getFullText()
359 * @covers WikitextContent::getModel
361 public function testGetModel() {
362 $content = $this->newContent( "hello world." );
364 $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getModel() );
368 * @covers WikitextContent::getContentHandler
370 public function testGetContentHandler() {
371 $content = $this->newContent( "hello world." );
373 $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getContentHandler()->getModelID() );
376 public function testRedirectParserOption() {
377 $title = Title::newFromText( 'testRedirectParserOption' );
379 // Set up hook and its reporting variables
381 $redirectTarget = null;
382 $this->mergeMwGlobalArrayValue( 'wgHooks', [
383 'InternalParseBeforeLinks' => [
384 function ( &$parser, &$text, &$stripState ) use ( &$wikitext, &$redirectTarget ) {
386 $redirectTarget = $parser->getOptions()->getRedirectTarget();
391 // Test with non-redirect page
393 $redirectTarget = false;
394 $content = $this->newContent( 'hello world.' );
395 $options = $content->getContentHandler()->makeParserOptions( 'canonical' );
396 $options->setRedirectTarget( $title );
397 $content->getParserOutput( $title, null, $options );
398 $this->assertEquals( 'hello world.', $wikitext,
399 'Wikitext passed to hook was not as expected'
401 $this->assertEquals( null, $redirectTarget, 'Redirect seen in hook was not null' );
402 $this->assertEquals( $title, $options->getRedirectTarget(),
403 'ParserOptions\' redirectTarget was changed'
406 // Test with a redirect page
408 $redirectTarget = false;
409 $content = $this->newContent(
410 "#REDIRECT [[TestRedirectParserOption/redir]]\nhello redirect."
412 $options = $content->getContentHandler()->makeParserOptions( 'canonical' );
413 $content->getParserOutput( $title, null, $options );
417 'Wikitext passed to hook was not as expected'
419 $this->assertNotEquals(
422 'Redirect seen in hook was null' );
424 'TestRedirectParserOption/redir',
425 $redirectTarget->getFullText(),
426 'Redirect seen in hook was not the expected title'
430 $options->getRedirectTarget(),
431 'ParserOptions\' redirectTarget was changed'
435 public static function dataEquals() {
437 [ new WikitextContent( "hallo" ), null, false ],
438 [ new WikitextContent( "hallo" ), new WikitextContent( "hallo" ), true ],
439 [ new WikitextContent( "hallo" ), new JavaScriptContent( "hallo" ), false ],
440 [ new WikitextContent( "hallo" ), new TextContent( "hallo" ), false ],
441 [ new WikitextContent( "hallo" ), new WikitextContent( "HALLO" ), false ],
445 public static function dataGetDeletionUpdates() {
447 [ "WikitextContentTest_testGetSecondaryDataUpdates_1",
448 CONTENT_MODEL_WIKITEXT, "hello ''world''\n",
449 [ 'LinksDeletionUpdate' => [] ]
451 [ "WikitextContentTest_testGetSecondaryDataUpdates_2",
452 CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n",
453 [ 'LinksDeletionUpdate' => [] ]