wiki.techinc.nl/tests/phpunit/includes/content/TextContentTest.php
Tim Starling 2c6c954e23 Abstract and refactor Tidy support
* Split tidy implementations into a class hierarchy
* Bring all tidy configuration into a single associative array and
  deprecate the old configuration.
* Remove $wgAlwaysUseTidy

This is preparatory to replacement of Tidy (T89331). I used the name
"Raggett" for things relating to Dave Raggett's Tidy, since if we use
"tidy" to mean the new abstract system as well as Raggett's tidy, it
gets confusing.

Change-Id: I77af1a16cbbb47fc226d05fb9aad56c58e8910b5
2015-09-10 20:18:52 -07:00

477 lines
11 KiB
PHP

<?php
/**
* @group ContentHandler
* @group Database
* ^--- needed, because we do need the database to test link updates
*/
class TextContentTest extends MediaWikiLangTestCase {
protected $context;
protected function setUp() {
parent::setUp();
// Anon user
$user = new User();
$user->setName( '127.0.0.1' );
$this->context = new RequestContext( new FauxRequest() );
$this->context->setTitle( Title::newFromText( 'Test' ) );
$this->context->setUser( $user );
$this->setMwGlobals( array(
'wgUser' => $user,
'wgTextModelsToParse' => array(
CONTENT_MODEL_WIKITEXT,
CONTENT_MODEL_CSS,
CONTENT_MODEL_JAVASCRIPT,
),
'wgUseTidy' => false,
'wgCapitalLinks' => true,
'wgHooks' => array(), // bypass hook ContentGetParserOutput that force custom rendering
) );
MWTidy::destroySingleton();
}
protected function tearDown() {
MWTidy::destroySingleton();
parent::tearDown();
}
public function newContent( $text ) {
return new TextContent( $text );
}
public static function dataGetParserOutput() {
return array(
array(
'TextContentTest_testGetParserOutput',
CONTENT_MODEL_TEXT,
"hello ''world'' & [[stuff]]\n", "hello ''world'' &amp; [[stuff]]",
array(
'Links' => array()
)
),
// TODO: more...?
);
}
/**
* @dataProvider dataGetParserOutput
* @covers TextContent::getParserOutput
*/
public function testGetParserOutput( $title, $model, $text, $expectedHtml,
$expectedFields = null
) {
$title = Title::newFromText( $title );
$content = ContentHandler::makeContent( $text, $title, $model );
$po = $content->getParserOutput( $title );
$html = $po->getText();
$html = preg_replace( '#<!--.*?-->#sm', '', $html ); // strip comments
$this->assertEquals( $expectedHtml, trim( $html ) );
if ( $expectedFields ) {
foreach ( $expectedFields as $field => $exp ) {
$f = 'get' . ucfirst( $field );
$v = call_user_func( array( $po, $f ) );
if ( is_array( $exp ) ) {
$this->assertArrayEquals( $exp, $v );
} else {
$this->assertEquals( $exp, $v );
}
}
}
// TODO: assert more properties
}
public static function dataPreSaveTransform() {
return array(
array(
#0: no signature resolution
'hello this is ~~~',
'hello this is ~~~',
),
array(
#1: rtrim
" Foo \n ",
' Foo',
),
);
}
/**
* @dataProvider dataPreSaveTransform
* @covers TextContent::preSaveTransform
*/
public function testPreSaveTransform( $text, $expected ) {
global $wgContLang;
$options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang );
$content = $this->newContent( $text );
$content = $content->preSaveTransform(
$this->context->getTitle(),
$this->context->getUser(),
$options
);
$this->assertEquals( $expected, $content->getNativeData() );
}
public static function dataPreloadTransform() {
return array(
array(
'hello this is ~~~',
'hello this is ~~~',
),
);
}
/**
* @dataProvider dataPreloadTransform
* @covers TextContent::preloadTransform
*/
public function testPreloadTransform( $text, $expected ) {
global $wgContLang;
$options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang );
$content = $this->newContent( $text );
$content = $content->preloadTransform( $this->context->getTitle(), $options );
$this->assertEquals( $expected, $content->getNativeData() );
}
public static function dataGetRedirectTarget() {
return array(
array( '#REDIRECT [[Test]]',
null,
),
);
}
/**
* @dataProvider dataGetRedirectTarget
* @covers TextContent::getRedirectTarget
*/
public function testGetRedirectTarget( $text, $expected ) {
$content = $this->newContent( $text );
$t = $content->getRedirectTarget();
if ( is_null( $expected ) ) {
$this->assertNull( $t, "text should not have generated a redirect target: $text" );
} else {
$this->assertEquals( $expected, $t->getPrefixedText() );
}
}
/**
* @dataProvider dataGetRedirectTarget
* @covers TextContent::isRedirect
*/
public function testIsRedirect( $text, $expected ) {
$content = $this->newContent( $text );
$this->assertEquals( !is_null( $expected ), $content->isRedirect() );
}
/**
* @todo Test needs database! Should be done by a test class in the Database group.
*/
/*
public function getRedirectChain() {
$text = $this->getNativeData();
return Title::newFromRedirectArray( $text );
}
*/
/**
* @todo Test needs database! Should be done by a test class in the Database group.
*/
/*
public function getUltimateRedirectTarget() {
$text = $this->getNativeData();
return Title::newFromRedirectRecurse( $text );
}
*/
public static function dataIsCountable() {
return array(
array( '',
null,
'any',
true
),
array( 'Foo',
null,
'any',
true
),
array( 'Foo',
null,
'comma',
false
),
array( 'Foo, bar',
null,
'comma',
false
),
);
}
/**
* @dataProvider dataIsCountable
* @group Database
* @covers TextContent::isCountable
*/
public function testIsCountable( $text, $hasLinks, $mode, $expected ) {
$this->setMwGlobals( 'wgArticleCountMethod', $mode );
$content = $this->newContent( $text );
$v = $content->isCountable( $hasLinks, $this->context->getTitle() );
$this->assertEquals(
$expected,
$v,
'isCountable() returned unexpected value ' . var_export( $v, true )
. ' instead of ' . var_export( $expected, true )
. " in mode `$mode` for text \"$text\""
);
}
public static function dataGetTextForSummary() {
return array(
array( "hello\nworld.",
16,
'hello world.',
),
array( 'hello world.',
8,
'hello...',
),
array( '[[hello world]].',
8,
'[[hel...',
),
);
}
/**
* @dataProvider dataGetTextForSummary
* @covers TextContent::getTextForSummary
*/
public function testGetTextForSummary( $text, $maxlength, $expected ) {
$content = $this->newContent( $text );
$this->assertEquals( $expected, $content->getTextForSummary( $maxlength ) );
}
/**
* @covers TextContent::getTextForSearchIndex
*/
public function testGetTextForSearchIndex() {
$content = $this->newContent( 'hello world.' );
$this->assertEquals( 'hello world.', $content->getTextForSearchIndex() );
}
/**
* @covers TextContent::copy
*/
public function testCopy() {
$content = $this->newContent( 'hello world.' );
$copy = $content->copy();
$this->assertTrue( $content->equals( $copy ), 'copy must be equal to original' );
$this->assertEquals( 'hello world.', $copy->getNativeData() );
}
/**
* @covers TextContent::getSize
*/
public function testGetSize() {
$content = $this->newContent( 'hello world.' );
$this->assertEquals( 12, $content->getSize() );
}
/**
* @covers TextContent::getNativeData
*/
public function testGetNativeData() {
$content = $this->newContent( 'hello world.' );
$this->assertEquals( 'hello world.', $content->getNativeData() );
}
/**
* @covers TextContent::getWikitextForTransclusion
*/
public function testGetWikitextForTransclusion() {
$content = $this->newContent( 'hello world.' );
$this->assertEquals( 'hello world.', $content->getWikitextForTransclusion() );
}
/**
* @covers TextContent::getModel
*/
public function testGetModel() {
$content = $this->newContent( "hello world." );
$this->assertEquals( CONTENT_MODEL_TEXT, $content->getModel() );
}
/**
* @covers TextContent::getContentHandler
*/
public function testGetContentHandler() {
$content = $this->newContent( "hello world." );
$this->assertEquals( CONTENT_MODEL_TEXT, $content->getContentHandler()->getModelID() );
}
public static function dataIsEmpty() {
return array(
array( '', true ),
array( ' ', false ),
array( '0', false ),
array( 'hallo welt.', false ),
);
}
/**
* @dataProvider dataIsEmpty
* @covers TextContent::isEmpty
*/
public function testIsEmpty( $text, $empty ) {
$content = $this->newContent( $text );
$this->assertEquals( $empty, $content->isEmpty() );
}
public static function dataEquals() {
return array(
array( new TextContent( "hallo" ), null, false ),
array( new TextContent( "hallo" ), new TextContent( "hallo" ), true ),
array( new TextContent( "hallo" ), new JavaScriptContent( "hallo" ), false ),
array( new TextContent( "hallo" ), new WikitextContent( "hallo" ), false ),
array( new TextContent( "hallo" ), new TextContent( "HALLO" ), false ),
);
}
/**
* @dataProvider dataEquals
* @covers TextContent::equals
*/
public function testEquals( Content $a, Content $b = null, $equal = false ) {
$this->assertEquals( $equal, $a->equals( $b ) );
}
public static function dataGetDeletionUpdates() {
return array(
array( "TextContentTest_testGetSecondaryDataUpdates_1",
CONTENT_MODEL_TEXT, "hello ''world''\n",
array()
),
array( "TextContentTest_testGetSecondaryDataUpdates_2",
CONTENT_MODEL_TEXT, "hello [[world test 21344]]\n",
array()
),
// TODO: more...?
);
}
/**
* @dataProvider dataGetDeletionUpdates
* @covers TextContent::getDeletionUpdates
*/
public function testDeletionUpdates( $title, $model, $text, $expectedStuff ) {
$ns = $this->getDefaultWikitextNS();
$title = Title::newFromText( $title, $ns );
$content = ContentHandler::makeContent( $text, $title, $model );
$page = WikiPage::factory( $title );
$page->doEditContent( $content, '' );
$updates = $content->getDeletionUpdates( $page );
// make updates accessible by class name
foreach ( $updates as $update ) {
$class = get_class( $update );
$updates[$class] = $update;
}
if ( !$expectedStuff ) {
$this->assertTrue( true ); // make phpunit happy
return;
}
foreach ( $expectedStuff as $class => $fieldValues ) {
$this->assertArrayHasKey( $class, $updates, "missing an update of type $class" );
$update = $updates[$class];
foreach ( $fieldValues as $field => $value ) {
$v = $update->$field; #if the field doesn't exist, just crash and burn
$this->assertEquals( $value, $v, "unexpected value for field $field in instance of $class" );
}
}
$page->doDeleteArticle( '' );
}
public static function provideConvert() {
return array(
array( // #0
'Hallo Welt',
CONTENT_MODEL_WIKITEXT,
'lossless',
'Hallo Welt'
),
array( // #1
'Hallo Welt',
CONTENT_MODEL_WIKITEXT,
'lossless',
'Hallo Welt'
),
array( // #1
'Hallo Welt',
CONTENT_MODEL_CSS,
'lossless',
'Hallo Welt'
),
array( // #1
'Hallo Welt',
CONTENT_MODEL_JAVASCRIPT,
'lossless',
'Hallo Welt'
),
);
}
/**
* @dataProvider provideConvert
* @covers TextContent::convert
*/
public function testConvert( $text, $model, $lossy, $expectedNative ) {
$content = $this->newContent( $text );
$converted = $content->convert( $model, $lossy );
if ( $expectedNative === false ) {
$this->assertFalse( $converted, "conversion to $model was expected to fail!" );
} else {
$this->assertInstanceOf( 'Content', $converted );
$this->assertEquals( $expectedNative, $converted->getNativeData() );
}
}
}