3 use MediaWiki\MediaWikiServices
;
6 * @group ContentHandler
8 * ^--- needed, because we do need the database to test link updates
10 class TextContentTest
extends MediaWikiLangTestCase
{
13 protected function setUp() {
16 // trigger purging of all page related tables
17 $this->tablesUsed
[] = 'page';
18 $this->tablesUsed
[] = 'revision';
22 $user->setName( '127.0.0.1' );
24 $this->context
= new RequestContext( new FauxRequest() );
25 $this->context
->setTitle( Title
::newFromText( 'Test' ) );
26 $this->context
->setUser( $user );
28 $this->setMwGlobals( [
30 'wgTextModelsToParse' => [
31 CONTENT_MODEL_WIKITEXT
,
33 CONTENT_MODEL_JAVASCRIPT
,
35 'wgTidyConfig' => [ 'driver' => 'RemexHtml' ],
36 'wgCapitalLinks' => true,
37 'wgHooks' => [], // bypass hook ContentGetParserOutput that force custom rendering
40 MWTidy
::destroySingleton();
43 protected function tearDown() {
44 MWTidy
::destroySingleton();
52 public function newContent( $text ) {
53 return new TextContent( $text );
56 public static function dataGetParserOutput() {
59 'TextContentTest_testGetParserOutput',
61 "hello ''world'' & [[stuff]]\n", "hello ''world'' & [[stuff]]",
71 * @dataProvider dataGetParserOutput
72 * @covers TextContent::getParserOutput
74 public function testGetParserOutput( $title, $model, $text, $expectedHtml,
75 $expectedFields = null
77 $title = Title
::newFromText( $title );
78 $content = ContentHandler
::makeContent( $text, $title, $model );
80 $po = $content->getParserOutput( $title );
82 $html = $po->getText();
83 $html = preg_replace( '#<!--.*?-->#sm', '', $html ); // strip comments
85 $this->assertEquals( $expectedHtml, trim( $html ) );
87 if ( $expectedFields ) {
88 foreach ( $expectedFields as $field => $exp ) {
89 $f = 'get' . ucfirst( $field );
90 $v = call_user_func( [ $po, $f ] );
92 if ( is_array( $exp ) ) {
93 $this->assertArrayEquals( $exp, $v );
95 $this->assertEquals( $exp, $v );
100 // TODO: assert more properties
103 public static function dataPreSaveTransform() {
106 # 0: no signature resolution
116 # 2: newline normalization
117 "LF\n\nCRLF\r\n\r\nCR\r\rEND",
118 "LF\n\nCRLF\n\nCR\n\nEND",
124 * @dataProvider dataPreSaveTransform
125 * @covers TextContent::preSaveTransform
127 public function testPreSaveTransform( $text, $expected ) {
128 $options = ParserOptions
::newFromUserAndLang( $this->context
->getUser(),
129 MediaWikiServices
::getInstance()->getContentLanguage() );
131 $content = $this->newContent( $text );
132 $content = $content->preSaveTransform(
133 $this->context
->getTitle(),
134 $this->context
->getUser(),
138 $this->assertEquals( $expected, $content->getText() );
141 public static function dataPreloadTransform() {
151 * @dataProvider dataPreloadTransform
152 * @covers TextContent::preloadTransform
154 public function testPreloadTransform( $text, $expected ) {
155 $options = ParserOptions
::newFromUserAndLang( $this->context
->getUser(),
156 MediaWikiServices
::getInstance()->getContentLanguage() );
158 $content = $this->newContent( $text );
159 $content = $content->preloadTransform( $this->context
->getTitle(), $options );
161 $this->assertEquals( $expected, $content->getText() );
164 public static function dataGetRedirectTarget() {
166 [ '#REDIRECT [[Test]]',
173 * @dataProvider dataGetRedirectTarget
174 * @covers TextContent::getRedirectTarget
176 public function testGetRedirectTarget( $text, $expected ) {
177 $content = $this->newContent( $text );
178 $t = $content->getRedirectTarget();
180 if ( is_null( $expected ) ) {
181 $this->assertNull( $t, "text should not have generated a redirect target: $text" );
183 $this->assertEquals( $expected, $t->getPrefixedText() );
188 * @dataProvider dataGetRedirectTarget
189 * @covers TextContent::isRedirect
191 public function testIsRedirect( $text, $expected ) {
192 $content = $this->newContent( $text );
194 $this->assertEquals( !is_null( $expected ), $content->isRedirect() );
197 public static function dataIsCountable() {
213 * @dataProvider dataIsCountable
214 * @covers TextContent::isCountable
216 public function testIsCountable( $text, $hasLinks, $mode, $expected ) {
217 $this->setMwGlobals( 'wgArticleCountMethod', $mode );
219 $content = $this->newContent( $text );
221 $v = $content->isCountable( $hasLinks, $this->context
->getTitle() );
226 'isCountable() returned unexpected value ' . var_export( $v, true )
227 . ' instead of ' . var_export( $expected, true )
228 . " in mode `$mode` for text \"$text\""
232 public static function dataGetTextForSummary() {
242 [ '[[hello world]].',
250 * @dataProvider dataGetTextForSummary
251 * @covers TextContent::getTextForSummary
253 public function testGetTextForSummary( $text, $maxlength, $expected ) {
254 $content = $this->newContent( $text );
256 $this->assertEquals( $expected, $content->getTextForSummary( $maxlength ) );
260 * @covers TextContent::getTextForSearchIndex
262 public function testGetTextForSearchIndex() {
263 $content = $this->newContent( 'hello world.' );
265 $this->assertEquals( 'hello world.', $content->getTextForSearchIndex() );
269 * @covers TextContent::copy
271 public function testCopy() {
272 $content = $this->newContent( 'hello world.' );
273 $copy = $content->copy();
275 $this->assertTrue( $content->equals( $copy ), 'copy must be equal to original' );
276 $this->assertEquals( 'hello world.', $copy->getText() );
280 * @covers TextContent::getSize
282 public function testGetSize() {
283 $content = $this->newContent( 'hello world.' );
285 $this->assertEquals( 12, $content->getSize() );
289 * @covers TextContent::getText
291 public function testGetText() {
292 $content = $this->newContent( 'hello world.' );
294 $this->assertEquals( 'hello world.', $content->getText() );
298 * @covers TextContent::getNativeData
300 public function testGetNativeData() {
301 $content = $this->newContent( 'hello world.' );
303 $this->assertEquals( 'hello world.', $content->getText() );
307 * @covers TextContent::getWikitextForTransclusion
309 public function testGetWikitextForTransclusion() {
310 $content = $this->newContent( 'hello world.' );
312 $this->assertEquals( 'hello world.', $content->getWikitextForTransclusion() );
316 * @covers TextContent::getModel
318 public function testGetModel() {
319 $content = $this->newContent( "hello world." );
321 $this->assertEquals( CONTENT_MODEL_TEXT
, $content->getModel() );
325 * @covers TextContent::getContentHandler
327 public function testGetContentHandler() {
328 $content = $this->newContent( "hello world." );
330 $this->assertEquals( CONTENT_MODEL_TEXT
, $content->getContentHandler()->getModelID() );
333 public static function dataIsEmpty() {
338 [ 'hallo welt.', false ],
343 * @dataProvider dataIsEmpty
344 * @covers TextContent::isEmpty
346 public function testIsEmpty( $text, $empty ) {
347 $content = $this->newContent( $text );
349 $this->assertEquals( $empty, $content->isEmpty() );
352 public static function dataEquals() {
354 [ new TextContent( "hallo" ), null, false ],
355 [ new TextContent( "hallo" ), new TextContent( "hallo" ), true ],
356 [ new TextContent( "hallo" ), new JavaScriptContent( "hallo" ), false ],
357 [ new TextContent( "hallo" ), new WikitextContent( "hallo" ), false ],
358 [ new TextContent( "hallo" ), new TextContent( "HALLO" ), false ],
363 * @dataProvider dataEquals
364 * @covers TextContent::equals
366 public function testEquals( Content
$a, Content
$b = null, $equal = false ) {
367 $this->assertEquals( $equal, $a->equals( $b ) );
370 public static function dataGetDeletionUpdates() {
373 CONTENT_MODEL_TEXT
, "hello ''world''\n",
377 CONTENT_MODEL_TEXT
, "hello [[world test 21344]]\n",
385 * @dataProvider dataGetDeletionUpdates
386 * @covers TextContent::getDeletionUpdates
388 public function testDeletionUpdates( $model, $text, $expectedStuff ) {
389 $page = $this->getNonexistingTestPage( get_class( $this ) . '-' . $this->getName() );
390 $title = $page->getTitle();
392 $content = ContentHandler
::makeContent( $text, $title, $model );
393 $page->doEditContent( $content, '' );
395 $updates = $content->getDeletionUpdates( $page );
397 // make updates accessible by class name
398 foreach ( $updates as $update ) {
399 $class = get_class( $update );
400 $updates[$class] = $update;
403 foreach ( $expectedStuff as $class => $fieldValues ) {
404 $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" );
406 $update = $updates[$class];
408 foreach ( $fieldValues as $field => $value ) {
409 $v = $update->$field; # if the field doesn't exist, just crash and burn
410 $this->assertEquals( $value, $v, "unexpected value for field $field in instance of $class" );
414 // make phpunit happy even if $expectedStuff was empty
415 $this->assertTrue( true );
418 public static function provideConvert() {
422 CONTENT_MODEL_WIKITEXT
,
428 CONTENT_MODEL_WIKITEXT
,
440 CONTENT_MODEL_JAVASCRIPT
,
448 * @dataProvider provideConvert
449 * @covers TextContent::convert
451 public function testConvert( $text, $model, $lossy, $expectedNative ) {
452 $content = $this->newContent( $text );
454 /** @var TextContent $converted */
455 $converted = $content->convert( $model, $lossy );
457 if ( $expectedNative === false ) {
458 $this->assertFalse( $converted, "conversion to $model was expected to fail!" );
460 $this->assertInstanceOf( Content
::class, $converted );
461 $this->assertEquals( $expectedNative, $converted->getText() );
466 * @covers TextContent::normalizeLineEndings
467 * @dataProvider provideNormalizeLineEndings
469 public function testNormalizeLineEndings( $input, $expected ) {
470 $this->assertEquals( $expected, TextContent
::normalizeLineEndings( $input ) );
473 public static function provideNormalizeLineEndings() {
491 * @covers TextContent::__construct
492 * @covers TextContentHandler::serializeContent
494 public function testSerialize() {
495 $cnt = $this->newContent( 'testing text' );
497 $this->assertSame( 'testing text', $cnt->serialize() );