MediaWiki  REL1_31
TextContentTest.php
Go to the documentation of this file.
1 <?php
2 
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->context = new RequestContext( new FauxRequest() );
19  $this->context->setTitle( Title::newFromText( 'Test' ) );
20  $this->context->setUser( $user );
21 
22  $this->setMwGlobals( [
23  'wgUser' => $user,
24  'wgTextModelsToParse' => [
28  ],
29  'wgUseTidy' => false,
30  'wgCapitalLinks' => true,
31  'wgHooks' => [], // bypass hook ContentGetParserOutput that force custom rendering
32  ] );
33 
35  }
36 
37  protected function tearDown() {
39  parent::tearDown();
40  }
41 
42  public function newContent( $text ) {
43  return new TextContent( $text );
44  }
45 
46  public static function dataGetParserOutput() {
47  return [
48  [
49  'TextContentTest_testGetParserOutput',
51  "hello ''world'' & [[stuff]]\n", "hello ''world'' &amp; [[stuff]]",
52  [
53  'Links' => []
54  ]
55  ],
56  // TODO: more...?
57  ];
58  }
59 
64  public function testGetParserOutput( $title, $model, $text, $expectedHtml,
65  $expectedFields = null
66  ) {
68  $content = ContentHandler::makeContent( $text, $title, $model );
69 
70  $po = $content->getParserOutput( $title );
71 
72  $html = $po->getText();
73  $html = preg_replace( '#<!--.*?-->#sm', '', $html ); // strip comments
74 
75  $this->assertEquals( $expectedHtml, trim( $html ) );
76 
77  if ( $expectedFields ) {
78  foreach ( $expectedFields as $field => $exp ) {
79  $f = 'get' . ucfirst( $field );
80  $v = call_user_func( [ $po, $f ] );
81 
82  if ( is_array( $exp ) ) {
83  $this->assertArrayEquals( $exp, $v );
84  } else {
85  $this->assertEquals( $exp, $v );
86  }
87  }
88  }
89 
90  // TODO: assert more properties
91  }
92 
93  public static function dataPreSaveTransform() {
94  return [
95  [
96  # 0: no signature resolution
97  'hello this is ~~~',
98  'hello this is ~~~',
99  ],
100  [
101  # 1: rtrim
102  " Foo \n ",
103  ' Foo',
104  ],
105  [
106  # 2: newline normalization
107  "LF\n\nCRLF\r\n\r\nCR\r\rEND",
108  "LF\n\nCRLF\n\nCR\n\nEND",
109  ],
110  ];
111  }
112 
117  public function testPreSaveTransform( $text, $expected ) {
119 
120  $options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang );
121 
122  $content = $this->newContent( $text );
123  $content = $content->preSaveTransform(
124  $this->context->getTitle(),
125  $this->context->getUser(),
126  $options
127  );
128 
129  $this->assertEquals( $expected, $content->getNativeData() );
130  }
131 
132  public static function dataPreloadTransform() {
133  return [
134  [
135  'hello this is ~~~',
136  'hello this is ~~~',
137  ],
138  ];
139  }
140 
145  public function testPreloadTransform( $text, $expected ) {
147  $options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang );
148 
149  $content = $this->newContent( $text );
150  $content = $content->preloadTransform( $this->context->getTitle(), $options );
151 
152  $this->assertEquals( $expected, $content->getNativeData() );
153  }
154 
155  public static function dataGetRedirectTarget() {
156  return [
157  [ '#REDIRECT [[Test]]',
158  null,
159  ],
160  ];
161  }
162 
167  public function testGetRedirectTarget( $text, $expected ) {
168  $content = $this->newContent( $text );
169  $t = $content->getRedirectTarget();
170 
171  if ( is_null( $expected ) ) {
172  $this->assertNull( $t, "text should not have generated a redirect target: $text" );
173  } else {
174  $this->assertEquals( $expected, $t->getPrefixedText() );
175  }
176  }
177 
182  public function testIsRedirect( $text, $expected ) {
183  $content = $this->newContent( $text );
184 
185  $this->assertEquals( !is_null( $expected ), $content->isRedirect() );
186  }
187 
188  public static function dataIsCountable() {
189  return [
190  [ '',
191  null,
192  'any',
193  true
194  ],
195  [ 'Foo',
196  null,
197  'any',
198  true
199  ],
200  ];
201  }
202 
207  public function testIsCountable( $text, $hasLinks, $mode, $expected ) {
208  $this->setMwGlobals( 'wgArticleCountMethod', $mode );
209 
210  $content = $this->newContent( $text );
211 
212  $v = $content->isCountable( $hasLinks, $this->context->getTitle() );
213 
214  $this->assertEquals(
215  $expected,
216  $v,
217  'isCountable() returned unexpected value ' . var_export( $v, true )
218  . ' instead of ' . var_export( $expected, true )
219  . " in mode `$mode` for text \"$text\""
220  );
221  }
222 
223  public static function dataGetTextForSummary() {
224  return [
225  [ "hello\nworld.",
226  16,
227  'hello world.',
228  ],
229  [ 'hello world.',
230  8,
231  'hello...',
232  ],
233  [ '[[hello world]].',
234  8,
235  '[[hel...',
236  ],
237  ];
238  }
239 
244  public function testGetTextForSummary( $text, $maxlength, $expected ) {
245  $content = $this->newContent( $text );
246 
247  $this->assertEquals( $expected, $content->getTextForSummary( $maxlength ) );
248  }
249 
253  public function testGetTextForSearchIndex() {
254  $content = $this->newContent( 'hello world.' );
255 
256  $this->assertEquals( 'hello world.', $content->getTextForSearchIndex() );
257  }
258 
262  public function testCopy() {
263  $content = $this->newContent( 'hello world.' );
264  $copy = $content->copy();
265 
266  $this->assertTrue( $content->equals( $copy ), 'copy must be equal to original' );
267  $this->assertEquals( 'hello world.', $copy->getNativeData() );
268  }
269 
273  public function testGetSize() {
274  $content = $this->newContent( 'hello world.' );
275 
276  $this->assertEquals( 12, $content->getSize() );
277  }
278 
282  public function testGetNativeData() {
283  $content = $this->newContent( 'hello world.' );
284 
285  $this->assertEquals( 'hello world.', $content->getNativeData() );
286  }
287 
291  public function testGetWikitextForTransclusion() {
292  $content = $this->newContent( 'hello world.' );
293 
294  $this->assertEquals( 'hello world.', $content->getWikitextForTransclusion() );
295  }
296 
300  public function testGetModel() {
301  $content = $this->newContent( "hello world." );
302 
303  $this->assertEquals( CONTENT_MODEL_TEXT, $content->getModel() );
304  }
305 
309  public function testGetContentHandler() {
310  $content = $this->newContent( "hello world." );
311 
312  $this->assertEquals( CONTENT_MODEL_TEXT, $content->getContentHandler()->getModelID() );
313  }
314 
315  public static function dataIsEmpty() {
316  return [
317  [ '', true ],
318  [ ' ', false ],
319  [ '0', false ],
320  [ 'hallo welt.', false ],
321  ];
322  }
323 
328  public function testIsEmpty( $text, $empty ) {
329  $content = $this->newContent( $text );
330 
331  $this->assertEquals( $empty, $content->isEmpty() );
332  }
333 
334  public static function dataEquals() {
335  return [
336  [ new TextContent( "hallo" ), null, false ],
337  [ new TextContent( "hallo" ), new TextContent( "hallo" ), true ],
338  [ new TextContent( "hallo" ), new JavaScriptContent( "hallo" ), false ],
339  [ new TextContent( "hallo" ), new WikitextContent( "hallo" ), false ],
340  [ new TextContent( "hallo" ), new TextContent( "HALLO" ), false ],
341  ];
342  }
343 
348  public function testEquals( Content $a, Content $b = null, $equal = false ) {
349  $this->assertEquals( $equal, $a->equals( $b ) );
350  }
351 
352  public static function dataGetDeletionUpdates() {
353  return [
354  [ "TextContentTest_testGetSecondaryDataUpdates_1",
355  CONTENT_MODEL_TEXT, "hello ''world''\n",
356  []
357  ],
358  [ "TextContentTest_testGetSecondaryDataUpdates_2",
359  CONTENT_MODEL_TEXT, "hello [[world test 21344]]\n",
360  []
361  ],
362  // TODO: more...?
363  ];
364  }
365 
370  public function testDeletionUpdates( $title, $model, $text, $expectedStuff ) {
371  $ns = $this->getDefaultWikitextNS();
372  $title = Title::newFromText( $title, $ns );
373 
374  $content = ContentHandler::makeContent( $text, $title, $model );
375 
376  $page = WikiPage::factory( $title );
377  $page->doEditContent( $content, '' );
378 
379  $updates = $content->getDeletionUpdates( $page );
380 
381  // make updates accessible by class name
382  foreach ( $updates as $update ) {
383  $class = get_class( $update );
384  $updates[$class] = $update;
385  }
386 
387  if ( !$expectedStuff ) {
388  $this->assertTrue( true ); // make phpunit happy
389  return;
390  }
391 
392  foreach ( $expectedStuff as $class => $fieldValues ) {
393  $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" );
394 
395  $update = $updates[$class];
396 
397  foreach ( $fieldValues as $field => $value ) {
398  $v = $update->$field; # if the field doesn't exist, just crash and burn
399  $this->assertEquals( $value, $v, "unexpected value for field $field in instance of $class" );
400  }
401  }
402 
403  $page->doDeleteArticle( '' );
404  }
405 
406  public static function provideConvert() {
407  return [
408  [ // #0
409  'Hallo Welt',
410  CONTENT_MODEL_WIKITEXT,
411  'lossless',
412  'Hallo Welt'
413  ],
414  [ // #1
415  'Hallo Welt',
416  CONTENT_MODEL_WIKITEXT,
417  'lossless',
418  'Hallo Welt'
419  ],
420  [ // #1
421  'Hallo Welt',
422  CONTENT_MODEL_CSS,
423  'lossless',
424  'Hallo Welt'
425  ],
426  [ // #1
427  'Hallo Welt',
428  CONTENT_MODEL_JAVASCRIPT,
429  'lossless',
430  'Hallo Welt'
431  ],
432  ];
433  }
434 
439  public function testConvert( $text, $model, $lossy, $expectedNative ) {
440  $content = $this->newContent( $text );
441 
442  $converted = $content->convert( $model, $lossy );
443 
444  if ( $expectedNative === false ) {
445  $this->assertFalse( $converted, "conversion to $model was expected to fail!" );
446  } else {
447  $this->assertInstanceOf( Content::class, $converted );
448  $this->assertEquals( $expectedNative, $converted->getNativeData() );
449  }
450  }
451 
456  public function testNormalizeLineEndings( $input, $expected ) {
457  $this->assertEquals( $expected, TextContent::normalizeLineEndings( $input ) );
458  }
459 
460  public static function provideNormalizeLineEndings() {
461  return [
462  [
463  "Foo\r\nbar",
464  "Foo\nbar"
465  ],
466  [
467  "Foo\rbar",
468  "Foo\nbar"
469  ],
470  [
471  "Foobar\n ",
472  "Foobar"
473  ]
474  ];
475  }
476 
477 }
TextContentTest\dataGetTextForSummary
static dataGetTextForSummary()
Definition: TextContentTest.php:223
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:247
TextContentTest\testGetTextForSummary
testGetTextForSummary( $text, $maxlength, $expected)
dataGetTextForSummary TextContent::getTextForSummary
Definition: TextContentTest.php:244
FauxRequest
WebRequest clone which takes values from a provided array.
Definition: FauxRequest.php:33
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:273
MediaWikiTestCase\assertArrayEquals
assertArrayEquals(array $expected, array $actual, $ordered=false, $named=false)
Assert that two arrays are equal.
Definition: MediaWikiTestCase.php:1771
TextContentTest\testPreSaveTransform
testPreSaveTransform( $text, $expected)
dataPreSaveTransform TextContent::preSaveTransform
Definition: TextContentTest.php:117
$html
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 an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses & $html
Definition: hooks.txt:2013
TextContentTest\testPreloadTransform
testPreloadTransform( $text, $expected)
dataPreloadTransform TextContent::preloadTransform
Definition: TextContentTest.php:145
TextContentTest\dataGetRedirectTarget
static dataGetRedirectTarget()
Definition: TextContentTest.php:155
CONTENT_MODEL_CSS
const CONTENT_MODEL_CSS
Definition: Defines.php:247
TextContentTest\setUp
setUp()
Definition: TextContentTest.php:11
TextContentTest
ContentHandler Database ^— needed, because we do need the database to test link updates.
Definition: TextContentTest.php:8
TextContentTest\testIsCountable
testIsCountable( $text, $hasLinks, $mode, $expected)
dataIsCountable TextContent::isCountable
Definition: TextContentTest.php:207
TextContentTest\testGetNativeData
testGetNativeData()
TextContent::getNativeData.
Definition: TextContentTest.php:282
User
User
Definition: All_system_messages.txt:425
CONTENT_MODEL_WIKITEXT
const CONTENT_MODEL_WIKITEXT
Definition: Defines.php:245
TextContentTest\dataGetParserOutput
static dataGetParserOutput()
Definition: TextContentTest.php:46
true
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
php
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:37
TextContentTest\testEquals
testEquals(Content $a, Content $b=null, $equal=false)
dataEquals TextContent::equals
Definition: TextContentTest.php:348
TextContentTest\dataEquals
static dataEquals()
Definition: TextContentTest.php:334
WikiPage\factory
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:115
ParserOptions\newFromUserAndLang
static newFromUserAndLang(User $user, Language $lang)
Get a ParserOptions object from a given user and language.
Definition: ParserOptions.php:992
TextContentTest\testGetParserOutput
testGetParserOutput( $title, $model, $text, $expectedHtml, $expectedFields=null)
dataGetParserOutput TextContent::getParserOutput
Definition: TextContentTest.php:64
MediaWikiTestCase\setMwGlobals
setMwGlobals( $pairs, $value=null)
Sets a global, maintaining a stashed version of the previous global to be restored in tearDown.
Definition: MediaWikiTestCase.php:678
TextContentTest\$context
$context
Definition: TextContentTest.php:9
TextContentTest\testGetModel
testGetModel()
TextContent::getModel.
Definition: TextContentTest.php:300
TextContentTest\newContent
newContent( $text)
Definition: TextContentTest.php:42
$title
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:964
TextContentTest\testGetTextForSearchIndex
testGetTextForSearchIndex()
TextContent::getTextForSearchIndex.
Definition: TextContentTest.php:253
MediaWikiTestCase\getDefaultWikitextNS
getDefaultWikitextNS()
Returns the ID of a namespace that defaults to Wikitext.
Definition: MediaWikiTestCase.php:1912
TextContentTest\dataPreloadTransform
static dataPreloadTransform()
Definition: TextContentTest.php:132
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:95
RequestContext
Group all the pieces relevant to the context of a request into one instance.
Definition: RequestContext.php:32
WikitextContent
Content object for wiki text pages.
Definition: WikitextContent.php:33
TextContentTest\dataIsEmpty
static dataIsEmpty()
Definition: TextContentTest.php:315
ContentHandler\makeContent
static makeContent( $text, Title $title=null, $modelId=null, $format=null)
Convenience function for creating a Content object from a given textual representation.
Definition: ContentHandler.php:129
JavaScriptContent
Content for JavaScript pages.
Definition: JavaScriptContent.php:33
$options
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
TextContentTest\testIsEmpty
testIsEmpty( $text, $empty)
dataIsEmpty TextContent::isEmpty
Definition: TextContentTest.php:328
Content\equals
equals(Content $that=null)
Returns true if this Content objects is conceptually equivalent to the given Content object.
TextContentTest\testGetRedirectTarget
testGetRedirectTarget( $text, $expected)
dataGetRedirectTarget TextContent::getRedirectTarget
Definition: TextContentTest.php:167
$value
$value
Definition: styleTest.css.php:45
TextContentTest\dataPreSaveTransform
static dataPreSaveTransform()
Definition: TextContentTest.php:93
TextContentTest\dataIsCountable
static dataIsCountable()
Definition: TextContentTest.php:188
TextContentTest\tearDown
tearDown()
Definition: TextContentTest.php:37
TextContentTest\testGetSize
testGetSize()
TextContent::getSize.
Definition: TextContentTest.php:273
MediaWikiLangTestCase
Base class that store and restore the Language objects.
Definition: MediaWikiLangTestCase.php:6
TextContentTest\dataGetDeletionUpdates
static dataGetDeletionUpdates()
Definition: TextContentTest.php:352
TextContent
Content object implementation for representing flat text.
Definition: TextContent.php:35
Content
Base interface for content objects.
Definition: Content.php:34
TextContentTest\testGetWikitextForTransclusion
testGetWikitextForTransclusion()
TextContent::getWikitextForTransclusion.
Definition: TextContentTest.php:291
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:22
CONTENT_MODEL_JAVASCRIPT
const CONTENT_MODEL_JAVASCRIPT
Definition: Defines.php:246
$t
$t
Definition: testCompression.php:69
TextContentTest\testDeletionUpdates
testDeletionUpdates( $title, $model, $text, $expectedStuff)
dataGetDeletionUpdates TextContent::getDeletionUpdates
Definition: TextContentTest.php:370
CONTENT_MODEL_TEXT
const CONTENT_MODEL_TEXT
Definition: Defines.php:248
TextContentTest\testCopy
testCopy()
TextContent::copy.
Definition: TextContentTest.php:262
MWTidy\destroySingleton
static destroySingleton()
Destroy the current singleton instance.
Definition: MWTidy.php:142
false
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:187
TextContentTest\testGetContentHandler
testGetContentHandler()
TextContent::getContentHandler.
Definition: TextContentTest.php:309
TextContentTest\testIsRedirect
testIsRedirect( $text, $expected)
dataGetRedirectTarget TextContent::isRedirect
Definition: TextContentTest.php:182
$wgContLang
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the content language as $wgContLang
Definition: design.txt:57