Merge "Clean up zh-tw.json"
[lhc/web/wiklou.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 array(
28 array(
29 "WikitextContentTest_testGetParserOutput",
30 CONTENT_MODEL_WIKITEXT,
31 "hello ''world''\n",
32 "<p>hello <i>world</i>\n</p>"
33 ),
34 // TODO: more...?
35 );
36 }
37
38 public static function dataGetSecondaryDataUpdates() {
39 return array(
40 array( "WikitextContentTest_testGetSecondaryDataUpdates_1",
41 CONTENT_MODEL_WIKITEXT, "hello ''world''\n",
42 array(
43 'LinksUpdate' => array(
44 'mRecursive' => true,
45 'mLinks' => array()
46 )
47 )
48 ),
49 array( "WikitextContentTest_testGetSecondaryDataUpdates_2",
50 CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n",
51 array(
52 'LinksUpdate' => array(
53 'mRecursive' => true,
54 'mLinks' => array(
55 array( '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 array(
106 array( WikitextContentTest::$sections,
107 "0",
108 "Intro"
109 ),
110 array( WikitextContentTest::$sections,
111 "2",
112 "== test ==
113 just a test"
114 ),
115 array( WikitextContentTest::$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 array(
141 array( WikitextContentTest::$sections,
142 "0",
143 "No more",
144 null,
145 trim( preg_replace( '/^Intro/sm', 'No more', WikitextContentTest::$sections ) )
146 ),
147 array( WikitextContentTest::$sections,
148 "",
149 "No more",
150 null,
151 "No more"
152 ),
153 array( WikitextContentTest::$sections,
154 "2",
155 "== TEST ==\nmore fun",
156 null,
157 trim( preg_replace(
158 '/^== test ==.*== foo ==/sm', "== TEST ==\nmore fun\n\n== foo ==",
159 WikitextContentTest::$sections
160 ) )
161 ),
162 array( WikitextContentTest::$sections,
163 "8",
164 "No more",
165 null,
166 WikitextContentTest::$sections
167 ),
168 array( WikitextContentTest::$sections,
169 "new",
170 "No more",
171 "New",
172 trim( WikitextContentTest::$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 array(
200 array( 'hello this is ~~~',
201 "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
202 ),
203 array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
204 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
205 ),
206 array( // rtrim
207 " Foo \n ",
208 " Foo",
209 ),
210 );
211 }
212
213 public static function dataPreloadTransform() {
214 return array(
215 array(
216 'hello this is ~~~',
217 "hello this is ~~~",
218 ),
219 array(
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 array(
228 array( '#REDIRECT [[Test]]',
229 'Test',
230 ),
231 array( '#REDIRECT Test',
232 null,
233 ),
234 array( '* #REDIRECT [[Test]]',
235 null,
236 ),
237 );
238 }
239
240 public static function dataGetTextForSummary() {
241 return array(
242 array( "hello\nworld.",
243 16,
244 'hello world.',
245 ),
246 array( 'hello world.',
247 8,
248 'hello...',
249 ),
250 array( '[[hello world]].',
251 8,
252 'hel...',
253 ),
254 );
255 }
256
257 public static function dataIsCountable() {
258 return array(
259 array( '',
260 null,
261 'any',
262 true
263 ),
264 array( 'Foo',
265 null,
266 'any',
267 true
268 ),
269 array( 'Foo',
270 null,
271 'comma',
272 false
273 ),
274 array( 'Foo, bar',
275 null,
276 'comma',
277 true
278 ),
279 array( 'Foo',
280 null,
281 'link',
282 false
283 ),
284 array( 'Foo [[bar]]',
285 null,
286 'link',
287 true
288 ),
289 array( 'Foo',
290 true,
291 'link',
292 true
293 ),
294 array( 'Foo [[bar]]',
295 false,
296 'link',
297 false
298 ),
299 array( '#REDIRECT [[bar]]',
300 true,
301 'any',
302 false
303 ),
304 array( '#REDIRECT [[bar]]',
305 true,
306 'comma',
307 false
308 ),
309 array( '#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', array(
383 'InternalParseBeforeLinks' => array(
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 array(
437 array( new WikitextContent( "hallo" ), null, false ),
438 array( new WikitextContent( "hallo" ), new WikitextContent( "hallo" ), true ),
439 array( new WikitextContent( "hallo" ), new JavaScriptContent( "hallo" ), false ),
440 array( new WikitextContent( "hallo" ), new TextContent( "hallo" ), false ),
441 array( new WikitextContent( "hallo" ), new WikitextContent( "HALLO" ), false ),
442 );
443 }
444
445 public static function dataGetDeletionUpdates() {
446 return array(
447 array( "WikitextContentTest_testGetSecondaryDataUpdates_1",
448 CONTENT_MODEL_WIKITEXT, "hello ''world''\n",
449 array( 'LinksDeletionUpdate' => array() )
450 ),
451 array( "WikitextContentTest_testGetSecondaryDataUpdates_2",
452 CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n",
453 array( 'LinksDeletionUpdate' => array() )
454 ),
455 // @todo more...?
456 );
457 }
458 }