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",
43 LinksUpdate
::class => [
49 [ "WikitextContentTest_testGetSecondaryDataUpdates_2",
50 CONTENT_MODEL_WIKITEXT
, "hello [[world test 21344]]\n",
52 LinksUpdate
::class => [
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() {
289 [ '#REDIRECT [[bar]]',
294 [ '#REDIRECT [[bar]]',
303 * @covers WikitextContent::matchMagicWord
305 public function testMatchMagicWord() {
306 $mw = MagicWord
::get( "staticredirect" );
308 $content = $this->newContent( "#REDIRECT [[FOO]]\n__STATICREDIRECT__" );
309 $this->assertTrue( $content->matchMagicWord( $mw ), "should have matched magic word" );
311 $content = $this->newContent( "#REDIRECT [[FOO]]" );
313 $content->matchMagicWord( $mw ),
314 "should not have matched magic word"
319 * @covers WikitextContent::updateRedirect
321 public function testUpdateRedirect() {
322 $target = Title
::newFromText( "testUpdateRedirect_target" );
324 // test with non-redirect page
325 $content = $this->newContent( "hello world." );
326 $newContent = $content->updateRedirect( $target );
328 $this->assertTrue( $content->equals( $newContent ), "content should be unchanged" );
330 // test with actual redirect
331 $content = $this->newContent( "#REDIRECT [[Someplace]]" );
332 $newContent = $content->updateRedirect( $target );
334 $this->assertFalse( $content->equals( $newContent ), "content should have changed" );
335 $this->assertTrue( $newContent->isRedirect(), "new content should be a redirect" );
338 $target->getFullText(),
339 $newContent->getRedirectTarget()->getFullText()
344 * @covers WikitextContent::getModel
346 public function testGetModel() {
347 $content = $this->newContent( "hello world." );
349 $this->assertEquals( CONTENT_MODEL_WIKITEXT
, $content->getModel() );
353 * @covers WikitextContent::getContentHandler
355 public function testGetContentHandler() {
356 $content = $this->newContent( "hello world." );
358 $this->assertEquals( CONTENT_MODEL_WIKITEXT
, $content->getContentHandler()->getModelID() );
361 public function testRedirectParserOption() {
362 $title = Title
::newFromText( 'testRedirectParserOption' );
364 // Set up hook and its reporting variables
366 $redirectTarget = null;
367 $this->mergeMwGlobalArrayValue( 'wgHooks', [
368 'InternalParseBeforeLinks' => [
369 function ( &$parser, &$text, &$stripState ) use ( &$wikitext, &$redirectTarget ) {
371 $redirectTarget = $parser->getOptions()->getRedirectTarget();
376 // Test with non-redirect page
378 $redirectTarget = false;
379 $content = $this->newContent( 'hello world.' );
380 $options = $content->getContentHandler()->makeParserOptions( 'canonical' );
381 $options->setRedirectTarget( $title );
382 $content->getParserOutput( $title, null, $options );
383 $this->assertEquals( 'hello world.', $wikitext,
384 'Wikitext passed to hook was not as expected'
386 $this->assertEquals( null, $redirectTarget, 'Redirect seen in hook was not null' );
387 $this->assertEquals( $title, $options->getRedirectTarget(),
388 'ParserOptions\' redirectTarget was changed'
391 // Test with a redirect page
393 $redirectTarget = false;
394 $content = $this->newContent(
395 "#REDIRECT [[TestRedirectParserOption/redir]]\nhello redirect."
397 $options = $content->getContentHandler()->makeParserOptions( 'canonical' );
398 $content->getParserOutput( $title, null, $options );
402 'Wikitext passed to hook was not as expected'
404 $this->assertNotEquals(
407 'Redirect seen in hook was null' );
409 'TestRedirectParserOption/redir',
410 $redirectTarget->getFullText(),
411 'Redirect seen in hook was not the expected title'
415 $options->getRedirectTarget(),
416 'ParserOptions\' redirectTarget was changed'
420 public static function dataEquals() {
422 [ new WikitextContent( "hallo" ), null, false ],
423 [ new WikitextContent( "hallo" ), new WikitextContent( "hallo" ), true ],
424 [ new WikitextContent( "hallo" ), new JavaScriptContent( "hallo" ), false ],
425 [ new WikitextContent( "hallo" ), new TextContent( "hallo" ), false ],
426 [ new WikitextContent( "hallo" ), new WikitextContent( "HALLO" ), false ],
430 public static function dataGetDeletionUpdates() {
432 [ "WikitextContentTest_testGetSecondaryDataUpdates_1",
433 CONTENT_MODEL_WIKITEXT
, "hello ''world''\n",
434 [ LinksDeletionUpdate
::class => [] ]
436 [ "WikitextContentTest_testGetSecondaryDataUpdates_2",
437 CONTENT_MODEL_WIKITEXT
, "hello [[world test 21344]]\n",
438 [ LinksDeletionUpdate
::class => [] ]