MediaWiki REL1_31
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::class => [
44 'mRecursive' => true,
45 'mLinks' => []
46 ]
47 ]
48 ],
49 [ "WikitextContentTest_testGetSecondaryDataUpdates_2",
50 CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n",
51 [
52 LinksUpdate::class => [
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 'link',
272 false
273 ],
274 [ 'Foo [[bar]]',
275 null,
276 'link',
277 true
278 ],
279 [ 'Foo',
280 true,
281 'link',
282 true
283 ],
284 [ 'Foo [[bar]]',
285 false,
286 'link',
287 false
288 ],
289 [ '#REDIRECT [[bar]]',
290 true,
291 'any',
292 false
293 ],
294 [ '#REDIRECT [[bar]]',
295 true,
296 'link',
297 false
298 ],
299 ];
300 }
301
305 public function testMatchMagicWord() {
306 $mw = MagicWord::get( "staticredirect" );
307
308 $content = $this->newContent( "#REDIRECT [[FOO]]\n__STATICREDIRECT__" );
309 $this->assertTrue( $content->matchMagicWord( $mw ), "should have matched magic word" );
310
311 $content = $this->newContent( "#REDIRECT [[FOO]]" );
312 $this->assertFalse(
313 $content->matchMagicWord( $mw ),
314 "should not have matched magic word"
315 );
316 }
317
321 public function testUpdateRedirect() {
322 $target = Title::newFromText( "testUpdateRedirect_target" );
323
324 // test with non-redirect page
325 $content = $this->newContent( "hello world." );
326 $newContent = $content->updateRedirect( $target );
327
328 $this->assertTrue( $content->equals( $newContent ), "content should be unchanged" );
329
330 // test with actual redirect
331 $content = $this->newContent( "#REDIRECT [[Someplace]]" );
332 $newContent = $content->updateRedirect( $target );
333
334 $this->assertFalse( $content->equals( $newContent ), "content should have changed" );
335 $this->assertTrue( $newContent->isRedirect(), "new content should be a redirect" );
336
337 $this->assertEquals(
338 $target->getFullText(),
339 $newContent->getRedirectTarget()->getFullText()
340 );
341 }
342
346 public function testGetModel() {
347 $content = $this->newContent( "hello world." );
348
349 $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getModel() );
350 }
351
355 public function testGetContentHandler() {
356 $content = $this->newContent( "hello world." );
357
358 $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getContentHandler()->getModelID() );
359 }
360
361 public function testRedirectParserOption() {
362 $title = Title::newFromText( 'testRedirectParserOption' );
363
364 // Set up hook and its reporting variables
365 $wikitext = null;
366 $redirectTarget = null;
367 $this->mergeMwGlobalArrayValue( 'wgHooks', [
368 'InternalParseBeforeLinks' => [
369 function ( &$parser, &$text, &$stripState ) use ( &$wikitext, &$redirectTarget ) {
370 $wikitext = $text;
371 $redirectTarget = $parser->getOptions()->getRedirectTarget();
372 }
373 ]
374 ] );
375
376 // Test with non-redirect page
377 $wikitext = false;
378 $redirectTarget = false;
379 $content = $this->newContent( 'hello world.' );
380 $options = $content->getContentHandler()->makeParserOptions( 'canonical' );
381 $options->setRedirectTarget( $title );
382 $content->getParserOutput( $title, null, $options );
383 $this->assertEquals( 'hello world.', $wikitext,
384 'Wikitext passed to hook was not as expected'
385 );
386 $this->assertEquals( null, $redirectTarget, 'Redirect seen in hook was not null' );
387 $this->assertEquals( $title, $options->getRedirectTarget(),
388 'ParserOptions\' redirectTarget was changed'
389 );
390
391 // Test with a redirect page
392 $wikitext = false;
393 $redirectTarget = false;
394 $content = $this->newContent(
395 "#REDIRECT [[TestRedirectParserOption/redir]]\nhello redirect."
396 );
397 $options = $content->getContentHandler()->makeParserOptions( 'canonical' );
398 $content->getParserOutput( $title, null, $options );
399 $this->assertEquals(
400 'hello redirect.',
401 $wikitext,
402 'Wikitext passed to hook was not as expected'
403 );
404 $this->assertNotEquals(
405 null,
406 $redirectTarget,
407 'Redirect seen in hook was null' );
408 $this->assertEquals(
409 'TestRedirectParserOption/redir',
410 $redirectTarget->getFullText(),
411 'Redirect seen in hook was not the expected title'
412 );
413 $this->assertEquals(
414 null,
415 $options->getRedirectTarget(),
416 'ParserOptions\' redirectTarget was changed'
417 );
418 }
419
420 public static function dataEquals() {
421 return [
422 [ new WikitextContent( "hallo" ), null, false ],
423 [ new WikitextContent( "hallo" ), new WikitextContent( "hallo" ), true ],
424 [ new WikitextContent( "hallo" ), new JavaScriptContent( "hallo" ), false ],
425 [ new WikitextContent( "hallo" ), new TextContent( "hallo" ), false ],
426 [ new WikitextContent( "hallo" ), new WikitextContent( "HALLO" ), false ],
427 ];
428 }
429
430 public static function dataGetDeletionUpdates() {
431 return [
432 [ "WikitextContentTest_testGetSecondaryDataUpdates_1",
433 CONTENT_MODEL_WIKITEXT, "hello ''world''\n",
434 [ LinksDeletionUpdate::class => [] ]
435 ],
436 [ "WikitextContentTest_testGetSecondaryDataUpdates_2",
437 CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n",
438 [ LinksDeletionUpdate::class => [] ]
439 ],
440 // @todo more...?
441 ];
442 }
443}
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.
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:2001
usually copyright or history_copyright This message must be in HTML not wikitext if the section is included from a template to be included in the link
Definition hooks.txt:3023
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:2006
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:245