Merge "Show a tip at the end of the installer to prompt about extensions"
[lhc/web/wiklou.git] / tests / phpunit / includes / content / TextContentTest.php
1 <?php
2
3 /**
4 * @group ContentHandler
5 * @group Database
6 * ^--- needed, because we do need the database to test link updates
7 */
8 class TextContentTest extends MediaWikiLangTestCase {
9 protected $context;
10
11 protected function setUp() {
12 parent::setUp();
13
14 // Anon user
15 $user = new User();
16 $user->setName( '127.0.0.1' );
17
18 $this->setMwGlobals( array(
19 'wgUser' => $user,
20 'wgTextModelsToParse' => array(
21 CONTENT_MODEL_WIKITEXT,
22 CONTENT_MODEL_CSS,
23 CONTENT_MODEL_JAVASCRIPT,
24 ),
25 'wgUseTidy' => false,
26 'wgAlwaysUseTidy' => false,
27 ) );
28
29 $this->context = new RequestContext( new FauxRequest() );
30 $this->context->setTitle( Title::newFromText( 'Test' ) );
31 $this->context->setUser( $user );
32 }
33
34 public function newContent( $text ) {
35 return new TextContent( $text );
36 }
37
38 public static function dataGetParserOutput() {
39 return array(
40 array(
41 'TextContentTest_testGetParserOutput',
42 CONTENT_MODEL_TEXT,
43 "hello ''world'' & [[stuff]]\n", "hello ''world'' &amp; [[stuff]]",
44 array(
45 'Links' => array()
46 )
47 ),
48 // TODO: more...?
49 );
50 }
51
52 /**
53 * @dataProvider dataGetParserOutput
54 */
55 public function testGetParserOutput( $title, $model, $text, $expectedHtml, $expectedFields = null ) {
56 $title = Title::newFromText( $title );
57 $content = ContentHandler::makeContent( $text, $title, $model );
58
59 $po = $content->getParserOutput( $title );
60
61 $html = $po->getText();
62 $html = preg_replace( '#<!--.*?-->#sm', '', $html ); // strip comments
63
64 $this->assertEquals( $expectedHtml, trim( $html ) );
65
66 if ( $expectedFields ) {
67 foreach ( $expectedFields as $field => $exp ) {
68 $f = 'get' . ucfirst( $field );
69 $v = call_user_func( array( $po, $f ) );
70
71 if ( is_array( $exp ) ) {
72 $this->assertArrayEquals( $exp, $v );
73 } else {
74 $this->assertEquals( $exp, $v );
75 }
76 }
77 }
78
79 // TODO: assert more properties
80 }
81
82 public static function dataPreSaveTransform() {
83 return array(
84 array(
85 #0: no signature resolution
86 'hello this is ~~~',
87 'hello this is ~~~',
88 ),
89 array(
90 #1: rtrim
91 " Foo \n ",
92 ' Foo',
93 ),
94 );
95 }
96
97 /**
98 * @dataProvider dataPreSaveTransform
99 */
100 public function testPreSaveTransform( $text, $expected ) {
101 global $wgContLang;
102
103 $options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang );
104
105 $content = $this->newContent( $text );
106 $content = $content->preSaveTransform( $this->context->getTitle(), $this->context->getUser(), $options );
107
108 $this->assertEquals( $expected, $content->getNativeData() );
109 }
110
111 public static function dataPreloadTransform() {
112 return array(
113 array(
114 'hello this is ~~~',
115 'hello this is ~~~',
116 ),
117 );
118 }
119
120 /**
121 * @dataProvider dataPreloadTransform
122 */
123 public function testPreloadTransform( $text, $expected ) {
124 global $wgContLang;
125 $options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang );
126
127 $content = $this->newContent( $text );
128 $content = $content->preloadTransform( $this->context->getTitle(), $options );
129
130 $this->assertEquals( $expected, $content->getNativeData() );
131 }
132
133 public static function dataGetRedirectTarget() {
134 return array(
135 array( '#REDIRECT [[Test]]',
136 null,
137 ),
138 );
139 }
140
141 /**
142 * @dataProvider dataGetRedirectTarget
143 */
144 public function testGetRedirectTarget( $text, $expected ) {
145 $content = $this->newContent( $text );
146 $t = $content->getRedirectTarget();
147
148 if ( is_null( $expected ) ) {
149 $this->assertNull( $t, "text should not have generated a redirect target: $text" );
150 } else {
151 $this->assertEquals( $expected, $t->getPrefixedText() );
152 }
153 }
154
155 /**
156 * @dataProvider dataGetRedirectTarget
157 */
158 public function testIsRedirect( $text, $expected ) {
159 $content = $this->newContent( $text );
160
161 $this->assertEquals( !is_null( $expected ), $content->isRedirect() );
162 }
163
164 /**
165 * @todo: test needs database! Should be done by a test class in the Database group.
166 */
167 /*
168 public function getRedirectChain() {
169 $text = $this->getNativeData();
170 return Title::newFromRedirectArray( $text );
171 }
172 */
173
174 /**
175 * @todo: test needs database! Should be done by a test class in the Database group.
176 */
177 /*
178 public function getUltimateRedirectTarget() {
179 $text = $this->getNativeData();
180 return Title::newFromRedirectRecurse( $text );
181 }
182 */
183
184 public static function dataIsCountable() {
185 return array(
186 array( '',
187 null,
188 'any',
189 true
190 ),
191 array( 'Foo',
192 null,
193 'any',
194 true
195 ),
196 array( 'Foo',
197 null,
198 'comma',
199 false
200 ),
201 array( 'Foo, bar',
202 null,
203 'comma',
204 false
205 ),
206 );
207 }
208
209 /**
210 * @dataProvider dataIsCountable
211 * @group Database
212 */
213 public function testIsCountable( $text, $hasLinks, $mode, $expected ) {
214 $this->setMwGlobals( 'wgArticleCountMethod', $mode );
215
216 $content = $this->newContent( $text );
217
218 $v = $content->isCountable( $hasLinks, $this->context->getTitle() );
219
220 $this->assertEquals( $expected, $v, 'isCountable() returned unexpected value ' . var_export( $v, true )
221 . ' instead of ' . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
222 }
223
224 public static function dataGetTextForSummary() {
225 return array(
226 array( "hello\nworld.",
227 16,
228 'hello world.',
229 ),
230 array( 'hello world.',
231 8,
232 'hello...',
233 ),
234 array( '[[hello world]].',
235 8,
236 '[[hel...',
237 ),
238 );
239 }
240
241 /**
242 * @dataProvider dataGetTextForSummary
243 */
244 public function testGetTextForSummary( $text, $maxlength, $expected ) {
245 $content = $this->newContent( $text );
246
247 $this->assertEquals( $expected, $content->getTextForSummary( $maxlength ) );
248 }
249
250 public function testGetTextForSearchIndex() {
251 $content = $this->newContent( 'hello world.' );
252
253 $this->assertEquals( 'hello world.', $content->getTextForSearchIndex() );
254 }
255
256 public function testCopy() {
257 $content = $this->newContent( 'hello world.' );
258 $copy = $content->copy();
259
260 $this->assertTrue( $content->equals( $copy ), 'copy must be equal to original' );
261 $this->assertEquals( 'hello world.', $copy->getNativeData() );
262 }
263
264 public function testGetSize() {
265 $content = $this->newContent( 'hello world.' );
266
267 $this->assertEquals( 12, $content->getSize() );
268 }
269
270 public function testGetNativeData() {
271 $content = $this->newContent( 'hello world.' );
272
273 $this->assertEquals( 'hello world.', $content->getNativeData() );
274 }
275
276 public function testGetWikitextForTransclusion() {
277 $content = $this->newContent( 'hello world.' );
278
279 $this->assertEquals( 'hello world.', $content->getWikitextForTransclusion() );
280 }
281
282 public function testGetModel() {
283 $content = $this->newContent( "hello world." );
284
285 $this->assertEquals( CONTENT_MODEL_TEXT, $content->getModel() );
286 }
287
288 public function testGetContentHandler() {
289 $content = $this->newContent( "hello world." );
290
291 $this->assertEquals( CONTENT_MODEL_TEXT, $content->getContentHandler()->getModelID() );
292 }
293
294 public static function dataIsEmpty() {
295 return array(
296 array( '', true ),
297 array( ' ', false ),
298 array( '0', false ),
299 array( 'hallo welt.', false ),
300 );
301 }
302
303 /**
304 * @dataProvider dataIsEmpty
305 */
306 public function testIsEmpty( $text, $empty ) {
307 $content = $this->newContent( $text );
308
309 $this->assertEquals( $empty, $content->isEmpty() );
310 }
311
312 public static function dataEquals() {
313 return array(
314 array( new TextContent( "hallo" ), null, false ),
315 array( new TextContent( "hallo" ), new TextContent( "hallo" ), true ),
316 array( new TextContent( "hallo" ), new JavaScriptContent( "hallo" ), false ),
317 array( new TextContent( "hallo" ), new WikitextContent( "hallo" ), false ),
318 array( new TextContent( "hallo" ), new TextContent( "HALLO" ), false ),
319 );
320 }
321
322 /**
323 * @dataProvider dataEquals
324 */
325 public function testEquals( Content $a, Content $b = null, $equal = false ) {
326 $this->assertEquals( $equal, $a->equals( $b ) );
327 }
328
329 public static function dataGetDeletionUpdates() {
330 return array(
331 array( "TextContentTest_testGetSecondaryDataUpdates_1",
332 CONTENT_MODEL_TEXT, "hello ''world''\n",
333 array()
334 ),
335 array( "TextContentTest_testGetSecondaryDataUpdates_2",
336 CONTENT_MODEL_TEXT, "hello [[world test 21344]]\n",
337 array()
338 ),
339 // TODO: more...?
340 );
341 }
342
343 /**
344 * @dataProvider dataGetDeletionUpdates
345 */
346 public function testDeletionUpdates( $title, $model, $text, $expectedStuff ) {
347 $ns = $this->getDefaultWikitextNS();
348 $title = Title::newFromText( $title, $ns );
349
350 $content = ContentHandler::makeContent( $text, $title, $model );
351
352 $page = WikiPage::factory( $title );
353 $page->doEditContent( $content, '' );
354
355 $updates = $content->getDeletionUpdates( $page );
356
357 // make updates accessible by class name
358 foreach ( $updates as $update ) {
359 $class = get_class( $update );
360 $updates[$class] = $update;
361 }
362
363 if ( !$expectedStuff ) {
364 $this->assertTrue( true ); // make phpunit happy
365 return;
366 }
367
368 foreach ( $expectedStuff as $class => $fieldValues ) {
369 $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" );
370
371 $update = $updates[$class];
372
373 foreach ( $fieldValues as $field => $value ) {
374 $v = $update->$field; #if the field doesn't exist, just crash and burn
375 $this->assertEquals( $value, $v, "unexpected value for field $field in instance of $class" );
376 }
377 }
378
379 $page->doDeleteArticle( '' );
380 }
381
382 public static function provideConvert() {
383 return array(
384 array( // #0
385 'Hallo Welt',
386 CONTENT_MODEL_WIKITEXT,
387 'lossless',
388 'Hallo Welt'
389 ),
390 array( // #1
391 'Hallo Welt',
392 CONTENT_MODEL_WIKITEXT,
393 'lossless',
394 'Hallo Welt'
395 ),
396 array( // #1
397 'Hallo Welt',
398 CONTENT_MODEL_CSS,
399 'lossless',
400 'Hallo Welt'
401 ),
402 array( // #1
403 'Hallo Welt',
404 CONTENT_MODEL_JAVASCRIPT,
405 'lossless',
406 'Hallo Welt'
407 ),
408 );
409 }
410
411 /**
412 * @dataProvider provideConvert
413 */
414 public function testConvert( $text, $model, $lossy, $expectedNative ) {
415 $content = $this->newContent( $text );
416
417 $converted = $content->convert( $model, $lossy );
418
419 if ( $expectedNative === false ) {
420 $this->assertFalse( $converted, "conversion to $model was expected to fail!" );
421 } else {
422 $this->assertInstanceOf( 'Content', $converted );
423 $this->assertEquals( $expectedNative, $converted->getNativeData() );
424 }
425 }
426 }