]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - tests/phpunit/includes/content/WikitextContentTest.php
MediaWiki 1.30.2-scripts2
[autoinstalls/mediawiki.git] / tests / phpunit / includes / content / WikitextContentTest.php
1 <?php
2
3 /**
4  * @group ContentHandler
5  *
6  * @group Database
7  *        ^--- needed, because we do need the database to test link updates
8  */
9 class WikitextContentTest extends TextContentTest {
10         public static $sections = "Intro
11
12 == stuff ==
13 hello world
14
15 == test ==
16 just a test
17
18 == foo ==
19 more stuff
20 ";
21
22         public function newContent( $text ) {
23                 return new WikitextContent( $text );
24         }
25
26         public static function dataGetParserOutput() {
27                 return [
28                         [
29                                 "WikitextContentTest_testGetParserOutput",
30                                 CONTENT_MODEL_WIKITEXT,
31                                 "hello ''world''\n",
32                                 "<div class=\"mw-parser-output\"><p>hello <i>world</i>\n</p>\n\n\n</div>"
33                         ],
34                         // TODO: more...?
35                 ];
36         }
37
38         public static function dataGetSecondaryDataUpdates() {
39                 return [
40                         [ "WikitextContentTest_testGetSecondaryDataUpdates_1",
41                                 CONTENT_MODEL_WIKITEXT, "hello ''world''\n",
42                                 [
43                                         'LinksUpdate' => [
44                                                 'mRecursive' => true,
45                                                 'mLinks' => []
46                                         ]
47                                 ]
48                         ],
49                         [ "WikitextContentTest_testGetSecondaryDataUpdates_2",
50                                 CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n",
51                                 [
52                                         'LinksUpdate' => [
53                                                 'mRecursive' => true,
54                                                 'mLinks' => [
55                                                         [ 'World_test_21344' => 0 ]
56                                                 ]
57                                         ]
58                                 ]
59                         ],
60                         // TODO: more...?
61                 ];
62         }
63
64         /**
65          * @dataProvider dataGetSecondaryDataUpdates
66          * @group Database
67          * @covers WikitextContent::getSecondaryDataUpdates
68          */
69         public function testGetSecondaryDataUpdates( $title, $model, $text, $expectedStuff ) {
70                 $ns = $this->getDefaultWikitextNS();
71                 $title = Title::newFromText( $title, $ns );
72
73                 $content = ContentHandler::makeContent( $text, $title, $model );
74
75                 $page = WikiPage::factory( $title );
76                 $page->doEditContent( $content, '' );
77
78                 $updates = $content->getSecondaryDataUpdates( $title );
79
80                 // make updates accessible by class name
81                 foreach ( $updates as $update ) {
82                         $class = get_class( $update );
83                         $updates[$class] = $update;
84                 }
85
86                 foreach ( $expectedStuff as $class => $fieldValues ) {
87                         $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" );
88
89                         $update = $updates[$class];
90
91                         foreach ( $fieldValues as $field => $value ) {
92                                 $v = $update->$field; # if the field doesn't exist, just crash and burn
93                                 $this->assertEquals(
94                                         $value,
95                                         $v,
96                                         "unexpected value for field $field in instance of $class"
97                                 );
98                         }
99                 }
100
101                 $page->doDeleteArticle( '' );
102         }
103
104         public static function dataGetSection() {
105                 return [
106                         [ self::$sections,
107                                 "0",
108                                 "Intro"
109                         ],
110                         [ self::$sections,
111                                 "2",
112                                 "== test ==
113 just a test"
114                         ],
115                         [ self::$sections,
116                                 "8",
117                                 false
118                         ],
119                 ];
120         }
121
122         /**
123          * @dataProvider dataGetSection
124          * @covers WikitextContent::getSection
125          */
126         public function testGetSection( $text, $sectionId, $expectedText ) {
127                 $content = $this->newContent( $text );
128
129                 $sectionContent = $content->getSection( $sectionId );
130                 if ( is_object( $sectionContent ) ) {
131                         $sectionText = $sectionContent->getNativeData();
132                 } else {
133                         $sectionText = $sectionContent;
134                 }
135
136                 $this->assertEquals( $expectedText, $sectionText );
137         }
138
139         public static function dataReplaceSection() {
140                 return [
141                         [ self::$sections,
142                                 "0",
143                                 "No more",
144                                 null,
145                                 trim( preg_replace( '/^Intro/sm', 'No more', self::$sections ) )
146                         ],
147                         [ self::$sections,
148                                 "",
149                                 "No more",
150                                 null,
151                                 "No more"
152                         ],
153                         [ self::$sections,
154                                 "2",
155                                 "== TEST ==\nmore fun",
156                                 null,
157                                 trim( preg_replace(
158                                         '/^== test ==.*== foo ==/sm', "== TEST ==\nmore fun\n\n== foo ==",
159                                         self::$sections
160                                 ) )
161                         ],
162                         [ self::$sections,
163                                 "8",
164                                 "No more",
165                                 null,
166                                 self::$sections
167                         ],
168                         [ self::$sections,
169                                 "new",
170                                 "No more",
171                                 "New",
172                                 trim( self::$sections ) . "\n\n\n== New ==\n\nNo more"
173                         ],
174                 ];
175         }
176
177         /**
178          * @dataProvider dataReplaceSection
179          * @covers WikitextContent::replaceSection
180          */
181         public function testReplaceSection( $text, $section, $with, $sectionTitle, $expected ) {
182                 $content = $this->newContent( $text );
183                 $c = $content->replaceSection( $section, $this->newContent( $with ), $sectionTitle );
184
185                 $this->assertEquals( $expected, is_null( $c ) ? null : $c->getNativeData() );
186         }
187
188         /**
189          * @covers WikitextContent::addSectionHeader
190          */
191         public function testAddSectionHeader() {
192                 $content = $this->newContent( 'hello world' );
193                 $content = $content->addSectionHeader( 'test' );
194
195                 $this->assertEquals( "== test ==\n\nhello world", $content->getNativeData() );
196         }
197
198         public static function dataPreSaveTransform() {
199                 return [
200                         [ 'hello this is ~~~',
201                                 "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
202                         ],
203                         [ 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
204                                 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
205                         ],
206                         [ // rtrim
207                                 " Foo \n ",
208                                 " Foo",
209                         ],
210                 ];
211         }
212
213         public static function dataPreloadTransform() {
214                 return [
215                         [
216                                 'hello this is ~~~',
217                                 "hello this is ~~~",
218                         ],
219                         [
220                                 'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>',
221                                 'hello \'\'this\'\' is bar',
222                         ],
223                 ];
224         }
225
226         public static function dataGetRedirectTarget() {
227                 return [
228                         [ '#REDIRECT [[Test]]',
229                                 'Test',
230                         ],
231                         [ '#REDIRECT Test',
232                                 null,
233                         ],
234                         [ '* #REDIRECT [[Test]]',
235                                 null,
236                         ],
237                 ];
238         }
239
240         public static function dataGetTextForSummary() {
241                 return [
242                         [ "hello\nworld.",
243                                 16,
244                                 'hello world.',
245                         ],
246                         [ 'hello world.',
247                                 8,
248                                 'hello...',
249                         ],
250                         [ '[[hello world]].',
251                                 8,
252                                 'hel...',
253                         ],
254                 ];
255         }
256
257         public static function dataIsCountable() {
258                 return [
259                         [ '',
260                                 null,
261                                 'any',
262                                 true
263                         ],
264                         [ 'Foo',
265                                 null,
266                                 'any',
267                                 true
268                         ],
269                         [ 'Foo',
270                                 null,
271                                 'comma',
272                                 false
273                         ],
274                         [ 'Foo, bar',
275                                 null,
276                                 'comma',
277                                 true
278                         ],
279                         [ 'Foo',
280                                 null,
281                                 'link',
282                                 false
283                         ],
284                         [ 'Foo [[bar]]',
285                                 null,
286                                 'link',
287                                 true
288                         ],
289                         [ 'Foo',
290                                 true,
291                                 'link',
292                                 true
293                         ],
294                         [ 'Foo [[bar]]',
295                                 false,
296                                 'link',
297                                 false
298                         ],
299                         [ '#REDIRECT [[bar]]',
300                                 true,
301                                 'any',
302                                 false
303                         ],
304                         [ '#REDIRECT [[bar]]',
305                                 true,
306                                 'comma',
307                                 false
308                         ],
309                         [ '#REDIRECT [[bar]]',
310                                 true,
311                                 'link',
312                                 false
313                         ],
314                 ];
315         }
316
317         /**
318          * @covers WikitextContent::matchMagicWord
319          */
320         public function testMatchMagicWord() {
321                 $mw = MagicWord::get( "staticredirect" );
322
323                 $content = $this->newContent( "#REDIRECT [[FOO]]\n__STATICREDIRECT__" );
324                 $this->assertTrue( $content->matchMagicWord( $mw ), "should have matched magic word" );
325
326                 $content = $this->newContent( "#REDIRECT [[FOO]]" );
327                 $this->assertFalse(
328                         $content->matchMagicWord( $mw ),
329                         "should not have matched magic word"
330                 );
331         }
332
333         /**
334          * @covers WikitextContent::updateRedirect
335          */
336         public function testUpdateRedirect() {
337                 $target = Title::newFromText( "testUpdateRedirect_target" );
338
339                 // test with non-redirect page
340                 $content = $this->newContent( "hello world." );
341                 $newContent = $content->updateRedirect( $target );
342
343                 $this->assertTrue( $content->equals( $newContent ), "content should be unchanged" );
344
345                 // test with actual redirect
346                 $content = $this->newContent( "#REDIRECT [[Someplace]]" );
347                 $newContent = $content->updateRedirect( $target );
348
349                 $this->assertFalse( $content->equals( $newContent ), "content should have changed" );
350                 $this->assertTrue( $newContent->isRedirect(), "new content should be a redirect" );
351
352                 $this->assertEquals(
353                         $target->getFullText(),
354                         $newContent->getRedirectTarget()->getFullText()
355                 );
356         }
357
358         /**
359          * @covers WikitextContent::getModel
360          */
361         public function testGetModel() {
362                 $content = $this->newContent( "hello world." );
363
364                 $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getModel() );
365         }
366
367         /**
368          * @covers WikitextContent::getContentHandler
369          */
370         public function testGetContentHandler() {
371                 $content = $this->newContent( "hello world." );
372
373                 $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getContentHandler()->getModelID() );
374         }
375
376         public function testRedirectParserOption() {
377                 $title = Title::newFromText( 'testRedirectParserOption' );
378
379                 // Set up hook and its reporting variables
380                 $wikitext = null;
381                 $redirectTarget = null;
382                 $this->mergeMwGlobalArrayValue( 'wgHooks', [
383                         'InternalParseBeforeLinks' => [
384                                 function ( &$parser, &$text, &$stripState ) use ( &$wikitext, &$redirectTarget ) {
385                                         $wikitext = $text;
386                                         $redirectTarget = $parser->getOptions()->getRedirectTarget();
387                                 }
388                         ]
389                 ] );
390
391                 // Test with non-redirect page
392                 $wikitext = false;
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'
400                 );
401                 $this->assertEquals( null, $redirectTarget, 'Redirect seen in hook was not null' );
402                 $this->assertEquals( $title, $options->getRedirectTarget(),
403                         'ParserOptions\' redirectTarget was changed'
404                 );
405
406                 // Test with a redirect page
407                 $wikitext = false;
408                 $redirectTarget = false;
409                 $content = $this->newContent(
410                         "#REDIRECT [[TestRedirectParserOption/redir]]\nhello redirect."
411                 );
412                 $options = $content->getContentHandler()->makeParserOptions( 'canonical' );
413                 $content->getParserOutput( $title, null, $options );
414                 $this->assertEquals(
415                         'hello redirect.',
416                         $wikitext,
417                         'Wikitext passed to hook was not as expected'
418                 );
419                 $this->assertNotEquals(
420                         null,
421                         $redirectTarget,
422                         'Redirect seen in hook was null' );
423                 $this->assertEquals(
424                         'TestRedirectParserOption/redir',
425                         $redirectTarget->getFullText(),
426                         'Redirect seen in hook was not the expected title'
427                 );
428                 $this->assertEquals(
429                         null,
430                         $options->getRedirectTarget(),
431                         'ParserOptions\' redirectTarget was changed'
432                 );
433         }
434
435         public static function dataEquals() {
436                 return [
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 ],
442                 ];
443         }
444
445         public static function dataGetDeletionUpdates() {
446                 return [
447                         [ "WikitextContentTest_testGetSecondaryDataUpdates_1",
448                                 CONTENT_MODEL_WIKITEXT, "hello ''world''\n",
449                                 [ 'LinksDeletionUpdate' => [] ]
450                         ],
451                         [ "WikitextContentTest_testGetSecondaryDataUpdates_2",
452                                 CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n",
453                                 [ 'LinksDeletionUpdate' => [] ]
454                         ],
455                         // @todo more...?
456                 ];
457         }
458 }