From 4ac9fa081a7c045f6a9f1cfc529d82423f485b2e Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Sun, 8 Dec 2013 09:55:49 +0100 Subject: Update to MediaWiki 1.22.0 --- .../phpunit/includes/parser/MagicVariableTest.php | 107 ++++--- .../includes/parser/MediaWikiParserTest.php | 108 ++++++- tests/phpunit/includes/parser/NewParserTest.php | 347 ++++++++++++--------- .../phpunit/includes/parser/ParserMethodsTest.php | 48 ++- tests/phpunit/includes/parser/ParserOutputTest.php | 12 +- .../phpunit/includes/parser/ParserPreloadTest.php | 18 +- tests/phpunit/includes/parser/PreprocessorTest.php | 38 ++- tests/phpunit/includes/parser/TagHooksTest.php | 8 +- tests/phpunit/includes/parser/TidyTest.php | 44 +++ 9 files changed, 503 insertions(+), 227 deletions(-) create mode 100644 tests/phpunit/includes/parser/TidyTest.php (limited to 'tests/phpunit/includes/parser') diff --git a/tests/phpunit/includes/parser/MagicVariableTest.php b/tests/phpunit/includes/parser/MagicVariableTest.php index dfcdafde..c2c97c01 100644 --- a/tests/phpunit/includes/parser/MagicVariableTest.php +++ b/tests/phpunit/includes/parser/MagicVariableTest.php @@ -9,11 +9,13 @@ * @author Antoine Musso * @copyright Copyright © 2011, Antoine Musso * @file + * @todo covers tags */ -/** */ class MagicVariableTest extends MediaWikiTestCase { - /** Will contains a parser object*/ + /** + * @var Parser + */ private $testParser = null; /** @@ -51,11 +53,31 @@ class MagicVariableTest extends MediaWikiTestCase { $this->testParser->setTitle( $title ); } - /** destroy parser (TODO: is it really neded?)*/ - protected function tearDown() { - unset( $this->testParser ); + /** + * @param int $num upper limit for numbers + * @return array of numbers from 1 up to $num + */ + private static function createProviderUpTo( $num ) { + $ret = array(); + for ( $i = 1; $i <= $num; $i++ ) { + $ret[] = array( $i ); + } + + return $ret; + } + + /** + * @return array of months numbers (as an integer) + */ + public static function provideMonths() { + return self::createProviderUpTo( 12 ); + } - parent::tearDown(); + /** + * @return array of days numbers (as an integer) + */ + public static function provideDays() { + return self::createProviderUpTo( 31 ); } ############### TESTS ############################################# @@ -65,100 +87,101 @@ class MagicVariableTest extends MediaWikiTestCase { # day - /** @dataProvider MediaWikiProvide::Days */ - function testCurrentdayIsUnPadded( $day ) { + /** @dataProvider provideDays */ + public function testCurrentdayIsUnPadded( $day ) { $this->assertUnPadded( 'currentday', $day ); } - /** @dataProvider MediaWikiProvide::Days */ - function testCurrentdaytwoIsZeroPadded( $day ) { + /** @dataProvider provideDays */ + public function testCurrentdaytwoIsZeroPadded( $day ) { $this->assertZeroPadded( 'currentday2', $day ); } - /** @dataProvider MediaWikiProvide::Days */ - function testLocaldayIsUnPadded( $day ) { + /** @dataProvider provideDays */ + public function testLocaldayIsUnPadded( $day ) { $this->assertUnPadded( 'localday', $day ); } - /** @dataProvider MediaWikiProvide::Days */ - function testLocaldaytwoIsZeroPadded( $day ) { + /** @dataProvider provideDays */ + public function testLocaldaytwoIsZeroPadded( $day ) { $this->assertZeroPadded( 'localday2', $day ); } # month - /** @dataProvider MediaWikiProvide::Months */ - function testCurrentmonthIsZeroPadded( $month ) { + /** @dataProvider provideMonths */ + public function testCurrentmonthIsZeroPadded( $month ) { $this->assertZeroPadded( 'currentmonth', $month ); } - /** @dataProvider MediaWikiProvide::Months */ - function testCurrentmonthoneIsUnPadded( $month ) { + /** @dataProvider provideMonths */ + public function testCurrentmonthoneIsUnPadded( $month ) { $this->assertUnPadded( 'currentmonth1', $month ); } - /** @dataProvider MediaWikiProvide::Months */ - function testLocalmonthIsZeroPadded( $month ) { + /** @dataProvider provideMonths */ + public function testLocalmonthIsZeroPadded( $month ) { $this->assertZeroPadded( 'localmonth', $month ); } - /** @dataProvider MediaWikiProvide::Months */ - function testLocalmonthoneIsUnPadded( $month ) { + /** @dataProvider provideMonths */ + public function testLocalmonthoneIsUnPadded( $month ) { $this->assertUnPadded( 'localmonth1', $month ); } - # revision day - /** @dataProvider MediaWikiProvide::Days */ - function testRevisiondayIsUnPadded( $day ) { + /** @dataProvider provideDays */ + public function testRevisiondayIsUnPadded( $day ) { $this->assertUnPadded( 'revisionday', $day ); } - /** @dataProvider MediaWikiProvide::Days */ - function testRevisiondaytwoIsZeroPadded( $day ) { + /** @dataProvider provideDays */ + public function testRevisiondaytwoIsZeroPadded( $day ) { $this->assertZeroPadded( 'revisionday2', $day ); } # revision month - /** @dataProvider MediaWikiProvide::Months */ - function testRevisionmonthIsZeroPadded( $month ) { + /** @dataProvider provideMonths */ + public function testRevisionmonthIsZeroPadded( $month ) { $this->assertZeroPadded( 'revisionmonth', $month ); } - /** @dataProvider MediaWikiProvide::Months */ - function testRevisionmonthoneIsUnPadded( $month ) { + /** @dataProvider provideMonths */ + public function testRevisionmonthoneIsUnPadded( $month ) { $this->assertUnPadded( 'revisionmonth1', $month ); } /** * Rough tests for {{SERVERNAME}} magic word * Bug 31176 + * @group Database + * @dataProvider provideDataServernameFromDifferentProtocols */ - function testServernameFromDifferentProtocols() { - global $wgServer; - $saved_wgServer = $wgServer; + public function testServernameFromDifferentProtocols( $server ) { + $this->setMwGlobals( 'wgServer', $server ); - $wgServer = 'http://localhost/'; - $this->assertMagic( 'localhost', 'servername' ); - $wgServer = 'https://localhost/'; - $this->assertMagic( 'localhost', 'servername' ); - $wgServer = '//localhost/'; # bug 31176 $this->assertMagic( 'localhost', 'servername' ); + } - $wgServer = $saved_wgServer; + public static function provideDataServernameFromDifferentProtocols() { + return array( + array( 'http://localhost/' ), + array( 'https://localhost/' ), + array( '//localhost/' ), # bug 31176 + ); } ############### HELPERS ############################################ /** assertion helper expecting a magic output which is zero padded */ - PUBLIC function assertZeroPadded( $magic, $value ) { + public function assertZeroPadded( $magic, $value ) { $this->assertMagicPadding( $magic, $value, '%02d' ); } /** assertion helper expecting a magic output which is unpadded */ - PUBLIC function assertUnPadded( $magic, $value ) { + public function assertUnPadded( $magic, $value ) { $this->assertMagicPadding( $magic, $value, '%d' ); } diff --git a/tests/phpunit/includes/parser/MediaWikiParserTest.php b/tests/phpunit/includes/parser/MediaWikiParserTest.php index 067a7c4e..c120ca34 100644 --- a/tests/phpunit/includes/parser/MediaWikiParserTest.php +++ b/tests/phpunit/includes/parser/MediaWikiParserTest.php @@ -1,5 +1,5 @@ "\\'", '\\' => '\\\\' ) ); /* This used to be ucfirst( basename( dirname( $filename ) ) ) * and then was ucfirst( basename( $filename, '.txt' ) * but that didn't work with names like foo.tests.txt */ - $className = str_replace( '.', '_', ucfirst( $testsName ) ); - - eval( "/** @group Database\n@group Parser\n*/ class $className extends NewParserTest { protected \$file = '" . strtr( $filename, array( "'" => "\\'", '\\' => '\\\\' ) ) . "'; } " ); + $parserTestClassName = str_replace( '.', '_', ucfirst( $testsName ) ); + $parserTestClassDefinition = <<addTestSuite( new ReflectionClass ( $parserTester ) ); + eval( $parserTestClassDefinition ); + self::debug( "Adding test class $parserTestClassName" ); + $suite->addTestSuite( $parserTestClassName ); } return $suite; } + + /** + * Write $msg under log group 'tests-parser' + * @param string $msg Message to log + */ + protected static function debug( $msg ) { + return wfDebugLog( 'tests-parser', wfGetCaller() . ' ' . $msg ); + } } diff --git a/tests/phpunit/includes/parser/NewParserTest.php b/tests/phpunit/includes/parser/NewParserTest.php index bf6931a1..eac4de5c 100644 --- a/tests/phpunit/includes/parser/NewParserTest.php +++ b/tests/phpunit/includes/parser/NewParserTest.php @@ -6,6 +6,8 @@ * @group Database * @group Parser * @group Stub + * + * @todo covers tags */ class NewParserTest extends MediaWikiTestCase { static protected $articles = array(); // Array of test articles defined by the tests @@ -19,7 +21,6 @@ class NewParserTest extends MediaWikiTestCase { public $runParsoid = false; public $regex = ''; public $showProgress = true; - public $savedInitialGlobals = array(); public $savedWeirdGlobals = array(); public $savedGlobals = array(); public $hooks = array(); @@ -32,8 +33,13 @@ class NewParserTest extends MediaWikiTestCase { protected $file = false; + public static function setUpBeforeClass() { + // Inject ParserTest well-known interwikis + ParserTest::setupInterwikis(); + } + protected function setUp() { - global $wgNamespaceProtection, $wgNamespaceAliases; + global $wgNamespaceAliases, $wgContLang; global $wgHooks, $IP; parent::setUp(); @@ -52,11 +58,16 @@ class NewParserTest extends MediaWikiTestCase { $tmpGlobals['wgLanguageCode'] = 'en'; $tmpGlobals['wgContLang'] = Language::factory( 'en' ); + $tmpGlobals['wgSitename'] = 'MediaWiki'; + $tmpGlobals['wgServer'] = 'http://example.org'; $tmpGlobals['wgScript'] = '/index.php'; $tmpGlobals['wgScriptPath'] = '/'; $tmpGlobals['wgArticlePath'] = '/wiki/$1'; - $tmpGlobals['wgStyleSheetPath'] = '/skins'; + $tmpGlobals['wgActionPaths'] = array(); + $tmpGlobals['wgVariantArticlePath'] = false; + $tmpGlobals['wgExtensionAssetsPath'] = '/extensions'; $tmpGlobals['wgStylePath'] = '/skins'; + $tmpGlobals['wgEnableUploads'] = true; $tmpGlobals['wgThumbnailScriptPath'] = false; $tmpGlobals['wgLocalFileRepo'] = array( 'class' => 'LocalRepo', @@ -67,51 +78,81 @@ class NewParserTest extends MediaWikiTestCase { 'backend' => 'local-backend' ); $tmpGlobals['wgForeignFileRepos'] = array(); + $tmpGlobals['wgDefaultExternalStore'] = array(); $tmpGlobals['wgEnableParserCache'] = false; - $tmpGlobals['wgHooks'] = $wgHooks; + $tmpGlobals['wgCapitalLinks'] = true; + $tmpGlobals['wgNoFollowLinks'] = true; + $tmpGlobals['wgNoFollowDomainExceptions'] = array(); + $tmpGlobals['wgExternalLinkTarget'] = false; + $tmpGlobals['wgThumbnailScriptPath'] = false; + $tmpGlobals['wgUseImageResize'] = true; + $tmpGlobals['wgAllowExternalImages'] = true; + $tmpGlobals['wgRawHtml'] = false; + $tmpGlobals['wgUseTidy'] = false; + $tmpGlobals['wgAlwaysUseTidy'] = false; + $tmpGlobals['wgWellFormedXml'] = true; + $tmpGlobals['wgAllowMicrodataAttributes'] = true; + $tmpGlobals['wgExperimentalHtmlIds'] = false; + $tmpGlobals['wgAdaptiveMessageCache'] = true; + $tmpGlobals['wgUseDatabaseMessages'] = true; + $tmpGlobals['wgLocaltimezone'] = 'UTC'; $tmpGlobals['wgDeferredUpdateList'] = array(); - $tmpGlobals['wgMemc'] = wfGetMainCache(); - $tmpGlobals['messageMemc'] = wfGetMessageCacheStorage(); - $tmpGlobals['parserMemc'] = wfGetParserCacheStorage(); + $tmpGlobals['wgGroupPermissions'] = array( + '*' => array( + 'createaccount' => true, + 'read' => true, + 'edit' => true, + 'createpage' => true, + 'createtalk' => true, + ) ); + $tmpGlobals['wgNamespaceProtection'] = array( NS_MEDIAWIKI => 'editinterface' ); - // $tmpGlobals['wgContLang'] = new StubContLang; - $tmpGlobals['wgUser'] = new User; - $context = new RequestContext(); - $tmpGlobals['wgLang'] = $context->getLanguage(); - $tmpGlobals['wgOut'] = $context->getOutput(); - $tmpGlobals['wgParser'] = new StubObject( 'wgParser', $GLOBALS['wgParserConf']['class'], array( $GLOBALS['wgParserConf'] ) ); - $tmpGlobals['wgRequest'] = $context->getRequest(); + $tmpGlobals['wgParser'] = new StubObject( + 'wgParser', $GLOBALS['wgParserConf']['class'], + array( $GLOBALS['wgParserConf'] ) ); + + $tmpGlobals['wgFileExtensions'][] = 'svg'; + $tmpGlobals['wgSVGConverter'] = 'rsvg'; + $tmpGlobals['wgSVGConverters']['rsvg'] = + '$path/rsvg-convert -w $width -h $height $input -o $output'; if ( $GLOBALS['wgStyleDirectory'] === false ) { $tmpGlobals['wgStyleDirectory'] = "$IP/skins"; } + # Replace all media handlers with a mock. We do not need to generate + # actual thumbnails to do parser testing, we only care about receiving + # a ThumbnailImage properly initialized. + global $wgMediaHandlers; + foreach ( $wgMediaHandlers as $type => $handler ) { + $tmpGlobals['wgMediaHandlers'][$type] = 'MockBitmapHandler'; + } + // Vector images have to be handled slightly differently + $tmpGlobals['wgMediaHandlers']['image/svg+xml'] = 'MockSvgHandler'; - foreach ( $tmpGlobals as $var => $val ) { - if ( array_key_exists( $var, $GLOBALS ) ) { - $this->savedInitialGlobals[$var] = $GLOBALS[$var]; - } + $tmpHooks = $wgHooks; + $tmpHooks['ParserTestParser'][] = 'ParserTestParserHook::setup'; + $tmpHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp'; + $tmpGlobals['wgHooks'] = $tmpHooks; + # add a namespace shadowing a interwiki link, to test + # proper precedence when resolving links. (bug 51680) + $tmpGlobals['wgExtraNamespaces'] = array( 100 => 'MemoryAlpha' ); - $GLOBALS[$var] = $val; - } + $this->setMwGlobals( $tmpGlobals ); - $this->savedWeirdGlobals['mw_namespace_protection'] = $wgNamespaceProtection[NS_MEDIAWIKI]; $this->savedWeirdGlobals['image_alias'] = $wgNamespaceAliases['Image']; $this->savedWeirdGlobals['image_talk_alias'] = $wgNamespaceAliases['Image_talk']; - $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; $wgNamespaceAliases['Image'] = NS_FILE; $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; + + MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache + $wgContLang->resetNamespaces(); # reset namespace cache } protected function tearDown() { - foreach ( $this->savedInitialGlobals as $var => $val ) { - $GLOBALS[$var] = $val; - } + global $wgNamespaceAliases, $wgContLang; - global $wgNamespaceProtection, $wgNamespaceAliases; - - $wgNamespaceProtection[NS_MEDIAWIKI] = $this->savedWeirdGlobals['mw_namespace_protection']; $wgNamespaceAliases['Image'] = $this->savedWeirdGlobals['image_alias']; $wgNamespaceAliases['Image_talk'] = $this->savedWeirdGlobals['image_talk_alias']; @@ -119,67 +160,34 @@ class NewParserTest extends MediaWikiTestCase { RepoGroup::destroySingleton(); FileBackendGroup::destroySingleton(); + // Remove temporary pages from the link cache + LinkCache::singleton()->clear(); + + // Restore message cache (temporary pages and $wgUseDatabaseMessages) + MessageCache::destroyInstance(); + parent::tearDown(); + + MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache + $wgContLang->resetNamespaces(); # reset namespace cache + } + + public static function tearDownAfterClass() { + ParserTest::tearDownInterwikis(); + parent::tearDownAfterClass(); } function addDBData() { $this->tablesUsed[] = 'site_stats'; - $this->tablesUsed[] = 'interwiki'; # disabled for performance #$this->tablesUsed[] = 'image'; - # Hack: insert a few Wikipedia in-project interwiki prefixes, - # for testing inter-language links - $this->db->insert( 'interwiki', array( - array( 'iw_prefix' => 'wikipedia', - 'iw_url' => 'http://en.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 0 ), - array( 'iw_prefix' => 'meatball', - 'iw_url' => 'http://www.usemod.com/cgi-bin/mb.pl?$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 0 ), - array( 'iw_prefix' => 'zh', - 'iw_url' => 'http://zh.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 1 ), - array( 'iw_prefix' => 'es', - 'iw_url' => 'http://es.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 1 ), - array( 'iw_prefix' => 'fr', - 'iw_url' => 'http://fr.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 1 ), - array( 'iw_prefix' => 'ru', - 'iw_url' => 'http://ru.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 1 ), - /** - * @todo Fixme! Why are we inserting duplicate data here? Shouldn't - * need this IGNORE or shouldn't need the insert at all. - */ - ), __METHOD__, array( 'IGNORE' ) - ); - # Update certain things in site_stats $this->db->insert( 'site_stats', array( 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ), __METHOD__ ); - # Reinitialise the LocalisationCache to match the database state - Language::getLocalisationCache()->unloadAll(); - - # Clear the message cache - MessageCache::singleton()->clear(); - $user = User::newFromId( 0 ); LinkCache::singleton()->clear(); # Avoids the odd failure at creating the nullRevision @@ -187,6 +195,10 @@ class NewParserTest extends MediaWikiTestCase { # We will upload the actual files later. Note that if anything causes LocalFile::load() # to be triggered before then, it will break via maybeUpgrade() setting the fileExists # member to false and storing it in cache. + # note that the size/width/height/bits/etc of the file + # are actually set by inspecting the file itself; the arguments + # to recordUpload2 have no effect. That said, we try to make things + # match up so it is less confusing to readers of the code & tests. $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.jpg' ) ); if ( !$this->db->selectField( 'image', '1', array( 'img_name' => $image->getName() ) ) ) { $image->recordUpload2( @@ -194,19 +206,39 @@ class NewParserTest extends MediaWikiTestCase { 'Upload of some lame file', 'Some lame file', array( - 'size' => 12345, + 'size' => 7881, 'width' => 1941, 'height' => 220, - 'bits' => 24, + 'bits' => 8, 'media_type' => MEDIATYPE_BITMAP, 'mime' => 'image/jpeg', 'metadata' => serialize( array() ), - 'sha1' => wfBaseConvert( '', 16, 36, 31 ), + 'sha1' => wfBaseConvert( '1', 16, 36, 31 ), 'fileExists' => true ), $this->db->timestamp( '20010115123500' ), $user ); } + $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Thumb.png' ) ); + if ( !$this->db->selectField( 'image', '1', array( 'img_name' => $image->getName() ) ) ) { + $image->recordUpload2( + '', // archive name + 'Upload of some lame thumbnail', + 'Some lame thumbnail', + array( + 'size' => 22589, + 'width' => 135, + 'height' => 135, + 'bits' => 8, + 'media_type' => MEDIATYPE_BITMAP, + 'mime' => 'image/png', + 'metadata' => serialize( array() ), + 'sha1' => wfBaseConvert( '2', 16, 36, 31 ), + 'fileExists' => true ), + $this->db->timestamp( '20130225203040' ), $user + ); + } + # This image will be blacklisted in [[MediaWiki:Bad image list]] $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Bad.jpg' ) ); if ( !$this->db->selectField( 'image', '1', array( 'img_name' => $image->getName() ) ) ) { @@ -222,11 +254,25 @@ class NewParserTest extends MediaWikiTestCase { 'media_type' => MEDIATYPE_BITMAP, 'mime' => 'image/jpeg', 'metadata' => serialize( array() ), - 'sha1' => wfBaseConvert( '', 16, 36, 31 ), + 'sha1' => wfBaseConvert( '3', 16, 36, 31 ), 'fileExists' => true ), $this->db->timestamp( '20010115123500' ), $user ); } + $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.svg' ) ); + if ( !$this->db->selectField( 'image', '1', array( 'img_name' => $image->getName() ) ) ) { + $image->recordUpload2( '', 'Upload of some lame SVG', 'Some lame SVG', array( + 'size' => 12345, + 'width' => 200, + 'height' => 200, + 'bits' => 24, + 'media_type' => MEDIATYPE_DRAWING, + 'mime' => 'image/svg+xml', + 'metadata' => serialize( array() ), + 'sha1' => wfBaseConvert( '', 16, 36, 31 ), + 'fileExists' => true + ), $this->db->timestamp( '20010115123500' ), $user ); + } } //ParserTest setup/teardown functions @@ -265,7 +311,10 @@ class NewParserTest extends MediaWikiTestCase { $backend = self::$backendToUse; } } else { - $backend = new FSFileBackend( array( + # Replace with a mock. We do not care about generating real + # files on the filesystem, just need to expose the file + # informations. + $backend = new MockFileBackend( array( 'name' => 'local-backend', 'lockManager' => 'nullLockManager', 'containerPaths' => array( @@ -276,12 +325,6 @@ class NewParserTest extends MediaWikiTestCase { } $settings = array( - 'wgServer' => 'http://example.org', - 'wgScript' => '/index.php', - 'wgScriptPath' => '/', - 'wgArticlePath' => '/wiki/$1', - 'wgExtensionAssetsPath' => '/extensions', - 'wgActionPaths' => array(), 'wgLocalFileRepo' => array( 'class' => 'LocalRepo', 'name' => 'local', @@ -291,47 +334,16 @@ class NewParserTest extends MediaWikiTestCase { 'backend' => $backend ), 'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ), - 'wgStylePath' => '/skins', - 'wgStyleSheetPath' => '/skins', - 'wgSitename' => 'MediaWiki', 'wgLanguageCode' => $lang, 'wgDBprefix' => $this->db->getType() != 'oracle' ? 'unittest_' : 'ut_', - 'wgRawHtml' => isset( $opts['rawhtml'] ), - 'wgLang' => null, - 'wgContLang' => null, + 'wgRawHtml' => self::getOptionValue( 'wgRawHtml', $opts, false ), 'wgNamespacesWithSubpages' => array( NS_MAIN => isset( $opts['subpage'] ) ), + 'wgAllowExternalImages' => self::getOptionValue( 'wgAllowExternalImages', $opts, true ), 'wgMaxTocLevel' => $maxtoclevel, - 'wgCapitalLinks' => true, - 'wgNoFollowLinks' => true, - 'wgNoFollowDomainExceptions' => array(), - 'wgThumbnailScriptPath' => false, - 'wgUseImageResize' => true, - 'wgUseTeX' => isset( $opts['math'] ), + 'wgUseTeX' => isset( $opts['math'] ) || isset( $opts['texvc'] ), 'wgMathDirectory' => $uploadDir . '/math', - 'wgLocaltimezone' => 'UTC', - 'wgAllowExternalImages' => true, - 'wgUseTidy' => false, 'wgDefaultLanguageVariant' => $variant, - 'wgVariantArticlePath' => false, - 'wgGroupPermissions' => array( '*' => array( - 'createaccount' => true, - 'read' => true, - 'edit' => true, - 'createpage' => true, - 'createtalk' => true, - ) ), - 'wgNamespaceProtection' => array( NS_MEDIAWIKI => 'editinterface' ), - 'wgDefaultExternalStore' => array(), - 'wgForeignFileRepos' => array(), 'wgLinkHolderBatchSize' => $linkHolderBatchSize, - 'wgExperimentalHtmlIds' => false, - 'wgExternalLinkTarget' => false, - 'wgAlwaysUseTidy' => false, - 'wgHtml5' => true, - 'wgWellFormedXml' => true, - 'wgAllowMicrodataAttributes' => true, - 'wgAdaptiveMessageCache' => true, - 'wgUseDatabaseMessages' => true, ); if ( $config ) { @@ -349,6 +361,15 @@ class NewParserTest extends MediaWikiTestCase { /** @since 1.20 */ wfRunHooks( 'ParserTestGlobals', array( &$settings ) ); + $langObj = Language::factory( $lang ); + $settings['wgContLang'] = $langObj; + $settings['wgLang'] = $langObj; + + $context = new RequestContext(); + $settings['wgOut'] = $context->getOutput(); + $settings['wgUser'] = $context->getUser(); + $settings['wgRequest'] = $context->getRequest(); + foreach ( $settings as $var => $val ) { if ( array_key_exists( $var, $GLOBALS ) ) { $this->savedGlobals[$var] = $GLOBALS[$var]; @@ -357,21 +378,9 @@ class NewParserTest extends MediaWikiTestCase { $GLOBALS[$var] = $val; } - $langObj = Language::factory( $lang ); - $GLOBALS['wgContLang'] = $langObj; - $context = new RequestContext(); - $GLOBALS['wgLang'] = $context->getLanguage(); - - $GLOBALS['wgMemc'] = new EmptyBagOStuff; - $GLOBALS['wgOut'] = $context->getOutput(); - $GLOBALS['wgUser'] = $context->getUser(); - - global $wgHooks; - - $wgHooks['ParserTestParser'][] = 'ParserTestParserHook::setup'; - $wgHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp'; - MagicWord::clearCache(); + + # The entries saved into RepoGroup cache with previous globals will be wrong. RepoGroup::destroySingleton(); FileBackendGroup::destroySingleton(); @@ -381,9 +390,6 @@ class NewParserTest extends MediaWikiTestCase { # Publish the articles after we have the final language set $this->publishTestArticles(); - # The entries saved into RepoGroup cache with previous globals will be wrong. - RepoGroup::destroySingleton(); - FileBackendGroup::destroySingleton(); MessageCache::destroyInstance(); return $context; @@ -408,6 +414,7 @@ class NewParserTest extends MediaWikiTestCase { // wfDebug( "Creating upload directory $dir\n" ); if ( file_exists( $dir ) ) { wfDebug( "Already exists!\n" ); + return $dir; } @@ -429,10 +436,27 @@ class NewParserTest extends MediaWikiTestCase { $backend->store( array( 'src' => "$IP/skins/monobook/headbg.jpg", 'dst' => "$base/local-public/3/3a/Foobar.jpg" ) ); + $backend->prepare( array( 'dir' => "$base/local-public/e/ea" ) ); + $backend->store( array( + 'src' => "$IP/skins/monobook/wiki.png", 'dst' => "$base/local-public/e/ea/Thumb.png" + ) ); $backend->prepare( array( 'dir' => "$base/local-public/0/09" ) ); $backend->store( array( 'src' => "$IP/skins/monobook/headbg.jpg", 'dst' => "$base/local-public/0/09/Bad.jpg" ) ); + + // No helpful SVG file to copy, so make one ourselves + $tmpDir = wfTempDir(); + $tempFsFile = new TempFSFile( "$tmpDir/Foobar.svg" ); + $tempFsFile->autocollect(); // destroy file when $tempFsFile leaves scope + file_put_contents( "$tmpDir/Foobar.svg", + '' . + 'Foo' ); + + $backend->prepare( array( 'dir' => "$base/local-public/f/ff" ) ); + $backend->quickStore( array( + 'src' => "$tmpDir/Foobar.svg", 'dst' => "$base/local-public/f/ff/Foobar.svg" + ) ); } /** @@ -445,9 +469,6 @@ class NewParserTest extends MediaWikiTestCase { foreach ( $this->savedGlobals as $var => $val ) { $GLOBALS[$var] = $val; } - - RepoGroup::destroySingleton(); - LinkCache::singleton()->clear(); } /** @@ -458,6 +479,12 @@ class NewParserTest extends MediaWikiTestCase { return; } + $backend = RepoGroup::singleton()->getLocalRepo()->getBackend(); + if ( $backend instanceof MockFileBackend ) { + # In memory backend, so dont bother cleaning them up. + return; + } + $base = $this->getBaseDir(); // delete the files first, then the dirs. self::deleteFiles( @@ -478,8 +505,17 @@ class NewParserTest extends MediaWikiTestCase { "$base/local-thumb/3/3a/Foobar.jpg/70px-Foobar.jpg", "$base/local-thumb/3/3a/Foobar.jpg/960px-Foobar.jpg", + "$base/local-public/e/ea/Thumb.png", + "$base/local-public/0/09/Bad.jpg", - "$base/local-thumb/0/09/Bad.jpg", + + "$base/local-public/f/ff/Foobar.svg", + "$base/local-thumb/f/ff/Foobar.svg/180px-Foobar.svg.jpg", + "$base/local-thumb/f/ff/Foobar.svg/270px-Foobar.svg.jpg", + "$base/local-thumb/f/ff/Foobar.svg/360px-Foobar.svg.jpg", + "$base/local-thumb/f/ff/Foobar.svg/langde-180px-Foobar.svg.jpg", + "$base/local-thumb/f/ff/Foobar.svg/langde-270px-Foobar.svg.jpg", + "$base/local-thumb/f/ff/Foobar.svg/langde-360px-Foobar.svg.jpg", "$base/local-public/math/f/a/5/fa50b8b616463173474302ca3e63586b.png", ) @@ -514,6 +550,7 @@ class NewParserTest extends MediaWikiTestCase { global $wgParserTestFiles; $this->file = $wgParserTestFiles[0]; } + return new TestFileIterator( $this->file, $this ); } @@ -537,7 +574,7 @@ class NewParserTest extends MediaWikiTestCase { if ( !$this->isWikitextNS( NS_MAIN ) ) { // parser tests frequently assume that the main namespace contains wikitext. - // @todo: When setting up pages, force the content model. Only skip if + // @todo When setting up pages, force the content model. Only skip if // $wgtContentModelUseDB is false. $this->markTestSkipped( "Main namespace does not support wikitext," . "skipping parser test: $desc" ); @@ -563,6 +600,20 @@ class NewParserTest extends MediaWikiTestCase { $title = Title::newFromText( $titleText ); + # Parser test requiring math. Make sure texvc is executable + # or just skip such tests. + if ( isset( $opts['math'] ) || isset( $opts['texvc'] ) ) { + global $wgTexvc; + + if ( !isset( $wgTexvc ) ) { + $this->markTestSkipped( "SKIPPED: \$wgTexvc is not set" ); + } elseif ( !is_executable( $wgTexvc ) ) { + $this->markTestSkipped( "SKIPPED: texvc binary does not exist" + . " or is not executable.\n" + . "Current configuration is:\n\$wgTexvc = '$wgTexvc'" ); + } + } + if ( isset( $opts['pst'] ) ) { $out = $parser->preSaveTransform( $input, $title, $user, $options ); } elseif ( isset( $opts['msg'] ) ) { @@ -577,9 +628,10 @@ class NewParserTest extends MediaWikiTestCase { } elseif ( isset( $opts['comment'] ) ) { $out = Linker::formatComment( $input, $title, $local ); } elseif ( isset( $opts['preload'] ) ) { - $out = $parser->getpreloadText( $input, $title, $options ); + $out = $parser->getPreloadText( $input, $title, $options ); } else { $output = $parser->parse( $input, $title, $options, true, true, 1337 ); + $output->setTOCEnabled( !isset( $opts['notoc'] ) ); $out = $output->getText(); if ( isset( $opts['showtitle'] ) ) { @@ -621,7 +673,7 @@ class NewParserTest extends MediaWikiTestCase { * * @group ParserFuzz */ - function testFuzzTests() { + public function testFuzzTests() { global $wgParserTestFiles; $files = $wgParserTestFiles; @@ -666,7 +718,9 @@ class NewParserTest extends MediaWikiTestCase { } catch ( Exception $exception ) { $input_dump = sprintf( "string(%d) \"%s\"\n", strlen( $input ), $input ); - $this->assertTrue( false, "Test $id, fuzz seed {$this->fuzzSeed}. \n\nInput: $input_dump\n\nError: {$exception->getMessage()}\n\nBacktrace: {$exception->getTraceAsString()}" ); + $this->assertTrue( false, "Test $id, fuzz seed {$this->fuzzSeed}. \n\n" . + "Input: $input_dump\n\nError: {$exception->getMessage()}\n\n" . + "Backtrace: {$exception->getTraceAsString()}" ); } $this->teardownGlobals(); @@ -688,7 +742,6 @@ class NewParserTest extends MediaWikiTestCase { } $id++; - } } @@ -882,6 +935,7 @@ class NewParserTest extends MediaWikiTestCase { } } } + return $opts; } @@ -893,6 +947,7 @@ class NewParserTest extends MediaWikiTestCase { if ( substr( $opt, 0, 2 ) == '[[' ) { return substr( $opt, 2, -2 ); } + return $opt; } diff --git a/tests/phpunit/includes/parser/ParserMethodsTest.php b/tests/phpunit/includes/parser/ParserMethodsTest.php index 50fe0e4d..e5c5cb21 100644 --- a/tests/phpunit/includes/parser/ParserMethodsTest.php +++ b/tests/phpunit/includes/parser/ParserMethodsTest.php @@ -15,6 +15,7 @@ class ParserMethodsTest extends MediaWikiLangTestCase { /** * @dataProvider providePreSaveTransform + * @covers Parser::preSaveTransform */ public function testPreSaveTransform( $text, $expected ) { global $wgParser; @@ -28,6 +29,9 @@ class ParserMethodsTest extends MediaWikiLangTestCase { $this->assertEquals( $expected, $text ); } + /** + * @covers Parser::callParserFunction + */ public function testCallParserFunction() { global $wgParser; @@ -45,5 +49,47 @@ class ParserMethodsTest extends MediaWikiLangTestCase { ), $ret, 'callParserFunction works for {{#tag:pre|foo|style=margin-left: 1.6em}}' ); } - // TODO: Add tests for cleanSig() / cleanSigInSig(), getSection(), replaceSection(), getPreloadText() + /** + * @covers Parser::parse + * @covers ParserOutput::getSections + */ + public function testGetSections() { + global $wgParser; + + $title = Title::newFromText( str_replace( '::', '__', __METHOD__ ) ); + $out = $wgParser->parse( "==foo==\n

bar

\n==baz==\n", $title, new ParserOptions() ); + $this->assertSame( array( + array( + 'toclevel' => 1, + 'level' => '2', + 'line' => 'foo', + 'number' => '1', + 'index' => '1', + 'fromtitle' => $title->getPrefixedDBkey(), + 'byteoffset' => 0, + 'anchor' => 'foo', + ), + array( + 'toclevel' => 1, + 'level' => '2', + 'line' => 'bar', + 'number' => '2', + 'index' => '', + 'fromtitle' => false, + 'byteoffset' => null, + 'anchor' => 'bar', + ), + array( + 'toclevel' => 1, + 'level' => '2', + 'line' => 'baz', + 'number' => '3', + 'index' => '2', + 'fromtitle' => $title->getPrefixedDBkey(), + 'byteoffset' => 21, + 'anchor' => 'baz', + ), + ), $out->getSections(), 'getSections() with proper value when

is used' ); + } + //@Todo Add tests for cleanSig() / cleanSigInSig(), getSection(), replaceSection(), getPreloadText() } diff --git a/tests/phpunit/includes/parser/ParserOutputTest.php b/tests/phpunit/includes/parser/ParserOutputTest.php index 68f77ab5..c73666da 100644 --- a/tests/phpunit/includes/parser/ParserOutputTest.php +++ b/tests/phpunit/includes/parser/ParserOutputTest.php @@ -2,7 +2,7 @@ class ParserOutputTest extends MediaWikiTestCase { - function dataIsLinkInternal() { + public static function provideIsLinkInternal() { return array( // Different domains array( false, 'http://example.org', 'http://mediawiki.org' ), @@ -29,13 +29,17 @@ class ParserOutputTest extends MediaWikiTestCase { /** * Test to make sure ParserOutput::isLinkInternal behaves properly - * @dataProvider dataIsLinkInternal + * @dataProvider provideIsLinkInternal + * @covers ParserOutput::isLinkInternal */ - function testIsLinkInternal( $shouldMatch, $server, $url ) { - + public function testIsLinkInternal( $shouldMatch, $server, $url ) { $this->assertEquals( $shouldMatch, ParserOutput::isLinkInternal( $server, $url ) ); } + /** + * @covers ParserOutput::setExtensionData + * @covers ParserOutput::getExtensionData + */ public function testExtensionData() { $po = new ParserOutput(); diff --git a/tests/phpunit/includes/parser/ParserPreloadTest.php b/tests/phpunit/includes/parser/ParserPreloadTest.php index e16b407e..d12fee36 100644 --- a/tests/phpunit/includes/parser/ParserPreloadTest.php +++ b/tests/phpunit/includes/parser/ParserPreloadTest.php @@ -4,8 +4,17 @@ * @author Antoine Musso */ class ParserPreloadTest extends MediaWikiTestCase { + /** + * @var Parser + */ private $testParser; + /** + * @var ParserOptions + */ private $testParserOptions; + /** + * @var Title + */ private $title; protected function setUp() { @@ -31,14 +40,14 @@ class ParserPreloadTest extends MediaWikiTestCase { /** * @covers Parser::getPreloadText */ - function testPreloadSimpleText() { + public function testPreloadSimpleText() { $this->assertPreloaded( 'simple', 'simple' ); } /** * @covers Parser::getPreloadText */ - function testPreloadedPreIsUnstripped() { + public function testPreloadedPreIsUnstripped() { $this->assertPreloaded( '
monospaced
', '
monospaced
', @@ -49,7 +58,7 @@ class ParserPreloadTest extends MediaWikiTestCase { /** * @covers Parser::getPreloadText */ - function testPreloadedNowikiIsUnstripped() { + public function testPreloadedNowikiIsUnstripped() { $this->assertPreloaded( '[[Dummy title]]', '[[Dummy title]]', @@ -57,7 +66,7 @@ class ParserPreloadTest extends MediaWikiTestCase { ); } - function assertPreloaded( $expected, $text, $msg = '' ) { + protected function assertPreloaded( $expected, $text, $msg = '' ) { $this->assertEquals( $expected, $this->testParser->getPreloadText( @@ -68,5 +77,4 @@ class ParserPreloadTest extends MediaWikiTestCase { $msg ); } - } diff --git a/tests/phpunit/includes/parser/PreprocessorTest.php b/tests/phpunit/includes/parser/PreprocessorTest.php index c51a1dc5..8aee937c 100644 --- a/tests/phpunit/includes/parser/PreprocessorTest.php +++ b/tests/phpunit/includes/parser/PreprocessorTest.php @@ -1,9 +1,16 @@ Foo" ), array( "", "<!-- Foo -->" ), @@ -115,7 +122,7 @@ class PreprocessorTest extends MediaWikiTestCase { * @param string $wikiText * @return string */ - function preprocessToXml( $wikiText ) { + protected function preprocessToXml( $wikiText ) { if ( method_exists( $this->mPreprocessor, 'preprocessToXml' ) ) { return $this->normalizeXml( $this->mPreprocessor->preprocessToXml( $wikiText ) ); } @@ -134,21 +141,22 @@ class PreprocessorTest extends MediaWikiTestCase { * @param string $xml * @return string */ - function normalizeXml( $xml ) { + protected function normalizeXml( $xml ) { return preg_replace( '!<([a-z]+)/>!', '<$1>', str_replace( ' />', '/>', $xml ) ); } /** * @dataProvider provideCases + * @covers Preprocessor_DOM::preprocessToXml */ - function testPreprocessorOutput( $wikiText, $expectedXml ) { + public function testPreprocessorOutput( $wikiText, $expectedXml ) { $this->assertEquals( $this->normalizeXml( $expectedXml ), $this->preprocessToXml( $wikiText ) ); } /** * These are more complex test cases taken out of wiki articles. */ - function provideFiles() { + public static function provideFiles() { return array( array( "QuoteQuran" ), # http://en.wikipedia.org/w/index.php?title=Template:QuoteQuran/sandbox&oldid=237348988 GFDL + CC-BY-SA by Striver array( "Factorial" ), # http://en.wikipedia.org/w/index.php?title=Template:Factorial&oldid=98548758 GFDL + CC-BY-SA by Polonium @@ -160,8 +168,9 @@ class PreprocessorTest extends MediaWikiTestCase { /** * @dataProvider provideFiles + * @covers Preprocessor_DOM::preprocessToXml */ - function testPreprocessorOutputFiles( $filename ) { + public function testPreprocessorOutputFiles( $filename ) { $folder = __DIR__ . "/../../../parser/preprocess"; $wikiText = file_get_contents( "$folder/$filename.txt" ); $output = $this->preprocessToXml( $wikiText ); @@ -180,7 +189,7 @@ class PreprocessorTest extends MediaWikiTestCase { /** * Tests from Bug 28642 · https://bugzilla.wikimedia.org/28642 */ - function provideHeadings() { + public static function provideHeadings() { return array( /* These should become headings: */ array( "== h ==", "== h ==<!--c1-->" ), array( "== h == ", "== h == <!--c1-->" ), @@ -209,11 +218,11 @@ class PreprocessorTest extends MediaWikiTestCase { array( "== h == ", "== h == <!--c1--> <!--c2--><!--c3--> " ), array( "== h == ", "== h == <!--c1--><!--c2--> <!--c3--> " ), array( "== h == ", "== h == <!--c1--> <!--c2--> <!--c3--> " ), + array( "== h == ", "== h ==<!--c1--> <!--c2-->" ), + array( "== h == ", "== h == <!--c1--> <!--c2-->" ), + array( "== h == ", "== h ==<!--c1--> <!--c2--> " ), /* These are not working: */ - array( "== h == ", "== h ==<!--c1--> <!--c2-->" ), - array( "== h == ", "== h == <!--c1--> <!--c2-->" ), - array( "== h == ", "== h ==<!--c1--> <!--c2--> " ), array( "== h == x ", "== h == x <!--c1--><!--c2--><!--c3--> " ), array( "== h == x ", "== h ==<!--c1--> x <!--c2--><!--c3--> " ), array( "== h == x ", "== h ==<!--c1--><!--c2--><!--c3--> x " ), @@ -222,8 +231,9 @@ class PreprocessorTest extends MediaWikiTestCase { /** * @dataProvider provideHeadings + * @covers Preprocessor_DOM::preprocessToXml */ - function testHeadings( $wikiText, $expectedXml ) { + public function testHeadings( $wikiText, $expectedXml ) { $this->assertEquals( $this->normalizeXml( $expectedXml ), $this->preprocessToXml( $wikiText ) ); } } diff --git a/tests/phpunit/includes/parser/TagHooksTest.php b/tests/phpunit/includes/parser/TagHooksTest.php index ed600790..61cbe45d 100644 --- a/tests/phpunit/includes/parser/TagHooksTest.php +++ b/tests/phpunit/includes/parser/TagHooksTest.php @@ -21,7 +21,7 @@ class TagHookTest extends MediaWikiTestCase { /** * @dataProvider provideValidNames */ - function testTagHooks( $tag ) { + public function testTagHooks( $tag ) { global $wgParserConf, $wgContLang; $parser = new Parser( $wgParserConf ); @@ -36,7 +36,7 @@ class TagHookTest extends MediaWikiTestCase { * @dataProvider provideBadNames * @expectedException MWException */ - function testBadTagHooks( $tag ) { + public function testBadTagHooks( $tag ) { global $wgParserConf, $wgContLang; $parser = new Parser( $wgParserConf ); @@ -48,7 +48,7 @@ class TagHookTest extends MediaWikiTestCase { /** * @dataProvider provideValidNames */ - function testFunctionTagHooks( $tag ) { + public function testFunctionTagHooks( $tag ) { global $wgParserConf, $wgContLang; $parser = new Parser( $wgParserConf ); @@ -63,7 +63,7 @@ class TagHookTest extends MediaWikiTestCase { * @dataProvider provideBadNames * @expectedException MWException */ - function testBadFunctionTagHooks( $tag ) { + public function testBadFunctionTagHooks( $tag ) { global $wgParserConf, $wgContLang; $parser = new Parser( $wgParserConf ); diff --git a/tests/phpunit/includes/parser/TidyTest.php b/tests/phpunit/includes/parser/TidyTest.php new file mode 100644 index 00000000..57a88b9d --- /dev/null +++ b/tests/phpunit/includes/parser/TidyTest.php @@ -0,0 +1,44 @@ +markTestSkipped( 'Tidy not found' ); + } + } + + /** + * @dataProvider provideTestWrapping + */ + public function testTidyWrapping( $expected, $text, $msg = '' ) { + $text = MWTidy::tidy( $text ); + // We don't care about where Tidy wants to stick is

s + $text = trim( preg_replace( '##', '', $text ) ); + // Windows, we love you! + $text = str_replace( "\r", '', $text ); + $this->assertEquals( $expected, $text, $msg ); + } + + public function provideTestWrapping() { + return array( + array( + 'foo', + 'foo', + ' should survive tidy' + ), + array( + 'foo', + 'foo', + ' should survive tidy' + ), + array( 'foo', 'foo', ' should survive tidy' ), + array( "\nfoo", 'foo', ' should survive tidy' ), + array( "\nfoo", 'foo', ' should survive tidy' ), + ); + } +} \ No newline at end of file -- cgit v1.2.2