Merge "Set relevant User on Special:Unblock"
[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 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( $value, $v, "unexpected value for field $field in instance of $class" );
94 }
95 }
96
97 $page->doDeleteArticle( '' );
98 }
99
100 public static function dataGetSection() {
101 return array(
102 array( WikitextContentTest::$sections,
103 "0",
104 "Intro"
105 ),
106 array( WikitextContentTest::$sections,
107 "2",
108 "== test ==
109 just a test"
110 ),
111 array( WikitextContentTest::$sections,
112 "8",
113 false
114 ),
115 );
116 }
117
118 /**
119 * @dataProvider dataGetSection
120 * @covers WikitextContent::getSection
121 */
122 public function testGetSection( $text, $sectionId, $expectedText ) {
123 $content = $this->newContent( $text );
124
125 $sectionContent = $content->getSection( $sectionId );
126 if ( is_object( $sectionContent ) ) {
127 $sectionText = $sectionContent->getNativeData();
128 } else {
129 $sectionText = $sectionContent;
130 }
131
132 $this->assertEquals( $expectedText, $sectionText );
133 }
134
135 public static function dataReplaceSection() {
136 return array(
137 array( WikitextContentTest::$sections,
138 "0",
139 "No more",
140 null,
141 trim( preg_replace( '/^Intro/sm', 'No more', WikitextContentTest::$sections ) )
142 ),
143 array( WikitextContentTest::$sections,
144 "",
145 "No more",
146 null,
147 "No more"
148 ),
149 array( WikitextContentTest::$sections,
150 "2",
151 "== TEST ==\nmore fun",
152 null,
153 trim( preg_replace( '/^== test ==.*== foo ==/sm', "== TEST ==\nmore fun\n\n== foo ==", WikitextContentTest::$sections ) )
154 ),
155 array( WikitextContentTest::$sections,
156 "8",
157 "No more",
158 null,
159 WikitextContentTest::$sections
160 ),
161 array( WikitextContentTest::$sections,
162 "new",
163 "No more",
164 "New",
165 trim( WikitextContentTest::$sections ) . "\n\n\n== New ==\n\nNo more"
166 ),
167 );
168 }
169
170 /**
171 * @dataProvider dataReplaceSection
172 * @covers WikitextContent::replaceSection
173 */
174 public function testReplaceSection( $text, $section, $with, $sectionTitle, $expected ) {
175 $content = $this->newContent( $text );
176 $c = $content->replaceSection( $section, $this->newContent( $with ), $sectionTitle );
177
178 $this->assertEquals( $expected, is_null( $c ) ? null : $c->getNativeData() );
179 }
180
181 /**
182 * @covers WikitextContent::addSectionHeader
183 */
184 public function testAddSectionHeader() {
185 $content = $this->newContent( 'hello world' );
186 $content = $content->addSectionHeader( 'test' );
187
188 $this->assertEquals( "== test ==\n\nhello world", $content->getNativeData() );
189 }
190
191 public static function dataPreSaveTransform() {
192 return array(
193 array( 'hello this is ~~~',
194 "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
195 ),
196 array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
197 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
198 ),
199 array( // rtrim
200 " Foo \n ",
201 " Foo",
202 ),
203 );
204 }
205
206 public static function dataPreloadTransform() {
207 return array(
208 array( 'hello this is ~~~',
209 "hello this is ~~~",
210 ),
211 array( 'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>',
212 'hello \'\'this\'\' is bar',
213 ),
214 );
215 }
216
217 public static function dataGetRedirectTarget() {
218 return array(
219 array( '#REDIRECT [[Test]]',
220 'Test',
221 ),
222 array( '#REDIRECT Test',
223 null,
224 ),
225 array( '* #REDIRECT [[Test]]',
226 null,
227 ),
228 );
229 }
230
231 public static function dataGetTextForSummary() {
232 return array(
233 array( "hello\nworld.",
234 16,
235 'hello world.',
236 ),
237 array( 'hello world.',
238 8,
239 'hello...',
240 ),
241 array( '[[hello world]].',
242 8,
243 'hel...',
244 ),
245 );
246 }
247
248 /**
249 * @todo Test needs database! Should be done by a test class in the Database group.
250 */
251 /*
252 public function getRedirectChain() {
253 $text = $this->getNativeData();
254 return Title::newFromRedirectArray( $text );
255 }
256 */
257
258 /**
259 * @todo Test needs database! Should be done by a test class in the Database group.
260 */
261 /*
262 public function getUltimateRedirectTarget() {
263 $text = $this->getNativeData();
264 return Title::newFromRedirectRecurse( $text );
265 }
266 */
267
268 public static function dataIsCountable() {
269 return array(
270 array( '',
271 null,
272 'any',
273 true
274 ),
275 array( 'Foo',
276 null,
277 'any',
278 true
279 ),
280 array( 'Foo',
281 null,
282 'comma',
283 false
284 ),
285 array( 'Foo, bar',
286 null,
287 'comma',
288 true
289 ),
290 array( 'Foo',
291 null,
292 'link',
293 false
294 ),
295 array( 'Foo [[bar]]',
296 null,
297 'link',
298 true
299 ),
300 array( 'Foo',
301 true,
302 'link',
303 true
304 ),
305 array( 'Foo [[bar]]',
306 false,
307 'link',
308 false
309 ),
310 array( '#REDIRECT [[bar]]',
311 true,
312 'any',
313 false
314 ),
315 array( '#REDIRECT [[bar]]',
316 true,
317 'comma',
318 false
319 ),
320 array( '#REDIRECT [[bar]]',
321 true,
322 'link',
323 false
324 ),
325 );
326 }
327
328 /**
329 * @covers WikitextContent::matchMagicWord
330 */
331 public function testMatchMagicWord() {
332 $mw = MagicWord::get( "staticredirect" );
333
334 $content = $this->newContent( "#REDIRECT [[FOO]]\n__STATICREDIRECT__" );
335 $this->assertTrue( $content->matchMagicWord( $mw ), "should have matched magic word" );
336
337 $content = $this->newContent( "#REDIRECT [[FOO]]" );
338 $this->assertFalse( $content->matchMagicWord( $mw ), "should not have matched magic word" );
339 }
340
341 /**
342 * @covers WikitextContent::updateRedirect
343 */
344 public function testUpdateRedirect() {
345 $target = Title::newFromText( "testUpdateRedirect_target" );
346
347 // test with non-redirect page
348 $content = $this->newContent( "hello world." );
349 $newContent = $content->updateRedirect( $target );
350
351 $this->assertTrue( $content->equals( $newContent ), "content should be unchanged" );
352
353 // test with actual redirect
354 $content = $this->newContent( "#REDIRECT [[Someplace]]" );
355 $newContent = $content->updateRedirect( $target );
356
357 $this->assertFalse( $content->equals( $newContent ), "content should have changed" );
358 $this->assertTrue( $newContent->isRedirect(), "new content should be a redirect" );
359
360 $this->assertEquals( $target->getFullText(), $newContent->getRedirectTarget()->getFullText() );
361 }
362
363 /**
364 * @covers WikitextContent::getModel
365 */
366 public function testGetModel() {
367 $content = $this->newContent( "hello world." );
368
369 $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getModel() );
370 }
371
372 /**
373 * @covers WikitextContent::getContentHandler
374 */
375 public function testGetContentHandler() {
376 $content = $this->newContent( "hello world." );
377
378 $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getContentHandler()->getModelID() );
379 }
380
381 public static function dataEquals() {
382 return array(
383 array( new WikitextContent( "hallo" ), null, false ),
384 array( new WikitextContent( "hallo" ), new WikitextContent( "hallo" ), true ),
385 array( new WikitextContent( "hallo" ), new JavaScriptContent( "hallo" ), false ),
386 array( new WikitextContent( "hallo" ), new TextContent( "hallo" ), false ),
387 array( new WikitextContent( "hallo" ), new WikitextContent( "HALLO" ), false ),
388 );
389 }
390
391 public static function dataGetDeletionUpdates() {
392 return array(
393 array( "WikitextContentTest_testGetSecondaryDataUpdates_1",
394 CONTENT_MODEL_WIKITEXT, "hello ''world''\n",
395 array( 'LinksDeletionUpdate' => array() )
396 ),
397 array( "WikitextContentTest_testGetSecondaryDataUpdates_2",
398 CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n",
399 array( 'LinksDeletionUpdate' => array() )
400 ),
401 // @todo more...?
402 );
403 }
404 }