Merge "Provide direction hinting in the personal toolbar"
[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 public static function dataIsCountable() {
249 return array(
250 array( '',
251 null,
252 'any',
253 true
254 ),
255 array( 'Foo',
256 null,
257 'any',
258 true
259 ),
260 array( 'Foo',
261 null,
262 'comma',
263 false
264 ),
265 array( 'Foo, bar',
266 null,
267 'comma',
268 true
269 ),
270 array( 'Foo',
271 null,
272 'link',
273 false
274 ),
275 array( 'Foo [[bar]]',
276 null,
277 'link',
278 true
279 ),
280 array( 'Foo',
281 true,
282 'link',
283 true
284 ),
285 array( 'Foo [[bar]]',
286 false,
287 'link',
288 false
289 ),
290 array( '#REDIRECT [[bar]]',
291 true,
292 'any',
293 false
294 ),
295 array( '#REDIRECT [[bar]]',
296 true,
297 'comma',
298 false
299 ),
300 array( '#REDIRECT [[bar]]',
301 true,
302 'link',
303 false
304 ),
305 );
306 }
307
308 /**
309 * @covers WikitextContent::matchMagicWord
310 */
311 public function testMatchMagicWord() {
312 $mw = MagicWord::get( "staticredirect" );
313
314 $content = $this->newContent( "#REDIRECT [[FOO]]\n__STATICREDIRECT__" );
315 $this->assertTrue( $content->matchMagicWord( $mw ), "should have matched magic word" );
316
317 $content = $this->newContent( "#REDIRECT [[FOO]]" );
318 $this->assertFalse( $content->matchMagicWord( $mw ), "should not have matched magic word" );
319 }
320
321 /**
322 * @covers WikitextContent::updateRedirect
323 */
324 public function testUpdateRedirect() {
325 $target = Title::newFromText( "testUpdateRedirect_target" );
326
327 // test with non-redirect page
328 $content = $this->newContent( "hello world." );
329 $newContent = $content->updateRedirect( $target );
330
331 $this->assertTrue( $content->equals( $newContent ), "content should be unchanged" );
332
333 // test with actual redirect
334 $content = $this->newContent( "#REDIRECT [[Someplace]]" );
335 $newContent = $content->updateRedirect( $target );
336
337 $this->assertFalse( $content->equals( $newContent ), "content should have changed" );
338 $this->assertTrue( $newContent->isRedirect(), "new content should be a redirect" );
339
340 $this->assertEquals( $target->getFullText(), $newContent->getRedirectTarget()->getFullText() );
341 }
342
343 /**
344 * @covers WikitextContent::getModel
345 */
346 public function testGetModel() {
347 $content = $this->newContent( "hello world." );
348
349 $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getModel() );
350 }
351
352 /**
353 * @covers WikitextContent::getContentHandler
354 */
355 public function testGetContentHandler() {
356 $content = $this->newContent( "hello world." );
357
358 $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getContentHandler()->getModelID() );
359 }
360
361 public static function dataEquals() {
362 return array(
363 array( new WikitextContent( "hallo" ), null, false ),
364 array( new WikitextContent( "hallo" ), new WikitextContent( "hallo" ), true ),
365 array( new WikitextContent( "hallo" ), new JavaScriptContent( "hallo" ), false ),
366 array( new WikitextContent( "hallo" ), new TextContent( "hallo" ), false ),
367 array( new WikitextContent( "hallo" ), new WikitextContent( "HALLO" ), false ),
368 );
369 }
370
371 public static function dataGetDeletionUpdates() {
372 return array(
373 array( "WikitextContentTest_testGetSecondaryDataUpdates_1",
374 CONTENT_MODEL_WIKITEXT, "hello ''world''\n",
375 array( 'LinksDeletionUpdate' => array() )
376 ),
377 array( "WikitextContentTest_testGetSecondaryDataUpdates_2",
378 CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n",
379 array( 'LinksDeletionUpdate' => array() )
380 ),
381 // @todo more...?
382 );
383 }
384 }