MediaWiki REL1_30
WikitextContentTest.php
Go to the documentation of this file.
1<?php
2
10 public static $sections = "Intro
11
12== stuff ==
13hello world
14
15== test ==
16just a test
17
18== foo ==
19more 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",
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
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 ==
113just a test"
114 ],
115 [ self::$sections,
116 "8",
117 false
118 ],
119 ];
120 }
121
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
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
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
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
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
361 public function testGetModel() {
362 $content = $this->newContent( "hello world." );
363
364 $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getModel() );
365 }
366
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}
static makeContent( $text, Title $title=null, $modelId=null, $format=null)
Convenience function for creating a Content object from a given textual representation.
Content for JavaScript pages.
getDefaultWikitextNS()
Returns the ID of a namespace that defaults to Wikitext.
Set options of the Parser.
ContentHandler Database ^— needed, because we do need the database to test link updates.
Content object implementation for representing flat text.
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition WikiPage.php:121
testGetSecondaryDataUpdates( $title, $model, $text, $expectedStuff)
dataGetSecondaryDataUpdates Database WikitextContent::getSecondaryDataUpdates
Content object for wiki text pages.
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped & $options
Definition hooks.txt:1971
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return true
Definition hooks.txt:1976
processing should stop and the error should be shown to the user * false
Definition hooks.txt:187
globals will be eliminated from MediaWiki replaced by an application object which would be passed to constructors Whether that would be an convenient solution remains to be seen
Definition globals.txt:31
const CONTENT_MODEL_WIKITEXT
Definition Defines.php:236