diff options
Diffstat (limited to 'tests')
339 files changed, 15236 insertions, 12138 deletions
diff --git a/tests/RunSeleniumTests.php b/tests/RunSeleniumTests.php deleted file mode 100644 index b7320cb1..00000000 --- a/tests/RunSeleniumTests.php +++ /dev/null @@ -1,258 +0,0 @@ -#!/usr/bin/env php -<?php -/** - * @file - * @ingroup Maintenance - * @copyright Copyright © Wikimedia Deuschland, 2009 - * @author Hallo Welt! Medienwerkstatt GmbH - * @author Markus Glaser, Dan Nessett, Priyanka Dhanda - * initial idea by Daniel Kinzler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -if ( PHP_SAPI != 'cli' ) { - die( "Run me from the command line please.\n" ); -} - -define( 'SELENIUMTEST', true ); - -require( __DIR__ . '/../maintenance/Maintenance.php' ); - -require_once( 'PHPUnit/Runner/Version.php' ); -if ( version_compare( PHPUnit_Runner_Version::id(), '3.5.0', '>=' ) ) { - # PHPUnit 3.5.0 introduced a nice autoloader based on class name - require_once( 'PHPUnit/Autoload.php' ); -} else { - # Keep the old pre PHPUnit 3.5.0 behavior for compatibility - require_once( 'PHPUnit/TextUI/Command.php' ); -} - -require_once( 'PHPUnit/Extensions/SeleniumTestCase.php' ); -include_once( 'PHPUnit/Util/Log/JUnit.php' ); - -require_once( __DIR__ . "/selenium/SeleniumServerManager.php" ); - -class SeleniumTester extends Maintenance { - protected $selenium; - protected $serverManager; - protected $seleniumServerExecPath; - - public function __construct() { - parent::__construct(); - $this->mDescription = "Selenium Test Runner. For documentation, visit http://www.mediawiki.org/wiki/SeleniumFramework"; - $this->addOption( 'port', 'Port used by selenium server. Default: 4444', false, true ); - $this->addOption( 'host', 'Host selenium server. Default: $wgServer . $wgScriptPath', false, true ); - $this->addOption( 'testBrowser', 'The browser used during testing. Default: firefox', false, true ); - $this->addOption( 'wikiUrl', 'The Mediawiki installation to point to. Default: http://localhost', false, true ); - $this->addOption( 'username', 'The login username for sunning tests. Default: empty', false, true ); - $this->addOption( 'userPassword', 'The login password for running tests. Default: empty', false, true ); - $this->addOption( 'seleniumConfig', 'Location of the selenium config file. Default: empty', false, true ); - $this->addOption( 'list-browsers', 'List the available browsers.' ); - $this->addOption( 'verbose', 'Be noisier.' ); - $this->addOption( 'startserver', 'Start Selenium Server (on localhost) before the run.' ); - $this->addOption( 'stopserver', 'Stop Selenium Server (on localhost) after the run.' ); - $this->addOption( 'jUnitLogFile', 'Log results in a specified JUnit log file. Default: empty', false, true ); - $this->addOption( 'runAgainstGrid', 'The test will be run against a Selenium Grid. Default: false.', false, true ); - $this->deleteOption( 'dbpass' ); - $this->deleteOption( 'dbuser' ); - $this->deleteOption( 'globals' ); - $this->deleteOption( 'wiki' ); - } - - public function listBrowsers() { - $desc = "Available browsers:\n"; - - foreach ( $this->selenium->getAvailableBrowsers() as $k => $v ) { - $desc .= " $k => $v\n"; - } - - echo $desc; - } - - protected function startServer() { - if ( $this->seleniumServerExecPath == '' ) { - die ( "The selenium server exec path is not set in " . - "selenium_settings.ini. Cannot start server \n" . - "as requested - terminating RunSeleniumTests\n" ); - } - $this->serverManager = new SeleniumServerManager( 'true', - $this->selenium->getPort(), - $this->seleniumServerExecPath ); - switch ( $this->serverManager->start() ) { - case 'started': - break; - case 'failed': - die ( "Unable to start the Selenium Server - " . - "terminating RunSeleniumTests\n" ); - case 'running': - echo ( "Warning: The Selenium Server is " . - "already running\n" ); - break; - } - - return; - } - - protected function stopServer() { - if ( !isset ( $this->serverManager ) ) { - echo ( "Warning: Request to stop Selenium Server, but it was " . - "not stared by RunSeleniumTests\n" . - "RunSeleniumTests cannot stop a Selenium Server it " . - "did not start\n" ); - } else { - switch ( $this->serverManager->stop() ) { - case 'stopped': - break; - case 'failed': - echo ( "unable to stop the Selenium Server\n" ); - } - } - return; - } - - protected function runTests( $seleniumTestSuites = array() ) { - $result = new PHPUnit_Framework_TestResult; - $result->addListener( new SeleniumTestListener( $this->selenium->getLogger() ) ); - if ( $this->selenium->getJUnitLogFile() ) { - $jUnitListener = new PHPUnit_Util_Log_JUnit( $this->selenium->getJUnitLogFile(), true ); - $result->addListener( $jUnitListener ); - } - - foreach ( $seleniumTestSuites as $testSuiteName => $testSuiteFile ) { - require( $testSuiteFile ); - $suite = new $testSuiteName(); - $suite->setName( $testSuiteName ); - $suite->addTests(); - - try { - $suite->run( $result ); - } catch ( Testing_Selenium_Exception $e ) { - $suite->tearDown(); - throw new MWException( $e->getMessage() ); - } - } - - if ( $this->selenium->getJUnitLogFile() ) { - $jUnitListener->flush(); - } - } - - public function execute() { - global $wgServer, $wgScriptPath, $wgHooks; - - $seleniumSettings = array(); - $seleniumBrowsers = array(); - $seleniumTestSuites = array(); - - $configFile = $this->getOption( 'seleniumConfig', '' ); - if ( strlen( $configFile ) > 0 ) { - $this->output( "Using Selenium Configuration file: " . $configFile . "\n" ); - SeleniumConfig::getSeleniumSettings( $seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites, - $configFile ); - } elseif ( !isset( $wgHooks['SeleniumSettings'] ) ) { - $this->output( "No command line, configuration file or configuration hook found.\n" ); - SeleniumConfig::getSeleniumSettings( $seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites - ); - } else { - $this->output( "Using 'SeleniumSettings' hook for configuration.\n" ); - wfRunHooks( 'SeleniumSettings', array( $seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites ) ); - } - - // State for starting/stopping the Selenium server has nothing to do with the Selenium - // class. Keep this state local to SeleniumTester class. Using getOption() is clumsy, but - // the Maintenance class does not have a setOption() - if ( !isset( $seleniumSettings['startserver'] ) ) { - $this->getOption( 'startserver', true ); - } - if ( !isset( $seleniumSettings['stopserver'] ) ) { - $this->getOption( 'stopserver', true ); - } - if ( !isset( $seleniumSettings['seleniumserverexecpath'] ) ) { - $seleniumSettings['seleniumserverexecpath'] = ''; - } - $this->seleniumServerExecPath = $seleniumSettings['seleniumserverexecpath']; - - //set reasonable defaults if we did not find the settings - if ( !isset( $seleniumBrowsers ) ) { - $seleniumBrowsers = array( 'firefox' => '*firefox' ); - } - if ( !isset( $seleniumSettings['host'] ) ) { - $seleniumSettings['host'] = $wgServer . $wgScriptPath; - } - if ( !isset( $seleniumSettings['port'] ) ) { - $seleniumSettings['port'] = '4444'; - } - if ( !isset( $seleniumSettings['wikiUrl'] ) ) { - $seleniumSettings['wikiUrl'] = 'http://localhost'; - } - if ( !isset( $seleniumSettings['username'] ) ) { - $seleniumSettings['username'] = ''; - } - if ( !isset( $seleniumSettings['userPassword'] ) ) { - $seleniumSettings['userPassword'] = ''; - } - if ( !isset( $seleniumSettings['testBrowser'] ) ) { - $seleniumSettings['testBrowser'] = 'firefox'; - } - if ( !isset( $seleniumSettings['jUnitLogFile'] ) ) { - $seleniumSettings['jUnitLogFile'] = false; - } - if ( !isset( $seleniumSettings['runAgainstGrid'] ) ) { - $seleniumSettings['runAgainstGrid'] = false; - } - - // Setup Selenium class - $this->selenium = new Selenium(); - $this->selenium->setAvailableBrowsers( $seleniumBrowsers ); - $this->selenium->setRunAgainstGrid( $this->getOption( 'runAgainstGrid', $seleniumSettings['runAgainstGrid'] ) ); - $this->selenium->setUrl( $this->getOption( 'wikiUrl', $seleniumSettings['wikiUrl'] ) ); - $this->selenium->setBrowser( $this->getOption( 'testBrowser', $seleniumSettings['testBrowser'] ) ); - $this->selenium->setPort( $this->getOption( 'port', $seleniumSettings['port'] ) ); - $this->selenium->setHost( $this->getOption( 'host', $seleniumSettings['host'] ) ); - $this->selenium->setUser( $this->getOption( 'username', $seleniumSettings['username'] ) ); - $this->selenium->setPass( $this->getOption( 'userPassword', $seleniumSettings['userPassword'] ) ); - $this->selenium->setVerbose( $this->hasOption( 'verbose' ) ); - $this->selenium->setJUnitLogFile( $this->getOption( 'jUnitLogFile', $seleniumSettings['jUnitLogFile'] ) ); - - if ( $this->hasOption( 'list-browsers' ) ) { - $this->listBrowsers(); - exit( 0 ); - } - if ( $this->hasOption( 'startserver' ) ) { - $this->startServer(); - } - - $logger = new SeleniumTestConsoleLogger; - $this->selenium->setLogger( $logger ); - - $this->runTests( $seleniumTestSuites ); - - if ( $this->hasOption( 'stopserver' ) ) { - $this->stopServer(); - } - } -} - -$maintClass = "SeleniumTester"; - -require_once( RUN_MAINTENANCE_IF_MAIN ); diff --git a/tests/TestsAutoLoader.php b/tests/TestsAutoLoader.php index c1c301f6..00ce13c8 100644 --- a/tests/TestsAutoLoader.php +++ b/tests/TestsAutoLoader.php @@ -30,14 +30,16 @@ $wgAutoloadClasses += array( 'DbTestPreviewer' => "$testDir/testHelpers.inc", 'DbTestRecorder' => "$testDir/testHelpers.inc", 'DelayedParserTest' => "$testDir/testHelpers.inc", + 'ParserTestResult' => "$testDir/parser/ParserTestResult.php", 'TestFileIterator' => "$testDir/testHelpers.inc", 'TestRecorder' => "$testDir/testHelpers.inc", + 'ITestRecorder' => "$testDir/testHelpers.inc", # tests/phpunit 'MediaWikiTestCase' => "$testDir/phpunit/MediaWikiTestCase.php", 'MediaWikiPHPUnitCommand' => "$testDir/phpunit/MediaWikiPHPUnitCommand.php", + 'MediaWikiPHPUnitTestListener' => "$testDir/phpunit/MediaWikiPHPUnitTestListener.php", 'MediaWikiLangTestCase' => "$testDir/phpunit/MediaWikiLangTestCase.php", - 'MediaWikiProvide' => "$testDir/phpunit/includes/Providers.php", 'TestUser' => "$testDir/phpunit/includes/TestUser.php", # tests/phpunit/includes @@ -48,9 +50,7 @@ $wgAutoloadClasses += array( //db 'ORMTableTest' => "$testDir/phpunit/includes/db/ORMTableTest.php", 'PageORMTableForTesting' => "$testDir/phpunit/includes/db/ORMTableTest.php", - - //Selenium - 'SeleniumTestConstants' => "$testDir/selenium/SeleniumTestConstants.php", + 'DatabaseTestHelper' => "$testDir/phpunit/includes/db/DatabaseTestHelper.php", # tests/phpunit/includes/api 'ApiFormatTestBase' => "$testDir/phpunit/includes/api/format/ApiFormatTestBase.php", @@ -73,14 +73,25 @@ $wgAutoloadClasses += array( # tests/phpunit/includes/parser 'NewParserTest' => "$testDir/phpunit/includes/parser/NewParserTest.php", + 'MediaWikiParserTest' => "$testDir/phpunit/includes/parser/MediaWikiParserTest.php", # tests/phpunit/includes/libs 'GenericArrayObjectTest' => "$testDir/phpunit/includes/libs/GenericArrayObjectTest.php", + # tests/phpunit/media + 'FakeDimensionFile' => "$testDir/phpunit/includes/media/FakeDimensionFile.php", + # tests/phpunit/includes/site 'SiteTest' => "$testDir/phpunit/includes/site/SiteTest.php", 'TestSites' => "$testDir/phpunit/includes/site/TestSites.php", + # tests/phpunit/mocks + 'MockFSFile' => "$testDir/phpunit/mocks/filebackend/MockFSFile.php", + 'MockFileBackend' => "$testDir/phpunit/mocks/filebackend/MockFileBackend.php", + 'MockBitmapHandler' => "$testDir/phpunit/mocks/media/MockBitmapHandler.php", + 'MockImageHandler' => "$testDir/phpunit/mocks/media/MockBitmapHandler.php", + 'MockSvgHandler' => "$testDir/phpunit/mocks/media/MockBitmapHandler.php", + # tests/phpunit/languages 'LanguageClassesTestCase' => "$testDir/phpunit/languages/LanguageClassesTestCase.php", @@ -90,15 +101,4 @@ $wgAutoloadClasses += array( # tests/parser 'ParserTest' => "$testDir/parser/parserTest.inc", 'ParserTestParserHook' => "$testDir/parser/parserTestsParserHook.php", - - # tests/selenium - 'Selenium' => "$testDir/selenium/Selenium.php", - 'SeleniumLoader' => "$testDir/selenium/SeleniumLoader.php", - 'SeleniumTestCase' => "$testDir/selenium/SeleniumTestCase.php", - 'SeleniumTestConsoleLogger' => "$testDir/selenium/SeleniumTestConsoleLogger.php", - 'SeleniumTestConstants' => "$testDir/selenium/SeleniumTestConstants.php", - 'SeleniumTestHTMLLogger' => "$testDir/selenium/SeleniumTestHTMLLogger.php", - 'SeleniumTestListener' => "$testDir/selenium/SeleniumTestListener.php", - 'SeleniumTestSuite' => "$testDir/selenium/SeleniumTestSuite.php", - 'SeleniumConfig' => "$testDir/selenium/SeleniumConfig.php", ); diff --git a/tests/parser/ParserTestResult.php b/tests/parser/ParserTestResult.php new file mode 100644 index 00000000..d9ad773d --- /dev/null +++ b/tests/parser/ParserTestResult.php @@ -0,0 +1,42 @@ +<?php +/** + * @copyright Copyright © 2013, Antoine Musso + * @copyright Copyright © 2013, Wikimedia Foundation Inc. + * @license GNU GPL v2 + * + * @file + */ + +/** + * Represent the result of a parser test. + * + * @since 1.22 + */ +class ParserTestResult { + /** + * Description of the parser test. + * + * This is usually the text used to describe a parser test in the .txt + * files. It is initialized on a construction and you most probably + * never want to change it. + */ + public $description; + /** Text that was expected */ + public $expected; + /** Actual text rendered */ + public $actual; + + /** + * @param $description string A short text describing the parser test + * usually the text in the parser test .txt file. The description + * is later available using the property $description. + */ + public function __construct( $description ) { + $this->description = $description; + } + + /** Whether the test passed */ + public function isSuccess() { + return $this->expected === $this->actual; + } +} diff --git a/tests/parser/parserTest.inc b/tests/parser/parserTest.inc index ce621f4e..58ea1ed0 100644 --- a/tests/parser/parserTest.inc +++ b/tests/parser/parserTest.inc @@ -1,6 +1,8 @@ <?php /** - * Helper code for the MediaWiki parser test suite. + * Helper code for the MediaWiki parser test suite. Some code is duplicated + * in PHPUnit's NewParserTests.php, so you'll probably want to update both + * at the same time. * * Copyright © 2004, 2010 Brion Vibber <brion@pobox.com> * http://www.mediawiki.org/ @@ -31,22 +33,22 @@ */ class ParserTest { /** - * boolean $color whereas output should be colorized + * @var bool $color whereas output should be colorized */ private $color; /** - * boolean $showOutput Show test output + * @var bool $showOutput Show test output */ private $showOutput; /** - * boolean $useTemporaryTables Use temporary tables for the temporary database + * @var bool $useTemporaryTables Use temporary tables for the temporary database */ private $useTemporaryTables = true; /** - * boolean $databaseSetupDone True if the database has been set up + * @var bool $databaseSetupDone True if the database has been set up */ private $databaseSetupDone = false; @@ -63,7 +65,7 @@ class ParserTest { private $dbClone; /** - * string $oldTablePrefix Original table prefix + * @var string $oldTablePrefix Original table prefix */ private $oldTablePrefix; @@ -141,15 +143,14 @@ class ParserTest { static function setUp() { global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache, - $wgNamespaceAliases, $wgNamespaceProtection, $wgLocalFileRepo, + $wgExtraNamespaces, $wgNamespaceAliases, $wgNamespaceProtection, $wgLocalFileRepo, $parserMemc, $wgThumbnailScriptPath, $wgScriptPath, - $wgArticlePath, $wgStyleSheetPath, $wgScript, $wgStylePath, $wgExtensionAssetsPath, + $wgArticlePath, $wgScript, $wgStylePath, $wgExtensionAssetsPath, $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType, $wgLockManagers; $wgScript = '/index.php'; $wgScriptPath = '/'; $wgArticlePath = '/wiki/$1'; - $wgStyleSheetPath = '/skins'; $wgStylePath = '/skins'; $wgExtensionAssetsPath = '/extensions'; $wgThumbnailScriptPath = false; @@ -181,6 +182,9 @@ class ParserTest { $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; $wgNamespaceAliases['Image'] = NS_FILE; $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; + # add a namespace shadowing a interwiki link, to test + # proper precedence when resolving links. (bug 51680) + $wgExtraNamespaces[100] = 'MemoryAlpha'; // XXX: tests won't run without this (for CACHE_DB) if ( $wgMainCacheType === CACHE_DB ) { @@ -211,6 +215,73 @@ class ParserTest { $wgStyleDirectory = "$IP/skins"; } + self::setupInterwikis(); + } + + /** + * Insert hardcoded interwiki in the lookup table. + * + * This function insert a set of well known interwikis that are used in + * the parser tests. They can be considered has fixtures are injected in + * the interwiki cache by using the 'InterwikiLoadPrefix' hook. + * Since we are not interested in looking up interwikis in the database, + * the hook completely replace the existing mechanism (hook returns false). + */ + public static function setupInterwikis() { + # Hack: insert a few Wikipedia in-project interwiki prefixes, + # for testing inter-language links + Hooks::register( 'InterwikiLoadPrefix', function ( $prefix, &$iwData ) { + static $testInterwikis = array( + 'wikipedia' => array( + 'iw_url' => 'http://en.wikipedia.org/wiki/$1', + 'iw_api' => '', + 'iw_wikiid' => '', + 'iw_local' => 0 ), + 'meatball' => array( + 'iw_url' => 'http://www.usemod.com/cgi-bin/mb.pl?$1', + 'iw_api' => '', + 'iw_wikiid' => '', + 'iw_local' => 0 ), + 'memoryalpha' => array( + 'iw_url' => 'http://www.memory-alpha.org/en/index.php/$1', + 'iw_api' => '', + 'iw_wikiid' => '', + 'iw_local' => 0 ), + 'zh' => array( + 'iw_url' => 'http://zh.wikipedia.org/wiki/$1', + 'iw_api' => '', + 'iw_wikiid' => '', + 'iw_local' => 1 ), + 'es' => array( + 'iw_url' => 'http://es.wikipedia.org/wiki/$1', + 'iw_api' => '', + 'iw_wikiid' => '', + 'iw_local' => 1 ), + 'fr' => array( + 'iw_url' => 'http://fr.wikipedia.org/wiki/$1', + 'iw_api' => '', + 'iw_wikiid' => '', + 'iw_local' => 1 ), + 'ru' => array( + 'iw_url' => 'http://ru.wikipedia.org/wiki/$1', + 'iw_api' => '', + 'iw_wikiid' => '', + 'iw_local' => 1 ), + ); + if ( array_key_exists( $prefix, $testInterwikis ) ) { + $iwData = $testInterwikis[$prefix]; + } + + // We only want to rely on the above fixtures + return false; + } );// hooks::register + } + + /** + * Remove the hardcoded interwiki lookup table. + */ + public static function tearDownInterwikis() { + Hooks::clear( 'InterwikiLoadPrefix' ); } public function setupRecorder( $options ) { @@ -378,7 +449,12 @@ class ParserTest { */ public function runTestsFromFiles( $filenames ) { $ok = false; + + // be sure, ParserTest::addArticle has correct language set, + // so that system messages gets into the right language cache + $GLOBALS['wgLanguageCode'] = 'en'; $GLOBALS['wgContLang'] = Language::factory( 'en' ); + $this->recorder->start(); try { $this->setupDatabase(); @@ -418,6 +494,9 @@ class ParserTest { /** * Get a Parser object + * + * @param string $preprocessor + * @return Parser */ function getParser( $preprocessor = null ) { global $wgParserConf; @@ -487,9 +566,10 @@ class ParserTest { } 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'] ) ) { @@ -518,18 +598,23 @@ class ParserTest { } $this->teardownGlobals(); - return $this->showTestResult( $desc, $result, $out ); + + $testResult = new ParserTestResult( $desc ); + $testResult->expected = $result; + $testResult->actual = $out; + + return $this->showTestResult( $testResult ); } /** - * + * Refactored in 1.22 to use ParserTestResult */ - function showTestResult( $desc, $result, $out ) { - if ( $result === $out ) { - $this->showSuccess( $desc ); + function showTestResult( ParserTestResult $testResult ) { + if ( $testResult->isSuccess() ) { + $this->showSuccess( $testResult ); return true; } else { - $this->showFailure( $desc, $result, $out ); + $this->showFailure( $testResult ); return false; } } @@ -537,7 +622,7 @@ class ParserTest { /** * Use a regex to find out the value of an option * @param $key String: name of option val to retrieve - * @param $opts Options array to look in + * @param $opts array: Options array to look in * @param $default Mixed: default value returned if not found */ private static function getOptionValue( $key, $opts, $default ) { @@ -664,11 +749,10 @@ class ParserTest { ), 'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ), 'wgStylePath' => '/skins', - 'wgStyleSheetPath' => '/skins', 'wgSitename' => 'MediaWiki', 'wgLanguageCode' => $lang, 'wgDBprefix' => $this->db->getType() != 'oracle' ? 'parsertest_' : 'pt_', - 'wgRawHtml' => isset( $opts['rawhtml'] ), + 'wgRawHtml' => self::getOptionValue( 'wgRawHtml', $opts, false ), 'wgLang' => null, 'wgContLang' => null, 'wgNamespacesWithSubpages' => array( 0 => isset( $opts['subpage'] ) ), @@ -678,8 +762,10 @@ class ParserTest { 'wgNoFollowDomainExceptions' => array(), 'wgThumbnailScriptPath' => false, 'wgUseImageResize' => true, + 'wgSVGConverter' => 'null', + 'wgSVGConverters' => array( 'null' => 'echo "1">$output' ), 'wgLocaltimezone' => 'UTC', - 'wgAllowExternalImages' => true, + 'wgAllowExternalImages' => self::getOptionValue( 'wgAllowExternalImages', $opts, true ), 'wgUseTidy' => false, 'wgDefaultLanguageVariant' => $variant, 'wgVariantArticlePath' => false, @@ -822,43 +908,9 @@ class ParserTest { 'user_name' => 'Anonymous' ) ); } - # 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 ), - ) ); - # Update certain things in site_stats - $this->db->insert( 'site_stats', array( 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ) ); + $this->db->insert( 'site_stats', + array( 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ) ); # Reinitialise the LocalisationCache to match the database state Language::getLocalisationCache()->unloadAll(); @@ -866,19 +918,52 @@ class ParserTest { # Clear the message cache MessageCache::singleton()->clear(); + // Remember to update newParserTests.php after changing the below + // (and it uses a slightly different syntax just for teh lulz) $this->uploadDir = $this->setupUploadDir(); $user = User::createNew( 'WikiSysop' ); $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.jpg' ) ); + # 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->recordUpload2( '', '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' ) ); + # again, note that size/width/height below are ignored; see above. + $image->recordUpload2( '', '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 ); + + $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.svg' ) ); + $image->recordUpload2( '', 'Upload of some lame SVG', 'Some lame SVG', array( + 'size' => 12345, + 'width' => 240, + 'height' => 180, + '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 ); # This image will be blacklisted in [[MediaWiki:Bad image list]] @@ -891,7 +976,7 @@ class ParserTest { '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 ); } @@ -922,8 +1007,11 @@ class ParserTest { $tables = $this->listTables(); foreach ( $tables as $table ) { - $sql = $this->db->getType() == 'oracle' ? "DROP TABLE pt_$table DROP CONSTRAINTS" : "DROP TABLE `parsertest_$table`"; - $this->db->query( $sql ); + if ( $this->db->getType() == 'oracle' ) { + $this->db->query( "DROP TABLE pt_$table DROP CONSTRAINTS" ); + } else { + $this->db->query( "DROP TABLE `parsertest_$table`" ); + } } if ( $this->db->getType() == 'oracle' ) { @@ -960,9 +1048,15 @@ class ParserTest { wfMkdirParents( $dir . '/3/3a', null, __METHOD__ ); copy( "$IP/skins/monobook/headbg.jpg", "$dir/3/3a/Foobar.jpg" ); + wfMkdirParents( $dir . '/e/ea', null, __METHOD__ ); + copy( "$IP/skins/monobook/wiki.png", "$dir/e/ea/Thumb.png" ); wfMkdirParents( $dir . '/0/09', null, __METHOD__ ); copy( "$IP/skins/monobook/headbg.jpg", "$dir/0/09/Bad.jpg" ); - + wfMkdirParents( $dir . '/f/ff', null, __METHOD__ ); + copy( "$IP/skins/monobook/headbg.jpg", "$dir/f/ff/Foobar.svg" ); + file_put_contents( "$dir/f/ff/Foobar.svg", + '<?xml version="1.0" encoding="utf-8"?>' . + '<svg xmlns="http://www.w3.org/2000/svg" />' ); return $dir; } @@ -1008,8 +1102,18 @@ class ParserTest { "$dir/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg", "$dir/thumb/3/3a/Foobar.jpg/960px-Foobar.jpg", + "$dir/e/ea/Thumb.png", + "$dir/0/09/Bad.jpg", + "$dir/f/ff/Foobar.svg", + "$dir/thumb/f/ff/Foobar.svg/180px-Foobar.svg.png", + "$dir/thumb/f/ff/Foobar.svg/360px-Foobar.svg.png", + "$dir/thumb/f/ff/Foobar.svg/langde-270px-Foobar.svg.png", + "$dir/thumb/f/ff/Foobar.svg/270px-Foobar.svg.png", + "$dir/thumb/f/ff/Foobar.svg/langde-180px-Foobar.svg.png", + "$dir/thumb/f/ff/Foobar.svg/langde-360px-Foobar.svg.png", + "$dir/math/f/a/5/fa50b8b616463173474302ca3e63586b.png", ) ); @@ -1023,7 +1127,13 @@ class ParserTest { "$dir/thumb/3/3a/Foobar.jpg", "$dir/thumb/3/3a", "$dir/thumb/3", - + "$dir/e/ea", + "$dir/e", + "$dir/f/ff/", + "$dir/f/", + "$dir/thumb/f/ff/Foobar.svg", + "$dir/thumb/f/ff/", + "$dir/thumb/f/", "$dir/0/09/", "$dir/0/", "$dir/thumb", @@ -1070,10 +1180,12 @@ class ParserTest { /** * Print a happy success message. * - * @param $desc String: the test name + * Refactored in 1.22 to use ParserTestResult + * + * @param $testResult ParserTestResult * @return Boolean */ - protected function showSuccess( $desc ) { + protected function showSuccess( ParserTestResult $testResult ) { if ( $this->showProgress ) { print $this->term->color( '1;32' ) . 'PASSED' . $this->term->reset() . "\n"; } @@ -1085,28 +1197,29 @@ class ParserTest { * Print a failure message and provide some explanatory output * about what went wrong if so configured. * - * @param $desc String: the test name - * @param $result String: expected HTML output - * @param $html String: actual HTML output + * Refactored in 1.22 to use ParserTestResult + * + * @param $testResult ParserTestResult * @return Boolean */ - protected function showFailure( $desc, $result, $html ) { + protected function showFailure( ParserTestResult $testResult ) { if ( $this->showFailure ) { if ( !$this->showProgress ) { # In quiet mode we didn't show the 'Testing' message before the # test, in case it succeeded. Show it now: - $this->showTesting( $desc ); + $this->showTesting( $testResult->description ); } print $this->term->color( '31' ) . 'FAILED!' . $this->term->reset() . "\n"; if ( $this->showOutput ) { - print "--- Expected ---\n$result\n--- Actual ---\n$html\n"; + print "--- Expected ---\n{$testResult->expected}\n"; + print "--- Actual ---\n{$testResult->actual}\n"; } if ( $this->showDiffs ) { - print $this->quickDiff( $result, $html ); - if ( !$this->wellFormed( $html ) ) { + print $this->quickDiff( $testResult->expected, $testResult->actual ); + if ( !$this->wellFormed( $testResult->actual ) ) { print "XML error: $this->mXmlError\n"; } } @@ -1125,7 +1238,9 @@ class ParserTest { * @param $outFileTail String: tailing for the output file name * @return String */ - protected function quickDiff( $input, $output, $inFileTail = 'expected', $outFileTail = 'actual' ) { + protected function quickDiff( $input, $output, + $inFileTail = 'expected', $outFileTail = 'actual' + ) { # Windows, or at least the fc utility, is retarded $slash = wfIsWindows() ? '\\' : '/'; $prefix = wfTempDir() . "{$slash}mwParser-" . mt_rand(); @@ -1141,9 +1256,10 @@ class ParserTest { global $wgDiff3; // we assume that people with diff3 also have usual diff - $diff = ( wfIsWindows() && !$wgDiff3 ) - ? `fc $shellInfile $shellOutfile` - : `diff -au $shellInfile $shellOutfile`; + $shellCommand = ( wfIsWindows() && !$wgDiff3 ) ? 'fc' : 'diff -au'; + + $diff = wfShellExec( "$shellCommand $shellInfile $shellOutfile" ); + unlink( $infile ); unlink( $outfile ); @@ -1343,7 +1459,7 @@ class ParserTest { } static function getFakeTimestamp( &$parser, &$ts ) { - $ts = 123; + $ts = 123; //parsed as '1970-01-01T00:02:03Z' return true; } } diff --git a/tests/parser/parserTests.txt b/tests/parser/parserTests.txt index f0603e75..02a66b51 100644 --- a/tests/parser/parserTests.txt +++ b/tests/parser/parserTests.txt @@ -26,6 +26,11 @@ # showtitle make the first line the title # comment run through Linker::formatComment() instead of main parser # local format section links in edit comment text as local links +# notoc disable table of contents +# +# You can also set the following parser properties via test options: +# wgEnableUploads, wgAllowExternalImages, wgMaxTocLevel, +# wgLinkHolderBatchSize, wgRawHtml # # For testing purposes, temporary articles can created: # !!article / NAMESPACE:TITLE / !!text / ARTICLE TEXT / !!endarticle @@ -117,11 +122,30 @@ Template:table_attribs !! endarticle !! article +Template:table_cells +!! text +{{table_attribs}} || Bar || Baz +!! endarticle + +!! article +Template:image_attribs +!! text +<noinclude> +[[File:foobar.jpg|</noinclude>right|Caption text<noinclude>]]</noinclude> +!! endarticle + +!! article A?b !! text Weirdo titles! !! endarticle +!!article +Template:Bullet +!!text +* Bar +!!endarticle + ### ### Basic tests ### @@ -165,6 +189,206 @@ baz !! end !! test +Paragraphs with newline spacing with comment lines in between +!! input +---- +a +<!--foo--> +b +---- +a +<!--foo--><!--More than 1 comment, still stripped--> +b +---- +a + <!--foo--> <!----> <!-- bar --> +b +---- +a +<!--foo--> + +b +---- +a + +<!--foo--> +b +---- +a +<!--foo--> + + +b +---- +a + + +<!--foo--> +b +---- +!! result +<hr /> +<p>a +b +</p> +<hr /> +<p>a +b +</p> +<hr /> +<p>a +b +</p> +<hr /> +<p>a +</p><p>b +</p> +<hr /> +<p>a +</p><p>b +</p> +<hr /> +<p>a +</p><p><br /> +b +</p> +<hr /> +<p>a +</p><p><br /> +b +</p> +<hr /> + +!! end + +!! test +Paragraphs with newline spacing with non-empty white-space lines in between +!! input +---- +a + +b +---- +a + + +b +---- +!! result +<hr /> +<p>a +</p><p>b +</p> +<hr /> +<p>a +</p><p><br /> +b +</p> +<hr /> + +!! end + +!! test +Paragraphs with newline spacing with non-empty mixed comment and white-space lines in between +!! input +---- +a + <!--foo--> +b +---- +a + <!--foo--><!--More than 1 comment doesn't disable stripping of this line!--> +b +---- +a + +<!--foo--> + <!--bar--> +b +---- +a + + <!--foo--> + <!--bar--> + +b +---- +!! result +<hr /> +<p>a +b +</p> +<hr /> +<p>a +b +</p> +<hr /> +<p>a +</p><p>b +</p> +<hr /> +<p>a +</p><p><br /> +b +</p> +<hr /> + +!! end + +!! test +Extra newlines: More paragraphs with indented comment +!! input +a + + <!--boo--> + +b +!!result +<p>a +</p><p><br /> +b +</p> +!!end + +!! test +Extra newlines followed by heading +!! input +a + + + +=b= +[[a]] + + +=b= +!! result +<p>a +</p><p><br /> +</p> +<h1><span class="mw-headline" id="b">b</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: b">edit</a><span class="mw-editsection-bracket">]</span></span></h1> +<p><a href="/index.php?title=A&action=edit&redlink=1" class="new" title="A (page does not exist)">a</a> +</p><p><br /> +</p> +<h1><span class="mw-headline" id="b_2">b</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: b">edit</a><span class="mw-editsection-bracket">]</span></span></h1> + +!! end + +!! test +Extra newlines between heading and content are swallowed +!! input +=b= + + + +[[a]] +!! result +<h1><span class="mw-headline" id="b">b</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: b">edit</a><span class="mw-editsection-bracket">]</span></span></h1> +<p><a href="/index.php?title=A&action=edit&redlink=1" class="new" title="A (page does not exist)">a</a> +</p> +!! end + +!! test Parsing an URL !! input http://fr.wikipedia.org/wiki/🍺 @@ -180,9 +404,12 @@ Simple list * Item 1 * Item 2 !! result -<ul><li> Item 1 -</li><li> Item 2 -</li></ul> +<ul> +<li> Item 1 +</li> +<li> Item 2 +</li> +</ul> !! end @@ -205,25 +432,72 @@ Italics and bold * plain l'''italic''plain * plain l''''bold''' plain !! result -<ul><li> plain -</li><li> plain<i>italic</i>plain -</li><li> plain<i>italic</i>plain<i>italic</i>plain -</li><li> plain<b>bold</b>plain -</li><li> plain<b>bold</b>plain<b>bold</b>plain -</li><li> plain<i>italic</i>plain<b>bold</b>plain -</li><li> plain<b>bold</b>plain<i>italic</i>plain -</li><li> plain<i>italic<b>bold-italic</b>italic</i>plain -</li><li> plain<b>bold<i>bold-italic</i>bold</b>plain -</li><li> plain<i><b>bold-italic</b>italic</i>plain -</li><li> plain<b><i>bold-italic</i>bold</b>plain -</li><li> plain<i>italic<b>bold-italic</b></i>plain -</li><li> plain<b>bold<i>bold-italic</i></b>plain -</li><li> plain l'<i>italic</i>plain -</li><li> plain l'<b>bold</b> plain -</li></ul> +<ul> +<li> plain +</li> +<li> plain<i>italic</i>plain +</li> +<li> plain<i>italic</i>plain<i>italic</i>plain +</li> +<li> plain<b>bold</b>plain +</li> +<li> plain<b>bold</b>plain<b>bold</b>plain +</li> +<li> plain<i>italic</i>plain<b>bold</b>plain +</li> +<li> plain<b>bold</b>plain<i>italic</i>plain +</li> +<li> plain<i>italic<b>bold-italic</b>italic</i>plain +</li> +<li> plain<b>bold<i>bold-italic</i>bold</b>plain +</li> +<li> plain<i><b>bold-italic</b>italic</i>plain +</li> +<li> plain<b><i>bold-italic</i>bold</b>plain +</li> +<li> plain<i>italic<b>bold-italic</b></i>plain +</li> +<li> plain<b>bold<i>bold-italic</i></b>plain +</li> +<li> plain l'<i>italic</i>plain +</li> +<li> plain l'<b>bold</b> plain +</li> +</ul> + +!! end + +# this example taken from the [[simple:Moon]] article (bug 47326) +!! test +Italics and possessives (1) +!! input +obtained by ''[[Lunar Prospector]]'''s gamma-ray spectrometer +!! result +<p>obtained by <i><a href="/index.php?title=Lunar_Prospector&action=edit&redlink=1" class="new" title="Lunar Prospector (page does not exist)">Lunar Prospector</a>'</i>s gamma-ray spectrometer +</p> +!! end + +# this example taken from [[en:Flaming Pie]] (bug 49926) +!! test +Italics and possessives (2) +!! input +'''''Flaming Pie''''' is ... released in 1997. In ''Flaming Pie'''s liner notes +!! result +<p><i><b>Flaming Pie</b></i> is ... released in 1997. In <i>Flaming Pie'</i>s liner notes +</p> +!! end +# this example taken from [[en:Dictionary]] (bug 49926) +!! test +Italics and possessives (3) +!! input +The first monolingual dictionary written in a Romance language was ''Sebastián Covarrubias''' ''Tesoro de la lengua castellana o española'', published in 1611 in Madrid. In 1612 the first edition of the ''Vocabolario dell'[[Accademia della Crusca]]'', for Italian, was published. In 1690 in Rotterdam was published, posthumously, the ''Dictionnaire Universel''. +!! result +<p>The first monolingual dictionary written in a Romance language was <i>Sebastián Covarrubias'</i> <i>Tesoro de la lengua castellana o española</i>, published in 1611 in Madrid. In 1612 the first edition of the <i>Vocabolario dell'<a href="/index.php?title=Accademia_della_Crusca&action=edit&redlink=1" class="new" title="Accademia della Crusca (page does not exist)">Accademia della Crusca</a></i>, for Italian, was published. In 1690 in Rotterdam was published, posthumously, the <i>Dictionnaire Universel</i>. +</p> !! end + ### ### 2-quote opening sequence tests ### @@ -258,13 +532,26 @@ Italics and bold: 2-quote opening sequence: (2,4) !! test -Italics and bold: 2-quote opening sequence: (2,5) +Italics and bold: 2-quote opening sequence: (2,5) (php) +!! options +php !! input ''foo''''' !! result <p><i>foo</i> </p> !!end +# The PHP parser strips the empty tags out for giggles; parsoid doesn't. +!! test +Italics and bold: 2-quote opening sequence: (2,5) (parsoid) +!! options +parsoid +!! input +''foo''''' +!! result +<p><i>foo</i><b></b> +</p> +!!end ### @@ -302,13 +589,26 @@ Italics and bold: 3-quote opening sequence: (3,4) !! test -Italics and bold: 3-quote opening sequence: (3,5) +Italics and bold: 3-quote opening sequence: (3,5) (php) +!! options +php !! input '''foo''''' !! result <p><b>foo</b> </p> !!end +# The PHP parser strips the empty tags out for giggles; parsoid doesn't. +!! test +Italics and bold: 3-quote opening sequence: (3,5) (parsoid) +!! options +parsoid +!! input +'''foo''''' +!! result +<p><b>foo</b><i></i> +</p> +!!end ### @@ -346,13 +646,26 @@ Italics and bold: 4-quote opening sequence: (4,4) !! test -Italics and bold: 4-quote opening sequence: (4,5) +Italics and bold: 4-quote opening sequence: (4,5) (php) +!! options +php !! input ''''foo''''' !! result <p>'<b>foo</b> </p> !!end +# The PHP parser strips the empty tags out for giggles; parsoid doesn't. +!! test +Italics and bold: 4-quote opening sequence: (4,5) (parsoid) +!! options +parsoid +!! input +''''foo''''' +!! result +<p>'<b>foo</b><i></i> +</p> +!!end ### @@ -361,6 +674,7 @@ Italics and bold: 4-quote opening sequence: (4,5) !! test Italics and bold: 5-quote opening sequence: (5,2) +!! options !! input '''''foo'' !! result @@ -432,23 +746,49 @@ Italics and bold: multiple quote sequences: (2,4,4) !! test -Italics and bold: multiple quote sequences: (3,4,2) +Italics and bold: multiple quote sequences: (3,4,2) (php) +!! options +php !! input '''foo''''bar'' !! result <p><b>foo'</b>bar </p> !!end +# The PHP parser strips the empty tags out for giggles; parsoid doesn't. +!! test +Italics and bold: multiple quote sequences: (3,4,2) (parsoid) +!! options +parsoid +!! input +'''foo''''bar'' +!! result +<p><b>foo'</b>bar<i></i> +</p> +!!end !! test -Italics and bold: multiple quote sequences: (3,4,3) +Italics and bold: multiple quote sequences: (3,4,3) (php) +!! options +php !! input '''foo''''bar''' !! result <p><b>foo'</b>bar </p> !!end +# The PHP parser strips the empty tags out for giggles; parsoid doesn't. +!! test +Italics and bold: multiple quote sequences: (3,4,3) (parsoid) +!! options +parsoid +!! input +'''foo''''bar''' +!! result +<p><b>foo'</b>bar<b></b> +</p> +!!end ### ### other quote tests @@ -485,6 +825,7 @@ Italics and bold: other quote tests: (3,2,3,2) !! test Italics and bold: other quote tests: (3,2,3,3) +!! options !! input '''this is about ''foo'''s family''' !! result @@ -512,6 +853,23 @@ The ''[[Main Page]]'''s talk page. </p> !! end +!! test +Parsoid only: Quote balancing context should be restricted to td/th cells on the same wikitext line +(Requires tidy for PHP parser output to be fixed up) +!! options +parsoid=wt2html,wt2wt +!! input +{| +!''a!!''b +|''a||''b +|} +!! result +<table> +<tbody><tr><th><i>a</i></th><th><i>b</i></th> +<td><i>a</i></td><td><i>b</i></td></tr> +</tbody></table> +!! end + ### ### Non-html5 tags ### @@ -533,6 +891,74 @@ Non-html5 tags should be accepted </p> !! end +!! test +<wbr> is valid wikitext (bug 52468) +!! input +<wbr> +!! result +<p><wbr /> +</p> +!! end + +# <strike> is HTML4, <s> is HTML4/5. +!! test +<s> or <strike> for strikethrough +!! input +<strike>strike</strike> + +<s>s</s> +!! result +<p><strike>strike</strike> +</p><p><s>s</s> +</p> +!! end + +!! test +Non-word characters don't terminate tag names (bug 17663, 40670, 52022) +!! input +<b→> doesn't work! </b> + +<bä> doesn't work! </b> + +<boo> works fine </b> + +<s.foo>foo</s> + +<s.foo>s.foo</s.foo> + +<sub-ID#1> +!! result +<p><b→> doesn't work! </b> +</p><p><bä> doesn't work! </b> +</p><p><boo> works fine </b> +</p><p><s.foo>foo</s> +</p><p><s.foo>s.foo</s.foo> +</p><p><sub-ID#1> +</p> +!! end + +### +### Special characters +### + +!! test +Bare pipe character (bug 52363) +!! input +| +!! result +<p>| +</p> +!! end + +!! test +Bare pipe character from a template (bug 52363) +!! input +{{pipe}} +!! result +<p>| +</p> +!! end + ### ### <nowiki> test cases ### @@ -579,15 +1005,24 @@ nowiki 3 *There is not nowiki. *There is <nowiki>nowiki</nowiki>. !! result -<dl><dd>There is not nowiki. -</dd><dd>There is nowiki. -</dd></dl> -<ol><li>There is not nowiki. -</li><li>There is nowiki. -</li></ol> -<ul><li>There is not nowiki. -</li><li>There is nowiki. -</li></ul> +<dl> +<dd>There is not nowiki. +</dd> +<dd>There is nowiki. +</dd> +</dl> +<ol> +<li>There is not nowiki. +</li> +<li>There is nowiki. +</li> +</ol> +<ul> +<li>There is not nowiki. +</li> +<li>There is nowiki. +</li> +</ul> !! end @@ -600,6 +1035,16 @@ Entities inside <nowiki> </p> !! end +!! test +Entities inside template parameters +!! options +parsoid +!! input +{{echo|–}} +!! result +<p><span typeof="mw:Transclusion mw:Entity" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&ndash;"}},"i":0}}]}'>–</span> +</p> +!! end ### ### Comments @@ -781,7 +1226,7 @@ b !! end ### -### paragraph wraping tests +### paragraph wrapping tests ### !! test No block tags @@ -794,8 +1239,9 @@ b </p><p>b </p> !! end + !! test -Block tag on one line +Block tag on one line (<div>) !! input a <div>foo</div> @@ -807,7 +1253,19 @@ a <div>foo</div> !! end !! test -Block tag on both lines +Block tag on one line (<blockquote>) +!! input +a <blockquote>foo</blockquote> + +b +!! result +a <blockquote>foo</blockquote> +<p>b +</p> +!! end + +!! test +Block tag on both lines (<div>) !! input a <div>foo</div> @@ -819,6 +1277,18 @@ b <div>foo</div> !! end !! test +Block tag on both lines (<blockquote>) +!! input +a <blockquote>foo</blockquote> + +b <blockquote>foo</blockquote> +!! result +a <blockquote>foo</blockquote> +b <blockquote>foo</blockquote> + +!! end + +!! test Multiple lines without block tags !! input <div>foo</div> a @@ -837,7 +1307,7 @@ x <div>foo</div> z !! end !! test -Empty lines between block tags to test open p-tags are closed between the block tags +Empty lines between lines with block tags !! input <div></div> @@ -845,6 +1315,12 @@ Empty lines between block tags to test open p-tags are closed between the block <div></div>a b +<div>a</div>b + +<div>b</div>d + + +<div>e</div> !! result <div></div> <p><br /> @@ -852,6 +1328,12 @@ b <div></div>a <p>b </p> +<div>a</div>b +<div>b</div>d +<p><br /> +</p> +<div>e</div> + !! end ### @@ -875,6 +1357,22 @@ And a <a href="/wiki/Main_Page" title="Main Page">link</a> !! end !! test +Tabs don't trigger preformatted text +!! input + This is not + preformatted text. + This is preformatted text. + So is this. +!! result +<p> This is not + preformatted text. +</p> +<pre>This is preformatted text. + So is this. +</pre> +!! end + +!! test Ident preformatting with inline content !! input a @@ -916,17 +1414,61 @@ Regression with preformatted in <center> !! end -# Expected output in the following test is not really expected (there should be -# <pre> in the output) -- it's only testing for well-formedness. !! test -Bug 6200: Preformatted in <blockquote> +Bug 52763: Preformatted in <blockquote> !! input <blockquote> Blah </blockquote> !! result <blockquote> - Blah +<p> Blah +</p> +</blockquote> + +!! end + +!! test +Bug 51086: Double newlines in blockquotes should be turned into paragraphs +!! input +<blockquote> +Foo + +Bar +</blockquote> +!! result +<blockquote> +<p>Foo +</p><p>Bar +</p> +</blockquote> + +!! end + +!! test +Bug 15491: <ins>/<del> in blockquote +!! input +<blockquote> +Foo <del>bar</del> <ins>baz</ins> quux +</blockquote> +!! result +<blockquote> +<p>Foo <del>bar</del> <ins>baz</ins> quux +</p> +</blockquote> + +!! end + +# Note that the p-wrapping is newline sensitive, which could be +# considered a bug: tidy will wrap only the 'Foo' in the example +# below in a <p> tag. (see comment 23-25 of bug #6200) +!! test +Bug 15491: <ins>/<del> in blockquote (2) +!! input +<blockquote>Foo <del>bar</del> <ins>baz</ins> quux +</blockquote> +!! result +<blockquote>Foo <del>bar</del> <ins>baz</ins> quux </blockquote> !! end @@ -1156,53 +1698,224 @@ Templates: Indent-Pre: 1f: Wrapping should be based on expanded content </pre> !!end +# TODO / maybe: fix wt2wt for this !! test -Templates: Single-line variant of parameter whitespace stripping test +Parsoid: Don't paragraph-wrap fosterable content +!! options +parsoid=wt2html !! input -{{echo| a}} +{| +<td></td> +<td></td> -{{echo|1= a}} -{{echo|{{echo| a}}}} -{{echo|1={{echo| a}}}} +|} +!! result +<table> + +<tbody> +<tr> +<td></td> + +<td></td></tr> + + + +</tbody></table> +!! end + +!! test +Parsoid: Don't paragraph-wrap fosterable content even if table syntax is unbalanced +!! options +parsoid=wt2html +!! input +{| +<td> +<td> +</td> + + + +|} +!! result +<table> + +<tbody> +<tr> +<td></td> + +<td> +</td></tr> + + + +</tbody></table> +!! end + + +#-------------------------------------------------------------------- +# Transclusion parameter whitespace stripping tests +# Behavior is different for positional and named parameters +#-------------------------------------------------------------------- +!! test +Templates: Strip leading and trailing whitespace from named-param values +!! input +{{echo|1= a }} + +{{echo|1= {{echo|b}} }} + +{{echo| 1 = + c }} + +{{echo| 1 = +* d +}} !! result -<pre>a -</pre> -<p>a -</p> -<pre>a -</pre> <p>a +</p><p>b +</p><p>c </p> +<ul> +<li> d +</li> +</ul> + !! end !! test -Templates: Strip whitespace from named parameters, but not positional ones +Templates: Don't strip whitespace from positional-param values !! input -{{echo| - foo}} +{{echo|a }} + +{{echo|{{echo|b}} }} + +{{echo| c +}} + +{{echo| {{echo|d}} +}} {{echo| -* foo}} + e}} -{{echo| 1 = - foo}} +{{echo| +* f}} -{{echo| 1 = -* foo}} +{{echo| + }}g !! result -<pre>foo +<p>a +</p><p>b +</p> +<pre>c </pre> <p><br /> </p> -<ul><li> foo -</li></ul> +<pre>d +</pre> +<p><br /> +</p> +<pre>e +</pre> +<p><br /> +</p> +<ul> +<li> f +</li> +</ul> +<p><br /> +</p> +<pre>g +</pre> +!! end + +!! test +Templates: Handle empty comment-and-ws-only lines correctly +!! input +{{echo|foo +<!--should be ignored--> + <!--should be ignored as well--> +bar}} +!! result <p>foo +bar </p> -<ul><li> foo -</li></ul> +!! end +#-------------------------------------------------------------------- +# Transclusion parameter escaping tests +#-------------------------------------------------------------------- +!! test +Templates: Parsoid parameter escaping test 1 +!! options +parsoid +!! input +{{echo|[foo]|{{echo|[bar]}}}} +!! result +<p about="#mwt1" typeof="mw:Transclusion" +data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[foo]"},"2":{"wt":"{{echo|[bar]}}"}},"i":0}}]}'>[foo]</p> +!! end + +!! test +Parsoid: Pipes in external links in template parameter +!! options +parsoid +!! input +{{echo|[{{echo|http://example.com}} link]}} +!! result +<p><a rel="mw:ExtLink" href="http://example.com" about="#mwt31" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[{{echo|http://example.com}} link]"}},"i":0}}]}'>link</a></p> +!! end + +!! test +Parsoid: pipe in transclusion parameter +!! options +parsoid +!! input +{{echo|http://foo.com/a|b}} +!! result +<p><a rel="mw:ExtLink" href="http://foo.com/a|b" about="#mwt1" +typeof="mw:Transclusion" +data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"http://foo.com/a&#124;b"}},"i":0}}]}'>http://foo.com/a|b</a></p> +!! end + +!! test +Parsoid: Pipe in external link target and content in template parameter +!! options +parsoid=html2wt,wt2wt +!! input +{{echo|[http://foo.com/a|b a|b]}} +!! result +<p><a rel="mw:ExtLink" href="http://foo.com/a|b" about="#mwt1" +typeof="mw:Transclusion" +data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"}, +"params":{"1":{"wt":"[http://foo.com/a|b a|b]"}},"i":0}}]}'>a|b</a></p> +!! end + +!! test +Templates: Dont escape already nowiki-escaped text in template parameters +!! options +parsoid=html2wt,wt2wt +!! input +{{echo|foo<nowiki>|</nowiki>bar}} +{{echo|<nowiki><div></nowiki>}} +{{echo|<nowiki></nowiki>}} +!! result +<p><span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo<nowiki>|</nowiki>bar"}},"i":0}}]}'}'>foo</span><span typeof="mw:Nowiki" about="#mwt1">|</span><span about="#mwt1">bar</span> +<span typeof="mw:Transclusion mw:Nowiki" about="#mwt2" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<nowiki>&lt;div&gt;</nowiki>"}},"i":0}}]}'><span typeof="mw:Entity"><</span>div<span typeof="mw:Entity">></span></span> +<span typeof="mw:Transclusion mw:Nowiki" about="#mwt3" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<nowiki></nowiki>"}},"i":0}}]}'></span> +</p> +!! end + +## Bug 52824 +!! test +Templates: '=' char in nested transclusions should not trigger nowiki escapes or conversion to named param +!! options +parsoid=html2wt,wt2wt +!! input +{{echo|{{echo|1=bar}}}} +!! result +<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"{{echo|1=bar}}"}},"i":0}}]}'>bar</p> !! end ### @@ -1249,6 +1962,20 @@ c !!end !!test +1d. Indent-Pre and Comments +(Pre-handler currently cannot distinguish between comment/ws order and normalizes them to [comment,ws] order) +!!input +<!--a--> a + + <!--b-->b +!!result +<pre>a +</pre> +<pre>b +</pre> +!!end + +!!test 2a. Indent-Pre and tables !!input {| @@ -1307,10 +2034,12 @@ c !!input <p> foo </p> <div> foo </div> + <blockquote> foo </blockquote> <span> foo </span> !!result <p> foo </p> <div> foo </div> + <blockquote> foo </blockquote> <pre><span> foo </span> </pre> !!end @@ -1334,6 +2063,12 @@ c foo </blockquote> +<blockquote> +<pre> +foo +</pre> +</blockquote> + <table><tr><td> foo </td></tr></table> @@ -1355,7 +2090,13 @@ c </pre> </center> <blockquote> - foo +<p> foo +</p> +</blockquote> +<blockquote> +<pre> +foo +</pre> </blockquote> <table><tr><td> <pre>foo @@ -1400,6 +2141,56 @@ b </pre> !! end +!! test +6. Pre-blocks should extend across lines with leading WS even when there is no wrappable content +!! input + a + + <!-- continue --> + b + + c + +d +!! result +<pre>a + +b +</pre> +<pre>c + +</pre> +<p>d +</p> +!! end + +!! test +7a. Indent-pre and category links +!! options +parsoid=wt2html,wt2wt +!! input + [[Category:foo]] <!-- No pre-wrapping --> +{{echo| [[Category:foo]]}} <!-- No pre-wrapping --> +!! result + <link rel="mw:WikiLink/Category" href="./Category:Foo"> <!-- No pre-wrapping --> +<span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":" [[Category:foo]]"}},"i":0}}]}'> </span> +<link rel="mw:WikiLink/Category" href="./Category:Foo" about="#mwt1"> <!-- No pre-wrapping --> +!! end + +!! test +7b. Indent-pre and category links +!! options +parsoid=wt2html,wt2wt +!! input + [[Category:foo]] a + [[Category:foo]] {{echo|b}} +!! result +<pre> +<link rel="mw:WikiLink/Category" href="./Category:Foo"> a + +<link rel="mw:WikiLink/Category" href="./Category:Foo"> <span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"b"}},"i":0}}]}'>b</span></pre> +!! end + ### ### HTML-pre (some to spec PHP parser behavior and some Parsoid-RT-centric) ### @@ -1482,8 +2273,11 @@ Simple definition !! input ; name : Definition !! result -<dl><dt> name </dt><dd> Definition -</dd></dl> +<dl> +<dt> name </dt> +<dd> Definition +</dd> +</dl> !! end @@ -1492,8 +2286,10 @@ Definition list for indentation only !! input : Indented text !! result -<dl><dd> Indented text -</dd></dl> +<dl> +<dd> Indented text +</dd> +</dl> !! end @@ -1502,8 +2298,11 @@ Definition list with no space !! input ;name:Definition !! result -<dl><dt>name</dt><dd>Definition -</dd></dl> +<dl> +<dt>name</dt> +<dd>Definition +</dd> +</dl> !!end @@ -1512,8 +2311,11 @@ Definition list with URL link !! input ; http://example.com/ : definition !! result -<dl><dt> <a rel="nofollow" class="external free" href="http://example.com/">http://example.com/</a> </dt><dd> definition -</dd></dl> +<dl> +<dt> <a rel="nofollow" class="external free" href="http://example.com/">http://example.com/</a> </dt> +<dd> definition +</dd> +</dl> !! end @@ -1522,8 +2324,11 @@ Definition list with bracketed URL link !! input ;[http://www.example.com/ Example]:Something about it !! result -<dl><dt><a rel="nofollow" class="external text" href="http://www.example.com/">Example</a></dt><dd>Something about it -</dd></dl> +<dl> +<dt><a rel="nofollow" class="external text" href="http://www.example.com/">Example</a></dt> +<dd>Something about it +</dd> +</dl> !! end @@ -1532,8 +2337,11 @@ Definition list with wikilink containing colon !! input ; [[Help:FAQ]]: The least-read page on Wikipedia !! result -<dl><dt> <a href="/index.php?title=Help:FAQ&action=edit&redlink=1" class="new" title="Help:FAQ (page does not exist)">Help:FAQ</a></dt><dd> The least-read page on Wikipedia -</dd></dl> +<dl> +<dt> <a href="/index.php?title=Help:FAQ&action=edit&redlink=1" class="new" title="Help:FAQ (page does not exist)">Help:FAQ</a></dt> +<dd> The least-read page on Wikipedia +</dd> +</dl> !! end @@ -1543,8 +2351,11 @@ Definition list with news link containing colon !! input ; news:alt.wikipedia.rox: This isn't even a real newsgroup! !! result -<dl><dt> <a rel="nofollow" class="external free" href="news:alt.wikipedia.rox">news:alt.wikipedia.rox</a></dt><dd> This isn't even a real newsgroup! -</dd></dl> +<dl> +<dt> <a rel="nofollow" class="external free" href="news:alt.wikipedia.rox">news:alt.wikipedia.rox</a></dt> +<dd> This isn't even a real newsgroup! +</dd> +</dl> !! end @@ -1553,8 +2364,10 @@ Malformed definition list with colon !! input ; news:alt.wikipedia.rox -- don't crash or enter an infinite loop !! result -<dl><dt> <a rel="nofollow" class="external free" href="news:alt.wikipedia.rox">news:alt.wikipedia.rox</a> -- don't crash or enter an infinite loop -</dt></dl> +<dl> +<dt> <a rel="nofollow" class="external free" href="news:alt.wikipedia.rox">news:alt.wikipedia.rox</a> -- don't crash or enter an infinite loop +</dt> +</dl> !! end @@ -1563,8 +2376,11 @@ Definition lists: colon in external link text !! input ; [http://www.wikipedia2.org/ Wikipedia : The Next Generation]: OK, I made that up !! result -<dl><dt> <a rel="nofollow" class="external text" href="http://www.wikipedia2.org/">Wikipedia : The Next Generation</a></dt><dd> OK, I made that up -</dd></dl> +<dl> +<dt> <a rel="nofollow" class="external text" href="http://www.wikipedia2.org/">Wikipedia : The Next Generation</a></dt> +<dd> OK, I made that up +</dd> +</dl> !! end @@ -1573,8 +2389,10 @@ Definition lists: colon in HTML attribute !! input ;<b style="display: inline">bold</b> !! result -<dl><dt><b style="display: inline">bold</b> -</dt></dl> +<dl> +<dt><b style="display: inline">bold</b> +</dt> +</dl> !! end @@ -1583,8 +2401,11 @@ Definition lists: self-closed tag !! input ;one<br/>two : two-line fun !! result -<dl><dt>one<br />two </dt><dd> two-line fun -</dd></dl> +<dl> +<dt>one<br />two </dt> +<dd> two-line fun +</dd> +</dl> !! end @@ -1613,16 +2434,19 @@ Definition and unordered list using wiki syntax nested in unordered list using h <ul><li> ; term : description * unordered -</li> -</ul> +</li></ul> !! result <ul><li> -<dl><dt> term </dt><dd> description -</dd></dl> -<ul><li> unordered -</li></ul> +<dl> +<dt> term </dt> +<dd> description +</dd> +</dl> +<ul> +<li> unordered </li> </ul> +</li></ul> !! end @@ -1633,8 +2457,11 @@ Definition list with empty definition and following paragraph ; term: Paragraph text !! result -<dl><dt> term</dt><dd> -</dd></dl> +<dl> +<dt> term</dt> +<dd> +</dd> +</dl> <p>Paragraph text </p> !! end @@ -1663,10 +2490,14 @@ Definition Lists: No nesting: Multiple dd's :a :b !! result -<dl><dt>x -</dt><dd>a -</dd><dd>b -</dd></dl> +<dl> +<dt>x +</dt> +<dd>a +</dd> +<dd>b +</dd> +</dl> !! end @@ -1677,12 +2508,18 @@ Definition Lists: Indentation: Regular ::i2 :::i3 !! result -<dl><dd>i1 -<dl><dd>i2 -<dl><dd>i3 -</dd></dl> -</dd></dl> -</dd></dl> +<dl> +<dd>i1 +<dl> +<dd>i2 +<dl> +<dd>i3 +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> !! end @@ -1692,11 +2529,17 @@ Definition Lists: Indentation: Missing 1st level ::i2 :::i3 !! result -<dl><dd><dl><dd>i2 -<dl><dd>i3 -</dd></dl> -</dd></dl> -</dd></dl> +<dl> +<dd><dl> +<dd>i2 +<dl> +<dd>i3 +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> !! end @@ -1705,10 +2548,16 @@ Definition Lists: Indentation: Multi-level indent !! input :::i3 !! result -<dl><dd><dl><dd><dl><dd>i3 -</dd></dl> -</dd></dl> -</dd></dl> +<dl> +<dd><dl> +<dd><dl> +<dd>i3 +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> !! end @@ -1732,6 +2581,21 @@ should be left alone should be left alone </p> !! end + +# Bug 52473 +!! test +Definition Lists: Hacky use to indent tables (WS-insensitive) +!! options +parsoid +!! input +: {| +|a +|} +!! result +<dl> +<dd> <table><tr><td>a</td></tr></table> </dd> +</dl> +!! end ## The PHP parser treats : items (dd) without a corresponding ; item (dt) ## as an empty dt item. It also ignores all but the last ";" when followed ## by ":" later on. So, ";" are not ignored in ";;;t3" but are ignored in @@ -1783,13 +2647,17 @@ Table / list interaction: indented table with lists in table contents <tr> <td> a -<ul><li> b -</li></ul> +<ul> +<li> b +</li> +</ul> </td></tr> <tr> <td> c -<ul><li> d -</li></ul> +<ul> +<li> d +</li> +</ul> </td></tr></table></dd></dl> !! end @@ -1812,18 +2680,27 @@ Table / list interaction: lists nested in tables nested in indented lists <dl><dd><table> <tr> <td> -<dl><dd>a -</dd><dd>b -</dd></dl> +<dl> +<dd>a +</dd> +<dd>b +</dd> +</dl> </td> <td> -<ul><li>c -</li><li>d -</li></ul> +<ul> +<li>c +</li> +<li>d +</li> +</ul> </td></tr></table></dd></dl> -<ul><li>e -</li><li>f -</li></ul> +<ul> +<li>e +</li> +<li>f +</li> +</ul> !!end @@ -1911,32 +2788,75 @@ Definition Lists: Nesting: Test 4 ::;t3 :::d3 !! result -<dl><dd><dl><dd><dl><dt>t3 -</dt><dd>d3 -</dd></dl> -</dd></dl> -</dd></dl> +<dl> +<dd><dl> +<dd><dl> +<dt>t3 +</dt> +<dd>d3 +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> !! end +## The Parsoid team believes the following three test exposes a +## bug in the PHP parser. (Parsoid team thinks the PHP parser is +## wrong to close the <dl> after the <dt> containing the <ul>.) !! test -Definition Lists: Mixed Lists: Test 1 +Definition Lists: Mixed Lists: Test 1 (php) +!! options +php !! input :;* foo ::* bar :; baz !! result -<dl><dd><dl><dt><ul><li> foo -</li><li> bar -</li></ul> -</dt></dl> -<dl><dt> baz -</dt></dl> -</dd></dl> +<dl> +<dd><dl> +<dt><ul> +<li> foo +</li> +<li> bar +</li> +</ul> +</dt> +</dl> +<dl> +<dt> baz +</dt> +</dl> +</dd> +</dl> !! end - +!! test +Definition Lists: Mixed Lists: Test 1 (parsoid) +!! options +parsoid +!! input +:;* foo +::* bar +:; baz +!! result +<dl> +<dd><dl> +<dt><ul> +<li> foo +</li> +</ul></dt> +<dd><ul> +<li> bar +</li> +</ul></dd> +<dt> baz</dt> +</dl></dd> +</dl> +!! end !! test Definition Lists: Mixed Lists: Test 2 @@ -1944,10 +2864,15 @@ Definition Lists: Mixed Lists: Test 2 *: d1 *: d2 !! result -<ul><li><dl><dd> d1 -</dd><dd> d2 -</dd></dl> -</li></ul> +<ul> +<li><dl> +<dd> d1 +</dd> +<dd> d2 +</dd> +</dl> +</li> +</ul> !! end @@ -1958,12 +2883,21 @@ Definition Lists: Mixed Lists: Test 3 *::: d1 *::: d2 !! result -<ul><li><dl><dd><dl><dd><dl><dd> d1 -</dd><dd> d2 -</dd></dl> -</dd></dl> -</dd></dl> -</li></ul> +<ul> +<li><dl> +<dd><dl> +<dd><dl> +<dd> d1 +</dd> +<dd> d2 +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> +</li> +</ul> !! end @@ -1974,10 +2908,17 @@ Definition Lists: Mixed Lists: Test 4 *;d1 :d2 *;d3 :d4 !! result -<ul><li><dl><dt>d1 </dt><dd>d2 -</dd><dt>d3 </dt><dd>d4 -</dd></dl> -</li></ul> +<ul> +<li><dl> +<dt>d1 </dt> +<dd>d2 +</dd> +<dt>d3 </dt> +<dd>d4 +</dd> +</dl> +</li> +</ul> !! end @@ -1988,11 +2929,17 @@ Definition Lists: Mixed Lists: Test 5 *:d1 *:: d2 !! result -<ul><li><dl><dd>d1 -<dl><dd> d2 -</dd></dl> -</dd></dl> -</li></ul> +<ul> +<li><dl> +<dd>d1 +<dl> +<dd> d2 +</dd> +</dl> +</dd> +</dl> +</li> +</ul> !! end @@ -2003,13 +2950,23 @@ Definition Lists: Mixed Lists: Test 6 #*:d1 #*::: d3 !! result -<ol><li><ul><li><dl><dd>d1 -<dl><dd><dl><dd> d3 -</dd></dl> -</dd></dl> -</dd></dl> -</li></ul> -</li></ol> +<ol> +<li><ul> +<li><dl> +<dd>d1 +<dl> +<dd><dl> +<dd> d3 +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> +</li> +</ul> +</li> +</ol> !! end @@ -2020,10 +2977,15 @@ Definition Lists: Mixed Lists: Test 7 :* d1 :* d2 !! result -<dl><dd><ul><li> d1 -</li><li> d2 -</li></ul> -</dd></dl> +<dl> +<dd><ul> +<li> d1 +</li> +<li> d2 +</li> +</ul> +</dd> +</dl> !! end @@ -2034,12 +2996,20 @@ Definition Lists: Mixed Lists: Test 8 :* d1 ::* d2 !! result -<dl><dd><ul><li> d1 -</li></ul> -<dl><dd><ul><li> d2 -</li></ul> -</dd></dl> -</dd></dl> +<dl> +<dd><ul> +<li> d1 +</li> +</ul> +<dl> +<dd><ul> +<li> d2 +</li> +</ul> +</dd> +</dl> +</dd> +</dl> !! end @@ -2049,9 +3019,14 @@ Definition Lists: Mixed Lists: Test 9 !! input *;foo :bar !! result -<ul><li><dl><dt>foo </dt><dd>bar -</dd></dl> -</li></ul> +<ul> +<li><dl> +<dt>foo </dt> +<dd>bar +</dd> +</dl> +</li> +</ul> !! end @@ -2061,51 +3036,172 @@ Definition Lists: Mixed Lists: Test 10 !! input *#;foo :bar !! result -<ul><li><ol><li><dl><dt>foo </dt><dd>bar -</dd></dl> -</li></ol> -</li></ul> +<ul> +<li><ol> +<li><dl> +<dt>foo </dt> +<dd>bar +</dd> +</dl> +</li> +</ol> +</li> +</ul> !! end +# The Parsoid team disagrees with the PHP parser's seemingly-random +# rules regarding dd/dt on the next two tests. Parsoid is more +# consistent, and recognizes the shared nesting and keeps the +# still-open tags around until the nesting is complete. !! test -Definition Lists: Mixed Lists: Test 11 +Definition Lists: Mixed Lists: Test 11 (php) +!! options +php !! input *#*#;*;;foo :bar *#*#;boo :baz !! result -<ul><li><ol><li><ul><li><ol><li><dl><dt>foo </dt><dd><ul><li><dl><dt><dl><dt>bar -</dt></dl> -</dd></dl> -</li></ul> -</dd></dl> -<dl><dt>boo </dt><dd>baz -</dd></dl> -</li></ol> -</li></ul> -</li></ol> -</li></ul> +<ul> +<li><ol> +<li><ul> +<li><ol> +<li><dl> +<dt>foo </dt> +<dd><ul> +<li><dl> +<dt><dl> +<dt>bar +</dt> +</dl> +</dd> +</dl> +</li> +</ul> +</dd> +</dl> +<dl> +<dt>boo </dt> +<dd>baz +</dd> +</dl> +</li> +</ol> +</li> +</ul> +</li> +</ol> +</li> +</ul> !! end +!! test +Definition Lists: Mixed Lists: Test 11 (parsoid) +!! options +parsoid +!! input +*#*#;*;;foo :bar +*#*#;boo :baz +!! result +<ul> +<li> +<ol> +<li> +<ul> +<li> +<ol> +<li> +<dl> +<dt> +<ul> +<li> +<dl> +<dt> +<dl> +<dt>foo<span typeof="mw:Placeholder" data-parsoid='{"src":" "}'> </span></dt> +<dd data-parsoid='{"stx":"row"}'>bar</dd> +</dl></dt> +</dl></li> +</ul></dt> +<dt>boo<span typeof="mw:Placeholder" data-parsoid='{"src":" "}'> </span></dt> +<dd data-parsoid='{"stx":"row"}'>baz</dd> +</dl></li> +</ol></li> +</ul></li> +</ol></li> +</ul> +!! end !! test -Definition Lists: Weird Ones: Test 1 +Definition Lists: Weird Ones: Test 1 (php) +!! options +php !! input *#;*::;; foo : bar (who uses this?) !! result -<ul><li><ol><li><dl><dt> foo </dt><dd><ul><li><dl><dd><dl><dd><dl><dt><dl><dt> bar (who uses this?) -</dt></dl> -</dd></dl> -</dd></dl> -</dd></dl> -</li></ul> -</dd></dl> -</li></ol> -</li></ul> +<ul> +<li><ol> +<li><dl> +<dt> foo </dt> +<dd><ul> +<li><dl> +<dd><dl> +<dd><dl> +<dt><dl> +<dt> bar (who uses this?) +</dt> +</dl> +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> +</li> +</ul> +</dd> +</dl> +</li> +</ol> +</li> +</ul> !! end +!! test +Definition Lists: Weird Ones: Test 1 (parsoid) +!! options +parsoid +!! input +*#;*::;; foo : bar (who uses this?) +!! result +<ul> +<li> +<ol> +<li> +<dl> +<dt> +<ul> +<li> +<dl> +<dd> +<dl> +<dd> +<dl> +<dt> +<dl> +<dt> foo<span typeof="mw:Placeholder" data-parsoid='{"src":" "}'> </span></dt> +<dd data-parsoid='{"stx":"row"}'> bar (who uses this?)</dd> +</dl></dt> +</dl></dd> +</dl></dd> +</dl></li> +</ul></dt> +</dl></li> +</ol></li> +</ul> +!! end ### ### External links @@ -2270,6 +3366,17 @@ External image from https: https://meta.wikimedia.org/upload/f/f1/Ncwikicol.png !! end !! test +External image (when not allowed) +!! options +wgAllowExternalImages=0 +!! input +External image: http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png +!! result +<p>External image: <a rel="nofollow" class="external free" href="http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png">http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png</a> +</p> +!! end + +!! test Link to non-http image, no img tag !! input Link to non-http image, no img tag: ftp://example.com/test.jpg @@ -2692,6 +3799,15 @@ External link containing double-single-quotes with no space separating the url f !! end !! test +External link with comments in link text +!! input +[http://www.google.com Google <!-- comment -->] +!! result +<p><a rel="nofollow" class="external text" href="http://www.google.com">Google </a> +</p> +!! end + +!! test URL-encoding in URL functions (single parameter) !! input {{localurl:Some page|amp=&}} @@ -2763,6 +3879,28 @@ Non-extlinks in brackets </p> !! end +!! test +Parsoid: Percent encoding in external links +!! options +parsoid +!! input +[https://github.com/search?l=&q=ResourceLoader+%40wikimedia Search] +!! result +<p><a rel="mw:ExtLink" +href="https://github.com/search?l=&q=ResourceLoader+%40wikimedia">Search</a></p> +!! end + +!! test +Parsoid: use url link syntax for links where the content is equal the link +target +!! options +parsoid +!! input +http://example.com +!! result +<p><a rel="mw:ExtLink" href="http://example.com">http://example.com</a></p> +!! end + ### ### Quotes ### @@ -2781,7 +3919,9 @@ Normal text. '''''Bold italic text.''''' Normal text. !! test -Unclosed and unmatched quotes +Unclosed and unmatched quotes (php) +!! options +php !! input '''''Bold italic text '''with bold deactivated''' in between.''''' @@ -2816,6 +3956,47 @@ Plain ''italic'''s plain </p><p>Plain <i>italic'</i>s plain </p> !! end +# Parsoid inserts an empty bold tag pair at the end of the line, that the PHP +# parser strips. The wikitext contains just the first half of the bold +# quote pair. +!! test +Unclosed and unmatched quotes (parsoid) +!! options +parsoid +!! input +'''''Bold italic text '''with bold deactivated''' in between.''''' + +'''''Bold italic text ''with italic deactivated'' in between.''''' + +'''Bold text.. + +..spanning two paragraphs (should not work).''' + +'''Bold tag left open + +''Italic tag left open + +Normal text. + +<!-- Unmatching number of opening, closing tags: --> +'''This year''''s election ''should'' beat '''last year''''s. + +''Tom'''s car is bigger than ''Susan'''s. + +Plain ''italic'''s plain +!! result +<p><i><b>Bold italic text </b>with bold deactivated<b> in between.</b></i> +</p><p><b><i>Bold italic text </i>with italic deactivated<i> in between.</i></b> +</p><p><b>Bold text..</b> +</p><p>..spanning two paragraphs (should not work).<b></b> +</p><p><b>Bold tag left open</b> +</p><p><i>Italic tag left open</i> +</p><p>Normal text. +</p><p><b>This year'</b>s election <i>should</i> beat <b>last year'</b>s. +</p><p><i>Tom<b>s car is bigger than </b></i><b>Susan</b>s. +</p><p>Plain <i>italic'</i>s plain +</p> +!! end ### ### Tables @@ -2824,19 +4005,33 @@ Plain ''italic'''s plain ### # This should not produce <table></table> as <table><tr><td></td></tr></table> -# is the bare minimun required by the spec, see: +# is the bare minimum required by the spec, see: # http://www.w3.org/TR/xhtml-modularization/dtd_module_defs.html#a_module_Basic_Tables !! test -A table with no data. +A table with no data. (php) +!! options +php +!! input +{||} +!! result +!! end +# Parsoid team replies: empty table tags are legal in HTML5 +!! test +A table with no data. (parsoid) +!! options +parsoid !! input {||} !! result +<table></table> !! end # A table with nothing but a caption is invalid XHTML, we might want to render # this as <p>caption</p> !! test -A table with nothing but a caption +A table with nothing but a caption (php) +!! options +php !! input {| |+ caption @@ -2847,6 +4042,18 @@ A table with nothing but a caption </caption><tr><td></td></tr></table> !! end +# Parsoid team replies: table with only a caption is legal in HTML5 +!! test +A table with nothing but a caption (parsoid) +!! options +parsoid +!! input +{| +|+ caption +|} +!! result +<table><caption> caption</caption></table> +!! end !! test A table with caption with default-spaced attributes and a table row @@ -3243,11 +4450,44 @@ Template-generated table cell attributes and cell content !! input {| |{{table_attribs}} +| {{table_attribs}} |} !! result <table> <tr> <td style="color: red"> Foo +</td> +<td style="color: red"> Foo +</td></tr></table> + +!! end + +!! test +Template-generated table cell attributes and cell content (2) +!! input +{| +|align=center {{table_attribs}} +|} +!! result +<table> +<tr> +<td align="center" style="color: red"> Foo +</td></tr></table> + +!! end + +!! test +Template-generated table cell attributes and cell content (3) +!! input +{| +|align=center {{table_cells}} +|} +!! result +<table> +<tr> +<td align="center" style="color: red"> Foo </td> +<td> Bar </td> +<td> Baz </td></tr></table> !! end @@ -3270,21 +4510,40 @@ Table with row followed by newlines and table heading !! end +!! test +Table with empty line following the start tag +!! input +{| + +|- +| foo +|} +!! result +<table> + + +<tr> +<td> foo +</td></tr></table> + +!! end + # FIXME: Preserve the attribute properly (with an empty string as value) in # the PHP parser. Parsoid implements the behavior below. !! test Table attributes with empty value !! options -disabled +parsoid !! input {| | style=| hello |} !! result <table> +<tbody> <tr> <td style=""> hello -</td></tr></table> +</td></tr></tbody></table> !! end @@ -3311,6 +4570,159 @@ Wikitext table with a lot of comments !! end +!! test +Wikitext table with double-line table cell +!! input +{| +|a +b +|} +!! result +<table> +<tr> +<td>a +<p>b +</p> +</td></tr></table> + +!! end + +!! test +Table cell with a single comment +!! input +{| +| <!-- c1 --> +| a +|} +!! result +<table> +<tr> +<td> +</td> +<td> a +</td></tr></table> + +!! end + +# The expected HTML structure in this test is debatable. The PHP parser does +# not parse this kind of table at all. The main focus for Parsoid is on +# round-tripping, so this output is ok for now. TODO: revisit! +!! test +Wikitext table with html-syntax row (Parsoid) +!! options +parsoid +!! input +{| +|- +<td>foo</td> +|} +!! result +<table> +<tbody> +<tr> +<td>foo</td></tr></tbody></table> +!! end + +!! test +Implicit <td> after a |- +(PHP parser relies on Tidy to add the missing <td> tags) +!! options +parsoid=wt2html,wt2wt +!! input +{| +|- +a +|} +!! result +<table> +<tr><td>a</td></tr> +</table> +!! end + +!! test +Pres should be recognized in an explicit <td> context, but not in an implicit <td> context +(PHP parser relies on Tidy to add the missing <td> tags) +!! options +parsoid=wt2html,wt2wt +!! input +{| +|- +| + a +|- + b +|} +!! result +<table> +<tbody> +<tr><td><pre>a</pre></td></tr> +<tr><td> b</td></tr> +</tbody> +</table> +!! end + +!! test +Lists should be recognized in an implicit <td> context +(PHP parser relies on Tidy to add the missing <td> tags) +!! options +parsoid=wt2html,wt2wt +!! input +{| +|- +*a +|} +!! result +<table> +<tr> +<td><ul> +<li>a</li> +</ul></td> +</tr> +</table> +!! end + +!! test +Parsoid: Round-trip tables directly followed by content (bug 51219) +!! options +parsoid=wt2html,wt2wt +!! input +{| +|foo +|} bar + +{| +|baz +|}<b>quux</b> +!! result +<table><tbody> +<tr> +<td>foo</td></tr></tbody></table> bar +<table> +<tbody> +<tr> +<td>baz</td></tr></tbody></table><b>quux</b> +!! end + +!! test +Parsoid: Default to a newline after tables in new content (bug 51219) +!! options +parsoid=html2wt +!! input +{| +|foo +|} +<nowiki> </nowiki>bar +{| +|baz +|} +'''quux''' +!! result +<table><tbody> +<tr><td>foo</td></tr></tbody></table> bar +<table><tbody> +<tr><td>baz</td></tr></tbody></table><b>quux</b> +!! end + ### ### Internal links ### @@ -3342,6 +4754,15 @@ Piped link !! end !! test +Piped link with comment in link text +!! input +[[Main Page|The Main<!--front--> Page]] +!! result +<p><a href="/wiki/Main_Page" title="Main Page">The Main Page</a> +</p> +!! end + +!! test Broken link !! input [[Zigzagzogzagzig]] @@ -3462,6 +4883,22 @@ Link to namespaces </p> !! end +!! article +MemoryAlpha:AlphaTest +!! text +This is an article in the MemoryAlpha namespace +(which shadows the memoryalpha interwiki link). +!! endarticle + +!! test +Namespace takes precedence over interwiki link (bug 51680) +!! input +[[MemoryAlpha:AlphaTest]] +!! result +<p><a href="/wiki/MemoryAlpha:AlphaTest" title="MemoryAlpha:AlphaTest">MemoryAlpha:AlphaTest</a> +</p> +!! end + !! test Piped link to namespace !! input @@ -3527,6 +4964,33 @@ Link containing "<#" and ">#" as a hex sequences !! end !! test +Link containing an equals sign +!! input +[[Special:BookSources/isbn=4-00-026157-6]] +!! result +<p><a href="/wiki/Special:BookSources/isbn%3D4-00-026157-6" title="Special:BookSources/isbn=4-00-026157-6">Special:BookSources/isbn=4-00-026157-6</a> +</p> +!! end + +!! article +Foo~bar +!! text +Just a test of an article title containing a tilde. +!! endarticle + +# note that links containing signatures, like [[Foo~~~~]], are +# massaged by the pre-save transform (PST) and so the tildes are never +# seen by the parser. +!! test +Link containing a tilde +!! input +[[Foo~bar]] +!! result +<p><a href="/wiki/Foo%7Ebar" title="Foo~bar">Foo~bar</a> +</p> +!! end + +!! test Link containing double-single-quotes '' (bug 4598) !! input [[Lista d''e paise d''o munno]] @@ -3787,6 +5251,69 @@ language=kaa </p> !! end +!! article +Söfnuður +!! text +Test. +!! endarticle + +!! test +Internal link with is link prefix +!! options +language=is +!! input +Aðrir mótmælenda[[söfnuður|söfnuðir]] og +!! result +<p>Aðrir <a href="/wiki/S%C3%B6fnu%C3%B0ur" title="Söfnuður">mótmælendasöfnuðir</a> og +</p> +!! end + +!! article +Mótmælendatrú +!! text +Test. +!! endarticle + +!! test +Internal link with is link trail and link prefix +!! options +language=is +!! input +[[mótmælendatrú|xxx]]ar +[[mótmælendatrú]]ar +mótmælenda[[söfnuður]] +mótmælenda[[söfnuður|söfnuðir]] +mótmælenda[[söfnuður|söfnuðir]]xxx +!! result +<p><a href="/wiki/M%C3%B3tm%C3%A6lendatr%C3%BA" title="Mótmælendatrú">xxxar</a> +<a href="/wiki/M%C3%B3tm%C3%A6lendatr%C3%BA" title="Mótmælendatrú">mótmælendatrúar</a> +<a href="/wiki/S%C3%B6fnu%C3%B0ur" title="Söfnuður">mótmælendasöfnuður</a> +<a href="/wiki/S%C3%B6fnu%C3%B0ur" title="Söfnuður">mótmælendasöfnuðir</a> +<a href="/wiki/S%C3%B6fnu%C3%B0ur" title="Söfnuður">mótmælendasöfnuðirxxx</a> +</p> +!! end + +!! test +Parsoid link trail escaping +!! options +parsoid=html2wt,html2html +!! input +[[apple]]<nowiki/>s +!! result +<p><a rel="mw:WikiLink" href="Apple">apple</a>s</p> +!! end + +!! test +Parsoid link prefix escaping +!! options +language=is +parsoid=html2wt,html2html +!! input +Aðrir mótmælenda<nowiki/>[[söfnuður]] +!! result +<p>Aðrir mótmælenda<a rel="mw:WikiLink" href="Söfnuður">söfnuður</a></p> +!! end + !! test Parsoid-centric test: Whitespace in ext- and wiki-links should be preserved !! input @@ -3833,9 +5360,12 @@ Interwiki link encoding conversion (bug 1636) *[[Wikipedia:ro:Olteniţa]] *[[Wikipedia:ro:Olteniţa]] !! result -<ul><li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteniţa</a> -</li><li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteniţa</a> -</li></ul> +<ul> +<li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteniţa</a> +</li> +<li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteniţa</a> +</li> +</ul> !! end @@ -3848,6 +5378,12 @@ Interwiki link with fragment (bug 2130) </p> !! end + +### +### Interlanguage links +### Language links (so that searching for '### language' matches..) +### + !! test Interlanguage link !! input @@ -3905,6 +5441,189 @@ language=ln </p> !! end +!! test +Parsoid bug 53221: Wikilinks should be properly entity-escaped +!! options +parsoid=html2wt +!! input +He&nbsp;llo [[Foo|He&nbsp;llo]] + +He&nbsp;llo [[He&nbsp;llo]] +!!result +<p>He&nbsp;llo <a href="Foo" rel="mw:WikiLink">He&nbsp;llo</a></p> +<p>He&nbsp;llo <a href="He&nbsp;llo" rel="mw:WikiLink">He&nbsp;llo</a></p> +!! end + +!! test +Parsoid: handle constructor well +!! options +parsoid +!! input +[[constructor]] + +[[constructor:foo]] +!! result +<p data-parsoid="{"dsr":[0,15,0,0]}"><a rel="mw:WikiLink" href="./Constructor" data-parsoid="{"stx":"simple","a":{"href":"./Constructor"},"sa":{"href":"constructor"},"dsr":[0,15,2,2]}">constructor</a></p> + + +<p data-parsoid="{"dsr":[17,36,0,0]}"><a rel="mw:WikiLink" href="./Foo" data-parsoid="{"stx":"simple","a":{"href":"./Foo"},"sa":{"href":"constructor:foo"},"dsr":[17,36,2,2]}">constructor:foo</a></p> +!! end + +!! test +Parsoid: recognize interlanguage links without a target page +!! options +parsoid +!! input +[[ko:]] +!! result +<p> +<link rel="mw:WikiLink/Language" href="http://ko.wikipedia.org/wiki/"></p> +!! end + +!! test +Parsoid: recognize interwiki links without a target page +!! options +parsoid +!! input +[[:ko:]] +!! result +<p><a rel="mw:WikiLink/Interwiki" href="http://ko.wikipedia.org/wiki/">ko:</a></p> +!! end + +### +### Redirects, Parsoid-only +### +!! test +Simple redirect to page +!! options +parsoid +!! input +#REDIRECT [[Main Page]] +!! result +<link rel="mw:PageProp/redirect" href="./Main_Page"> +!! end + +!! test +Optional colon in #REDIRECT +!! options +# the colon is archaic syntax. we support it for wt2html, but we +# don't care that it roundtrips back to the modern syntax. +parsoid=wt2html,html2html +!! input +#REDIRECT:[[Main Page]] +!! result +<link rel="mw:PageProp/redirect" href="./Main_Page"> +!! end + +!! test +Whitespace in #REDIRECT with optional colon +!! options +# the colon and gratuitous whitespace is archaic syntax. we support +# it for wt2html, but we don't care that it roundtrips back to the +# modern syntax (without extra whitespace) +parsoid=wt2html,html2html +!! input + + #REDIRECT +: +[[Main Page]] +!! result +<link rel="mw:PageProp/redirect" href="./Main_Page"> +!! end + +!! test +Piped link in #REDIRECT +!! options +# content after piped link is ignored. we support this syntax, +# but don't care that the piped link is lost when we roundtrip this. +parsoid=wt2html +!! input +#REDIRECT [[Main Page|bar]] +!! result +<link rel="mw:PageProp/redirect" href="./Main_Page"> +!! end + +!! test +Redirect to category +!! options +parsoid=wt2html +!! input +#REDIRECT [[Category:Foo]] +!! result +<link rel="mw:PageProp/redirect" href="./Category:Foo"><link rel="mw:WikiLink/Category" href="./Category:Foo"> +!! end + +!! test +Redirect to category with URL encoding +!! options +parsoid=wt2html +!! input +#REDIRECT [[Category%3AFoo]] +!! result +<link rel="mw:PageProp/redirect" href="./Category:Foo"><link rel="mw:WikiLink/Category" href="./Category:Foo"> +!! end + +!! test +Redirect to category page +!! options +parsoid=wt2html,html2html +!! input +#REDIRECT [[:Category:Foo]] +!! result +<p><a rel="mw:WikiLink" href="Category:Foo">Category:Foo</a></p> +!! end + +!! test +Redirect to image page (1) +!! options +parsoid +!! input +#REDIRECT [[File:Wiki.png]] +!! result +<link rel="mw:PageProp/redirect" href="./File:Wiki.png"> +!! end + +!! test +Redirect to image page (2) +!! options +parsoid +!! input +#REDIRECT [[Image:Wiki.png]] +!! result +<link rel="mw:PageProp/redirect" href="./File:Wiki.png"> +!! end + +!! test +Redirect to language +!! options +parsoid +!! input +#REDIRECT [[en:File:Wiki.png]] +!! result +<link rel="mw:PageProp/redirect" href="File:Wiki.png"> +!! end + +!! test +Redirect to interwiki +!! options +parsoid +!! input +#REDIRECT [[meatball:File:Wiki.png]] +!! result +<link rel="mw:PageProp/redirect" href="File:Wiki.png"> +!! end + +!! test +Non-English #REDIRECT +!! options +parsoid +language=is +!! input +#TILVÍSUN [[Main Page]] +!! result +<link rel="mw:PageProp/redirect" href="./Main_Page"> +!! end + ## ## XHTML tidiness ### @@ -3920,6 +5639,8 @@ language=ln !! test Broken br tag sanitization +!! options +php !! input </br> !! result @@ -3927,6 +5648,17 @@ Broken br tag sanitization </p> !! end +# TODO: Fix html2html mode (bug 51055)! +!! test +Parsoid: Broken br tag recognition +!! options +parsoid=wt2html +!! input +</br> +!! result +<p><br></p> +!! end + !! test Incorrecly removing closing slashes from correctly formed XHTML !! input @@ -4023,7 +5755,7 @@ Horizontal ruler -- eats additional dashes on the same line !! end !! test -Horizontal ruler -- does not collaps dashes on consecutive lines +Horizontal ruler -- does not collapse dashes on consecutive lines !! input ---- ---- @@ -4061,10 +5793,14 @@ Common list * item 2 *item 3 !! result -<ul><li>Common list -</li><li> item 2 -</li><li>item 3 -</li></ul> +<ul> +<li>Common list +</li> +<li> item 2 +</li> +<li>item 3 +</li> +</ul> !! end @@ -4075,10 +5811,14 @@ Numbered list #item 2 # item 3 !! result -<ol><li>Numbered list -</li><li>item 2 -</li><li> item 3 -</li></ol> +<ol> +<li>Numbered list +</li> +<li>item 2 +</li> +<li> item 3 +</li> +</ol> !! end @@ -4101,35 +5841,67 @@ Mixed list *** Level 3 #** Level 3, but ordered !! result -<ul><li>Mixed list -<ol><li> with numbers -</li></ol> -<ul><li> and bullets -</li></ul> -<ol><li> and numbers -</li></ol> -</li><li>bullets again -<ul><li>bullet level 2 -<ul><li>bullet level 3 -<ol><li>Number on level 4 -</li></ol> -</li></ul> -</li><li>bullet level 2 -<ol><li>Number on level 3 -</li><li>Number on level 3 -</li></ol> -</li></ul> -<ol><li>number level 2 -</li></ol> -</li><li>Level 1 -<ul><li><ul><li> Level 3 -</li></ul> -</li></ul> -</li></ul> -<ol><li><ul><li><ul><li> Level 3, but ordered -</li></ul> -</li></ul> -</li></ol> +<ul> +<li>Mixed list +<ol> +<li> with numbers +</li> +</ol> +<ul> +<li> and bullets +</li> +</ul> +<ol> +<li> and numbers +</li> +</ol> +</li> +<li>bullets again +<ul> +<li>bullet level 2 +<ul> +<li>bullet level 3 +<ol> +<li>Number on level 4 +</li> +</ol> +</li> +</ul> +</li> +<li>bullet level 2 +<ol> +<li>Number on level 3 +</li> +<li>Number on level 3 +</li> +</ol> +</li> +</ul> +<ol> +<li>number level 2 +</li> +</ol> +</li> +<li>Level 1 +<ul> +<li><ul> +<li> Level 3 +</li> +</ul> +</li> +</ul> +</li> +</ul> +<ol> +<li><ul> +<li><ul> +<li> Level 3, but ordered +</li> +</ul> +</li> +</ul> +</li> +</ol> !! end @@ -4139,10 +5911,14 @@ Nested lists 1 *foo **bar !! result -<ul><li>foo -<ul><li>bar -</li></ul> -</li></ul> +<ul> +<li>foo +<ul> +<li>bar +</li> +</ul> +</li> +</ul> !! end @@ -4152,10 +5928,15 @@ Nested lists 2 **foo *bar !! result -<ul><li><ul><li>foo -</li></ul> -</li><li>bar -</li></ul> +<ul> +<li><ul> +<li>foo +</li> +</ul> +</li> +<li>bar +</li> +</ul> !! end @@ -4165,10 +5946,14 @@ Nested lists 3 (first element empty) * **bar !! result -<ul><li> -<ul><li>bar -</li></ul> -</li></ul> +<ul> +<li> +<ul> +<li>bar +</li> +</ul> +</li> +</ul> !! end @@ -4178,10 +5963,15 @@ Nested lists 4 (first element empty) ** *bar !! result -<ul><li><ul><li> -</li></ul> -</li><li>bar -</li></ul> +<ul> +<li><ul> +<li> +</li> +</ul> +</li> +<li>bar +</li> +</ul> !! end @@ -4191,10 +5981,15 @@ Nested lists 5 (both elements empty) ** * !! result -<ul><li><ul><li> -</li></ul> -</li><li> -</li></ul> +<ul> +<li><ul> +<li> +</li> +</ul> +</li> +<li> +</li> +</ul> !! end @@ -4204,10 +5999,14 @@ Nested lists 6 (both elements empty) * ** !! result -<ul><li> -<ul><li> -</li></ul> -</li></ul> +<ul> +<li> +<ul> +<li> +</li> +</ul> +</li> +</ul> !! end @@ -4216,10 +6015,16 @@ Nested lists 7 (skip initial nesting levels) !! input *** foo !! result -<ul><li><ul><li><ul><li> foo -</li></ul> -</li></ul> -</li></ul> +<ul> +<li><ul> +<li><ul> +<li> foo +</li> +</ul> +</li> +</ul> +</li> +</ul> !! end @@ -4231,13 +6036,21 @@ Nested lists 8 (multiple nesting transitions) ** baz * boo !! result -<ul><li> foo -<ul><li><ul><li> bar -</li></ul> -</li><li> baz -</li></ul> -</li><li> boo -</li></ul> +<ul> +<li> foo +<ul> +<li><ul> +<li> bar +</li> +</ul> +</li> +<li> baz +</li> +</ul> +</li> +<li> boo +</li> +</ul> !! end @@ -4248,10 +6061,14 @@ Nested lists 8 (multiple nesting transitions) *<!--cmt-->bar <!--cmt-->*baz !! result -<ul><li>foo -</li><li>bar -</li><li>baz -</li></ul> +<ul> +<li>foo +</li> +<li>bar +</li> +<li>baz +</li> +</ul> !! end @@ -4261,34 +6078,268 @@ Nested lists 8 (multiple nesting transitions) *foo {{echo|bar }}*baz !! result -<ul><li>foo bar -</li><li>baz -</li></ul> +<ul> +<li>foo bar +</li> +<li>baz +</li> +</ul> + +!! end + +!! test +List items are not parsed correctly following a <pre> block (bug 785) +!! input +* <pre>foo</pre> +* <pre>bar</pre> +* zar +!! result +<ul> +<li> <pre>foo</pre> +</li> +<li> <pre>bar</pre> +</li> +<li> zar +</li> +</ul> + +!! end + +!! test +List items from template +!! input + +{{inner list}} +* item 2 + +* item 0 +{{inner list}} +* item 2 + +* item 0 +* notSOL{{inner list}} +* item 2 +!! result +<ul> +<li> item 1 +</li> +<li> item 2 +</li> +</ul> +<ul> +<li> item 0 +</li> +<li> item 1 +</li> +<li> item 2 +</li> +</ul> +<ul> +<li> item 0 +</li> +<li> notSOL +</li> +<li> item 1 +</li> +<li> item 2 +</li> +</ul> + +!! end + +!! test +List interrupted by empty line or heading +!! input +* foo + +** bar +== A heading == +* Another list item +!! result +<ul> +<li> foo +</li> +</ul> +<ul> +<li><ul> +<li> bar +</li> +</ul> +</li> +</ul> +<h2><span class="mw-headline" id="A_heading">A heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: A heading">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<ul> +<li> Another list item +</li> +</ul> + +!!end + +!!test +Multiple list tags generated by templates +!!input +{{echo|<li>}}a +{{echo|<li>}}b +{{echo|<li>}}c +!!result +<li>a +<li>b +<li>c</li> +</li> +</li> + +!!end + +!!test +Single-comment whitespace lines dont break lists, and neither do multi-comment whitespace lines +!!input +*a +<!--This line will NOT split the list--> +*b + <!--This line will NOT split the list either--> +*c + <!--foo--> <!----> <!--This line NOT split the list either--> +*d +!!result +<ul> +<li>a +</li> +<li>b +</li> +<li>c +</li> +<li>d +</li> +</ul> + +!!end + +!!test +Replacing whitespace with tabs still doesn't break the list (gerrit 78327) +!!input +*a +<!--This line will NOT split the list--> +*b + <!--This line will NOT split the list either--> +*c + <!--foo--> <!----> <!--This line NOT split the list + either--> +*d +!!result +<ul> +<li>a +</li> +<li>b +</li> +<li>c +</li> +<li>d +</li> +</ul> +!!end + +!!test +Test the li-hack +(Cannot test this with PHP parser since it relies on Tidy for the hack) +!!options +parsoid=wt2html,wt2wt +!!input +* foo +* <li>li-hack +* {{echo|<li>templated li-hack}} +* <!--foo--> <li> unsupported li-hack with preceding comments + +<ul> +<li><li>not a li-hack +</li> +</ul> +!!result +<ul> +<li> foo</li> +<li>li-hack</li> +<li about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<li>templated li-hack"}}}}]}'>templated li-hack</li> +<li> <!--foo--> </li> +<li> li-hack with preceding comments</li> +</ul> + +<ul> +<li></li> +<li>not a li-hack +</li> +</ul> +!!end + +!! test +Parsoid: Make sure nested lists are serialized on their own line even if HTML contains no newlines +!! options +parsoid +!! input +# foo +## bar +* foo +** bar +: foo +:: bar +!! result +<ol> +<li> foo<ol> +<li> bar</li> +</ol></li> +</ol><ul> +<li> foo<ul> +<li> bar</li> +</ul></li> +</ul><dl> +<dd> foo<dl> +<dd> bar</dd> +</dl></dd> +</dl> !! end !! test +Parsoid: Test of whitespace serialization with Templated bullets +!! options +parsoid +!! input +* {{bullet}} +!! result +<ul> +<li> </li><li about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"bullet","href":"./Template:Bullet"},"params":{},"i":0}}]}'> Bar</li> +</ul> +!! end + +# ------------------------------------------------------------------------ +# The next set of tests are about Parsoid's ability to handle badly nested +# tags (parse, minimize scope of fixup, and roundtrip back) +# ------------------------------------------------------------------------ + +!! test Unbalanced closing block tags break a list -(Disabled since php parser generates broken html -- relies on Tidy to fix up) +(Parsoid-only since php parser generates broken html -- relies on Tidy to fix up) !! options -disabled +parsoid !! input <div> *a</div><div> *b</div> !! result <div> -<ul><li>a -</li></ul></div><div> -<ul><li>b -</li></ul></div> +<ul> +<li>a +</li> +</ul></div><div> +<ul> +<li>b +</li> +</ul></div> !! end !! test Unbalanced closing non-block tags don't break a list -(Disabled since php parser generates broken html -- relies on Tidy to fix up) +(Parsoid-only since php parser generates broken html -- relies on Tidy to fix up) !! options -disabled +parsoid !! input <span> *a</span><span> @@ -4296,23 +6347,29 @@ disabled !! result <p><span></span> </p> -<ul><li>a<span></span> -</li><li>b -</li></ul> +<ul> +<li>a<span></span> +</li> +<li>b +</li> +</ul> !! end !! test Unclosed formatting tags that straddle lists are closed and reopened -(Disabled since php parser generates broken html -- relies on Tidy to fix up) +(Parsoid-only since php parser generates broken html -- relies on Tidy to fix up) !! options -disabled +parsoid !! input # <s> a # b </s> !! result -<ol><li> <s> a </s> -</li><li> <s> b </s> -</li></ol> +<ol> +<li> <s> a </s> +</li> +<li> <s> b </s> +</li> +</ol> !! end !!test @@ -4335,88 +6392,31 @@ parsoid !!end !! test -List items are not parsed correctly following a <pre> block (bug 785) -!! input -* <pre>foo</pre> -* <pre>bar</pre> -* zar -!! result -<ul><li> <pre>foo</pre> -</li><li> <pre>bar</pre> -</li><li> zar -</li></ul> - -!! end - -!! test -List items from template +Table with missing opening <tr> tag +!! options +parsoid=wt2html,wt2wt !! input - -{{inner list}} -* item 2 - -* item 0 -{{inner list}} -* item 2 - -* item 0 -* notSOL{{inner list}} -* item 2 +<table> +<td>foo</td> +</tr> +</table> !! result -<ul><li> item 1 -</li><li> item 2 -</li></ul> -<ul><li> item 0 -</li><li> item 1 -</li><li> item 2 -</li></ul> -<ul><li> item 0 -</li><li> notSOL -</li><li> item 1 -</li><li> item 2 -</li></ul> - +<table> +<tr> +<td>foo</td> +</tr> +</table> !! end -!! test -List interrupted by empty line or heading -!! input -* foo - -** bar -== A heading == -* Another list item -!! result -<ul><li> foo -</li></ul> -<ul><li><ul><li> bar -</li></ul> -</li></ul> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: A heading">edit</a>]</span> <span class="mw-headline" id="A_heading"> A heading </span></h2> -<ul><li> Another list item -</li></ul> - -!!end - -!!test -Multiple list tags generated by templates -!!input -{{echo|<li>}}a -{{echo|<li>}}b -{{echo|<li>}}c -!!result -<li>a -<li>b -<li>c</li> -</li> -</li> - -!!end - ### ### Magic Words ### +# Note that the current date is hard-coded as +# 1970-01-01T00:02:03Z (a Thursday) +# when running parser tests. The timezone is also fixed to GMT, so +# local date will be identical to current date. + !! test Magic Word: {{CURRENTDAY}} !! input @@ -4463,6 +6463,15 @@ Magic Word: {{CURRENTMONTH}} !! end !! test +Magic Word: {{CURRENTMONTH1}} +!! input +{{CURRENTMONTH1}} +!! result +<p>1 +</p> +!! end + +!! test Magic Word: {{CURRENTMONTHABBREV}} !! input {{CURRENTMONTHABBREV}} @@ -4499,6 +6508,15 @@ Magic Word: {{CURRENTTIME}} !! end !! test +Magic Word: {{CURRENTHOUR}} +!! input +{{CURRENTHOUR}} +!! result +<p>00 +</p> +!! end + +!! test Magic Word: {{CURRENTWEEK}} (@bug 4594) !! input {{CURRENTWEEK}} @@ -4517,6 +6535,66 @@ Magic Word: {{CURRENTYEAR}} !! end !! test +Magic Word: {{CURRENTTIMESTAMP}} +!! input +{{CURRENTTIMESTAMP}} +!! result +<p>19700101000203 +</p> +!! end + +!! test +Magic Words LOCAL (UTC) +!! input +* {{LOCALMONTH}} +* {{LOCALMONTH1}} +* {{LOCALMONTHNAME}} +* {{LOCALMONTHNAMEGEN}} +* {{LOCALMONTHABBREV}} +* {{LOCALDAY}} +* {{LOCALDAY2}} +* {{LOCALDAYNAME}} +* {{LOCALYEAR}} +* {{LOCALTIME}} +* {{LOCALHOUR}} +* {{LOCALWEEK}} +* {{LOCALDOW}} +* {{LOCALTIMESTAMP}} +!! result +<ul> +<li> 01 +</li> +<li> 1 +</li> +<li> January +</li> +<li> January +</li> +<li> Jan +</li> +<li> 1 +</li> +<li> 01 +</li> +<li> Thursday +</li> +<li> 1970 +</li> +<li> 00:02 +</li> +<li> 00 +</li> +<li> 1 +</li> +<li> 4 +</li> +<li> 19700101000203 +</li> +</ul> + +!! end + +!! test Magic Word: {{FULLPAGENAME}} !! options title=[[User:Ævar Arnfjörð Bjarmason]] @@ -4539,6 +6617,93 @@ title=[[User:Ævar Arnfjörð Bjarmason]] !! end !! test +Magic Word: {{TALKSPACE}} +!! options +title=[[User:Ævar Arnfjörð Bjarmason]] +!! input +{{TALKSPACE}} +!! result +<p>User talk +</p> +!! end + +!! test +Magic Word: {{TALKSPACE}}, same namespace +!! options +title=[[User talk:Ævar Arnfjörð Bjarmason]] +!! input +{{TALKSPACE}} +!! result +<p>User talk +</p> +!! end + +!! test +Magic Word: {{TALKSPACE}}, main namespace +!! options +title=[[Parser Test]] +!! input +{{TALKSPACE}} +!! result +<p>Talk +</p> +!! end + +!! test +Magic Word: {{TALKSPACEE}} +!! options +title=[[User:Ævar Arnfjörð Bjarmason]] +!! input +{{TALKSPACEE}} +!! result +<p>User_talk +</p> +!! end + +!! test +Magic Word: {{SUBJECTSPACE}} +!! options +title=[[User talk:Ævar Arnfjörð Bjarmason]] +!! input +{{SUBJECTSPACE}} +!! result +<p>User +</p> +!! end + +!! test +Magic Word: {{SUBJECTSPACE}}, same namespace +!! options +title=[[User:Ævar Arnfjörð Bjarmason]] +!! input +{{SUBJECTSPACE}} +!! result +<p>User +</p> +!! end + +!! test +Magic Word: {{SUBJECTSPACE}}, main namespace +!! options +title=[[Parser Test]] +!! input +{{SUBJECTSPACE}} +!! result + +!! end + +!! test +Magic Word: {{SUBJECTSPACEE}} +!! options +title=[[User talk:Ævar Arnfjörð Bjarmason]] +!! input +{{SUBJECTSPACEE}} +!! result +<p>User +</p> +!! end + +!! test Magic Word: {{NAMESPACE}} !! options title=[[User:Ævar Arnfjörð Bjarmason]] @@ -4572,11 +6737,121 @@ title=[[User:Ævar Arnfjörð Bjarmason]] !! end !! test +Magic Word: {{SUBPAGENAME}} +!! options +title=[[Ævar Arnfjörð Bjarmason/sub ö]] subpage +!! input +{{SUBPAGENAME}} +!! result +<p>sub ö +</p> +!! end + +!! test +Magic Word: {{SUBPAGENAMEE}} +!! options +title=[[Ævar Arnfjörð Bjarmason/sub ö]] subpage +!! input +{{SUBPAGENAMEE}} +!! result +<p>sub_%C3%B6 +</p> +!! end + +!! test +Magic Word: {{ROOTPAGENAME}} +!! options +title=[[Ævar Arnfjörð Bjarmason/sub/sub2]] subpage +!! input +{{ROOTPAGENAME}} +!! result +<p>Ævar Arnfjörð Bjarmason +</p> +!! end + +!! test +Magic Word: {{ROOTPAGENAMEE}} +!! options +title=[[Ævar Arnfjörð Bjarmason/sub/sub2]] subpage +!! input +{{ROOTPAGENAMEE}} +!! result +<p>%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason +</p> +!! end + +!! test +Magic Word: {{BASEPAGENAME}} +!! options +title=[[Ævar Arnfjörð Bjarmason/sub]] subpage +!! input +{{BASEPAGENAME}} +!! result +<p>Ævar Arnfjörð Bjarmason +</p> +!! end + +!! test +Magic Word: {{BASEPAGENAMEE}} +!! options +title=[[Ævar Arnfjörð Bjarmason/sub]] subpage +!! input +{{BASEPAGENAMEE}} +!! result +<p>%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason +</p> +!! end + +!! test +Magic Word: {{TALKPAGENAME}} +!! options +title=[[User:Ævar Arnfjörð Bjarmason]] +!! input +{{TALKPAGENAME}} +!! result +<p>User talk:Ævar Arnfjörð Bjarmason +</p> +!! end + +!! test +Magic Word: {{TALKPAGENAMEE}} +!! options +title=[[User:Ævar Arnfjörð Bjarmason]] +!! input +{{TALKPAGENAMEE}} +!! result +<p>User_talk:%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason +</p> +!! end + +!! test +Magic Word: {{SUBJECTPAGENAME}} +!! options +title=[[User talk:Ævar Arnfjörð Bjarmason]] +!! input +{{SUBJECTPAGENAME}} +!! result +<p>User:Ævar Arnfjörð Bjarmason +</p> +!! end + +!! test +Magic Word: {{SUBJECTPAGENAMEE}} +!! options +title=[[User talk:Ævar Arnfjörð Bjarmason]] +!! input +{{SUBJECTPAGENAMEE}} +!! result +<p>User:%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason +</p> +!! end + +!! test Magic Word: {{NUMBEROFFILES}} !! input {{NUMBEROFFILES}} !! result -<p>2 +<p>4 </p> !! end @@ -4654,6 +6929,15 @@ Magic Word: {{SCRIPTPATH}} !! end !! test +Magic Word: {{STYLEPATH}} +!! input +{{STYLEPATH}} +!! result +<p>/skins +</p> +!! end + +!! test Magic Word: {{SERVER}} !! input {{SERVER}} @@ -4681,6 +6965,36 @@ Magic Word: {{SITENAME}} !! end !! test +Case-sensitive magic words, when cased differently, should just be template transclusions +!! input +{{CurrentMonth}} +{{currentday}} +{{cURreNTweEK}} +{{currentHour}} +!! result +<p><a href="/index.php?title=Template:CurrentMonth&action=edit&redlink=1" class="new" title="Template:CurrentMonth (page does not exist)">Template:CurrentMonth</a> +<a href="/index.php?title=Template:Currentday&action=edit&redlink=1" class="new" title="Template:Currentday (page does not exist)">Template:Currentday</a> +<a href="/index.php?title=Template:CURreNTweEK&action=edit&redlink=1" class="new" title="Template:CURreNTweEK (page does not exist)">Template:CURreNTweEK</a> +<a href="/index.php?title=Template:CurrentHour&action=edit&redlink=1" class="new" title="Template:CurrentHour (page does not exist)">Template:CurrentHour</a> +</p> +!! end + +!! test +Case-insensitive magic words should still work with weird casing. +!! input +{{sErVeRNaMe}} +{{LCFirst:AOEU}} +{{ucFIRST:aoeu}} +{{SERver}} +!! result +<p>example.org +aOEU +Aoeu +<a rel="nofollow" class="external free" href="http://example.org">http://example.org</a> +</p> +!! end + +!! test Namespace 1 {{ns:1}} !! input {{ns:1}} @@ -5422,8 +7736,8 @@ Bug 6563: Edit link generation for section shown by <includeonly> !! input {{includeonly section}} !! result -<h2><span class="editsection">[<a href="/index.php?title=Template:Includeonly_section&action=edit&section=T-1" title="Template:Includeonly section">edit</a>]</span> <span class="mw-headline" id="Includeonly_section">Includeonly section</span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Template:Includeonly_section&action=edit&section=T-2" title="Template:Includeonly section">edit</a>]</span> <span class="mw-headline" id="Section_T-1">Section T-1</span></h2> +<h2><span class="mw-headline" id="Includeonly_section">Includeonly section</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Template:Includeonly_section&action=edit&section=T-1" title="Template:Includeonly section">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Section_T-1">Section T-1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Template:Includeonly_section&action=edit&section=T-2" title="Template:Includeonly section">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -5449,7 +7763,7 @@ Bug 6563: Edit link generation for section suppressed by <includeonly> </includeonly> ==Section 1== !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 1">edit</a>]</span> <span class="mw-headline" id="Section_1">Section 1</span></h2> +<h2><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -5473,6 +7787,77 @@ Un-closed <includeonly> !! result !! end +# TODO: test with DOM fragment reuse! +!! test +Parsoid: DOM fragment reuse +!! options +parsoid=wt2wt,wt2html +!! input +a{{echo|b<table></table>c}}d + +a{{echo|b +<table></table> +c}}d + +{{echo|a + +<table></table> + +b}} +!! result +a<span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"b +<table></table>c"}},"i":0}}]}'>b</span> +<table about="#mwt1"></table><span about="#mwt1">c</span>d + + +<p about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":["a",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"b\n<table></table>\nc"}},"i":0}},"d"]}'>ab</p><span about="#mwt2"> +</span> +<table about="#mwt2"></table><span about="#mwt2"> +</span> +<p about="#mwt2">cd</p> + + +<p about="#mwt3" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n\n<table></table>\n\nb"}},"i":0}}]}'>a</p><span about="#mwt3"> + +</span> +<table about="#mwt3"></table><span about="#mwt3"> + +</span> +<p about="#mwt3">b</p> +!! end + +!! test +Parsoid: Merge double tds (bug 50603) +!! options +parsoid +!! input +{| +|{{echo|{{!}} foo}} +|} +!! result +<table><tbody> +<tr><td about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":["|",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"{{!}} foo"}},"i":0}}]}'> foo</td></tr> +</tbody></table> +!! end + +!! test +Parsoid: Merge double tds in nested transclusion content (bug 50603) +!! options +parsoid +!! input +{{echo|<div>}} +{| +|{{echo|{{!}} foo}} +|} +{{echo|</div>}} +!! result +<div about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<div>"}},"i":0}},"\n{|\n|",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"{{!}} foo"}},"i":1}},"\n|}\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"</div>"}},"i":2}}]}'> +<table><tbody> +<tr><td data-mw='{"parts":["|"]}'> foo</td></tr> +</tbody></table> +</div> +!! end + ### ### <includeonly> and <noinclude> in attributes ### @@ -5569,8 +7954,10 @@ Templates: 1. Simple use Templates: 2. Inside a block tag !!input <div>{{echo|Foo}}</div> +<blockquote>{{echo|Foo}}</blockquote> !!result <div>Foo</div> +<blockquote>Foo</blockquote> !!end @@ -5612,6 +7999,19 @@ bar <div>baz</div> !!end !!test +Templates: P-wrapping: 1d. Template preceded by comment-only line +!!options +parsoid +!!input +<!-- foo --> +{{echo|Bar}} +!!result +<!-- foo --> + +<p about="#mwt223" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"Bar"}},"i":0}}]}'>Bar</p> +!!end + +!!test Templates: Inline Text: 1. Multiple tmeplate uses !!input {{echo|Foo}}bar{{echo|baz}} @@ -5771,6 +8171,15 @@ Templates: HTML Tag: 6. Generation of end piece of HTML attr value !!end !!test +Templates: HTML Tag: 7. Generation of partial attribute key string +!!input +<div st{{echo|yle}}="color:red;">foo</div> +!!result +<div style="color:red;">foo</div> + +!!end + +!!test Templates: HTML Tables: 1. Generating start of a HTML table !!input {{echo|<table><tr><td>foo</td>}}</tr></table> @@ -5861,6 +8270,20 @@ Templates: HTML Tables: 4f. Generating a single tag of a HTML table !!end !!test +Templates: HTML Tables: 5. Proper fostering of categories from inside +!!options +parsoid=wt2html,wt2wt +!!input +<table>[[Category:foo1]]<tr><td>foo</td></tr></table> +<!--Two categories (Bug 50330)--> +<table>[[Category:bar1]][[Category:bar2]]<tr><td>foo</td></tr></table> +!!result +<link rel="mw:WikiLink/Category" href="./Category:Foo1"><table><tbody><tr><td>foo</td></tr></tbody></table> +<!--Two categories (Bug 50330)--> +<link rel="mw:WikiLink/Category" href="./Category:Bar1"><link rel="mw:WikiLink/Category" href="./Category:Bar2"><table><tbody><tr><td>foo</td></tr></tbody></table> +!!end + +!!test Templates: Wiki Tables: 1a. Fostering of entire template content !!input {| @@ -5967,9 +8390,12 @@ unused}}}} *{{echo|b {{nonexistent| unused}}}} !!result -<ul><li>a <a href="/index.php?title=Template:Nonexistent&action=edit&redlink=1" class="new" title="Template:Nonexistent (page does not exist)">Template:Nonexistent</a> -</li><li>b <a href="/index.php?title=Template:Nonexistent&action=edit&redlink=1" class="new" title="Template:Nonexistent (page does not exist)">Template:Nonexistent</a> -</li></ul> +<ul> +<li>a <a href="/index.php?title=Template:Nonexistent&action=edit&redlink=1" class="new" title="Template:Nonexistent (page does not exist)">Template:Nonexistent</a> +</li> +<li>b <a href="/index.php?title=Template:Nonexistent&action=edit&redlink=1" class="new" title="Template:Nonexistent (page does not exist)">Template:Nonexistent</a> +</li> +</ul> !!end @@ -5986,24 +8412,24 @@ Templates: Ugly nesting: 1. Quotes opened/closed across templates (echo) Templates: Ugly nesting: 2. Quotes opened/closed across templates (echo_with_span) (PHP parser generates misnested html) !! options -disabled +parsoid !!input {{echo_with_span|''a}}{{echo_with_span|b''c''d}}{{echo_with_span|''e}} !!result -<p><span><i>a</i></span><i><span>b</span></i><span>c</span><i>d</i><span>e</span></p> +<p><span about="#mwt1" typeof="mw:Transclusion" data-mw="{"parts":[{"template":{"target":{"wt":"echo_with_span","href":"./Template:Echo_with_span"},"params":{"1":{"wt":"''a"}},"i":0}}]}"><i>a</i></span><i about="#mwt2" typeof="mw:Transclusion" data-mw="{"parts":[{"template":{"target":{"wt":"echo_with_span","href":"./Template:Echo_with_span"},"params":{"1":{"wt":"b''c''d"}},"i":0}},{"template":{"target":{"wt":"echo_with_span","href":"./Template:Echo_with_span"},"params":{"1":{"wt":"''e"}},"i":1}}]}"><span>b</span></i><span about="#mwt2">c</span><i about="#mwt2">d<span></span></i><span about="#mwt2">e</span></p> !!end !!test Templates: Ugly nesting: 3. Quotes opened/closed across templates (echo_with_div) -(PHP parser generates misnested html) +(PHP parser generates misnested html; Parsoid html2wt mode adds newlines between {{echo}}s) !! options -disabled +parsoid=wt2html,wt2wt !!input {{echo_with_div|''a}}{{echo_with_div|b''c''d}}{{echo_with_div|''e}} !!result -<div><i>a</i></div> -<div><i>b</i>c<i>d</i></div> -<div>e</div> +<div about="#mwt1" typeof="mw:Transclusion" data-mw="{"parts":[{"template":{"target":{"wt":"echo_with_div","href":"./Template:Echo_with_div"},"params":{"1":{"wt":"''a"}},"i":0}}]}"><i>a</i></div> +<div about="#mwt2" typeof="mw:Transclusion" data-mw="{"parts":[{"template":{"target":{"wt":"echo_with_div","href":"./Template:Echo_with_div"},"params":{"1":{"wt":"b''c''d"}},"i":0}}]}"><i>b</i>c<i>d</i></div> +<div about="#mwt3" typeof="mw:Transclusion" data-mw="{"parts":[{"template":{"target":{"wt":"echo_with_div","href":"./Template:Echo_with_div"},"params":{"1":{"wt":"''e"}},"i":0}}]}">e</div> !!end !!test @@ -6026,9 +8452,12 @@ parsoid |bar |} !!result -<table about="#mwt1" typeof="mw:Object/Template "> -<tbody><tr><td>foo</td></tr></tbody></table><span about="#mwt1"> -bar</span><span about="#mwt1"> +<table about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":["{|\n|",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo</table>"}},"i":0}},"\n|bar\n|}"]}'> + +<tbody> +<tr> +<td>foo</td></tr></tbody></table><span about="#mwt1"> +</span><span about="#mwt1">bar</span><span about="#mwt1"> </span> !!end @@ -6058,24 +8487,24 @@ parsoid </tr> </table> !!result -<table about="#mwt1" typeof="mw:Object/Template"> - <tbody><tr > - <td > - <table > - <tbody><tr > - <td >1. foo </td></tr></tbody></table></td> - <td > bar </td> - <td >2. baz </td></tr></tbody></table><span about="#mwt1"> - </span><span about="#mwt1"> - - abc</span><span about="#mwt1"> - </span><span about="#mwt1"> - </span><span about="#mwt1"> - </span><span about="#mwt1"> - </span><span about="#mwt1"> - - xyz</span><span about="#mwt1"> - </span><span about="#mwt1"> +<table about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":["<table>\n <tr>\n <td>\n <table>\n <tr>\n <td>1. ",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo </table>"}},"i":0}},"</td>\n <td> bar </td>\n <td>2. ",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"baz </table>"}},"i":1}},"</td>\n </tr>\n <tr>\n <td>abc</td>\n </tr>\n </table>\n </td>\n </tr>\n <tr>\n <td>xyz</td>\n </tr>\n</table>"]}'> + <tbody><tr> + <td> + <table> + <tbody><tr> + <td>1. foo </td></tr></tbody></table></td> + <td> bar </td> + <td>2. baz </td></tr></tbody></table><span about="#mwt2"> + </span><span about="#mwt2"> + </span><span about="#mwt2"> + </span><span about="#mwt2">abc</span><span about="#mwt2"> + </span><span about="#mwt2"> + </span><span about="#mwt2"> + </span><span about="#mwt2"> + </span><span about="#mwt2"> + </span><span about="#mwt2"> + </span><span about="#mwt2">xyz</span><span about="#mwt2"> + </span><span about="#mwt2"> </span> !!end @@ -6237,10 +8666,13 @@ wiki<nowiki>nowiki<!--nowiki</nowiki>wiki wiki<nowiki>nowiki<!--nowiki</nowiki>wiki !!end +# Leading @ in this template definition works around a limitation +# in parsoid's parserTests which otherwise strips the <span> from the +# result (confusing it for a template wrapper) !! article Template:dangerous !!text -<span onmouseover="alert('crap')">Oh no</span> +@<span onmouseover="alert('crap')">Oh no</span> !!endarticle !!test @@ -6248,7 +8680,7 @@ Template:dangerous !! input {{Template:dangerous}} !! result -<p><span>Oh no</span> +<p>@<span>Oh no</span> </p> !! end @@ -6637,6 +9069,62 @@ But not inside includeonly <includeonly>{{subst:Foo}}</includeonly> !! end +!! test +Parsoid: Recognize nowiki with trailing space in tags +!! options +parsoid=wt2html +!! input +<nowiki ><div>[[foo]]</nowiki > + +a<nowiki / >b + +c<nowiki />d + +e<nowiki/ >f +!! result +<p><span typeof="mw:Nowiki"><div>[[foo]]</span></p> +<p>ab</p> +<p>cd</p> +<p>ef</p> +!! end + +!! test +Parsoid: Recognize nowiki with odd capitalization +!! options +parsoid=wt2html +!! input +<noWikI ><div>[[foo]]</Nowiki > +!! result +<p><span typeof="mw:Nowiki"><div>[[foo]]</span></p> +!! end + + +!! test +Parsoid: Escape nowiki with trailing space in tags +!! options +parsoid=html2wt +!! input +<nowiki > foo </nowiki > + +a<nowiki />b + +c<nowiki/ >d +!! result +<p><nowiki > foo </nowiki ></p> +<p>a<nowiki />b</p> +<p>c<nowiki/ >d</p> +!! end + +!! test +Parsoid: Escape weird noWikI capitalizations +!! options +parsoid=html2wt +!! input +<noWikI > foo </NoWikI > +!! result +<p><noWikI > foo </NoWikI ></p> +!! end + ### ### Message transform tests ### @@ -6705,9 +9193,9 @@ Special:RecentChanges/param !! options msg !! input -{{#special:foobarnonexistent}} +{{#special:foobar nonexistent}} !! result -No such special page +Special:Foobar nonexistent !! end !! test @@ -6735,16 +9223,21 @@ Special:RecentChanges/param !! options msg !! input -{{#speciale:foobarnonexistent}} +{{#speciale:foobar nonexistent}} !! result -No_such_special_page +Special:Foobar_nonexistent !! end ### ### Images ### +### For Parsoid-specific tests, see +#### http://www.mediawiki.org/wiki/Parsoid/MediaWiki_DOM_spec#Images + !! test -Simple image +Simple image (php) +!! options +php !! input [[Image:foobar.jpg]] !! result @@ -6753,16 +9246,20 @@ Simple image !! end !! test -Right-aligned image +Simple image (parsoid) +!! options +parsoid=wt2html !! input -[[Image:foobar.jpg|right]] +[[Image:foobar.jpg]] !! result -<div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div> - +<p><span class="mw-default-size" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span> +</p> !! end !! test -Simple image (using File: namespace, now canonical) +Simple image (using File: namespace, now canonical) (php) +!! options +php !! input [[File:foobar.jpg]] !! result @@ -6771,29 +9268,108 @@ Simple image (using File: namespace, now canonical) !! end !! test -Image with caption +Simple image (using File: namespace, now canonical) (parsoid) +!! options +parsoid !! input -[[Image:foobar.jpg|right|Caption text]] +[[File:Foobar.jpg]] +!! result +<p><span class="mw-default-size" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span> +</p> +!! end + +!! test +Right-aligned image (php) +!! options +php +!! input +[[Image:foobar.jpg|right]] +!! result +<div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div> + +!! end + +!! test +Right-aligned image (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|right]] +!! result +<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></figure> +!! end + +!! test +Image with caption (php) +!! options +php +!! input +[[File:Foobar.jpg|right|Caption text]] +!! result +<div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption text"><img alt="Caption text" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div> + +!! end + +!! test +Image with caption (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|right|Caption text]] +!! result +<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a><figcaption>Caption text</figcaption></figure> +!! end + +!! test +Image with empty attribute (php) +!! options +php +!! input +[[File:Foobar.jpg|right||Caption text]] !! result <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption text"><img alt="Caption text" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div> !! end !! test -Image with empty attribute +Image with empty attribute (parsoid) +!! options +parsoid=wt2html +!! input +[[File:Foobar.jpg|right||Caption text]] +!! result +<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a><figcaption>Caption text</figcaption></figure> +!! end + +!! test +Image with attributes from template (php) +!! options +php !! input -[[Image:foobar.jpg|right||Caption text]] +[[File:Foobar.jpg|{{image_attribs}}]] !! result <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption text"><img alt="Caption text" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div> !! end !! test -Image with link tails +Image with attributes from template (parsoid) +!! options +parsoid !! input -123[[Image:foobar.jpg]]456 -123[[Image:foobar.jpg|right]]456 -123[[Image:foobar.jpg|thumb]]456 +[[File:Foobar.jpg|{{image_attribs}}]] +!! result +<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a><figcaption>Caption text</figcaption></figure> +!! end + +!! test +Image with link tails (php) +!! options +php +!! input +123[[File:Foobar.jpg]]456 +123[[File:Foobar.jpg|right]]456 +123[[File:Foobar.jpg|thumb]]456 !! result <p>123<a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>456 </p> @@ -6803,20 +9379,48 @@ Image with link tails !! end !! test -Image with multiple captions -- only last one is accepted +Image with link tails (parsoid) +!! options +parsoid +!! input +123[[File:Foobar.jpg]]456 +123[[File:Foobar.jpg|right]]456 +123[[File:Foobar.jpg|thumb]]456 +!! result +<p>123<span class="mw-default-size" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span>456</p> +123<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></figure>456 +123<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" height="20" width="180"></a></figure>456 +!! end + +!! test +Image with multiple captions -- only last one is accepted (php) +!! options +php !! input -[[Image:foobar.jpg|right|Caption1 - ignored|[[Caption2]] - ignored|Caption3 - accepted]] +[[File:Foobar.jpg|right|Caption1 - ignored|[[Caption2]] - ignored|Caption3 - accepted]] !! result <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption3 - accepted"><img alt="Caption3 - accepted" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div> !! end !! test -Image with width attribute at different positions +Image with multiple captions -- only last one is accepted (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|right|Caption1 - ignored|[[Caption2]] - ignored|Caption3 - accepted]] +!! result +<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a><figcaption>Caption3 - accepted</figcaption></figure> +!! end + +!! test +Image with width attribute at different positions (php) +!! options +php !! input -[[Image:foobar.jpg|200px|right|Caption]] -[[Image:foobar.jpg|right|200px|Caption]] -[[Image:foobar.jpg|right|Caption|200px]] +[[File:Foobar.jpg|200px|right|Caption]] +[[File:Foobar.jpg|right|200px|Caption]] +[[File:Foobar.jpg|right|Caption|200px]] !! result <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption"><img alt="Caption" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" width="200" height="23" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg 2x" /></a></div> <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption"><img alt="Caption" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" width="200" height="23" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg 2x" /></a></div> @@ -6825,23 +9429,84 @@ Image with width attribute at different positions !! end !! test -Image with link parameter, wiki target +Image with width attribute at different positions (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|200px|right|Caption]] +[[File:Foobar.jpg|right|200px|Caption]] +[[File:Foobar.jpg|right|Caption|200px]] +!! result +<figure class="mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" height="23" width="200"></a><figcaption>Caption</figcaption></figure> +<figure class="mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" height="23" width="200"></a><figcaption>Caption</figcaption></figure> +<figure class="mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" height="23" width="200"></a><figcaption>Caption</figcaption></figure> +!! end + +!! test +Image with link parameter, wiki target (php) +!! options +php !! input -[[Image:foobar.jpg|link=Target page]] +[[File:Foobar.jpg|link=Main Page]] !! result -<p><a href="/wiki/Target_page" title="Target page"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +<p><a href="/wiki/Main_Page" title="Main Page"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> </p> !! end !! test -Image with link parameter, URL target +Image with link parameter, wiki target (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|link=Main Page]] +!! result +<p><span class="mw-default-size" typeof="mw:Image"><a href="Main_Page"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span></p> +!! end + +!! test +Image with link parameter, URL target (php) +!! options +php !! input -[[Image:foobar.jpg|link=http://example.com/]] +[[File:Foobar.jpg|link=http://example.com/]] !! result <p><a href="http://example.com/" rel="nofollow"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> </p> !! end +# parsoid bug 49293 (part 1) +!! test +Image with link parameter, URL target (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|link=http://example.com/]] +!! result +<p><span class="mw-default-size" typeof="mw:Image"><a href="http://example.com/"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span></p> +!! end + +!! test +Image with link parameter, protocol-less URL target (php) +!! options +php +!! input +[[File:Foobar.jpg|link=//example.com/]] +!! result +<p><a href="//example.com/" rel="nofollow"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +</p> +!! end + +# parsoid bug 49293 (part 2) +!! test +Image with link parameter, protocol-less URL target (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|link=//example.com/]] +!! result +<p><span class="mw-default-size" typeof="mw:Image"><a href="//example.com/"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span></p> +!! end + !! test Image with link parameter, wgExternalLinkTarget !! input @@ -6887,34 +9552,72 @@ wgExternalLinkTarget='foobar' !! end !! test -Image with empty link parameter +Image with empty link parameter (php) +!! options +php !! input -[[Image:foobar.jpg|link=]] +[[File:Foobar.jpg|link=]] !! result <p><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /> </p> !! end !! test -Image with link parameter (wiki target) and unnamed parameter +Image with empty link parameter (parsoid) +!! options +parsoid !! input -[[Image:foobar.jpg|link=Target page|Title]] +[[File:Foobar.jpg|link=]] !! result -<p><a href="/wiki/Target_page" title="Title"><img alt="Title" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +<p><span class="mw-default-size" typeof="mw:Image"><span><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></span></span></p> +!! end + +!! test +Image with link parameter (wiki target) and unnamed parameter (php) +!! options +php +!! input +[[File:Foobar.jpg|link=Main Page|Title]] +!! result +<p><a href="/wiki/Main_Page" title="Title"><img alt="Title" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> </p> !! end !! test -Image with link parameter (URL target) and unnamed parameter +Image with link parameter (wiki target) and unnamed parameter (parsoid) +!! options +parsoid !! input -[[Image:foobar.jpg|link=http://example.com/|Title]] +[[File:Foobar.jpg|link=Main Page|Title]] +!! result +<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"Title"}'><a href="Main_Page"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span></p> +!! end + +!! test +Image with link parameter (URL target) and unnamed parameter (php) +!! options +php +!! input +[[File:Foobar.jpg|link=http://example.com/|Title]] !! result <p><a href="http://example.com/" title="Title" rel="nofollow"><img alt="Title" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> </p> !! end !! test +Image with link parameter (URL target) and unnamed parameter (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|link=http://example.com/|Title]] +!! result +<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"Title"}'><a href="http://example.com/"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span></p> +!! end + +!! test Thumbnail image with link parameter +!! options +php !! input [[Image:foobar.jpg|thumb|link=http://example.com/|Title]] !! result @@ -6923,6 +9626,61 @@ Thumbnail image with link parameter !! end !! test +Manually-specified thumbnail image +!! options +php +!! input +[[Image:Foobar.jpg|thumb=Thumb.png|Title]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/File:Foobar.jpg"><img alt="" src="http://example.com/images/e/ea/Thumb.png" width="135" height="135" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>Title</div></div></div> + +!! end + +!! test +Manually-specified thumbnail image with explicit link to wiki page +!! options +php +!! input +[[Image:Foobar.jpg|thumb=Thumb.png|link=Main Page|Title]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/Main_Page" title="Main Page"><img alt="" src="http://example.com/images/e/ea/Thumb.png" width="135" height="135" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>Title</div></div></div> + +!! end + +!! test +Manually-specified thumbnail image with explicit link to url +!! options +php +!! input +[[Image:Foobar.jpg|thumb=Thumb.png|link=http://example.com|Title]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="http://example.com"><img alt="" src="http://example.com/images/e/ea/Thumb.png" width="135" height="135" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>Title</div></div></div> + +!! end + +!! test +Manually-specified thumbnail image with explicit no link +!! options +php +!! input +[[Image:Foobar.jpg|thumb=Thumb.png|link=|Title]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:137px;"><img alt="" src="http://example.com/images/e/ea/Thumb.png" width="135" height="135" class="thumbimage" /> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>Title</div></div></div> + +!! end + +!! test +Manually-specified thumbnail image with explicit link and alt text +!! options +php +!! input +[[Image:Foobar.jpg|thumb=Thumb.png|link=Main Page|alt=alttext|Title]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/Main_Page" title="Main Page"><img alt="alttext" src="http://example.com/images/e/ea/Thumb.png" width="135" height="135" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>Title</div></div></div> + +!! end + +!! test Image with frame and link !! input [[Image:Foobar.jpg|frame|left|This is a test image [[Main Page]]]] @@ -7006,6 +9764,36 @@ Thumbnail image caption with a free URL and explicit alt !! end !! test +SVG thumbnails with no language set +!! options +!! input +[[File:Foobar.svg|thumb|width=200]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.svg" class="image"><img alt="" src="http://example.com/images/thumb/f/ff/Foobar.svg/180px-Foobar.svg.png" width="180" height="180" class="thumbimage" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/270px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/360px-Foobar.svg.png 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.svg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>width=200</div></div></div> + +!! end + +!! test +SVG thumbnails with language de +!! options +!! input +[[File:Foobar.svg|thumb|width=200|lang=de]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/index.php?title=File:Foobar.svg&lang=de" class="image"><img alt="" src="http://example.com/images/thumb/f/ff/Foobar.svg/langde-180px-Foobar.svg.png" width="180" height="180" class="thumbimage" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/langde-270px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/langde-360px-Foobar.svg.png 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.svg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>width=200</div></div></div> + +!! end + +!! test +SVG thumbnails with invalid language code +!! options +!! input +[[File:Foobar.svg|thumb|width=200|lang=invalid.language.code]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.svg" class="image"><img alt="" src="http://example.com/images/thumb/f/ff/Foobar.svg/180px-Foobar.svg.png" width="180" height="180" class="thumbimage" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/270px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/360px-Foobar.svg.png 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.svg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>lang=invalid.language.code</div></div></div> + +!! end + +!! test BUG 1887: A ISBN with a thumbnail !! input [[Image:foobar.jpg|thumb|ISBN 1235467890]] @@ -7200,6 +9988,152 @@ wgEnableUploads=0 </p> !! end +# Parsoid-specific testing for images +# http://www.mediawiki.org/wiki/Parsoid/MediaWiki_DOM_spec#Images +# Currently imperfect due to a flaw in the Parsoid testrunner +# Work in progress +# THESE TESTS SHOULD BE MOVED UP and merged with the php-specific +# image tests. + +!! test +Parsoid-specific image handling - simple image with size and middle alignment +!! options +parsoid +!! input +[[Image:Foobar.jpg|50px|middle]] +!! result +<p> +<span class="mw-valign-middle" typeof="mw:Image"> +<a href="File:Foobar.jpg"> +<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" height="6" width="50"> +</a> +</span> +</p> +!! end + +!! test +Parsoid-specific image handling - simple image with both sizes, a baseline alignment, and a caption +!! options +parsoid +!! input +[[Image:Foobar.jpg|500x10px|baseline|caption]] +!! result +<p> +<span class="mw-valign-baseline" typeof="mw:Image" data-mw="{"caption":"caption"}"> +<a href="File:Foobar.jpg"> +<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/89px-Foobar.jpg" height="10" width="89"> +</a> +</span> +</p> +!! end + +!! test +Parsoid-specific image handling - simple image with border and size spec +!! options +parsoid +!! input +[[Image:Foobar.jpg|50px|border|caption]] +!! result +<p> +<span class="mw-image-border" typeof="mw:Image" data-mw="{"caption":"caption"}"> +<a href="File:Foobar.jpg"> +<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" height="6" width="50"> +</a> +</span> +</p> +!! end + +!! test +Parsoid-specific image handling - thumbnail with halign, valign, and caption +!! options +parsoid +!! input +[[Image:Foobar.jpg|thumb|left|baseline|caption content]] +!! result +<figure class="mw-default-size mw-halign-left mw-valign-baseline" typeof="mw:Image/Thumb"> +<a href="File:Foobar.jpg"> +<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" height="21" width="180" /> +</a> +<figcaption>caption content</figcaption> +</figure> +!! end + +!! test +Parsoid-specific image handling - thumbnail with specific size, halign, valign, and caption +!! options +parsoid +!! input +[[Image:Foobar.jpg|thumb|50x50px|right|middle|caption]] +!! result +<figure class="mw-halign-right mw-valign-middle" typeof="mw:Image/Thumb"> +<a href="File:Foobar.jpg"> +<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" height="6" width="50" /> +</a> +<figcaption>caption</figcaption> +</figure> +!! end + +!! test +Parsoid-specific image handling - framed image with specific size and caption +!! options +parsoid +!! input +[[Image:Foobar.jpg|500x50px|frame|caption]] +!! result +<figure typeof="mw:Image/Frame"> +<a href="File:Foobar.jpg"> +<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/442px-Foobar.jpg" height="50" width="442" /> +</a> +<figcaption>caption</figcaption> +</figure> +!! end + +!! test +Parsoid-specific image handling - framed image with specific size, halign, valign, and caption +!! options +parsoid +!! input +[[Image:Foobar.jpg|500x50px|frame|left|baseline|caption]] +!! result +<figure class="mw-halign-left mw-valign-baseline" typeof="mw:Image/Frame"> +<a href="File:Foobar.jpg"> +<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/442px-Foobar.jpg" height="50" width="442" /> +</a> +<figcaption>caption</figcaption> +</figure> +!! end + +!! test +Parsoid-specific image handling - frameless image with specific size, border, and caption +!! options +parsoid +!! input +[[Image:Foobar.jpg|frameless|500x50px|border|caption]] +!! result +<p> +<span class="mw-image-border" typeof="mw:Image/Frameless" data-mw="{"caption":"caption"}"> +<a href="File:Foobar.jpg"> +<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/442px-Foobar.jpg" height="50" width="442" /> +</a> +</p> +!! end + +#!! test +#Parsoid-specific image handling - simple image with a formatted caption +#!! options +#parsoid +#!! input +#[[Image:Foobar.jpg|<table><tr><td>a</td><td>b</td></tr><tr><td>c</td></tr></table>]] +#!! result +#<p> +#<span typeof="mw:Image"> +#<a class="mw-default-size" href="Image:Foobar.jpg"> +#<img alt="Foobar.jpg" class="mw-default-size" src="http://example.com/images/3/3a/Foobar.jpg" height="220" width="1941"> +#</a> +#<span>abc</span> +#</span> +#</p> + ### ### Subpages @@ -7232,6 +10166,38 @@ subpage title=[[Subpage test]] </p> !! end +# TODO: make this PHP-parser compatible! +!! test +Relative subpage noslash link +!! options +parsoid=wt2wt,wt2html,html2html +subpage title=[[Subpage test/1/2/3/4]] +!!input +[[../../subpage/]] + +[[../../subpage]] +!! result +<p><a rel="mw:WikiLink" href="Subpage_test/1/2/subpage/">subpage</a></p> +<p><a rel="mw:WikiLink" href="Subpage_test/1/2/subpage">Subpage_test/1/2/subpage</a></p> +!! end + +# TODO: make this PHP-parser compatible! +!! test +Parsoid: dot-slash prefixed wikilinks +!! options +parsoid=wt2wt,wt2html,html2html +!!input +[[./foo]] + +[[././bar]] + +[[././baz/]] +!! result +<p><a rel="mw:WikiLink" href="./Foo">foo</a></p> +<p><a rel="mw:WikiLink" href="./Bar">bar</a></p> +<p><a rel="mw:WikiLink" href="./Baz/">baz/</a></p> +!! end + !! test Disabled subpages !! input @@ -7415,6 +10381,59 @@ Bar </p> !! end +!! test +Parsoid: Serialize link to category page with colon escape +!! options +parsoid +!! input + +[[:Category:Foo]] +[[:Category:Foo|Bar]] +!! result +<p> +<a rel="mw:WikiLink" href="Category:Foo">Category:Foo</a> +<a rel="mw:WikiLink" href="Category:Foo">Bar</a> +</p> +!! end + +!! test +Parsoid: Link prefix/suffixes aren't applied to category links +!! options +parsoid=wt2html,wt2wt,html2html +language=is +!! input +x[[Category:Foo]]y +!! result +<p>x<link rel="mw:WikiLink/Category" href="Category:Foo">y</p> +!! end + +!! test +Parsoid: Serialize link to file page with colon escape +!! options +parsoid +!! input + +[[:File:Foo.png]] +[[:File:Foo.png|Bar]] +!! result +<p> +<a rel="mw:WikiLink" href="File:Foo.png">File:Foo.png</a> +<a rel="mw:WikiLink" href="File:Foo.png">Bar</a> +</p> +!! end + +!! test +Parsoid: Serialize a genuine category link without colon escape +!! options +parsoid +!! input +[[Category:Foo]] +[[Category:Foo|Bar]] +!! result +<link rel="mw:WikiLink/Category" href="Category:Foo"> +<link rel="mw:WikiLink/Category" href="Category:Foo#Bar"> +!! end + ### ### Inter-language links ### @@ -7457,13 +10476,13 @@ More ===Smaller headline=== Blah blah !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Headline 1">edit</a>]</span> <span class="mw-headline" id="Headline_1"> Headline 1 </span></h2> +<h2><span class="mw-headline" id="Headline_1">Headline 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Headline 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p>Some text </p> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Headline 2">edit</a>]</span> <span class="mw-headline" id="Headline_2">Headline 2</span></h2> +<h2><span class="mw-headline" id="Headline_2">Headline 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Headline 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p>More </p> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Smaller headline">edit</a>]</span> <span class="mw-headline" id="Smaller_headline">Smaller headline</span></h3> +<h3><span class="mw-headline" id="Smaller_headline">Smaller headline</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Smaller headline">edit</a><span class="mw-editsection-bracket">]</span></span></h3> <p>Blah blah </p> !! end @@ -7480,7 +10499,7 @@ Section headings with TOC Some text ===Another headline=== !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Headline_1"><span class="tocnumber">1</span> <span class="toctext">Headline 1</span></a> <ul> @@ -7501,15 +10520,16 @@ Some text </ul> </li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Headline 1">edit</a>]</span> <span class="mw-headline" id="Headline_1"> Headline 1 </span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Subheadline 1">edit</a>]</span> <span class="mw-headline" id="Subheadline_1"> Subheadline 1 </span></h3> -<h5><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Skipping a level">edit</a>]</span> <span class="mw-headline" id="Skipping_a_level"> Skipping a level </span></h5> -<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Skipping a level">edit</a>]</span> <span class="mw-headline" id="Skipping_a_level_2"> Skipping a level </span></h6> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Headline 2">edit</a>]</span> <span class="mw-headline" id="Headline_2"> Headline 2 </span></h2> +</div> + +<h2><span class="mw-headline" id="Headline_1">Headline 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Headline 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="Subheadline_1">Subheadline 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Subheadline 1">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h5><span class="mw-headline" id="Skipping_a_level">Skipping a level</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Skipping a level">edit</a><span class="mw-editsection-bracket">]</span></span></h5> +<h6><span class="mw-headline" id="Skipping_a_level_2">Skipping a level</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Skipping a level">edit</a><span class="mw-editsection-bracket">]</span></span></h6> +<h2><span class="mw-headline" id="Headline_2">Headline 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Headline 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p>Some text </p> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: Another headline">edit</a>]</span> <span class="mw-headline" id="Another_headline">Another headline</span></h3> +<h3><span class="mw-headline" id="Another_headline">Another headline</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: Another headline">edit</a><span class="mw-editsection-bracket">]</span></span></h3> !! end @@ -7528,7 +10548,7 @@ Handling of sections up to level 6 and beyond ========= Level 9 Heading========= ========== Level 10 Heading========== !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Level_1_Heading"><span class="tocnumber">1</span> <span class="toctext">Level 1 Heading</span></a> <ul> @@ -7556,17 +10576,18 @@ Handling of sections up to level 6 and beyond </ul> </li> </ul> -</td></tr></table> -<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Level 1 Heading">edit</a>]</span> <span class="mw-headline" id="Level_1_Heading"> Level 1 Heading</span></h1> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Level 2 Heading">edit</a>]</span> <span class="mw-headline" id="Level_2_Heading"> Level 2 Heading</span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Level 3 Heading">edit</a>]</span> <span class="mw-headline" id="Level_3_Heading"> Level 3 Heading</span></h3> -<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Level 4 Heading">edit</a>]</span> <span class="mw-headline" id="Level_4_Heading"> Level 4 Heading</span></h4> -<h5><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Level 5 Heading">edit</a>]</span> <span class="mw-headline" id="Level_5_Heading"> Level 5 Heading</span></h5> -<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: Level 6 Heading">edit</a>]</span> <span class="mw-headline" id="Level_6_Heading"> Level 6 Heading</span></h6> -<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=7" title="Edit section: = Level 7 Heading=">edit</a>]</span> <span class="mw-headline" id=".3D_Level_7_Heading.3D">= Level 7 Heading=</span></h6> -<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=8" title="Edit section: == Level 8 Heading==">edit</a>]</span> <span class="mw-headline" id=".3D.3D_Level_8_Heading.3D.3D">== Level 8 Heading==</span></h6> -<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=9" title="Edit section: === Level 9 Heading===">edit</a>]</span> <span class="mw-headline" id=".3D.3D.3D_Level_9_Heading.3D.3D.3D">=== Level 9 Heading===</span></h6> -<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=10" title="Edit section: ==== Level 10 Heading====">edit</a>]</span> <span class="mw-headline" id=".3D.3D.3D.3D_Level_10_Heading.3D.3D.3D.3D">==== Level 10 Heading====</span></h6> +</div> + +<h1><span class="mw-headline" id="Level_1_Heading">Level 1 Heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Level 1 Heading">edit</a><span class="mw-editsection-bracket">]</span></span></h1> +<h2><span class="mw-headline" id="Level_2_Heading">Level 2 Heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Level 2 Heading">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="Level_3_Heading">Level 3 Heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Level 3 Heading">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h4><span class="mw-headline" id="Level_4_Heading">Level 4 Heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Level 4 Heading">edit</a><span class="mw-editsection-bracket">]</span></span></h4> +<h5><span class="mw-headline" id="Level_5_Heading">Level 5 Heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Level 5 Heading">edit</a><span class="mw-editsection-bracket">]</span></span></h5> +<h6><span class="mw-headline" id="Level_6_Heading">Level 6 Heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: Level 6 Heading">edit</a><span class="mw-editsection-bracket">]</span></span></h6> +<h6><span class="mw-headline" id=".3D_Level_7_Heading.3D">= Level 7 Heading=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=7" title="Edit section: = Level 7 Heading=">edit</a><span class="mw-editsection-bracket">]</span></span></h6> +<h6><span class="mw-headline" id=".3D.3D_Level_8_Heading.3D.3D">== Level 8 Heading==</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=8" title="Edit section: == Level 8 Heading==">edit</a><span class="mw-editsection-bracket">]</span></span></h6> +<h6><span class="mw-headline" id=".3D.3D.3D_Level_9_Heading.3D.3D.3D">=== Level 9 Heading===</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=9" title="Edit section: === Level 9 Heading===">edit</a><span class="mw-editsection-bracket">]</span></span></h6> +<h6><span class="mw-headline" id=".3D.3D.3D.3D_Level_10_Heading.3D.3D.3D.3D">==== Level 10 Heading====</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=10" title="Edit section: ==== Level 10 Heading====">edit</a><span class="mw-editsection-bracket">]</span></span></h6> !! end @@ -7580,7 +10601,7 @@ TOC regression (bug 9764) == title 2 == === title 2.1 === !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#title_1"><span class="tocnumber">1</span> <span class="toctext">title 1</span></a> <ul> @@ -7598,13 +10619,14 @@ TOC regression (bug 9764) </ul> </li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a>]</span> <span class="mw-headline" id="title_1"> title 1 </span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1"> title 1.1 </span></h3> -<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 1.1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1.1"> title 1.1.1 </span></h4> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: title 1.2">edit</a>]</span> <span class="mw-headline" id="title_1.2"> title 1.2 </span></h3> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: title 2">edit</a>]</span> <span class="mw-headline" id="title_2"> title 2 </span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: title 2.1">edit</a>]</span> <span class="mw-headline" id="title_2.1"> title 2.1 </span></h3> +</div> + +<h2><span class="mw-headline" id="title_1">title 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="title_1.1">title 1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h4><span class="mw-headline" id="title_1.1.1">title 1.1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 1.1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h4> +<h3><span class="mw-headline" id="title_1.2">title 1.2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: title 1.2">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h2><span class="mw-headline" id="title_2">title 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: title 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="title_2.1">title 2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: title 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3> !! end @@ -7620,7 +10642,7 @@ wgMaxTocLevel=3 == title 2 == === title 2.1 === !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#title_1"><span class="tocnumber">1</span> <span class="toctext">title 1</span></a> <ul> @@ -7634,13 +10656,14 @@ wgMaxTocLevel=3 </ul> </li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a>]</span> <span class="mw-headline" id="title_1"> title 1 </span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1"> title 1.1 </span></h3> -<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 1.1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1.1"> title 1.1.1 </span></h4> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: title 1.2">edit</a>]</span> <span class="mw-headline" id="title_1.2"> title 1.2 </span></h3> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: title 2">edit</a>]</span> <span class="mw-headline" id="title_2"> title 2 </span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: title 2.1">edit</a>]</span> <span class="mw-headline" id="title_2.1"> title 2.1 </span></h3> +</div> + +<h2><span class="mw-headline" id="title_1">title 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="title_1.1">title 1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h4><span class="mw-headline" id="title_1.1.1">title 1.1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 1.1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h4> +<h3><span class="mw-headline" id="title_1.2">title 1.2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: title 1.2">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h2><span class="mw-headline" id="title_2">title 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: title 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="title_2.1">title 2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: title 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3> !! end @@ -7655,7 +10678,7 @@ wgMaxTocLevel=3 ====Section 1.1.1.1==== ==Section 2== !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Section_1"><span class="tocnumber">1</span> <span class="toctext">Section 1</span></a> <ul> @@ -7664,12 +10687,13 @@ wgMaxTocLevel=3 </li> <li class="toclevel-1 tocsection-5"><a href="#Section_2"><span class="tocnumber">2</span> <span class="toctext">Section 2</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 1">edit</a>]</span> <span class="mw-headline" id="Section_1">Section 1</span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Section 1.1">edit</a>]</span> <span class="mw-headline" id="Section_1.1">Section 1.1</span></h3> -<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Section 1.1.1">edit</a>]</span> <span class="mw-headline" id="Section_1.1.1">Section 1.1.1</span></h4> -<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Section 1.1.1.1">edit</a>]</span> <span class="mw-headline" id="Section_1.1.1.1">Section 1.1.1.1</span></h4> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Section 2">edit</a>]</span> <span class="mw-headline" id="Section_2">Section 2</span></h2> +</div> + +<h2><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="Section_1.1">Section 1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Section 1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h4><span class="mw-headline" id="Section_1.1.1">Section 1.1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Section 1.1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h4> +<h4><span class="mw-headline" id="Section_1.1.1.1">Section 1.1.1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Section 1.1.1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h4> +<h2><span class="mw-headline" id="Section_2">Section 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Section 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -7680,8 +10704,8 @@ Resolving duplicate section names == Foo bar == == Foo bar == !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Foo bar">edit</a>]</span> <span class="mw-headline" id="Foo_bar"> Foo bar </span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Foo bar">edit</a>]</span> <span class="mw-headline" id="Foo_bar_2"> Foo bar </span></h2> +<h2><span class="mw-headline" id="Foo_bar">Foo bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Foo bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Foo_bar_2">Foo bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Foo bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -7691,8 +10715,8 @@ Resolving duplicate section names with differing case (bug 10721) == Foo bar == == Foo Bar == !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Foo bar">edit</a>]</span> <span class="mw-headline" id="Foo_bar"> Foo bar </span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Foo Bar">edit</a>]</span> <span class="mw-headline" id="Foo_Bar_2"> Foo Bar </span></h2> +<h2><span class="mw-headline" id="Foo_bar">Foo bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Foo bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Foo_Bar_2">Foo Bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -7711,10 +10735,10 @@ __NOTOC__ {{sections}} ==Section 4== !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 0">edit</a>]</span> <span class="mw-headline" id="Section_0">Section 0</span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Template:Sections&action=edit&section=T-1" title="Template:Sections">edit</a>]</span> <span class="mw-headline" id="Section_1">Section 1</span></h3> -<h2><span class="editsection">[<a href="/index.php?title=Template:Sections&action=edit&section=T-2" title="Template:Sections">edit</a>]</span> <span class="mw-headline" id="Section_2">Section 2</span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Section 4">edit</a>]</span> <span class="mw-headline" id="Section_4">Section 4</span></h2> +<h2><span class="mw-headline" id="Section_0">Section 0</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 0">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Template:Sections&action=edit&section=T-1" title="Template:Sections">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h2><span class="mw-headline" id="Section_2">Section 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Template:Sections&action=edit&section=T-2" title="Template:Sections">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Section_4">Section 4</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Section 4">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -7725,8 +10749,8 @@ __NOEDITSECTION__ ==Section 1== ==Section 2== !! result -<h2> <span class="mw-headline" id="Section_1">Section 1</span></h2> -<h2> <span class="mw-headline" id="Section_2">Section 2</span></h2> +<h2><span class="mw-headline" id="Section_1">Section 1</span></h2> +<h2><span class="mw-headline" id="Section_2">Section 2</span></h2> !! end @@ -7735,7 +10759,7 @@ Link inside a section heading !! input ==Section with a [[Main Page|link]] in it== !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section with a link in it">edit</a>]</span> <span class="mw-headline" id="Section_with_a_link_in_it">Section with a <a href="/wiki/Main_Page" title="Main Page">link</a> in it</span></h2> +<h2><span class="mw-headline" id="Section_with_a_link_in_it">Section with a <a href="/wiki/Main_Page" title="Main Page">link</a> in it</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section with a link in it">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -7747,7 +10771,7 @@ __TOC__ === title 1.1 === == title 2 == !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#title_1"><span class="tocnumber">1</span> <span class="toctext">title 1</span></a> <ul> @@ -7756,10 +10780,11 @@ __TOC__ </li> <li class="toclevel-1 tocsection-3"><a href="#title_2"><span class="tocnumber">2</span> <span class="toctext">title 2</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a>]</span> <span class="mw-headline" id="title_1"> title 1 </span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1"> title 1.1 </span></h3> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 2">edit</a>]</span> <span class="mw-headline" id="title_2"> title 2 </span></h2> +</div> + +<h2><span class="mw-headline" id="title_1">title 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="title_1.1">title 1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h2><span class="mw-headline" id="title_2">title 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -7781,10 +10806,10 @@ The line above must have a trailing space! --> <!-- --> But just in case it doesn't... !! result -<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: =">edit</a>]</span> <span class="mw-headline" id=".3D">=</span></h1> +<h1><span class="mw-headline" id=".3D">=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: =">edit</a><span class="mw-editsection-bracket">]</span></span></h1> <p>The line above must have a trailing space! </p> -<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: =">edit</a>]</span> <span class="mw-headline" id=".3D_2">=</span></h1> +<h1><span class="mw-headline" id=".3D_2">=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: =">edit</a><span class="mw-editsection-bracket">]</span></span></h1> <p>But just in case it doesn't... </p> !! end @@ -7811,7 +10836,7 @@ section 5 !! result <p>The tooltips shall not show entities to the user (ie. be double escaped) </p> -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#text_.3E_text"><span class="tocnumber">1</span> <span class="toctext">text > text</span></a></li> <li class="toclevel-1 tocsection-2"><a href="#text_.3C_text"><span class="tocnumber">2</span> <span class="toctext">text < text</span></a></li> @@ -7819,20 +10844,21 @@ section 5 <li class="toclevel-1 tocsection-4"><a href="#text_.27_text"><span class="tocnumber">4</span> <span class="toctext">text ' text</span></a></li> <li class="toclevel-1 tocsection-5"><a href="#text_.22_text"><span class="tocnumber">5</span> <span class="toctext">text " text</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: text > text">edit</a>]</span> <span class="mw-headline" id="text_.3E_text"> text > text </span></h2> +</div> + +<h2><span class="mw-headline" id="text_.3E_text">text > text</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: text > text">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p>section 1 </p> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: text < text">edit</a>]</span> <span class="mw-headline" id="text_.3C_text"> text < text </span></h2> +<h2><span class="mw-headline" id="text_.3C_text">text < text</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: text < text">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p>section 2 </p> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: text & text">edit</a>]</span> <span class="mw-headline" id="text_.26_text"> text & text </span></h2> +<h2><span class="mw-headline" id="text_.26_text">text & text</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: text & text">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p>section 3 </p> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: text ' text">edit</a>]</span> <span class="mw-headline" id="text_.27_text"> text ' text </span></h2> +<h2><span class="mw-headline" id="text_.27_text">text ' text</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: text ' text">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p>section 4 </p> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: text " text">edit</a>]</span> <span class="mw-headline" id="text_.22_text"> text " text </span></h2> +<h2><span class="mw-headline" id="text_.22_text">text " text</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: text " text">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p>section 5 </p> !! end @@ -7846,18 +10872,59 @@ Headers with excess '=' characters =''italic'' heading== ==''italic'' heading= !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#foo.3D"><span class="tocnumber">1</span> <span class="toctext">foo=</span></a></li> <li class="toclevel-1 tocsection-2"><a href="#.3Dfoo"><span class="tocnumber">2</span> <span class="toctext">=foo</span></a></li> <li class="toclevel-1 tocsection-3"><a href="#italic_heading.3D"><span class="tocnumber">3</span> <span class="toctext"><i>italic</i> heading=</span></a></li> <li class="toclevel-1 tocsection-4"><a href="#.3Ditalic_heading"><span class="tocnumber">4</span> <span class="toctext">=<i>italic</i> heading</span></a></li> </ul> -</td></tr></table> -<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: foo=">edit</a>]</span> <span class="mw-headline" id="foo.3D">foo=</span></h1> -<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: =foo">edit</a>]</span> <span class="mw-headline" id=".3Dfoo">=foo</span></h1> -<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: italic heading=">edit</a>]</span> <span class="mw-headline" id="italic_heading.3D"><i>italic</i> heading=</span></h1> -<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: =italic heading">edit</a>]</span> <span class="mw-headline" id=".3Ditalic_heading">=<i>italic</i> heading</span></h1> +</div> + +<h1><span class="mw-headline" id="foo.3D">foo=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: foo=">edit</a><span class="mw-editsection-bracket">]</span></span></h1> +<h1><span class="mw-headline" id=".3Dfoo">=foo</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: =foo">edit</a><span class="mw-editsection-bracket">]</span></span></h1> +<h1><span class="mw-headline" id="italic_heading.3D"><i>italic</i> heading=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: italic heading=">edit</a><span class="mw-editsection-bracket">]</span></span></h1> +<h1><span class="mw-headline" id=".3Ditalic_heading">=<i>italic</i> heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: =italic heading">edit</a><span class="mw-editsection-bracket">]</span></span></h1> + +!! end + +!! test +HTML headers vs TOC (bug 23393) +(__NOEDITSECTION__ for clearer output, doesn't matter here) +!! input +<h1>Header 1</h1> +== Header 1.1 == +== Header 1.2 == + +<h1>Header 2 +</h1> +== Header 2.1 == +== Header 2.2 == +__NOEDITSECTION__ +!! result +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> +<ul> +<li class="toclevel-1"><a href="#Header_1"><span class="tocnumber">1</span> <span class="toctext">Header 1</span></a> +<ul> +<li class="toclevel-2 tocsection-1"><a href="#Header_1.1"><span class="tocnumber">1.1</span> <span class="toctext">Header 1.1</span></a></li> +<li class="toclevel-2 tocsection-2"><a href="#Header_1.2"><span class="tocnumber">1.2</span> <span class="toctext">Header 1.2</span></a></li> +</ul> +</li> +<li class="toclevel-1"><a href="#Header_2"><span class="tocnumber">2</span> <span class="toctext">Header 2</span></a> +<ul> +<li class="toclevel-2 tocsection-3"><a href="#Header_2.1"><span class="tocnumber">2.1</span> <span class="toctext">Header 2.1</span></a></li> +<li class="toclevel-2 tocsection-4"><a href="#Header_2.2"><span class="tocnumber">2.2</span> <span class="toctext">Header 2.2</span></a></li> +</ul> +</li> +</ul> +</div> + +<h1><span class="mw-headline" id="Header_1">Header 1</span></h1> +<h2><span class="mw-headline" id="Header_1.1">Header 1.1</span></h2> +<h2><span class="mw-headline" id="Header_1.2">Header 1.2</span></h2> +<h1><span class="mw-headline" id="Header_2">Header 2</span></h1> +<h2><span class="mw-headline" id="Header_2.1">Header 2.1</span></h2> +<h2><span class="mw-headline" id="Header_2.2">Header 2.2</span></h2> !! end @@ -7953,7 +11020,7 @@ div with illegal double attributes !! test div with empty attribute value, space before equals !! options -disabled +parsoid !! input <div class =>HTML rocks</div> !! result @@ -7966,7 +11033,7 @@ disabled !! test div with braces in attribute value !! options -disabled +parsoid !! input <div title="{}">Foo</div> !! result @@ -7983,7 +11050,7 @@ disabled !! test div with empty attribute value, no space before equals !! options -disabled +parsoid !! input <div class=>HTML rocks</div> !! result @@ -8079,6 +11146,81 @@ I always thought &xacute; was a cute letter. ### +### Nesting tests (see bug 41545, 50604, 51081) +### + +# This test case is fixed in Parsoid by domino 1.0.12. (bug 50604) +# Note that html2wt is considerably more difficult if we use <b> in +# the test case, instead of <big> +!! test +Ensure that HTML adoption agency algorithm is properly implemented. +!! input +<big>X<big>Y</big>Z</big> +!! result +<p><big>X<big>Y</big>Z</big> +</p> +!! end + +# This was bug 41545 in the PHP parser. +!! test +Nesting of <kbd> +!! input +<kbd>X<kbd>Y</kbd>Z</kbd> +!! result +<p><kbd>X<kbd>Y</kbd>Z</kbd> +</p> +!! end + +# The following cases were bug 51081 in the PHP parser. +# Note that there are some other nestable tags (b, i, etc) which are +# not covered; see bug 51081 for discussion. +!! test +Nesting of <em> +!! input +<em>X<em>Y</em>Z</em> +!! result +<p><em>X<em>Y</em>Z</em> +</p> +!! end + +!! test +Nesting of <strong> +!! input +<strong>X<strong>Y</strong>Z</strong> +!! result +<p><strong>X<strong>Y</strong>Z</strong> +</p> +!! end + +!! test +Nesting of <q> +!! input +<q>X<q>Y</q>Z</q> +!! result +<p><q>X<q>Y</q>Z</q> +</p> +!! end + +!! test +Nesting of <ruby> +!! input +<ruby>X<ruby>Y</ruby>Z</ruby> +!! result +<p><ruby>X<ruby>Y</ruby>Z</ruby> +</p> +!! end + +!! test +Nesting of <bdo> +!! input +<bdo>X<bdo>Y</bdo>Z</bdo> +!! result +<p><bdo>X<bdo>Y</bdo>Z</bdo> +</p> +!! end + + +### ### Media links ### @@ -8470,70 +11612,6 @@ MSIE CSS safety test: comment in expression !! end -!! test -CSS safety test: vertical tab -!! input -<p style="font-size: 100px; background-image:url\b(https://www.google.com/images/srpr/logo6w.png)">A</p> -!! result -<p style="/* invalid control char */">A</p> - -!! end - -!! test -MSIE CSS safety test: Fullwidth -!! input -<p style="font-size: 100px; color: expression((title='XSSed'),'red')">A</p> -<div style="top:EXPRESSION(alert())">B</div> -!! result -<p style="/* insecure input */">A</p> -<div style="/* insecure input */">B</div> - -!! end - -!! test -MSIE CSS safety test: IPA extensions -!! input -<div style="background-image:uʀʟ(javascript:alert())">A</div> -<p style="font-size: 100px; color: expʀessɪoɴ((title='XSSed'),'red')">B</p> -!! result -<div style="/* insecure input */">A</div> -<p style="/* insecure input */">B</p> - -!! end - -!! test -MSIE CSS safety test: sup/sub script -!! input -<div style="background-image:url⁽javascript:alert())">A</div> -<div style="background-image:url₍javascript:alert())">B</div> -<p style="font-size: 100px; color: expressioⁿ((title='XSSed'),'red')">C</p> -!! result -<div style="/* insecure input */">A</div> -<div style="/* insecure input */">B</div> -<p style="/* insecure input */">C</p> - -!! end - -!! test -MSIE CSS safety test: Repetition markers -!! input -<p style="font-size: 100px; color: expres〱ion((title='XSSed'),'red')">A</p> -<p style="font-size: 100px; color: expresゝion((title='XSSed'),'red')">B</p> -<p style="font-size: 100px; color: expresーion((title='XSSed'),'red')">C</p> -<p style="font-size: 100px; color: expresヽion((title='XSSed'),'red')">D</p> -<p style="font-size: 100px; color: expresﹽion((title='XSSed'),'red')">E</p> -<p style="font-size: 100px; color: expresﹼion((title='XSSed'),'red')">F</p> -<p style="font-size: 100px; color: expresーion((title='XSSed'),'red')">G</p> -!! result -<p style="/* insecure input */">A</p> -<p style="/* insecure input */">B</p> -<p style="/* insecure input */">C</p> -<p style="/* insecure input */">D</p> -<p style="/* insecure input */">E</p> -<p style="/* insecure input */">F</p> -<p style="/* insecure input */">G</p> - -!! end !! test Table attribute legitimate extension @@ -8617,7 +11695,7 @@ Expansion of multi-line templates in attribute values (bug 6255 sanity check 2) !! end ### -### Parser hooks (see maintenance/parserTestsParserHook.php for the <tag> extension) +### Parser hooks (see tests/parser/parserTestsParserHook.php for the <tag> extension) ### !! test Parser hook: empty input @@ -8782,7 +11860,7 @@ array ( !! end ### -### (see maintenance/parserTestsStaticParserHook.php for the <statictag> extension) +### (see tests/parser/parserTestsParserHook.php for the <statictag> extension) ### !! test @@ -9014,8 +12092,10 @@ disabled !! result <ul> <li>One -</li><li>Two -</li></ul> +</li> +<li>Two +</li> +</ul> !! end @@ -9046,8 +12126,10 @@ disabled !! result <ol> <li>One -</li><li>Two -</li></ol> +</li> +<li>Two +</li> +</ol> !! end @@ -9092,12 +12174,16 @@ disabled !! result <ul> <li>One -</li><li>Two: +</li> +<li>Two: <ul> <li>Sub-one -</li><li>Sub-two -</li></ul> -</li></ul> +</li> +<li>Sub-two +</li> +</ul> +</li> +</ul> !! end @@ -9142,21 +12228,27 @@ disabled !! result <ol> <li>One -</li><li>Two: +</li> +<li>Two: <ol> <li>Sub-one -</li><li>Sub-two -</li></ol> -</li></ol> +</li> +<li>Sub-two +</li> +</ol> +</li> +</ol> !! end !! test HTML ordered list item with parameters oddity !! input -<ol><li id="fragment">One</li></ol> +<ol><li id="fragment">One</li> +</ol> !! result -<ol><li id="fragment">One</li></ol> +<ol><li id="fragment">One</li> +</ol> !! end @@ -9208,12 +12300,13 @@ Fuzz testing: Parser14 == onmouseover= == http://__TOC__ !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: onmouseover=">edit</a>]</span> <span class="mw-headline" id="onmouseover.3D"> onmouseover= </span></h2> -http://<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<h2><span class="mw-headline" id="onmouseover.3D">onmouseover=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: onmouseover=">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +http://<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#onmouseover.3D"><span class="tocnumber">1</span> <span class="toctext">onmouseover=</span></a></li> </ul> -</td></tr></table> +</div> + !! end @@ -9223,7 +12316,7 @@ Fuzz testing: Parser14-table ==a== {| STYLE=__TOC__ !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: a">edit</a>]</span> <span class="mw-headline" id="a">a</span></h2> +<h2><span class="mw-headline" id="a">a</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: a">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <table style="__TOC__"> <tr><td></td></tr> </table> @@ -9369,7 +12462,7 @@ Fuzz testing: image with bogus manual thumbnail !!input [[Image:foobar.jpg|thumbnail= ]] !!result -<div class="thumb tright"><div class="thumbinner" style="width:1943px;">Error creating thumbnail: <div class="thumbcaption"></div></div></div> +<div class="thumb tright"><div class="thumbinner" style="width:182px;">Error creating thumbnail: <div class="thumbcaption"></div></div></div> !!end @@ -10380,17 +13473,33 @@ Handling of 
 in URLs !! input **irc://
a !! result -<ul><li><ul><li><a rel="nofollow" class="external free" href="irc://%0Aa">irc://%0Aa</a> -</li></ul> -</li></ul> +<ul> +<li><ul> +<li><a rel="nofollow" class="external free" href="irc://%0Aa">irc://%0Aa</a> +</li> +</ul> +</li> +</ul> !!end !! test -5 quotes, code coverage +1 line +5 quotes, code coverage +1 line (php) +!! options +php +!! input +''''' +!! result +!! end +# The PHP parser strips the empty tags out for giggles; parsoid doesn't. +!! test +5 quotes, code coverage +1 line (parsoid) +!! options +parsoid !! input ''''' !! result +<p><b><i></i></b></p> !! end !! test @@ -10404,43 +13513,78 @@ Special:Search page linking. !! test Say the magic word +!! options +title=[[Parser test]] !! input * {{PAGENAME}} +* {{PAGENAMEE}} +* {{FULLPAGENAME}} +* {{FULLPAGENAMEE}} * {{BASEPAGENAME}} +* {{BASEPAGENAMEE}} * {{SUBPAGENAME}} * {{SUBPAGENAMEE}} -* {{BASEPAGENAME}} -* {{BASEPAGENAMEE}} +* {{ROOTPAGENAME}} +* {{ROOTPAGENAMEE}} * {{TALKPAGENAME}} * {{TALKPAGENAMEE}} * {{SUBJECTPAGENAME}} * {{SUBJECTPAGENAMEE}} * {{NAMESPACEE}} * {{NAMESPACE}} +* {{NAMESPACENUMBER}} * {{TALKSPACE}} * {{TALKSPACEE}} * {{SUBJECTSPACE}} * {{SUBJECTSPACEE}} * {{Dynamic|{{NUMBEROFUSERS}}|{{NUMBEROFPAGES}}|{{CURRENTVERSION}}|{{CONTENTLANGUAGE}}|{{DIRECTIONMARK}}|{{CURRENTTIMESTAMP}}|{{NUMBEROFARTICLES}}}} !! result -<ul><li> Parser test -</li><li> Parser test -</li><li> Parser test -</li><li> Parser_test -</li><li> Parser test -</li><li> Parser_test -</li><li> Talk:Parser test -</li><li> Talk:Parser_test -</li><li> Parser test -</li><li> Parser_test -</li><li> -</li><li> -</li><li> Talk -</li><li> Talk -</li><li> -</li><li> -</li><li> <a href="/index.php?title=Template:Dynamic&action=edit&redlink=1" class="new" title="Template:Dynamic (page does not exist)">Template:Dynamic</a> -</li></ul> +<ul> +<li> Parser test +</li> +<li> Parser_test +</li> +<li> Parser test +</li> +<li> Parser_test +</li> +<li> Parser test +</li> +<li> Parser_test +</li> +<li> Parser test +</li> +<li> Parser_test +</li> +<li> Parser test +</li> +<li> Parser_test +</li> +<li> Talk:Parser test +</li> +<li> Talk:Parser_test +</li> +<li> Parser test +</li> +<li> Parser_test +</li> +<li> +</li> +<li> +</li> +<li> 0 +</li> +<li> Talk +</li> +<li> Talk +</li> +<li> +</li> +<li> +</li> +<li> <a href="/index.php?title=Template:Dynamic&action=edit&redlink=1" class="new" title="Template:Dynamic (page does not exist)">Template:Dynamic</a> +</li> +</ul> !! end ### Note: Above tests excludes the "{{NUMBEROFADMINS}}" magic word because it generates a MySQL error when included. @@ -10459,40 +13603,40 @@ image4 |300px| centre * image6 </gallery> !! result -<ul class="gallery"> +<ul class="gallery mw-gallery-traditional"> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Image1.png</div> + <div class="thumb" style="height: 150px;">Image1.png</div> <div class="gallerytext"> </div> </div></li> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Image2.gif</div> + <div class="thumb" style="height: 150px;">Image2.gif</div> <div class="gallerytext"> <p>|||| </p> </div> </div></li> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Image3</div> + <div class="thumb" style="height: 150px;">Image3</div> <div class="gallerytext"> </div> </div></li> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Image4</div> + <div class="thumb" style="height: 150px;">Image4</div> <div class="gallerytext"> <p>300px| centre </p> </div> </div></li> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Image5.svg</div> + <div class="thumb" style="height: 150px;">Image5.svg</div> <div class="gallerytext"> <p><a rel="nofollow" class="external free" href="http://///////">http://///////</a> </p> </div> </div></li> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">* image6</div> + <div class="thumb" style="height: 150px;">* image6</div> <div class="gallerytext"> </div> </div></li> @@ -10511,17 +13655,17 @@ image:foobar.jpg image:foobar.jpg|Blabla|alt=This is a foo-bar.|blabla. </gallery> !! result -<ul class="gallery" style="max-width: 226px;_width: 226px;"> +<ul class="gallery mw-gallery-traditional" style="max-width: 226px;_width: 226px;"> <li class='gallerycaption'>Foo <a href="/wiki/Main_Page" title="Main Page">Main Page</a></li> <li class="gallerybox" style="width: 105px"><div style="width: 105px"> - <div style="height: 70px;">Nonexistant.jpg</div> + <div class="thumb" style="height: 70px;">Nonexistant.jpg</div> <div class="gallerytext"> <p>caption </p> </div> </div></li> <li class="gallerybox" style="width: 105px"><div style="width: 105px"> - <div style="height: 70px;">Nonexistant.jpg</div> + <div class="thumb" style="height: 70px;">Nonexistant.jpg</div> <div class="gallerytext"> </div> </div></li> @@ -10556,7 +13700,7 @@ File:foobar.jpg|[[File:foobar.jpg|20px|desc|alt=inneralt]]|alt=galleryalt File:foobar.jpg|{{Test|unamedParam|alt=param}}|alt=galleryalt </gallery> !! result -<ul class="gallery"> +<ul class="gallery mw-gallery-traditional"> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div> <div class="gallerytext"> @@ -10585,9 +13729,9 @@ image:foobar.jpg|some '''caption''' [[Main Page]] File:Foobar.jpg </gallery> !! result -<ul class="gallery"> +<ul class="gallery mw-gallery-traditional"> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Nonexistant.jpg</div> + <div class="thumb" style="height: 150px;">Nonexistant.jpg</div> <div class="gallerytext"> <p><a href="/wiki/File:Nonexistant.jpg" title="File:Nonexistant.jpg">Nonexistant.jpg</a><br /> caption @@ -10595,7 +13739,7 @@ caption </div> </div></li> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Nonexistant.jpg</div> + <div class="thumb" style="height: 150px;">Nonexistant.jpg</div> <div class="gallerytext"> <p><a href="/wiki/File:Nonexistant.jpg" title="File:Nonexistant.jpg">Nonexistant.jpg</a><br /> </p> @@ -10630,14 +13774,14 @@ image:foobar.jpg foobar.jpg </gallery> !! result -<ul class="gallery"> +<ul class="gallery mw-gallery-traditional"> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Nonexistant.jpg</div> + <div class="thumb" style="height: 150px;">Nonexistant.jpg</div> <div class="gallerytext"> </div> </div></li> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Nonexistant.jpg</div> + <div class="thumb" style="height: 150px;">Nonexistant.jpg</div> <div class="gallerytext"> </div> </div></li> @@ -10828,13 +13972,25 @@ disabled !! input :;;;:: !! result -<dl><dd><dl><dt><dl><dt><dl><dt><dl><dd><dl><dd> -</dd></dl> -</dd></dl> -</dt></dl> -</dt></dl> -</dt></dl> -</dd></dl> +<dl> +<dd><dl> +<dt><dl> +<dt><dl> +<dt><dl> +<dd><dl> +<dd> +</dd> +</dl> +</dd> +</dl> +</dt> +</dl> +</dt> +</dl> +</dt> +</dl> +</dd> +</dl> !!end @@ -10861,7 +14017,7 @@ Images with the "|" character in the comment !! test HTML with raw HTML ($wgRawHtml==true) !! options -rawhtml +wgRawHtml=1 !! input <html><script>alert(1);</script></html> !! result @@ -10930,6 +14086,45 @@ subpage title=[[Subpage test/L1/L2/L3]] </p> !! end +!! article +Subpage test/L1/L2/L3Sibling +!! text +Sibling article +!! endarticle + +!! test +Transclusion of a sibling page (one level up) +!! options +subpage title=[[Subpage test/L1/L2/L3]] +!! input +{{../L3Sibling}} +!! result +<p>Sibling article +</p> +!! end + +!! test +Transclusion of a child page +!! options +subpage title=[[Subpage test/L1/L2]] +!! input +{{/L3Sibling}} +!! result +<p>Sibling article +</p> +!! end + +!! test +Non-transclusion because of too many up levels +!! options +subpage title=[[Subpage test/L1/L2/L3]] +!! input +{{../../../../More than parent}} +!! result +<p>{{../../../../More than parent}} +</p> +!! end + !! test Definition list code coverage !! input @@ -10937,10 +14132,17 @@ Definition list code coverage ; title : def ;title: def !! result -<dl><dt> title  </dt><dd> def -</dd><dt> title </dt><dd> def -</dd><dt>title</dt><dd> def -</dd></dl> +<dl> +<dt> title  </dt> +<dd> def +</dd> +<dt> title </dt> +<dd> def +</dd> +<dt>title</dt> +<dd> def +</dd> +</dl> !! end @@ -11004,7 +14206,7 @@ Inclusion of !userCanEdit() content !! input {{MediaWiki:Fake}} !! result -<h2><span class="editsection">[<a href="/index.php?title=MediaWiki:Fake&action=edit&section=T-1" title="MediaWiki:Fake">edit</a>]</span> <span class="mw-headline" id="header">header</span></h2> +<h2><span class="mw-headline" id="header">header</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=MediaWiki:Fake&action=edit&section=T-1" title="MediaWiki:Fake">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -11019,7 +14221,7 @@ Out-of-order TOC heading levels =====5===== ==2== !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#2"><span class="tocnumber">1</span> <span class="toctext">2</span></a> <ul> @@ -11034,13 +14236,14 @@ Out-of-order TOC heading levels </ul> </li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: 2">edit</a>]</span> <span class="mw-headline" id="2">2</span></h2> -<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: 6">edit</a>]</span> <span class="mw-headline" id="6">6</span></h6> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: 3">edit</a>]</span> <span class="mw-headline" id="3">3</span></h3> -<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: 1">edit</a>]</span> <span class="mw-headline" id="1">1</span></h1> -<h5><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: 5">edit</a>]</span> <span class="mw-headline" id="5">5</span></h5> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: 2">edit</a>]</span> <span class="mw-headline" id="2_2">2</span></h2> +</div> + +<h2><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h6><span class="mw-headline" id="6">6</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: 6">edit</a><span class="mw-editsection-bracket">]</span></span></h6> +<h3><span class="mw-headline" id="3">3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: 3">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1> +<h5><span class="mw-headline" id="5">5</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: 5">edit</a><span class="mw-editsection-bracket">]</span></span></h5> +<h2><span class="mw-headline" id="2_2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -11147,14 +14350,11 @@ anchorencode encodes like the TOC generator: (bug 18431) {{anchorencode: _ +:.3A%3A&&]] }} __NOEDITSECTION__ !! result -<h3> <span class="mw-headline" id=".2B:.3A.253A.26.26.5D.5D"> _ +:.3A%3A&&]] </span></h3> +<h3><span class="mw-headline" id=".2B:.3A.253A.26.26.5D.5D">_ +:.3A%3A&&]]</span></h3> <p>.2B:.3A.253A.26.26.5D.5D </p> !! end -# Expected output in the following test is not necessarily expected (there -# should probably be <p> tags inside the <blockquote> in the output) -- it's -# only testing for well-formedness. !! test Bug 6200: blockquotes and paragraph formatting !! input @@ -11167,7 +14367,8 @@ bar baz !! result <blockquote> -foo +<p>foo +</p> </blockquote> <p>bar </p> @@ -11196,6 +14397,27 @@ bar </pre> !! end +!!test +Parsing of overlapping (improperly nested) inline html tags (PHP parser) +!!options +php +!!input +<span><s>x</span></s> +!!result +<p><span><s>x</span></s></span> +</p> +!!end + +!!test +Parsing of overlapping (improperly nested) inline html tags (Parsoid) +!!options +parsoid +!!input +<span><s>x</span></s> +!!result +<p><span><s>x</s></span><s></s> +</p> +!!end ### ### Language variants related tests @@ -11229,6 +14451,17 @@ title=[[Duna]] language=sr !! end !! test +Link to a section of a variant of this title shouldn't be parsed as self-link +!! options +title=[[Duna]] language=sr +!! input +[[Dуна]] is a self-link while [[Dunа#Foo]] and [[Dуна#Foo]] are not self-links. +!! result +<p><strong class="selflink">Dуна</strong> is a self-link while <a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Dunа#Foo</a> and <a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Dуна#Foo</a> are not self-links. +</p> +!! end + +!! test Link to pages in language variants !! options language=sr @@ -11377,7 +14610,7 @@ language=sr variant=sr-ec !! input == -{Naslov}- == !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Уредите одељак „Naslov“">уреди</a>]</span> <span class="mw-headline" id="-.7BNaslov.7D-"> Naslov </span></h2> +<h2><span class="mw-headline" id="-.7BNaslov.7D-">Naslov</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Уредите одељак „Naslov“">уреди</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -11491,6 +14724,30 @@ This won't take interferes with the title rule. !! end !! test +Partly disable title conversion if variant == main language code +!! options +language=zh variant=zh title=[[ZH]] showtitle +!! input +-{T|zh-cn:CN;zh-tw:TW}- +!! result +ZH +<p> +</p> +!! end + +!! test +Partly disable title conversion if variant == main language code, more +!! options +language=zh variant=zh title=[[ZH]] showtitle +!! input +-{T|TW}- +!! result +ZH +<p> +</p> +!! end + +!! test Raw output of variant escape tags (R flag) !! options language=zh variant=zh-tw @@ -11568,20 +14825,17 @@ language=sr </p> !!end -!!article -Template:Bullet -!!text -* Bar -!!endarticle - !! test Bug 529: Uncovered bullet !! input * Foo {{bullet}} !! result -<ul><li> Foo -</li><li> Bar -</li></ul> +<ul> +<li> Foo +</li> +<li> Bar +</li> +</ul> !! end @@ -11596,15 +14850,30 @@ Bug 529: Uncovered bullet leaving empty list, normally removed by tidy !! input ******* Foo {{bullet}} !! result -<ul><li><ul><li><ul><li><ul><li><ul><li><ul><li><ul><li> Foo -</li></ul> -</li></ul> -</li></ul> -</li></ul> -</li></ul> -</li></ul> -</li><li> Bar -</li></ul> +<ul> +<li><ul> +<li><ul> +<li><ul> +<li><ul> +<li><ul> +<li><ul> +<li> Foo +</li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +<li> Bar +</li> +</ul> !! end @@ -11636,9 +14905,12 @@ Bug 529: Uncovered bullet in parser function result !! input * Foo {{lc:{{bullet}} }} !! result -<ul><li> Foo -</li><li> bar -</li></ul> +<ul> +<li> Foo +</li> +<li> bar +</li> +</ul> !! end @@ -11694,7 +14966,7 @@ Morwen/13: Unclosed link followed by heading !! result <p>[[link </p> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: heading">edit</a>]</span> <span class="mw-headline" id="heading">heading</span></h2> +<h2><span class="mw-headline" id="heading">heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: heading">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -11706,7 +14978,7 @@ HHP2.1: Heuristics for headings in preprocessor parenthetical structures !! result <p>{{foo| </p> -<h1> <span class="mw-headline" id="heading">heading</span></h1> +<h1><span class="mw-headline" id="heading">heading</span></h1> !! end @@ -11718,7 +14990,7 @@ HHP2.2: Heuristics for headings in preprocessor parenthetical structures !! result <p>{{foo| </p> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: heading">edit</a>]</span> <span class="mw-headline" id="heading">heading</span></h2> +<h2><span class="mw-headline" id="heading">heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: heading">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -11808,8 +15080,6 @@ B</strong> # Bug 6200: <blockquote> should behave like <div> with respect to line breaks !! test Bug 6200: paragraphs inside blockquotes (no extra line breaks) -!! options -disabled !! input <blockquote>Line one @@ -11822,8 +15092,6 @@ Line two</blockquote> !! test Bug 6200: paragraphs inside blockquotes (extra line break on open) -!! options -disabled !! input <blockquote> Line one @@ -11839,8 +15107,6 @@ Line two</blockquote> !! test Bug 6200: paragraphs inside blockquotes (extra line break on close) -!! options -disabled !! input <blockquote>Line one @@ -11856,8 +15122,6 @@ Line two !! test Bug 6200: paragraphs inside blockquotes (extra line break on open and close) -!! options -disabled !! input <blockquote> Line one @@ -12078,7 +15342,7 @@ comment title=[[Main Page]] !! input pre-comment text /* External links */ removed bogus entries !! result -pre-comment text - <a href="/wiki/Main_Page#External_links" title="Main Page">→</a><span dir="auto"><span class="autocomment">External links: </span> removed bogus entries</span> +pre-comment text <a href="/wiki/Main_Page#External_links" title="Main Page">→</a><span dir="auto"><span class="autocomment">External links: </span> removed bogus entries</span> !!end !! test @@ -12310,6 +15574,40 @@ Screen !! end !! test +Verify that displaytitle handles inline CSS styles (bug 26547) - rejected value +!! options +showtitle +title=[[Screen]] +!! config +wgAllowDisplayTitle=true +wgRestrictDisplayTitle=true +!! input +this is not the the title +{{DISPLAYTITLE:<span style="display: none;">s</span>creen}} +!! result +<span style="/* attempt to bypass $wgRestrictDisplayTitle */">s</span>creen +<p>this is not the the title +</p> +!! end + +!! test +Verify that displaytitle handles inline CSS styles (bug 26547) - accepted value +!! options +showtitle +title=[[Screen]] +!! config +wgAllowDisplayTitle=true +wgRestrictDisplayTitle=true +!! input +this is not the the title +{{DISPLAYTITLE:<span style="color: red;">s</span>creen}} +!! result +<span style="color: red;">s</span>creen +<p>this is not the the title +</p> +!! end + +!! test preload: check <noinclude> and <includeonly> !! options preload @@ -12533,12 +15831,13 @@ title=[[Main Page]] __TOC__ == ''Lost'' episodes == !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Lost_episodes"><span class="tocnumber">1</span> <span class="toctext"><i>Lost</i> episodes</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Lost episodes">edit</a>]</span> <span class="mw-headline" id="Lost_episodes"> <i>Lost</i> episodes </span></h2> +</div> + +<h2><span class="mw-headline" id="Lost_episodes"><i>Lost</i> episodes</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Lost episodes">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12550,12 +15849,13 @@ title=[[Main Page]] __TOC__ == '''should be bold''' then normal text == !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#should_be_bold_then_normal_text"><span class="tocnumber">1</span> <span class="toctext"><b>should be bold</b> then normal text</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: should be bold then normal text">edit</a>]</span> <span class="mw-headline" id="should_be_bold_then_normal_text"> <b>should be bold</b> then normal text </span></h2> +</div> + +<h2><span class="mw-headline" id="should_be_bold_then_normal_text"><b>should be bold</b> then normal text</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: should be bold then normal text">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12567,12 +15867,13 @@ title=[[Main Page]] __TOC__ == Image [[Image:foobar.jpg]] == !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Image"><span class="tocnumber">1</span> <span class="toctext">Image</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Image">edit</a>]</span> <span class="mw-headline" id="Image"> Image <a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> </span></h2> +</div> + +<h2><span class="mw-headline" id="Image">Image <a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Image">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12584,12 +15885,13 @@ title=[[Main Page]] __TOC__ == <blockquote>Quote</blockquote> == !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Quote"><span class="tocnumber">1</span> <span class="toctext">Quote</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Quote">edit</a>]</span> <span class="mw-headline" id="Quote"> <blockquote>Quote</blockquote> </span></h2> +</div> + +<h2><span class="mw-headline" id="Quote"><blockquote>Quote</blockquote></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Quote">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12603,12 +15905,13 @@ __TOC__ <small>Hanc marginis exiguitas non caperet.</small> QED !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Proof:_2_.3C_3"><span class="tocnumber">1</span> <span class="toctext">Proof: 2 < 3</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Proof: 2 < 3">edit</a>]</span> <span class="mw-headline" id="Proof:_2_.3C_3"> Proof: 2 < 3 </span></h2> +</div> + +<h2><span class="mw-headline" id="Proof:_2_.3C_3">Proof: 2 < 3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Proof: 2 < 3">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p><small>Hanc marginis exiguitas non caperet.</small> QED </p> @@ -12622,14 +15925,15 @@ __TOC__ == <i>Foo</i> <blockquote>Bar</blockquote> == !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Foo_Bar"><span class="tocnumber">1</span> <span class="toctext"><i>Foo</i> <b>Bar</b></span></a></li> <li class="toclevel-1 tocsection-2"><a href="#Foo_Bar_2"><span class="tocnumber">2</span> <span class="toctext"><i>Foo</i> Bar</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Foo Bar">edit</a>]</span> <span class="mw-headline" id="Foo_Bar"> <i>Foo</i> <b>Bar</b> </span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Foo Bar">edit</a>]</span> <span class="mw-headline" id="Foo_Bar_2"> <i>Foo</i> <blockquote>Bar</blockquote> </span></h2> +</div> + +<h2><span class="mw-headline" id="Foo_Bar"><i>Foo</i> <b>Bar</b></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Foo_Bar_2"><i>Foo</i> <blockquote>Bar</blockquote></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12641,14 +15945,15 @@ __TOC__ == <sup class="a > b">Evilbye</sup> == !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Hello"><span class="tocnumber">1</span> <span class="toctext"><sup>Hello</sup></span></a></li> <li class="toclevel-1 tocsection-2"><a href="#b.22.3EEvilbye"><span class="tocnumber">2</span> <span class="toctext"><sup> b">Evilbye</sup></span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Hello">edit</a>]</span> <span class="mw-headline" id="Hello"> <sup class="in-h2">Hello</sup> </span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: b">Evilbye">edit</a>]</span> <span class="mw-headline" id="b.22.3EEvilbye"> <sup> b">Evilbye</sup> </span></h2> +</div> + +<h2><span class="mw-headline" id="Hello"><sup class="in-h2">Hello</sup></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Hello">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="b.22.3EEvilbye"><sup> b">Evilbye</sup></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: b">Evilbye">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12666,7 +15971,7 @@ __TOC__ == <span dir="ltr" style="font-style: italic">Attributes after dir on these span tags must be deleted from the TOC</span> == !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#C.2B.2B"><span class="tocnumber">1</span> <span class="toctext"><span dir="ltr">C++</span></span></a></li> <li class="toclevel-1 tocsection-2"><a href="#.D7.96.D7.91.D7.A0.D7.92.21"><span class="tocnumber">2</span> <span class="toctext"><span dir="rtl">זבנג!</span></span></a></li> @@ -12674,12 +15979,13 @@ __TOC__ <li class="toclevel-1 tocsection-4"><a href="#All_attributes_on_these_span_tags_must_be_deleted_from_the_TOC"><span class="tocnumber">4</span> <span class="toctext"><span>All attributes on these span tags must be deleted from the TOC</span></span></a></li> <li class="toclevel-1 tocsection-5"><a href="#Attributes_after_dir_on_these_span_tags_must_be_deleted_from_the_TOC"><span class="tocnumber">5</span> <span class="toctext"><span dir="ltr">Attributes after dir on these span tags must be deleted from the TOC</span></span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: C++">edit</a>]</span> <span class="mw-headline" id="C.2B.2B"> <span dir="ltr">C++</span> </span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: זבנג!">edit</a>]</span> <span class="mw-headline" id=".D7.96.D7.91.D7.A0.D7.92.21"> <span dir="rtl">זבנג!</span> </span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: The attributes on these span tags must be deleted from the TOC">edit</a>]</span> <span class="mw-headline" id="The_attributes_on_these_span_tags_must_be_deleted_from_the_TOC"> <span style="font-style: italic">The attributes on these span tags must be deleted from the TOC</span> </span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: All attributes on these span tags must be deleted from the TOC">edit</a>]</span> <span class="mw-headline" id="All_attributes_on_these_span_tags_must_be_deleted_from_the_TOC"> <span style="font-style: italic" dir="ltr">All attributes on these span tags must be deleted from the TOC</span> </span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Attributes after dir on these span tags must be deleted from the TOC">edit</a>]</span> <span class="mw-headline" id="Attributes_after_dir_on_these_span_tags_must_be_deleted_from_the_TOC"> <span dir="ltr" style="font-style: italic">Attributes after dir on these span tags must be deleted from the TOC</span> </span></h2> +</div> + +<h2><span class="mw-headline" id="C.2B.2B"><span dir="ltr">C++</span></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: C++">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id=".D7.96.D7.91.D7.A0.D7.92.21"><span dir="rtl">זבנג!</span></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: זבנג!">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="The_attributes_on_these_span_tags_must_be_deleted_from_the_TOC"><span style="font-style: italic">The attributes on these span tags must be deleted from the TOC</span></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: The attributes on these span tags must be deleted from the TOC">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="All_attributes_on_these_span_tags_must_be_deleted_from_the_TOC"><span style="font-style: italic" dir="ltr">All attributes on these span tags must be deleted from the TOC</span></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: All attributes on these span tags must be deleted from the TOC">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Attributes_after_dir_on_these_span_tags_must_be_deleted_from_the_TOC"><span dir="ltr" style="font-style: italic">Attributes after dir on these span tags must be deleted from the TOC</span></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Attributes after dir on these span tags must be deleted from the TOC">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12696,7 +16002,7 @@ title=[[Main Page]] !! input {{int:Bug32057}} !! result -<h2><span class="editsection">[<a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Headline text">edit</a>]</span> <span class="mw-headline" id="Headline_text"> Headline text </span></h2> +<h2><span class="mw-headline" id="Headline_text">Headline text</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Headline text">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12798,7 +16104,7 @@ nowiki inside link inside heading (bug 18295) !! input ==[[foo|x<nowiki>y</nowiki>z]]== !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: xyz">edit</a>]</span> <span class="mw-headline" id="xyz"><a href="/index.php?title=Foo&action=edit&redlink=1" class="new" title="Foo (page does not exist)">xyz</a></span></h2> +<h2><span class="mw-headline" id="xyz"><a href="/index.php?title=Foo&action=edit&redlink=1" class="new" title="Foo (page does not exist)">xyz</a></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: xyz">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12837,7 +16143,7 @@ Gallery override link with WikiLink (bug 34852) File:foobar.jpg|caption|alt=galleryalt|link=InterWikiLink </gallery> !! result -<ul class="gallery"> +<ul class="gallery mw-gallery-traditional"> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/InterWikiLink"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div> <div class="gallerytext"> @@ -12856,7 +16162,7 @@ Gallery override link with absolute external link (bug 34852) File:foobar.jpg|caption|alt=galleryalt|link=http://www.example.org </gallery> !! result -<ul class="gallery"> +<ul class="gallery mw-gallery-traditional"> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="http://www.example.org"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div> <div class="gallerytext"> @@ -12875,7 +16181,7 @@ Gallery override link with malicious javascript (bug 34852) File:foobar.jpg|caption|alt=galleryalt|link=" onclick="alert('malicious javascript code!'); </gallery> !! result -<ul class="gallery"> +<ul class="gallery mw-gallery-traditional"> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/%22_onclick%3D%22alert(%27malicious_javascript_code!%27);"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div> <div class="gallerytext"> @@ -12894,7 +16200,7 @@ Gallery with invalid title as link (bug 43964) File:foobar.jpg|link=< </gallery> !! result -<ul class="gallery"> +<ul class="gallery mw-gallery-traditional"> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div> <div class="gallerytext"> @@ -12925,6 +16231,19 @@ abc !! end !!test +Special parser function +!! input +{{#special:RandomPage}} +{{#special:BaDtItLe}} +{{#special:Foobar}} +!! result +<p>Special:Random +Special:Badtitle +Special:Foobar +</p> +!! end + +!!test Bug 34939 - Case insensitive link parsing ([HttP://]) !! input [HttP://MediaWiki.Org/] @@ -12951,6 +16270,30 @@ HttP://MediaWiki.Org/ </p> !! end +!!test +Disable TOC +!! options +notoc +!! input +Lead +== Section 1 == +== Section 2 == +== Section 3 == +== Section 4 == +== Section 5 == +!! result +<p>Lead +</p> + +<h2><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Section_2">Section 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Section 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Section_3">Section 3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Section 3">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Section_4">Section 4</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Section 4">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Section_5">Section 5</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Section 5">edit</a><span class="mw-editsection-bracket">]</span></span></h2> + +!! end + + ### ### Parsoids-specific tests ### Parsoid-PHP parser incompatibilities @@ -12958,25 +16301,433 @@ HttP://MediaWiki.Org/ !!test 1. SOL-sensitive wikitext tokens as template-args !!options -disabled +parsoid=wt2html,wt2wt !!input {{echo|*a}} {{echo|#a}} {{echo|:a}} !!result -<p>*a -#a -:a -</p> +<span about="#mwt1" typeof="mw:Transclusion"> +</span><ul about="#mwt1"><li>a</li> +</ul> +<span about="#mwt2" typeof="mw:Transclusion"> +</span><ol about="#mwt2"><li>a</li> +</ol> +<span about="#mwt3" typeof="mw:Transclusion"> +</span><dl about="#mwt3"><dd>a</dd> +</dl> +!!end + +#### ---------------------------------------------------------------- +#### Parsoid-only testing of Parsoid's impl of <ref> and <references> +#### tags. Parsoid's output for these tags differs from that of the +#### PHP parser. +#### ---------------------------------------------------------------- + +!!test +Ref: 1. ref-location should be replaced with an index span +!!options +parsoid +!!input +A <ref>foo</ref> +B <ref name="x">foo</ref> +C <ref name="y" /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span> +B <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{"name":"x"}}' id="cite_ref-x-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-x-2">[2]</a></span> +C <span about="#mwt3" class="reference" data-mw='{"name":"ref","attrs":{"name":"y"}}' id="cite_ref-y-3-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-y-3">[3]</a></span></p> +!!end + +!!test +Ref: 2. ref-tags with identical names should all get the same index +!!options +parsoid +!!input +A <ref name="x">foo</ref> +B <ref name="x" /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{"name":"x"}}' id="cite_ref-x-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-x-1">[1]</a></span> +B <span about="#mwt2" class="reference" data-mw='{"name":"ref","attrs":{"name":"x"}}' id="cite_ref-x-1-1" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-x-1">[1]</a></span></p> +!!end + +!!test +Ref: 3. spaces in ref-names should be ignored +!!options +parsoid +!!input +A <ref name="x">foo</ref> +B <ref name=" x " /> +C <ref name= x /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{"name":"x"}}' id="cite_ref-x-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-x-1">[1]</a></span> +B <span about="#mwt2" class="reference" data-mw='{"name":"ref","attrs":{"name":"x"}}' id="cite_ref-x-1-1" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-x-1">[1]</a></span> +C <span about="#mwt3" class="reference" data-mw='{"name":"ref","attrs":{"name":"x"}}' id="cite_ref-x-1-2" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-x-1">[1]</a></span></p> +!!end + +!!test +Ref: 4. 'constructor' should be accepted as a valid ref-name +(NOTE: constructor is a predefined property in JS and constructor as a ref-name can clash with it if not handled properly) +!!options +parsoid +!!input +A <ref name="constructor">foo</ref> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{"name":"constructor"}}' id="cite_ref-constructor-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-constructor-1">[1]</a></span></p> +!!end + +!!test +Ref: 5. body should accept generic wikitext +!!options +parsoid +!!input +A <ref> + This is a '''[[bolded link]]''' and this is a {{echo|transclusion}} +</ref> + +<references /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"This is a <b data-parsoid=\"{&quot;dsr&quot;:[19,40,3,3]}\"><a rel=\"mw:WikiLink\" href=\"./Bolded_link\" data-parsoid=\"{&quot;stx&quot;:&quot;simple&quot;,&quot;a&quot;:{&quot;href&quot;:&quot;./Bolded_link&quot;},&quot;sa&quot;:{&quot;href&quot;:&quot;bolded link&quot;},&quot;dsr&quot;:[22,37,2,2]}\">bolded link</a></b> and this is a <span about=\"#mwt5\" typeof=\"mw:Transclusion\" data-mw=\"{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;transclusion&quot;}},&quot;i&quot;:0}}]}\" data-parsoid=\"{&quot;dsr&quot;:[55,76,null,null],&quot;pi&quot;:[[{&quot;k&quot;:&quot;1&quot;,&quot;spc&quot;:[&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;]}]]}\">transclusion</span>\n"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span></p> + +<ol class="references" typeof="mw:Extension/references" about="#mwt2" data-mw='{"name":"references","attrs":{}}'> +<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> This is a <b><a rel="mw:WikiLink" href="./Bolded_link">bolded link</a></b> and this is a <span about="#mwt3" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"transclusion"}},"i":0}}]}'>transclusion</span> +</li> +</ol> +!!end + +!!test +Ref: 6. indent-pres should not be output in ref-body +!!options +parsoid +!!input +A <ref> + foo + bar + baz +</ref> + +<references /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo\n bar\n baz\n"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span></p> + +<ol class="references" typeof="mw:Extension/references" about="#mwt3" data-mw='{"name":"references","attrs":{}}'> +<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo + bar + baz +</li> +</ol> +!!end + +!!test +Ref: 7. No p-wrapping in ref-body +!!options +parsoid +!!input +A <ref> +foo + +bar + + +baz + + + +booz +</ref> + +<references /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo\n\nbar\n\n\nbaz\n\n\n\nbooz\n"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span></p> + +<ol about="#mwt2" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'> +<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo + +bar + + +baz + + + +booz +</li> +</ol> +!!end + +!!test +Ref: 8. transclusion wikitext has lower precedence +!!options +parsoid +!!input +A <ref> foo {{echo|</ref> B C}} + +<references /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo <span typeof=\"mw:Nowiki\" data-parsoid=\"{&quot;src&quot;:&quot;{{&quot;,&quot;dsr&quot;:[12,14,0,0]}\">{{</span>echo|"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span> B C<span typeof="mw:Nowiki">}}</span></p> + +<ol about="#mwt2" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'> +<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo <span typeof="mw:Nowiki">{{</span>echo|</li> +</ol> +!!end + +!!test +Ref: 9. unclosed comments should not leak out of ref-body +!!options +parsoid +!!input +A <ref> foo <!--</ref> B C + +<references /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo <!---->"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span> B C</p> + +<ol about="#mwt2" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'> +<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo <!----></li> +</ol> +!!end + +!!test +Ref: 10. Unclosed HTML tags should not leak out of ref-body +!!options +parsoid +!!input +A <ref> <b> foo </ref> B C + +<references /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"<b data-parsoid=\"{&quot;stx&quot;:&quot;html&quot;,&quot;autoInsertedEnd&quot;:true,&quot;dsr&quot;:[8,16,3,0]}\"> foo </b>"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span> B C</p> + +<ol about="#mwt2" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'> +<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> <b> foo </b></li> +</ol> +!!end + +!!test +Ref: 11. ref-tags acts like an inline element wrt P-wrapping +!!options +parsoid +!!input +A <ref>foo</ref> B +C <ref>bar</ref> D +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span> B +C <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{}}' id="cite_ref-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-2">[2]</a></span> D</p> +!!end + +!!test +Ref: 12. ref-tags act as trailing newline migration barrier +!!options +parsoid +!!input +<!--the newline at the end of this line moves out of the p-tag-->a + +b<!--the newline at the end of this line stays inside the p-tag--> <ref /> +<ref /> + +c +!!result +<p><!--the newline at the end of this line moves out of the p-tag-->a</p> + + +<p>b<!--the newline at the end of this line stays inside the p-tag--> <span about="#mwt1" class="reference" data-mw='{"name":"ref","attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span> +<span about="#mwt2" class="reference" data-mw='{"name":"ref","attrs":{}}' id="cite_ref-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-2">[2]</a></span></p> + + +<p>c</p> +!!end + +!!test +Ref: 13. ref-tags are not SOL-transparent and block indent-pres +!!options +parsoid +!!input +<ref>foo</ref> A +<ref>bar +</ref> B +!!result +<p><span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span> A +<span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"bar\n"},"attrs":{}}' id="cite_ref-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-2">[2]</a></span> B</p> +!!end + +!!test +Ref: 14. A nested ref-tag should be emitted as plain text +!!options +parsoid +!!input +<ref>foo <ref>bar</ref> baz</ref> + +<references /> +!!result +<p><span about="#mwt1" class="reference" data-mw="{"name":"ref","body":{"html":"foo &lt;ref&gt;bar&lt;/ref&gt; baz"},"attrs":{}}" id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span></p> + +<ol class="references" typeof="mw:Extension/references" about="#mwt2" data-mw="{"name":"references","attrs":{}}"> +<li about="#cite_note-1" id="cite_note-1" data-parsoid="{}"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo <ref>bar</ref> baz</li> +</ol> +!!end + +!!test +Ref: 15. ref-tags with identical names should get identical indexes +!!options +parsoid +!!input +A1 <ref name="a">foo</ref> A2 <ref name="a" /> +B1 <ref name="b" /> B2 <ref name="b">bar</ref> + +<references /> +!!result +<p>A1 <span about="#mwt3" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{"name":"a"}}' id="cite_ref-a-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-a-1">[1]</a></span> A2 <span about="#mwt4" class="reference" data-mw='{"name":"ref","attrs":{"name":"a"}}' id="cite_ref-a-1-1" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-a-1">[1]</a></span> +B1 <span about="#mwt7" class="reference" data-mw='{"name":"ref","attrs":{"name":"b"}}' id="cite_ref-b-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-b-2">[2]</a></span> B2 <span about="#mwt8" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{"name":"b"}}' id="cite_ref-b-2-1" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-b-2">[2]</a></span></p> + +<ol about="#mwt10" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-a-1" id="cite_note-a-1"><span rel="mw:referencedBy">↑ <a href="#cite_ref-a-1-0">1.0</a> <a href="#cite_ref-a-1-1">1.1</a></span> foo</li><li about="#cite_note-b-2" id="cite_note-b-2"><span rel="mw:referencedBy">↑ <a href="#cite_ref-b-2-0">2.0</a> <a href="#cite_ref-b-2-1">2.1</a></span> bar</li> +</ol> +!!end + +!!test +References: 1. references tag without any refs should be handled properly +!!options +parsoid +!!input +<references /> +!!result +<ol about="#mwt2" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'></ol> +!!end + +!!test +References: 2. references tag with group only outputs references from that group +!!options +parsoid +!!input +A <ref group="a">foo</ref> +B <ref group="b">bar</ref> + +<references group='a' /> +!!result +<p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{"group":"a"}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[a 1]</a></span> +B <span about="#mwt4" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{"group":"b"}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[b 1]</a></span></p> + +<ol about="#mwt6" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{"group":"a"}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo</li> +</ol> +!!end + +!!test +References: 3. ref list should be cleared after processing references +!!options +parsoid +!!input +A <ref>foo</ref> + +<references /> + +B <ref>bar</ref> + +<references /> +!!result +<p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span></p> + +<ol about="#mwt4" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo</li> +</ol> + +<p>B <span about="#mwt6" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span></p> + +<ol about="#mwt8" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> bar</li> +</ol> !!end +!!test +References: 4. only referenced group should be cleared after processing references +!!options +parsoid +!!input +A <ref group="a">afoo</ref> +B <ref>bfoo</ref> + +<references group="a"/> + +C <ref>cfoo</ref> + +<references /> +!!result +<p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"afoo"},"attrs":{"group":"a"}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[a 1]</a></span> +B <span about="#mwt4" class="reference" data-mw='{"name":"ref","body":{"html":"bfoo"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"<ref>bfoo</ref>","dsr":[30,45,5,6]}'><a href="#cite_note-1">[1]</a></span></p> + +<ol about="#mwt6" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{"group":"a"}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> afoo</li> +</ol> + +<p>C <span about="#mwt8" class="reference" data-mw='{"name":"ref","body":{"html":"cfoo"},"attrs":{}}' id="cite_ref-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-2">[2]</a></span></p> + +<ol about="#mwt10" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> bfoo</li><li about="#cite_note-2" id="cite_note-2"><span rel="mw:referencedBy"><a href="#cite_ref-2-0">↑</a></span> cfoo</li> +</ol> +!!end + +!!test +References: 5. ref tags in references should be processed while ignoring all other content +!!options +parsoid +!!input +A <ref name="a" /> +B <ref name="b">bar</ref> + +<references> +<ref name="a">foo</ref> +This should just get lost. +</references> +!!result +<p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","attrs":{"name":"a"}}' id="cite_ref-a-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-a-1">[1]</a></span> +B <span about="#mwt4" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{"name":"b"}}' id="cite_ref-b-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-b-2">[2]</a></span></p> + +<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","body":{"extsrc":"<ref name=\"a\">foo</ref>\nThis should just get lost.","html":"\n<span about=\"#mwt8\" class=\"reference\" data-mw=\"{&quot;name&quot;:&quot;ref&quot;,&quot;body&quot;:{&quot;html&quot;:&quot;foo&quot;},&quot;attrs&quot;:{&quot;name&quot;:&quot;a&quot;}}\" rel=\"dc:references\" typeof=\"mw:Extension/ref\"><a href=\"#cite_note-a-1\">[1]</a></span>\n"},"attrs":{}}'><li about="#cite_note-a-1" id="cite_note-a-1"><span rel="mw:referencedBy"><a href="#cite_ref-a-1-0">↑</a></span> foo</li><li about="#cite_note-b-2" id="cite_note-b-2"><span rel="mw:referencedBy"><a href="#cite_ref-b-2-0">↑</a></span> bar</li> +</ol> +!!end + +!!test +References: 6. <references /> from a transclusion +!!options +parsoid +!!input +{{echo|<references />}} +!!result +<ol class="references" about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<references />"}},"i":0}}]}'></ol> +!!end + +!! test +References: 7. Multiple references tags (one without and one with nested refs) should be correctly handled +!! options +parsoid +!! input +A <ref>foo bar for a</ref> +B <ref name="b" /> + +<references /> + +<references> +<ref name="b">foo</ref> +</references> +!! result +<p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"foo bar for a"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span> +B <span about="#mwt4" class="reference" data-mw='{"name":"ref","attrs":{"name":"b"}}' id="cite_ref-b-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-b-2">[2]</a></span></p> + +<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'> +<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo bar for a</li> +<li about="#cite_note-b-2" id="cite_note-b-2"><span rel="mw:referencedBy"><a href="#cite_ref-b-2-0">↑</a></span> </li> +</ol> + +<ol class="references" typeof="mw:Extension/references" about="#mwt8" data-mw='{"name":"references","body":{"extsrc":"<ref name=\"b\">foo</ref>","html":"\n<span about=\"#mwt10\" class=\"reference\" data-mw=\"{&quot;name&quot;:&quot;ref&quot;,&quot;body&quot;:{&quot;html&quot;:&quot;foo&quot;},&quot;attrs&quot;:{&quot;name&quot;:&quot;b&quot;}}\" rel=\"dc:references\" typeof=\"mw:Extension/ref\"><a href=\"#cite_note-b-1\">[1]</a></span>\n"},"attrs":{}}'> +<li about="#cite_note-b-1" id="cite_note-b-1"><span rel="mw:referencedBy">↑</span> foo</li> +</ol> +!! end + +#### ---------------------------------------------------------------- #### The following section of tests are primarily to test -#### wikitext escaping capabilities of Parsoid. -#### A lot of the tests are disabled for the PHP parser either -#### because of minor newline diffs or other reasons. -#### As Parsoid serializer can handle newlines and other HTML -#### more robustly, some of these tests might get reenabled -#### for the PHP parser. +#### wikitext escaping capabilities of Parsoid. Given that +#### escaping can be done any number of ways, the wikitext (input) +#### is always adjusted to reflect how Parsoid adds nowiki +#### escape tags. +#### +#### We are marking several tests as parsoid-only since the +#### HTML in the result section is different from what the +#### PHP parser generates for it. +#### ---------------------------------------------------------------- + #### --------------- Headings --------------- #### 0. Unnested @@ -12989,45 +16740,62 @@ disabled #### ---------------------------------------- !! test Headings: 0. Unnested +!! options +parsoid !! input <nowiki>=foo=</nowiki> -<nowiki>=foo</nowiki>''a''= +<nowiki> =foo= </nowiki> +<!--cmt--> +<nowiki>=foo=</nowiki> + +=foo''a''<nowiki>=</nowiki> !! result -<p>=foo= -</p><p>=foo<i>a</i>= -</p> +<p><span typeof="mw:Nowiki">=foo=</span></p> + +<p><span typeof="mw:Nowiki"> =foo= </span> +<!--cmt--> +<span typeof="mw:Nowiki">=foo=</span></p> + +<p>=foo<i>a</i><span typeof="mw:Nowiki">=</span></p> !!end !! test Headings: 1. Nested inside html !! options -disabled +parsoid !! input =<nowiki>=foo=</nowiki>= + ==<nowiki>=foo=</nowiki>== + ===<nowiki>=foo=</nowiki>=== + ====<nowiki>=foo=</nowiki>==== + =====<nowiki>=foo=</nowiki>===== + ======<nowiki>=foo=</nowiki>====== !! result -<h1>=foo=</h1> -<h2>=foo=</h2> -<h3>=foo=</h3> -<h4>=foo=</h4> -<h5>=foo=</h5> -<h6>=foo=</h6> +<h1><span typeof="mw:Nowiki">=foo=</span></h1> +<h2><span typeof="mw:Nowiki">=foo=</span></h2> +<h3><span typeof="mw:Nowiki">=foo=</span></h3> +<h4><span typeof="mw:Nowiki">=foo=</span></h4> +<h5><span typeof="mw:Nowiki">=foo=</span></h5> +<h6><span typeof="mw:Nowiki">=foo=</span></h6> !!end !! test Headings: 2. Outside heading nest on a single line <h1>foo</h1>*bar !! options -disabled +parsoid !! input =foo= -<nowiki>*bar</nowiki> +<nowiki>*</nowiki>bar + =foo= =bar + =foo= <nowiki>=bar=</nowiki> !! result @@ -13039,44 +16807,75 @@ disabled !! test Headings: 3. Nested inside html with wikitext split by html tags !! options -disabled +parsoid !! input -=<nowiki>=</nowiki>'''bold'''foo== +=='''bold'''<nowiki>foo=</nowiki>= !! result -<h1>=<b>bold</b>foo=</h1> +<h1>=<b>bold</b><span typeof="mw:Nowiki">foo=</span></h1> !!end !! test -Headings: 4. No escaping needed (testing just h1 and h2) +Headings: 4a. No escaping needed (testing just h1 and h2) !! options -disabled +parsoid !! input ==foo= + =foo== + += =foo= = + +==foo= bar= + ===foo== + ==foo=== + =''=''foo== -=== + +=<nowiki>=</nowiki>= !! result <h1>=foo</h1> <h1>foo=</h1> +<h1> =foo= </h1> +<h1>=foo= bar</h1> <h2>=foo</h2> <h2>foo=</h2> <h1><i>=</i>foo=</h1> -<h1>=</h1> +<h1><span typeof="mw:Nowiki">=</span></h1> +!!end + +!! test +Headings: 4b. No escaping needed (inside p-tags) +!! options +parsoid +!! input +=== +=foo= x +=foo= <s></s> +!! result +<p>=== +=foo= x +=foo= <s></s> +</p> !!end !! test Headings: 5. Empty headings !! options -disabled +parsoid !! input -=<nowiki></nowiki>= -==<nowiki></nowiki>== -===<nowiki></nowiki>=== -====<nowiki></nowiki>==== -=====<nowiki></nowiki>===== -======<nowiki></nowiki>====== +=<nowiki/>= + +==<nowiki/>== + +===<nowiki/>=== + +====<nowiki/>==== + +=====<nowiki/>===== + +======<nowiki/>====== !! result <h1></h1> <h2></h2> @@ -13087,16 +16886,87 @@ disabled !!end !! test -Headings: 6. Heading chars in SOL context +Headings: 6a. Heading chars in SOL context (with trailing spaces) !! options -disabled +parsoid +!! input +<nowiki>=a=</nowiki> + +<nowiki>=a=</nowiki> + +<nowiki>=a=</nowiki> + +<nowiki>=a=</nowiki> +!! result +<p>=a=</p> +<p>=a= </p> +<p>=a= </p> +<p>=a= </p> +!!end + +!! test +Headings: 6b. Heading chars in SOL context (with trailing newlines) +!! options +parsoid !! input -<!--cmt--><nowiki>=h1=</nowiki> +<nowiki>=a= +b</nowiki> + +<nowiki>=a= +b</nowiki> + +<nowiki>=a= +b</nowiki> + +<nowiki>=a= +b</nowiki> !! result -<p><!--cmt-->=h1= +<p>=a= +b</p> +<p>=a= +b</p> +<p>=a= +b</p> +<p>=a= +b</p> </p> !!end +!! test +Headings: 6c. Heading chars in SOL context (leading newline break) +!! options +parsoid +!! input +a +<nowiki>=b=</nowiki> +!! result +<p>a +=b=</p> +!!end + +!! test +Headings: 6d. Heading chars in SOL context (with interspersed comments) +!! options +parsoid +!! input +<!--c0--><nowiki>=a=</nowiki> +<!--c1--> +<nowiki>=a=</nowiki> <!--c2--> <!--c3--> +!! result +<p><!--c0-->=a=</p> +<p><!--c1-->=a= <!--c2--> <!--c3--></p> +!!end + +!! test +Headings: 6d. Heading chars in SOL context (No escaping needed) +!! options +parsoid=html2wt +!! input +=a=<div>b</div> +!! result +=a=<div>b</div> +!!end + #### --------------- Lists --------------- #### 0. Outside nests (*foo, etc.) #### 1. Nested inside html <ul><li>*foo</li></ul> @@ -13111,9 +16981,9 @@ disabled !! test Lists: 0. Outside nests !! input -<nowiki>*foo</nowiki> +<nowiki>*</nowiki>foo -<nowiki>#foo</nowiki> +<nowiki>#</nowiki>foo !! result <p>*foo </p><p>#foo @@ -13139,22 +17009,38 @@ Lists: 1. Nested inside html #<nowiki>;foo</nowiki> !! result -<ul><li>*foo -</li></ul> -<ul><li>#foo -</li></ul> -<ul><li>:foo -</li></ul> -<ul><li>;foo -</li></ul> -<ol><li>*foo -</li></ol> -<ol><li>#foo -</li></ol> -<ol><li>:foo -</li></ol> -<ol><li>;foo -</li></ol> +<ul> +<li>*foo +</li> +</ul> +<ul> +<li>#foo +</li> +</ul> +<ul> +<li>:foo +</li> +</ul> +<ul> +<li>;foo +</li> +</ul> +<ol> +<li>*foo +</li> +</ol> +<ol> +<li>#foo +</li> +</ol> +<ol> +<li>:foo +</li> +</ol> +<ol> +<li>;foo +</li> +</ol> !!end @@ -13170,15 +17056,24 @@ Lists: 2. Inside definition lists :<nowiki>:foo</nowiki> !! result -<dl><dt>;foo -</dt></dl> -<dl><dt>:foo -</dt></dl> -<dl><dt>:foo -</dt><dd>bar -</dd></dl> -<dl><dd>:foo -</dd></dl> +<dl> +<dt>;foo +</dt> +</dl> +<dl> +<dt>:foo +</dt> +</dl> +<dl> +<dt>:foo +</dt> +<dd>bar +</dd> +</dl> +<dl> +<dd>:foo +</dd> +</dl> !!end @@ -13189,17 +17084,21 @@ Lists: 3. Only bullets at start of text should be escaped *<nowiki>*foo</nowiki>''it''*bar !! result -<ul><li>*foo*bar -</li></ul> -<ul><li>*foo<i>it</i>*bar -</li></ul> +<ul> +<li>*foo*bar +</li> +</ul> +<ul> +<li>*foo<i>it</i>*bar +</li> +</ul> !!end !! test Lists: 4. No escapes needed !! options -disabled +parsoid !! input *foo*bar @@ -13207,12 +17106,18 @@ disabled *[[Foo]]: bar !! result -<ul><li>foo*bar -</li></ul> -<ul><li><i>foo</i>*bar -</li></ul> -<ul><li><a href="Foo" rel="mw:WikiLink">Foo</a>: bar -</li></ul> +<ul> +<li>foo*bar +</li> +</ul> +<ul> +<li><i>foo</i>*bar +</li> +</ul> +<ul> +<li><a rel="mw:WikiLink" href="Foo">Foo</a>: bar +</li> +</ul> !!end !! test @@ -13224,39 +17129,54 @@ Lists: 5. No unnecessary escapes *[[bar <span><nowiki>[[foo]]</nowiki></span> -*<nowiki>]]bar </nowiki><span><nowiki>[[foo]]</nowiki></span> +*]]bar <span><nowiki>[[foo]]</nowiki></span> *=bar <span>foo]]</span>= + +* <s></s>: a !! result -<ul><li> bar <span>[[foo]]</span> -</li></ul> -<ul><li>=bar <span>[[foo]]</span> -</li></ul> -<ul><li>[[bar <span>[[foo]]</span> -</li></ul> -<ul><li>]]bar <span>[[foo]]</span> -</li></ul> -<ul><li>=bar <span>foo]]</span>= -</li></ul> +<ul> +<li> bar <span>[[foo]]</span> +</li> +</ul> +<ul> +<li>=bar <span>[[foo]]</span> +</li> +</ul> +<ul> +<li>[[bar <span>[[foo]]</span> +</li> +</ul> +<ul> +<li>]]bar <span>[[foo]]</span> +</li> +</ul> +<ul> +<li>=bar <span>foo]]</span>= +</li> +</ul> +<ul> +<li> <s></s>: a +</li> +</ul> !!end !! test Lists: 6. Escape bullets in SOL position !! options -disabled +parsoid !! input <!--cmt--><nowiki>*foo</nowiki> !! result -<p><!--cmt-->*foo -</p> +<p><!--cmt--><span typeof="mw:Nowiki">*foo</span></p> !!end !! test Lists: 7. Escape bullets in a multi-line context !! input -<nowiki>a -*b</nowiki> +a +<nowiki>*</nowiki>b !! result <p>a *b @@ -13270,18 +17190,15 @@ Lists: 7. Escape bullets in a multi-line context !! test HRs: 1. Single line !! options -disabled +parsoid !! input ----- -<nowiki>----</nowiki> ----- -<nowiki>=foo=</nowiki> ----- -<nowiki>*foo</nowiki> +----<nowiki>----</nowiki> +----=foo= +----*foo !! result -<hr/>---- -<hr/>=foo= -<hr/>*foo +<hr><span typeof="mw:Nowiki">----</span> +<hr>=foo= +<hr>*foo !! end #### --------------- Tables --------------- @@ -13344,102 +17261,92 @@ Tables: 1d. No escaping needed !! test Tables: 2a. Nested in td !! options -disabled +parsoid !! input {| |<nowiki>foo|bar</nowiki> |} !! result -<table> -<tr><td>foo|bar -</td></tr></table> - +<table><tbody><tr> +<td><span typeof="mw:Nowiki">foo|bar</span></td></tr></tbody></table> !! end !! test Tables: 2b. Nested in td !! options -disabled +parsoid !! input {| |<nowiki>foo||bar</nowiki> |''it''<nowiki>foo||bar</nowiki> |} !! result -<table> -<tr><td>foo||bar -</td><td><i>it</i>foo||bar -</td></tr></table> - +<table><tbody><tr> +<td><span typeof="mw:Nowiki">foo||bar</span></td> +<td><i>it</i><span typeof="mw:Nowiki">foo||bar</span></td></tr></tbody></table> !! end !! test Tables: 2c. Nested in td -- no escaping needed !! options -disabled +parsoid !! input {| |foo!!bar |} !! result -<table> -<tr><td>foo!!bar -</td></tr></table> +<table><tbody><tr><td>foo!!bar +</td></tr></tbody></table> !! end !! test Tables: 3a. Nested in th !! options -disabled +parsoid !! input {| !foo!bar |} !! result -<table> -<tr><th>foo!bar -</th></tr></table> +<table><tbody><tr><th>foo!bar +</th></tr></tbody></table> !! end !! test Tables: 3b. Nested in th !! options -disabled +parsoid !! input {| !<nowiki>foo!!bar</nowiki> |} !! result <table> -<tr><th>foo!!bar -</th></tr></table> - +<tbody><tr><th><span typeof="mw:Nowiki">foo!!bar</span></th></tr> +</tbody></table> !! end !! test Tables: 3c. Nested in th -- no escaping needed !! options -disabled +parsoid !! input {| -!foo||bar +!<nowiki>foo||bar</nowiki> |} !! result -<table> -<tr><th>foo||bar -</th></tr></table> - +<table><tbody><tr> +<th><span typeof="mw:Nowiki">foo||bar</span></th></tr></tbody></table> !! end !! test Tables: 4a. Escape - !! options -disabled +parsoid !! input {| -|- !-bar |- |<nowiki>-bar</nowiki> @@ -13447,17 +17354,16 @@ disabled !! result <table><tbody> <tr><th>-bar</th></tr> -<tr><td>-bar</td></tr> -</tbody></table> +<tr> +<td><span typeof="mw:Nowiki">-bar</span></td></tr></tbody></table> !! end !! test Tables: 4b. Escape + !! options -disabled +parsoid !! input {| -|- !+bar |- |<nowiki>+bar</nowiki> @@ -13465,32 +17371,48 @@ disabled !! result <table><tbody> <tr><th>+bar</th></tr> -<tr><td>+bar</td></tr> -</tbody></table> +<tr> +<td><span typeof="mw:Nowiki">+bar</span></td></tr></tbody></table> !! end !! test Tables: 4c. No escaping needed !! options -disabled +parsoid !! input {| -|- |foo-bar |foo+bar |- |''foo''-bar |''foo''+bar +|- +|foo +bar|baz ++bar +-bar |} !! result <table><tbody> <tr><td>foo-bar</td><td>foo+bar</td></tr> <tr><td><i>foo</i>-bar</td><td><i>foo</i>+bar</td></tr> +<tr><td>foo +<p>bar|baz ++bar +-bar</p></td></tr> </tbody></table> !! end +### SSS FIXME: Disabled right now because accurate html2wt +### on this snippet requires data-parsoid flags that we've +### stripped out of these tests. We should scheme how we +### we want to handle these kind of tests that require +### data-parsoid flags for accurate html2wt serialization + !! test Tables: 4d. No escaping needed +!! options +disabled !! input {| ||+1 @@ -13506,7 +17428,7 @@ Tables: 4d. No escaping needed !! end -#### --------------- Links --------------- +#### --------------- Links ---------------- #### 1. Quote marks in link text #### 2. Wikilinks: Escapes needed #### 3. Wikilinks: No escapes needed @@ -13516,9 +17438,9 @@ Tables: 4d. No escaping needed !! test Links 1. Quote marks in link text !! options -disabled +parsoid !! input -[[Foo|<nowiki>Foo''boo''</nowiki>]] +[[Foo|Foo<nowiki>''boo''</nowiki>]] !! result <a rel="mw:WikiLink" href="Foo">Foo''boo''</a> !! end @@ -13526,15 +17448,18 @@ disabled !! test Links 2. WikiLinks: Escapes needed !! options -disabled +parsoid !! input [[Foo|<nowiki>[Foobar]</nowiki>]] [[Foo|<nowiki>Foobar]</nowiki>]] -[[Foo|<nowiki>x [Foobar] x</nowiki>]] +[[Foo|x [Foobar] x]] [[Foo|<nowiki>x [http://google.com g] x</nowiki>]] [[Foo|<nowiki>[[Bar]]</nowiki>]] [[Foo|<nowiki>x [[Bar]] x</nowiki>]] [[Foo|<nowiki>|Bar</nowiki>]] +[[Foo|<nowiki>]]bar</nowiki>]] +[[Foo|<nowiki>[[bar</nowiki>]] +[[Foo|<nowiki>x ]] y [[ z</nowiki>]] !! result <a href="Foo" rel="mw:WikiLink">[Foobar]</a> <a href="Foo" rel="mw:WikiLink">Foobar]</a> @@ -13543,12 +17468,15 @@ disabled <a href="Foo" rel="mw:WikiLink">[[Bar]]</a> <a href="Foo" rel="mw:WikiLink">x [[Bar]] x</a> <a href="Foo" rel="mw:WikiLink">|Bar</a> +<a href="Foo" rel="mw:WikiLink">]]bar</a> +<a href="Foo" rel="mw:WikiLink">[[bar</a> +<a href="Foo" rel="mw:WikiLink">x ]] y [[ z</a> !! end !! test Links 3. WikiLinks: No escapes needed !! options -disabled +parsoid !! input [[Foo|[Foobar]] [[Foo|foo|bar]] @@ -13560,7 +17488,7 @@ disabled !! test Links 4. ExtLinks: Escapes needed !! options -disabled +parsoid !! input [http://google.com <nowiki>[google]</nowiki>] [http://google.com <nowiki>google]</nowiki>] @@ -13572,7 +17500,7 @@ disabled !! test Links 5. ExtLinks: No escapes needed !! options -disabled +parsoid !! input [http://google.com [google] !! result @@ -13583,26 +17511,44 @@ disabled #### 1. Quotes inside <b> and <i> #### 2. Link fragments separated by <i> and <b> tags #### 3. Link fragments inside <i> and <b> +#### 4. No escaping needed #### -------------------------------------- !! test 1. Quotes inside <b> and <i> +!! options +parsoid=html2wt,wt2wt !! input ''<nowiki>'foo'</nowiki>'' ''<nowiki>''foo''</nowiki>'' ''<nowiki>'''foo'''</nowiki>'' +''foo''<nowiki/>'s '''<nowiki>'foo'</nowiki>''' '''<nowiki>''foo''</nowiki>''' '''<nowiki>'''foo'''</nowiki>''' '''<nowiki>foo'</nowiki>''<nowiki>bar'</nowiki>''baz''' +'''foo'''<nowiki/>'s +'''foo'' +''foo''<nowiki/>' +'<nowiki/>''foo''<nowiki/>' +''''foo''' +'''foo'''<nowiki/>' +'<nowiki/>'''foo'''<nowiki/>' !! result <p><i>'foo'</i> <i>''foo''</i> <i>'''foo'''</i> +<i>foo</i>'s <b>'foo'</b> <b>''foo''</b> <b>'''foo'''</b> <b>foo'<i>bar'</i>baz</b> -</p> +<b>foo</b>'s +'<i>foo</i> +<i>foo</i>' +'<i>foo</i>' +'<b>foo</b> +<b>foo</b>' +'<b>foo</b>'</p> !! end !! test @@ -13618,7 +17564,7 @@ disabled !! end !! test -2. Link fragments inside <i> and <b> +3. Link fragments inside <i> and <b> (FIXME: Escaping one or both of [[ and ]] is also acceptable -- this is one of the shortcomings of this format) !! input @@ -13631,7 +17577,18 @@ disabled </p> !! end -#### --------------- Paragraphs --------------- +!! test +4. No escaping needed +!! input +'<span>''bar''</span>' +'<span>'''bar'''</span>' +!! result +<p>'<span><i>bar</i></span>' +'<span><b>bar</b></span>' +</p> +!! end + +#### ----------- Paragraphs --------------- #### 1. No unnecessary escapes #### -------------------------------------- @@ -13644,9 +17601,9 @@ bar <span><nowiki>[[foo]]</nowiki></span> [[bar <span><nowiki>[[foo]]</nowiki></span> -<nowiki>]]bar </nowiki><span><nowiki>[[foo]]</nowiki></span> +]]bar <span><nowiki>[[foo]]</nowiki></span> -<nowiki>=bar </nowiki><span>foo]]</span>= +=bar <span>foo]]</span><nowiki>=</nowiki> !! result <p>bar <span>[[foo]]</span> </p><p>=bar <span>[[foo]]</span> @@ -13656,31 +17613,78 @@ bar <span><nowiki>[[foo]]</nowiki></span> </p> !!end -#### --------------- PRE ------------------ -#### 1. Leading space in SOL context should be escaped -#### -------------------------------------- +#### ----------------------- PRE -------------------------- +#### 1. Leading whitespace in SOL context should be escaped +#### ------------------------------------------------------ !! test -1. Leading space in SOL context should be escaped +1. Leading whitespace in SOL context should be escaped !! options -disabled +parsoid !! input -<nowiki> foo</nowiki> -<!--cmt--><nowiki> foo</nowiki> +<nowiki> </nowiki>a + +<nowiki> </nowiki> a + +<nowiki> </nowiki>a(tab) + +<nowiki> </nowiki> a +<!--cmt--> +<nowiki> </nowiki> a + +a +<nowiki> </nowiki>b + +a +<nowiki> </nowiki>b + +a +<nowiki> </nowiki> b !! result -<p> foo -<!--cmt--> foo -</p> +<p> a</p> +<p> a</p> +<p> a(tab)</p> +<p> a</p> +<p><!--cmt--> a</p> +<p>a + b</p> +<p>a + b</p> +<p>a + b</p> +!! end + +#### --------------- Behavior Switches -------------------- +!! test +1. Valid behavior switches should be escaped +!! options +parsoid=html2wt +!! input +<nowiki>__TOC__</nowiki> +!! result +__TOC__ +!! end + +!! test +2. Invalid behavior switches should not be escaped +!! options +parsoid=html2wt +!! input +__TOO__ +__|__ +!! result +__TOO__ +__|__ !! end #### --------------- HTML tags --------------- #### 1. a tags #### 2. other tags #### 3. multi-line html tag -#### -------------------------------------- +#### ----------------------------------------- !! test 1. a tags !! options -disabled +parsoid !! input <a href="http://google.com">google</a> !! result @@ -13711,6 +17715,15 @@ disabled </p> !! end +!! test +4. extension tags +!! input +<nowiki><ref>foo</ref></nowiki> +!! result +<p><ref>foo</ref> +</p> +!! end + #### --------------- Others --------------- !! test Escaping nowikis @@ -13721,7 +17734,19 @@ Escaping nowikis </p> !! end +## The quote-char in the input is necessary for triggering the bug +!! test +(Bug 52035) Nowiki-escaping should not get tripped by " :" in text +!! options +parsoid=wt2wt,html2wt +!! input +foo's bar : +!! result +<p>foo's bar :</p> +!! end + !! test + Tag-like HTML structures are passed through as text !! input <x y> @@ -13749,16 +17774,14 @@ a>b !! end -# This fails in the PHP parser (see bug 40670, -# https://bugzilla.wikimedia.org/show_bug.cgi?id=40670), so disabled for it. +# This was a bug in the PHP parser (see bug 17663 and its dups, +# https://bugzilla.wikimedia.org/show_bug.cgi?id=17663) !! test Tag names followed by punctuation should not be recognized as tags -!! options -disabled !! input <s.ome> text !! result -<p><s.ome> text +<p><s.ome> text </p> !! end @@ -13841,14 +17864,34 @@ parsoid | style="color:red|Bar |} !! result -<table> +<table><tbody> <tr> <td title="Hello world">Foo </td><td style="color: red">Bar -</td></tr></table> +</td></tr></tbody></table> !! end +!! test +Parsoid-only: Don't wrap broken template tags in <nowiki> on wt2wt (Bug 42353) +!! options +parsoid +!! input +{{}} +!! result +{{}} +!! end + +!! test +Parsoid-only: Don't wrap broken template tags in <nowiki> on wt2wt (Bug 42353) +!! options +parsoid +!! input +}}{{ +!! result +}}{{ +!! end + !!test Accept empty td cell attribute !!input @@ -13915,6 +17958,556 @@ Empty table rows go away !! end +### +### Parsoid-centric tests for testing RTing of inter-element separators +### Edge cases not tested by existing parser tests and specific to +### Parsoid-specific serialization strategies. +### + +!!test +RT-ed inter-element separators should be valid separators +!!input +{| +|- [[foo]] +|} +!!result +<table> + +</table> + +!!end + +!!test +Trailing newlines in a deep dom-subtree that ends a wikitext line should be migrated out +(Parsoid-only since PHP parser relies on Tidy for correct output) +!!options +parsoid +!!input +{| +|<small>foo +bar +|} + +{| +|<small>foo<small> +|} +!!result +!!end + +!!test +Empty TD followed by TD with tpl-generated attribute +!!input +{| +|- +| +|{{echo|style='color:red'}}|foo +|} +!!result +<table> + +<tr> +<td> +</td> +<td>foo +</td></tr></table> + +!!end + +!!test +Indented table with an empty td +!!input + {| + |- + | + |foo + |} +!!result +<table> + +<tr> +<td> +</td> +<td>foo +</td></tr></table> + +!!end + +!!test +Empty TR followed by a template-generated TR +(Parsoid-specific since PHP parser doesn't handle this mixed tbl-wikitext) +!!options +parsoid +!!input +{| +|- +{{echo|<tr><td>foo</td></tr>}} +|} +!!result +<table> +<tbody> +<tr></tr> +<tr about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<tr><td>foo</td></tr>"}},"i":0}}]}'> +<td>foo</td></tr> +</tbody></table> +!!end + +## PHP and parsoid output differ for this, and since this is primarily +## for testing Parsoid's serializer, marking this Parsoid only +!!test +Empty TR followed by mixed-ws-comment line should RT correctly +!!options +parsoid +!!input +{| +|- + <!--c--> +|- +<!--c--> <!--d--> +|} +!!result +<table> +<tbody> +<tr></tr> + <!--c--> +<tr> +<!--c--> </tr><!--d--> +</tbody></table> + +!!end + +!!test +Multi-line image caption generated by templates with/without trailing newlines +!!options +parsoid +!!input +[[File:foo.jpg|thumb|300px|foo\n{{echo|A}}\n{{echo|B}}\n{{echo|C}}]] +[[File:foo.jpg|thumb|300px|foo\n{{echo|A}}\n{{echo|B}}\n{{echo|C}}\n\n]] +!!result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/index.php?title=Special:Upload&wpDestFile=Foo.jpg" class="new" title="File:Foo.jpg">File:Foo.jpg</a> <div class="thumbcaption">foo\nA\nB\nC</div></div></div> +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/index.php?title=Special:Upload&wpDestFile=Foo.jpg" class="new" title="File:Foo.jpg">File:Foo.jpg</a> <div class="thumbcaption">foo\nA\nB\nC\n\n</div></div></div> + +!!end + +## PHP emits broken html for this, and since this is primarily +## a Parsoid serializer test, marking this Parsoid only +!!test +Improperly nested inline or quotes tags with whitespace in between +!!options +parsoid +!!input +<span> <s>x</span> </s> +''' ''x''' '' +!!result +<p><span> <s>x</s></span><s> </s> +<b> <i>x</i></b><i> </i> +</p> +!!end + +!!test +Encapsulate protected attributes from wt +!!options +parsoid +!!input +<div typeof="mw:placeholder stuff" data-parsoid="weird" data-parsoid-other="no" about="time" rel="mw:true">foo</div> +!!result +<body><div data-x-typeof="mw:placeholder stuff" data-x-data-parsoid="weird" data-x-data-parsoid-other="no" data-x-about="time" data-x-rel="mw:true">foo</div> +</body> +!!end + +## Currently the p-wrapper is fragile in how adds / removes transformations. +## Having nested or stray pre tags results in the attempt to add duplicates, +## causing an assertion fail. This test tries to prevent that situation. +!!test +Ensure ParagraphWrapper can deal with stray closing pre tags +!!options +parsoid=wt2html +!!input +plain text</pre> +!!result +plain text +!!end + +!!test +Ensure fostered text content is wrapped in spans +!!options +parsoid=wt2html +!!input +<table>hi</table><table>ho</table> +!!result +<span>hi</span> +<table></table> +<span>ho</span> +<table></table> +!!end + +!!test +Encapsulation properly handles null DSR information from foster box +!!options +parsoid=wt2html,wt2wt +!!input +{{echo|<table>foo<tr><td>bar</td></tr></table>}} +!!result +<span typeof="mw:Transclusion" data-mw="{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":" +<table>foo +<tr> +<td>bar</td></tr></table>"}},"i":0}}]}">foo</span> +<table> +<tbody> +<tr> +<td>bar</td></tr></tbody></table> +!!end + +!!test +1. Encapsulate foster-parented transclusion content +!!options +parsoid=wt2wt,wt2html +!!input +<table>{{echo|foo<tr><td>bar</td></tr>}}</table> +!!result +<span typeof="mw:Transclusion" data-mw="{"parts":[" +<table>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo +<tr> +<td>bar</td></tr>"}},"i":0}},"</table>"]}">foo</span> +<table> +<tbody> +<tr> +<td>bar</td></tr></tbody></table> +!!end + +!!test +2. Encapsulate foster-parented transclusion content +!!options +parsoid=wt2wt,wt2html +!!input +<table><div>{{echo|foo}}</div><tr><td>bar</td></tr></table> +!!result +<div typeof="mw:Transclusion" data-mw="{"parts":[" +<table> +<div>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo"}},"i":0}},"</div> +<tr> +<td>bar</td></tr></table>"]}">foo</div> +<table> +<tbody> +<tr> +<td>bar</td></tr></tbody></table> +!!end + +!!test +3. Encapsulate foster-parented transclusion content +!!options +parsoid=wt2wt,wt2html +!!input +<table><div><p>{{echo|foo</p></div><tr><td>}}bar</td></tr></table> +!!result +<div typeof="mw:Transclusion" data-mw="{"parts":[" +<table> +<div> +<p>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo</p></div> +<tr> +<td>"}},"i":0}},"bar</td></tr></table>"]}"> +<p>foo</p></div> +<table> +<tbody> +<tr> +<td>bar</td></tr></tbody></table> +!!end + +!!test +4. Encapsulate foster-parented transclusion content +!!options +parsoid=wt2wt,wt2html +!!input +<table><div><p>{{echo|foo</p></div><tr><td>}}bar</td></tr></table> +!!result +<div typeof="mw:Transclusion" data-mw="{"parts":[" +<table> +<div> +<p>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo</p></div> +<tr> +<td>"}},"i":0}},"bar</td></tr></table>"]}"> +<p>foo</p></div> +<table> +<tbody> +<tr> +<td>bar</td></tr></tbody></table> +!!end + +!!test +5. Encapsulate foster-parented transclusion content +!!options +parsoid=wt2wt,wt2html +!!input +<table><tr><td><div><p>{{echo|foo</p></div></td>foo}}</tr></table> +!!result +<span typeof="mw:Transclusion" data-mw="{"parts":[" +<table> +<tr> +<td> +<div> +<p>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo</p></div></td>foo"}},"i":0}},"</tr></table>"]}">foo</span> +<table> +<tbody> +<tr> +<td> +<div> +<p>foo</p></div></td></tr></tbody></table> +!!end + +!!test +6. Encapsulate foster-parented transclusion content +!!options +parsoid=wt2wt,wt2html +!!input +<table><tr><td><div><p>{{echo|foo</p></div></td>foo</tr></table>}}<p>ok</p> +!!result +<span typeof="mw:Transclusion" data-mw="{"parts":[" +<table> +<tr> +<td> +<div> +<p>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo</p></div></td>foo</tr></table>"}},"i":0}}]}">foo</span> +<table> +<tbody> +<tr> +<td> +<div> +<p>foo</p></div></td></tr></tbody></table> +<p>ok</p> +!!end + +!!test +7. Encapsulate foster-parented transclusion content +!!options +parsoid=wt2wt,wt2html +!!input +<table>{{echo|<p>foo</p>}}<td>bar</td></table> +!!result +<p typeof="mw:Transclusion" data-mw="{"parts":[" +<table>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":" +<p>foo</p>"}},"i":0}}," +<td>bar</td></table>"]}">foo</p> +<table> +<tbody> +<tr> +<td>bar</td></tr></tbody></table> +!!end + +!!test +8. Encapsulate foster-parented transclusion content +!!options +parsoid=wt2wt,wt2html +!!input +{{echo|a +}}{|{{echo|style='color:red'}} +|- +|b +|} +!!result +<p typeof="mw:Transclusion" data-mw="{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n"}},"i":0}}]}">a</p><span typeof="mw:Transclusion" data-mw="{"parts":["{|",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"style":{"wt":"'color:red'"}},"i":0}},"\n|-\n|b\n|}"]}">{{{1}}}</span> +<table> +<tbody> +<tr> +<td>b</td></tr></tbody></table> +!!end + +# ----------------------------------------------------------------- +# The following section of tests are primarily to spec requirements +# around serialization of new/edited content. +# +# All these tests are marked Parsoid html2wt and html2html only +# ---------------------------------------------------------------- + +!! test +Image: Modifying size of an image +!! options +parsoid=html2wt +!! input +[[Image:Wiki.png|230x230px]] +!! result +<p data-parsoid='{"dsr":[0,24,0,0]}'><span typeof="mw:Image" data-parsoid='{"optList":[{"ck":"width","ak":"100px"}],"cacheKey":"[[Image:Wiki.png|100px]]","img":{"h":115,"w":100,"wdset":true},"dsr":[0,24,null,null]}'><a href="./File:Wiki.png" data-parsoid='{"a":{"href":"./File:Wiki.png"}}'><img resource="./File:Wiki.png" src="//upload.wikimedia.org/wikipedia/en/thumb/b/bc/Wiki.png/100px-Wiki.png" height="230" width="200" data-parsoid='{"a":{"resource":"./File:Wiki.png"},"sa":{"resource":"Image:Wiki.png"}}'></a></span></p> +!!end + +!! test +Image: New block level image should have \n before and after +!! options +parsoid=html2wt +!! input +123 +[[File:Wiki.png|right|thumb|150x150px]] +456 +!! result +<p>123</p><figure typeof="mw:Image/Thumb" class="mw-halign-right"><a href="./File:Wiki.png"><img src="http://192.168.142.128/mw/images/thumb/b/bc/Wiki.png/131px-Wiki.png" width="131" height="150" resource="./File:Wiki.png"></a></figure><p>456</p> +!!end + +# Wacky -- the leading newline in input is required because +# that is what the serializer emits. To be fixed. Not fixing +# the test because this test is required to test serialization of +# new content and preferred whitespace style. +!! test +Lists: Serialize correctly even when list content is wrapped in p-tags (like VE does) +!! options +parsoid=html2wt +!! input + +* foo +!! result +<ul> +<li><p>foo</p></li> +</ul> +!! end + +# Wacky -- the leading newline in input is required because +# that is what the serializer emits. To be fixed. Not fixing +# the test because this test is required to test serialization of +# new content and preferred whitespace style. +!! test +Lists: Add space after bullets +!! options +parsoid=html2wt +!! input + +* foo +* bar +* <span> baz</span> +!! result +<ul> +<li>foo</li> +<li> bar</li> +<li><span> baz</span></li> +</ul> +!! end + +!! test +Parsoid: Serialize positional parameters with = in them as named parameter +!! options +parsoid=html2wt +!! input +{{echo|1 = f=oo}} + +{{echo|1 = f=oo|2 = bar}} + +<!--Orig params with data-parsoid has heuristics for handling = chars--> +<!--FIXME: But maybe the heuristic needs fixing to apply to new params as well--> +{{echo|<nowiki>f=oo</nowiki>|bar}} +!! result +<p about="#mwt1" typeof="mw:Transclusion" +data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"f=oo"}},"i":0}}]}'>foo</p> + +<p about="#mwt1" typeof="mw:Transclusion" +data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"f=oo"}, "2":{"wt":"bar"}},"i":0}}]}'>foo</p> + +<!--Orig params with data-parsoid has heuristics for handling = chars--> +<!--FIXME: But maybe the heuristic needs fixing to apply to new params as well--> +<p data-parsoid='{"pi":[[{"k":"1","spc":["","","",""]},{"k":"2","spc":["","","",""]}]]}' about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"f=oo"},"2":{"wt":"bar"}},"i":0}}]}'>foo</p> +!! end + +!! test +Parsoid: Correctly serialize block-node children when they are a combination of text and p-nodes +!! options +parsoid=html2wt +!! input +<div>a +b +</div> +<div>a +b +</div> +<div> +a + +b +</div> +!! result +<div>a<p>b</p></div> +<div>a +<p>b</p></div> +<div> +a +<p>b</p></div> +!! end + +#----------------------------- +# I/B quote minimization tests +#----------------------------- + +!! test +1. I/B quote minimization: wikitext-only tags should be combined +!! options +parsoid=html2wt +!! input +''AB'' + +'''AB''' + +''A'''B''''' + +'''A''B''''' + +'''A''BC''D''' + +'''''AB''''' + +'''''AB''''' + +'''''AB''''' +!! result +<p><i>A</i><i>B</i></p> +<p><b>A</b><b>B</b></p> +<p><i>A</i><b><i>B</i></b></p> +<p><b>A</b><i><b>B</b></i></p> +<p><b>A</b><i><b>B</b><b>C</b></i><b>D</b></p> +<p><i><b>A</b></i><i><b>B</b></i></p> +<p><i><b>A</b></i><b><i>B</i></b></p> +<p><b><i>A</i></b><i><b>B</b></i></p> +!! end + +!! test +2. I/B quote minimization: wikitext and html tags should not be combined +!! options +parsoid=html2wt +!! input +''A''<i>B</i> + +''A'''''<i>B</i>''' +!! result +<p><i>A</i><i data-parsoid='{"stx":"html"}'>B</i></p> +<p><i>A</i><b><i data-parsoid='{"stx":"html"}'>B</i></b></p> +!! end + +!! test +3. I/B quote minimization: templated content stops minimization +!! options +parsoid=html2wt +!! input +''A''{{echo|''B''}} + +''A''{{echo|'''''B'''''}} +!! result +<p><i>A</i><i about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"''B''"}},"i":0}}]}'>B</i> +<p><i>A</i><b about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"'''''B'''''"}},"i":0}}]}'><i>B</i></b> +!! end + +!! test +4. I/B quote minimization: new content should be mimimized with adjacent old content +!! options +parsoid=html2wt +!! input +''AB'' + +'''AB''' + +''A'''B''''' +!! result +<p><i>A</i><i data-parsoid='{}'>B</i></p> +<p><b data-parsoid='{}'>A</b><b>B</b></p> +<p><i>A</i><b data-parsoid='{}'><i data-parsoid='{}'>B</i></b></p> +!! end + +# ----------------------------------------------------------------- +# End of section for Parsoid-only html2wt tests for serialization +# of new content +# ----------------------------------------------------------------- + TODO: more images more tables diff --git a/tests/parser/preprocess/All_system_messages.expected b/tests/parser/preprocess/All_system_messages.expected index 897c5fb0..078d8f0d 100644 --- a/tests/parser/preprocess/All_system_messages.expected +++ b/tests/parser/preprocess/All_system_messages.expected @@ -1239,27 +1239,6 @@ diff </td><td> <template lineStart="1"><title>int:Difference</title></template> </td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disambiguations&action=edit disambiguations]<br> -[[MediaWiki_talk:Disambiguations|Talk]] -</td><td> -Disambiguation pages -</td><td> -<template lineStart="1"><title>int:Disambiguations</title></template> -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disambiguationspage&action=edit disambiguationspage]<br> -[[MediaWiki_talk:Disambiguationspage|Talk]] -</td><td> -Wiktionary:Links_to_disambiguating_pages -</td><td> -<template lineStart="1"><title>int:Disambiguationspage</title></template> -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disambiguationstext&action=edit disambiguationstext]<br> -[[MediaWiki_talk:Disambiguationstext|Talk]] -</td><td> -The following pages link to a &lt;i&gt;disambiguation page&lt;/i&gt;. They should link to the appropriate topic instead.&lt;br /&gt;A page is treated as dismbiguation if it is linked from $1.&lt;br /&gt;Links from other namespaces are &lt;i&gt;not&lt;/i&gt; listed here. -</td><td> -<template lineStart="1"><title>int:Disambiguationstext</title></template> -</td></tr><tr><td> [http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disclaimerpage&action=edit disclaimerpage]<br> [[MediaWiki_talk:Disclaimerpage|Talk]] </td><td> diff --git a/tests/parser/preprocess/All_system_messages.txt b/tests/parser/preprocess/All_system_messages.txt index fc10d7cf..3c30da94 100644 --- a/tests/parser/preprocess/All_system_messages.txt +++ b/tests/parser/preprocess/All_system_messages.txt @@ -1239,27 +1239,6 @@ diff </td><td> {{int:Difference}} </td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disambiguations&action=edit disambiguations]<br> -[[MediaWiki_talk:Disambiguations|Talk]] -</td><td> -Disambiguation pages -</td><td> -{{int:Disambiguations}} -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disambiguationspage&action=edit disambiguationspage]<br> -[[MediaWiki_talk:Disambiguationspage|Talk]] -</td><td> -Wiktionary:Links_to_disambiguating_pages -</td><td> -{{int:Disambiguationspage}} -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disambiguationstext&action=edit disambiguationstext]<br> -[[MediaWiki_talk:Disambiguationstext|Talk]] -</td><td> -The following pages link to a <i>disambiguation page</i>. They should link to the appropriate topic instead.<br />A page is treated as dismbiguation if it is linked from $1.<br />Links from other namespaces are <i>not</i> listed here. -</td><td> -{{int:Disambiguationstext}} -</td></tr><tr><td> [http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disclaimerpage&action=edit disclaimerpage]<br> [[MediaWiki_talk:Disclaimerpage|Talk]] </td><td> diff --git a/tests/parserTests.php b/tests/parserTests.php index 804a30cb..debb3575 100644 --- a/tests/parserTests.php +++ b/tests/parserTests.php @@ -27,8 +27,8 @@ $otions = array( 'quick', 'color', 'quiet', 'help', 'show-output', 'record', 'run-disabled', 'run-parsoid' ); $optionsWithArgs = array( 'regex', 'filter', 'seed', 'setversion' ); -require_once( __DIR__ . '/../maintenance/commandLine.inc' ); -require_once( __DIR__ . '/TestsAutoLoader.php' ); +require_once __DIR__ . '/../maintenance/commandLine.inc'; +require_once __DIR__ . '/TestsAutoLoader.php'; if ( isset( $options['help'] ) ) { echo <<<ENDS @@ -84,11 +84,11 @@ if ( isset( $options['file'] ) ) { # Print out software version to assist with locating regressions $version = SpecialVersion::getVersion(); -echo( "This is MediaWiki version {$version}.\n\n" ); +echo "This is MediaWiki version {$version}.\n\n"; if ( isset( $options['fuzz'] ) ) { $tester->fuzzTest( $files ); } else { $ok = $tester->runTestsFromFiles( $files ); - exit ( $ok ? 0 : 1 ); + exit( $ok ? 0 : 1 ); } diff --git a/tests/phpunit/MediaWikiLangTestCase.php b/tests/phpunit/MediaWikiLangTestCase.php index 0cf6e383..1131385f 100644 --- a/tests/phpunit/MediaWikiLangTestCase.php +++ b/tests/phpunit/MediaWikiLangTestCase.php @@ -15,6 +15,10 @@ abstract class MediaWikiLangTestCase extends MediaWikiTestCase { "\$wgContLang->getCode() (" . $wgContLang->getCode() . ")" ); } + // HACK: Call getLanguage() so the real $wgContLang is cached as the user language + // rather than our fake one. This is to avoid breaking other, unrelated tests. + RequestContext::getMain()->getLanguage(); + $langCode = 'en'; # For mainpage to be 'Main Page' $langObj = Language::factory( $langCode ); diff --git a/tests/phpunit/MediaWikiPHPUnitCommand.php b/tests/phpunit/MediaWikiPHPUnitCommand.php index 12c2e003..042956a9 100644 --- a/tests/phpunit/MediaWikiPHPUnitCommand.php +++ b/tests/phpunit/MediaWikiPHPUnitCommand.php @@ -12,13 +12,29 @@ class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command { 'use-normal-tables' => false, 'reuse-db' => false, 'wiki=' => false, + 'debug-tests' => false, ); public function __construct() { foreach ( self::$additionalOptions as $option => $default ) { $this->longOptions[$option] = $option . 'Handler'; } + } + + protected function handleArguments( array $argv ) { + parent::handleArguments( $argv ); + + if ( !isset( $this->arguments['listeners'] ) ) { + $this->arguments['listeners'] = array(); + } + foreach ( $this->options[0] as $option ) { + switch ( $option[0] ) { + case '--debug-tests': + $this->arguments['listeners'][] = new MediaWikiPHPUnitTestListener( 'PHPUnitCommand' ); + break; + } + } } public static function main( $exit = true ) { @@ -86,7 +102,7 @@ class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command { ParserTest-specific options: --regex="<regex>" Only run parser tests that match the given regex - --file="<filename>" Prints the version and exits. + --file="<filename>" File describing parser tests --keep-uploads Re-use the same upload directory for each test, don't delete it @@ -95,7 +111,9 @@ Database options: --reuse-db Init DB only if tables are missing and keep after finish. +Debugging options: + --debug-tests Log testing activity to the PHPUnitCommand log channel. + EOT; } - } diff --git a/tests/phpunit/MediaWikiPHPUnitTestListener.php b/tests/phpunit/MediaWikiPHPUnitTestListener.php new file mode 100644 index 00000000..7237ef32 --- /dev/null +++ b/tests/phpunit/MediaWikiPHPUnitTestListener.php @@ -0,0 +1,114 @@ +<?php +class MediaWikiPHPUnitTestListener implements PHPUnit_Framework_TestListener { + + /** + * @var string + */ + protected $logChannel; + + public function __construct( $logChannel ) { + $this->logChannel = $logChannel; + } + + protected function getTestName( PHPUnit_Framework_Test $test ) { + $name = get_class( $test ); + + if ( $test instanceof PHPUnit_Framework_TestCase ) { + $name .= '::' . $test->getName( true ); + } + + return $name; + } + + protected function getErrorName( Exception $exception ) { + $name = get_class( $exception ); + $name = "[$name] " . $exception->getMessage(); + + return $name; + } + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError( PHPUnit_Framework_Test $test, Exception $e, $time ) { + wfDebugLog( $this->logChannel, 'ERROR in ' . $this->getTestName( $test ) . ': ' . $this->getErrorName( $e ) ); + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure( PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time ) { + wfDebugLog( $this->logChannel, 'FAILURE in ' . $this->getTestName( $test ) . ': ' . $this->getErrorName( $e ) ); + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest( PHPUnit_Framework_Test $test, Exception $e, $time ) { + wfDebugLog( $this->logChannel, 'Incomplete test ' . $this->getTestName( $test ) . ': ' . $this->getErrorName( $e ) ); + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * + * @since Method available since Release 3.0.0 + */ + public function addSkippedTest( PHPUnit_Framework_Test $test, Exception $e, $time ) { + wfDebugLog( $this->logChannel, 'Skipped test ' . $this->getTestName( $test ) . ': ' . $this->getErrorName( $e ) ); + } + + /** + * A test suite started. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function startTestSuite( PHPUnit_Framework_TestSuite $suite ) { + wfDebugLog( $this->logChannel, 'START suite ' . $suite->getName() ); + } + + /** + * A test suite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function endTestSuite( PHPUnit_Framework_TestSuite $suite ) { + wfDebugLog( $this->logChannel, 'END suite ' . $suite->getName() ); + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest( PHPUnit_Framework_Test $test ) { + wfDebugLog( $this->logChannel, 'Start test ' . $this->getTestName( $test ) ); + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest( PHPUnit_Framework_Test $test, $time ) { + wfDebugLog( $this->logChannel, 'End test ' . $this->getTestName( $test ) ); + } +} diff --git a/tests/phpunit/MediaWikiTestCase.php b/tests/phpunit/MediaWikiTestCase.php index 7e6e0ab8..6ce78b56 100644 --- a/tests/phpunit/MediaWikiTestCase.php +++ b/tests/phpunit/MediaWikiTestCase.php @@ -64,7 +64,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { 'oracle' ); - function __construct( $name = null, array $data = array(), $dataName = '' ) { + function __construct( $name = null, array $data = array(), $dataName = '' ) { parent::__construct( $name, $data, $dataName ); $this->backupGlobals = false; @@ -137,6 +137,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { protected function getNewTempFile() { $fname = tempnam( wfTempDir(), 'MW_PHPUnit_' . get_class( $this ) . '_' ); $this->tmpfiles[] = $fname; + return $fname; } @@ -158,6 +159,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { // where temporary directory creation is bundled and can be improved unlink( $fname ); $this->assertTrue( wfMkdirParents( $fname ) ); + return $fname; } @@ -171,7 +173,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { $this->called['setUp'] = 1; /* - //@todo: global variables to restore for *every* test + // @todo global variables to restore for *every* test array( 'wgLang', 'wgContLang', @@ -348,7 +350,8 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * Stub. If a test needs to add additional data to the database, it should * implement this method and do so */ - function addDBData() {} + function addDBData() { + } private function addCoreDBData() { # disabled for performance @@ -377,7 +380,6 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { 'page_touched' => $this->db->timestamp(), 'page_latest' => 0, 'page_len' => 0 ), __METHOD__, array( 'IGNORE' ) ); - } User::resetIdByNameCache(); @@ -394,7 +396,6 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { $user->saveSettings(); } - //Make 1 page with 1 revision $page = WikiPage::factory( Title::newFromText( 'UTPage' ) ); if ( !$page->getId() == 0 ) { @@ -438,7 +439,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * even if using different parameters. * * @param DatabaseBase $db The database connection - * @param String $prefix The prefix to use for the new table set (aka schema). + * @param String $prefix The prefix to use for the new table set (aka schema). * * @throws MWException if the database table prefix is already $prefix */ @@ -461,6 +462,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { if ( ( $db->getType() == 'oracle' || !self::$useTemporaryTables ) && self::$reuseDB ) { CloneDatabase::changePrefix( $prefix ); + return; } else { $dbClone->cloneTableStructure(); @@ -523,6 +525,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { private static function unprefixTable( $tableName ) { global $wgDBprefix; + return substr( $tableName, strlen( $wgDBprefix ) ); } @@ -534,6 +537,12 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { global $wgDBprefix; $tables = $db->listTables( $wgDBprefix, __METHOD__ ); + + if ( $db->getType() === 'mysql' ) { + # bug 43571: cannot clone VIEWs under MySQL + $views = $db->listViews( $wgDBprefix, __METHOD__ ); + $tables = array_diff( $tables, $views ); + } $tables = array_map( array( __CLASS__, 'unprefixTable' ), $tables ); // Don't duplicate test tables from the previous fataled run @@ -547,6 +556,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { unset( $tables['searchindex_segments'] ); $tables = array_flip( $tables ); } + return $tables; } @@ -561,13 +571,11 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { if ( isset( MediaWikiPHPUnitCommand::$additionalOptions[$offset] ) ) { return MediaWikiPHPUnitCommand::$additionalOptions[$offset]; } - } public function setCliArg( $offset, $value ) { MediaWikiPHPUnitCommand::$additionalOptions[$offset] = $value; - } /** @@ -775,7 +783,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { } /** - * Returns true iff the given namespace defaults to Wikitext + * Returns true if the given namespace defaults to Wikitext * according to $wgNamespaceContentModels * * @param int $ns The namespace ID to check @@ -839,12 +847,13 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { ) { $wikitextNS = $ns; + return $wikitextNS; } } // give up - // @todo: Inside a test, we could skip the test as incomplete. + // @todo Inside a test, we could skip the test as incomplete. // But frequently, this is used in fixture setup. throw new MWException( "No namespace defaults to wikitext!" ); } @@ -906,6 +915,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { if ( !$loaded ) { $this->markTestSkipped( "PHP extension '$extName' is not loaded, skipping." ); } + return $loaded; } @@ -914,6 +924,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * the provided code. * * @since 1.21 + * @deprecated since 1.22 Use setExpectedException * * @param callable $code * @param string $expected @@ -934,5 +945,4 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { $this->assertInstanceOf( $expected, $pokemons, $message ); } - } diff --git a/tests/phpunit/bootstrap.php b/tests/phpunit/bootstrap.php index 01caf8f4..d929b79d 100644 --- a/tests/phpunit/bootstrap.php +++ b/tests/phpunit/bootstrap.php @@ -11,22 +11,5 @@ if ( !defined( 'MW_PHPUNIT_TEST' ) ) { You are running these tests directly from phpunit. You may not have all globals correctly set. Running phpunit.php instead is recommended. EOF; - require_once ( __DIR__ . "/phpunit.php" ); + require_once __DIR__ . "/phpunit.php"; } - -// Output a notice when running with older versions of PHPUnit -if ( version_compare( PHPUnit_Runner_Version::id(), "3.6.7", "<" ) ) { - echo <<<EOF -******************************************************************************** - -These tests run best with version PHPUnit 3.6.7 or better. Earlier versions may -show failures because earlier versions of PHPUnit do not properly implement -dependencies. - -******************************************************************************** - -EOF; -} - -/** @todo Check if this is really needed */ -MessageCache::destroyInstance(); diff --git a/tests/phpunit/data/db/sqlite/tables-1.16.sql b/tests/phpunit/data/db/sqlite/tables-1.16.sql index 6e56add2..7e8f30ec 100644 --- a/tests/phpunit/data/db/sqlite/tables-1.16.sql +++ b/tests/phpunit/data/db/sqlite/tables-1.16.sql @@ -146,11 +146,6 @@ CREATE TABLE /*_*/externallinks ( CREATE INDEX /*i*/el_from ON /*_*/externallinks (el_from, el_to(40)); CREATE INDEX /*i*/el_to ON /*_*/externallinks (el_to(60), el_from); CREATE INDEX /*i*/el_index ON /*_*/externallinks (el_index(60)); -CREATE TABLE /*_*/external_user ( - eu_local_id int unsigned NOT NULL PRIMARY KEY, - eu_external_id varchar(255) binary NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/eu_external_id ON /*_*/external_user (eu_external_id); CREATE TABLE /*_*/langlinks ( ll_from int unsigned NOT NULL default 0, ll_lang varbinary(20) NOT NULL default '', diff --git a/tests/phpunit/data/db/sqlite/tables-1.17.sql b/tests/phpunit/data/db/sqlite/tables-1.17.sql index 69ae3764..e02e3e14 100644 --- a/tests/phpunit/data/db/sqlite/tables-1.17.sql +++ b/tests/phpunit/data/db/sqlite/tables-1.17.sql @@ -151,11 +151,6 @@ CREATE TABLE /*_*/externallinks ( CREATE INDEX /*i*/el_from ON /*_*/externallinks (el_from, el_to(40)); CREATE INDEX /*i*/el_to ON /*_*/externallinks (el_to(60), el_from); CREATE INDEX /*i*/el_index ON /*_*/externallinks (el_index(60)); -CREATE TABLE /*_*/external_user ( - eu_local_id int unsigned NOT NULL PRIMARY KEY, - eu_external_id varchar(255) binary NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/eu_external_id ON /*_*/external_user (eu_external_id); CREATE TABLE /*_*/langlinks ( ll_from int unsigned NOT NULL default 0, ll_lang varbinary(20) NOT NULL default '', diff --git a/tests/phpunit/data/db/sqlite/tables-1.18.sql b/tests/phpunit/data/db/sqlite/tables-1.18.sql index b106d2b7..8bfc28e2 100644 --- a/tests/phpunit/data/db/sqlite/tables-1.18.sql +++ b/tests/phpunit/data/db/sqlite/tables-1.18.sql @@ -157,11 +157,6 @@ CREATE TABLE /*_*/externallinks ( CREATE INDEX /*i*/el_from ON /*_*/externallinks (el_from, el_to(40)); CREATE INDEX /*i*/el_to ON /*_*/externallinks (el_to(60), el_from); CREATE INDEX /*i*/el_index ON /*_*/externallinks (el_index(60)); -CREATE TABLE /*_*/external_user ( - eu_local_id int unsigned NOT NULL PRIMARY KEY, - eu_external_id varchar(255) binary NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/eu_external_id ON /*_*/external_user (eu_external_id); CREATE TABLE /*_*/langlinks ( ll_from int unsigned NOT NULL default 0, ll_lang varbinary(20) NOT NULL default '', diff --git a/tests/phpunit/data/less/common/test.common.mixins.less b/tests/phpunit/data/less/common/test.common.mixins.less new file mode 100644 index 00000000..2fbe9b79 --- /dev/null +++ b/tests/phpunit/data/less/common/test.common.mixins.less @@ -0,0 +1,5 @@ +.test-mixin (@value) { + color: @value; + border: @foo solid @Foo; + line-height: test-sum(@bar, 10, 20); +} diff --git a/tests/phpunit/data/less/module/dependency.less b/tests/phpunit/data/less/module/dependency.less new file mode 100644 index 00000000..c7725a25 --- /dev/null +++ b/tests/phpunit/data/less/module/dependency.less @@ -0,0 +1,3 @@ +@import "test.common.mixins"; + +@unitTestColor: green; diff --git a/tests/phpunit/data/less/module/styles.css b/tests/phpunit/data/less/module/styles.css new file mode 100644 index 00000000..b78780a9 --- /dev/null +++ b/tests/phpunit/data/less/module/styles.css @@ -0,0 +1,6 @@ +/* @noflip */ +.unit-tests { + color: green; + border: 2px solid #eeeeee; + line-height: 35; +} diff --git a/tests/phpunit/data/less/module/styles.less b/tests/phpunit/data/less/module/styles.less new file mode 100644 index 00000000..ecac8392 --- /dev/null +++ b/tests/phpunit/data/less/module/styles.less @@ -0,0 +1,6 @@ +@import "dependency"; + +/* @noflip */ +.unit-tests { + .test-mixin(@unitTestColor); +} diff --git a/tests/phpunit/data/xmp/7.result.php b/tests/phpunit/data/xmp/7.result.php index 9aa867bc..115cdc92 100644 --- a/tests/phpunit/data/xmp/7.result.php +++ b/tests/phpunit/data/xmp/7.result.php @@ -1,26 +1,26 @@ <?php -$result = array ( +$result = array( 'xmp-exif' => - array ( + array( 'CameraOwnerName' => 'Me!', ), 'xmp-general' => - array ( + array( 'LicenseUrl' => 'http://creativecommons.com/cc-by-2.9', 'ImageDescription' => - array ( + array( 'x-default' => 'Test image for the cc: xmp: xmpRights: namespaces in xmp', '_type' => 'lang', ), 'ObjectName' => - array ( + array( 'x-default' => 'xmp core/xmp rights/cc ns test', '_type' => 'lang', ), 'DateTimeDigitized' => '2005:04:03', 'Software' => 'The one true editor: Vi (ok i used gimp)', 'Identifier' => - array ( + array( 0 => 'http://example.com/identifierurl', 1 => 'urn:sha1:342524abcdef', '_type' => 'ul', @@ -33,12 +33,12 @@ $result = array ( 'RightsCertificate' => 'http://example.com/rights-certificate/', 'Copyrighted' => 'True', 'CopyrightOwner' => - array ( + array( 0 => 'Bawolff is copyright owner', '_type' => 'ul', ), 'UsageTerms' => - array ( + array( 'x-default' => 'do whatever you want', 'en-gb' => 'Do whatever you want in british english', '_type' => 'lang', @@ -46,7 +46,7 @@ $result = array ( 'WebStatement' => 'http://example.com/web_statement', ), 'xmp-deprecated' => - array ( + array( 'Identifier' => 'http://example.com/identifierurl/wrong', ), ); diff --git a/tests/phpunit/includes/ArticleTablesTest.php b/tests/phpunit/includes/ArticleTablesTest.php index 967ffa17..0f159ae4 100644 --- a/tests/phpunit/includes/ArticleTablesTest.php +++ b/tests/phpunit/includes/ArticleTablesTest.php @@ -5,7 +5,7 @@ */ class ArticleTablesTest extends MediaWikiLangTestCase { - function testbug14404() { + public function testbug14404() { global $wgContLang, $wgLanguageCode, $wgLang; $title = Title::newFromText( 'Bug 14404' ); @@ -16,18 +16,17 @@ class ArticleTablesTest extends MediaWikiLangTestCase { $wgContLang = Language::factory( 'es' ); $wgLang = Language::factory( 'fr' ); - $status = $page->doEditContent( new WikitextContent( '{{:{{int:history}}}}' ), 'Test code for bug 14404', 0, false, $user ); + $page->doEditContent( new WikitextContent( '{{:{{int:history}}}}' ), 'Test code for bug 14404', 0, false, $user ); $templates1 = $title->getTemplateLinksFrom(); $wgLang = Language::factory( 'de' ); $page->mPreparedEdit = false; // In order to force the rerendering of the same wikitext // We need an edit, a purge is not enough to regenerate the tables - $status = $page->doEditContent( new WikitextContent( '{{:{{int:history}}}}' ), 'Test code for bug 14404', EDIT_UPDATE, false, $user ); + $page->doEditContent( new WikitextContent( '{{:{{int:history}}}}' ), 'Test code for bug 14404', EDIT_UPDATE, false, $user ); $templates2 = $title->getTemplateLinksFrom(); $this->assertEquals( $templates1, $templates2 ); $this->assertEquals( $templates1[0]->getFullText(), 'Historial' ); } - } diff --git a/tests/phpunit/includes/ArticleTest.php b/tests/phpunit/includes/ArticleTest.php index 867c4f00..b4d6dca6 100644 --- a/tests/phpunit/includes/ArticleTest.php +++ b/tests/phpunit/includes/ArticleTest.php @@ -25,14 +25,14 @@ class ArticleTest extends MediaWikiTestCase { $this->article = null; } - function testImplementsGetMagic() { + public function testImplementsGetMagic() { $this->assertEquals( false, $this->article->mLatest, "Article __get magic" ); } /** * @depends testImplementsGetMagic */ - function testImplementsSetMagic() { + public function testImplementsSetMagic() { $this->article->mLatest = 2; $this->assertEquals( 2, $this->article->mLatest, "Article __set magic" ); } @@ -40,13 +40,13 @@ class ArticleTest extends MediaWikiTestCase { /** * @depends testImplementsSetMagic */ - function testImplementsCallMagic() { + public function testImplementsCallMagic() { $this->article->mLatest = 33; $this->article->mDataLoaded = true; $this->assertEquals( 33, $this->article->getLatest(), "Article __call magic" ); } - function testGetOrSetOnNewProperty() { + public function testGetOrSetOnNewProperty() { $this->article->ext_someNewProperty = 12; $this->assertEquals( 12, $this->article->ext_someNewProperty, "Article get/set magic on new field" ); @@ -59,7 +59,7 @@ class ArticleTest extends MediaWikiTestCase { /** * Checks for the existence of the backwards compatibility static functions (forwarders to WikiPage class) */ - function testStaticFunctions() { + public function testStaticFunctions() { $this->hideDeprecated( 'Article::getAutosummary' ); $this->hideDeprecated( 'WikiPage::getAutosummary' ); $this->hideDeprecated( 'CategoryPage::getAutosummary' ); // Inherited from Article @@ -76,7 +76,7 @@ class ArticleTest extends MediaWikiTestCase { "Article static functions" ); } - function testWikiPageFactory() { + public function testWikiPageFactory() { $title = Title::makeTitle( NS_FILE, 'Someimage.png' ); $page = WikiPage::factory( $title ); $this->assertEquals( 'WikiFilePage', get_class( $page ) ); diff --git a/tests/phpunit/includes/BlockTest.php b/tests/phpunit/includes/BlockTest.php index 19c9b687..21de0985 100644 --- a/tests/phpunit/includes/BlockTest.php +++ b/tests/phpunit/includes/BlockTest.php @@ -51,36 +51,36 @@ class BlockTest extends MediaWikiLangTestCase { } else { throw new MWException( "Failed to insert block for BlockTest; old leftover block remaining?" ); } + + $this->addXffBlocks(); } /** * debug function : dump the ipblocks table */ function dumpBlocks() { - $v = $this->db->query( 'SELECT * FROM unittest_ipblocks' ); + $v = $this->db->select( 'ipblocks', '*' ); print "Got " . $v->numRows() . " rows. Full dump follow:\n"; foreach ( $v as $row ) { print_r( $row ); } } - function testInitializerFunctionsReturnCorrectBlock() { + public function testInitializerFunctionsReturnCorrectBlock() { // $this->dumpBlocks(); $this->assertTrue( $this->block->equals( Block::newFromTarget( 'UTBlockee' ) ), "newFromTarget() returns the same block as the one that was made" ); $this->assertTrue( $this->block->equals( Block::newFromID( $this->blockId ) ), "newFromID() returns the same block as the one that was made" ); - } /** * per bug 26425 */ - function testBug26425BlockTimestampDefaultsToTime() { + public function testBug26425BlockTimestampDefaultsToTime() { // delta to stop one-off errors when things happen to go over a second mark. $delta = abs( $this->madeAt - $this->block->mTimestamp ); $this->assertLessThan( 2, $delta, "If no timestamp is specified, the block is recorded as time()" ); - } /** @@ -91,7 +91,7 @@ class BlockTest extends MediaWikiLangTestCase { * * @dataProvider provideBug29116Data */ - function testBug29116LoadWithEmptyIp( $vagueTarget ) { + public function testBug29116LoadWithEmptyIp( $vagueTarget ) { $this->hideDeprecated( 'Block::load' ); $uid = User::idFromName( 'UTBlockee' ); @@ -111,7 +111,7 @@ class BlockTest extends MediaWikiLangTestCase { * * @dataProvider provideBug29116Data */ - function testBug29116NewFromTargetWithEmptyIp( $vagueTarget ) { + public function testBug29116NewFromTargetWithEmptyIp( $vagueTarget ) { $block = Block::newFromTarget( 'UTBlockee', $vagueTarget ); $this->assertTrue( $this->block->equals( $block ), "newFromTarget() returns the same block as the one that was made when given empty vagueTarget param " . var_export( $vagueTarget, true ) ); } @@ -124,14 +124,13 @@ class BlockTest extends MediaWikiLangTestCase { ); } - function testBlockedUserCanNotCreateAccount() { + public function testBlockedUserCanNotCreateAccount() { $username = 'BlockedUserToCreateAccountWith'; $u = User::newFromName( $username ); $u->setPassword( 'NotRandomPass' ); $u->addToDatabase(); unset( $u ); - // Sanity check $this->assertNull( Block::newFromTarget( $username ), @@ -185,7 +184,7 @@ class BlockTest extends MediaWikiLangTestCase { ); } - function testCrappyCrossWikiBlocks() { + public function testCrappyCrossWikiBlocks() { // Delete the last round's block if it's still there $oldBlock = Block::newFromTarget( 'UserOnForeignWiki' ); if ( $oldBlock ) { @@ -228,4 +227,128 @@ class BlockTest extends MediaWikiLangTestCase { $this->assertEquals( 'MetaWikiUser', $block->getByName(), 'Correct blocker name' ); $this->assertEquals( 0, $block->getBy(), 'Correct blocker id' ); } + + protected function addXffBlocks() { + static $inited = false; + + if ( $inited ) { + return; + } + + $inited = true; + + $blockList = array( + array( 'target' => '70.2.0.0/16', + 'type' => Block::TYPE_RANGE, + 'desc' => 'Range Hardblock', + 'ACDisable' => false, + 'isHardblock' => true, + 'isAutoBlocking' => false, + ), + array( 'target' => '2001:4860:4001::/48', + 'type' => Block::TYPE_RANGE, + 'desc' => 'Range6 Hardblock', + 'ACDisable' => false, + 'isHardblock' => true, + 'isAutoBlocking' => false, + ), + array( 'target' => '60.2.0.0/16', + 'type' => Block::TYPE_RANGE, + 'desc' => 'Range Softblock with AC Disabled', + 'ACDisable' => true, + 'isHardblock' => false, + 'isAutoBlocking' => false, + ), + array( 'target' => '50.2.0.0/16', + 'type' => Block::TYPE_RANGE, + 'desc' => 'Range Softblock', + 'ACDisable' => false, + 'isHardblock' => false, + 'isAutoBlocking' => false, + ), + array( 'target' => '50.1.1.1', + 'type' => Block::TYPE_IP, + 'desc' => 'Exact Softblock', + 'ACDisable' => false, + 'isHardblock' => false, + 'isAutoBlocking' => false, + ), + ); + + foreach ( $blockList as $insBlock ) { + $target = $insBlock['target']; + + if ( $insBlock['type'] === Block::TYPE_IP ) { + $target = User::newFromName( IP::sanitizeIP( $target ), false )->getName(); + } elseif ( $insBlock['type'] === Block::TYPE_RANGE ) { + $target = IP::sanitizeRange( $target ); + } + + $block = new Block(); + $block->setTarget( $target ); + $block->setBlocker( 'testblocker@global' ); + $block->mReason = $insBlock['desc']; + $block->mExpiry = 'infinity'; + $block->prevents( 'createaccount', $insBlock['ACDisable'] ); + $block->isHardblock( $insBlock['isHardblock'] ); + $block->isAutoblocking( $insBlock['isAutoBlocking'] ); + $block->insert(); + } + } + + public static function providerXff() { + return array( + array( 'xff' => '1.2.3.4, 70.2.1.1, 60.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Range Hardblock' + ), + array( 'xff' => '1.2.3.4, 50.2.1.1, 60.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Range Softblock with AC Disabled' + ), + array( 'xff' => '1.2.3.4, 70.2.1.1, 50.1.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Exact Softblock' + ), + array( 'xff' => '1.2.3.4, 70.2.1.1, 50.2.1.1, 50.1.1.1, 2.3.4.5', + 'count' => 3, + 'result' => 'Exact Softblock' + ), + array( 'xff' => '1.2.3.4, 70.2.1.1, 50.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Range Hardblock' + ), + array( 'xff' => '1.2.3.4, 70.2.1.1, 60.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Range Hardblock' + ), + array( 'xff' => '50.2.1.1, 60.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Range Softblock with AC Disabled' + ), + array( 'xff' => '1.2.3.4, 50.1.1.1, 60.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Exact Softblock' + ), + array( 'xff' => '1.2.3.4, <$A_BUNCH-OF{INVALID}TEXT\>, 60.2.1.1, 2.3.4.5', + 'count' => 1, + 'result' => 'Range Softblock with AC Disabled' + ), + array( 'xff' => '1.2.3.4, 50.2.1.1, 2001:4860:4001:802::1003, 2.3.4.5', + 'count' => 2, + 'result' => 'Range6 Hardblock' + ), + ); + } + + /** + * @dataProvider providerXff + */ + public function testBlocksOnXff( $xff, $exCount, $exResult ) { + $list = array_map( 'trim', explode( ',', $xff ) ); + $xffblocks = Block::getBlocksForIPList( $list, true ); + $this->assertEquals( $exCount, count( $xffblocks ), 'Number of blocks for ' . $xff ); + $block = Block::chooseBlock( $xffblocks, $list ); + $this->assertEquals( $exResult, $block->mReason, 'Correct block type for XFF header ' . $xff ); + } } diff --git a/tests/phpunit/includes/CdbTest.php b/tests/phpunit/includes/CdbTest.php index add585d7..e3d9da7c 100644 --- a/tests/phpunit/includes/CdbTest.php +++ b/tests/phpunit/includes/CdbTest.php @@ -66,7 +66,6 @@ class CdbTest extends MediaWikiTestCase { $this->cdbAssert( "PHP error", $key, $v1, $value ); $this->cdbAssert( "DBA error", $key, $v2, $value ); } - } private function randomString() { @@ -75,6 +74,7 @@ class CdbTest extends MediaWikiTestCase { for ( $j = 0; $j < $len; $j++ ) { $s .= chr( mt_rand( 0, 255 ) ); } + return $s; } diff --git a/tests/phpunit/includes/CollationTest.php b/tests/phpunit/includes/CollationTest.php index c746208b..43bb3941 100644 --- a/tests/phpunit/includes/CollationTest.php +++ b/tests/phpunit/includes/CollationTest.php @@ -20,7 +20,7 @@ class CollationTest extends MediaWikiLangTestCase { * * @dataProvider prefixDataProvider */ - function testIsPrefix( $lang, $base, $extended ) { + public function testIsPrefix( $lang, $base, $extended ) { $cp = Collator::create( $lang ); $cp->setStrength( Collator::PRIMARY ); $baseBin = $cp->getSortKey( $base ); @@ -47,12 +47,13 @@ class CollationTest extends MediaWikiLangTestCase { array( 'en', 'A', 'Aꦲ' ), ); } + /** * Opposite of testIsPrefix * * @dataProvider notPrefixDataProvider */ - function testNotIsPrefix( $lang, $base, $extended ) { + public function testNotIsPrefix( $lang, $base, $extended ) { $cp = Collator::create( $lang ); $cp->setStrength( Collator::PRIMARY ); $baseBin = $cp->getSortKey( $base ); @@ -80,10 +81,11 @@ class CollationTest extends MediaWikiLangTestCase { * * @dataProvider firstLetterProvider */ - function testGetFirstLetter( $collation, $string, $firstLetter ) { + public function testGetFirstLetter( $collation, $string, $firstLetter ) { $col = Collation::factory( $collation ); $this->assertEquals( $firstLetter, $col->getFirstLetter( $string ) ); } + function firstLetterProvider() { return array( array( 'uppercase', 'Abc', 'A' ), diff --git a/tests/phpunit/includes/DiffHistoryBlobTest.php b/tests/phpunit/includes/DiffHistoryBlobTest.php index dcd9dddf..a4d5b91a 100644 --- a/tests/phpunit/includes/DiffHistoryBlobTest.php +++ b/tests/phpunit/includes/DiffHistoryBlobTest.php @@ -4,14 +4,17 @@ class DiffHistoryBlobTest extends MediaWikiTestCase { protected function setUp() { if ( !extension_loaded( 'xdiff' ) ) { $this->markTestSkipped( 'The xdiff extension is not available' ); + return; } if ( !function_exists( 'xdiff_string_rabdiff' ) ) { $this->markTestSkipped( 'The version of xdiff extension is lower than 1.5.0' ); + return; } - if ( !extension_loaded( 'hash' ) && !extension_loaded( 'mhash' ) ) { - $this->markTestSkipped( 'Neither the hash nor mhash extension is available' ); + if ( !extension_loaded( 'hash' ) ) { + $this->markTestSkipped( 'The hash extension is not available' ); + return; } parent::setUp(); @@ -21,7 +24,7 @@ class DiffHistoryBlobTest extends MediaWikiTestCase { * Test for DiffHistoryBlob::xdiffAdler32() * @dataProvider provideXdiffAdler32 */ - function testXdiffAdler32( $input ) { + public function testXdiffAdler32( $input ) { $xdiffHash = substr( xdiff_string_rabdiff( $input, '' ), 0, 4 ); $dhb = new DiffHistoryBlob; $myHash = $dhb->xdiffAdler32( $input ); diff --git a/tests/phpunit/includes/EditPageTest.php b/tests/phpunit/includes/EditPageTest.php index 00eba30a..87272a4c 100644 --- a/tests/phpunit/includes/EditPageTest.php +++ b/tests/phpunit/includes/EditPageTest.php @@ -9,12 +9,12 @@ * @group medium * ^--- tell phpunit that these test cases may take longer than 2 seconds. */ -class EditPageTest extends MediaWikiTestCase { +class EditPageTest extends MediaWikiLangTestCase { /** * @dataProvider provideExtractSectionTitle */ - function testExtractSectionTitle( $section, $title ) { + public function testExtractSectionTitle( $section, $title ) { $extracted = EditPage::extractSectionTitle( $section ); $this->assertEquals( $title, $extracted ); } @@ -173,15 +173,90 @@ class EditPageTest extends MediaWikiTestCase { } public function testCreatePage() { - $text = "Hello World!"; - $edit = array( - 'wpTextbox1' => $text, - 'wpSummary' => 'just testing', + $this->assertEdit( + 'EditPageTest_testCreatePage', + null, + null, + array( + 'wpTextbox1' => "Hello World!", + ), + EditPage::AS_SUCCESS_NEW_ARTICLE, + "Hello World!", + "expected article being created" + )->doDeleteArticleReal( 'EditPageTest_testCreatePage' ); + + $this->assertEdit( + 'EditPageTest_testCreatePage', + null, + null, + array( + 'wpTextbox1' => "", + ), + EditPage::AS_BLANK_ARTICLE, + null, + "expected article not being created if empty" + ); + + + $this->assertEdit( + 'MediaWiki:January', + null, + 'UTSysop', + array( + 'wpTextbox1' => "Not January", + ), + EditPage::AS_SUCCESS_NEW_ARTICLE, + "Not January", + "expected MediaWiki: page being created" + )->doDeleteArticleReal( 'EditPageTest_testCreatePage' ); + + $this->assertEdit( + 'MediaWiki:EditPageTest_testCreatePage', + null, + 'UTSysop', + array( + 'wpTextbox1' => "", + ), + EditPage::AS_BLANK_ARTICLE, + null, + "expected not-registered MediaWiki: page not being created if empty" ); - $this->assertEdit( 'EditPageTest_testCreatePafe', null, null, $edit, - EditPage::AS_SUCCESS_NEW_ARTICLE, $text, - "expected successfull creation with given text" ); + $this->assertEdit( + 'MediaWiki:January', + null, + 'UTSysop', + array( + 'wpTextbox1' => "", + ), + EditPage::AS_SUCCESS_NEW_ARTICLE, + "", + "expected registered MediaWiki: page being created even if empty" + )->doDeleteArticleReal( 'EditPageTest_testCreatePage' ); + + $this->assertEdit( + 'MediaWiki:Ipb-default-expiry', + null, + 'UTSysop', + array( + 'wpTextbox1' => "", + ), + EditPage::AS_BLANK_ARTICLE, + "", + "expected registered MediaWiki: page whose default content is empty not being created if empty" + ); + + $this->assertEdit( + 'MediaWiki:January', + null, + 'UTSysop', + array( + 'wpTextbox1' => "January", + ), + EditPage::AS_BLANK_ARTICLE, + null, + "expected MediaWiki: page not being created if text equals default message" + ); } public function testUpdatePage() { diff --git a/tests/phpunit/includes/ExternalStoreTest.php b/tests/phpunit/includes/ExternalStoreTest.php index 99544e7e..fcffcbc2 100644 --- a/tests/phpunit/includes/ExternalStoreTest.php +++ b/tests/phpunit/includes/ExternalStoreTest.php @@ -5,7 +5,7 @@ class ExternalStoreTest extends MediaWikiTestCase { - function testExternalFetchFromURL() { + public function testExternalFetchFromURL() { $this->setMwGlobals( 'wgExternalStores', false ); $this->assertFalse( diff --git a/tests/phpunit/includes/ExtraParserTest.php b/tests/phpunit/includes/ExtraParserTest.php index 067cfc4a..6c67beb1 100644 --- a/tests/phpunit/includes/ExtraParserTest.php +++ b/tests/phpunit/includes/ExtraParserTest.php @@ -27,7 +27,7 @@ class ExtraParserTest extends MediaWikiTestCase { } // Bug 8689 - Long numeric lines kill the parser - function testBug8689() { + public function testBug8689() { global $wgUser; $longLine = '1.' . str_repeat( '1234567890', 100000 ) . "\n"; @@ -38,13 +38,13 @@ class ExtraParserTest extends MediaWikiTestCase { } /* Test the parser entry points */ - function testParse() { + public function testParse() { $title = Title::newFromText( __FUNCTION__ ); $parserOutput = $this->parser->parse( "Test\n{{Foo}}\n{{Bar}}", $title, $this->options ); $this->assertEquals( "<p>Test\nContent of <i>Template:Foo</i>\nContent of <i>Template:Bar</i>\n</p>", $parserOutput->getText() ); } - function testPreSaveTransform() { + public function testPreSaveTransform() { global $wgUser; $title = Title::newFromText( __FUNCTION__ ); $outputText = $this->parser->preSaveTransform( "Test\r\n{{subst:Foo}}\n{{Bar}}", $title, $wgUser, $this->options ); @@ -52,7 +52,7 @@ class ExtraParserTest extends MediaWikiTestCase { $this->assertEquals( "Test\nContent of ''Template:Foo''\n{{Bar}}", $outputText ); } - function testPreprocess() { + public function testPreprocess() { $title = Title::newFromText( __FUNCTION__ ); $outputText = $this->parser->preprocess( "Test\n{{Foo}}\n{{Bar}}", $title, $this->options ); @@ -62,7 +62,7 @@ class ExtraParserTest extends MediaWikiTestCase { /** * cleanSig() makes all templates substs and removes tildes */ - function testCleanSig() { + public function testCleanSig() { $title = Title::newFromText( __FUNCTION__ ); $outputText = $this->parser->cleanSig( "{{Foo}} ~~~~" ); @@ -72,9 +72,8 @@ class ExtraParserTest extends MediaWikiTestCase { /** * cleanSig() should do nothing if disabled */ - function testCleanSigDisabled() { - global $wgCleanSignatures; - $wgCleanSignatures = false; + public function testCleanSigDisabled() { + $this->setMwGlobals( 'wgCleanSignatures', false ); $title = Title::newFromText( __FUNCTION__ ); $outputText = $this->parser->cleanSig( "{{Foo}} ~~~~" ); @@ -86,7 +85,7 @@ class ExtraParserTest extends MediaWikiTestCase { * cleanSigInSig() just removes tildes * @dataProvider provideStringsForCleanSigInSig */ - function testCleanSigInSig( $in, $out ) { + public function testCleanSigInSig( $in, $out ) { $this->assertEquals( Parser::cleanSigInSig( $in ), $out ); } @@ -98,7 +97,7 @@ class ExtraParserTest extends MediaWikiTestCase { ); } - function testGetSection() { + public function testGetSection() { $outputText2 = $this->parser->getSection( "Section 0\n== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2\n== Heading 3 ==\nSection 3\n", 2 ); $outputText1 = $this->parser->getSection( "Section 0\n== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2\n== Heading 3 ==\nSection 3\n", 1 ); @@ -106,7 +105,7 @@ class ExtraParserTest extends MediaWikiTestCase { $this->assertEquals( "== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2", $outputText1 ); } - function testReplaceSection() { + public function testReplaceSection() { $outputText = $this->parser->replaceSection( "Section 0\n== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2\n== Heading 3 ==\nSection 3\n", 1, "New section 1" ); $this->assertEquals( "Section 0\nNew section 1\n\n== Heading 3 ==\nSection 3", $outputText ); @@ -115,7 +114,7 @@ class ExtraParserTest extends MediaWikiTestCase { /** * Templates and comments are not affected, but noinclude/onlyinclude is. */ - function testGetPreloadText() { + public function testGetPreloadText() { $title = Title::newFromText( __FUNCTION__ ); $outputText = $this->parser->getPreloadText( "{{Foo}}<noinclude> censored</noinclude> information <!-- is very secret -->", $title, $this->options ); @@ -135,7 +134,7 @@ class ExtraParserTest extends MediaWikiTestCase { /** * @group Database */ - function testTrackingCategory() { + public function testTrackingCategory() { $title = Title::newFromText( __FUNCTION__ ); $catName = wfMessage( 'broken-file-category' )->inContentLanguage()->text(); $cat = Title::makeTitleSafe( NS_CATEGORY, $catName ); @@ -148,7 +147,7 @@ class ExtraParserTest extends MediaWikiTestCase { /** * @group Database */ - function testTrackingCategorySpecial() { + public function testTrackingCategorySpecial() { // Special pages shouldn't have tracking cats. $title = SpecialPage::getTitleFor( 'Contributions' ); $parserOutput = $this->parser->parse( "[[file:nonexistent]]", $title, $this->options ); diff --git a/tests/phpunit/includes/FallbackTest.php b/tests/phpunit/includes/FallbackTest.php new file mode 100644 index 00000000..f408f471 --- /dev/null +++ b/tests/phpunit/includes/FallbackTest.php @@ -0,0 +1,73 @@ +<?php + +/** + * @covers Fallback + */ +class FallbackTest extends MediaWikiTestCase { + + public function testFallbackMbstringFunctions() { + + if ( !extension_loaded( 'mbstring' ) ) { + $this->markTestSkipped( "The mb_string functions must be installed to test the fallback functions" ); + } + + $sampleUTF = "Östergötland_coat_of_arms.png"; + + //mb_substr + $substr_params = array( + array( 0, 0 ), + array( 5, -4 ), + array( 33 ), + array( 100, -5 ), + array( -8, 10 ), + array( 1, 1 ), + array( 2, -1 ) + ); + + foreach ( $substr_params as $param_set ) { + $old_param_set = $param_set; + array_unshift( $param_set, $sampleUTF ); + + $this->assertEquals( + call_user_func_array( 'mb_substr', $param_set ), + call_user_func_array( 'Fallback::mb_substr', $param_set ), + 'Fallback mb_substr with params ' . implode( ', ', $old_param_set ) + ); + } + + //mb_strlen + $this->assertEquals( + mb_strlen( $sampleUTF ), + Fallback::mb_strlen( $sampleUTF ), + 'Fallback mb_strlen' + ); + + //mb_str(r?)pos + $strpos_params = array( + //array( 'ter' ), + //array( 'Ö' ), + //array( 'Ö', 3 ), + //array( 'oat_', 100 ), + //array( 'c', -10 ), + //Broken for now + ); + + foreach ( $strpos_params as $param_set ) { + $old_param_set = $param_set; + array_unshift( $param_set, $sampleUTF ); + + $this->assertEquals( + call_user_func_array( 'mb_strpos', $param_set ), + call_user_func_array( 'Fallback::mb_strpos', $param_set ), + 'Fallback mb_strpos with params ' . implode( ', ', $old_param_set ) + ); + + $this->assertEquals( + call_user_func_array( 'mb_strrpos', $param_set ), + call_user_func_array( 'Fallback::mb_strrpos', $param_set ), + 'Fallback mb_strrpos with params ' . implode( ', ', $old_param_set ) + ); + } + } + +}
\ No newline at end of file diff --git a/tests/phpunit/includes/FauxRequestTest.php b/tests/phpunit/includes/FauxRequestTest.php new file mode 100644 index 00000000..9f3aa11d --- /dev/null +++ b/tests/phpunit/includes/FauxRequestTest.php @@ -0,0 +1,15 @@ +<?php + +class FauxRequestTest extends MediaWikiTestCase { + + public function testGetSetHeader() { + $value = 'test/test'; + + $request = new FauxRequest(); + $request->setHeader( 'Content-Type', $value ); + + $this->assertEquals( $request->getHeader( 'Content-Type' ), $value ); + $this->assertEquals( $request->getHeader( 'CONTENT-TYPE' ), $value ); + $this->assertEquals( $request->getHeader( 'content-type' ), $value ); + } +} diff --git a/tests/phpunit/includes/FauxResponseTest.php b/tests/phpunit/includes/FauxResponseTest.php index 56691c9e..f9ba1b3b 100644 --- a/tests/phpunit/includes/FauxResponseTest.php +++ b/tests/phpunit/includes/FauxResponseTest.php @@ -30,13 +30,13 @@ class FauxResponseTest extends MediaWikiTestCase { $this->response = new FauxResponse; } - function testCookie() { + public function testCookie() { $this->assertEquals( null, $this->response->getcookie( 'key' ), 'Non-existing cookie' ); $this->response->setcookie( 'key', 'val' ); $this->assertEquals( 'val', $this->response->getcookie( 'key' ), 'Existing cookie' ); } - function testHeader() { + public function testHeader() { $this->assertEquals( null, $this->response->getheader( 'Location' ), 'Non-existing header' ); $this->response->header( 'Location: http://localhost/' ); @@ -47,9 +47,12 @@ class FauxResponseTest extends MediaWikiTestCase { $this->response->header( 'Location: http://127.0.0.2/', false ); $this->assertEquals( 'http://127.0.0.1/', $this->response->getheader( 'Location' ), 'Same header with override disabled' ); + + $this->response->header( 'Location: http://localhost/' ); + $this->assertEquals( 'http://localhost/', $this->response->getheader( 'LOCATION' ), 'Get header case insensitive' ); } - function testResponseCode() { + public function testResponseCode() { $this->response->header( 'HTTP/1.1 200' ); $this->assertEquals( 200, $this->response->getStatusCode(), 'Header with no message' ); diff --git a/tests/phpunit/includes/FormOptionsInitializationTest.php b/tests/phpunit/includes/FormOptionsInitializationTest.php index 4053683f..fb2304dc 100644 --- a/tests/phpunit/includes/FormOptionsInitializationTest.php +++ b/tests/phpunit/includes/FormOptionsInitializationTest.php @@ -81,5 +81,4 @@ class FormOptionsInitializationTest extends MediaWikiTestCase { $this->object->getOptions() ); } - } diff --git a/tests/phpunit/includes/GlobalFunctions/GlobalTest.php b/tests/phpunit/includes/GlobalFunctions/GlobalTest.php index 24fc47cf..6154df1d 100644 --- a/tests/phpunit/includes/GlobalFunctions/GlobalTest.php +++ b/tests/phpunit/includes/GlobalFunctions/GlobalTest.php @@ -29,7 +29,10 @@ class GlobalTest extends MediaWikiTestCase { parent::tearDown(); } - /** @dataProvider provideForWfArrayDiff2 */ + /** + * @dataProvider provideForWfArrayDiff2 + * @covers ::wfArrayDiff2 + */ public function testWfArrayDiff2( $a, $b, $expected ) { $this->assertEquals( wfArrayDiff2( $a, $b ), $expected @@ -53,25 +56,37 @@ class GlobalTest extends MediaWikiTestCase { ); } - function testRandom() { + /** + * @covers ::wfRandom + */ + public function testRandom() { # This could hypothetically fail, but it shouldn't ;) $this->assertFalse( wfRandom() == wfRandom() ); } - function testUrlencode() { + /** + * @covers ::wfUrlencode + */ + public function testUrlencode() { $this->assertEquals( "%E7%89%B9%E5%88%A5:Contributions/Foobar", wfUrlencode( "\xE7\x89\xB9\xE5\x88\xA5:Contributions/Foobar" ) ); } - function testExpandIRI() { + /** + * @covers ::wfExpandIRI + */ + public function testExpandIRI() { $this->assertEquals( "https://te.wikibooks.org/wiki/ఉబుంటు_వాడుకరి_మార్గదర్శని", wfExpandIRI( "https://te.wikibooks.org/wiki/%E0%B0%89%E0%B0%AC%E0%B1%81%E0%B0%82%E0%B0%9F%E0%B1%81_%E0%B0%B5%E0%B0%BE%E0%B0%A1%E0%B1%81%E0%B0%95%E0%B0%B0%E0%B0%BF_%E0%B0%AE%E0%B0%BE%E0%B0%B0%E0%B1%8D%E0%B0%97%E0%B0%A6%E0%B0%B0%E0%B1%8D%E0%B0%B6%E0%B0%A8%E0%B0%BF" ) ); } - function testReadOnlyEmpty() { + /** + * @covers ::wfReadOnly + */ + public function testReadOnlyEmpty() { global $wgReadOnly; $wgReadOnly = null; @@ -79,7 +94,10 @@ class GlobalTest extends MediaWikiTestCase { $this->assertFalse( wfReadOnly() ); } - function testReadOnlySet() { + /** + * @covers ::wfReadOnly + */ + public function testReadOnlySet() { global $wgReadOnly, $wgReadOnlyFile; $f = fopen( $wgReadOnlyFile, "wt" ); @@ -97,19 +115,6 @@ class GlobalTest extends MediaWikiTestCase { $this->assertFalse( wfReadOnly() ); } - function testQuotedPrintable() { - $this->assertEquals( - "=?UTF-8?Q?=C4=88u=20legebla=3F?=", - UserMailer::quotedPrintable( "\xc4\x88u legebla?", "UTF-8" ) ); - } - - function testTime() { - $start = wfTime(); - $this->assertInternalType( 'float', $start ); - $end = wfTime(); - $this->assertTrue( $end > $start, "Time is running backwards!" ); - } - public static function provideArrayToCGI() { return array( array( array(), '' ), // empty @@ -130,13 +135,17 @@ class GlobalTest extends MediaWikiTestCase { /** * @dataProvider provideArrayToCGI + * @covers ::wfArrayToCgi */ - function testArrayToCGI( $array, $result ) { + public function testArrayToCGI( $array, $result ) { $this->assertEquals( $result, wfArrayToCgi( $array ) ); } - function testArrayToCGI2() { + /** + * @covers ::testWfArrayDiff2 + */ + public function testArrayToCGI2() { $this->assertEquals( "baz=bar&foo=bar", wfArrayToCgi( @@ -161,8 +170,9 @@ class GlobalTest extends MediaWikiTestCase { /** * @dataProvider provideCgiToArray + * @covers ::wfCgiToArray */ - function testCgiToArray( $cgi, $result ) { + public function testCgiToArray( $cgi, $result ) { $this->assertEquals( $result, wfCgiToArray( $cgi ) ); } @@ -181,12 +191,16 @@ class GlobalTest extends MediaWikiTestCase { /** * @dataProvider provideCgiRoundTrip + * @covers ::wfArrayToCgi */ - function testCgiRoundTrip( $cgi ) { + public function testCgiRoundTrip( $cgi ) { $this->assertEquals( $cgi, wfArrayToCgi( wfCgiToArray( $cgi ) ) ); } - function testMimeTypeMatch() { + /** + * @covers ::mimeTypeMatch + */ + public function testMimeTypeMatch() { $this->assertEquals( 'text/html', mimeTypeMatch( 'text/html', @@ -208,7 +222,10 @@ class GlobalTest extends MediaWikiTestCase { 'image/svg+xml' => 0.5 ) ) ); } - function testNegotiateType() { + /** + * @covers ::wfNegotiateType + */ + public function testNegotiateType() { $this->assertEquals( 'text/html', wfNegotiateType( @@ -249,77 +266,11 @@ class GlobalTest extends MediaWikiTestCase { array( 'application/xhtml+xml' => 1.0 ) ) ); } - function testFallbackMbstringFunctions() { - - if ( !extension_loaded( 'mbstring' ) ) { - $this->markTestSkipped( "The mb_string functions must be installed to test the fallback functions" ); - } - - $sampleUTF = "Östergötland_coat_of_arms.png"; - - - //mb_substr - $substr_params = array( - array( 0, 0 ), - array( 5, -4 ), - array( 33 ), - array( 100, -5 ), - array( -8, 10 ), - array( 1, 1 ), - array( 2, -1 ) - ); - - foreach ( $substr_params as $param_set ) { - $old_param_set = $param_set; - array_unshift( $param_set, $sampleUTF ); - - $this->assertEquals( - MWFunction::callArray( 'mb_substr', $param_set ), - MWFunction::callArray( 'Fallback::mb_substr', $param_set ), - 'Fallback mb_substr with params ' . implode( ', ', $old_param_set ) - ); - } - - - //mb_strlen - $this->assertEquals( - mb_strlen( $sampleUTF ), - Fallback::mb_strlen( $sampleUTF ), - 'Fallback mb_strlen' - ); - - - //mb_str(r?)pos - $strpos_params = array( - //array( 'ter' ), - //array( 'Ö' ), - //array( 'Ö', 3 ), - //array( 'oat_', 100 ), - //array( 'c', -10 ), - //Broken for now - ); - - foreach ( $strpos_params as $param_set ) { - $old_param_set = $param_set; - array_unshift( $param_set, $sampleUTF ); - - $this->assertEquals( - MWFunction::callArray( 'mb_strpos', $param_set ), - MWFunction::callArray( 'Fallback::mb_strpos', $param_set ), - 'Fallback mb_strpos with params ' . implode( ', ', $old_param_set ) - ); - - $this->assertEquals( - MWFunction::callArray( 'mb_strrpos', $param_set ), - MWFunction::callArray( 'Fallback::mb_strrpos', $param_set ), - 'Fallback mb_strrpos with params ' . implode( ', ', $old_param_set ) - ); - } - - } - - - function testDebugFunctionTest() { + /** + * @covers ::wfDebug + * @covers ::wfDebugMem + */ + public function testDebugFunctionTest() { global $wgDebugLogFile, $wgDebugTimestamps; @@ -329,7 +280,6 @@ class GlobalTest extends MediaWikiTestCase { $old_wgDebugTimestamps = $wgDebugTimestamps; $wgDebugTimestamps = false; - wfDebug( "This is a normal string" ); $this->assertEquals( "This is a normal string", file_get_contents( $wgDebugLogFile ) ); unlink( $wgDebugLogFile ); @@ -338,7 +288,6 @@ class GlobalTest extends MediaWikiTestCase { $this->assertEquals( "This is nöt an ASCII string", file_get_contents( $wgDebugLogFile ) ); unlink( $wgDebugLogFile ); - wfDebug( "\00305This has böth UTF and control chars\003" ); $this->assertEquals( " 05This has böth UTF and control chars ", file_get_contents( $wgDebugLogFile ) ); unlink( $wgDebugLogFile ); @@ -351,12 +300,14 @@ class GlobalTest extends MediaWikiTestCase { $this->assertGreaterThan( 5000000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) ); unlink( $wgDebugLogFile ); - $wgDebugLogFile = $old_log_file; $wgDebugTimestamps = $old_wgDebugTimestamps; } - function testClientAcceptsGzipTest() { + /** + * @covers ::wfClientAcceptsGzip + */ + public function testClientAcceptsGzipTest() { $settings = array( 'gzip' => true, @@ -387,7 +338,10 @@ class GlobalTest extends MediaWikiTestCase { } } - function testSwapVarsTest() { + /** + * @covers ::swap + */ + public function testSwapVarsTest() { $var1 = 1; $var2 = 2; @@ -398,10 +352,12 @@ class GlobalTest extends MediaWikiTestCase { $this->assertEquals( $var1, 2, 'var1 is swapped' ); $this->assertEquals( $var2, 1, 'var2 is swapped' ); - } - function testWfPercentTest() { + /** + * @covers ::wfPercent + */ + public function testWfPercentTest() { $pcts = array( array( 6 / 7, '0.86%', 2, false ), @@ -429,6 +385,7 @@ class GlobalTest extends MediaWikiTestCase { /** * test @see wfShorthandToInteger() * @dataProvider provideShorthand + * @covers ::wfShorthandToInteger */ public function testWfShorthandToInteger( $shorthand, $expected ) { $this->assertEquals( $expected, @@ -439,7 +396,7 @@ class GlobalTest extends MediaWikiTestCase { /** array( shorthand, expected integer ) */ public static function provideShorthand() { return array( - # Null, empty ... + # Null, empty ... array( '', -1 ), array( ' ', -1 ), array( null, -1 ), @@ -489,6 +446,7 @@ class GlobalTest extends MediaWikiTestCase { * * @dataProvider provideMerge() * @group medium + * @covers ::wfMerge */ public function testMerge( $old, $mine, $yours, $expectedMergeResult, $expectedText ) { $this->checkHasDiff3(); @@ -564,13 +522,14 @@ class GlobalTest extends MediaWikiTestCase { /** * @dataProvider provideMakeUrlIndexes() + * @covers ::wfMakeUrlIndexes */ - function testMakeUrlIndexes( $url, $expected ) { + public function testMakeUrlIndexes( $url, $expected ) { $index = wfMakeUrlIndexes( $url ); $this->assertEquals( $expected, $index, "wfMakeUrlIndexes(\"$url\")" ); } - function provideMakeUrlIndexes() { + public static function provideMakeUrlIndexes() { return array( array( // just a regular :) @@ -621,13 +580,14 @@ class GlobalTest extends MediaWikiTestCase { /** * @dataProvider provideWfMatchesDomainList + * @covers ::wfMatchesDomainList */ - function testWfMatchesDomainList( $url, $domains, $expected, $description ) { + public function testWfMatchesDomainList( $url, $domains, $expected, $description ) { $actual = wfMatchesDomainList( $url, $domains ); $this->assertEquals( $expected, $actual, $description ); } - function provideWfMatchesDomainList() { + public static function provideWfMatchesDomainList() { $a = array(); $protocols = array( 'HTTP' => 'http:', 'HTTPS' => 'https:', 'protocol-relative' => '' ); foreach ( $protocols as $pDesc => $p ) { @@ -638,18 +598,30 @@ class GlobalTest extends MediaWikiTestCase { array( "$p//www.example2.com", array( 'www.example.com', 'www.example2.com', 'www.example3.com' ), true, "Exact match with other domains in array, $pDesc URL" ), array( "$p//www.example2.com", array( 'example.com', 'example2.com', 'example3,com' ), true, "Match without subdomain with other domains in array, $pDesc URL" ), array( "$p//www.example4.com", array( 'example.com', 'example2.com', 'example3,com' ), false, "Domain not in array, $pDesc URL" ), - - // FIXME: This is a bug in wfMatchesDomainList(). If and when this is fixed, update this test case - array( "$p//nds-nl.wikipedia.org", array( 'nl.wikipedia.org' ), true, "Substrings of domains match while they shouldn't, $pDesc URL" ), + array( "$p//nds-nl.wikipedia.org", array( 'nl.wikipedia.org' ), false, "Non-matching substring of domain, $pDesc URL" ), ) ); } + return $a; } /** + * @covers ::wfMkdirParents + */ + public function testWfMkdirParents() { + // Should not return true if file exists instead of directory + $fname = $this->getNewTempFile(); + wfSuppressWarnings(); + $ok = wfMkdirParents( $fname ); + wfRestoreWarnings(); + $this->assertFalse( $ok ); + } + + /** * @dataProvider provideWfShellMaintenanceCmdList + * @covers ::wfShellMaintenanceCmd */ - function testWfShellMaintenanceCmd( $script, $parameters, $options, $expected, $description ) { + public function testWfShellMaintenanceCmd( $script, $parameters, $options, $expected, $description ) { if ( wfIsWindows() ) { // Approximation that's good enough for our purposes just now $expected = str_replace( "'", '"', $expected ); @@ -658,8 +630,9 @@ class GlobalTest extends MediaWikiTestCase { $this->assertEquals( $expected, $actual, $description ); } - function provideWfShellMaintenanceCmdList() { + public static function provideWfShellMaintenanceCmdList() { global $wgPhpCli; + return array( array( 'eval.php', array( '--help', '--test' ), array(), "'$wgPhpCli' 'eval.php' '--help' '--test'", @@ -675,5 +648,5 @@ class GlobalTest extends MediaWikiTestCase { "Called eval.php --help --test with wrapper and php option" ), ); } - /* TODO: many more! */ + /* @TODO many more! */ } diff --git a/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php b/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php index 4879a38d..cf891e7b 100644 --- a/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php +++ b/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php @@ -6,13 +6,15 @@ class GlobalWithDBTest extends MediaWikiTestCase { /** * @dataProvider provideWfIsBadImageList + * @covers ::wfIsBadImage */ - function testWfIsBadImage( $name, $title, $blacklist, $expected, $desc ) { + public function testWfIsBadImage( $name, $title, $blacklist, $expected, $desc ) { $this->assertEquals( $expected, wfIsBadImage( $name, $title, $blacklist ), $desc ); } - function provideWfIsBadImageList() { + public static function provideWfIsBadImageList() { $blacklist = '* [[File:Bad.jpg]] except [[Nasty page]]'; + return array( array( 'Bad.jpg', false, $blacklist, true, 'Called on a bad image' ), diff --git a/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php index 4bd8c685..9bb74873 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php @@ -1,9 +1,11 @@ <?php /** - * Tests for wfAssembleUrl() + * @covers ::wfAssembleUrl */ class WfAssembleUrlTest extends MediaWikiTestCase { - /** @dataProvider provideURLParts */ + /** + * @dataProvider provideURLParts + */ public function testWfAssembleUrl( $parts, $output ) { $partsDump = print_r( $parts, true ); $this->assertEquals( @@ -87,7 +89,6 @@ class WfAssembleUrlTest extends MediaWikiTestCase { $url .= '#' . $fragment; } - $cases[] = array( $parts, $url, diff --git a/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php b/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php index 8df038dd..a01c0d49 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php +++ b/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php @@ -1,6 +1,6 @@ <?php /** - * Tests for wfBCP47() + * @covers ::wfBCP47 */ class WfBCP47Test extends MediaWikiTestCase { /** @@ -13,7 +13,7 @@ class WfBCP47Test extends MediaWikiTestCase { * @see http://tools.ietf.org/html/bcp47 * @dataProvider provideLanguageCodes() */ - function testBCP47( $code, $expected ) { + public function testBCP47( $code, $expected ) { $code = strtolower( $code ); $this->assertEquals( $expected, wfBCP47( $code ), "Applying BCP47 standard to lower case '$code'" @@ -28,7 +28,7 @@ class WfBCP47Test extends MediaWikiTestCase { /** * Array format is ($code, $expected) */ - function provideLanguageCodes() { + public static function provideLanguageCodes() { return array( // Extracted from BCP47 (list not exhaustive) # 2.1.1 @@ -115,20 +115,6 @@ class WfBCP47Test extends MediaWikiTestCase { // de-419-DE // a-DE // ar-a-aaa-b-bbb-a-ccc - - /* - // ISO 15924 : - array( 'sr-Cyrl', 'sr-Cyrl' ), - # @todo FIXME: Fix our function? - array( 'SR-lATN', 'sr-Latn' ), - array( 'fr-latn', 'fr-Latn' ), - // Use lowercase for single segment - // ISO 3166-1-alpha-2 code - array( 'US', 'us' ), # USA - array( 'uS', 'us' ), # USA - array( 'Fr', 'fr' ), # France - array( 'va', 'va' ), # Holy See (Vatican City State) - */ ); } } diff --git a/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php b/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php index 10b62b3c..7da804e6 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php @@ -1,6 +1,6 @@ <?php /** - * Tests for wfBaseConvert() + * @covers ::wfBaseConvert */ class WfBaseConvertTest extends MediaWikiTestCase { public static function provideSingleDigitConversions() { @@ -152,6 +152,7 @@ class WfBaseConvertTest extends MediaWikiTestCase { $x[] = array( $base, $str ); } + return $x; } diff --git a/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php b/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php index 407be8d2..8c548040 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php @@ -1,17 +1,17 @@ <?php /** - * Tests for wfBaseName() + * @covers ::wfBaseName */ class WfBaseNameTest extends MediaWikiTestCase { /** * @dataProvider providePaths */ - function testBaseName( $fullpath, $basename ) { + public function testBaseName( $fullpath, $basename ) { $this->assertEquals( $basename, wfBaseName( $fullpath ), "wfBaseName('$fullpath') => '$basename'" ); } - function providePaths() { + public static function providePaths() { return array( array( '', '' ), array( '/', '' ), diff --git a/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php index c1225e3e..41230a1e 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php @@ -1,16 +1,17 @@ <?php /** - * Tests for wfExpandUrl() + * @covers ::wfExpandUrl */ class WfExpandUrlTest extends MediaWikiTestCase { - /** @dataProvider provideExpandableUrls */ + /** + * @dataProvider provideExpandableUrls + */ public function testWfExpandUrl( $fullUrl, $shortUrl, $defaultProto, $server, $canServer, $httpsMode, $message ) { // Fake $wgServer and $wgCanonicalServer - global $wgServer, $wgCanonicalServer; - $oldServer = $wgServer; - $oldCanServer = $wgCanonicalServer; - $wgServer = $server; - $wgCanonicalServer = $canServer; + $this->setMwGlobals( array( + 'wgServer' => $server, + 'wgCanonicalServer' => $canServer, + ) ); // Fake $_SERVER['HTTPS'] if needed if ( $httpsMode ) { @@ -20,10 +21,6 @@ class WfExpandUrlTest extends MediaWikiTestCase { } $this->assertEquals( $fullUrl, wfExpandUrl( $shortUrl, $defaultProto ), $message ); - - // Restore $wgServer and $wgCanonicalServer - $wgServer = $oldServer; - $wgCanonicalServer = $oldCanServer; } /** @@ -108,6 +105,7 @@ class WfExpandUrlTest extends MediaWikiTestCase { } } } + return $retval; } } diff --git a/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php b/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php index 58cf6b95..62296245 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php @@ -1,8 +1,11 @@ <?php +/** + * @covers ::wfGetCaller + */ class WfGetCallerTest extends MediaWikiTestCase { - function testZero() { + public function testZero() { $this->assertEquals( __METHOD__, wfGetCaller( 1 ) ); } @@ -10,7 +13,7 @@ class WfGetCallerTest extends MediaWikiTestCase { return wfGetCaller(); } - function testOne() { + public function testOne() { $this->assertEquals( 'WfGetCallerTest::testOne', self::callerOne() ); } @@ -18,18 +21,20 @@ class WfGetCallerTest extends MediaWikiTestCase { if ( $n > 0 ) { return self::intermediateFunction( $level, $n - 1 ); } + return wfGetCaller( $level ); } - function testTwo() { + public function testTwo() { $this->assertEquals( 'WfGetCallerTest::testTwo', self::intermediateFunction() ); } - function testN() { + public function testN() { $this->assertEquals( 'WfGetCallerTest::testN', self::intermediateFunction( 2, 0 ) ); $this->assertEquals( 'WfGetCallerTest::intermediateFunction', self::intermediateFunction( 1, 0 ) ); - for ( $i = 0; $i < 10; $i++ ) + for ( $i = 0; $i < 10; $i++ ) { $this->assertEquals( 'WfGetCallerTest::intermediateFunction', self::intermediateFunction( $i + 1, $i ) ); + } } } diff --git a/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php index 841a1b12..5032dc11 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php @@ -1,7 +1,5 @@ <?php /** - * Tests for wfParseUrl() - * * Copyright © 2013 Alexandre Emsenhuber * * This program is free software; you can redistribute it and/or modify @@ -22,6 +20,9 @@ * @file */ +/** + * @covers ::wfParseUrl + */ class WfParseUrlTest extends MediaWikiTestCase { protected function setUp() { parent::setUp(); @@ -31,7 +32,9 @@ class WfParseUrlTest extends MediaWikiTestCase { ) ); } - /** @dataProvider provideURLs */ + /** + * @dataProvider provideURLs + */ public function testWfParseUrl( $url, $parts ) { $partsDump = var_export( $parts, true ); $this->assertEquals( diff --git a/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php b/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php index 67861eeb..238a2c9c 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php @@ -1,9 +1,11 @@ <?php /** - * Tests for wfRemoveDotSegments() + *@covers ::wfRemoveDotSegments */ class WfRemoveDotSegmentsTest extends MediaWikiTestCase { - /** @dataProvider providePaths */ + /** + * @dataProvider providePaths + */ public function testWfRemoveDotSegments( $inputPath, $outputPath ) { $this->assertEquals( $outputPath, diff --git a/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php b/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php index 9d66d6b9..aadec87f 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php @@ -1,10 +1,13 @@ <?php +/** + * @covers ::wfShorthandToInteger + */ class WfShorthandToIntegerTest extends MediaWikiTestCase { /** * @dataProvider provideABunchOfShorthands */ - function testWfShorthandToInteger( $input, $output, $description ) { + public function testWfShorthandToInteger( $input, $output, $description ) { $this->assertEquals( wfShorthandToInteger( $input ), $output, @@ -12,7 +15,7 @@ class WfShorthandToIntegerTest extends MediaWikiTestCase { ); } - function provideABunchOfShorthands() { + public static function provideABunchOfShorthands() { return array( array( '', -1, 'Empty string' ), array( ' ', -1, 'String of spaces' ), @@ -24,5 +27,4 @@ class WfShorthandToIntegerTest extends MediaWikiTestCase { array( '1k', 1024, 'One kb lowercased' ), ); } - } diff --git a/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php b/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php index cf1830f5..5998f186 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php @@ -1,17 +1,18 @@ <?php /* - * Tests for wfTimestamp() + * @covers ::wfTimestamp */ class WfTimestampTest extends MediaWikiTestCase { /** * @dataProvider provideNormalTimestamps */ - function testNormalTimestamps( $input, $format, $output, $desc ) { + public function testNormalTimestamps( $input, $format, $output, $desc ) { $this->assertEquals( $output, wfTimestamp( $format, $input ), $desc ); } - function provideNormalTimestamps() { + public static function provideNormalTimestamps() { $t = gmmktime( 12, 34, 56, 1, 15, 2001 ); + return array( // TS_UNIX array( $t, TS_MW, '20010115123456', 'TS_UNIX to TS_MW' ), @@ -56,11 +57,11 @@ class WfTimestampTest extends MediaWikiTestCase { * See r74778 and bug 25451 * @dataProvider provideOldTimestamps */ - function testOldTimestamps( $input, $format, $output, $desc ) { + public function testOldTimestamps( $input, $format, $output, $desc ) { $this->assertEquals( $output, wfTimestamp( $format, $input ), $desc ); } - function provideOldTimestamps() { + public static function provideOldTimestamps() { return array( array( '19011213204554', TS_RFC2822, 'Fri, 13 Dec 1901 20:45:54 GMT', 'Earliest time according to php documentation' ), array( '20380119031407', TS_RFC2822, 'Tue, 19 Jan 2038 03:14:07 GMT', 'Latest 32 bit time' ), @@ -95,11 +96,11 @@ class WfTimestampTest extends MediaWikiTestCase { * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1 * @dataProvider provideHttpDates */ - function testHttpDate( $input, $output, $desc ) { + public function testHttpDate( $input, $output, $desc ) { $this->assertEquals( $output, wfTimestamp( TS_MW, $input ), $desc ); } - function provideHttpDates() { + public static function provideHttpDates() { return array( array( 'Sun, 06 Nov 1994 08:49:37 GMT', '19941106084937', 'RFC 822 date' ), array( 'Sunday, 06-Nov-94 08:49:37 GMT', '19941106084937', 'RFC 850 date' ), @@ -113,9 +114,9 @@ class WfTimestampTest extends MediaWikiTestCase { * There are a number of assumptions in our codebase where wfTimestamp() * should give the current date but it is not given a 0 there. See r71751 CR */ - function testTimestampParameter() { + public function testTimestampParameter() { $now = wfTimestamp( TS_UNIX ); - // We check that wfTimestamp doesn't return false (error) and use a LessThan assert + // We check that wfTimestamp doesn't return false (error) and use a LessThan assert // for the cases where the test is run in a second boundary. $zero = wfTimestamp( TS_UNIX, 0 ); diff --git a/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php b/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php index 77685d50..ce6c82c5 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php @@ -1,18 +1,21 @@ <?php /** - * Tests for wfUrlencode() - * * The function only need a string parameter and might react to IIS7.0 + * @covers ::wfUrlencode */ class WfUrlencodeTest extends MediaWikiTestCase { #### TESTS ############################################################## - /** @dataProvider provideURLS */ + /** + * @dataProvider provideURLS + */ public function testEncodingUrlWith( $input, $expected ) { $this->verifyEncodingFor( 'Apache', $input, $expected ); } - /** @dataProvider provideURLS */ + /** + * @dataProvider provideURLS + */ public function testEncodingUrlWithMicrosoftIis7( $input, $expected ) { $this->verifyEncodingFor( 'Microsoft-IIS/7', $input, $expected ); } diff --git a/tests/phpunit/includes/HTMLCheckMatrixTest.php b/tests/phpunit/includes/HTMLCheckMatrixTest.php new file mode 100644 index 00000000..5bbafd37 --- /dev/null +++ b/tests/phpunit/includes/HTMLCheckMatrixTest.php @@ -0,0 +1,102 @@ +<?php + +/** + * Unit tests for the HTMLCheckMatrix form field + */ +class HtmlCheckMatrixTest extends MediaWikiTestCase { + static private $defaultOptions = array( + 'rows' => array( 'r1', 'r2' ), + 'columns' => array( 'c1', 'c2' ), + 'fieldname' => 'test', + ); + + public function testPlainInstantiation() { + try { + $form = new HTMLCheckMatrix( array() ); + } catch ( MWException $e ) { + $this->assertInstanceOf( 'HTMLFormFieldRequiredOptionsException', $e ); + return; + } + + $this->fail( 'Expected MWException indicating missing parameters but none was thrown.' ); + } + + public function testInstantiationWithMinimumRequiredParameters() { + $form = new HTMLCheckMatrix( self::$defaultOptions ); + $this->assertTrue( true ); // form instantiation must throw exception on failure + } + + public function testValidateCallsUserDefinedValidationCallback() { + $called = false; + $field = new HTMLCheckMatrix( self::$defaultOptions + array( + 'validation-callback' => function() use ( &$called ) { + $called = true; + return false; + }, + ) ); + $this->assertEquals( false, $this->validate( $field, array() ) ); + $this->assertTrue( $called ); + } + + public function testValidateRequiresArrayInput() { + $field = new HTMLCheckMatrix( self::$defaultOptions ); + $this->assertEquals( false, $this->validate( $field, null ) ); + $this->assertEquals( false, $this->validate( $field, true ) ); + $this->assertEquals( false, $this->validate( $field, 'abc' ) ); + $this->assertEquals( false, $this->validate( $field, new stdClass ) ); + $this->assertEquals( true, $this->validate( $field, array() ) ); + } + + public function testValidateAllowsOnlyKnownTags() { + $field = new HTMLCheckMatrix( self::$defaultOptions ); + $this->assertInternalType( 'string', $this->validate( $field, array( 'foo' ) ) ); + } + + public function testValidateAcceptsPartialTagList() { + $field = new HTMLCheckMatrix( self::$defaultOptions ); + $this->assertTrue( $this->validate( $field, array() ) ); + $this->assertTrue( $this->validate( $field, array( 'c1-r1' ) ) ); + $this->assertTrue( $this->validate( $field, array( 'c1-r1', 'c1-r2', 'c2-r1', 'c2-r2' ) ) ); + } + + /** + * This form object actually has no visibility into what happens later on, but essentially + * if the data submitted by the user passes validate the following is run: + * foreach ( $field->filterDataForSubmit( $data ) as $k => $v ) { + * $user->setOption( $k, $v ); + * } + */ + public function testValuesForcedOnRemainOn() { + $field = new HTMLCheckMatrix( self::$defaultOptions + array( + 'force-options-on' => array( 'c2-r1' ), + ) ); + $expected = array( + 'c1-r1' => false, + 'c1-r2' => false, + 'c2-r1' => true, + 'c2-r2' => false, + ); + $this->assertEquals( $expected, $field->filterDataForSubmit( array() ) ); + } + + public function testValuesForcedOffRemainOff() { + $field = new HTMLCheckMatrix( self::$defaultOptions + array( + 'force-options-off' => array( 'c1-r2', 'c2-r2' ), + ) ); + $expected = array( + 'c1-r1' => true, + 'c1-r2' => false, + 'c2-r1' => true, + 'c2-r2' => false, + ); + // array_keys on the result simulates submitting all fields checked + $this->assertEquals( $expected, $field->filterDataForSubmit( array_keys( $expected ) ) ); + } + + protected function validate( HTMLFormField $field, $submitted ) { + return $field->validate( + $submitted, + array( self::$defaultOptions['fieldname'] => $submitted ) + ); + } +} diff --git a/tests/phpunit/includes/HashRingTest.php b/tests/phpunit/includes/HashRingTest.php new file mode 100644 index 00000000..65f13696 --- /dev/null +++ b/tests/phpunit/includes/HashRingTest.php @@ -0,0 +1,53 @@ +<?php + +/** + * @group HashRing + */ +class HashRingTest extends MediaWikiTestCase { + public function testHashRing() { + $ring = new HashRing( array( 's1' => 1, 's2' => 1, 's3' => 2, 's4' => 2, 's5' => 2, 's6' => 3 ) ); + + $locations = array(); + for ( $i = 0; $i < 20; $i++ ) { + $locations[ "hello$i"] = $ring->getLocation( "hello$i" ); + } + $expectedLocations = array( + "hello0" => "s5", + "hello1" => "s6", + "hello2" => "s2", + "hello3" => "s5", + "hello4" => "s6", + "hello5" => "s4", + "hello6" => "s5", + "hello7" => "s4", + "hello8" => "s5", + "hello9" => "s5", + "hello10" => "s3", + "hello11" => "s6", + "hello12" => "s1", + "hello13" => "s3", + "hello14" => "s3", + "hello15" => "s5", + "hello16" => "s4", + "hello17" => "s6", + "hello18" => "s6", + "hello19" => "s3" + ); + + $this->assertEquals( $expectedLocations, $locations, 'Items placed at proper locations' ); + + $locations = array(); + for ( $i = 0; $i < 5; $i++ ) { + $locations[ "hello$i"] = $ring->getLocations( "hello$i", 2 ); + } + + $expectedLocations = array( + "hello0" => array( "s5", "s6" ), + "hello1" => array( "s6", "s4" ), + "hello2" => array( "s2", "s1" ), + "hello3" => array( "s5", "s6" ), + "hello4" => array( "s6", "s4" ), + ); + $this->assertEquals( $expectedLocations, $locations, 'Items placed at proper locations' ); + } +} diff --git a/tests/phpunit/includes/HooksTest.php b/tests/phpunit/includes/HooksTest.php index 89e789b1..81dd4870 100644 --- a/tests/phpunit/includes/HooksTest.php +++ b/tests/phpunit/includes/HooksTest.php @@ -2,81 +2,62 @@ class HooksTest extends MediaWikiTestCase { - public function testOldStyleHooks() { - $foo = 'Foo'; - $bar = 'Bar'; - - $i = new NothingClass(); - + function setUp() { global $wgHooks; - - $wgHooks['MediaWikiHooksTest001'][] = array( $i, 'someNonStatic' ); - - wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'fOO', $foo, 'Standard method' ); - $foo = 'Foo'; - - $wgHooks['MediaWikiHooksTest001'][] = $i; - - wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'foo', $foo, 'onEventName style' ); - $foo = 'Foo'; - - $wgHooks['MediaWikiHooksTest001'][] = array( $i, 'someNonStaticWithData', 'baz' ); - - wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'baz', $foo, 'Data included' ); - $foo = 'Foo'; - - $wgHooks['MediaWikiHooksTest001'][] = array( $i, 'someStatic' ); - - wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'bah', $foo, 'Standard static method' ); - //$foo = 'Foo'; - + parent::setUp(); + Hooks::clear( 'MediaWikiHooksTest001' ); unset( $wgHooks['MediaWikiHooksTest001'] ); - } - public function testNewStyleHooks() { - $foo = 'Foo'; - $bar = 'Bar'; - + public static function provideHooks() { $i = new NothingClass(); - Hooks::register( 'MediaWikiHooksTest001', array( $i, 'someNonStatic' ) ); - - Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'fOO', $foo, 'Standard method' ); - $foo = 'Foo'; - - Hooks::register( 'MediaWikiHooksTest001', $i ); - - Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'foo', $foo, 'onEventName style' ); - $foo = 'Foo'; + return array( + array( 'Object and method', array( $i, 'someNonStatic' ), 'changed-nonstatic', 'changed-nonstatic' ), + array( 'Object and no method', array( $i ), 'changed-onevent', 'original' ), + array( 'Object and method with data', array( $i, 'someNonStaticWithData', 'data' ), 'data', 'original' ), + array( 'Object and static method', array( $i, 'someStatic' ), 'changed-static', 'original' ), + array( 'Class::method static call', array( 'NothingClass::someStatic' ), 'changed-static', 'original' ), + array( 'Global function', array( 'NothingFunction' ), 'changed-func', 'original' ), + array( 'Global function with data', array( 'NothingFunctionData', 'data' ), 'data', 'original' ), + array( 'Closure', array( function ( &$foo, $bar ) { + $foo = 'changed-closure'; + + return true; + } ), 'changed-closure', 'original' ), + array( 'Closure with data', array( function ( $data, &$foo, $bar ) { + $foo = $data; + + return true; + }, 'data' ), 'data', 'original' ) + ); + } - Hooks::register( 'MediaWikiHooksTest001', array( $i, 'someNonStaticWithData', 'baz' ) ); + /** + * @dataProvider provideHooks + */ + public function testOldStyleHooks( $msg, array $hook, $expectedFoo, $expectedBar ) { + global $wgHooks; + $foo = $bar = 'original'; - Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); + $wgHooks['MediaWikiHooksTest001'][] = $hook; + wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - $this->assertEquals( 'baz', $foo, 'Data included' ); - $foo = 'Foo'; + $this->assertSame( $expectedFoo, $foo, $msg ); + $this->assertSame( $expectedBar, $bar, $msg ); + } - Hooks::register( 'MediaWikiHooksTest001', array( $i, 'someStatic' ) ); + /** + * @dataProvider provideHooks + */ + public function testNewStyleHooks( $msg, $hook, $expectedFoo, $expectedBar ) { + $foo = $bar = 'original'; + Hooks::register( 'MediaWikiHooksTest001', $hook ); Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - $this->assertEquals( 'bah', $foo, 'Standard static method' ); - $foo = 'Foo'; - - Hooks::clear( 'MediaWikiHooksTest001' ); + $this->assertSame( $expectedFoo, $foo, $msg ); + $this->assertSame( $expectedBar, $bar, $msg ); } public function testNewStyleHookInteraction() { @@ -85,10 +66,6 @@ class HooksTest extends MediaWikiTestCase { $a = new NothingClass(); $b = new NothingClass(); - // make sure to start with a clean slate - Hooks::clear( 'MediaWikiHooksTest001' ); - unset( $wgHooks['MediaWikiHooksTest001'] ); - $wgHooks['MediaWikiHooksTest001'][] = $a; $this->assertTrue( Hooks::isRegistered( 'MediaWikiHooksTest001' ), 'Hook registered via $wgHooks should be noticed by Hooks::isRegistered' ); @@ -101,37 +78,81 @@ class HooksTest extends MediaWikiTestCase { Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); $this->assertEquals( 1, $a->calls, 'Hooks::run() should run hooks registered via wgHooks as well as Hooks::register' ); $this->assertEquals( 1, $b->calls, 'Hooks::run() should run hooks registered via wgHooks as well as Hooks::register' ); + } - // clean up - Hooks::clear( 'MediaWikiHooksTest001' ); - unset( $wgHooks['MediaWikiHooksTest001'] ); + /** + * @expectedException MWException + */ + public function testUncallableFunction() { + Hooks::register( 'MediaWikiHooksTest001', 'ThisFunctionDoesntExist' ); + Hooks::run( 'MediaWikiHooksTest001', array() ); } + + public function testFalseReturn() { + Hooks::register( 'MediaWikiHooksTest001', function ( &$foo ) { + return false; + } ); + Hooks::register( 'MediaWikiHooksTest001', function ( &$foo ) { + $foo = 'test'; + + return true; + } ); + $foo = 'original'; + Hooks::run( 'MediaWikiHooksTest001', array( &$foo ) ); + $this->assertSame( 'original', $foo, 'Hooks continued processing after a false return.' ); + } + + /** + * @expectedException FatalError + */ + public function testFatalError() { + Hooks::register( 'MediaWikiHooksTest001', function () { + return 'test'; + } ); + Hooks::run( 'MediaWikiHooksTest001', array() ); + } +} + +function NothingFunction( &$foo, &$bar ) { + $foo = 'changed-func'; + + return true; +} + +function NothingFunctionData( $data, &$foo, &$bar ) { + $foo = $data; + + return true; } class NothingClass { public $calls = 0; public static function someStatic( &$foo, &$bar ) { - $foo = 'bah'; + $foo = 'changed-static'; + return true; } public function someNonStatic( &$foo, &$bar ) { $this->calls++; - $foo = 'fOO'; - $bar = 'bAR'; + $foo = 'changed-nonstatic'; + $bar = 'changed-nonstatic'; + return true; } public function onMediaWikiHooksTest001( &$foo, &$bar ) { $this->calls++; - $foo = 'foo'; + $foo = 'changed-onevent'; + return true; } - public function someNonStaticWithData( $foo, &$bar ) { + public function someNonStaticWithData( $data, &$foo, &$bar ) { $this->calls++; - $bar = $foo; + $foo = $data; + return true; } } diff --git a/tests/phpunit/includes/HtmlFormatterTest.php b/tests/phpunit/includes/HtmlFormatterTest.php new file mode 100644 index 00000000..a37df74f --- /dev/null +++ b/tests/phpunit/includes/HtmlFormatterTest.php @@ -0,0 +1,81 @@ +<?php + +/** + * @group HtmlFormatter + */ +class HtmlFormatterTest extends MediaWikiTestCase { + /** + * @dataProvider getHtmlData + */ + public function testTransform( $input, $expected, $callback = false ) { + $input = self::normalize( $input ); + $formatter = new HtmlFormatter( HtmlFormatter::wrapHTML( $input ) ); + if ( $callback ) { + $callback( $formatter ); + } + $formatter->filterContent(); + $html = $formatter->getText(); + $this->assertEquals( self::normalize( $expected ), self::normalize( $html ) ); + } + + private static function normalize( $s ) { + return str_replace( "\n", '', + str_replace( "\r", '', $s ) // "yay" to Windows! + ); + } + + public function getHtmlData() { + $removeImages = function( HtmlFormatter $f ) { + $f->setRemoveMedia(); + }; + $removeTags = function( HtmlFormatter $f ) { + $f->remove( array( 'table', '.foo', '#bar', 'div.baz' ) ); + }; + $flattenSomeStuff = function( HtmlFormatter $f ) { + $f->flatten( array( 's', 'div' ) ); + }; + $flattenEverything = function( HtmlFormatter $f ) { + $f->flattenAllTags(); + }; + return array( + // remove images if asked + array( + '<img src="/foo/bar.jpg" alt="Blah"/>', + '', + $removeImages, + ), + // basic tag removal + array( + '<table><tr><td>foo</td></tr></table><div class="foo">foo</div><div class="foo quux">foo</div><span id="bar">bar</span> +<strong class="foo" id="bar">foobar</strong><div class="notfoo">test</div><div class="baz"/> +<span class="baz">baz</span>', + + '<div class="notfoo">test</div> +<span class="baz">baz</span>', + $removeTags, + ), + // don't flatten tags that start like chosen ones + array( + '<div><s>foo</s> <span>bar</span></div>', + 'foo <span>bar</span>', + $flattenSomeStuff, + ), + // total flattening + array( + '<div style="foo">bar<sup>2</sup></div>', + 'bar2', + $flattenEverything, + ), + // UTF-8 preservation and security + array( + '<span title="" \' &"><Тест!></span> &<&&&&', + '<span title="" \' &"><Тест!></span> &<&&&&', + ), + // https://bugzilla.wikimedia.org/show_bug.cgi?id=53086 + array( + 'Foo<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup> <a href="/wiki/Bar" title="Bar" class="mw-redirect">Bar</a>', + 'Foo<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup> <a href="/wiki/Bar" title="Bar" class="mw-redirect">Bar</a>', + ), + ); + } +} diff --git a/tests/phpunit/includes/HtmlTest.php b/tests/phpunit/includes/HtmlTest.php index 590664e8..1c62d032 100644 --- a/tests/phpunit/includes/HtmlTest.php +++ b/tests/phpunit/includes/HtmlTest.php @@ -37,14 +37,11 @@ class HtmlTest extends MediaWikiTestCase { 'wgLanguageCode' => $langCode, 'wgContLang' => $langObj, 'wgLang' => $langObj, - 'wgHtml5' => true, 'wgWellFormedXml' => false, ) ); } public function testElementBasics() { - global $wgWellFormedXml; - $this->assertEquals( '<img>', Html::element( 'img', null, '' ), @@ -63,7 +60,7 @@ class HtmlTest extends MediaWikiTestCase { 'Close tag for empty element (array, string)' ); - $wgWellFormedXml = true; + $this->setMwGlobals( 'wgWellFormedXml', true ); $this->assertEquals( '<img />', @@ -72,6 +69,31 @@ class HtmlTest extends MediaWikiTestCase { ); } + public function dataXmlMimeType() { + return array( + // ( $mimetype, $isXmlMimeType ) + # HTML is not an XML MimeType + array( 'text/html', false ), + # XML is an XML MimeType + array( 'text/xml', true ), + array( 'application/xml', true ), + # XHTML is an XML MimeType + array( 'application/xhtml+xml', true ), + # Make sure other +xml MimeTypes are supported + # SVG is another random MimeType even though we don't use it + array( 'image/svg+xml', true ), + # Complete random other MimeTypes are not XML + array( 'text/plain', false ), + ); + } + + /** + * @dataProvider dataXmlMimeType + */ + public function testXmlMimeType( $mimetype, $isXmlMimeType ) { + $this->assertEquals( $isXmlMimeType, Html::isXmlMimeType( $mimetype ) ); + } + public function testExpandAttributesSkipsNullAndFalse() { ### EMPTY ######## @@ -90,8 +112,6 @@ class HtmlTest extends MediaWikiTestCase { } public function testExpandAttributesForBooleans() { - global $wgHtml5, $wgWellFormedXml; - $this->assertEquals( '', Html::expandAttributes( array( 'selected' => false ) ), @@ -114,21 +134,13 @@ class HtmlTest extends MediaWikiTestCase { 'Boolean attributes have no value when value is true (passed as numerical array)' ); - $wgWellFormedXml = true; + $this->setMwGlobals( 'wgWellFormedXml', true ); $this->assertEquals( ' selected=""', Html::expandAttributes( array( 'selected' => true ) ), 'Boolean attributes have empty string value when value is true (wgWellFormedXml)' ); - - $wgHtml5 = false; - - $this->assertEquals( - ' selected="selected"', - Html::expandAttributes( array( 'selected' => true ) ), - 'Boolean attributes have their key as value when value is true (wgWellFormedXml, wgHTML5 = false)' - ); } /** @@ -136,8 +148,6 @@ class HtmlTest extends MediaWikiTestCase { * Please note it output a string prefixed with a space! */ public function testExpandAttributesVariousExpansions() { - global $wgWellFormedXml; - ### NOT EMPTY #### $this->assertEquals( ' empty_string=""', @@ -160,7 +170,7 @@ class HtmlTest extends MediaWikiTestCase { 'Number 0 value needs no quotes' ); - $wgWellFormedXml = true; + $this->setMwGlobals( 'wgWellFormedXml', true ); $this->assertEquals( ' empty_string=""', @@ -240,7 +250,7 @@ class HtmlTest extends MediaWikiTestCase { * Test feature added by r96188, let pass attributes values as * a PHP array. Restricted to class,rel, accesskey. */ - function testExpandAttributesSpaceSeparatedAttributesWithBoolean() { + public function testExpandAttributesSpaceSeparatedAttributesWithBoolean() { $this->assertEquals( ' class="booltrue one"', Html::expandAttributes( array( 'class' => array( @@ -264,7 +274,7 @@ class HtmlTest extends MediaWikiTestCase { * * Feature added by r96188 */ - function testValueIsAuthoritativeInSpaceSeparatedAttributesArrays() { + public function testValueIsAuthoritativeInSpaceSeparatedAttributesArrays() { $this->assertEquals( ' class=""', Html::expandAttributes( array( 'class' => array( @@ -275,7 +285,7 @@ class HtmlTest extends MediaWikiTestCase { ); } - function testNamespaceSelector() { + public function testNamespaceSelector() { $this->assertEquals( '<select id=namespace name=namespace>' . "\n" . '<option value=0>(Main)</option>' . "\n" . @@ -354,7 +364,7 @@ class HtmlTest extends MediaWikiTestCase { ); } - function testCanFilterOutNamespaces() { + public function testCanFilterOutNamespaces() { $this->assertEquals( '<select id=namespace name=namespace>' . "\n" . '<option value=2>User</option>' . "\n" . @@ -376,7 +386,7 @@ class HtmlTest extends MediaWikiTestCase { ); } - function testCanDisableANamespaces() { + public function testCanDisableANamespaces() { $this->assertEquals( '<select id=namespace name=namespace>' . "\n" . '<option disabled value=0>(Main)</option>' . "\n" . @@ -406,7 +416,7 @@ class HtmlTest extends MediaWikiTestCase { /** * @dataProvider provideHtml5InputTypes */ - function testHtmlElementAcceptsNewHtml5TypesInHtml5Mode( $HTML5InputType ) { + public function testHtmlElementAcceptsNewHtml5TypesInHtml5Mode( $HTML5InputType ) { $this->assertEquals( '<input type=' . $HTML5InputType . '>', Html::element( 'input', array( 'type' => $HTML5InputType ) ), @@ -418,7 +428,7 @@ class HtmlTest extends MediaWikiTestCase { * List of input element types values introduced by HTML5 * Full list at http://www.w3.org/TR/html-markup/input.html */ - function provideHtml5InputTypes() { + public static function provideHtml5InputTypes() { $types = array( 'datetime', 'datetime-local', @@ -438,6 +448,7 @@ class HtmlTest extends MediaWikiTestCase { foreach ( $types as $type ) { $cases[] = array( $type ); } + return $cases; } @@ -446,7 +457,7 @@ class HtmlTest extends MediaWikiTestCase { * @covers Html::dropDefaults * @dataProvider provideElementsWithAttributesHavingDefaultValues */ - function testDropDefaults( $expected, $element, $attribs, $message = '' ) { + public function testDropDefaults( $expected, $element, $attribs, $message = '' ) { $this->assertEquals( $expected, Html::element( $element, $attribs ), $message ); } @@ -602,6 +613,7 @@ class HtmlTest extends MediaWikiTestCase { isset( $case[3] ) ? $case[3] : '' ); } + return $ret; } @@ -616,5 +628,4 @@ class HtmlTest extends MediaWikiTestCase { 'Allow special case "step=any".' ); } - } diff --git a/tests/phpunit/includes/HttpTest.php b/tests/phpunit/includes/HttpTest.php index 7698776c..11d8ed60 100644 --- a/tests/phpunit/includes/HttpTest.php +++ b/tests/phpunit/includes/HttpTest.php @@ -5,8 +5,9 @@ class HttpTest extends MediaWikiTestCase { /** * @dataProvider cookieDomains + * @covers Cookie::validateCookieDomain */ - function testValidateCookieDomain( $expected, $domain, $origin = null ) { + public function testValidateCookieDomain( $expected, $domain, $origin = null ) { if ( $origin ) { $ok = Cookie::validateCookieDomain( $domain, $origin ); $msg = "$domain against origin $origin"; @@ -50,8 +51,9 @@ class HttpTest extends MediaWikiTestCase { * Test Http::isValidURI() * @bug 27854 : Http::isValidURI is too lax * @dataProvider provideURI + * @covers Http::isValidURI */ - function testIsValidUri( $expect, $URI, $message = '' ) { + public function testIsValidUri( $expect, $URI, $message = '' ) { $this->assertEquals( $expect, (bool)Http::isValidURI( $URI ), @@ -132,7 +134,7 @@ class HttpTest extends MediaWikiTestCase { * rewritten when bug 29232 is taken care of (high-level handling of * HTTP redirects). */ - function testRelativeRedirections() { + public function testRelativeRedirections() { $h = MWHttpRequestTester::factory( 'http://oldsite/file.ext' ); # Forge a Location header @@ -176,7 +178,7 @@ class HttpTest extends MediaWikiTestCase { */ class MWHttpRequestTester extends MWHttpRequest { - // function derived from the MWHttpRequest factory function but + // function derived from the MWHttpRequest factory function but // returns appropriate tester class here public static function factory( $url, $options = null ) { if ( !Http::$httpEngine ) { @@ -194,6 +196,7 @@ class MWHttpRequestTester extends MWHttpRequest { throw new MWException( __METHOD__ . ': allow_url_fopen needs to be enabled for pure PHP' . ' http requests to work. If possible, curl should be used instead. See http://php.net/curl.' ); } + return new PhpHttpRequestTester( $url, $options ); default: } diff --git a/tests/phpunit/includes/IPTest.php b/tests/phpunit/includes/IPTest.php index 7bc29385..c074eea6 100644 --- a/tests/phpunit/includes/IPTest.php +++ b/tests/phpunit/includes/IPTest.php @@ -1,7 +1,12 @@ <?php /** - * Tests for IP validity functions. Ported from /t/inc/IP.t by avar. + * Tests for IP validity functions. + * + * Ported from /t/inc/IP.t by avar. + * * @group IP + * @todo Test methods in this call should be split into a method and a + * dataprovider. */ class IPTest extends MediaWikiTestCase { @@ -259,14 +264,63 @@ class IPTest extends MediaWikiTestCase { } /** - * test wrapper around ip2long which might return -1 or false depending on PHP version * @covers IP::toUnsigned + * @dataProvider provideToUnsigned */ - public function testip2longWrapper() { - // @todo FIXME: Add more tests ? - $this->assertEquals( pow( 2, 32 ) - 1, IP::toUnsigned( '255.255.255.255' ) ); - $i = 'IN.VA.LI.D'; - $this->assertFalse( IP::toUnSigned( $i ) ); + public function testToUnsigned( $expected, $input ) { + $result = IP::toUnsigned( $input ); + $this->assertTrue( $result === false || is_string( $result ) || is_int( $result ) ); + $this->assertEquals( $expected, $result ); + } + + /** + * Provider for IP::testToUnsigned() + */ + public static function provideToUnsigned() { + return array( + array( 1, '0.0.0.1' ), + array( 16909060, '1.2.3.4' ), + array( 2130706433, '127.0.0.1' ), + array( '2147483648', '128.0.0.0' ), + array( '3735931646', '222.173.202.254' ), + array( pow( 2, 32 ) - 1, '255.255.255.255' ), + array( false, 'IN.VA.LI.D' ), + array( 1, '::1' ), + array( '42540766452641154071740215577757643572', '2001:0db8:85a3:0000:0000:8a2e:0370:7334' ), + array( '42540766452641154071740215577757643572', '2001:db8:85a3::8a2e:0370:7334' ), + array( false, 'IN:VA::LI:D' ), + array( false, ':::1' ) + ); + } + + /** + * @covers IP::toHex + * @dataProvider provideToHex + */ + public function testToHex( $expected, $input ) { + $result = IP::toHex( $input ); + $this->assertTrue( $result === false || is_string( $result ) ); + $this->assertEquals( $expected, $result ); + } + + /** + * Provider for IP::testToHex() + */ + public static function provideToHex() { + return array( + array( '00000001', '0.0.0.1' ), + array( '01020304', '1.2.3.4' ), + array( '7F000001', '127.0.0.1' ), + array( '80000000', '128.0.0.0' ), + array( 'DEADCAFE', '222.173.202.254' ), + array( 'FFFFFFFF', '255.255.255.255' ), + array( false, 'IN.VA.LI.D' ), + array( 'v6-00000000000000000000000000000001', '::1' ), + array( 'v6-20010DB885A3000000008A2E03707334', '2001:0db8:85a3:0000:0000:8a2e:0370:7334' ), + array( 'v6-20010DB885A3000000008A2E03707334', '2001:db8:85a3::8a2e:0370:7334' ), + array( false, 'IN:VA::LI:D' ), + array( false, ':::1' ) + ); } /** @@ -338,7 +392,7 @@ class IPTest extends MediaWikiTestCase { * representing the network mask and the bit mask. * @covers IP::parseCIDR */ - function testCIDRParsing() { + public function testCIDRParsing() { $this->assertFalseCIDR( '192.0.2.0', "missing mask" ); $this->assertFalseCIDR( '192.0.2.0/', "missing bitmask" ); @@ -435,7 +489,7 @@ class IPTest extends MediaWikiTestCase { * Test for IP::splitHostAndPort(). * @dataProvider provideSplitHostAndPort */ - function testSplitHostAndPort( $expected, $input, $description ) { + public function testSplitHostAndPort( $expected, $input, $description ) { $this->assertEquals( $expected, IP::splitHostAndPort( $input ), $description ); } @@ -462,7 +516,7 @@ class IPTest extends MediaWikiTestCase { * Test for IP::combineHostAndPort() * @dataProvider provideCombineHostAndPort */ - function testCombineHostAndPort( $expected, $input, $description ) { + public function testCombineHostAndPort( $expected, $input, $description ) { list( $host, $port, $defaultPort ) = $input; $this->assertEquals( $expected, @@ -486,7 +540,7 @@ class IPTest extends MediaWikiTestCase { * Test for IP::sanitizeRange() * @dataProvider provideIPCIDRs */ - function testSanitizeRange( $input, $expected, $description ) { + public function testSanitizeRange( $input, $expected, $description ) { $this->assertEquals( $expected, IP::sanitizeRange( $input ), $description ); } @@ -510,7 +564,7 @@ class IPTest extends MediaWikiTestCase { * Test for IP::prettifyIP() * @dataProvider provideIPsToPrettify */ - function testPrettifyIP( $ip, $prettified ) { + public function testPrettifyIP( $ip, $prettified ) { $this->assertEquals( $prettified, IP::prettifyIP( $ip ), "Prettify of $ip" ); } diff --git a/tests/phpunit/includes/JsonTest.php b/tests/phpunit/includes/JsonTest.php deleted file mode 100644 index 96a2ead5..00000000 --- a/tests/phpunit/includes/JsonTest.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php - -class JsonTest extends MediaWikiTestCase { - - function testPhpBug46944Test() { - $this->assertNotEquals( - '\ud840\udc00', - strtolower( FormatJson::encode( "\xf0\xa0\x80\x80" ) ), - 'Test encoding an broken json_encode character (U+20000)' - ); - - } - - function testDecodeVarTypes() { - $this->assertInternalType( - 'object', - FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}' ), - 'Default to object' - ); - - $this->assertInternalType( - 'array', - FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}', true ), - 'Optional array' - ); - } -} diff --git a/tests/phpunit/includes/LanguageConverterTest.php b/tests/phpunit/includes/LanguageConverterTest.php index d4d93b07..7c2134b9 100644 --- a/tests/phpunit/includes/LanguageConverterTest.php +++ b/tests/phpunit/includes/LanguageConverterTest.php @@ -30,39 +30,39 @@ class LanguageConverterTest extends MediaWikiLangTestCase { parent::tearDown(); } - function testGetPreferredVariantDefaults() { + public function testGetPreferredVariantDefaults() { $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantHeaders() { + public function testGetPreferredVariantHeaders() { global $wgRequest; $wgRequest->setHeader( 'Accept-Language', 'tg-latn' ); $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantHeaderWeight() { + public function testGetPreferredVariantHeaderWeight() { global $wgRequest; $wgRequest->setHeader( 'Accept-Language', 'tg;q=1' ); $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantHeaderWeight2() { + public function testGetPreferredVariantHeaderWeight2() { global $wgRequest; $wgRequest->setHeader( 'Accept-Language', 'tg-latn;q=1' ); $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantHeaderMulti() { + public function testGetPreferredVariantHeaderMulti() { global $wgRequest; $wgRequest->setHeader( 'Accept-Language', 'en, tg-latn;q=1' ); $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantUserOption() { + public function testGetPreferredVariantUserOption() { global $wgUser; $wgUser = new User; @@ -75,7 +75,21 @@ class LanguageConverterTest extends MediaWikiLangTestCase { $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantHeaderUserVsUrl() { + public function testGetPreferredVariantUserOptionForForeignLanguage() { + global $wgContLang, $wgUser; + + $wgContLang = Language::factory( 'en' ); + $wgUser = new User; + $wgUser->load(); // from 'defaults' + $wgUser->mId = 1; + $wgUser->mDataLoaded = true; + $wgUser->mOptionsLoaded = true; + $wgUser->setOption( 'variant-tg', 'tg-latn' ); + + $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); + } + + public function testGetPreferredVariantHeaderUserVsUrl() { global $wgContLang, $wgRequest, $wgUser; $wgContLang = Language::factory( 'tg-latn' ); @@ -85,19 +99,19 @@ class LanguageConverterTest extends MediaWikiLangTestCase { $wgUser->mFrom = 'defaults'; $wgUser->mOptionsLoaded = true; // The user's data is ignored because the variant is set in the URL. - $wgUser->setOption( 'variant', 'tg-latn' ); + $wgUser->setOption( 'variant', 'tg-latn' ); $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantDefaultLanguageVariant() { + public function testGetPreferredVariantDefaultLanguageVariant() { global $wgDefaultLanguageVariant; $wgDefaultLanguageVariant = 'tg-latn'; $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantDefaultLanguageVsUrlVariant() { + public function testGetPreferredVariantDefaultLanguageVsUrlVariant() { global $wgDefaultLanguageVariant, $wgRequest, $wgContLang; $wgContLang = Language::factory( 'tg-latn' ); @@ -123,7 +137,6 @@ class TestConverter extends LanguageConverter { 'tg' => new ReplacementArray() ); } - } class LanguageToTest extends Language { diff --git a/tests/phpunit/includes/LicensesTest.php b/tests/phpunit/includes/LicensesTest.php index 212b3b3b..478a2ffc 100644 --- a/tests/phpunit/includes/LicensesTest.php +++ b/tests/phpunit/includes/LicensesTest.php @@ -2,7 +2,7 @@ class LicensesTest extends MediaWikiTestCase { - function testLicenses() { + public function testLicenses() { $str = " * Free licenses: ** GFDL|Debian disagrees diff --git a/tests/phpunit/includes/LinkerTest.php b/tests/phpunit/includes/LinkerTest.php index e353c46c..b605f08f 100644 --- a/tests/phpunit/includes/LinkerTest.php +++ b/tests/phpunit/includes/LinkerTest.php @@ -6,7 +6,7 @@ class LinkerTest extends MediaWikiLangTestCase { * @dataProvider provideCasesForUserLink * @covers Linker::userLink */ - function testUserLink( $expected, $userId, $userName, $altUserName = false, $msg = '' ) { + public function testUserLink( $expected, $userId, $userName, $altUserName = false, $msg = '' ) { $this->setMwGlobals( array( 'wgArticlePath' => '/wiki/$1', 'wgWellFormedXml' => true, @@ -17,7 +17,7 @@ class LinkerTest extends MediaWikiLangTestCase { ); } - function provideCasesForUserLink() { + public static function provideCasesForUserLink() { # Format: # - expected # - userid diff --git a/tests/phpunit/includes/LinksUpdateTest.php b/tests/phpunit/includes/LinksUpdateTest.php index a79b3a25..5ade250e 100644 --- a/tests/phpunit/includes/LinksUpdateTest.php +++ b/tests/phpunit/includes/LinksUpdateTest.php @@ -7,7 +7,7 @@ */ class LinksUpdateTest extends MediaWikiTestCase { - function __construct( $name = null, array $data = array(), $dataName = '' ) { + function __construct( $name = null, array $data = array(), $dataName = '' ) { parent::__construct( $name, $data, $dataName ); $this->tablesUsed = array_merge( $this->tablesUsed, @@ -60,18 +60,30 @@ class LinksUpdateTest extends MediaWikiTestCase { $po->addLink( Title::newFromText( "linksupdatetest:Foo" ) ); // interwiki link should be ignored $po->addLink( Title::newFromText( "#Foo" ) ); // hash link should be ignored - $this->assertLinksUpdate( $t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = 111', array( + $update = $this->assertLinksUpdate( $t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = 111', array( array( NS_MAIN, 'Foo' ), ) ); + $this->assertArrayEquals( array( + Title::makeTitle( NS_MAIN, 'Foo' ), // newFromText doesn't yield the same internal state.... + ), $update->getAddedLinks() ); $po = new ParserOutput(); $po->setTitleText( $t->getPrefixedText() ); $po->addLink( Title::newFromText( "Bar" ) ); + $po->addLink( Title::newFromText( "Talk:Bar" ) ); - $this->assertLinksUpdate( $t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = 111', array( + $update = $this->assertLinksUpdate( $t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = 111', array( array( NS_MAIN, 'Bar' ), + array( NS_TALK, 'Bar' ), ) ); + $this->assertArrayEquals( array( + Title::makeTitle( NS_MAIN, 'Bar' ), + Title::makeTitle( NS_TALK, 'Bar' ), + ), $update->getAddedLinks() ); + $this->assertArrayEquals( array( + Title::makeTitle( NS_MAIN, 'Foo' ), + ), $update->getRemovedLinks() ); } public function testUpdate_externallinks() { @@ -122,7 +134,6 @@ class LinksUpdateTest extends MediaWikiTestCase { $po->addImage( "Foo.png" ); - $this->assertLinksUpdate( $t, $po, 'imagelinks', 'il_to', 'il_from = 111', array( array( 'Foo.png' ), ) ); @@ -133,7 +144,6 @@ class LinksUpdateTest extends MediaWikiTestCase { $po->addLanguageLink( Title::newFromText( "en:Foo" )->getFullText() ); - $this->assertLinksUpdate( $t, $po, 'langlinks', 'll_lang, ll_title', 'll_from = 111', array( array( 'En', 'Foo' ), ) ); @@ -149,7 +159,7 @@ class LinksUpdateTest extends MediaWikiTestCase { ) ); } - #@todo: test recursive, too! + // @todo test recursive, too! protected function assertLinksUpdate( Title $title, ParserOutput $parserOutput, $table, $fields, $condition, array $expectedRows ) { $update = new LinksUpdate( $title, $parserOutput ); @@ -160,5 +170,6 @@ class LinksUpdateTest extends MediaWikiTestCase { $update->commitTransaction(); $this->assertSelect( $table, $fields, $condition, $expectedRows ); + return $update; } } diff --git a/tests/phpunit/includes/LocalFileTest.php b/tests/phpunit/includes/LocalFileTest.php index d6f0d2ee..2501c783 100644 --- a/tests/phpunit/includes/LocalFileTest.php +++ b/tests/phpunit/includes/LocalFileTest.php @@ -35,72 +35,72 @@ class LocalFileTest extends MediaWikiTestCase { $this->file_lc = $this->repo_lc->newFile( 'test!' ); } - function testGetHashPath() { + public function testGetHashPath() { $this->assertEquals( '', $this->file_hl0->getHashPath() ); $this->assertEquals( 'a/a2/', $this->file_hl2->getHashPath() ); $this->assertEquals( 'c/c4/', $this->file_lc->getHashPath() ); } - function testGetRel() { + public function testGetRel() { $this->assertEquals( 'Test!', $this->file_hl0->getRel() ); $this->assertEquals( 'a/a2/Test!', $this->file_hl2->getRel() ); $this->assertEquals( 'c/c4/test!', $this->file_lc->getRel() ); } - function testGetUrlRel() { + public function testGetUrlRel() { $this->assertEquals( 'Test%21', $this->file_hl0->getUrlRel() ); $this->assertEquals( 'a/a2/Test%21', $this->file_hl2->getUrlRel() ); $this->assertEquals( 'c/c4/test%21', $this->file_lc->getUrlRel() ); } - function testGetArchivePath() { + public function testGetArchivePath() { $this->assertEquals( 'mwstore://local-backend/test-public/archive', $this->file_hl0->getArchivePath() ); $this->assertEquals( 'mwstore://local-backend/test-public/archive/a/a2', $this->file_hl2->getArchivePath() ); $this->assertEquals( 'mwstore://local-backend/test-public/archive/!', $this->file_hl0->getArchivePath( '!' ) ); $this->assertEquals( 'mwstore://local-backend/test-public/archive/a/a2/!', $this->file_hl2->getArchivePath( '!' ) ); } - function testGetThumbPath() { + public function testGetThumbPath() { $this->assertEquals( 'mwstore://local-backend/test-thumb/Test!', $this->file_hl0->getThumbPath() ); $this->assertEquals( 'mwstore://local-backend/test-thumb/a/a2/Test!', $this->file_hl2->getThumbPath() ); $this->assertEquals( 'mwstore://local-backend/test-thumb/Test!/x', $this->file_hl0->getThumbPath( 'x' ) ); $this->assertEquals( 'mwstore://local-backend/test-thumb/a/a2/Test!/x', $this->file_hl2->getThumbPath( 'x' ) ); } - function testGetArchiveUrl() { + public function testGetArchiveUrl() { $this->assertEquals( '/testurl/archive', $this->file_hl0->getArchiveUrl() ); $this->assertEquals( '/testurl/archive/a/a2', $this->file_hl2->getArchiveUrl() ); $this->assertEquals( '/testurl/archive/%21', $this->file_hl0->getArchiveUrl( '!' ) ); $this->assertEquals( '/testurl/archive/a/a2/%21', $this->file_hl2->getArchiveUrl( '!' ) ); } - function testGetThumbUrl() { + public function testGetThumbUrl() { $this->assertEquals( '/testurl/thumb/Test%21', $this->file_hl0->getThumbUrl() ); $this->assertEquals( '/testurl/thumb/a/a2/Test%21', $this->file_hl2->getThumbUrl() ); $this->assertEquals( '/testurl/thumb/Test%21/x', $this->file_hl0->getThumbUrl( 'x' ) ); $this->assertEquals( '/testurl/thumb/a/a2/Test%21/x', $this->file_hl2->getThumbUrl( 'x' ) ); } - function testGetArchiveVirtualUrl() { + public function testGetArchiveVirtualUrl() { $this->assertEquals( 'mwrepo://test/public/archive', $this->file_hl0->getArchiveVirtualUrl() ); $this->assertEquals( 'mwrepo://test/public/archive/a/a2', $this->file_hl2->getArchiveVirtualUrl() ); $this->assertEquals( 'mwrepo://test/public/archive/%21', $this->file_hl0->getArchiveVirtualUrl( '!' ) ); $this->assertEquals( 'mwrepo://test/public/archive/a/a2/%21', $this->file_hl2->getArchiveVirtualUrl( '!' ) ); } - function testGetThumbVirtualUrl() { + public function testGetThumbVirtualUrl() { $this->assertEquals( 'mwrepo://test/thumb/Test%21', $this->file_hl0->getThumbVirtualUrl() ); $this->assertEquals( 'mwrepo://test/thumb/a/a2/Test%21', $this->file_hl2->getThumbVirtualUrl() ); $this->assertEquals( 'mwrepo://test/thumb/Test%21/%21', $this->file_hl0->getThumbVirtualUrl( '!' ) ); $this->assertEquals( 'mwrepo://test/thumb/a/a2/Test%21/%21', $this->file_hl2->getThumbVirtualUrl( '!' ) ); } - function testGetUrl() { + public function testGetUrl() { $this->assertEquals( '/testurl/Test%21', $this->file_hl0->getUrl() ); $this->assertEquals( '/testurl/a/a2/Test%21', $this->file_hl2->getUrl() ); } - function testWfLocalFile() { + public function testWfLocalFile() { $file = wfLocalFile( "File:Some_file_that_probably_doesn't exist.png" ); $this->assertThat( $file, $this->isInstanceOf( 'LocalFile' ), 'wfLocalFile() returns LocalFile for valid Titles' ); } diff --git a/tests/phpunit/includes/MWExceptionHandlerTest.php b/tests/phpunit/includes/MWExceptionHandlerTest.php new file mode 100644 index 00000000..987dfa83 --- /dev/null +++ b/tests/phpunit/includes/MWExceptionHandlerTest.php @@ -0,0 +1,73 @@ +<?php +/** + * Tests for includes/Exception.php. + * + * @author Antoine Musso + * @copyright Copyright © 2013, Antoine Musso + * @copyright Copyright © 2013, Wikimedia Foundation Inc. + * @file + */ + +class MWExceptionHandlerTest extends MediaWikiTestCase { + + /** + * @covers MWExceptionHandler::getRedactedTrace + */ + function testGetRedactedTrace() { + try { + $array = array( 'a', 'b' ); + $object = new StdClass(); + self::helperThrowAnException( $array, $object ); + } catch (Exception $e) { + } + + # Make sure our strack trace contains an array and an object passed to + # some function in the stacktrace. Else, we can not assert the trace + # redaction achieved its job. + $trace = $e->getTrace(); + $hasObject = false; + $hasArray = false; + foreach ( $trace as $frame ) { + if ( ! isset( $frame['args'] ) ) { + continue; + } + foreach ( $frame['args'] as $arg ) { + $hasObject = $hasObject || is_object( $arg ); + $hasArray = $hasArray || is_array( $arg ); + } + + if( $hasObject && $hasArray ) { + break; + } + } + $this->assertTrue( $hasObject, + "The stacktrace must have a function having an object has parameter" ); + $this->assertTrue( $hasArray, + "The stacktrace must have a function having an array has parameter" ); + + # Now we redact the trace.. and make sure no function arguments are + # arrays or objects. + $redacted = MWExceptionHandler::getRedactedTrace( $e ); + + foreach ( $redacted as $frame ) { + if ( ! isset( $frame['args'] ) ) { + continue; + } + foreach ( $frame['args'] as $arg ) { + $this->assertNotInternalType( 'array', $arg); + $this->assertNotInternalType( 'object', $arg); + } + } + } + + /** + * Helper function for testExpandArgumentsInCall + * + * Pass it an object and an array :-) + * + * @throws Exception + */ + protected static function helperThrowAnException( $a, $b ) { + throw new Exception(); + } +} diff --git a/tests/phpunit/includes/MWFunctionTest.php b/tests/phpunit/includes/MWFunctionTest.php index 6c17bf48..d86f2c9b 100644 --- a/tests/phpunit/includes/MWFunctionTest.php +++ b/tests/phpunit/includes/MWFunctionTest.php @@ -1,27 +1,7 @@ <?php class MWFunctionTest extends MediaWikiTestCase { - function testCallUserFuncWorkarounds() { - $this->assertEquals( - call_user_func( array( 'MWFunctionTest', 'someMethod' ) ), - MWFunction::call( 'MWFunctionTest::someMethod' ) - ); - $this->assertEquals( - call_user_func( array( 'MWFunctionTest', 'someMethod' ), 'foo', 'bar', 'baz' ), - MWFunction::call( 'MWFunctionTest::someMethod', 'foo', 'bar', 'baz' ) - ); - - $this->assertEquals( - call_user_func_array( array( 'MWFunctionTest', 'someMethod' ), array() ), - MWFunction::callArray( 'MWFunctionTest::someMethod', array() ) - ); - $this->assertEquals( - call_user_func_array( array( 'MWFunctionTest', 'someMethod' ), array( 'foo', 'bar', 'baz' ) ), - MWFunction::callArray( 'MWFunctionTest::someMethod', array( 'foo', 'bar', 'baz' ) ) - ); - } - - function testNewObjFunction() { + public function testNewObjFunction() { $arg1 = 'Foo'; $arg2 = 'Bar'; $arg3 = array( 'Baz' ); @@ -34,32 +14,7 @@ class MWFunctionTest extends MediaWikiTestCase { MWFunction::newObj( 'MWBlankClass', $args )->args, $newObject->args ); - - $this->assertEquals( - MWFunction::newObj( 'MWBlankClass', $args, true )->args, - $newObject->args, - 'Works even with PHP version < 5.1.3' - ); - } - - /** - * @expectedException MWException - */ - function testCallingParentFails() { - MWFunction::call( 'parent::foo' ); } - - /** - * @expectedException MWException - */ - function testCallingSelfFails() { - MWFunction::call( 'self::foo' ); - } - - public static function someMethod() { - return func_get_args(); - } - } class MWBlankClass { diff --git a/tests/phpunit/includes/MWNamespaceTest.php b/tests/phpunit/includes/MWNamespaceTest.php index 45f8dafc..10e9db61 100644 --- a/tests/phpunit/includes/MWNamespaceTest.php +++ b/tests/phpunit/includes/MWNamespaceTest.php @@ -125,7 +125,6 @@ class MWNamespaceTest extends MediaWikiTestCase { public function testGetAssociated() { $this->assertEquals( NS_TALK, MWNamespace::getAssociated( NS_MAIN ) ); $this->assertEquals( NS_MAIN, MWNamespace::getAssociated( NS_TALK ) ); - } ### Exceptions with getAssociated() @@ -201,7 +200,6 @@ class MWNamespaceTest extends MediaWikiTestCase { NS_SPECIAL, NS_MEDIA, "NS_SPECIAL and NS_MEDIA are different subject namespaces" ); - } /** @@ -346,33 +344,32 @@ class MWNamespaceTest extends MediaWikiTestCase { $this->assertEquals( array( NS_MAIN ), - MWNamespace::getcontentNamespaces(), + MWNamespace::getContentNamespaces(), '$wgContentNamespaces is an array with only NS_MAIN by default' ); - # test !is_array( $wgcontentNamespaces ) $wgContentNamespaces = ''; - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); + $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); $wgContentNamespaces = false; - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); + $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); $wgContentNamespaces = null; - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); + $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); $wgContentNamespaces = 5; - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); + $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); # test $wgContentNamespaces === array() $wgContentNamespaces = array(); - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); + $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); # test !in_array( NS_MAIN, $wgContentNamespaces ) $wgContentNamespaces = array( NS_USER, NS_CATEGORY ); $this->assertEquals( array( NS_MAIN, NS_USER, NS_CATEGORY ), - MWNamespace::getcontentNamespaces(), + MWNamespace::getContentNamespaces(), 'NS_MAIN is forced in $wgContentNamespaces even if unwanted' ); @@ -380,13 +377,13 @@ class MWNamespaceTest extends MediaWikiTestCase { $wgContentNamespaces = array( NS_MAIN ); $this->assertEquals( array( NS_MAIN ), - MWNamespace::getcontentNamespaces() + MWNamespace::getContentNamespaces() ); $wgContentNamespaces = array( NS_MAIN, NS_USER, NS_CATEGORY ); $this->assertEquals( array( NS_MAIN, NS_USER, NS_CATEGORY ), - MWNamespace::getcontentNamespaces() + MWNamespace::getContentNamespaces() ); } diff --git a/tests/phpunit/includes/MessageTest.php b/tests/phpunit/includes/MessageTest.php index c378bb8e..1e18f975 100644 --- a/tests/phpunit/includes/MessageTest.php +++ b/tests/phpunit/includes/MessageTest.php @@ -10,7 +10,7 @@ class MessageTest extends MediaWikiLangTestCase { ) ); } - function testExists() { + public function testExists() { $this->assertTrue( wfMessage( 'mainpage' )->exists() ); $this->assertTrue( wfMessage( 'mainpage' )->params( array() )->exists() ); $this->assertTrue( wfMessage( 'mainpage' )->rawParams( 'foo', 123 )->exists() ); @@ -19,7 +19,7 @@ class MessageTest extends MediaWikiLangTestCase { $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->rawParams( 'foo', 123 )->exists() ); } - function testKey() { + public function testKey() { $this->assertInstanceOf( 'Message', wfMessage( 'mainpage' ) ); $this->assertInstanceOf( 'Message', wfMessage( 'i-dont-exist-evar' ) ); $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->text() ); @@ -28,47 +28,103 @@ class MessageTest extends MediaWikiLangTestCase { $this->assertEquals( '<i-dont-exist-evar>', wfMessage( 'i-dont-exist-evar' )->escaped() ); } - function testInLanguage() { + public function testInLanguage() { $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->inLanguage( 'en' )->text() ); $this->assertEquals( 'Заглавная страница', wfMessage( 'mainpage' )->inLanguage( 'ru' )->text() ); $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->inLanguage( Language::factory( 'en' ) )->text() ); $this->assertEquals( 'Заглавная страница', wfMessage( 'mainpage' )->inLanguage( Language::factory( 'ru' ) )->text() ); } - function testMessageParams() { + public function testMessageParams() { $this->assertEquals( 'Return to $1.', wfMessage( 'returnto' )->text() ); $this->assertEquals( 'Return to $1.', wfMessage( 'returnto', array() )->text() ); $this->assertEquals( 'You have foo (bar).', wfMessage( 'youhavenewmessages', 'foo', 'bar' )->text() ); $this->assertEquals( 'You have foo (bar).', wfMessage( 'youhavenewmessages', array( 'foo', 'bar' ) )->text() ); } - function testMessageParamSubstitution() { + public function testMessageParamSubstitution() { $this->assertEquals( '(Заглавная страница)', wfMessage( 'parentheses', 'Заглавная страница' )->plain() ); $this->assertEquals( '(Заглавная страница $1)', wfMessage( 'parentheses', 'Заглавная страница $1' )->plain() ); $this->assertEquals( '(Заглавная страница)', wfMessage( 'parentheses' )->rawParams( 'Заглавная страница' )->plain() ); $this->assertEquals( '(Заглавная страница $1)', wfMessage( 'parentheses' )->rawParams( 'Заглавная страница $1' )->plain() ); } - function testDeliciouslyManyParams() { + public function testDeliciouslyManyParams() { $msg = new RawMessage( '$1$2$3$4$5$6$7$8$9$10$11$12' ); // One less than above has placeholders $params = array( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k' ); $this->assertEquals( 'abcdefghijka2', $msg->params( $params )->plain(), 'Params > 9 are replaced correctly' ); } - function testInContentLanguage() { - global $wgLang, $wgForceUIMsgAsContentMsg; - $wgLang = Language::factory( 'fr' ); + /** + * FIXME: This should not need database, but Language#formatExpiry does (bug 55912) + * @group Database + */ + public function testMessageParamTypes() { + $lang = Language::factory( 'en' ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatNum( 123456.789 ), + $msg->inLanguage( $lang )->numParams( 123456.789 )->plain(), + 'numParams is handled correctly' + ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatDuration( 1234 ), + $msg->inLanguage( $lang )->durationParams( 1234 )->plain(), + 'durationParams is handled correctly' + ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatExpiry( wfTimestampNow() ), + $msg->inLanguage( $lang )->expiryParams( wfTimestampNow() )->plain(), + 'expiryParams is handled correctly' + ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatTimePeriod( 1234 ), + $msg->inLanguage( $lang )->timeperiodParams( 1234 )->plain(), + 'timeperiodParams is handled correctly' + ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatSize( 123456 ), + $msg->inLanguage( $lang )->sizeParams( 123456 )->plain(), + 'sizeParams is handled correctly' + ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatBitrate( 123456 ), + $msg->inLanguage( $lang )->bitrateParams( 123456 )->plain(), + 'bitrateParams is handled correctly' + ); + } + + public function testInContentLanguageDisabled() { + $this->setMwGlobals( 'wgLang', Language::factory( 'fr' ) ); $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->inContentLanguage()->plain(), 'ForceUIMsg disabled' ); - $wgForceUIMsgAsContentMsg['testInContentLanguage'] = 'mainpage'; + } + + public function testInContentLanguageEnabled() { + $this->setMwGlobals( array( + 'wgLang' => Language::factory( 'fr' ), + 'wgForceUIMsgAsContentMsg' => array( 'mainpage' ), + ) ); + $this->assertEquals( 'Accueil', wfMessage( 'mainpage' )->inContentLanguage()->plain(), 'ForceUIMsg enabled' ); } /** * @expectedException MWException */ - function testInLanguageThrows() { + public function testInLanguageThrows() { wfMessage( 'foo' )->inLanguage( 123 ); } } diff --git a/tests/phpunit/includes/OutputPageTest.php b/tests/phpunit/includes/OutputPageTest.php index 4084fb17..56bb0fce 100644 --- a/tests/phpunit/includes/OutputPageTest.php +++ b/tests/phpunit/includes/OutputPageTest.php @@ -19,7 +19,6 @@ class OutputPageTest extends MediaWikiTestCase { * * options['printableQuery'] - value of query string for printable, or omitted for none * options['handheldQuery'] - value of query string for handheld, or omitted for none - * options['handheldForIPhone'] - value of the $wgHandheldForIPhone global * options['media'] - passed into the method under the same name * options['expectedReturn'] - expected return value * options['message'] - PHPUnit message for assertion @@ -39,7 +38,6 @@ class OutputPageTest extends MediaWikiTestCase { $fauxRequest = new FauxRequest( $queryData, false ); $this->setMWGlobals( array( 'wgRequest' => $fauxRequest, - 'wgHandheldForIPhone' => $args['handheldForIPhone'] ) ); $actualReturn = OutputPage::transformCssMedia( $args['media'] ); @@ -47,50 +45,31 @@ class OutputPageTest extends MediaWikiTestCase { } /** - * Tests a case of transformCssMedia with both values of wgHandheldForIPhone. - * Used to verify that behavior is orthogonal to that option. - * - * If the value of wgHandheldForIPhone should matter, use assertTransformCssMediaCase. - * - * @param array $args key-value array of arguments as shown in assertTransformCssMediaCase. - * Will be mutated. - */ - protected function assertTransformCssMediaCaseWithBothHandheldForIPhone( $args ) { - $message = $args['message']; - foreach ( array( true, false ) as $handheldForIPhone ) { - $args['handheldForIPhone'] = $handheldForIPhone; - $stringHandheldForIPhone = var_export( $handheldForIPhone, true ); - $args['message'] = "$message. \$wgHandheldForIPhone was $stringHandheldForIPhone"; - $this->assertTransformCssMediaCase( $args ); - } - } - - /** * Tests print requests */ public function testPrintRequests() { - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'printableQuery' => '1', 'media' => 'screen', 'expectedReturn' => null, 'message' => 'On printable request, screen returns null' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'printableQuery' => '1', 'media' => self::SCREEN_MEDIA_QUERY, 'expectedReturn' => null, 'message' => 'On printable request, screen media query returns null' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'printableQuery' => '1', 'media' => self::SCREEN_ONLY_MEDIA_QUERY, 'expectedReturn' => null, 'message' => 'On printable request, screen media query with only returns null' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'printableQuery' => '1', 'media' => 'print', 'expectedReturn' => '', @@ -103,25 +82,30 @@ class OutputPageTest extends MediaWikiTestCase { */ public function testScreenRequests() { $this->assertTransformCssMediaCase( array( - 'handheldForIPhone' => false, 'media' => 'screen', 'expectedReturn' => 'screen', - 'message' => 'On screen request, with handheldForIPhone false, screen media type is preserved' + 'message' => 'On screen request, screen media type is preserved' + ) ); + + $this->assertTransformCssMediaCase( array( + 'media' => 'handheld', + 'expectedReturn' => 'handheld', + 'message' => 'On screen request, handheld media type is preserved' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'media' => self::SCREEN_MEDIA_QUERY, 'expectedReturn' => self::SCREEN_MEDIA_QUERY, 'message' => 'On screen request, screen media query is preserved.' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'media' => self::SCREEN_ONLY_MEDIA_QUERY, 'expectedReturn' => self::SCREEN_ONLY_MEDIA_QUERY, 'message' => 'On screen request, screen media query with only is preserved.' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'media' => 'print', 'expectedReturn' => 'print', 'message' => 'On screen request, print media type is preserved' @@ -129,44 +113,21 @@ class OutputPageTest extends MediaWikiTestCase { } /** - * Tests handheld and wgHandheldForIPhone behavior + * Tests handheld behavior */ public function testHandheld() { - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'handheldQuery' => '1', 'media' => 'handheld', 'expectedReturn' => '', 'message' => 'On request with handheld querystring and media is handheld, returns empty string' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'handheldQuery' => '1', 'media' => 'screen', 'expectedReturn' => null, 'message' => 'On request with handheld querystring and media is screen, returns null' ) ); - - // A bit counter-intuitively, $wgHandheldForIPhone should only matter if the query handheld is false or omitted - $this->assertTransformCssMediaCase( array( - 'handheldQuery' => '0', - 'media' => 'screen', - 'handheldForIPhone' => true, - 'expectedReturn' => 'screen and (min-device-width: 481px)', - 'message' => 'With $wgHandheldForIPhone true, screen media type is transformed' - ) ); - - $this->assertTransformCssMediaCase( array( - 'media' => 'handheld', - 'handheldForIPhone' => true, - 'expectedReturn' => 'handheld, only screen and (max-device-width: 480px)', - 'message' => 'With $wgHandheldForIPhone true, handheld media type is transformed' - ) ); - - $this->assertTransformCssMediaCase( array( - 'media' => 'handheld', - 'handheldForIPhone' => false, - 'expectedReturn' => 'handheld', - 'message' => 'With $wgHandheldForIPhone false, handheld media type is preserved' - ) ); } } diff --git a/tests/phpunit/includes/PathRouterTest.php b/tests/phpunit/includes/PathRouterTest.php index 22591873..adfb215a 100644 --- a/tests/phpunit/includes/PathRouterTest.php +++ b/tests/phpunit/includes/PathRouterTest.php @@ -1,10 +1,17 @@ <?php /** - * Tests for the PathRouter parsing + * Tests for the PathRouter parsing. + * + * @todo Add covers tags. */ class PathRouterTest extends MediaWikiTestCase { + /** + * @var PathRouter + */ + protected $basicRouter; + protected function setUp() { parent::setUp(); $router = new PathRouter; @@ -151,18 +158,20 @@ class PathRouterTest extends MediaWikiTestCase { $router->add( array( 'qwerty' => "/qwerty/$1" ), array( 'qwerty' => '$key' ) ); $router->add( "/$2/$1", array( 'restricted-to-y' => '$2' ), array( '$2' => 'y' ) ); - foreach ( array( - '/Foo' => array( 'title' => 'Foo' ), - '/Bar' => array( 'ping' => 'pong' ), - '/Baz' => array( 'marco' => 'polo' ), - '/asdf-foo' => array( 'title' => 'qwerty-foo' ), - '/qwerty-bar' => array( 'title' => 'asdf-bar' ), - '/a/Foo' => array( 'title' => 'Foo' ), - '/asdf/Foo' => array( 'title' => 'Foo' ), - '/qwerty/Foo' => array( 'title' => 'Foo', 'qwerty' => 'qwerty' ), - '/baz/Foo' => array( 'title' => 'Foo', 'unrestricted' => 'baz' ), - '/y/Foo' => array( 'title' => 'Foo', 'restricted-to-y' => 'y' ), - ) as $path => $result ) { + foreach ( + array( + '/Foo' => array( 'title' => 'Foo' ), + '/Bar' => array( 'ping' => 'pong' ), + '/Baz' => array( 'marco' => 'polo' ), + '/asdf-foo' => array( 'title' => 'qwerty-foo' ), + '/qwerty-bar' => array( 'title' => 'asdf-bar' ), + '/a/Foo' => array( 'title' => 'Foo' ), + '/asdf/Foo' => array( 'title' => 'Foo' ), + '/qwerty/Foo' => array( 'title' => 'Foo', 'qwerty' => 'qwerty' ), + '/baz/Foo' => array( 'title' => 'Foo', 'unrestricted' => 'baz' ), + '/y/Foo' => array( 'title' => 'Foo', 'restricted-to-y' => 'y' ), + ) as $path => $result + ) { $this->assertEquals( $router->parse( $path ), $result ); } } @@ -251,5 +260,4 @@ class PathRouterTest extends MediaWikiTestCase { $matches = $router->parse( "/wiki/Foo" ); $this->assertEquals( $matches, array( 'title' => 'bar%20$1' ) ); } - } diff --git a/tests/phpunit/includes/PreferencesTest.php b/tests/phpunit/includes/PreferencesTest.php index 7aa3c4a4..3dec2da0 100644 --- a/tests/phpunit/includes/PreferencesTest.php +++ b/tests/phpunit/includes/PreferencesTest.php @@ -4,11 +4,16 @@ * @group Database */ class PreferencesTest extends MediaWikiTestCase { - /** Array of User objects */ + /** + * @var User[] + */ private $prefUsers; + /** + * @var RequestContext + */ private $context; - function __construct() { + public function __construct() { parent::__construct(); $this->prefUsers['noemail'] = new User; @@ -30,14 +35,17 @@ class PreferencesTest extends MediaWikiTestCase { protected function setUp() { parent::setUp(); - $this->setMwGlobals( 'wgEnableEmail', true ); + $this->setMwGlobals( array( + 'wgEnableEmail' => true, + 'wgEmailAuthentication' => true, + ) ); } /** * Placeholder to verify bug 34302 * @covers Preferences::profilePreferences */ - function testEmailFieldsWhenUserHasNoEmail() { + public function testEmailFieldsWhenUserHasNoEmail() { $prefs = $this->prefsFor( 'noemail' ); $this->assertArrayHasKey( 'cssclass', $prefs['emailaddress'] @@ -49,7 +57,7 @@ class PreferencesTest extends MediaWikiTestCase { * Placeholder to verify bug 34302 * @covers Preferences::profilePreferences */ - function testEmailFieldsWhenUserEmailNotAuthenticated() { + public function testEmailFieldsWhenUserEmailNotAuthenticated() { $prefs = $this->prefsFor( 'notauth' ); $this->assertArrayHasKey( 'cssclass', $prefs['emailaddress'] @@ -61,7 +69,7 @@ class PreferencesTest extends MediaWikiTestCase { * Placeholder to verify bug 34302 * @covers Preferences::profilePreferences */ - function testEmailFieldsWhenUserEmailIsAuthenticated() { + public function testEmailFieldsWhenUserEmailIsAuthenticated() { $prefs = $this->prefsFor( 'auth' ); $this->assertArrayHasKey( 'cssclass', $prefs['emailaddress'] @@ -70,13 +78,14 @@ class PreferencesTest extends MediaWikiTestCase { } /** Helper */ - function prefsFor( $user_key ) { + protected function prefsFor( $user_key ) { $preferences = array(); Preferences::profilePreferences( $this->prefUsers[$user_key] , $this->context , $preferences ); + return $preferences; } } diff --git a/tests/phpunit/includes/Providers.php b/tests/phpunit/includes/Providers.php deleted file mode 100644 index 948b6354..00000000 --- a/tests/phpunit/includes/Providers.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * Generic providers for the MediaWiki PHPUnit test suite - * - * @author Antoine Musso - * @copyright Copyright © 2011, Antoine Musso - * @file - */ - -/** */ -class MediaWikiProvide { - - /* provide an array of numbers from 1 up to @param $num */ - private static function createProviderUpTo( $num ) { - $ret = array(); - for ( $i = 1; $i <= $num; $i++ ) { - $ret[] = array( $i ); - } - return $ret; - } - - /* array of months numbers (as an integer) */ - public static function Months() { - return self::createProviderUpTo( 12 ); - } - - /* array of days numbers (as an integer) */ - public static function Days() { - return self::createProviderUpTo( 31 ); - } - - public static function DaysMonths() { - $ret = array(); - - $months = self::Months(); - $days = self::Days(); - foreach ( $months as $month ) { - foreach ( $days as $day ) { - $ret[] = array( $day[0], $month[0] ); - } - } - return $ret; - } -} diff --git a/tests/phpunit/includes/RecentChangeTest.php b/tests/phpunit/includes/RecentChangeTest.php index a1e62363..cfa3e777 100644 --- a/tests/phpunit/includes/RecentChangeTest.php +++ b/tests/phpunit/includes/RecentChangeTest.php @@ -9,7 +9,7 @@ class RecentChangeTest extends MediaWikiTestCase { protected $user_comment; protected $context; - function __construct() { + public function __construct() { parent::__construct(); $this->title = Title::newFromText( 'SomeTitle' ); @@ -56,7 +56,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeBlock() { + public function testIrcMsgForLogTypeBlock() { $sep = $this->context->msg( 'colon-separator' )->text(); # block/block @@ -78,7 +78,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeDelete() { + public function testIrcMsgForLogTypeDelete() { $sep = $this->context->msg( 'colon-separator' )->text(); # delete/delete @@ -101,7 +101,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeNewusers() { + public function testIrcMsgForLogTypeNewusers() { $this->assertIRCComment( 'New user account', 'newusers', 'newusers', @@ -127,7 +127,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeMove() { + public function testIrcMsgForLogTypeMove() { $move_params = array( '4::target' => $this->target->getPrefixedText(), '5::noredir' => 0, @@ -154,7 +154,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypePatrol() { + public function testIrcMsgForLogTypePatrol() { # patrol/patrol $this->assertIRCComment( $this->context->msg( 'patrol-log-line', 'revision 777', '[[SomeTitle]]', '' )->plain(), @@ -170,7 +170,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeProtect() { + public function testIrcMsgForLogTypeProtect() { $protectParams = array( '[edit=sysop] (indefinite) [move=sysop] (indefinite)' ); @@ -204,7 +204,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeUpload() { + public function testIrcMsgForLogTypeUpload() { $sep = $this->context->msg( 'colon-separator' )->text(); # upload/upload @@ -225,24 +225,24 @@ class RecentChangeTest extends MediaWikiTestCase { } /** - * @todo: Emulate these edits somehow and extract + * @todo Emulate these edits somehow and extract * raw edit summary from RecentChange object * -- */ /* - function testIrcMsgForBlankingAES() { + public function testIrcMsgForBlankingAES() { // $this->context->msg( 'autosumm-blank', .. ); } - function testIrcMsgForReplaceAES() { + public function testIrcMsgForReplaceAES() { // $this->context->msg( 'autosumm-replace', .. ); } - function testIrcMsgForRollbackAES() { + public function testIrcMsgForRollbackAES() { // $this->context->msg( 'revertpage', .. ); } - function testIrcMsgForUndoAES() { + public function testIrcMsgForUndoAES() { // $this->context->msg( 'undo-summary', .. ); } */ @@ -251,10 +251,11 @@ class RecentChangeTest extends MediaWikiTestCase { * @param $expected String Expected IRC text without colors codes * @param $type String Log type (move, delete, suppress, patrol ...) * @param $action String A log type action + * @param $params * @param $comment String (optional) A comment for the log action * @param $msg String (optional) A message for PHPUnit :-) */ - function assertIRCComment( $expected, $type, $action, $params, $comment = null, $msg = '' ) { + protected function assertIRCComment( $expected, $type, $action, $params, $comment = null, $msg = '' ) { $logEntry = new ManualLogEntry( $type, $action ); $logEntry->setPerformer( $this->user ); @@ -267,8 +268,8 @@ class RecentChangeTest extends MediaWikiTestCase { $formatter = LogFormatter::newFromEntry( $logEntry ); $formatter->setContext( $this->context ); - // Apply the same transformation as done in RecentChange::getIRCLine for rc_comment - $ircRcComment = RecentChange::cleanupForIRC( $formatter->getIRCActionComment() ); + // Apply the same transformation as done in IRCColourfulRCFeedFormatter::getLine for rc_comment + $ircRcComment = IRCColourfulRCFeedFormatter::cleanupForIRC( $formatter->getIRCActionComment() ); $this->assertEquals( $expected, @@ -276,5 +277,4 @@ class RecentChangeTest extends MediaWikiTestCase { $msg ); } - } diff --git a/tests/phpunit/includes/RequestContextTest.php b/tests/phpunit/includes/RequestContextTest.php index f5871716..1776b5d5 100644 --- a/tests/phpunit/includes/RequestContextTest.php +++ b/tests/phpunit/includes/RequestContextTest.php @@ -7,6 +7,8 @@ class RequestContextTest extends MediaWikiTestCase { /** * Test the relationship between title and wikipage in RequestContext + * @covers RequestContext::getWikiPage + * @covers RequestContext::getTitle */ public function testWikiPageTitle() { $context = new RequestContext(); @@ -25,9 +27,11 @@ class RequestContextTest extends MediaWikiTestCase { $context->setTitle( $curTitle ); $this->assertTrue( $curTitle->equals( $context->getWikiPage()->getTitle() ), "When a title is updated the WikiPage should be purged and recreated on-demand with the new title." ); - } + /** + * @covers RequestContext::importScopedSession + */ public function testImportScopedSession() { $context = RequestContext::getMain(); @@ -58,7 +62,7 @@ class RequestContextTest extends MediaWikiTestCase { $this->assertEquals( $sinfo['userId'], $context->getUser()->getId(), "Correct context user ID." ); $this->assertEquals( 'UnitTestContextUser', $context->getUser()->getName(), "Correct context user name." ); - unset ( $sc ); // restore previous context + unset( $sc ); // restore previous context $info = $context->exportSession(); $this->assertEquals( $oInfo['ip'], $info['ip'], "Correct initial IP address." ); diff --git a/tests/phpunit/includes/ResourceLoaderTest.php b/tests/phpunit/includes/ResourceLoaderTest.php index 60618b10..ca8b2b6e 100644 --- a/tests/phpunit/includes/ResourceLoaderTest.php +++ b/tests/phpunit/includes/ResourceLoaderTest.php @@ -4,6 +4,32 @@ class ResourceLoaderTest extends MediaWikiTestCase { protected static $resourceLoaderRegisterModulesHook; + protected function setUp() { + parent::setUp(); + + // $wgResourceLoaderLESSFunctions, $wgResourceLoaderLESSImportPaths; $wgResourceLoaderLESSVars; + + $this->setMwGlobals( array( + 'wgResourceLoaderLESSFunctions' => array( + 'test-sum' => function ( $frame, $less ) { + $sum = 0; + foreach ( $frame[2] as $arg ) { + $sum += (int)$arg[1]; + } + return $sum; + }, + ), + 'wgResourceLoaderLESSImportPaths' => array( + dirname( __DIR__ ) . '/data/less/common', + ), + 'wgResourceLoaderLESSVars' => array( + 'foo' => '2px', + 'Foo' => '#eeeeee', + 'bar' => 5, + ), + ) ); + } + /* Hook Methods */ /** @@ -11,6 +37,7 @@ class ResourceLoaderTest extends MediaWikiTestCase { */ public static function resourceLoaderRegisterModules( &$resourceLoader ) { self::$resourceLoaderRegisterModulesHook = true; + return true; } @@ -21,6 +48,14 @@ class ResourceLoaderTest extends MediaWikiTestCase { ); } + public static function provideResourceLoaderContext() { + $resourceLoader = new ResourceLoader(); + $request = new FauxRequest(); + return array( + array( new ResourceLoaderContext( $resourceLoader, $request ) ), + ); + } + /* Test Methods */ /** @@ -31,6 +66,7 @@ class ResourceLoaderTest extends MediaWikiTestCase { self::$resourceLoaderRegisterModulesHook = false; $resourceLoader = new ResourceLoader(); $this->assertTrue( self::$resourceLoaderRegisterModulesHook ); + return $resourceLoader; } @@ -48,7 +84,22 @@ class ResourceLoaderTest extends MediaWikiTestCase { } /** + * @dataProvider provideResourceLoaderContext + * @covers ResourceLoaderFileModule::compileLessFile + */ + public function testLessFileCompilation( $context ) { + $basePath = __DIR__ . '/../data/less/module'; + $module = new ResourceLoaderFileModule( array( + 'localBasePath' => $basePath, + 'styles' => array( 'styles.less' ), + ) ); + $styles = $module->getStyles( $context ); + $this->assertStringEqualsFile( $basePath . '/styles.css', $styles['all'] ); + } + + /** * @dataProvider providePackedModules + * @covers ResourceLoader::makePackedModulesString */ public function testMakePackedModulesString( $desc, $modules, $packed ) { $this->assertEquals( $packed, ResourceLoader::makePackedModulesString( $modules ), $desc ); @@ -56,6 +107,7 @@ class ResourceLoaderTest extends MediaWikiTestCase { /** * @dataProvider providePackedModules + * @covers ResourceLoaderContext::expandModuleNames */ public function testexpandModuleNames( $desc, $modules, $packed ) { $this->assertEquals( $modules, ResourceLoaderContext::expandModuleNames( $packed ), $desc ); @@ -77,14 +129,20 @@ class ResourceLoaderTest extends MediaWikiTestCase { 'Regression fixed in r88706 with dotless names', array( 'foo', 'bar', 'baz' ), 'foo,bar,baz', - ) + ), + array( + 'Prefixless modules after a prefixed module', + array( 'single.module', 'foobar', 'foobaz' ), + 'single.module|foobar,foobaz', + ), ); } } /* Stubs */ -class ResourceLoaderTestModule extends ResourceLoaderModule {} +class ResourceLoaderTestModule extends ResourceLoaderModule { +} /* Hooks */ global $wgHooks; diff --git a/tests/phpunit/includes/RevisionStorageTest.php b/tests/phpunit/includes/RevisionStorageTest.php index e8d8db0a..e17c7b0f 100644 --- a/tests/phpunit/includes/RevisionStorageTest.php +++ b/tests/phpunit/includes/RevisionStorageTest.php @@ -17,7 +17,7 @@ class RevisionStorageTest extends MediaWikiTestCase { */ var $the_page; - function __construct( $name = null, array $data = array(), $dataName = '' ) { + function __construct( $name = null, array $data = array(), $dataName = '' ) { parent::__construct( $name, $data, $dataName ); $this->tablesUsed = array_merge( $this->tablesUsed, @@ -38,7 +38,7 @@ class RevisionStorageTest extends MediaWikiTestCase { 'iwlinks' ) ); } - public function setUp() { + protected function setUp() { global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang; parent::setUp(); @@ -365,7 +365,7 @@ class RevisionStorageTest extends MediaWikiTestCase { $page = $this->createPage( 'RevisionStorageTest_testIsCurrent', 'Lorem Ipsum', CONTENT_MODEL_WIKITEXT ); $rev1 = $page->getRevision(); - # @todo: find out if this should be true + # @todo find out if this should be true # $this->assertTrue( $rev1->isCurrent() ); $rev1x = Revision::newFromId( $rev1->getId() ); @@ -374,7 +374,7 @@ class RevisionStorageTest extends MediaWikiTestCase { $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ), 'second rev' ); $rev2 = $page->getRevision(); - # @todo: find out if this should be true + # @todo find out if this should be true # $this->assertTrue( $rev2->isCurrent() ); $rev1x = Revision::newFromId( $rev1->getId() ); @@ -456,15 +456,15 @@ class RevisionStorageTest extends MediaWikiTestCase { * @dataProvider provideUserWasLastToEdit */ public function testUserWasLastToEdit( $sinceIdx, $expectedLast ) { - $userA = \User::newFromName( "RevisionStorageTest_userA" ); - $userB = \User::newFromName( "RevisionStorageTest_userB" ); + $userA = User::newFromName( "RevisionStorageTest_userA" ); + $userB = User::newFromName( "RevisionStorageTest_userB" ); if ( $userA->getId() === 0 ) { - $userA = \User::createNew( $userA->getName() ); + $userA = User::createNew( $userA->getName() ); } if ( $userB->getId() === 0 ) { - $userB = \User::createNew( $userB->getName() ); + $userB = User::createNew( $userB->getName() ); } $ns = $this->getDefaultWikitextNS(); diff --git a/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php b/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php index 3948e345..4e83e355 100644 --- a/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php +++ b/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php @@ -6,14 +6,9 @@ * ^--- important, causes temporary tables to be used instead of the real database */ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest { - var $saveContentHandlerNoDB = null; - function setUp() { - global $wgContentHandlerUseDB; - - $this->saveContentHandlerNoDB = $wgContentHandlerUseDB; - - $wgContentHandlerUseDB = false; + protected function setUp() { + $this->setMwGlobals( 'wgContentHandlerUseDB', false ); $dbw = wfGetDB( DB_MASTER ); @@ -32,14 +27,6 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest { parent::setUp(); } - function tearDown() { - global $wgContentHandlerUseDB; - - parent::tearDown(); - - $wgContentHandlerUseDB = $this->saveContentHandlerNoDB; - } - /** * @covers Revision::selectFields */ @@ -76,7 +63,7 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest { */ public function testGetContentFormat() { try { - //@todo: change this to test failure on using a non-standard (but supported) format + // @todo change this to test failure on using a non-standard (but supported) format // for a content model supported in the given location. As of 1.21, there are // no alternative formats for any of the standard content models that could be // used for this though. @@ -91,5 +78,4 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest { $this->assertTrue( true ); // ok } } - } diff --git a/tests/phpunit/includes/RevisionTest.php b/tests/phpunit/includes/RevisionTest.php index db0245b9..b5819ff6 100644 --- a/tests/phpunit/includes/RevisionTest.php +++ b/tests/phpunit/includes/RevisionTest.php @@ -54,7 +54,10 @@ class RevisionTest extends MediaWikiTestCase { parent::tearDown(); } - function testGetRevisionText() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionText() { $row = new stdClass; $row->old_flags = ''; $row->old_text = 'This is a bunch of revision text.'; @@ -63,7 +66,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testGetRevisionTextGzip() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionTextGzip() { $this->checkPHPExtension( 'zlib' ); $row = new stdClass; @@ -74,7 +80,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testGetRevisionTextUtf8Native() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionTextUtf8Native() { $row = new stdClass; $row->old_flags = 'utf-8'; $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; @@ -84,7 +93,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testGetRevisionTextUtf8Legacy() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionTextUtf8Legacy() { $row = new stdClass; $row->old_flags = ''; $row->old_text = "Wiki est l'\xe9cole superieur !"; @@ -94,7 +106,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testGetRevisionTextUtf8NativeGzip() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionTextUtf8NativeGzip() { $this->checkPHPExtension( 'zlib' ); $row = new stdClass; @@ -106,7 +121,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testGetRevisionTextUtf8LegacyGzip() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionTextUtf8LegacyGzip() { $this->checkPHPExtension( 'zlib' ); $row = new stdClass; @@ -118,7 +136,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testCompressRevisionTextUtf8() { + /** + * @covers Revision::compressRevisionText + */ + public function testCompressRevisionTextUtf8() { $row = new stdClass; $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; $row->old_flags = Revision::compressRevisionText( $row->old_text ); @@ -132,11 +153,12 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ), "getRevisionText" ); } - function testCompressRevisionTextUtf8Gzip() { + /** + * @covers Revision::compressRevisionText + */ + public function testCompressRevisionTextUtf8Gzip() { $this->checkPHPExtension( 'zlib' ); - - global $wgCompressRevisions; - $wgCompressRevisions = true; + $this->setMwGlobals( 'wgCompressRevisions', true ); $row = new stdClass; $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; @@ -157,6 +179,8 @@ class RevisionTest extends MediaWikiTestCase { * @param string $text * @param string $title * @param string $model + * @param null $format + * * @return Revision */ function newTestRevision( $text, $title = "Test", $model = CONTENT_MODEL_WIKITEXT, $format = null ) { @@ -196,8 +220,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetContentModel + * @covers Revision::getContentModel */ - function testGetContentModel( $text, $title, $model, $format, $expectedModel ) { + public function testGetContentModel( $text, $title, $model, $format, $expectedModel ) { $rev = $this->newTestRevision( $text, $title, $model, $format ); $this->assertEquals( $expectedModel, $rev->getContentModel() ); @@ -216,8 +241,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetContentFormat + * @covers Revision::getContentFormat */ - function testGetContentFormat( $text, $title, $model, $format, $expectedFormat ) { + public function testGetContentFormat( $text, $title, $model, $format, $expectedFormat ) { $rev = $this->newTestRevision( $text, $title, $model, $format ); $this->assertEquals( $expectedFormat, $rev->getContentFormat() ); @@ -235,8 +261,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetContentHandler + * @covers Revision::getContentHandler */ - function testGetContentHandler( $text, $title, $model, $format, $expectedClass ) { + public function testGetContentHandler( $text, $title, $model, $format, $expectedClass ) { $rev = $this->newTestRevision( $text, $title, $model, $format ); $this->assertEquals( $expectedClass, get_class( $rev->getContentHandler() ) ); @@ -254,8 +281,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetContent + * @covers Revision::getContent */ - function testGetContent( $text, $title, $model, $format, $audience, $expectedSerialization ) { + public function testGetContent( $text, $title, $model, $format, $audience, $expectedSerialization ) { $rev = $this->newTestRevision( $text, $title, $model, $format ); $content = $rev->getContent( $audience ); @@ -274,8 +302,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetText + * @covers Revision::getText */ - function testGetText( $text, $title, $model, $format, $audience, $expectedText ) { + public function testGetText( $text, $title, $model, $format, $audience, $expectedText ) { $this->hideDeprecated( 'Revision::getText' ); $rev = $this->newTestRevision( $text, $title, $model, $format ); @@ -286,8 +315,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetText + * @covers Revision::getRawText */ - function testGetRawText( $text, $title, $model, $format, $audience, $expectedText ) { + public function testGetRawText( $text, $title, $model, $format, $audience, $expectedText ) { $this->hideDeprecated( 'Revision::getRawText' ); $rev = $this->newTestRevision( $text, $title, $model, $format ); @@ -330,6 +360,9 @@ class RevisionTest extends MediaWikiTestCase { $this->assertEquals( $expected_hash, $rev->getSha1() ); } + /** + * @covers Revision::__construct + */ public function testConstructWithText() { $this->hideDeprecated( "Revision::getText" ); @@ -344,6 +377,9 @@ class RevisionTest extends MediaWikiTestCase { $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() ); } + /** + * @covers Revision::__construct + */ public function testConstructWithContent() { $this->hideDeprecated( "Revision::getText" ); @@ -363,8 +399,9 @@ class RevisionTest extends MediaWikiTestCase { * Tests whether $rev->getContent() returns a clone when needed. * * @group Database + * @covers Revision::getContent */ - function testGetContentClone() { + public function testGetContentClone() { $content = new RevisionTestModifyableContent( "foo" ); $rev = new Revision( @@ -396,8 +433,9 @@ class RevisionTest extends MediaWikiTestCase { * Tests whether $rev->getContent() returns the same object repeatedly if appropriate. * * @group Database + * @covers Revision::getContent */ - function testGetContentUncloned() { + public function testGetContentUncloned() { $rev = $this->newTestRevision( "hello", "testGetContentUncloned_dummy", CONTENT_MODEL_WIKITEXT ); $content = $rev->getContent( Revision::RAW ); $content2 = $rev->getContent( Revision::RAW ); @@ -405,7 +443,6 @@ class RevisionTest extends MediaWikiTestCase { // for immutable content like wikitext, this should be the same object $this->assertSame( $content, $content2 ); } - } class RevisionTestModifyableContent extends TextContent { @@ -424,7 +461,6 @@ class RevisionTestModifyableContent extends TextContent { public function setText( $text ) { $this->mText = $text; } - } class RevisionTestModifyableContentHandler extends TextContentHandler { diff --git a/tests/phpunit/includes/SampleTest.php b/tests/phpunit/includes/SampleTest.php index 8a881915..8516a4ce 100644 --- a/tests/phpunit/includes/SampleTest.php +++ b/tests/phpunit/includes/SampleTest.php @@ -33,7 +33,7 @@ class TestSample extends MediaWikiLangTestCase { * "Agile Documentation" at * http://www.phpunit.de/manual/3.4/en/other-uses-for-tests.html */ - function testTitleObjectStringConversion() { + public function testTitleObjectStringConversion() { $title = Title::newFromText( "text" ); $this->assertInstanceOf( 'Title', $title, "Title creation" ); $this->assertEquals( "Text", $title, "Automatic string conversion" ); @@ -98,7 +98,7 @@ class TestSample extends MediaWikiLangTestCase { * @expectedException MWException object * See http://www.phpunit.de/manual/3.4/en/appendixes.annotations.html#appendixes.annotations.expectedException */ - function testTitleObjectFromObject() { + public function testTitleObjectFromObject() { $title = Title::newFromText( Title::newFromText( "test" ) ); $this->assertEquals( "Test", $title->isLocal() ); } diff --git a/tests/phpunit/includes/SanitizerTest.php b/tests/phpunit/includes/SanitizerTest.php index c0ed4a59..81246d33 100644 --- a/tests/phpunit/includes/SanitizerTest.php +++ b/tests/phpunit/includes/SanitizerTest.php @@ -1,5 +1,9 @@ <?php +/** + * @todo Tests covering decodeCharReferences can be refactored into a single + * method and dataprovider. + */ class SanitizerTest extends MediaWikiTestCase { protected function setUp() { @@ -8,7 +12,10 @@ class SanitizerTest extends MediaWikiTestCase { AutoLoader::loadClass( 'Sanitizer' ); } - function testDecodeNamedEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testDecodeNamedEntities() { $this->assertEquals( "\xc3\xa9cole", Sanitizer::decodeCharReferences( 'école' ), @@ -16,7 +23,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testDecodeNumericEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testDecodeNumericEntities() { $this->assertEquals( "\xc4\x88io bonas dans l'\xc3\xa9cole!", Sanitizer::decodeCharReferences( "Ĉio bonas dans l'école!" ), @@ -24,7 +34,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testDecodeMixedEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testDecodeMixedEntities() { $this->assertEquals( "\xc4\x88io bonas dans l'\xc3\xa9cole!", Sanitizer::decodeCharReferences( "Ĉio bonas dans l'école!" ), @@ -32,7 +45,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testDecodeMixedComplexEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testDecodeMixedComplexEntities() { $this->assertEquals( "\xc4\x88io bonas dans l'\xc3\xa9cole! (mais pas Ĉio dans l'école)", Sanitizer::decodeCharReferences( @@ -42,7 +58,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testInvalidAmpersand() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testInvalidAmpersand() { $this->assertEquals( 'a & b', Sanitizer::decodeCharReferences( 'a & b' ), @@ -50,7 +69,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testInvalidEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testInvalidEntities() { $this->assertEquals( '&foo;', Sanitizer::decodeCharReferences( '&foo;' ), @@ -58,7 +80,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testInvalidNumberedEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testInvalidNumberedEntities() { $this->assertEquals( UTF8_REPLACEMENT, Sanitizer::decodeCharReferences( "�" ), 'Invalid numbered entity' ); } @@ -69,10 +94,8 @@ class SanitizerTest extends MediaWikiTestCase { * @param String $tag Name of an HTML5 element (ie: 'video') * @param Boolean $escaped Wheter sanitizer let the tag in or escape it (ie: '<video>') */ - function testRemovehtmltagsOnHtml5Tags( $tag, $escaped ) { + public function testRemovehtmltagsOnHtml5Tags( $tag, $escaped ) { $this->setMwGlobals( array( - # Enable HTML5 mode - 'wgHtml5' => true, 'wgUseTidy' => false ) ); @@ -90,7 +113,7 @@ class SanitizerTest extends MediaWikiTestCase { /** * Provide HTML5 tags */ - function provideHtml5Tags() { + public static function provideHtml5Tags() { $ESCAPED = true; # We want tag to be escaped $VERBATIM = false; # We want to keep the tag return array( @@ -101,31 +124,57 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testSelfClosingTag() { - $this->setMwGlobals( array( - 'wgUseTidy' => false - ) ); - - $this->assertEquals( - '<div>Hello world</div>', - Sanitizer::removeHTMLtags( '<div>Hello world</div />' ), - 'Self-closing closing div' + function dataRemoveHTMLtags() { + return array( + // former testSelfClosingTag + array( + '<div>Hello world</div />', + '<div>Hello world</div>', + 'Self-closing closing div' + ), + // Make sure special nested HTML5 semantics are not broken + // http://www.whatwg.org/html/text-level-semantics.html#the-kbd-element + array( + '<kbd><kbd>Shift</kbd>+<kbd>F3</kbd></kbd>', + '<kbd><kbd>Shift</kbd>+<kbd>F3</kbd></kbd>', + 'Nested <kbd>.' + ), + // http://www.whatwg.org/html/text-level-semantics.html#the-sub-and-sup-elements + array( + '<var>x<sub><var>i</var></sub></var>, <var>y<sub><var>i</var></sub></var>', + '<var>x<sub><var>i</var></sub></var>, <var>y<sub><var>i</var></sub></var>', + 'Nested <var>.' + ), + // http://www.whatwg.org/html/text-level-semantics.html#the-dfn-element + array( + '<dfn><abbr title="Garage Door Opener">GDO</abbr></dfn>', + '<dfn><abbr title="Garage Door Opener">GDO</abbr></dfn>', + '<abbr> inside <dfn>', + ), ); } + /** + * @dataProvider dataRemoveHTMLtags + * @covers Sanitizer::removeHTMLtags + */ + public function testRemoveHTMLtags( $input, $output, $msg = null ) { + $GLOBALS['wgUseTidy'] = false; + $this->assertEquals( $output, Sanitizer::removeHTMLtags( $input ), $msg ); + } /** * @dataProvider provideTagAttributesToDecode * @covers Sanitizer::decodeTagAttributes */ - function testDecodeTagAttributes( $expected, $attributes, $message = '' ) { + public function testDecodeTagAttributes( $expected, $attributes, $message = '' ) { $this->assertEquals( $expected, Sanitizer::decodeTagAttributes( $attributes ), $message ); } - function provideTagAttributesToDecode() { + public static function provideTagAttributesToDecode() { return array( array( array( 'foo' => 'bar' ), 'foo=bar', 'Unquoted attribute' ), array( array( 'foo' => 'bar' ), ' foo = bar ', 'Spaced attribute' ), @@ -148,7 +197,6 @@ class SanitizerTest extends MediaWikiTestCase { array( array( 'foo.' => 'baz' ), 'foo.=baz', 'A . is allowed as last character' ), array( array( 'foo6' => 'baz' ), 'foo6=baz', 'Numbers are allowed' ), - # This bit is more relaxed than XML rules, but some extensions use # it, like ProofreadPage (see bug 27539) array( array( '1foo' => 'baz' ), '1foo=baz', 'Leading numbers are allowed' ), @@ -167,7 +215,7 @@ class SanitizerTest extends MediaWikiTestCase { * @dataProvider provideDeprecatedAttributes * @covers Sanitizer::fixTagAttributes */ - function testDeprecatedAttributesUnaltered( $inputAttr, $inputEl, $message = '' ) { + public function testDeprecatedAttributesUnaltered( $inputAttr, $inputEl, $message = '' ) { $this->assertEquals( " $inputAttr", Sanitizer::fixTagAttributes( $inputAttr, $inputEl ), $message @@ -195,7 +243,7 @@ class SanitizerTest extends MediaWikiTestCase { * @dataProvider provideCssCommentsFixtures * @covers Sanitizer::checkCss */ - function testCssCommentsChecking( $expected, $css, $message = '' ) { + public function testCssCommentsChecking( $expected, $css, $message = '' ) { $this->assertEquals( $expected, Sanitizer::checkCss( $css ), $message @@ -205,10 +253,14 @@ class SanitizerTest extends MediaWikiTestCase { public static function provideCssCommentsFixtures() { /** array( <expected>, <css>, [message] ) */ return array( - array( ' ', '/**/' ), + // Valid comments spanning entire input + array( '/**/', '/**/' ), + array( '/* comment */', '/* comment */' ), + // Weird stuff array( ' ', '/****/' ), - array( ' ', '/* comment */' ), - array( ' ', "\\2f\\2a foo \\2a\\2f", + array( ' ', '/* /* */' ), + array( 'display: block;', "display:/* foo */block;" ), + array( 'display: block;', "display:\\2f\\2a foo \\2a\\2f block;", 'Backslash-escaped comments must be stripped (bug 28450)' ), array( '', '/* unfinished comment structure', 'Remove anything after a comment-start token' ), @@ -229,7 +281,7 @@ class SanitizerTest extends MediaWikiTestCase { /** * Test for support or lack of support for specific attributes in the attribute whitelist. */ - function provideAttributeSupport() { + public static function provideAttributeSupport() { /** array( <attributes>, <expected>, <message> ) */ return array( array( 'div', ' role="presentation"', ' role="presentation"', 'Support for WAI-ARIA\'s role="presentation".' ), @@ -239,12 +291,12 @@ class SanitizerTest extends MediaWikiTestCase { /** * @dataProvider provideAttributeSupport + * @covers Sanitizer::fixTagAttributes */ - function testAttributeSupport( $tag, $attributes, $expected, $message ) { + public function testAttributeSupport( $tag, $attributes, $expected, $message ) { $this->assertEquals( $expected, Sanitizer::fixTagAttributes( $attributes, $tag ), $message ); } - } diff --git a/tests/phpunit/includes/SanitizerValidateEmailTest.php b/tests/phpunit/includes/SanitizerValidateEmailTest.php index fe0bc64e..f13e8382 100644 --- a/tests/phpunit/includes/SanitizerValidateEmailTest.php +++ b/tests/phpunit/includes/SanitizerValidateEmailTest.php @@ -1,5 +1,10 @@ <?php +/** + * @covers Sanitizer::validateEmail + * @TODO all test methods in this class should be refactored and... + * use a single test method and a single data provider... + */ class SanitizerValidateEmailTest extends MediaWikiTestCase { private function checkEmail( $addr, $expected = true, $msg = '' ) { @@ -22,54 +27,56 @@ class SanitizerValidateEmailTest extends MediaWikiTestCase { $this->checkEmail( $addr, false, $msg ); } - function testEmailWellKnownUserAtHostDotTldAreValid() { + public function testEmailWellKnownUserAtHostDotTldAreValid() { $this->valid( 'user@example.com' ); $this->valid( 'user@example.museum' ); } - function testEmailWithUpperCaseCharactersAreValid() { + public function testEmailWithUpperCaseCharactersAreValid() { $this->valid( 'USER@example.com' ); $this->valid( 'user@EXAMPLE.COM' ); $this->valid( 'user@Example.com' ); $this->valid( 'USER@eXAMPLE.com' ); } - function testEmailWithAPlusInUserName() { + public function testEmailWithAPlusInUserName() { $this->valid( 'user+sub@example.com' ); $this->valid( 'user+@example.com' ); } - function testEmailDoesNotNeedATopLevelDomain() { + public function testEmailDoesNotNeedATopLevelDomain() { $this->valid( "user@localhost" ); $this->valid( "FooBar@localdomain" ); $this->valid( "nobody@mycompany" ); } - function testEmailWithWhiteSpacesBeforeOrAfterAreInvalids() { + public function testEmailWithWhiteSpacesBeforeOrAfterAreInvalids() { $this->invalid( " user@host.com" ); $this->invalid( "user@host.com " ); $this->invalid( "\tuser@host.com" ); $this->invalid( "user@host.com\t" ); } - function testEmailWithWhiteSpacesAreInvalids() { + public function testEmailWithWhiteSpacesAreInvalids() { $this->invalid( "User user@host" ); $this->invalid( "first last@mycompany" ); $this->invalid( "firstlast@my company" ); } - // bug 26948 : comma were matched by an incorrect regexp range - function testEmailWithCommasAreInvalids() { + /** + * bug 26948 : comma were matched by an incorrect regexp range + */ + public function testEmailWithCommasAreInvalids() { $this->invalid( "user,foo@example.org" ); $this->invalid( "userfoo@ex,ample.org" ); } - function testEmailWithHyphens() { + public function testEmailWithHyphens() { $this->valid( "user-foo@example.org" ); $this->valid( "userfoo@ex-ample.org" ); } - function testEmailDomainCanNotBeginWithDot() { + public function testEmailDomainCanNotBeginWithDot() { $this->invalid( "user@." ); $this->invalid( "user@.localdomain" ); $this->invalid( "user@localdomain." ); @@ -78,19 +85,19 @@ class SanitizerValidateEmailTest extends MediaWikiTestCase { $this->invalid( ".@a............" ); } - function testEmailWithFunnyCharacters() { + public function testEmailWithFunnyCharacters() { $this->valid( "\$user!ex{this}@123.com" ); } - function testEmailTopLevelDomainCanBeNumerical() { + public function testEmailTopLevelDomainCanBeNumerical() { $this->valid( "user@example.1234" ); } - function testEmailWithoutAtSignIsInvalid() { + public function testEmailWithoutAtSignIsInvalid() { $this->invalid( 'useràexample.com' ); } - function testEmailWithOneCharacterDomainIsValid() { + public function testEmailWithOneCharacterDomainIsValid() { $this->valid( 'user@a' ); } } diff --git a/tests/phpunit/includes/SeleniumConfigurationTest.php b/tests/phpunit/includes/SeleniumConfigurationTest.php deleted file mode 100644 index 3422c90c..00000000 --- a/tests/phpunit/includes/SeleniumConfigurationTest.php +++ /dev/null @@ -1,222 +0,0 @@ -<?php - -class SeleniumConfigurationTest extends MediaWikiTestCase { - - /** - * The file where the test temporarity stores the selenium config. - * This should be cleaned up as part of teardown. - */ - private $tempFileName; - - /** - * String containing the a sample selenium settings - */ - private $testConfig0 = ' -[SeleniumSettings] -browsers[firefox] = "*firefox" -browsers[iexplorer] = "*iexploreproxy" -browsers[chrome] = "*chrome" -host = "localhost" -port = "foobarr" -wikiUrl = "http://localhost/deployment" -username = "xxxxxxx" -userPassword = "" -testBrowser = "chrome" -startserver = -stopserver = -jUnitLogFile = -runAgainstGrid = false - -[SeleniumTests] -testSuite[SimpleSeleniumTestSuite] = "tests/selenium/SimpleSeleniumTestSuite.php" -testSuite[TestSuiteName] = "testSuitePath" -'; - /** - * Array of expected browsers from $testConfig0 - */ - private $testBrowsers0 = array( 'firefox' => '*firefox', - 'iexplorer' => '*iexploreproxy', - 'chrome' => '*chrome' - ); - /** - * Array of expected selenium settings from $testConfig0 - */ - private $testSettings0 = array( - 'host' => 'localhost', - 'port' => 'foobarr', - 'wikiUrl' => 'http://localhost/deployment', - 'username' => 'xxxxxxx', - 'userPassword' => '', - 'testBrowser' => 'chrome', - 'startserver' => null, - 'stopserver' => null, - 'seleniumserverexecpath' => null, - 'jUnitLogFile' => null, - 'runAgainstGrid' => null - ); - /** - * Array of expected testSuites from $testConfig0 - */ - private $testSuites0 = array( - 'SimpleSeleniumTestSuite' => 'tests/selenium/SimpleSeleniumTestSuite.php', - 'TestSuiteName' => 'testSuitePath' - ); - - /** - * Another sample selenium settings file contents - */ - private $testConfig1 = - ' -[SeleniumSettings] -host = "localhost" -testBrowser = "firefox" -'; - /** - * Expected browsers from $testConfig1 - */ - private $testBrowsers1 = null; - /** - * Expected selenium settings from $testConfig1 - */ - private $testSettings1 = array( - 'host' => 'localhost', - 'port' => null, - 'wikiUrl' => null, - 'username' => null, - 'userPassword' => null, - 'testBrowser' => 'firefox', - 'startserver' => null, - 'stopserver' => null, - 'seleniumserverexecpath' => null, - 'jUnitLogFile' => null, - 'runAgainstGrid' => null - ); - /** - * Expected test suites from $testConfig1 - */ - private $testSuites1 = null; - - - protected function setUp() { - parent::setUp(); - if ( !defined( 'SELENIUMTEST' ) ) { - define( 'SELENIUMTEST', true ); - } - } - - /** - * Clean up the temporary file used to store the selenium settings. - */ - protected function tearDown() { - if ( strlen( $this->tempFileName ) > 0 ) { - unlink( $this->tempFileName ); - unset( $this->tempFileName ); - } - parent::tearDown(); - } - - /** - * @expectedException MWException - * @group SeleniumFramework - */ - public function testErrorOnIncorrectConfigFile() { - $seleniumSettings = array(); - $seleniumBrowsers = array(); - $seleniumTestSuites = array(); - - SeleniumConfig::getSeleniumSettings( $seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites, - "Some_fake_settings_file.ini" ); - } - - /** - * @expectedException MWException - * @group SeleniumFramework - */ - public function testErrorOnMissingConfigFile() { - $seleniumSettings = array(); - $seleniumBrowsers = array(); - $seleniumTestSuites = array(); - global $wgSeleniumConfigFile; - $wgSeleniumConfigFile = ''; - SeleniumConfig::getSeleniumSettings( $seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites ); - } - - /** - * @group SeleniumFramework - */ - public function testUsesGlobalVarForConfigFile() { - $seleniumSettings = array(); - $seleniumBrowsers = array(); - $seleniumTestSuites = array(); - global $wgSeleniumConfigFile; - $this->writeToTempFile( $this->testConfig0 ); - $wgSeleniumConfigFile = $this->tempFileName; - SeleniumConfig::getSeleniumSettings( $seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites ); - $this->assertEquals( $seleniumSettings, $this->testSettings0, - 'The selenium settings should have been read from the file defined in $wgSeleniumConfigFile' - ); - $this->assertEquals( $seleniumBrowsers, $this->testBrowsers0, - 'The available browsers should have been read from the file defined in $wgSeleniumConfigFile' - ); - $this->assertEquals( $seleniumTestSuites, $this->testSuites0, - 'The test suites should have been read from the file defined in $wgSeleniumConfigFile' - ); - } - - /** - * @group SeleniumFramework - * @dataProvider sampleConfigs - */ - public function testgetSeleniumSettings( $sampleConfig, $expectedSettings, $expectedBrowsers, $expectedSuites ) { - $this->writeToTempFile( $sampleConfig ); - $seleniumSettings = array(); - $seleniumBrowsers = array(); - $seleniumTestSuites = null; - - SeleniumConfig::getSeleniumSettings( $seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites, - $this->tempFileName ); - - $this->assertEquals( $seleniumSettings, $expectedSettings, - "The selenium settings for the following test configuration was not retrieved correctly" . $sampleConfig - ); - $this->assertEquals( $seleniumBrowsers, $expectedBrowsers, - "The available browsers for the following test configuration was not retrieved correctly" . $sampleConfig - ); - $this->assertEquals( $seleniumTestSuites, $expectedSuites, - "The test suites for the following test configuration was not retrieved correctly" . $sampleConfig - ); - } - - /** - * create a temp file and write text to it. - * @param $testToWrite the text to write to the temp file - */ - private function writeToTempFile( $textToWrite ) { - $this->tempFileName = tempnam( sys_get_temp_dir(), 'test_settings.' ); - $tempFile = fopen( $this->tempFileName, "w" ); - fwrite( $tempFile, $textToWrite ); - fclose( $tempFile ); - } - - /** - * Returns an array containing: - * The contents of the selenium cingiguration ini file - * The expected selenium configuration array that getSeleniumSettings should return - * The expected available browsers array that getSeleniumSettings should return - * The expected test suites arrya that getSeleniumSettings should return - */ - public function sampleConfigs() { - return array( - array( $this->testConfig0, $this->testSettings0, $this->testBrowsers0, $this->testSuites0 ), - array( $this->testConfig1, $this->testSettings1, $this->testBrowsers1, $this->testSuites1 ) - ); - } -} diff --git a/tests/phpunit/includes/SiteConfigurationTest.php b/tests/phpunit/includes/SiteConfigurationTest.php index fc7d8d09..053d8a7d 100644 --- a/tests/phpunit/includes/SiteConfigurationTest.php +++ b/tests/phpunit/includes/SiteConfigurationTest.php @@ -10,6 +10,7 @@ function getSiteParams( $conf, $wiki ) { break; } } + return array( 'suffix' => $site, 'lang' => $lang, @@ -23,14 +24,18 @@ function getSiteParams( $conf, $wiki ) { } class SiteConfigurationTest extends MediaWikiTestCase { - var $mConf; + + /** + * @var SiteConfiguration + */ + protected $mConf; protected function setUp() { parent::setUp(); $this->mConf = new SiteConfiguration; - $this->mConf->suffixes = array( 'wiki' ); + $this->mConf->suffixes = array( 'wikipedia' => 'wiki' ); $this->mConf->wikis = array( 'enwiki', 'dewiki', 'frwiki' ); $this->mConf->settings = array( 'simple' => array( @@ -94,7 +99,10 @@ class SiteConfigurationTest extends MediaWikiTestCase { $GLOBALS['global'] = array( 'global' => 'global' ); } - function testSiteFromDb() { + /** + * @covers SiteConfiguration::siteFromDB + */ + public function testSiteFromDb() { $this->assertEquals( array( 'wikipedia', 'en' ), $this->mConf->siteFromDB( 'enwiki' ), @@ -119,7 +127,10 @@ class SiteConfigurationTest extends MediaWikiTestCase { ); } - function testGetLocalDatabases() { + /** + * @covers SiteConfiguration::getLocalDatabases + */ + public function testGetLocalDatabases() { $this->assertEquals( array( 'enwiki', 'dewiki', 'frwiki' ), $this->mConf->getLocalDatabases(), @@ -127,7 +138,10 @@ class SiteConfigurationTest extends MediaWikiTestCase { ); } - function testGetConfVariables() { + /** + * @covers SiteConfiguration::get + */ + public function testGetConfVariables() { $this->assertEquals( 'enwiki', $this->mConf->get( 'simple', 'enwiki', 'wiki' ), @@ -239,7 +253,10 @@ class SiteConfigurationTest extends MediaWikiTestCase { ); } - function testSiteFromDbWithCallback() { + /** + * @covers SiteConfiguration::siteFromDB + */ + public function testSiteFromDbWithCallback() { $this->mConf->siteParamsCallback = 'getSiteParams'; $this->assertEquals( @@ -259,7 +276,10 @@ class SiteConfigurationTest extends MediaWikiTestCase { ); } - function testParameterReplacement() { + /** + * @covers SiteConfiguration::get + */ + public function testParameterReplacement() { $this->mConf->siteParamsCallback = 'getSiteParams'; $this->assertEquals( @@ -289,7 +309,10 @@ class SiteConfigurationTest extends MediaWikiTestCase { ); } - function testGetAllGlobals() { + /** + * @covers SiteConfiguration::getAll + */ + public function testGetAllGlobals() { $this->mConf->siteParamsCallback = 'getSiteParams'; $getall = array( diff --git a/tests/phpunit/includes/StringUtilsTest.php b/tests/phpunit/includes/StringUtilsTest.php index db3d2655..89759e5c 100644 --- a/tests/phpunit/includes/StringUtilsTest.php +++ b/tests/phpunit/includes/StringUtilsTest.php @@ -3,13 +3,13 @@ class StringUtilsTest extends MediaWikiTestCase { /** - * This test StringUtils::isUtf8 whenever we have mbstring extension + * This tests StringUtils::isUtf8 whenever we have the mbstring extension * loaded. * * @covers StringUtils::isUtf8 * @dataProvider provideStringsForIsUtf8Check */ - function testIsUtf8WithMbstring( $expected, $string ) { + public function testIsUtf8WithMbstring( $expected, $string ) { if ( !function_exists( 'mb_check_encoding' ) ) { $this->markTestSkipped( 'Test requires the mbstring PHP extension' ); } @@ -20,16 +20,16 @@ class StringUtilsTest extends MediaWikiTestCase { } /** - * This test StringUtils::isUtf8 making sure we use the pure PHP + * This tests StringUtils::isUtf8 making sure we use the pure PHP * implementation used as a fallback when mb_check_encoding() is * not available. * * @covers StringUtils::isUtf8 * @dataProvider provideStringsForIsUtf8Check */ - function testIsUtf8WithPhpFallbackImplementation( $expected, $string ) { + public function testIsUtf8WithPhpFallbackImplementation( $expected, $string ) { $this->assertEquals( $expected, - StringUtils::isUtf8( $string, /** disable mbstring: */ true ), + StringUtils::isUtf8( $string, /** disable mbstring: */true ), 'Testing string "' . $this->escaped( $string ) . '" with pure PHP implementation' ); } @@ -49,6 +49,7 @@ class StringUtilsTest extends MediaWikiTestCase { $escaped .= $char; } } + return $escaped; } @@ -57,87 +58,90 @@ class StringUtilsTest extends MediaWikiTestCase { * Markus Kuhn: * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt */ - function provideStringsForIsUtf8Check() { + public static function provideStringsForIsUtf8Check() { // Expected return values for StringUtils::isUtf8() $PASS = true; $FAIL = false; return array( - array( $PASS, 'Some ASCII' ), - array( $PASS, "Euro sign €" ), - - # First possible sequences - array( $PASS, "\x00" ), - array( $PASS, "\xc2\x80" ), - array( $PASS, "\xe0\xa0\x80" ), - array( $PASS, "\xf0\x90\x80\x80" ), - array( $PASS, "\xf8\x88\x80\x80\x80" ), - array( $PASS, "\xfc\x84\x80\x80\x80\x80" ), - - # Last possible sequence - array( $PASS, "\x7f" ), - array( $PASS, "\xdf\xbf" ), - array( $PASS, "\xef\xbf\xbf" ), - array( $PASS, "\xf7\xbf\xbf\xbf" ), - array( $PASS, "\xfb\xbf\xbf\xbf\xbf" ), - array( $FAIL, "\xfd\xbf\xbf\xbf\xbf\xbf" ), - - # boundaries: - array( $PASS, "\xed\x9f\xbf" ), - array( $PASS, "\xee\x80\x80" ), - array( $PASS, "\xef\xbf\xbd" ), - array( $PASS, "\xf4\x8f\xbf\xbf" ), - array( $PASS, "\xf4\x90\x80\x80" ), - - # Malformed - array( $FAIL, "\x80" ), - array( $FAIL, "\xBF" ), - array( $FAIL, "\x80\xbf" ), - array( $FAIL, "\x80\xbf\x80" ), - array( $FAIL, "\x80\xbf\x80\xbf" ), - array( $FAIL, "\x80\xbf\x80\xbf\x80" ), - array( $FAIL, "\x80\xbf\x80\xbf\x80\xbf" ), - array( $FAIL, "\x80\xbf\x80\xbf\x80\xbf\x80" ), - - # last byte missing - array( $FAIL, "\xc0" ), - array( $FAIL, "\xe0\x80" ), - array( $FAIL, "\xf0\x80\x80" ), - array( $FAIL, "\xf8\x80\x80\x80" ), - array( $FAIL, "\xfc\x80\x80\x80\x80" ), - array( $FAIL, "\xdf" ), - array( $FAIL, "\xef\xbf" ), - array( $FAIL, "\xf7\xbf\xbf" ), - array( $FAIL, "\xfb\xbf\xbf\xbf" ), - array( $FAIL, "\xfd\xbf\xbf\xbf\xbf" ), - - # impossible bytes - array( $FAIL, "\xfe" ), - array( $FAIL, "\xff" ), - array( $FAIL, "\xfe\xfe\xff\xff" ), - - /** - # The PHP implementation does not handle characters - # being represented in a form which is too long :( - - # overlong sequences - array( $FAIL, "\xc0\xaf" ), - array( $FAIL, "\xe0\x80\xaf" ), - array( $FAIL, "\xf0\x80\x80\xaf" ), - array( $FAIL, "\xf8\x80\x80\x80\xaf" ), - array( $FAIL, "\xfc\x80\x80\x80\x80\xaf" ), - - # Maximum overlong sequences - array( $FAIL, "\xc1\xbf" ), - array( $FAIL, "\xe0\x9f\xbf" ), - array( $FAIL, "\xf0\x8F\xbf\xbf" ), - array( $FAIL, "\xf8\x87\xbf\xbf" ), - array( $FAIL, "\xfc\x83\xbf\xbf\xbf\xbf" ), - **/ - - # non characters - array( $PASS, "\xef\xbf\xbe" ), - array( $PASS, "\xef\xbf\xbf" ), + 'some ASCII' => array( $PASS, 'Some ASCII' ), + 'euro sign' => array( $PASS, "Euro sign €" ), + + 'first possible sequence 1 byte' => array( $PASS, "\x00" ), + 'first possible sequence 2 bytes' => array( $PASS, "\xc2\x80" ), + 'first possible sequence 3 bytes' => array( $PASS, "\xe0\xa0\x80" ), + 'first possible sequence 4 bytes' => array( $PASS, "\xf0\x90\x80\x80" ), + 'first possible sequence 5 bytes' => array( $FAIL, "\xf8\x88\x80\x80\x80" ), + 'first possible sequence 6 bytes' => array( $FAIL, "\xfc\x84\x80\x80\x80\x80" ), + + 'last possible sequence 1 byte' => array( $PASS, "\x7f" ), + 'last possible sequence 2 bytes' => array( $PASS, "\xdf\xbf" ), + 'last possible sequence 3 bytes' => array( $PASS, "\xef\xbf\xbf" ), + 'last possible sequence 4 bytes (U+1FFFFF)' => array( $FAIL, "\xf7\xbf\xbf\xbf" ), + 'last possible sequence 5 bytes' => array( $FAIL, "\xfb\xbf\xbf\xbf\xbf" ), + 'last possible sequence 6 bytes' => array( $FAIL, "\xfd\xbf\xbf\xbf\xbf\xbf" ), + + 'boundary 1' => array( $PASS, "\xed\x9f\xbf" ), + 'boundary 2' => array( $PASS, "\xee\x80\x80" ), + 'boundary 3' => array( $PASS, "\xef\xbf\xbd" ), + 'boundary 4' => array( $PASS, "\xf2\x80\x80\x80" ), + 'boundary 5 (U+FFFFF)' => array( $PASS, "\xf3\xbf\xbf\xbf" ), + 'boundary 6 (U+100000)' => array( $PASS, "\xf4\x80\x80\x80" ), + 'boundary 7 (U+10FFFF)' => array( $PASS, "\xf4\x8f\xbf\xbf" ), + 'boundary 8 (U+110000)' => array( $FAIL, "\xf4\x90\x80\x80" ), + + 'malformed 1' => array( $FAIL, "\x80" ), + 'malformed 2' => array( $FAIL, "\xbf" ), + 'malformed 3' => array( $FAIL, "\x80\xbf" ), + 'malformed 4' => array( $FAIL, "\x80\xbf\x80" ), + 'malformed 5' => array( $FAIL, "\x80\xbf\x80\xbf" ), + 'malformed 6' => array( $FAIL, "\x80\xbf\x80\xbf\x80" ), + 'malformed 7' => array( $FAIL, "\x80\xbf\x80\xbf\x80\xbf" ), + 'malformed 8' => array( $FAIL, "\x80\xbf\x80\xbf\x80\xbf\x80" ), + + 'last byte missing 1' => array( $FAIL, "\xc0" ), + 'last byte missing 2' => array( $FAIL, "\xe0\x80" ), + 'last byte missing 3' => array( $FAIL, "\xf0\x80\x80" ), + 'last byte missing 4' => array( $FAIL, "\xf8\x80\x80\x80" ), + 'last byte missing 5' => array( $FAIL, "\xfc\x80\x80\x80\x80" ), + 'last byte missing 6' => array( $FAIL, "\xdf" ), + 'last byte missing 7' => array( $FAIL, "\xef\xbf" ), + 'last byte missing 8' => array( $FAIL, "\xf7\xbf\xbf" ), + 'last byte missing 9' => array( $FAIL, "\xfb\xbf\xbf\xbf" ), + 'last byte missing 10' => array( $FAIL, "\xfd\xbf\xbf\xbf\xbf" ), + + 'extra continuation byte 1' => array( $FAIL, "e\xaf" ), + 'extra continuation byte 2' => array( $FAIL, "\xc3\x89\xaf" ), + 'extra continuation byte 3' => array( $FAIL, "\xef\xbc\xa5\xaf" ), + 'extra continuation byte 4' => array( $FAIL, "\xf0\x9d\x99\xb4\xaf" ), + + 'impossible bytes 1' => array( $FAIL, "\xfe" ), + 'impossible bytes 2' => array( $FAIL, "\xff" ), + 'impossible bytes 3' => array( $FAIL, "\xfe\xfe\xff\xff" ), + + 'overlong sequences 1' => array( $FAIL, "\xc0\xaf" ), + 'overlong sequences 2' => array( $FAIL, "\xc1\xaf" ), + 'overlong sequences 3' => array( $FAIL, "\xe0\x80\xaf" ), + 'overlong sequences 4' => array( $FAIL, "\xf0\x80\x80\xaf" ), + 'overlong sequences 5' => array( $FAIL, "\xf8\x80\x80\x80\xaf" ), + 'overlong sequences 6' => array( $FAIL, "\xfc\x80\x80\x80\x80\xaf" ), + + 'maximum overlong sequences 1' => array( $FAIL, "\xc1\xbf" ), + 'maximum overlong sequences 2' => array( $FAIL, "\xe0\x9f\xbf" ), + 'maximum overlong sequences 3' => array( $FAIL, "\xf0\x8f\xbf\xbf" ), + 'maximum overlong sequences 4' => array( $FAIL, "\xf8\x87\xbf\xbf" ), + 'maximum overlong sequences 5' => array( $FAIL, "\xfc\x83\xbf\xbf\xbf\xbf" ), + + 'surrogates 1 (U+D799)' => array( $PASS, "\xed\x9f\xbf" ), + 'surrogates 2 (U+E000)' => array( $PASS, "\xee\x80\x80" ), + 'surrogates 3 (U+D800)' => array( $FAIL, "\xed\xa0\x80" ), + 'surrogates 4 (U+DBFF)' => array( $FAIL, "\xed\xaf\xbf" ), + 'surrogates 5 (U+DC00)' => array( $FAIL, "\xed\xb0\x80" ), + 'surrogates 6 (U+DFFF)' => array( $FAIL, "\xed\xbf\xbf" ), + 'surrogates 7 (U+D800 U+DC00)' => array( $FAIL, "\xed\xa0\x80\xed\xb0\x80" ), + + 'noncharacters 1' => array( $PASS, "\xef\xbf\xbe" ), + 'noncharacters 2' => array( $PASS, "\xef\xbf\xbf" ), ); } } diff --git a/tests/phpunit/includes/TemplateCategoriesTest.php b/tests/phpunit/includes/TemplateCategoriesTest.php index a793babb..fb63a564 100644 --- a/tests/phpunit/includes/TemplateCategoriesTest.php +++ b/tests/phpunit/includes/TemplateCategoriesTest.php @@ -7,20 +7,37 @@ require __DIR__ . "/../../../maintenance/runJobs.php"; class TemplateCategoriesTest extends MediaWikiLangTestCase { - function testTemplateCategories() { + /** + * @covers Title::getParentCategories + */ + public function testTemplateCategories() { $title = Title::newFromText( "Categorized from template" ); $page = WikiPage::factory( $title ); $user = new User(); $user->mRights = array( 'createpage', 'edit', 'purge' ); - $status = $page->doEditContent( new WikitextContent( '{{Categorising template}}' ), 'Create a page with a template', 0, false, $user ); + $page->doEditContent( + new WikitextContent( '{{Categorising template}}' ), + 'Create a page with a template', + 0, + false, + $user + ); + $this->assertEquals( array() , $title->getParentCategories() ); $template = WikiPage::factory( Title::newFromText( 'Template:Categorising template' ) ); - $status = $template->doEditContent( new WikitextContent( '[[Category:Solved bugs]]' ), 'Add a category through a template', 0, false, $user ); + + $template->doEditContent( + new WikitextContent( '[[Category:Solved bugs]]' ), + 'Add a category through a template', + 0, + false, + $user + ); // Run the job queue JobQueueGroup::destroySingletons(); @@ -33,5 +50,4 @@ class TemplateCategoriesTest extends MediaWikiLangTestCase { , $title->getParentCategories() ); } - } diff --git a/tests/phpunit/includes/TestUser.php b/tests/phpunit/includes/TestUser.php index c4d89455..23e65031 100644 --- a/tests/phpunit/includes/TestUser.php +++ b/tests/phpunit/includes/TestUser.php @@ -1,6 +1,8 @@ <?php -/* Wraps the user object, so we can also retain full access to properties like password if we log in via the API */ +/** + * Wraps the user object, so we can also retain full access to properties like password if we log in via the API + */ class TestUser { public $username; public $password; @@ -8,7 +10,7 @@ class TestUser { public $groups; public $user; - function __construct( $username, $realname = 'Real Name', $email = 'sample@example.com', $groups = array() ) { + public function __construct( $username, $realname = 'Real Name', $email = 'sample@example.com', $groups = array() ) { $this->username = $username; $this->realname = $realname; $this->email = $email; @@ -53,6 +55,5 @@ class TestUser { } } $this->user->saveSettings(); - } } diff --git a/tests/phpunit/includes/TimeAdjustTest.php b/tests/phpunit/includes/TimeAdjustTest.php index a58702b2..0b368c25 100644 --- a/tests/phpunit/includes/TimeAdjustTest.php +++ b/tests/phpunit/includes/TimeAdjustTest.php @@ -4,22 +4,28 @@ class TimeAdjustTest extends MediaWikiLangTestCase { protected function setUp() { parent::setUp(); - $this->setMwGlobals( array( - 'wgLocalTZoffset' => null, - 'wgContLang' => Language::factory( 'en' ), - 'wgLanguageCode' => 'en', - ) ); - $this->iniSet( 'precision', 15 ); } - # Test offset usage for a given language::userAdjust - function testUserAdjust() { - global $wgLocalTZoffset, $wgContLang; + /** + * Test offset usage for a given Language::userAdjust + * @dataProvider dataUserAdjust + * @covers Language::userAdjust + */ + public function testUserAdjust( $date, $localTZoffset, $expected ) { + global $wgContLang; + + $this->setMwGlobals( 'wgLocalTZoffset', $localTZoffset ); - # Collection of parameters for Language_t_Offset. - # Format: date to be formatted, localTZoffset value, expected date - $userAdjust_tests = array( + $this->assertEquals( + strval( $expected ), + strval( $wgContLang->userAdjust( $date, '' ) ), + "User adjust {$date} by {$localTZoffset} minutes should give {$expected}" + ); + } + + public static function dataUserAdjust() { + return array( array( 20061231235959, 0, 20061231235959 ), array( 20061231235959, 5, 20070101000459 ), array( 20061231235959, 15, 20070101001459 ), @@ -31,15 +37,5 @@ class TimeAdjustTest extends MediaWikiLangTestCase { array( 20061231235959, -30, 20061231232959 ), array( 20061231235959, -60, 20061231225959 ), ); - - foreach ( $userAdjust_tests as $data ) { - $wgLocalTZoffset = $data[1]; - - $this->assertEquals( - strval( $data[2] ), - strval( $wgContLang->userAdjust( $data[0], '' ) ), - "User adjust {$data[0]} by {$data[1]} minutes should give {$data[2]}" - ); - } } } diff --git a/tests/phpunit/includes/TimestampTest.php b/tests/phpunit/includes/TimestampTest.php index 0690683a..53388392 100644 --- a/tests/phpunit/includes/TimestampTest.php +++ b/tests/phpunit/includes/TimestampTest.php @@ -3,23 +3,20 @@ /** * Tests timestamp parsing and output. */ -class TimestampTest extends MediaWikiTestCase { +class TimestampTest extends MediaWikiLangTestCase { protected function setUp() { parent::setUp(); - $this->setMwGlobals( array( - 'wgLanguageCode' => 'en', - 'wgContLang' => Language::factory( 'en' ), - 'wgLang' => Language::factory( 'en' ), - ) ); + RequestContext::getMain()->setLanguage( Language::factory( 'en' ) ); } /** * Test parsing of valid timestamps and outputing to MW format. * @dataProvider provideValidTimestamps + * @covers MWTimestamp::getTimestamp */ - function testValidParse( $format, $original, $expected ) { + public function testValidParse( $format, $original, $expected ) { $timestamp = new MWTimestamp( $original ); $this->assertEquals( $expected, $timestamp->getTimestamp( TS_MW ) ); } @@ -27,8 +24,9 @@ class TimestampTest extends MediaWikiTestCase { /** * Test outputting valid timestamps to different formats. * @dataProvider provideValidTimestamps + * @covers MWTimestamp::getTimestamp */ - function testValidOutput( $format, $expected, $original ) { + public function testValidOutput( $format, $expected, $original ) { $timestamp = new MWTimestamp( $original ); $this->assertEquals( $expected, (string)$timestamp->getTimestamp( $format ) ); } @@ -36,33 +34,23 @@ class TimestampTest extends MediaWikiTestCase { /** * Test an invalid timestamp. * @expectedException TimestampException + * @covers MWTimestamp */ - function testInvalidParse() { - $timestamp = new MWTimestamp( "This is not a timestamp." ); + public function testInvalidParse() { + new MWTimestamp( "This is not a timestamp." ); } /** * Test requesting an invalid output format. * @expectedException TimestampException + * @covers MWTimestamp::getTimestamp */ - function testInvalidOutput() { + public function testInvalidOutput() { $timestamp = new MWTimestamp( '1343761268' ); $timestamp->getTimestamp( 98 ); } /** - * Test human readable timestamp format. - */ - function testHumanOutput() { - $timestamp = new MWTimestamp( time() - 3600 ); - $this->assertEquals( "1 hour ago", $timestamp->getHumanTimestamp()->inLanguage( 'en' )->text() ); - $timestamp = new MWTimestamp( time() - 5184000 ); - $this->assertEquals( "2 months ago", $timestamp->getHumanTimestamp()->inLanguage( 'en' )->text() ); - $timestamp = new MWTimestamp( time() - 31536000 ); - $this->assertEquals( "1 year ago", $timestamp->getHumanTimestamp()->inLanguage( 'en' )->text() ); - } - - /** * Returns a list of valid timestamps in the format: * array( type, timestamp_of_type, timestamp_in_MW ) */ @@ -83,4 +71,234 @@ class TimestampTest extends MediaWikiTestCase { array( TS_UNIX, '-62135596801', '00001231235959' ) ); } + + /** + * @dataProvider provideHumanTimestampTests + * @covers MWTimestamp::getHumanTimestamp + */ + public function testHumanTimestamp( + $tsTime, // The timestamp to format + $currentTime, // The time to consider "now" + $timeCorrection, // The time offset to use + $dateFormat, // The date preference to use + $expectedOutput, // The expected output + $desc // Description + ) { + $user = $this->getMock( 'User' ); + $user->expects( $this->any() ) + ->method( 'getOption' ) + ->with( 'timecorrection' ) + ->will( $this->returnValue( $timeCorrection ) ); + + $user->expects( $this->any() ) + ->method( 'getDatePreference' ) + ->will( $this->returnValue( $dateFormat ) ); + + $tsTime = new MWTimestamp( $tsTime ); + $currentTime = new MWTimestamp( $currentTime ); + + $this->assertEquals( + $expectedOutput, + $tsTime->getHumanTimestamp( $currentTime, $user ), + $desc + ); + } + + public static function provideHumanTimestampTests() { + return array( + array( + '20111231170000', + '20120101000000', + 'Offset|0', + 'mdy', + 'Yesterday at 17:00', + '"Yesterday" across years', + ), + array( + '20120717190900', + '20120717190929', + 'Offset|0', + 'mdy', + 'just now', + '"Just now"', + ), + array( + '20120717190900', + '20120717191530', + 'Offset|0', + 'mdy', + '6 minutes ago', + 'X minutes ago', + ), + array( + '20121006173100', + '20121006173200', + 'Offset|0', + 'mdy', + '1 minute ago', + '"1 minute ago"', + ), + array( + '20120617190900', + '20120717190900', + 'Offset|0', + 'mdy', + 'June 17', + 'Another month' + ), + array( + '19910130151500', + '20120716193700', + 'Offset|0', + 'mdy', + '15:15, January 30, 1991', + 'Different year', + ), + array( + '20120101050000', + '20120101080000', + 'Offset|-360', + 'mdy', + 'Yesterday at 23:00', + '"Yesterday" across years with time correction', + ), + array( + '20120714184300', + '20120716184300', + 'Offset|-420', + 'mdy', + 'Saturday at 11:43', + 'Recent weekday with time correction', + ), + array( + '20120714184300', + '20120715040000', + 'Offset|-420', + 'mdy', + '11:43', + 'Today at another time with time correction', + ), + array( + '20120617190900', + '20120717190900', + 'Offset|0', + 'dmy', + '17 June', + 'Another month with dmy' + ), + array( + '20120617190900', + '20120717190900', + 'Offset|0', + 'ISO 8601', + '06-17', + 'Another month with ISO-8601' + ), + array( + '19910130151500', + '20120716193700', + 'Offset|0', + 'ISO 8601', + '1991-01-30T15:15:00', + 'Different year with ISO-8601', + ), + ); + } + + /** + * @dataProvider provideRelativeTimestampTests + * @covers MWTimestamp::getRelativeTimestamp + */ + public function testRelativeTimestamp( + $tsTime, // The timestamp to format + $currentTime, // The time to consider "now" + $timeCorrection, // The time offset to use + $dateFormat, // The date preference to use + $expectedOutput, // The expected output + $desc // Description + ) { + $user = $this->getMock( 'User' ); + $user->expects( $this->any() ) + ->method( 'getOption' ) + ->with( 'timecorrection' ) + ->will( $this->returnValue( $timeCorrection ) ); + + $tsTime = new MWTimestamp( $tsTime ); + $currentTime = new MWTimestamp( $currentTime ); + + $this->assertEquals( + $expectedOutput, + $tsTime->getRelativeTimestamp( $currentTime, $user ), + $desc + ); + } + + public static function provideRelativeTimestampTests() { + return array( + array( + '20111231170000', + '20120101000000', + 'Offset|0', + 'mdy', + '7 hours ago', + '"Yesterday" across years', + ), + array( + '20120717190900', + '20120717190929', + 'Offset|0', + 'mdy', + '29 seconds ago', + '"Just now"', + ), + array( + '20120717190900', + '20120717191530', + 'Offset|0', + 'mdy', + '6 minutes and 30 seconds ago', + 'Combination of multiple units', + ), + array( + '20121006173100', + '20121006173200', + 'Offset|0', + 'mdy', + '1 minute ago', + '"1 minute ago"', + ), + array( + '19910130151500', + '20120716193700', + 'Offset|0', + 'mdy', + '2 decades, 1 year, 168 days, 2 hours, 8 minutes and 48 seconds ago', + 'A long time ago', + ), + array( + '20120101050000', + '20120101080000', + 'Offset|-360', + 'mdy', + '3 hours ago', + '"Yesterday" across years with time correction', + ), + array( + '20120714184300', + '20120716184300', + 'Offset|-420', + 'mdy', + '2 days ago', + 'Recent weekday with time correction', + ), + array( + '20120714184300', + '20120715040000', + 'Offset|-420', + 'mdy', + '9 hours and 17 minutes ago', + 'Today at another time with time correction', + ), + ); + } } diff --git a/tests/phpunit/includes/TitleMethodsTest.php b/tests/phpunit/includes/TitleMethodsTest.php index 89812c90..3079d73a 100644 --- a/tests/phpunit/includes/TitleMethodsTest.php +++ b/tests/phpunit/includes/TitleMethodsTest.php @@ -6,11 +6,10 @@ * * @note: We don't make assumptions about the main namespace. * But we do expect the Help namespace to contain Wikitext. - * */ class TitleMethodsTest extends MediaWikiTestCase { - public function setup() { + public function setUp() { global $wgContLang; parent::setUp(); @@ -34,7 +33,7 @@ class TitleMethodsTest extends MediaWikiTestCase { $wgContLang->resetNamespaces(); # reset namespace cache } - public function teardown() { + public function tearDown() { global $wgContLang; parent::tearDown(); @@ -57,6 +56,7 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider provideEquals + * @covers Title::equals */ public function testEquals( $titleA, $titleB, $expectedBool ) { $titleA = Title::newFromText( $titleA ); @@ -81,12 +81,16 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider provideInNamespace + * @covers Title::inNamespace */ public function testInNamespace( $title, $ns, $expectedBool ) { $title = Title::newFromText( $title ); $this->assertEquals( $expectedBool, $title->inNamespace( $ns ) ); } + /** + * @covers Title::inNamespaces + */ public function testInNamespaces() { $mainpage = Title::newFromText( 'Main Page' ); $this->assertTrue( $mainpage->inNamespaces( NS_MAIN, NS_USER ) ); @@ -110,6 +114,7 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider provideHasSubjectNamespace + * @covers Title::hasSubjectNamespace */ public function testHasSubjectNamespace( $title, $ns, $expectedBool ) { $title = Title::newFromText( $title ); @@ -143,6 +148,7 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider dataGetContentModel + * @covers Title::getContentModel */ public function testGetContentModel( $title, $expectedModelId ) { $title = Title::newFromText( $title ); @@ -151,6 +157,7 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider dataGetContentModel + * @covers Title::hasContentModel */ public function testHasContentModel( $title, $expectedModelId ) { $title = Title::newFromText( $title ); @@ -181,13 +188,13 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider provideIsCssOrJsPage + * @covers Title::isCssOrJsPage */ public function testIsCssOrJsPage( $title, $expectedBool ) { $title = Title::newFromText( $title ); $this->assertEquals( $expectedBool, $title->isCssOrJsPage() ); } - public static function provideIsCssJsSubpage() { return array( array( 'Help:Foo', false ), @@ -210,6 +217,7 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider provideIsCssJsSubpage + * @covers Title::isCssJsSubpage */ public function testIsCssJsSubpage( $title, $expectedBool ) { $title = Title::newFromText( $title ); @@ -230,6 +238,7 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider provideIsCssSubpage + * @covers Title::isCssSubpage */ public function testIsCssSubpage( $title, $expectedBool ) { $title = Title::newFromText( $title ); @@ -250,6 +259,7 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider provideIsJsSubpage + * @covers Title::isJsSubpage */ public function testIsJsSubpage( $title, $expectedBool ) { $title = Title::newFromText( $title ); @@ -281,10 +291,10 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider provideIsWikitextPage + * @covers Title::isWikitextPage */ public function testIsWikitextPage( $title, $expectedBool ) { $title = Title::newFromText( $title ); $this->assertEquals( $expectedBool, $title->isWikitextPage() ); } - } diff --git a/tests/phpunit/includes/TitlePermissionTest.php b/tests/phpunit/includes/TitlePermissionTest.php index e2c079a7..f15c1772 100644 --- a/tests/phpunit/includes/TitlePermissionTest.php +++ b/tests/phpunit/includes/TitlePermissionTest.php @@ -2,6 +2,7 @@ /** * @group Database + * @todo covers tags */ class TitlePermissionTest extends MediaWikiLangTestCase { @@ -66,10 +67,9 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->user = $this->userUser; } - } - function setUserPerm( $perm ) { + protected function setUserPerm( $perm ) { // Setting member variables is evil!!! if ( is_array( $perm ) ) { @@ -79,11 +79,11 @@ class TitlePermissionTest extends MediaWikiLangTestCase { } } - function setTitle( $ns, $title = "Main_Page" ) { + protected function setTitle( $ns, $title = "Main_Page" ) { $this->title = Title::makeTitle( $ns, $title ); } - function setUser( $userName = null ) { + protected function setUser( $userName = null ) { if ( $userName === 'anon' ) { $this->user = $this->anonUser; } elseif ( $userName === null || $userName === $this->userName ) { @@ -93,7 +93,11 @@ class TitlePermissionTest extends MediaWikiLangTestCase { } } - function testQuickPermissions() { + /** + * @todo This test method should be split up into separate test methods and + * data providers + */ + public function testQuickPermissions() { global $wgContLang; $prefix = $wgContLang->getFormattedNsText( NS_PROJECT ); @@ -234,7 +238,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { if ( $this->isWikitextNS( NS_MAIN ) ) { //NOTE: some content models don't allow moving - //@todo: find a Wikitext namespace for testing + // @todo find a Wikitext namespace for testing $this->setTitle( NS_MAIN ); $this->setUser( 'anon' ); @@ -317,12 +321,11 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->title->userCan( $action, $this->user, true ) ); $this->assertEquals( $check[$action][3], $this->title->quickUserCan( $action, $this->user ) ); - # count( User::getGroupsWithPermissions( $action ) ) < 1 } } - function runGroupPermissions( $action, $result, $result2 = null ) { + protected function runGroupPermissions( $action, $result, $result2 = null ) { global $wgGroupPermissions; if ( $result2 === null ) { @@ -350,7 +353,11 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->assertEquals( $result2, $res ); } - function testSpecialsAndNSPermissions() { + /** + * @todo This test method should be split up into separate test methods and + * data providers + */ + public function testSpecialsAndNSPermissions() { global $wgNamespaceProtection; $this->setUser( $this->userName ); @@ -401,44 +408,85 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->title->userCan( 'bogus', $this->user ) ); } - function testCssAndJavascriptPermissions() { + /** + * @todo This test method should be split up into separate test methods and + * data providers + */ + public function testCssAndJavascriptPermissions() { $this->setUser( $this->userName ); + $this->setTitle( NS_USER, $this->userName . '/test.js' ); + $this->runCSSandJSPermissions( + array( array( 'badaccess-group0' ), array( 'mycustomjsprotected' ) ), + array( array( 'badaccess-group0' ), array( 'mycustomjsprotected' ) ), + array( array( 'badaccess-group0' ) ), + array( array( 'badaccess-group0' ), array( 'mycustomjsprotected' ) ), + array( array( 'badaccess-group0' ) ) + ); + + $this->setTitle( NS_USER, $this->userName . '/test.css' ); + $this->runCSSandJSPermissions( + array( array( 'badaccess-group0' ), array( 'mycustomcssprotected' ) ), + array( array( 'badaccess-group0' ) ), + array( array( 'badaccess-group0' ), array( 'mycustomcssprotected' ) ), + array( array( 'badaccess-group0' ) ), + array( array( 'badaccess-group0' ), array( 'mycustomcssprotected' ) ) + ); + $this->setTitle( NS_USER, $this->altUserName . '/test.js' ); $this->runCSSandJSPermissions( array( array( 'badaccess-group0' ), array( 'customjsprotected' ) ), array( array( 'badaccess-group0' ), array( 'customjsprotected' ) ), - array( array( 'badaccess-group0' ) ) ); + array( array( 'badaccess-group0' ), array( 'customjsprotected' ) ), + array( array( 'badaccess-group0' ), array( 'customjsprotected' ) ), + array( array( 'badaccess-group0' ) ) + ); $this->setTitle( NS_USER, $this->altUserName . '/test.css' ); $this->runCSSandJSPermissions( array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ), + array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ), + array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ), array( array( 'badaccess-group0' ) ), - array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ) ); + array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ) + ); $this->setTitle( NS_USER, $this->altUserName . '/tempo' ); $this->runCSSandJSPermissions( array( array( 'badaccess-group0' ) ), array( array( 'badaccess-group0' ) ), - array( array( 'badaccess-group0' ) ) ); + array( array( 'badaccess-group0' ) ), + array( array( 'badaccess-group0' ) ), + array( array( 'badaccess-group0' ) ) + ); } - function runCSSandJSPermissions( $result0, $result1, $result2 ) { + protected function runCSSandJSPermissions( $result0, $result1, $result2, $result3, $result4 ) { $this->setUserPerm( '' ); $this->assertEquals( $result0, $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - $this->setUserPerm( 'editusercss' ); + $this->setUserPerm( 'editmyusercss' ); $this->assertEquals( $result1, $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - $this->setUserPerm( 'edituserjs' ); + $this->setUserPerm( 'editmyuserjs' ); $this->assertEquals( $result2, $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); + $this->setUserPerm( 'editusercss' ); + $this->assertEquals( $result3, + $this->title->getUserPermissionsErrors( 'bogus', + $this->user ) ); + + $this->setUserPerm( 'edituserjs' ); + $this->assertEquals( $result4, + $this->title->getUserPermissionsErrors( 'bogus', + $this->user ) ); + $this->setUserPerm( 'editusercssjs' ); $this->assertEquals( array( array( 'badaccess-group0' ) ), $this->title->getUserPermissionsErrors( 'bogus', @@ -450,7 +498,11 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->user ) ); } - function testPageRestrictions() { + /** + * @todo This test method should be split up into separate test methods and + * data providers + */ + public function testPageRestrictions() { global $wgContLang; $prefix = $wgContLang->getFormattedNsText( NS_PROJECT ); @@ -471,39 +523,59 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->assertEquals( array( array( 'badaccess-group0' ), array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), + array( 'protectedpagetext', 'editprotected' ), array( 'protectedpagetext', 'protect' ) ), $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), + array( 'protectedpagetext', 'editprotected' ), array( 'protectedpagetext', 'protect' ) ), $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); $this->setUserPerm( "" ); $this->assertEquals( array( array( 'badaccess-group0' ), array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), + array( 'protectedpagetext', 'editprotected' ), array( 'protectedpagetext', 'protect' ) ), $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); $this->assertEquals( array( array( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ), array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), + array( 'protectedpagetext', 'editprotected' ), array( 'protectedpagetext', 'protect' ) ), $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); $this->setUserPerm( array( "edit", "editprotected" ) ); $this->assertEquals( array( array( 'badaccess-group0' ), array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), array( 'protectedpagetext', 'protect' ) ), $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - $this->assertEquals( array(), + $this->assertEquals( array( + array( 'protectedpagetext', 'bogus' ), + array( 'protectedpagetext', 'protect' ) ), $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); + $this->title->mCascadeRestriction = true; + $this->setUserPerm( "edit" ); + $this->assertEquals( false, + $this->title->quickUserCan( 'bogus', $this->user ) ); + $this->assertEquals( false, + $this->title->quickUserCan( 'edit', $this->user ) ); + $this->assertEquals( array( array( 'badaccess-group0' ), + array( 'protectedpagetext', 'bogus' ), + array( 'protectedpagetext', 'editprotected' ), + array( 'protectedpagetext', 'protect' ) ), + $this->title->getUserPermissionsErrors( 'bogus', + $this->user ) ); + $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ), + array( 'protectedpagetext', 'editprotected' ), + array( 'protectedpagetext', 'protect' ) ), + $this->title->getUserPermissionsErrors( 'edit', + $this->user ) ); + + $this->setUserPerm( array( "edit", "editprotected" ) ); $this->assertEquals( false, $this->title->quickUserCan( 'bogus', $this->user ) ); $this->assertEquals( false, @@ -521,7 +593,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->user ) ); } - function testCascadingSourcesRestrictions() { + public function testCascadingSourcesRestrictions() { $this->setTitle( NS_MAIN, "test page" ); $this->setUserPerm( array( "edit", "bogus" ) ); @@ -531,6 +603,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->assertEquals( false, $this->title->userCan( 'bogus', $this->user ) ); $this->assertEquals( array( array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ), + array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ), array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ) ), $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); @@ -538,10 +611,13 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->title->userCan( 'edit', $this->user ) ); $this->assertEquals( array(), $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); - } - function testActionPermissions() { + /** + * @todo This test method should be split up into separate test methods and + * data providers + */ + public function testActionPermissions() { $this->setUserPerm( array( "createpage" ) ); $this->setTitle( NS_MAIN, "test page" ); $this->title->mTitleProtection['pt_create_perm'] = ''; @@ -557,12 +633,17 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->title->mTitleProtection['pt_create_perm'] = 'sysop'; $this->setUserPerm( array( 'createpage', 'protect' ) ); + $this->assertEquals( array( array( 'titleprotected', 'Useruser', 'test' ) ), + $this->title->getUserPermissionsErrors( 'create', $this->user ) ); + $this->assertEquals( false, + $this->title->userCan( 'create', $this->user ) ); + + $this->setUserPerm( array( 'createpage', 'editprotected' ) ); $this->assertEquals( array(), $this->title->getUserPermissionsErrors( 'create', $this->user ) ); $this->assertEquals( true, $this->title->userCan( 'create', $this->user ) ); - $this->setUserPerm( array( 'createpage' ) ); $this->assertEquals( array( array( 'titleprotected', 'Useruser', 'test' ) ), $this->title->getUserPermissionsErrors( 'create', $this->user ) ); @@ -605,10 +686,9 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); $this->assertEquals( false, $this->title->userCan( 'move-target', $this->user ) ); - } - function testUserBlock() { + public function testUserBlock() { global $wgEmailConfirmToEdit, $wgEmailAuthentication; $wgEmailConfirmToEdit = true; $wgEmailAuthentication = true; @@ -648,13 +728,13 @@ class TitlePermissionTest extends MediaWikiLangTestCase { global $wgLocalTZoffset; $wgLocalTZoffset = -60; $this->user->mBlockedby = $this->user->getName(); - $this->user->mBlock = new Block( '127.0.8.1', 0, 1, 'no reason given', $now, 0, 10 ); + $this->user->mBlock = new Block( '127.0.8.1', 0, $this->user->getId(), + 'no reason given', $now, 0, 10 ); $this->assertEquals( array( array( 'blockedtext', '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1', 'Useruser', null, '23:00, 31 December 1969', '127.0.8.1', $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ) ), $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); - # $action != 'read' && $action != 'createaccount' && $user->isBlockedFrom( $this ) # $user->blockedFor() == '' # $user->mBlock->mExpiry == 'infinity' diff --git a/tests/phpunit/includes/TitleTest.php b/tests/phpunit/includes/TitleTest.php index a9067852..6bfe5453 100644 --- a/tests/phpunit/includes/TitleTest.php +++ b/tests/phpunit/includes/TitleTest.php @@ -1,7 +1,6 @@ <?php /** - * * @group Database * ^--- needed for language cache stuff */ @@ -19,7 +18,10 @@ class TitleTest extends MediaWikiTestCase { ) ); } - function testLegalChars() { + /** + * @covers Title::legalChars + */ + public function testLegalChars() { $titlechars = Title::legalChars(); foreach ( range( 1, 255 ) as $num ) { @@ -33,12 +35,160 @@ class TitleTest extends MediaWikiTestCase { } /** + * See also mediawiki.Title.test.js + * @covers Title::secureAndSplit + * @todo This method should be split into 2 separate tests each with a provider + */ + public function testSecureAndSplit() { + // Valid + foreach ( array( + 'Sandbox', + 'A "B"', + 'A \'B\'', + '.com', + '~', + '"', + '\'', + 'Talk:Sandbox', + 'Talk:Foo:Sandbox', + 'File:Example.svg', + 'File_talk:Example.svg', + 'Foo/.../Sandbox', + 'Sandbox/...', + 'A~~', + // Length is 256 total, but only title part matters + 'Category:' . str_repeat( 'x', 248 ), + str_repeat( 'x', 252 ) + ) as $text ) { + $this->assertInstanceOf( 'Title', Title::newFromText( $text ), "Valid: $text" ); + } + + // Invalid + foreach ( array( + '', + '__ __', + ' __ ', + // Bad characters forbidden regardless of wgLegalTitleChars + 'A [ B', + 'A ] B', + 'A { B', + 'A } B', + 'A < B', + 'A > B', + 'A | B', + // URL encoding + 'A%20B', + 'A%23B', + 'A%2523B', + // XML/HTML character entity references + // Note: Commented out because they are not marked invalid by the PHP test as + // Title::newFromText runs Sanitizer::decodeCharReferencesAndNormalize first. + //'A é B', + //'A é B', + //'A é B', + // Subject of NS_TALK does not roundtrip to NS_MAIN + 'Talk:File:Example.svg', + // Directory navigation + '.', + '..', + './Sandbox', + '../Sandbox', + 'Foo/./Sandbox', + 'Foo/../Sandbox', + 'Sandbox/.', + 'Sandbox/..', + // Tilde + 'A ~~~ Name', + 'A ~~~~ Signature', + 'A ~~~~~ Timestamp', + str_repeat( 'x', 256 ), + // Namespace prefix without actual title + // ':', // bug 54044 + 'Talk:', + 'Category: ', + 'Category: #bar' + ) as $text ) { + $this->assertNull( Title::newFromText( $text ), "Invalid: $text" ); + } + } + + public static function provideConvertByteClassToUnicodeClass() { + return array( + array( + ' %!"$&\'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF+', + ' %!"$&\'()*,\\-./0-9:;=?@A-Z\\\\\\^_`a-z~+\\u0080-\\uFFFF', + ), + array( + 'QWERTYf-\\xFF+', + 'QWERTYf-\\x7F+\\u0080-\\uFFFF', + ), + array( + 'QWERTY\\x66-\\xFD+', + 'QWERTYf-\\x7F+\\u0080-\\uFFFF', + ), + array( + 'QWERTYf-y+', + 'QWERTYf-y+', + ), + array( + 'QWERTYf-\\x80+', + 'QWERTYf-\\x7F+\\u0080-\\uFFFF', + ), + array( + 'QWERTY\\x66-\\x80+\\x23', + 'QWERTYf-\\x7F+#\\u0080-\\uFFFF', + ), + array( + 'QWERTY\\x66-\\x80+\\xD3', + 'QWERTYf-\\x7F+\\u0080-\\uFFFF', + ), + array( + '\\\\\\x99', + '\\\\\\u0080-\\uFFFF', + ), + array( + '-\\x99', + '\\-\\u0080-\\uFFFF', + ), + array( + 'QWERTY\\-\\x99', + 'QWERTY\\-\\u0080-\\uFFFF', + ), + array( + '\\\\x99', + '\\\\x99', + ), + array( + 'A-\\x9F', + 'A-\\x7F\\u0080-\\uFFFF', + ), + array( + '\\x66-\\x77QWERTY\\x88-\\x91FXZ', + 'f-wQWERTYFXZ\\u0080-\\uFFFF', + ), + array( + '\\x66-\\x99QWERTY\\xAA-\\xEEFXZ', + 'f-\\x7FQWERTYFXZ\\u0080-\\uFFFF', + ), + ); + } + + /** + * @dataProvider provideConvertByteClassToUnicodeClass + * @covers Title::convertByteClassToUnicodeClass + */ + public function testConvertByteClassToUnicodeClass( $byteClass, $unicodeClass ) { + $this->assertEquals( $unicodeClass, Title::convertByteClassToUnicodeClass( $byteClass ) ); + } + + /** * @dataProvider provideBug31100 + * @covers Title::fixSpecialName */ - function testBug31100FixSpecialName( $text, $expectedParam ) { + public function testBug31100FixSpecialName( $text, $expectedParam ) { $title = Title::newFromText( $text ); $fixed = $title->fixSpecialName(); - $stuff = explode( '/', $fixed->getDbKey(), 2 ); + $stuff = explode( '/', $fixed->getDBkey(), 2 ); if ( count( $stuff ) == 2 ) { $par = $stuff[1]; } else { @@ -61,10 +211,11 @@ class TitleTest extends MediaWikiTestCase { * @group Database * @param string $source * @param string $target - * @param array|string|true $expected Required error + * @param array|string|bool $expected Required error * @dataProvider provideTestIsValidMoveOperation + * @covers Title::isValidMoveOperation */ - function testIsValidMoveOperation( $source, $target, $expected ) { + public function testIsValidMoveOperation( $source, $target, $expected ) { $title = Title::newFromText( $source ); $nt = Title::newFromText( $target ); $errors = $title->isValidMoveOperation( $nt, false ); @@ -81,7 +232,7 @@ class TitleTest extends MediaWikiTestCase { /** * Provides test parameter values for testIsValidMoveOperation() */ - function dataTestIsValidMoveOperation() { + public function dataTestIsValidMoveOperation() { return array( array( 'Test', 'Test', 'selfmove' ), array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' ) @@ -94,12 +245,12 @@ class TitleTest extends MediaWikiTestCase { * @param array $whitelistRegexp * @param string $source * @param string $action - * @param array|string|true $expected Required error + * @param array|string|bool $expected Required error * * @covers Title::checkReadPermissions * @dataProvider dataWgWhitelistReadRegexp */ - function testWgWhitelistReadRegexp( $whitelistRegexp, $source, $action, $expected ) { + public function testWgWhitelistReadRegexp( $whitelistRegexp, $source, $action, $expected ) { // $wgWhitelistReadRegexp must be an array. Since the provided test cases // usually have only one regex, it is more concise to write the lonely regex // as a string. Thus we cast to an array() to honor $wgWhitelistReadRegexp @@ -156,7 +307,7 @@ class TitleTest extends MediaWikiTestCase { /** * Provides test parameter values for testWgWhitelistReadRegexp() */ - function dataWgWhitelistReadRegexp() { + public function dataWgWhitelistReadRegexp() { $ALLOWED = true; $DISALLOWED = false; @@ -192,11 +343,12 @@ class TitleTest extends MediaWikiTestCase { ); } - function flattenErrorsArray( $errors ) { + public function flattenErrorsArray( $errors ) { $result = array(); foreach ( $errors as $error ) { $result[] = $error[0]; } + return $result; } @@ -208,9 +360,10 @@ class TitleTest extends MediaWikiTestCase { } /** - * @dataProvider provideCasesForGetpageviewlanguage + * @dataProvider provideGetPageViewLanguage + * @covers Title::getPageViewLanguage */ - function testGetpageviewlanguage( $expected, $titleText, $contLang, $lang, $variant, $msg = '' ) { + public function testGetPageViewLanguage( $expected, $titleText, $contLang, $lang, $variant, $msg = '' ) { global $wgLanguageCode, $wgContLang, $wgLang, $wgDefaultLanguageVariant, $wgAllowUserJs; // Setup environnement for this test @@ -230,7 +383,7 @@ class TitleTest extends MediaWikiTestCase { ); } - function provideCasesForGetpageviewlanguage() { + public static function provideGetPageViewLanguage() { # Format: # - expected # - Title name @@ -271,8 +424,9 @@ class TitleTest extends MediaWikiTestCase { /** * @dataProvider provideBaseTitleCases + * @covers Title::getBaseText */ - function testExtractingBaseTextFromTitle( $title, $expected, $msg = '' ) { + public function testGetBaseText( $title, $expected, $msg = '' ) { $title = Title::newFromText( $title ); $this->assertEquals( $expected, $title->getBaseText(), @@ -280,7 +434,7 @@ class TitleTest extends MediaWikiTestCase { ); } - function provideBaseTitleCases() { + public static function provideBaseTitleCases() { return array( # Title, expected base, optional message array( 'User:John_Doe/subOne/subTwo', 'John Doe/subOne' ), @@ -290,8 +444,9 @@ class TitleTest extends MediaWikiTestCase { /** * @dataProvider provideRootTitleCases + * @covers Title::getRootText */ - function testExtractingRootTextFromTitle( $title, $expected, $msg = '' ) { + public function testGetRootText( $title, $expected, $msg = '' ) { $title = Title::newFromText( $title ); $this->assertEquals( $expected, $title->getRootText(), @@ -310,8 +465,9 @@ class TitleTest extends MediaWikiTestCase { /** * @todo Handle $wgNamespacesWithSubpages cases * @dataProvider provideSubpageTitleCases + * @covers Title::getSubpageText */ - function testExtractingSubpageTextFromTitle( $title, $expected, $msg = '' ) { + public function testGetSubpageText( $title, $expected, $msg = '' ) { $title = Title::newFromText( $title ); $this->assertEquals( $expected, $title->getSubpageText(), @@ -319,7 +475,7 @@ class TitleTest extends MediaWikiTestCase { ); } - function provideSubpageTitleCases() { + public static function provideSubpageTitleCases() { return array( # Title, expected base, optional message array( 'User:John_Doe/subOne/subTwo', 'subTwo' ), diff --git a/tests/phpunit/includes/UIDGeneratorTest.php b/tests/phpunit/includes/UIDGeneratorTest.php index 23553ca7..8f78ae51 100644 --- a/tests/phpunit/includes/UIDGeneratorTest.php +++ b/tests/phpunit/includes/UIDGeneratorTest.php @@ -1,8 +1,11 @@ <?php class UIDGeneratorTest extends MediaWikiTestCase { + /** * @dataProvider provider_testTimestampedUID + * @covers UIDGenerator::newTimestampedUID128 + * @covers UIDGenerator::newTimestampedUID88 */ public function testTimestampedUID( $method, $digitlen, $bits, $tbits, $hostbits ) { $id = call_user_func( array( 'UIDGenerator', $method ) ); @@ -46,6 +49,7 @@ class UIDGeneratorTest extends MediaWikiTestCase { /** * array( method, length, bits, hostbits ) + * NOTE: When adding a new method name here please update the covers tags for the tests! */ public static function provider_testTimestampedUID() { return array( @@ -55,22 +59,40 @@ class UIDGeneratorTest extends MediaWikiTestCase { ); } + /** + * @covers UIDGenerator::newUUIDv4 + */ public function testUUIDv4() { for ( $i = 0; $i < 100; $i++ ) { $id = UIDGenerator::newUUIDv4(); $this->assertEquals( true, preg_match( '!^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$!', $id ), "UID $id has the right format" ); + } + } + /** + * @covers UIDGenerator::newRawUUIDv4 + */ + public function testRawUUIDv4() { + for ( $i = 0; $i < 100; $i++ ) { $id = UIDGenerator::newRawUUIDv4(); $this->assertEquals( true, preg_match( '!^[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}$!', $id ), "UID $id has the right format" ); + } + } + /** + * @covers UIDGenerator::newRawUUIDv4 + */ + public function testRawUUIDv4QuickRand() { + for ( $i = 0; $i < 100; $i++ ) { $id = UIDGenerator::newRawUUIDv4( UIDGenerator::QUICK_RAND ); $this->assertEquals( true, preg_match( '!^[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}$!', $id ), "UID $id has the right format" ); } } + } diff --git a/tests/phpunit/includes/UserMailerTest.php b/tests/phpunit/includes/UserMailerTest.php new file mode 100644 index 00000000..278edfaa --- /dev/null +++ b/tests/phpunit/includes/UserMailerTest.php @@ -0,0 +1,14 @@ +<?php + +class UserMailerTest extends MediaWikiLangTestCase { + + /** + * @covers UserMailer::quotedPrintable + */ + public function testQuotedPrintable() { + $this->assertEquals( + "=?UTF-8?Q?=C4=88u=20legebla=3F?=", + UserMailer::quotedPrintable( "\xc4\x88u legebla?", "UTF-8" ) ); + } + +}
\ No newline at end of file diff --git a/tests/phpunit/includes/UserTest.php b/tests/phpunit/includes/UserTest.php index e777179a..ff33e825 100644 --- a/tests/phpunit/includes/UserTest.php +++ b/tests/phpunit/includes/UserTest.php @@ -46,8 +46,16 @@ class UserTest extends MediaWikiTestCase { $wgRevokePermissions['formertesters'] = array( 'runtest' => true, ); + + # For the options test + $wgGroupPermissions['*'] = array( + 'editmyoptions' => true, + ); } + /** + * @covers User::getGroupPermissions + */ public function testGroupPermissions() { $rights = User::getGroupPermissions( array( 'unittesters' ) ); $this->assertContains( 'runtest', $rights ); @@ -62,6 +70,9 @@ class UserTest extends MediaWikiTestCase { $this->assertNotContains( 'nukeworld', $rights ); } + /** + * @covers User::getGroupPermissions + */ public function testRevokePermissions() { $rights = User::getGroupPermissions( array( 'unittesters', 'formertesters' ) ); $this->assertNotContains( 'runtest', $rights ); @@ -70,6 +81,9 @@ class UserTest extends MediaWikiTestCase { $this->assertNotContains( 'nukeworld', $rights ); } + /** + * @covers User::getRights + */ public function testUserPermissions() { $rights = $this->user->getRights(); $this->assertContains( 'runtest', $rights ); @@ -80,6 +94,7 @@ class UserTest extends MediaWikiTestCase { /** * @dataProvider provideGetGroupsWithPermission + * @covers User::getGroupsWithPermission */ public function testGetGroupsWithPermission( $expected, $right ) { $result = User::getGroupsWithPermission( $right ); @@ -112,6 +127,7 @@ class UserTest extends MediaWikiTestCase { /** * @dataProvider provideUserNames + * @covers User::isValidUserName */ public function testIsValidUserName( $username, $result, $message ) { $this->assertEquals( $this->user->isValidUserName( $username ), $result, $message ); @@ -166,6 +182,7 @@ class UserTest extends MediaWikiTestCase { /** * Test User::editCount * @group medium + * @covers User::getEditCount */ public function testEditCount() { $user = User::newFromName( 'UnitTestUser' ); @@ -190,6 +207,8 @@ class UserTest extends MediaWikiTestCase { /** * Test changing user options. + * @covers User::setOption + * @covers User::getOption */ public function testOptions() { $user = User::newFromName( 'UnitTestUser' ); @@ -207,6 +226,7 @@ class UserTest extends MediaWikiTestCase { /** * Bug 37963 * Make sure defaults are loaded when setOption is called. + * @covers User::loadOptions */ public function testAnonOptions() { global $wgDefaultUserOptions; diff --git a/tests/phpunit/includes/WebRequestTest.php b/tests/phpunit/includes/WebRequestTest.php index 46f80255..f8ed14b6 100644 --- a/tests/phpunit/includes/WebRequestTest.php +++ b/tests/phpunit/includes/WebRequestTest.php @@ -1,5 +1,8 @@ <?php +/** + * @group WebRequest + */ class WebRequestTest extends MediaWikiTestCase { protected $oldServer; @@ -17,8 +20,9 @@ class WebRequestTest extends MediaWikiTestCase { /** * @dataProvider provideDetectServer + * @covers WebRequest::detectServer */ - function testDetectServer( $expected, $input, $description ) { + public function testDetectServer( $expected, $input, $description ) { $_SERVER = $input; $result = WebRequest::detectServer(); $this->assertEquals( $expected, $result, $description ); @@ -100,12 +104,23 @@ class WebRequestTest extends MediaWikiTestCase { /** * @dataProvider provideGetIP + * @covers WebRequest::getIP */ - function testGetIP( $expected, $input, $squid, $private, $description ) { - global $wgSquidServersNoPurge, $wgUsePrivateIPs; + public function testGetIP( $expected, $input, $squid, $xffList, $private, $description ) { $_SERVER = $input; - $wgSquidServersNoPurge = $squid; - $wgUsePrivateIPs = $private; + $this->setMwGlobals( array( + 'wgSquidServersNoPurge' => $squid, + 'wgUsePrivateIPs' => $private, + 'wgHooks' => array( + 'IsTrustedProxy' => array( + function( &$ip, &$trusted ) use ( $xffList ) { + $trusted = $trusted || in_array( $ip, $xffList ); + return true; + } + ) + ) + ) ); + $request = new WebRequest(); $result = $request->getIP(); $this->assertEquals( $expected, $result, $description ); @@ -119,6 +134,7 @@ class WebRequestTest extends MediaWikiTestCase { 'REMOTE_ADDR' => '127.0.0.1' ), array(), + array(), false, 'Simple IPv4' ), @@ -128,16 +144,29 @@ class WebRequestTest extends MediaWikiTestCase { 'REMOTE_ADDR' => '::1' ), array(), + array(), false, 'Simple IPv6' ), array( + '12.0.0.1', + array( + 'REMOTE_ADDR' => 'abcd:0001:002:03:4:555:6666:7777', + 'HTTP_X_FORWARDED_FOR' => '12.0.0.1, abcd:0001:002:03:4:555:6666:7777', + ), + array( 'ABCD:1:2:3:4:555:6666:7777' ), + array(), + false, + 'IPv6 normalisation' + ), + array( '12.0.0.3', array( 'REMOTE_ADDR' => '12.0.0.1', 'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2' ), array( '12.0.0.1', '12.0.0.2' ), + array(), false, 'With X-Forwaded-For' ), @@ -148,6 +177,7 @@ class WebRequestTest extends MediaWikiTestCase { 'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2' ), array(), + array(), false, 'With X-Forwaded-For and disallowed server' ), @@ -158,36 +188,95 @@ class WebRequestTest extends MediaWikiTestCase { 'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2' ), array( '12.0.0.1' ), + array(), false, 'With multiple X-Forwaded-For and only one allowed server' ), array( - '12.0.0.2', + '10.0.0.3', array( 'REMOTE_ADDR' => '12.0.0.2', - 'HTTP_X_FORWARDED_FOR' => '10.0.0.3, 12.0.0.2' + 'HTTP_X_FORWARDED_FOR' => '10.0.0.4, 10.0.0.3, 12.0.0.2' ), array( '12.0.0.1', '12.0.0.2' ), + array(), false, - 'With X-Forwaded-For and private IP' + 'With X-Forwaded-For and private IP (from cache proxy)' ), array( - '10.0.0.3', + '10.0.0.4', array( 'REMOTE_ADDR' => '12.0.0.2', - 'HTTP_X_FORWARDED_FOR' => '10.0.0.3, 12.0.0.2' + 'HTTP_X_FORWARDED_FOR' => '10.0.0.4, 10.0.0.3, 12.0.0.2' + ), + array( '12.0.0.1', '12.0.0.2', '10.0.0.3' ), + array(), + true, + 'With X-Forwaded-For and private IP (allowed)' + ), + array( + '10.0.0.4', + array( + 'REMOTE_ADDR' => '12.0.0.2', + 'HTTP_X_FORWARDED_FOR' => '10.0.0.4, 10.0.0.3, 12.0.0.2' ), array( '12.0.0.1', '12.0.0.2' ), + array( '10.0.0.3' ), true, 'With X-Forwaded-For and private IP (allowed)' ), + array( + '10.0.0.3', + array( + 'REMOTE_ADDR' => '12.0.0.2', + 'HTTP_X_FORWARDED_FOR' => '10.0.0.4, 10.0.0.3, 12.0.0.2' + ), + array( '12.0.0.1', '12.0.0.2' ), + array( '10.0.0.3' ), + false, + 'With X-Forwaded-For and private IP (disallowed)' + ), + array( + '12.0.0.3', + array( + 'REMOTE_ADDR' => '12.0.0.1', + 'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2' + ), + array(), + array( '12.0.0.1', '12.0.0.2' ), + false, + 'With X-Forwaded-For' + ), + array( + '12.0.0.2', + array( + 'REMOTE_ADDR' => '12.0.0.1', + 'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2' + ), + array(), + array( '12.0.0.1' ), + false, + 'With multiple X-Forwaded-For and only one allowed server' + ), + array( + '12.0.0.2', + array( + 'REMOTE_ADDR' => '12.0.0.2', + 'HTTP_X_FORWARDED_FOR' => '10.0.0.3, 12.0.0.2' + ), + array(), + array( '12.0.0.2' ), + false, + 'With X-Forwaded-For and private IP and hook (disallowed)' + ), ); } /** * @expectedException MWException + * @covers WebRequest::getIP */ - function testGetIpLackOfRemoteAddrThrowAnException() { + public function testGetIpLackOfRemoteAddrThrowAnException() { $request = new WebRequest(); # Next call throw an exception about lacking an IP $request->getIP(); @@ -211,8 +300,9 @@ class WebRequestTest extends MediaWikiTestCase { /** * @dataProvider provideLanguageData + * @covers WebRequest::getAcceptLang */ - function testAcceptLang( $acceptLanguageHeader, $expectedLanguages, $description ) { + public function testAcceptLang( $acceptLanguageHeader, $expectedLanguages, $description ) { $_SERVER = array( 'HTTP_ACCEPT_LANGUAGE' => $acceptLanguageHeader ); $request = new WebRequest(); $this->assertSame( $request->getAcceptLang(), $expectedLanguages, $description ); diff --git a/tests/phpunit/includes/WikiPageTest.php b/tests/phpunit/includes/WikiPageTest.php index 2501be33..e0d786b9 100644 --- a/tests/phpunit/includes/WikiPageTest.php +++ b/tests/phpunit/includes/WikiPageTest.php @@ -1,16 +1,16 @@ <?php + /** * @group ContentHandler * @group Database * ^--- important, causes temporary tables to be used instead of the real database * @group medium **/ - class WikiPageTest extends MediaWikiLangTestCase { - var $pages_to_delete; + protected $pages_to_delete; - function __construct( $name = null, array $data = array(), $dataName = '' ) { + function __construct( $name = null, array $data = array(), $dataName = '' ) { parent::__construct( $name, $data, $dataName ); $this->tablesUsed = array_merge( @@ -90,6 +90,9 @@ class WikiPageTest extends MediaWikiLangTestCase { return $page; } + /** + * @covers WikiPage::doEditContent + */ public function testDoEditContent() { $page = $this->newPage( "WikiPageTest_testDoEditContent" ); $title = $page->getTitle(); @@ -143,6 +146,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' ); } + /** + * @covers WikiPage::doEdit + */ public function testDoEdit() { $this->hideDeprecated( "WikiPage::doEdit" ); $this->hideDeprecated( "WikiPage::getText" ); @@ -200,6 +206,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' ); } + /** + * @covers WikiPage::doQuickEdit + */ public function testDoQuickEdit() { global $wgUser; @@ -216,6 +225,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( $text, $page->getText() ); } + /** + * @covers WikiPage::doQuickEditContent + */ public function testDoQuickEditContent() { global $wgUser; @@ -229,6 +241,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertTrue( $content->equals( $page->getContent() ) ); } + /** + * @covers WikiPage::doDeleteArticle + */ public function testDoDeleteArticle() { $page = $this->createPage( "WikiPageTest_testDoDeleteArticle", "[[original text]] foo", CONTENT_MODEL_WIKITEXT ); $id = $page->getId(); @@ -253,6 +268,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' ); } + /** + * @covers WikiPage::doDeleteUpdates + */ public function testDoDeleteUpdates() { $page = $this->createPage( "WikiPageTest_testDoDeleteArticle", "[[original text]] foo", CONTENT_MODEL_WIKITEXT ); $id = $page->getId(); @@ -268,6 +286,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' ); } + /** + * @covers WikiPage::getRevision + */ public function testGetRevision() { $page = $this->newPage( "WikiPageTest_testGetRevision" ); @@ -283,6 +304,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( "some text", $rev->getContent()->getNativeData() ); } + /** + * @covers WikiPage::getContent + */ public function testGetContent() { $page = $this->newPage( "WikiPageTest_testGetContent" ); @@ -296,6 +320,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( "some text", $content->getNativeData() ); } + /** + * @covers WikiPage::getText + */ public function testGetText() { $this->hideDeprecated( "WikiPage::getText" ); @@ -311,6 +338,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( "some text", $text ); } + /** + * @covers WikiPage::getRawText + */ public function testGetRawText() { $this->hideDeprecated( "WikiPage::getRawText" ); @@ -326,6 +356,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( "some text", $text ); } + /** + * @covers WikiPage::getContentModel + */ public function testGetContentModel() { global $wgContentHandlerUseDB; @@ -339,6 +372,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $page->getContentModel() ); } + /** + * @covers WikiPage::getContentHandler + */ public function testGetContentHandler() { global $wgContentHandlerUseDB; @@ -352,6 +388,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( 'JavaScriptContentHandler', get_class( $page->getContentHandler() ) ); } + /** + * @covers WikiPage::exists + */ public function testExists() { $page = $this->newPage( "WikiPageTest_testExists" ); $this->assertFalse( $page->exists() ); @@ -383,6 +422,7 @@ class WikiPageTest extends MediaWikiLangTestCase { /** * @dataProvider provideHasViewableContent + * @covers WikiPage::hasViewableContent */ public function testHasViewableContent( $title, $viewable, $create = false ) { $page = $this->newPage( $title ); @@ -406,6 +446,7 @@ class WikiPageTest extends MediaWikiLangTestCase { /** * @dataProvider provideGetRedirectTarget + * @covers WikiPage::getRedirectTarget */ public function testGetRedirectTarget( $title, $model, $text, $target ) { $page = $this->createPage( $title, $text, $model ); @@ -421,6 +462,7 @@ class WikiPageTest extends MediaWikiLangTestCase { /** * @dataProvider provideGetRedirectTarget + * @covers WikiPage::isRedirect */ public function testIsRedirect( $title, $model, $text, $target ) { $page = $this->createPage( $title, $text, $model ); @@ -537,6 +579,7 @@ class WikiPageTest extends MediaWikiLangTestCase { /** * @dataProvider provideIsCountable + * @covers WikiPage::isCountable */ public function testIsCountable( $title, $model, $text, $mode, $expected ) { global $wgContentHandlerUseDB; @@ -569,12 +612,13 @@ class WikiPageTest extends MediaWikiLangTestCase { public static function provideGetParserOutput() { return array( array( CONTENT_MODEL_WIKITEXT, "hello ''world''\n", "<p>hello <i>world</i></p>" ), - // @todo: more...? + // @todo more...? ); } /** * @dataProvider provideGetParserOutput + * @covers WikiPage::getParserOutput */ public function testGetParserOutput( $model, $text, $expectedHtml ) { $page = $this->createPage( 'WikiPageTest_testGetParserOutput', $text, $model ); @@ -587,9 +631,13 @@ class WikiPageTest extends MediaWikiLangTestCase { $text = preg_replace( '!\s*(</p>)!sm', '\1', $text ); # don't let tidy confuse us $this->assertEquals( $expectedHtml, $text ); + return $po; } + /** + * @covers WikiPage::getParserOutput + */ public function testGetParserOutput_nonexisting() { static $count = 0; $count++; @@ -602,13 +650,16 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertFalse( $po, "getParserOutput() shall return false for non-existing pages." ); } + /** + * @covers WikiPage::getParserOutput + */ public function testGetParserOutput_badrev() { $page = $this->createPage( 'WikiPageTest_testGetParserOutput', "dummy", CONTENT_MODEL_WIKITEXT ); $opt = new ParserOptions(); $po = $page->getParserOutput( $opt, $page->getLatest() + 1234 ); - //@todo: would be neat to also test deleted revision + // @todo would be neat to also test deleted revision $this->assertFalse( $po, "getParserOutput() shall return false for non-existing revisions." ); } @@ -678,6 +729,7 @@ more stuff /** * @dataProvider dataReplaceSection + * @covers WikiPage::replaceSection */ public function testReplaceSection( $title, $model, $text, $section, $with, $sectionTitle, $expected ) { $this->hideDeprecated( "WikiPage::replaceSection" ); @@ -691,6 +743,7 @@ more stuff /** * @dataProvider dataReplaceSection + * @covers WikiPage::replaceSectionContent */ public function testReplaceSectionContent( $title, $model, $text, $section, $with, $sectionTitle, $expected ) { $page = $this->createPage( $title, $text, $model ); @@ -801,6 +854,7 @@ more stuff /** * @todo FIXME: the above rollback test is better, but it keeps failing in jenkins for some reason. + * @covers WikiPage::doRollback */ public function testDoRollback() { $admin = new User(); @@ -877,6 +931,7 @@ more stuff /** * @dataProvider provideGetAutoSummary + * @covers WikiPage::getAutosummary */ public function testGetAutosummary( $old, $new, $flags, $expected ) { $this->hideDeprecated( "WikiPage::getAutosummary" ); @@ -949,6 +1004,7 @@ more stuff /** * @dataProvider provideGetAutoDeleteReason + * @covers WikiPage::getAutoDeleteReason */ public function testGetAutoDeleteReason( $edits, $expectedResult, $expectedHistory ) { global $wgUser; @@ -1002,6 +1058,7 @@ more stuff /** * @dataProvider providePreSaveTransform + * @covers WikiPage::preSaveTransform */ public function testPreSaveTransform( $text, $expected ) { $this->hideDeprecated( 'WikiPage::preSaveTransform' ); @@ -1014,5 +1071,4 @@ more stuff $this->assertEquals( $expected, $text ); } - } diff --git a/tests/phpunit/includes/WikiPageTest_ContentHandlerUseDB.php b/tests/phpunit/includes/WikiPageTest_ContentHandlerUseDB.php index 1d937e9b..2a723e85 100644 --- a/tests/phpunit/includes/WikiPageTest_ContentHandlerUseDB.php +++ b/tests/phpunit/includes/WikiPageTest_ContentHandlerUseDB.php @@ -6,16 +6,10 @@ * ^--- important, causes temporary tables to be used instead of the real database */ class WikiPageTest_ContentHandlerUseDB extends WikiPageTest { - var $saveContentHandlerNoDB = null; - - function setUp() { - global $wgContentHandlerUseDB; + protected function setUp() { parent::setUp(); - - $this->saveContentHandlerNoDB = $wgContentHandlerUseDB; - - $wgContentHandlerUseDB = false; + $this->setMwGlobals( 'wgContentHandlerUseDB', false ); $dbw = wfGetDB( DB_MASTER ); @@ -32,14 +26,9 @@ class WikiPageTest_ContentHandlerUseDB extends WikiPageTest { } } - function tearDown() { - global $wgContentHandlerUseDB; - - $wgContentHandlerUseDB = $this->saveContentHandlerNoDB; - - parent::tearDown(); - } - + /** + * @covers WikiPage::getContentModel + */ public function testGetContentModel() { $page = $this->createPage( "WikiPageTest_testGetContentModel", "some text", CONTENT_MODEL_JAVASCRIPT ); @@ -50,6 +39,9 @@ class WikiPageTest_ContentHandlerUseDB extends WikiPageTest { $this->assertEquals( CONTENT_MODEL_WIKITEXT, $page->getContentModel() ); } + /** + * @covers WikiPage::getContentHandler + */ public function testGetContentHandler() { $page = $this->createPage( "WikiPageTest_testGetContentHandler", "some text", CONTENT_MODEL_JAVASCRIPT ); @@ -58,5 +50,4 @@ class WikiPageTest_ContentHandlerUseDB extends WikiPageTest { $page = new WikiPage( $page->getTitle() ); $this->assertEquals( 'WikitextContentHandler', get_class( $page->getContentHandler() ) ); } - } diff --git a/tests/phpunit/includes/XmlJsTest.php b/tests/phpunit/includes/XmlJsTest.php index c5b411fb..161468e2 100644 --- a/tests/phpunit/includes/XmlJsTest.php +++ b/tests/phpunit/includes/XmlJsTest.php @@ -1,9 +1,24 @@ <?php + +/** + * @group Xml + */ class XmlJs extends MediaWikiTestCase { - public function testConstruction() { - $obj = new XmlJsCode( null ); - $this->assertNull( $obj->value ); - $obj = new XmlJsCode( '' ); - $this->assertSame( $obj->value, '' ); + + /** + * @covers XmlJsCode::__construct + * @dataProvider provideConstruction + */ + public function testConstruction( $value ) { + $obj = new XmlJsCode( $value ); + $this->assertEquals( $value, $obj->value ); } + + public function provideConstruction(){ + return array( + array( null ), + array( '' ), + ); + } + } diff --git a/tests/phpunit/includes/XmlSelectTest.php b/tests/phpunit/includes/XmlSelectTest.php index d7227b4d..56d28b54 100644 --- a/tests/phpunit/includes/XmlSelectTest.php +++ b/tests/phpunit/includes/XmlSelectTest.php @@ -1,13 +1,18 @@ <?php -// TODO +/** + * @group Xml + */ class XmlSelectTest extends MediaWikiTestCase { + + /** + * @var XmlSelect + */ protected $select; protected function setUp() { parent::setUp(); $this->setMwGlobals( array( - 'wgHtml5' => true, 'wgWellFormedXml' => true, ) ); $this->select = new XmlSelect(); @@ -18,8 +23,9 @@ class XmlSelectTest extends MediaWikiTestCase { $this->select = null; } - ### START OF TESTS ### - + /** + * @covers XmlSelect::__construct + */ public function testConstructWithoutParameters() { $this->assertEquals( '<select></select>', $this->select->getHTML() ); } @@ -27,6 +33,7 @@ class XmlSelectTest extends MediaWikiTestCase { /** * Parameters are $name (false), $id (false), $default (false) * @dataProvider provideConstructionParameters + * @covers XmlSelect::__construct */ public function testConstructParameters( $name, $id, $default, $expected ) { $this->select = new XmlSelect( $name, $id, $default ); @@ -40,7 +47,6 @@ class XmlSelectTest extends MediaWikiTestCase { * - $id (default: false) * - $default (default: false) * Provides a fourth parameters representing the expected HTML output - * */ public static function provideConstructionParameters() { return array( @@ -61,29 +67,41 @@ class XmlSelectTest extends MediaWikiTestCase { ); } - # Begin XmlSelect::addOption() similar to Xml::option + /** + * @covers XmlSelect::addOption + */ public function testAddOption() { $this->select->addOption( 'foo' ); $this->assertEquals( '<select><option value="foo">foo</option></select>', $this->select->getHTML() ); } + /** + * @covers XmlSelect::addOption + */ public function testAddOptionWithDefault() { $this->select->addOption( 'foo', true ); $this->assertEquals( '<select><option value="1">foo</option></select>', $this->select->getHTML() ); } + /** + * @covers XmlSelect::addOption + */ public function testAddOptionWithFalse() { $this->select->addOption( 'foo', false ); $this->assertEquals( '<select><option value="foo">foo</option></select>', $this->select->getHTML() ); } + /** + * @covers XmlSelect::addOption + */ public function testAddOptionWithValueZero() { $this->select->addOption( 'foo', 0 ); $this->assertEquals( '<select><option value="0">foo</option></select>', $this->select->getHTML() ); } - # End XmlSelect::addOption() similar to Xml::option - + /** + * @covers XmlSelect::setDefault + */ public function testSetDefault() { $this->select->setDefault( 'bar1' ); $this->select->addOption( 'foo1' ); @@ -99,6 +117,7 @@ class XmlSelectTest extends MediaWikiTestCase { * Adding default later on should set the correct selection or * raise an exception. * To handle this, we need to render the options in getHtml() + * @covers XmlSelect::setDefault */ public function testSetDefaultAfterAddingOptions() { $this->select->addOption( 'foo1' ); @@ -111,6 +130,10 @@ class XmlSelectTest extends MediaWikiTestCase { '<option value="foo2">foo2</option></select>', $this->select->getHTML() ); } + /** + * @covers XmlSelect::setAttribute + * @covers XmlSelect::getAttribute + */ public function testGetAttributes() { # create some attributes $this->select->setAttribute( 'dummy', 0x777 ); diff --git a/tests/phpunit/includes/XmlTest.php b/tests/phpunit/includes/XmlTest.php index f4823287..8205029f 100644 --- a/tests/phpunit/includes/XmlTest.php +++ b/tests/phpunit/includes/XmlTest.php @@ -1,8 +1,9 @@ <?php +/** + * @group Xml + */ class XmlTest extends MediaWikiTestCase { - private static $oldLang; - private static $oldNamespaces; protected function setUp() { parent::setUp(); @@ -29,11 +30,13 @@ class XmlTest extends MediaWikiTestCase { $this->setMwGlobals( array( 'wgLang' => $langObj, - 'wgHtml5' => true, 'wgWellFormedXml' => true, ) ); } + /** + * @covers Xml::expandAttributes + */ public function testExpandAttributes() { $this->assertNull( Xml::expandAttributes( null ), 'Converting a null list of attributes' @@ -43,12 +46,18 @@ class XmlTest extends MediaWikiTestCase { ); } + /** + * @covers Xml::expandAttributes + */ public function testExpandAttributesException() { $this->setExpectedException( 'MWException' ); Xml::expandAttributes( 'string' ); } - function testElementOpen() { + /** + * @covers Xml::element + */ + public function testElementOpen() { $this->assertEquals( '<element>', Xml::element( 'element', null, null ), @@ -56,7 +65,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testElementEmpty() { + /** + * @covers Xml::element + */ + public function testElementEmpty() { $this->assertEquals( '<element />', Xml::element( 'element', null, '' ), @@ -64,7 +76,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testElementInputCanHaveAValueOfZero() { + /** + * @covers Xml::input + */ + public function testElementInputCanHaveAValueOfZero() { $this->assertEquals( '<input name="name" value="0" />', Xml::input( 'name', false, 0 ), @@ -72,7 +87,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testElementEscaping() { + /** + * @covers Xml::element + */ + public function testElementEscaping() { $this->assertEquals( '<element>hello <there> you & you</element>', Xml::element( 'element', null, 'hello <there> you & you' ), @@ -80,13 +98,19 @@ class XmlTest extends MediaWikiTestCase { ); } + /** + * @covers Xml::escapeTagsOnly + */ public function testEscapeTagsOnly() { $this->assertEquals( '"><', Xml::escapeTagsOnly( '"><' ), 'replace " > and < with their HTML entitites' ); } - function testElementAttributes() { + /** + * @covers Xml::element + */ + public function testElementAttributes() { $this->assertEquals( '<element key="value" <>="<>">', Xml::element( 'element', array( 'key' => 'value', '<>' => '<>' ), null ), @@ -94,7 +118,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testOpenElement() { + /** + * @covers Xml::openElement + */ + public function testOpenElement() { $this->assertEquals( '<element k="v">', Xml::openElement( 'element', array( 'k' => 'v' ) ), @@ -102,10 +129,16 @@ class XmlTest extends MediaWikiTestCase { ); } - function testCloseElement() { + /** + * @covers Xml::closeElement + */ + public function testCloseElement() { $this->assertEquals( '</element>', Xml::closeElement( 'element' ), 'closeElement() shortcut' ); } + /** + * @covers Xml::dateMenu + */ public function testDateMenu() { $curYear = intval( gmdate( 'Y' ) ); $prevYear = $curYear - 1; @@ -186,10 +219,10 @@ class XmlTest extends MediaWikiTestCase { ); } - # - # textarea - # - function testTextareaNoContent() { + /** + * @covers Xml::textarea + */ + public function testTextareaNoContent() { $this->assertEquals( '<textarea name="name" id="name" cols="40" rows="5"></textarea>', Xml::textarea( 'name', '' ), @@ -197,7 +230,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testTextareaAttribs() { + /** + * @covers Xml::textarea + */ + public function testTextareaAttribs() { $this->assertEquals( '<textarea name="name" id="name" cols="20" rows="10"><txt></textarea>', Xml::textarea( 'name', '<txt>', 20, 10 ), @@ -205,10 +241,10 @@ class XmlTest extends MediaWikiTestCase { ); } - # - # input and label - # - function testLabelCreation() { + /** + * @covers Xml::label + */ + public function testLabelCreation() { $this->assertEquals( '<label for="id">name</label>', Xml::label( 'name', 'id' ), @@ -216,7 +252,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testLabelAttributeCanOnlyBeClassOrTitle() { + /** + * @covers Xml::label + */ + public function testLabelAttributeCanOnlyBeClassOrTitle() { $this->assertEquals( '<label for="id">name</label>', Xml::label( 'name', 'id', array( 'generated' => true ) ), @@ -245,7 +284,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testLanguageSelector() { + /** + * @covers Xml::languageSelector + */ + public function testLanguageSelector() { $select = Xml::languageSelector( 'en', true, null, array( 'id' => 'testlang' ), wfMessage( 'yourlanguage' ) ); $this->assertEquals( @@ -254,10 +296,10 @@ class XmlTest extends MediaWikiTestCase { ); } - # - # JS - # - function testEscapeJsStringSpecialChars() { + /** + * @covers Xml::escapeJsString + */ + public function testEscapeJsStringSpecialChars() { $this->assertEquals( '\\\\\r\n', Xml::escapeJsString( "\\\r\n" ), @@ -265,7 +307,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testEncodeJsVarBoolean() { + /** + * @covers Xml::encodeJsVar + */ + public function testEncodeJsVarBoolean() { $this->assertEquals( 'true', Xml::encodeJsVar( true ), @@ -273,7 +318,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testEncodeJsVarNull() { + /** + * @covers Xml::encodeJsVar + */ + public function testEncodeJsVarNull() { $this->assertEquals( 'null', Xml::encodeJsVar( null ), @@ -281,7 +329,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testEncodeJsVarArray() { + /** + * @covers Xml::encodeJsVar + */ + public function testEncodeJsVarArray() { $this->assertEquals( '["a",1]', Xml::encodeJsVar( array( 'a', 1 ) ), @@ -294,7 +345,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testEncodeJsVarObject() { + /** + * @covers Xml::encodeJsVar + */ + public function testEncodeJsVarObject() { $this->assertEquals( '{"a":"a","b":1}', Xml::encodeJsVar( (object)array( 'a' => 'a', 'b' => 1 ) ), @@ -302,7 +356,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testEncodeJsVarInt() { + /** + * @covers Xml::encodeJsVar + */ + public function testEncodeJsVarInt() { $this->assertEquals( '123456', Xml::encodeJsVar( 123456 ), @@ -310,7 +367,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testEncodeJsVarFloat() { + /** + * @covers Xml::encodeJsVar + */ + public function testEncodeJsVarFloat() { $this->assertEquals( '1.23456', Xml::encodeJsVar( 1.23456 ), @@ -318,7 +378,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testEncodeJsVarIntString() { + /** + * @covers Xml::encodeJsVar + */ + public function testEncodeJsVarIntString() { $this->assertEquals( '"123456"', Xml::encodeJsVar( '123456' ), @@ -326,7 +389,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testEncodeJsVarFloatString() { + /** + * @covers Xml::encodeJsVar + */ + public function testEncodeJsVarFloatString() { $this->assertEquals( '"1.23456"', Xml::encodeJsVar( '1.23456' ), diff --git a/tests/phpunit/includes/XmlTypeCheckTest.php b/tests/phpunit/includes/XmlTypeCheckTest.php new file mode 100644 index 00000000..8d6f1ed7 --- /dev/null +++ b/tests/phpunit/includes/XmlTypeCheckTest.php @@ -0,0 +1,30 @@ +<?php +/** + * PHPUnit tests for XMLTypeCheck. + * @author physikerwelt + * @group Xml + * @covers XMLTypeCheck + */ +class XmlTypeCheckTest extends MediaWikiTestCase { + const WELL_FORMED_XML = "<root><child /></root>"; + const MAL_FORMED_XML = "<root><child /></error>"; + + /** + * @covers XMLTypeCheck::newFromString + * @covers XMLTypeCheck::getRootElement + */ + public function testWellFormedXML() { + $testXML = XmlTypeCheck::newFromString( self::WELL_FORMED_XML ); + $this->assertTrue( $testXML->wellFormed ); + $this->assertEquals( 'root', $testXML->getRootElement() ); + } + + /** + * @covers XMLTypeCheck::newFromString + */ + public function testMalFormedXML() { + $testXML = XmlTypeCheck::newFromString( self::MAL_FORMED_XML ); + $this->assertFalse( $testXML->wellFormed ); + } + +} diff --git a/tests/phpunit/includes/ZipDirectoryReaderTest.php b/tests/phpunit/includes/ZipDirectoryReaderTest.php index 3fea57a0..2627a417 100644 --- a/tests/phpunit/includes/ZipDirectoryReaderTest.php +++ b/tests/phpunit/includes/ZipDirectoryReaderTest.php @@ -1,7 +1,12 @@ <?php +/** + * @covers ZipDirectoryReader + * NOTE: this test is more like an integration test than a unit test + */ class ZipDirectoryReaderTest extends MediaWikiTestCase { - var $zipDir, $entries; + protected $zipDir; + protected $entries; protected function setUp() { parent::setUp(); @@ -24,21 +29,21 @@ class ZipDirectoryReaderTest extends MediaWikiTestCase { $this->assertTrue( $status->isOK(), $assertMessage ); } - function testEmpty() { + public function testEmpty() { $this->readZipAssertSuccess( 'empty.zip', 'Empty zip' ); } - function testMultiDisk0() { + public function testMultiDisk0() { $this->readZipAssertError( 'split.zip', 'zip-unsupported', 'Split zip error' ); } - function testNoSignature() { + public function testNoSignature() { $this->readZipAssertError( 'nosig.zip', 'zip-wrong-format', 'No signature should give "wrong format" error' ); } - function testSimple() { + public function testSimple() { $this->readZipAssertSuccess( 'class.zip', 'Simple ZIP' ); $this->assertEquals( $this->entries, array( array( 'name' => 'Class.class', @@ -47,33 +52,33 @@ class ZipDirectoryReaderTest extends MediaWikiTestCase { ) ) ); } - function testBadCentralEntrySignature() { + public function testBadCentralEntrySignature() { $this->readZipAssertError( 'wrong-central-entry-sig.zip', 'zip-bad', 'Bad central entry error' ); } - function testTrailingBytes() { + public function testTrailingBytes() { $this->readZipAssertError( 'trail.zip', 'zip-bad', 'Trailing bytes error' ); } - function testWrongCDStart() { + public function testWrongCDStart() { $this->readZipAssertError( 'wrong-cd-start-disk.zip', 'zip-unsupported', 'Wrong CD start disk error' ); } - function testCentralDirectoryGap() { + public function testCentralDirectoryGap() { $this->readZipAssertError( 'cd-gap.zip', 'zip-bad', 'CD gap error' ); } - function testCentralDirectoryTruncated() { + public function testCentralDirectoryTruncated() { $this->readZipAssertError( 'cd-truncated.zip', 'zip-bad', 'CD truncated error (should hit unpack() overrun)' ); } - function testLooksLikeZip64() { + public function testLooksLikeZip64() { $this->readZipAssertError( 'looks-like-zip64.zip', 'zip-unsupported', 'A file which looks like ZIP64 but isn\'t, should give error' ); } diff --git a/tests/phpunit/includes/api/ApiAccountCreationTest.php b/tests/phpunit/includes/api/ApiAccountCreationTest.php index 94082e5a..68f80ac9 100644 --- a/tests/phpunit/includes/api/ApiAccountCreationTest.php +++ b/tests/phpunit/includes/api/ApiAccountCreationTest.php @@ -20,7 +20,7 @@ class ApiCreateAccountTest extends ApiTestCase { * a bit slow. Raise the default timeout. * @group medium */ - function testValid() { + public function testValid() { global $wgServer; if ( !isset( $wgServer ) ) { @@ -47,13 +47,16 @@ class ApiCreateAccountTest extends ApiTestCase { $token = $a['token']; // Finally create the account - $ret = $this->doApiRequest( array( - 'action' => 'createaccount', - 'name' => 'Apitestnew', - 'password' => $password, - 'token' => $token, - 'email' => 'test@domain.test', - 'realname' => 'Test Name' ), $ret[2] + $ret = $this->doApiRequest( + array( + 'action' => 'createaccount', + 'name' => 'Apitestnew', + 'password' => $password, + 'token' => $token, + 'email' => 'test@domain.test', + 'realname' => 'Test Name' + ), + $ret[2] ); $result = $ret[0]; @@ -65,8 +68,7 @@ class ApiCreateAccountTest extends ApiTestCase { 'action' => 'login', 'lgname' => 'Apitestnew', 'lgpassword' => $password, - ) - ); + ) ); $result = $ret[0]; $this->assertNotInternalType( 'bool', $result ); @@ -76,12 +78,14 @@ class ApiCreateAccountTest extends ApiTestCase { $this->assertEquals( 'NeedToken', $a ); $token = $result['login']['token']; - $ret = $this->doApiRequest( array( - 'action' => 'login', - 'lgtoken' => $token, - 'lgname' => 'Apitestnew', - 'lgpassword' => $password, - ), $ret[2] + $ret = $this->doApiRequest( + array( + 'action' => 'login', + 'lgtoken' => $token, + 'lgname' => 'Apitestnew', + 'lgpassword' => $password, + ), + $ret[2] ); $result = $ret[0]; @@ -92,9 +96,11 @@ class ApiCreateAccountTest extends ApiTestCase { $this->assertEquals( 'Success', $a ); // log out to destroy the session - $ret = $this->doApiRequest( array( - 'action' => 'logout', - ), $ret[2] + $ret = $this->doApiRequest( + array( + 'action' => 'logout', + ), + $ret[2] ); $this->assertEquals( array(), $ret[0] ); } @@ -103,8 +109,8 @@ class ApiCreateAccountTest extends ApiTestCase { * Make sure requests with no names are invalid. * @expectedException UsageException */ - function testNoName() { - $ret = $this->doApiRequest( array( + public function testNoName() { + $this->doApiRequest( array( 'action' => 'createaccount', 'token' => LoginForm::getCreateaccountToken(), 'password' => 'password', @@ -115,8 +121,8 @@ class ApiCreateAccountTest extends ApiTestCase { * Make sure requests with no password are invalid. * @expectedException UsageException */ - function testNoPassword() { - $ret = $this->doApiRequest( array( + public function testNoPassword() { + $this->doApiRequest( array( 'action' => 'createaccount', 'name' => 'testName', 'token' => LoginForm::getCreateaccountToken(), @@ -127,7 +133,7 @@ class ApiCreateAccountTest extends ApiTestCase { * Make sure requests with existing users are invalid. * @expectedException UsageException */ - function testExistingUser() { + public function testExistingUser() { $this->doApiRequest( array( 'action' => 'createaccount', 'name' => 'Apitestsysop', @@ -141,7 +147,7 @@ class ApiCreateAccountTest extends ApiTestCase { * Make sure requests with invalid emails are invalid. * @expectedException UsageException */ - function testInvalidEmail() { + public function testInvalidEmail() { $this->doApiRequest( array( 'action' => 'createaccount', 'name' => 'Test User', diff --git a/tests/phpunit/includes/api/ApiBlockTest.php b/tests/phpunit/includes/api/ApiBlockTest.php index 94643b10..8afb748a 100644 --- a/tests/phpunit/includes/api/ApiBlockTest.php +++ b/tests/phpunit/includes/api/ApiBlockTest.php @@ -6,7 +6,6 @@ * @group medium */ class ApiBlockTest extends ApiTestCase { - protected function setUp() { parent::setUp(); $this->doLogin(); @@ -35,9 +34,8 @@ class ApiBlockTest extends ApiTestCase { * Which made the Block/Unblock API to actually verify the token * previously always considered valid (bug 34212). */ - function testMakeNormalBlock() { - - $data = $this->getTokens(); + public function testMakeNormalBlock() { + $tokens = $this->getTokens(); $user = User::newFromName( 'UTApiBlockee' ); @@ -45,19 +43,15 @@ class ApiBlockTest extends ApiTestCase { $this->markTestIncomplete( "The user UTApiBlockee does not exist" ); } - if ( !isset( $data[0]['query']['pages'] ) ) { + if ( !array_key_exists( 'blocktoken', $tokens ) ) { $this->markTestIncomplete( "No block token found" ); } - $keys = array_keys( $data[0]['query']['pages'] ); - $key = array_pop( $keys ); - $pageinfo = $data[0]['query']['pages'][$key]; - - $data = $this->doApiRequest( array( + $this->doApiRequest( array( 'action' => 'block', 'user' => 'UTApiBlockee', 'reason' => 'Some reason', - 'token' => $pageinfo['blocktoken'] ), null, false, self::$users['sysop']->user ); + 'token' => $tokens['blocktoken'] ), null, false, self::$users['sysop']->user ); $block = Block::newFromTarget( 'UTApiBlockee' ); @@ -66,7 +60,6 @@ class ApiBlockTest extends ApiTestCase { $this->assertEquals( 'UTApiBlockee', (string)$block->getTarget() ); $this->assertEquals( 'Some reason', $block->mReason ); $this->assertEquals( 'infinity', $block->mExpiry ); - } /** @@ -77,7 +70,7 @@ class ApiBlockTest extends ApiTestCase { * @dataProvider provideBlockUnblockAction * @expectedException UsageException */ - function testBlockingActionWithNoToken( $action ) { + public function testBlockingActionWithNoToken( $action ) { $this->doApiRequest( array( 'action' => $action, @@ -93,7 +86,7 @@ class ApiBlockTest extends ApiTestCase { /** * Just provide the 'block' and 'unblock' action to test both API calls */ - function provideBlockUnblockAction() { + public static function provideBlockUnblockAction() { return array( array( 'block' ), array( 'unblock' ), diff --git a/tests/phpunit/includes/api/ApiEditPageTest.php b/tests/phpunit/includes/api/ApiEditPageTest.php index 1efbaeaf..0c49b12b 100644 --- a/tests/phpunit/includes/api/ApiEditPageTest.php +++ b/tests/phpunit/includes/api/ApiEditPageTest.php @@ -11,10 +11,10 @@ */ class ApiEditPageTest extends ApiTestCase { - public function setup() { + public function setUp() { global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang; - parent::setup(); + parent::setUp(); $wgExtraNamespaces[12312] = 'Dummy'; $wgExtraNamespaces[12313] = 'Dummy_talk'; @@ -28,7 +28,7 @@ class ApiEditPageTest extends ApiTestCase { $this->doLogin(); } - public function teardown() { + public function tearDown() { global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang; unset( $wgExtraNamespaces[12312] ); @@ -40,10 +40,10 @@ class ApiEditPageTest extends ApiTestCase { MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache $wgContLang->resetNamespaces(); # reset namespace cache - parent::teardown(); + parent::tearDown(); } - function testEdit() { + public function testEdit() { $name = 'Help:ApiEditPageTest_testEdit'; // assume Help namespace to default to wikitext // -- test new page -------------------------------------------- @@ -97,7 +97,7 @@ class ApiEditPageTest extends ApiTestCase { ); } - function testNonTextEdit() { + public function testNonTextEdit() { $name = 'Dummy:ApiEditPageTest_testNonTextEdit'; $data = serialize( 'some bla bla text' ); @@ -124,7 +124,7 @@ class ApiEditPageTest extends ApiTestCase { $this->assertEquals( $data, $page->getContent()->serialize() ); } - static function provideEditAppend() { + public static function provideEditAppend() { return array( array( #0: append 'foo', 'append', 'bar', "foobar" @@ -150,7 +150,7 @@ class ApiEditPageTest extends ApiTestCase { /** * @dataProvider provideEditAppend */ - function testEditAppend( $text, $op, $append, $expected ) { + public function testEditAppend( $text, $op, $append, $expected ) { static $count = 0; $count++; @@ -161,13 +161,13 @@ class ApiEditPageTest extends ApiTestCase { if ( $text !== null ) { if ( $text === '' ) { // can't create an empty page, so create it with some content - list( $re, , ) = $this->doApiRequestWithToken( array( + $this->doApiRequestWithToken( array( 'action' => 'edit', 'title' => $name, 'text' => '(dummy)', ) ); } - list( $re, , ) = $this->doApiRequestWithToken( array( + list( $re ) = $this->doApiRequestWithToken( array( 'action' => 'edit', 'title' => $name, 'text' => $text, ) ); @@ -176,7 +176,7 @@ class ApiEditPageTest extends ApiTestCase { } // -- try append/prepend -------------------------------------------- - list( $re, , ) = $this->doApiRequestWithToken( array( + list( $re ) = $this->doApiRequestWithToken( array( 'action' => 'edit', 'title' => $name, $op . 'text' => $append, ) ); @@ -193,15 +193,80 @@ class ApiEditPageTest extends ApiTestCase { $this->assertEquals( $expected, $text ); } - function testEditSection() { - $this->markTestIncomplete( "not yet implemented" ); + /** + * Test editing of sections + */ + public function testEditSection() { + $name = 'Help:ApiEditPageTest_testEditSection'; + $page = WikiPage::factory( Title::newFromText( $name ) ); + $text = "==section 1==\ncontent 1\n==section 2==\ncontent2"; + // Preload the page with some text + $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), 'summary' ); + + list( $re ) = $this->doApiRequestWithToken( array( + 'action' => 'edit', + 'title' => $name, + 'section' => '1', + 'text' => "==section 1==\nnew content 1", + ) ); + $this->assertEquals( 'Success', $re['edit']['result'] ); + $newtext = WikiPage::factory( Title::newFromText( $name) )->getContent( Revision::RAW )->getNativeData(); + $this->assertEquals( $newtext, "==section 1==\nnew content 1\n\n==section 2==\ncontent2" ); + + // Test that we raise a 'nosuchsection' error + try { + $this->doApiRequestWithToken( array( + 'action' => 'edit', + 'title' => $name, + 'section' => '9999', + 'text' => 'text', + ) ); + $this->fail( "Should have raised a UsageException" ); + } catch ( UsageException $e ) { + $this->assertEquals( $e->getCodeString(), 'nosuchsection' ); + } } - function testUndo() { - $this->markTestIncomplete( "not yet implemented" ); + /** + * Test action=edit§ion=new + * Run it twice so we test adding a new section on a + * page that doesn't exist (bug 52830) and one that + * does exist + */ + public function testEditNewSection() { + $name = 'Help:ApiEditPageTest_testEditNewSection'; + + // Test on a page that does not already exist + $this->assertFalse( Title::newFromText( $name )->exists() ); + list( $re ) = $this->doApiRequestWithToken( array( + 'action' => 'edit', + 'title' => $name, + 'section' => 'new', + 'text' => 'test', + 'summary' => 'header', + )); + + $this->assertEquals( 'Success', $re['edit']['result'] ); + // Check the page text is correct + $text = WikiPage::factory( Title::newFromText( $name ) )->getContent( Revision::RAW )->getNativeData(); + $this->assertEquals( $text, "== header ==\n\ntest" ); + + // Now on one that does + $this->assertTrue( Title::newFromText( $name )->exists() ); + list( $re2 ) = $this->doApiRequestWithToken( array( + 'action' => 'edit', + 'title' => $name, + 'section' => 'new', + 'text' => 'test', + 'summary' => 'header', + )); + + $this->assertEquals( 'Success', $re2['edit']['result'] ); + $text = WikiPage::factory( Title::newFromText( $name ) )->getContent( Revision::RAW )->getNativeData(); + $this->assertEquals( $text, "== header ==\n\ntest\n\n== header ==\n\ntest" ); } - function testEditConflict() { + public function testEditConflict() { static $count = 0; $count++; @@ -224,7 +289,7 @@ class ApiEditPageTest extends ApiTestCase { // try to save edit, expect conflict try { - list( $re, , ) = $this->doApiRequestWithToken( array( + $this->doApiRequestWithToken( array( 'action' => 'edit', 'title' => $name, 'text' => 'nix bar!', @@ -237,7 +302,7 @@ class ApiEditPageTest extends ApiTestCase { } } - function testEditConflict_redirect() { + public function testEditConflict_redirect() { static $count = 0; $count++; @@ -280,7 +345,7 @@ class ApiEditPageTest extends ApiTestCase { // try again, without following the redirect. Should fail. try { - list( $re, , ) = $this->doApiRequestWithToken( array( + $this->doApiRequestWithToken( array( 'action' => 'edit', 'title' => $rname, 'text' => 'nix bar!', @@ -293,13 +358,13 @@ class ApiEditPageTest extends ApiTestCase { } } - function testEditConflict_bug41990() { + public function testEditConflict_bug41990() { static $count = 0; $count++; /* * bug 41990: if the target page has a newer revision than the redirect, then editing the - * redirect while specifying 'redirect' and *not* specifying 'basetimestamp' erronously + * redirect while specifying 'redirect' and *not* specifying 'basetimestamp' erroneously * caused an edit conflict to be detected. */ diff --git a/tests/phpunit/includes/api/ApiOptionsTest.php b/tests/phpunit/includes/api/ApiOptionsTest.php index 902b7b85..ad1e73ab 100644 --- a/tests/phpunit/includes/api/ApiOptionsTest.php +++ b/tests/phpunit/includes/api/ApiOptionsTest.php @@ -20,9 +20,11 @@ class ApiOptionsTest extends MediaWikiLangTestCase { ->disableOriginalConstructor() ->getMock(); - // Set up groups + // Set up groups and rights $this->mUserMock->expects( $this->any() ) ->method( 'getEffectiveGroups' )->will( $this->returnValue( array( '*', 'user' ) ) ); + $this->mUserMock->expects( $this->any() ) + ->method( 'isAllowed' )->will( $this->returnValue( true ) ); // Set up callback for User::getOptionKinds $this->mUserMock->expects( $this->any() ) @@ -116,6 +118,7 @@ class ApiOptionsTest extends MediaWikiLangTestCase { $mapping[$key] = 'unused'; } } + return $mapping; } @@ -126,12 +129,14 @@ class ApiOptionsTest extends MediaWikiLangTestCase { 'optionname' => null, 'optionvalue' => null, ); + return array_merge( $request, $custom ); } private function executeQuery( $request ) { $this->mContext->setRequest( new FauxRequest( $request, true, $this->mSession ) ); $this->mTested->execute(); + return $this->mTested->getResult()->getData(); } @@ -156,6 +161,7 @@ class ApiOptionsTest extends MediaWikiLangTestCase { } catch ( UsageException $e ) { $this->assertEquals( 'notloggedin', $e->getCodeString() ); $this->assertEquals( 'Anonymous users cannot change preferences', $e->getMessage() ); + return; } $this->fail( "UsageException was not thrown" ); @@ -169,6 +175,7 @@ class ApiOptionsTest extends MediaWikiLangTestCase { } catch ( UsageException $e ) { $this->assertEquals( 'nooptionname', $e->getCodeString() ); $this->assertEquals( 'The optionname parameter must be set', $e->getMessage() ); + return; } $this->fail( "UsageException was not thrown" ); @@ -191,6 +198,7 @@ class ApiOptionsTest extends MediaWikiLangTestCase { } catch ( UsageException $e ) { $this->assertEquals( 'nochanges', $e->getCodeString() ); $this->assertEquals( 'No changes were requested', $e->getMessage() ); + return; } $this->fail( "UsageException was not thrown" ); @@ -274,21 +282,21 @@ class ApiOptionsTest extends MediaWikiLangTestCase { $this->mUserMock->expects( $this->at( 2 ) ) ->method( 'getOptions' ); - $this->mUserMock->expects( $this->at( 3 ) ) + $this->mUserMock->expects( $this->at( 4 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'willBeNull' ), $this->identicalTo( null ) ); - $this->mUserMock->expects( $this->at( 4 ) ) + $this->mUserMock->expects( $this->at( 5 ) ) ->method( 'getOptions' ); - $this->mUserMock->expects( $this->at( 5 ) ) + $this->mUserMock->expects( $this->at( 6 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'willBeEmpty' ), $this->equalTo( '' ) ); - $this->mUserMock->expects( $this->at( 6 ) ) + $this->mUserMock->expects( $this->at( 7 ) ) ->method( 'getOptions' ); - $this->mUserMock->expects( $this->at( 7 ) ) + $this->mUserMock->expects( $this->at( 8 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'willBeHappy' ), $this->equalTo( 'Happy' ) ); @@ -306,17 +314,17 @@ class ApiOptionsTest extends MediaWikiLangTestCase { $this->mUserMock->expects( $this->once() ) ->method( 'resetOptions' ); - $this->mUserMock->expects( $this->at( 3 ) ) + $this->mUserMock->expects( $this->at( 4 ) ) ->method( 'getOptions' ); - $this->mUserMock->expects( $this->at( 4 ) ) + $this->mUserMock->expects( $this->at( 5 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'willBeHappy' ), $this->equalTo( 'Happy' ) ); - $this->mUserMock->expects( $this->at( 5 ) ) + $this->mUserMock->expects( $this->at( 6 ) ) ->method( 'getOptions' ); - $this->mUserMock->expects( $this->at( 6 ) ) + $this->mUserMock->expects( $this->at( 7 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'name' ), $this->equalTo( 'value' ) ); @@ -339,19 +347,19 @@ class ApiOptionsTest extends MediaWikiLangTestCase { $this->mUserMock->expects( $this->never() ) ->method( 'resetOptions' ); - $this->mUserMock->expects( $this->at( 2 ) ) + $this->mUserMock->expects( $this->at( 3 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'testmultiselect-opt1' ), $this->identicalTo( true ) ); - $this->mUserMock->expects( $this->at( 3 ) ) + $this->mUserMock->expects( $this->at( 4 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'testmultiselect-opt2' ), $this->identicalTo( null ) ); - $this->mUserMock->expects( $this->at( 4 ) ) + $this->mUserMock->expects( $this->at( 5 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'testmultiselect-opt3' ), $this->identicalTo( false ) ); - $this->mUserMock->expects( $this->at( 5 ) ) + $this->mUserMock->expects( $this->at( 6 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'testmultiselect-opt4' ), $this->identicalTo( false ) ); @@ -394,7 +402,7 @@ class ApiOptionsTest extends MediaWikiLangTestCase { $this->mUserMock->expects( $this->never() ) ->method( 'resetOptions' ); - $this->mUserMock->expects( $this->at( 2 ) ) + $this->mUserMock->expects( $this->at( 3 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'userjs-option' ), $this->equalTo( '1' ) ); diff --git a/tests/phpunit/includes/api/ApiParseTest.php b/tests/phpunit/includes/api/ApiParseTest.php index a42e5aa5..2d714e65 100644 --- a/tests/phpunit/includes/api/ApiParseTest.php +++ b/tests/phpunit/includes/api/ApiParseTest.php @@ -12,11 +12,11 @@ class ApiParseTest extends ApiTestCase { $this->doLogin(); } - function testParseNonexistentPage() { + public function testParseNonexistentPage() { $somePage = mt_rand(); try { - $data = $this->doApiRequest( array( + $this->doApiRequest( array( 'action' => 'parse', 'page' => $somePage ) ); @@ -26,5 +26,4 @@ class ApiParseTest extends ApiTestCase { "Parse request for nonexistent page must give 'missingtitle' error: " . var_export( $ex->getMessageArray(), true ) ); } } - } diff --git a/tests/phpunit/includes/api/ApiPurgeTest.php b/tests/phpunit/includes/api/ApiPurgeTest.php index a7f9229d..28b5ff4d 100644 --- a/tests/phpunit/includes/api/ApiPurgeTest.php +++ b/tests/phpunit/includes/api/ApiPurgeTest.php @@ -15,7 +15,7 @@ class ApiPurgeTest extends ApiTestCase { /** * @group Broken */ - function testPurgeMainPage() { + public function testPurgeMainPage() { if ( !Title::newFromText( 'UTPage' )->exists() ) { $this->markTestIncomplete( "The article [[UTPage]] does not exist" ); } @@ -37,5 +37,4 @@ class ApiPurgeTest extends ApiTestCase { $this->assertArrayHasKey( $pages[$v['title']], $v ); } } - } diff --git a/tests/phpunit/includes/api/ApiTest.php b/tests/phpunit/includes/api/ApiTest.php index 22770288..472f8c4a 100644 --- a/tests/phpunit/includes/api/ApiTest.php +++ b/tests/phpunit/includes/api/ApiTest.php @@ -7,7 +7,7 @@ */ class ApiTest extends ApiTestCase { - function testRequireOnlyOneParameterDefault() { + public function testRequireOnlyOneParameterDefault() { $mock = new MockApi(); $this->assertEquals( @@ -18,7 +18,7 @@ class ApiTest extends ApiTestCase { /** * @expectedException UsageException */ - function testRequireOnlyOneParameterZero() { + public function testRequireOnlyOneParameterZero() { $mock = new MockApi(); $this->assertEquals( @@ -29,7 +29,7 @@ class ApiTest extends ApiTestCase { /** * @expectedException UsageException */ - function testRequireOnlyOneParameterTrue() { + public function testRequireOnlyOneParameterTrue() { $mock = new MockApi(); $this->assertEquals( @@ -43,7 +43,7 @@ class ApiTest extends ApiTestCase { * * @expectedException UsageException */ - function testApi() { + public function testApi() { $api = new ApiMain( new FauxRequest( array( 'action' => 'help', 'format' => 'xml' ) ) ); @@ -61,14 +61,14 @@ class ApiTest extends ApiTestCase { /** * Test result of attempted login with an empty username */ - function testApiLoginNoName() { + public function testApiLoginNoName() { $data = $this->doApiRequest( array( 'action' => 'login', 'lgname' => '', 'lgpassword' => self::$users['sysop']->password, ) ); $this->assertEquals( 'NoName', $data[0]['login']['result'] ); } - function testApiLoginBadPass() { + public function testApiLoginBadPass() { global $wgServer; $user = self::$users['sysop']; @@ -81,8 +81,7 @@ class ApiTest extends ApiTestCase { "action" => "login", "lgname" => $user->username, "lgpassword" => "bad", - ) - ); + ) ); $result = $ret[0]; @@ -110,7 +109,7 @@ class ApiTest extends ApiTestCase { $this->assertEquals( "WrongPass", $a ); } - function testApiLoginGoodPass() { + public function testApiLoginGoodPass() { global $wgServer; if ( !isset( $wgServer ) ) { @@ -136,7 +135,7 @@ class ApiTest extends ApiTestCase { $token = $result["login"]["token"]; $ret = $this->doApiRequest( - array( + array( "action" => "login", "lgtoken" => $token, "lgname" => $user->username, @@ -156,7 +155,7 @@ class ApiTest extends ApiTestCase { /** * @group Broken */ - function testApiGotCookie() { + public function testApiGotCookie() { $this->markTestIncomplete( "The server can't do external HTTP requests, and the internal one won't give cookies" ); global $wgServer, $wgScriptPath; @@ -202,7 +201,7 @@ class ApiTest extends ApiTestCase { return $cj; } - function testRunLogin() { + public function testRunLogin() { $sysopUser = self::$users['sysop']; $data = $this->doApiRequest( array( 'action' => 'login', @@ -228,39 +227,33 @@ class ApiTest extends ApiTestCase { return $data; } - function testGettingToken() { + public function testGettingToken() { foreach ( self::$users as $user ) { $this->runTokenTest( $user ); } } function runTokenTest( $user ) { - $data = $this->getTokenList( $user ); - - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'pages', $data[0]['query'] ); - $keys = array_keys( $data[0]['query']['pages'] ); - $key = array_pop( $keys ); + $tokens = $this->getTokenList( $user ); $rights = $user->user->getRights(); - $this->assertArrayHasKey( $key, $data[0]['query']['pages'] ); - $this->assertArrayHasKey( 'edittoken', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 'movetoken', $data[0]['query']['pages'][$key] ); + $this->assertArrayHasKey( 'edittoken', $tokens ); + $this->assertArrayHasKey( 'movetoken', $tokens ); if ( isset( $rights['delete'] ) ) { - $this->assertArrayHasKey( 'deletetoken', $data[0]['query']['pages'][$key] ); + $this->assertArrayHasKey( 'deletetoken', $tokens ); } if ( isset( $rights['block'] ) ) { - $this->assertArrayHasKey( 'blocktoken', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 'unblocktoken', $data[0]['query']['pages'][$key] ); + $this->assertArrayHasKey( 'blocktoken', $tokens ); + $this->assertArrayHasKey( 'unblocktoken', $tokens ); } if ( isset( $rights['protect'] ) ) { - $this->assertArrayHasKey( 'protecttoken', $data[0]['query']['pages'][$key] ); + $this->assertArrayHasKey( 'protecttoken', $tokens ); } - return $data; + return $tokens; } } diff --git a/tests/phpunit/includes/api/ApiTestCase.php b/tests/phpunit/includes/api/ApiTestCase.php index 552fbfbf..94ef9c68 100644 --- a/tests/phpunit/includes/api/ApiTestCase.php +++ b/tests/phpunit/includes/api/ApiTestCase.php @@ -52,6 +52,7 @@ abstract class ApiTestCase extends MediaWikiLangTestCase { protected function editPage( $pageName, $text, $summary = '', $defaultNs = NS_MAIN ) { $title = Title::newFromText( $pageName, $defaultNs ); $page = WikiPage::factory( $title ); + return $page->doEditContent( ContentHandler::makeContent( $text, $title ), $summary ); } @@ -131,17 +132,22 @@ abstract class ApiTestCase extends MediaWikiLangTestCase { $session['wsEditToken'] = $session['wsToken']; // add token to request parameters $params['token'] = md5( $session['wsToken'] ) . User::EDIT_TOKEN_SUFFIX; + return $this->doApiRequest( $params, $session, false, $user ); } else { throw new Exception( "request data not in right format" ); } } - protected function doLogin() { + protected function doLogin( $user = 'sysop' ) { + if ( !array_key_exists( $user, self::$users ) ) { + throw new MWException( "Can not log in to undefined user $user" ); + } + $data = $this->doApiRequest( array( 'action' => 'login', - 'lgname' => self::$users['sysop']->username, - 'lgpassword' => self::$users['sysop']->password ) ); + 'lgname' => self::$users[ $user ]->username, + 'lgpassword' => self::$users[ $user ]->password ) ); $token = $data[0]['login']['token']; @@ -149,8 +155,8 @@ abstract class ApiTestCase extends MediaWikiLangTestCase { array( 'action' => 'login', 'lgtoken' => $token, - 'lgname' => self::$users['sysop']->username, - 'lgpassword' => self::$users['sysop']->password, + 'lgname' => self::$users[ $user ]->username, + 'lgpassword' => self::$users[ $user ]->password, ), $data[2] ); @@ -160,11 +166,15 @@ abstract class ApiTestCase extends MediaWikiLangTestCase { protected function getTokenList( $user, $session = null ) { $data = $this->doApiRequest( array( - 'action' => 'query', - 'titles' => 'Main Page', - 'intoken' => 'edit|delete|protect|move|block|unblock|watch', - 'prop' => 'info' ), $session, false, $user->user ); - return $data; + 'action' => 'tokens', + 'type' => 'edit|delete|protect|move|block|unblock|watch' + ), $session, false, $user->user ); + + if ( !array_key_exists( 'tokens', $data[0] ) ) { + throw new MWException( 'Api failed to return a token list' ); + } + + return $data[0]['tokens']; } public function testApiTestGroup() { @@ -204,11 +214,14 @@ class UserWrapper { } class MockApi extends ApiBase { - public function execute() {} + public function execute() { + } - public function getVersion() {} + public function getVersion() { + } - public function __construct() {} + public function __construct() { + } public function getAllowedParams() { return array( @@ -234,6 +247,7 @@ class ApiTestContext extends RequestContext { if ( $user !== null ) { $context->setUser( $user ); } + return $context; } } diff --git a/tests/phpunit/includes/api/ApiTestCaseUpload.php b/tests/phpunit/includes/api/ApiTestCaseUpload.php index 80284917..7e18b6ed 100644 --- a/tests/phpunit/includes/api/ApiTestCaseUpload.php +++ b/tests/phpunit/includes/api/ApiTestCaseUpload.php @@ -47,6 +47,7 @@ abstract class ApiTestCaseUpload extends ApiTestCase { // see if it now doesn't exist; reload $title = Title::newFromText( $title->getText(), NS_FILE ); } + return !( $title && $title instanceof Title && $title->exists() ); } @@ -69,6 +70,7 @@ abstract class ApiTestCaseUpload extends ApiTestCase { foreach ( $dupes as $dupe ) { $success &= $this->deleteFileByTitle( $dupe->getTitle() ); } + return $success; } @@ -105,7 +107,6 @@ abstract class ApiTestCaseUpload extends ApiTestCase { ); return true; - } function fakeUploadChunk( $fieldName, $fileName, $type, & $chunkData ) { @@ -145,5 +146,4 @@ abstract class ApiTestCaseUpload extends ApiTestCase { function clearFakeUploads() { $_FILES = array(); } - } diff --git a/tests/phpunit/includes/api/ApiUploadTest.php b/tests/phpunit/includes/api/ApiUploadTest.php index 0d98b04d..1540af55 100644 --- a/tests/phpunit/includes/api/ApiUploadTest.php +++ b/tests/phpunit/includes/api/ApiUploadTest.php @@ -16,7 +16,7 @@ // TODO: port the other Upload tests, and other API tests to this framework -require_once( 'ApiTestCaseUpload.php' ); +require_once 'ApiTestCaseUpload.php'; /** * @group Database @@ -27,12 +27,11 @@ require_once( 'ApiTestCaseUpload.php' ); * This is pretty sucky... needs to be prettified. */ class ApiUploadTest extends ApiTestCaseUpload { - /** * Testing login * XXX this is a funny way of getting session context */ - function testLogin() { + public function testLogin() { $user = self::$users['uploader']; $params = array( @@ -59,8 +58,8 @@ class ApiUploadTest extends ApiTestCaseUpload { $this->assertArrayHasKey( 'lgtoken', $result['login'] ); $this->assertNotEmpty( $session, 'API Login must return a session' ); - return $session; + return $session; } /** @@ -118,7 +117,6 @@ class ApiUploadTest extends ApiTestCaseUpload { $this->deleteFileByFileName( $fileName ); $this->deleteFileByContent( $filePath ); - if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) { $this->markTestIncomplete( "Couldn't upload file!\n" ); } @@ -140,7 +138,7 @@ class ApiUploadTest extends ApiTestCaseUpload { } $this->assertTrue( isset( $result['upload'] ) ); $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertEquals( $fileSize, ( int )$result['upload']['imageinfo']['size'] ); + $this->assertEquals( $fileSize, (int)$result['upload']['imageinfo']['size'] ); $this->assertEquals( $mimeType, $result['upload']['imageinfo']['mime'] ); $this->assertFalse( $exception ); @@ -298,7 +296,7 @@ class ApiUploadTest extends ApiTestCaseUpload { $exception = false; try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, + list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); } catch ( UsageException $e ) { $exception = true; @@ -307,7 +305,6 @@ class ApiUploadTest extends ApiTestCaseUpload { $this->assertEquals( 'Success', $result['upload']['result'] ); $this->assertFalse( $exception ); - // second upload with the same content (but different name) if ( !$this->fakeUploadFile( 'file', $fileNames[1], $mimeType, $filePaths[0] ) ) { @@ -324,7 +321,7 @@ class ApiUploadTest extends ApiTestCaseUpload { $exception = false; try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, + list( $result ) = $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); // FIXME: leaks a temporary file } catch ( UsageException $e ) { $exception = true; @@ -341,7 +338,6 @@ class ApiUploadTest extends ApiTestCaseUpload { unlink( $filePaths[0] ); } - /** * @depends testLogin */ @@ -382,7 +378,7 @@ class ApiUploadTest extends ApiTestCaseUpload { $exception = false; try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, + list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); // FIXME: leaks a temporary file } catch ( UsageException $e ) { $exception = true; @@ -390,7 +386,7 @@ class ApiUploadTest extends ApiTestCaseUpload { $this->assertFalse( $exception ); $this->assertTrue( isset( $result['upload'] ) ); $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertEquals( $fileSize, ( int )$result['upload']['imageinfo']['size'] ); + $this->assertEquals( $fileSize, (int)$result['upload']['imageinfo']['size'] ); $this->assertEquals( $mimeType, $result['upload']['imageinfo']['mime'] ); $this->assertTrue( isset( $result['upload']['filekey'] ) ); $this->assertEquals( $result['upload']['sessionkey'], $result['upload']['filekey'] ); @@ -411,7 +407,7 @@ class ApiUploadTest extends ApiTestCaseUpload { $this->clearFakeUploads(); $exception = false; try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, + list( $result ) = $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); } catch ( UsageException $e ) { $exception = true; @@ -454,7 +450,7 @@ class ApiUploadTest extends ApiTestCaseUpload { $this->deleteFileByFileName( $fileName ); $this->deleteFileByContent( $filePath ); - // Base upload params: + // Base upload params: $params = array( 'action' => 'upload', 'stash' => 1, @@ -466,7 +462,7 @@ class ApiUploadTest extends ApiTestCaseUpload { // Upload chunks $chunkSessionKey = false; $resultOffset = 0; - // Open the file: + // Open the file: $handle = @fopen( $filePath, "r" ); if ( $handle === false ) { $this->markTestIncomplete( "could not open file: $filePath" ); @@ -482,15 +478,15 @@ class ApiUploadTest extends ApiTestCaseUpload { if ( !$chunkSessionKey ) { // Upload fist chunk ( and get the session key ) try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, + list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); } catch ( UsageException $e ) { $this->markTestIncomplete( $e->getMessage() ); } - // Make sure we got a valid chunk continue: + // Make sure we got a valid chunk continue: $this->assertTrue( isset( $result['upload'] ) ); $this->assertTrue( isset( $result['upload']['filekey'] ) ); - // If we don't get a session key mark test incomplete. + // If we don't get a session key mark test incomplete. if ( !isset( $result['upload']['filekey'] ) ) { $this->markTestIncomplete( "no filekey provided" ); } @@ -509,16 +505,16 @@ class ApiUploadTest extends ApiTestCaseUpload { $this->assertEquals( $resultOffset, $params['offset'] ); // Upload current chunk try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, + list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); } catch ( UsageException $e ) { $this->markTestIncomplete( $e->getMessage() ); } - // Make sure we got a valid chunk continue: + // Make sure we got a valid chunk continue: $this->assertTrue( isset( $result['upload'] ) ); $this->assertTrue( isset( $result['upload']['filekey'] ) ); - // Check if we were on the last chunk: + // Check if we were on the last chunk: if ( $params['offset'] + $chunkSize >= $fileSize ) { $this->assertEquals( 'Success', $result['upload']['result'] ); break; @@ -548,7 +544,7 @@ class ApiUploadTest extends ApiTestCaseUpload { $this->clearFakeUploads(); $exception = false; try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, + list( $result ) = $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); } catch ( UsageException $e ) { $exception = true; @@ -559,7 +555,7 @@ class ApiUploadTest extends ApiTestCaseUpload { // clean up $this->deleteFileByFilename( $fileName ); - // don't remove downloaded temporary file for fast subquent tests. + // don't remove downloaded temporary file for fast subquent tests. //unlink( $filePath ); } } diff --git a/tests/phpunit/includes/api/ApiWatchTest.php b/tests/phpunit/includes/api/ApiWatchTest.php index aefd9398..028ea9ff 100644 --- a/tests/phpunit/includes/api/ApiWatchTest.php +++ b/tests/phpunit/includes/api/ApiWatchTest.php @@ -7,32 +7,25 @@ * @todo This test suite is severly broken and need a full review */ class ApiWatchTest extends ApiTestCase { - protected function setUp() { parent::setUp(); $this->doLogin(); } function getTokens() { - $data = $this->getTokenList( self::$users['sysop'] ); - - $keys = array_keys( $data[0]['query']['pages'] ); - $key = array_pop( $keys ); - $pageinfo = $data[0]['query']['pages'][$key]; - - return $pageinfo; + return $this->getTokenList( self::$users['sysop'] ); } /** */ - function testWatchEdit() { - $pageinfo = $this->getTokens(); + public function testWatchEdit() { + $tokens = $this->getTokens(); $data = $this->doApiRequest( array( 'action' => 'edit', 'title' => 'Help:UTPage', // Help namespace is hopefully wikitext 'text' => 'new text', - 'token' => $pageinfo['edittoken'], + 'token' => $tokens['edittoken'], 'watchlist' => 'watch' ) ); $this->assertArrayHasKey( 'edit', $data[0] ); $this->assertArrayHasKey( 'result', $data[0]['edit'] ); @@ -44,9 +37,8 @@ class ApiWatchTest extends ApiTestCase { /** * @depends testWatchEdit */ - function testWatchClear() { - - $pageinfo = $this->getTokens(); + public function testWatchClear() { + $tokens = $this->getTokens(); $data = $this->doApiRequest( array( 'action' => 'query', @@ -60,7 +52,7 @@ class ApiWatchTest extends ApiTestCase { 'action' => 'watch', 'title' => $page['title'], 'unwatch' => true, - 'token' => $pageinfo['watchtoken'] ) ); + 'token' => $tokens['watchtoken'] ) ); } } $data = $this->doApiRequest( array( @@ -75,13 +67,12 @@ class ApiWatchTest extends ApiTestCase { /** */ - function testWatchProtect() { - - $pageinfo = $this->getTokens(); + public function testWatchProtect() { + $tokens = $this->getTokens(); $data = $this->doApiRequest( array( 'action' => 'protect', - 'token' => $pageinfo['protecttoken'], + 'token' => $tokens['protecttoken'], 'title' => 'Help:UTPage', 'protections' => 'edit=sysop', 'watchlist' => 'unwatch' ) ); @@ -94,9 +85,8 @@ class ApiWatchTest extends ApiTestCase { /** */ - function testGetRollbackToken() { - - $pageinfo = $this->getTokens(); + public function testGetRollbackToken() { + $this->getTokens(); if ( !Title::newFromText( 'Help:UTPage' )->exists() ) { $this->markTestSkipped( "The article [[Help:UTPage]] does not exist" ); //TODO: just create it? @@ -131,7 +121,7 @@ class ApiWatchTest extends ApiTestCase { * * @depends testGetRollbackToken */ - function testWatchRollback( $data ) { + public function testWatchRollback( $data ) { $keys = array_keys( $data[0]['query']['pages'] ); $key = array_pop( $keys ); $pageinfo = $data[0]['query']['pages'][$key]; @@ -155,23 +145,4 @@ class ApiWatchTest extends ApiTestCase { } } } - - /** - */ - function testWatchDelete() { - $pageinfo = $this->getTokens(); - - $data = $this->doApiRequest( array( - 'action' => 'delete', - 'token' => $pageinfo['deletetoken'], - 'title' => 'Help:UTPage' ) ); - $this->assertArrayHasKey( 'delete', $data[0] ); - $this->assertArrayHasKey( 'title', $data[0]['delete'] ); - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'list' => 'watchlist' ) ); - - $this->markTestIncomplete( 'This test needs to verify the deleted article was added to the users watchlist' ); - } } diff --git a/tests/phpunit/includes/api/RandomImageGenerator.php b/tests/phpunit/includes/api/RandomImageGenerator.php index 30407582..59756b21 100644 --- a/tests/phpunit/includes/api/RandomImageGenerator.php +++ b/tests/phpunit/includes/api/RandomImageGenerator.php @@ -34,7 +34,7 @@ class RandomImageGenerator { private $shapesToDraw = 5; /** - * Orientations: 0th row, 0th column, EXIF orientation code, rotation 2x2 matrix that is opposite of orientation + * Orientations: 0th row, 0th column, Exif orientation code, rotation 2x2 matrix that is opposite of orientation * n.b. we do not handle the 'flipped' orientations, which is why there is no entry for 2, 4, 5, or 7. Those * seem to be rare in real images anyway * (we also would need a non-symmetric shape for the images to test those, like a letter F) @@ -108,6 +108,7 @@ class RandomImageGenerator { foreach ( $filenames as $filename ) { $this->{$imageWriteMethod}( $this->getImageSpec(), $format, $filename ); } + return $filenames; } @@ -156,7 +157,6 @@ class RandomImageGenerator { } return $filenames; - } @@ -196,7 +196,6 @@ class RandomImageGenerator { array( 'x' => $originX, 'y' => $originY - $radius ) ); $draws[] = $draw; - } $spec['draws'] = $draws; @@ -216,6 +215,7 @@ class RandomImageGenerator { foreach ( $shape as $point ) { $points[] = $point['x'] . ',' . $point['y']; } + return join( " ", $points ); } @@ -304,7 +304,7 @@ class RandomImageGenerator { /** * Given an image specification, produce rotated version - * This is used when simulating a rotated image capture with EXIF orientation + * This is used when simulating a rotated image capture with Exif orientation * @param $spec Object returned by getImageSpec * @param $matrix 2x2 transformation matrix * @return transformed Spec @@ -337,6 +337,7 @@ class RandomImageGenerator { } $tSpec['draws'][] = $tDraw; } + return $tSpec; } @@ -384,6 +385,7 @@ class RandomImageGenerator { $command = wfEscapeShellArg( $wgImageMagickConvertCommand ) . " " . implode( " ", $args ); $retval = null; wfShellExec( $command, $retval ); + return ( $retval === 0 ); } @@ -397,6 +399,7 @@ class RandomImageGenerator { for ( $i = 0; $i <= 2; $i++ ) { $components[] = mt_rand( 0, 255 ); } + return 'rgb(' . join( ', ', $components ) . ')'; } @@ -414,6 +417,7 @@ class RandomImageGenerator { for ( $i = 0; $i < $count; $i += 2 ) { $pairs[] = array( $lines[$i], $lines[$i + 1] ); } + return $pairs; } @@ -461,5 +465,4 @@ class RandomImageGenerator { return $lines; } - } diff --git a/tests/phpunit/includes/api/format/ApiFormatPhpTest.php b/tests/phpunit/includes/api/format/ApiFormatPhpTest.php index a59983d8..a0bbb2dc 100644 --- a/tests/phpunit/includes/api/format/ApiFormatPhpTest.php +++ b/tests/phpunit/includes/api/format/ApiFormatPhpTest.php @@ -7,13 +7,11 @@ */ class ApiFormatPhpTest extends ApiFormatTestBase { - function testValidPhpSyntax() { + public function testValidPhpSyntax() { $data = $this->apiRequest( 'php', array( 'action' => 'query', 'meta' => 'siteinfo' ) ); $this->assertInternalType( 'array', unserialize( $data ) ); $this->assertGreaterThan( 0, count( (array)$data ) ); - } - } diff --git a/tests/phpunit/includes/api/generateRandomImages.php b/tests/phpunit/includes/api/generateRandomImages.php index bdd15c48..87f5c4c0 100644 --- a/tests/phpunit/includes/api/generateRandomImages.php +++ b/tests/phpunit/includes/api/generateRandomImages.php @@ -6,8 +6,8 @@ */ // Start up MediaWiki in command-line mode -require_once( __DIR__ . "/../../../../maintenance/Maintenance.php" ); -require( __DIR__ . "/RandomImageGenerator.php" ); +require_once __DIR__ . "/../../../../maintenance/Maintenance.php"; +require __DIR__ . "/RandomImageGenerator.php"; class GenerateRandomImages extends Maintenance { @@ -43,4 +43,4 @@ class GenerateRandomImages extends Maintenance { } $maintClass = 'GenerateRandomImages'; -require( RUN_MAINTENANCE_IF_MAIN ); +require RUN_MAINTENANCE_IF_MAIN; diff --git a/tests/phpunit/includes/api/query/ApiQueryBasicTest.php b/tests/phpunit/includes/api/query/ApiQueryBasicTest.php index 6d4e3711..1a2aa832 100644 --- a/tests/phpunit/includes/api/query/ApiQueryBasicTest.php +++ b/tests/phpunit/includes/api/query/ApiQueryBasicTest.php @@ -24,7 +24,7 @@ * @file */ -require_once( 'ApiQueryTestBase.php' ); +require_once 'ApiQueryTestBase.php'; /** These tests validate basic functionality of the api query module * @@ -67,7 +67,10 @@ class ApiQueryBasicTest extends ApiQueryTestBase { 'title' => 'AQBT-All', 'links' => array( array( 'ns' => 0, 'title' => 'AQBT-Links' ), - ) ) ) ) ); + ) + ) + ) ) + ); private static $templates = array( array( 'prop' => 'templates', 'titles' => 'AQBT-All' ), @@ -78,7 +81,10 @@ class ApiQueryBasicTest extends ApiQueryTestBase { 'title' => 'AQBT-All', 'templates' => array( array( 'ns' => 10, 'title' => 'Template:AQBT-T' ), - ) ) ) ) ); + ) + ) + ) ) + ); private static $categories = array( array( 'prop' => 'categories', 'titles' => 'AQBT-All' ), @@ -89,7 +95,10 @@ class ApiQueryBasicTest extends ApiQueryTestBase { 'title' => 'AQBT-All', 'categories' => array( array( 'ns' => 14, 'title' => 'Category:AQBT-Cat' ), - ) ) ) ) ); + ) + ) + ) ) + ); private static $allpages = array( array( 'list' => 'allpages', 'apprefix' => 'AQBT-' ), @@ -98,7 +107,8 @@ class ApiQueryBasicTest extends ApiQueryTestBase { array( 'pageid' => 2, 'ns' => 0, 'title' => 'AQBT-Categories' ), array( 'pageid' => 3, 'ns' => 0, 'title' => 'AQBT-Links' ), array( 'pageid' => 4, 'ns' => 0, 'title' => 'AQBT-Templates' ), - ) ) ); + ) ) + ); private static $alllinks = array( array( 'list' => 'alllinks', 'alprefix' => 'AQBT-' ), @@ -107,40 +117,46 @@ class ApiQueryBasicTest extends ApiQueryTestBase { array( 'ns' => 0, 'title' => 'AQBT-Categories' ), array( 'ns' => 0, 'title' => 'AQBT-Links' ), array( 'ns' => 0, 'title' => 'AQBT-Templates' ), - ) ) ); + ) ) + ); private static $alltransclusions = array( array( 'list' => 'alltransclusions', 'atprefix' => 'AQBT-' ), array( 'alltransclusions' => array( array( 'ns' => 10, 'title' => 'Template:AQBT-T' ), array( 'ns' => 10, 'title' => 'Template:AQBT-T' ), - ) ) ); + ) ) + ); private static $allcategories = array( array( 'list' => 'allcategories', 'acprefix' => 'AQBT-' ), array( 'allcategories' => array( array( '*' => 'AQBT-Cat' ), - ) ) ); + ) ) + ); private static $backlinks = array( array( 'list' => 'backlinks', 'bltitle' => 'AQBT-Links' ), array( 'backlinks' => array( array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ), - ) ) ); + ) ) + ); private static $embeddedin = array( array( 'list' => 'embeddedin', 'eititle' => 'Template:AQBT-T' ), array( 'embeddedin' => array( array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ), array( 'pageid' => 4, 'ns' => 0, 'title' => 'AQBT-Templates' ), - ) ) ); + ) ) + ); private static $categorymembers = array( array( 'list' => 'categorymembers', 'cmtitle' => 'Category:AQBT-Cat' ), array( 'categorymembers' => array( array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ), array( 'pageid' => 2, 'ns' => 0, 'title' => 'AQBT-Categories' ), - ) ) ); + ) ) + ); private static $generatorAllpages = array( array( 'generator' => 'allpages', 'gapprefix' => 'AQBT-' ), @@ -161,7 +177,8 @@ class ApiQueryBasicTest extends ApiQueryTestBase { 'pageid' => 4, 'ns' => 0, 'title' => 'AQBT-Templates' ), - ) ) ); + ) ) + ); private static $generatorLinks = array( array( 'generator' => 'links', 'titles' => 'AQBT-Links' ), @@ -178,14 +195,17 @@ class ApiQueryBasicTest extends ApiQueryTestBase { 'pageid' => 4, 'ns' => 0, 'title' => 'AQBT-Templates' ), - ) ) ); + ) ) + ); private static $generatorLinksPropLinks = array( array( 'prop' => 'links' ), array( 'pages' => array( '1' => array( 'links' => array( array( 'ns' => 0, 'title' => 'AQBT-Links' ), - ) ) ) ) ); + ) ) + ) ) + ); private static $generatorLinksPropTemplates = array( array( 'prop' => 'templates' ), @@ -194,7 +214,8 @@ class ApiQueryBasicTest extends ApiQueryTestBase { array( 'ns' => 10, 'title' => 'Template:AQBT-T' ) ) ), '4' => array( 'templates' => array( array( 'ns' => 10, 'title' => 'Template:AQBT-T' ) ) ), - ) ) ); + ) ) + ); /** * Test basic props @@ -300,6 +321,32 @@ class ApiQueryBasicTest extends ApiQueryTestBase { } /** + * Test bug 51821 + */ + public function testGeneratorRedirects() { + $this->editPage( 'AQBT-Target', 'test' ); + $this->editPage( 'AQBT-Redir', '#REDIRECT [[AQBT-Target]]' ); + $this->check( array( + array( 'generator' => 'backlinks', 'gbltitle' => 'AQBT-Target', 'redirects' => '1' ), + array( + 'redirects' => array( + array( + 'from' => 'AQBT-Redir', + 'to' => 'AQBT-Target', + ) + ), + 'pages' => array( + '6' => array( + 'pageid' => 6, + 'ns' => 0, + 'title' => 'AQBT-Target', + ) + ), + ) + ) ); + } + + /** * Recursively merges the expected values in the $item into the $all */ private function mergeExpected( &$all, $item ) { diff --git a/tests/phpunit/includes/api/query/ApiQueryContinue2Test.php b/tests/phpunit/includes/api/query/ApiQueryContinue2Test.php index 0a3ac1da..4d5ddbae 100644 --- a/tests/phpunit/includes/api/query/ApiQueryContinue2Test.php +++ b/tests/phpunit/includes/api/query/ApiQueryContinue2Test.php @@ -18,7 +18,7 @@ * http://www.gnu.org/copyleft/gpl.html */ -require_once( 'ApiQueryContinueTestBase.php' ); +require_once 'ApiQueryContinueTestBase.php'; /** * @group API @@ -48,7 +48,7 @@ class ApiQueryContinue2Test extends ApiQueryContinueTestBase { */ public function testA() { $this->mVerbose = false; - $mk = function( $g, $p, $gDir ) { + $mk = function ( $g, $p, $gDir ) { return array( 'generator' => 'allpages', 'gapprefix' => 'AQCT73462-', @@ -59,10 +59,10 @@ class ApiQueryContinue2Test extends ApiQueryContinueTestBase { ); }; // generator + 1 prop + 1 list - $data = $this->query( $mk(99,99,true), 1, 'g1p', false ); - $this->checkC( $data, $mk(1,1,true), 6, 'g1p-11t' ); - $this->checkC( $data, $mk(2,2,true), 3, 'g1p-22t' ); - $this->checkC( $data, $mk(1,1,false), 6, 'g1p-11f' ); - $this->checkC( $data, $mk(2,2,false), 3, 'g1p-22f' ); + $data = $this->query( $mk( 99, 99, true ), 1, 'g1p', false ); + $this->checkC( $data, $mk( 1, 1, true ), 6, 'g1p-11t' ); + $this->checkC( $data, $mk( 2, 2, true ), 3, 'g1p-22t' ); + $this->checkC( $data, $mk( 1, 1, false ), 6, 'g1p-11f' ); + $this->checkC( $data, $mk( 2, 2, false ), 3, 'g1p-22f' ); } } diff --git a/tests/phpunit/includes/api/query/ApiQueryContinueTest.php b/tests/phpunit/includes/api/query/ApiQueryContinueTest.php index cb8f1812..f494e9ca 100644 --- a/tests/phpunit/includes/api/query/ApiQueryContinueTest.php +++ b/tests/phpunit/includes/api/query/ApiQueryContinueTest.php @@ -18,7 +18,7 @@ * http://www.gnu.org/copyleft/gpl.html */ -require_once( 'ApiQueryContinueTestBase.php' ); +require_once 'ApiQueryContinueTestBase.php'; /** * These tests validate the new continue functionality of the api query module by @@ -58,21 +58,21 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { */ public function test1List() { $this->mVerbose = false; - $mk = function( $l ) { + $mk = function ( $l ) { return array( 'list' => 'allpages', 'apprefix' => 'AQCT-', 'aplimit' => "$l", ); }; - $data = $this->query( $mk(99), 1, '1L', false ); + $data = $this->query( $mk( 99 ), 1, '1L', false ); // 1 list - $this->checkC( $data, $mk(1), 5, '1L-1' ); - $this->checkC( $data, $mk(2), 3, '1L-2' ); - $this->checkC( $data, $mk(3), 2, '1L-3' ); - $this->checkC( $data, $mk(4), 2, '1L-4' ); - $this->checkC( $data, $mk(5), 1, '1L-5' ); + $this->checkC( $data, $mk( 1 ), 5, '1L-1' ); + $this->checkC( $data, $mk( 2 ), 3, '1L-2' ); + $this->checkC( $data, $mk( 3 ), 2, '1L-3' ); + $this->checkC( $data, $mk( 4 ), 2, '1L-4' ); + $this->checkC( $data, $mk( 5 ), 1, '1L-5' ); } /** @@ -81,7 +81,7 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { */ public function test2Lists() { $this->mVerbose = false; - $mk = function( $l1, $l2 ) { + $mk = function ( $l1, $l2 ) { return array( 'list' => 'allpages|alltransclusions', 'apprefix' => 'AQCT-', @@ -92,12 +92,12 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { ); }; // 2 lists - $data = $this->query( $mk(99,99), 1, '2L', false ); - $this->checkC( $data, $mk(1,1), 5, '2L-11' ); - $this->checkC( $data, $mk(2,2), 3, '2L-22' ); - $this->checkC( $data, $mk(3,3), 2, '2L-33' ); - $this->checkC( $data, $mk(4,4), 2, '2L-44' ); - $this->checkC( $data, $mk(5,5), 1, '2L-55' ); + $data = $this->query( $mk( 99, 99 ), 1, '2L', false ); + $this->checkC( $data, $mk( 1, 1 ), 5, '2L-11' ); + $this->checkC( $data, $mk( 2, 2 ), 3, '2L-22' ); + $this->checkC( $data, $mk( 3, 3 ), 2, '2L-33' ); + $this->checkC( $data, $mk( 4, 4 ), 2, '2L-44' ); + $this->checkC( $data, $mk( 5, 5 ), 1, '2L-55' ); } /** @@ -106,7 +106,7 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { */ public function testGen1Prop() { $this->mVerbose = false; - $mk = function( $g, $p ) { + $mk = function ( $g, $p ) { return array( 'generator' => 'allpages', 'gapprefix' => 'AQCT-', @@ -116,12 +116,12 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { ); }; // generator + 1 prop - $data = $this->query( $mk(99,99), 1, 'G1P', false ); - $this->checkC( $data, $mk(1,1), 11, 'G1P-11' ); - $this->checkC( $data, $mk(2,2), 6, 'G1P-22' ); - $this->checkC( $data, $mk(3,3), 4, 'G1P-33' ); - $this->checkC( $data, $mk(4,4), 3, 'G1P-44' ); - $this->checkC( $data, $mk(5,5), 2, 'G1P-55' ); + $data = $this->query( $mk( 99, 99 ), 1, 'G1P', false ); + $this->checkC( $data, $mk( 1, 1 ), 11, 'G1P-11' ); + $this->checkC( $data, $mk( 2, 2 ), 6, 'G1P-22' ); + $this->checkC( $data, $mk( 3, 3 ), 4, 'G1P-33' ); + $this->checkC( $data, $mk( 4, 4 ), 3, 'G1P-44' ); + $this->checkC( $data, $mk( 5, 5 ), 2, 'G1P-55' ); } /** @@ -130,7 +130,7 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { */ public function testGen2Prop() { $this->mVerbose = false; - $mk = function( $g, $p1, $p2 ) { + $mk = function ( $g, $p1, $p2 ) { return array( 'generator' => 'allpages', 'gapprefix' => 'AQCT-', @@ -141,17 +141,17 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { ); }; // generator + 2 props - $data = $this->query( $mk(99,99,99), 1, 'G2P', false ); - $this->checkC( $data, $mk(1,1,1), 16, 'G2P-111' ); - $this->checkC( $data, $mk(2,2,2), 9, 'G2P-222' ); - $this->checkC( $data, $mk(3,3,3), 6, 'G2P-333' ); - $this->checkC( $data, $mk(4,4,4), 4, 'G2P-444' ); - $this->checkC( $data, $mk(5,5,5), 2, 'G2P-555' ); - $this->checkC( $data, $mk(5,1,1), 10, 'G2P-511' ); - $this->checkC( $data, $mk(4,2,2), 7, 'G2P-422' ); - $this->checkC( $data, $mk(2,3,3), 7, 'G2P-233' ); - $this->checkC( $data, $mk(2,4,4), 5, 'G2P-244' ); - $this->checkC( $data, $mk(1,5,5), 5, 'G2P-155' ); + $data = $this->query( $mk( 99, 99, 99 ), 1, 'G2P', false ); + $this->checkC( $data, $mk( 1, 1, 1 ), 16, 'G2P-111' ); + $this->checkC( $data, $mk( 2, 2, 2 ), 9, 'G2P-222' ); + $this->checkC( $data, $mk( 3, 3, 3 ), 6, 'G2P-333' ); + $this->checkC( $data, $mk( 4, 4, 4 ), 4, 'G2P-444' ); + $this->checkC( $data, $mk( 5, 5, 5 ), 2, 'G2P-555' ); + $this->checkC( $data, $mk( 5, 1, 1 ), 10, 'G2P-511' ); + $this->checkC( $data, $mk( 4, 2, 2 ), 7, 'G2P-422' ); + $this->checkC( $data, $mk( 2, 3, 3 ), 7, 'G2P-233' ); + $this->checkC( $data, $mk( 2, 4, 4 ), 5, 'G2P-244' ); + $this->checkC( $data, $mk( 1, 5, 5 ), 5, 'G2P-155' ); } /** @@ -160,7 +160,7 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { */ public function testGen1Prop1List() { $this->mVerbose = false; - $mk = function( $g, $p, $l ) { + $mk = function ( $g, $p, $l ) { return array( 'generator' => 'allpages', 'gapprefix' => 'AQCT-', @@ -174,24 +174,24 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { ); }; // generator + 1 prop + 1 list - $data = $this->query( $mk(99,99,99), 1, 'G1P1L', false ); - $this->checkC( $data, $mk(1,1,1), 11, 'G1P1L-111' ); - $this->checkC( $data, $mk(2,2,2), 6, 'G1P1L-222' ); - $this->checkC( $data, $mk(3,3,3), 4, 'G1P1L-333' ); - $this->checkC( $data, $mk(4,4,4), 3, 'G1P1L-444' ); - $this->checkC( $data, $mk(5,5,5), 2, 'G1P1L-555' ); - $this->checkC( $data, $mk(5,5,1), 4, 'G1P1L-551' ); - $this->checkC( $data, $mk(5,5,2), 2, 'G1P1L-552' ); + $data = $this->query( $mk( 99, 99, 99 ), 1, 'G1P1L', false ); + $this->checkC( $data, $mk( 1, 1, 1 ), 11, 'G1P1L-111' ); + $this->checkC( $data, $mk( 2, 2, 2 ), 6, 'G1P1L-222' ); + $this->checkC( $data, $mk( 3, 3, 3 ), 4, 'G1P1L-333' ); + $this->checkC( $data, $mk( 4, 4, 4 ), 3, 'G1P1L-444' ); + $this->checkC( $data, $mk( 5, 5, 5 ), 2, 'G1P1L-555' ); + $this->checkC( $data, $mk( 5, 5, 1 ), 4, 'G1P1L-551' ); + $this->checkC( $data, $mk( 5, 5, 2 ), 2, 'G1P1L-552' ); } /** * Test smart continue - generator=allpages, prop=links|templates, - * list=alllinks|alltransclusions, meta=siteinfo + * list=alllinks|alltransclusions, meta=siteinfo * @medium */ public function testGen2Prop2List1Meta() { $this->mVerbose = false; - $mk = function( $g, $p1, $p2, $l1, $l2 ) { + $mk = function ( $g, $p1, $p2, $l1, $l2 ) { return array( 'generator' => 'allpages', 'gapprefix' => 'AQCT-', @@ -211,16 +211,16 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { ); }; // generator + 1 prop + 1 list - $data = $this->query( $mk(99,99,99,99,99), 1, 'G2P2L1M', false ); - $this->checkC( $data, $mk(1,1,1,1,1), 16, 'G2P2L1M-11111' ); - $this->checkC( $data, $mk(2,2,2,2,2), 9, 'G2P2L1M-22222' ); - $this->checkC( $data, $mk(3,3,3,3,3), 6, 'G2P2L1M-33333' ); - $this->checkC( $data, $mk(4,4,4,4,4), 4, 'G2P2L1M-44444' ); - $this->checkC( $data, $mk(5,5,5,5,5), 2, 'G2P2L1M-55555' ); - $this->checkC( $data, $mk(5,5,5,1,1), 4, 'G2P2L1M-55511' ); - $this->checkC( $data, $mk(5,5,5,2,2), 2, 'G2P2L1M-55522' ); - $this->checkC( $data, $mk(5,1,1,5,5), 10, 'G2P2L1M-51155' ); - $this->checkC( $data, $mk(5,2,2,5,5), 5, 'G2P2L1M-52255' ); + $data = $this->query( $mk( 99, 99, 99, 99, 99 ), 1, 'G2P2L1M', false ); + $this->checkC( $data, $mk( 1, 1, 1, 1, 1 ), 16, 'G2P2L1M-11111' ); + $this->checkC( $data, $mk( 2, 2, 2, 2, 2 ), 9, 'G2P2L1M-22222' ); + $this->checkC( $data, $mk( 3, 3, 3, 3, 3 ), 6, 'G2P2L1M-33333' ); + $this->checkC( $data, $mk( 4, 4, 4, 4, 4 ), 4, 'G2P2L1M-44444' ); + $this->checkC( $data, $mk( 5, 5, 5, 5, 5 ), 2, 'G2P2L1M-55555' ); + $this->checkC( $data, $mk( 5, 5, 5, 1, 1 ), 4, 'G2P2L1M-55511' ); + $this->checkC( $data, $mk( 5, 5, 5, 2, 2 ), 2, 'G2P2L1M-55522' ); + $this->checkC( $data, $mk( 5, 1, 1, 5, 5 ), 10, 'G2P2L1M-51155' ); + $this->checkC( $data, $mk( 5, 2, 2, 5, 5 ), 5, 'G2P2L1M-52255' ); } /** @@ -229,7 +229,7 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { */ public function testSameGenAndProp() { $this->mVerbose = false; - $mk = function( $g, $gDir, $p, $pDir ) { + $mk = function ( $g, $gDir, $p, $pDir ) { return array( 'titles' => 'AQCT-1', 'generator' => 'templates', @@ -241,31 +241,31 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { ); }; // generator + 1 prop - $data = $this->query( $mk(99,true,99,true), 1, 'G=P', false ); + $data = $this->query( $mk( 99, true, 99, true ), 1, 'G=P', false ); - $this->checkC( $data, $mk(1,true,1,true), 4, 'G=P-1t1t' ); - $this->checkC( $data, $mk(2,true,2,true), 2, 'G=P-2t2t' ); - $this->checkC( $data, $mk(3,true,3,true), 2, 'G=P-3t3t' ); - $this->checkC( $data, $mk(1,true,3,true), 4, 'G=P-1t3t' ); - $this->checkC( $data, $mk(3,true,1,true), 2, 'G=P-3t1t' ); + $this->checkC( $data, $mk( 1, true, 1, true ), 4, 'G=P-1t1t' ); + $this->checkC( $data, $mk( 2, true, 2, true ), 2, 'G=P-2t2t' ); + $this->checkC( $data, $mk( 3, true, 3, true ), 2, 'G=P-3t3t' ); + $this->checkC( $data, $mk( 1, true, 3, true ), 4, 'G=P-1t3t' ); + $this->checkC( $data, $mk( 3, true, 1, true ), 2, 'G=P-3t1t' ); - $this->checkC( $data, $mk(1,true,1,false), 4, 'G=P-1t1f' ); - $this->checkC( $data, $mk(2,true,2,false), 2, 'G=P-2t2f' ); - $this->checkC( $data, $mk(3,true,3,false), 2, 'G=P-3t3f' ); - $this->checkC( $data, $mk(1,true,3,false), 4, 'G=P-1t3f' ); - $this->checkC( $data, $mk(3,true,1,false), 2, 'G=P-3t1f' ); + $this->checkC( $data, $mk( 1, true, 1, false ), 4, 'G=P-1t1f' ); + $this->checkC( $data, $mk( 2, true, 2, false ), 2, 'G=P-2t2f' ); + $this->checkC( $data, $mk( 3, true, 3, false ), 2, 'G=P-3t3f' ); + $this->checkC( $data, $mk( 1, true, 3, false ), 4, 'G=P-1t3f' ); + $this->checkC( $data, $mk( 3, true, 1, false ), 2, 'G=P-3t1f' ); - $this->checkC( $data, $mk(1,false,1,true), 4, 'G=P-1f1t' ); - $this->checkC( $data, $mk(2,false,2,true), 2, 'G=P-2f2t' ); - $this->checkC( $data, $mk(3,false,3,true), 2, 'G=P-3f3t' ); - $this->checkC( $data, $mk(1,false,3,true), 4, 'G=P-1f3t' ); - $this->checkC( $data, $mk(3,false,1,true), 2, 'G=P-3f1t' ); + $this->checkC( $data, $mk( 1, false, 1, true ), 4, 'G=P-1f1t' ); + $this->checkC( $data, $mk( 2, false, 2, true ), 2, 'G=P-2f2t' ); + $this->checkC( $data, $mk( 3, false, 3, true ), 2, 'G=P-3f3t' ); + $this->checkC( $data, $mk( 1, false, 3, true ), 4, 'G=P-1f3t' ); + $this->checkC( $data, $mk( 3, false, 1, true ), 2, 'G=P-3f1t' ); - $this->checkC( $data, $mk(1,false,1,false), 4, 'G=P-1f1f' ); - $this->checkC( $data, $mk(2,false,2,false), 2, 'G=P-2f2f' ); - $this->checkC( $data, $mk(3,false,3,false), 2, 'G=P-3f3f' ); - $this->checkC( $data, $mk(1,false,3,false), 4, 'G=P-1f3f' ); - $this->checkC( $data, $mk(3,false,1,false), 2, 'G=P-3f1f' ); + $this->checkC( $data, $mk( 1, false, 1, false ), 4, 'G=P-1f1f' ); + $this->checkC( $data, $mk( 2, false, 2, false ), 2, 'G=P-2f2f' ); + $this->checkC( $data, $mk( 3, false, 3, false ), 2, 'G=P-3f3f' ); + $this->checkC( $data, $mk( 1, false, 3, false ), 4, 'G=P-1f3f' ); + $this->checkC( $data, $mk( 3, false, 1, false ), 2, 'G=P-3f1f' ); } /** @@ -274,7 +274,7 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { */ public function testSameGenList() { $this->mVerbose = false; - $mk = function( $g, $gDir, $l, $pDir ) { + $mk = function ( $g, $gDir, $l, $pDir ) { return array( 'generator' => 'allpages', 'gapprefix' => 'AQCT-', @@ -287,27 +287,27 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { ); }; // generator + 1 list - $data = $this->query( $mk(99,true,99,true), 1, 'G=L', false ); + $data = $this->query( $mk( 99, true, 99, true ), 1, 'G=L', false ); - $this->checkC( $data, $mk(1,true,1,true), 5, 'G=L-1t1t' ); - $this->checkC( $data, $mk(2,true,2,true), 3, 'G=L-2t2t' ); - $this->checkC( $data, $mk(3,true,3,true), 2, 'G=L-3t3t' ); - $this->checkC( $data, $mk(1,true,3,true), 5, 'G=L-1t3t' ); - $this->checkC( $data, $mk(3,true,1,true), 5, 'G=L-3t1t' ); - $this->checkC( $data, $mk(1,true,1,false), 5, 'G=L-1t1f' ); - $this->checkC( $data, $mk(2,true,2,false), 3, 'G=L-2t2f' ); - $this->checkC( $data, $mk(3,true,3,false), 2, 'G=L-3t3f' ); - $this->checkC( $data, $mk(1,true,3,false), 5, 'G=L-1t3f' ); - $this->checkC( $data, $mk(3,true,1,false), 5, 'G=L-3t1f' ); - $this->checkC( $data, $mk(1,false,1,true), 5, 'G=L-1f1t' ); - $this->checkC( $data, $mk(2,false,2,true), 3, 'G=L-2f2t' ); - $this->checkC( $data, $mk(3,false,3,true), 2, 'G=L-3f3t' ); - $this->checkC( $data, $mk(1,false,3,true), 5, 'G=L-1f3t' ); - $this->checkC( $data, $mk(3,false,1,true), 5, 'G=L-3f1t' ); - $this->checkC( $data, $mk(1,false,1,false), 5, 'G=L-1f1f' ); - $this->checkC( $data, $mk(2,false,2,false), 3, 'G=L-2f2f' ); - $this->checkC( $data, $mk(3,false,3,false), 2, 'G=L-3f3f' ); - $this->checkC( $data, $mk(1,false,3,false), 5, 'G=L-1f3f' ); - $this->checkC( $data, $mk(3,false,1,false), 5, 'G=L-3f1f' ); + $this->checkC( $data, $mk( 1, true, 1, true ), 5, 'G=L-1t1t' ); + $this->checkC( $data, $mk( 2, true, 2, true ), 3, 'G=L-2t2t' ); + $this->checkC( $data, $mk( 3, true, 3, true ), 2, 'G=L-3t3t' ); + $this->checkC( $data, $mk( 1, true, 3, true ), 5, 'G=L-1t3t' ); + $this->checkC( $data, $mk( 3, true, 1, true ), 5, 'G=L-3t1t' ); + $this->checkC( $data, $mk( 1, true, 1, false ), 5, 'G=L-1t1f' ); + $this->checkC( $data, $mk( 2, true, 2, false ), 3, 'G=L-2t2f' ); + $this->checkC( $data, $mk( 3, true, 3, false ), 2, 'G=L-3t3f' ); + $this->checkC( $data, $mk( 1, true, 3, false ), 5, 'G=L-1t3f' ); + $this->checkC( $data, $mk( 3, true, 1, false ), 5, 'G=L-3t1f' ); + $this->checkC( $data, $mk( 1, false, 1, true ), 5, 'G=L-1f1t' ); + $this->checkC( $data, $mk( 2, false, 2, true ), 3, 'G=L-2f2t' ); + $this->checkC( $data, $mk( 3, false, 3, true ), 2, 'G=L-3f3t' ); + $this->checkC( $data, $mk( 1, false, 3, true ), 5, 'G=L-1f3t' ); + $this->checkC( $data, $mk( 3, false, 1, true ), 5, 'G=L-3f1t' ); + $this->checkC( $data, $mk( 1, false, 1, false ), 5, 'G=L-1f1f' ); + $this->checkC( $data, $mk( 2, false, 2, false ), 3, 'G=L-2f2f' ); + $this->checkC( $data, $mk( 3, false, 3, false ), 2, 'G=L-3f3f' ); + $this->checkC( $data, $mk( 1, false, 3, false ), 5, 'G=L-1f3f' ); + $this->checkC( $data, $mk( 3, false, 1, false ), 5, 'G=L-3f1f' ); } } diff --git a/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php b/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php index 47174796..fbb1e640 100644 --- a/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php +++ b/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php @@ -24,7 +24,7 @@ * @file */ -require_once( 'ApiQueryTestBase.php' ); +require_once 'ApiQueryTestBase.php'; abstract class ApiQueryContinueTestBase extends ApiQueryTestBase { @@ -36,7 +36,7 @@ abstract class ApiQueryContinueTestBase extends ApiQueryTestBase { /** * Run query() and compare against expected values */ - protected function checkC( $expected, $params, $expectedCount, $id, $continue = true ) { + protected function checkC( $expected, $params, $expectedCount, $id, $continue = true ) { $result = $this->query( $params, $expectedCount, $id, $continue ); $this->assertResult( $expected, $result, $id ); } @@ -52,7 +52,7 @@ abstract class ApiQueryContinueTestBase extends ApiQueryTestBase { */ protected function query( $params, $expectedCount, $id, $useContinue = true ) { if ( isset( $params['action'] ) ) { - $this->assertEquals( 'query', $params['action'], 'Invalid query action'); + $this->assertEquals( 'query', $params['action'], 'Invalid query action' ); } else { $params['action'] = 'query'; } @@ -64,17 +64,18 @@ abstract class ApiQueryContinueTestBase extends ApiQueryTestBase { $continue = array(); do { $request = array_merge( $params, $continue ); - uksort( $request, function( $a, $b ) { + uksort( $request, function ( $a, $b ) { // put 'continue' params at the end - lazy method $a = strpos( $a, 'continue' ) !== false ? 'zzz ' . $a : $a; $b = strpos( $b, 'continue' ) !== false ? 'zzz ' . $b : $b; + return strcmp( $a, $b ); } ); $reqStr = http_build_query( $request ); //$reqStr = str_replace( '&', ' & ', $reqStr ); $this->assertLessThan( $expectedCount, $count, "$id more data: $reqStr" ); if ( $this->mVerbose ) { - print ("$id (#$count): $reqStr\n"); + print "$id (#$count): $reqStr\n"; } try { $data = $this->doApiRequest( $request ); @@ -103,52 +104,57 @@ abstract class ApiQueryContinueTestBase extends ApiQueryTestBase { if ( $expectedCount > $count ) { print "***** $id Finished early in $count turns. $expectedCount was expected\n"; } + return $result; } elseif ( !$useContinue ) { $this->assertFalse( 'Non-smart query must be requested all at once' ); } - } while( true ); + } while ( true ); } private function printResult( $data ) { $q = $data['query']; $print = array(); - if (isset($q['pages'])) { - foreach ($q['pages'] as $p) { + if ( isset( $q['pages'] ) ) { + foreach ( $q['pages'] as $p ) { $m = $p['title']; - if (isset($p['links'])) { - $m .= '/[' . implode(',', array_map( - function ($v) { + if ( isset( $p['links'] ) ) { + $m .= '/[' . implode( ',', array_map( + function ( $v ) { return $v['title']; }, - $p['links'])) . ']'; + $p['links'] ) ) . ']'; } - if (isset($p['categories'])) { - $m .= '/(' . implode(',', array_map( - function ($v) { - return str_replace('Category:', '', $v['title']); + if ( isset( $p['categories'] ) ) { + $m .= '/(' . implode( ',', array_map( + function ( $v ) { + return str_replace( 'Category:', '', $v['title'] ); }, - $p['categories'])) . ')'; + $p['categories'] ) ) . ')'; } $print[] = $m; } } - if (isset($q['allcategories'])) { - $print[] = '*Cats/(' . implode(',', array_map( - function ($v) { return $v['*']; }, - $q['allcategories'])) . ')'; + if ( isset( $q['allcategories'] ) ) { + $print[] = '*Cats/(' . implode( ',', array_map( + function ( $v ) { + return $v['*']; + }, + $q['allcategories'] ) ) . ')'; } self::GetItems( $q, 'allpages', 'Pages', $print ); self::GetItems( $q, 'alllinks', 'Links', $print ); self::GetItems( $q, 'alltransclusions', 'Trnscl', $print ); - print(' ' . implode(' ', $print) . "\n"); + print ' ' . implode( ' ', $print ) . "\n"; } private static function GetItems( $q, $moduleName, $name, &$print ) { - if (isset($q[$moduleName])) { - $print[] = "*$name/[" . implode(',', - array_map( function ($v) { return $v['title']; }, - $q[$moduleName])) . ']'; + if ( isset( $q[$moduleName] ) ) { + $print[] = "*$name/[" . implode( ',', + array_map( function ( $v ) { + return $v['title']; + }, + $q[$moduleName] ) ) . ']'; } } @@ -164,12 +170,12 @@ abstract class ApiQueryContinueTestBase extends ApiQueryTestBase { $this->assertEquals( $results, $newResult, 'Repeated result must be the same as before' ); } else { $sort = null; - foreach( $newResult as $key => $value ) { + foreach ( $newResult as $key => $value ) { if ( !$numericIds && $sort === null ) { if ( !is_array( $value ) ) { $sort = false; } elseif ( array_key_exists( 'title', $value ) ) { - $sort = function( $a, $b ) { + $sort = function ( $a, $b ) { return strcmp( $a['title'], $b['title'] ); }; } else { diff --git a/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php b/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php index 7f5fe91c..1bca2256 100644 --- a/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php +++ b/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php @@ -10,7 +10,7 @@ class ApiQueryRevisionsTest extends ApiTestCase { /** * @group medium */ - function testContentComesWithContentModelAndFormat() { + public function testContentComesWithContentModelAndFormat() { $pageName = 'Help:' . __METHOD__; $title = Title::newFromText( $pageName ); $page = WikiPage::factory( $title ); diff --git a/tests/phpunit/includes/api/query/ApiQueryTest.php b/tests/phpunit/includes/api/query/ApiQueryTest.php index 7fb53073..f5645555 100644 --- a/tests/phpunit/includes/api/query/ApiQueryTest.php +++ b/tests/phpunit/includes/api/query/ApiQueryTest.php @@ -12,7 +12,7 @@ class ApiQueryTest extends ApiTestCase { $this->doLogin(); } - function testTitlesGetNormalized() { + public function testTitlesGetNormalized() { global $wgMetaNamespace; @@ -20,7 +20,6 @@ class ApiQueryTest extends ApiTestCase { 'action' => 'query', 'titles' => 'Project:articleA|article_B' ) ); - $this->assertArrayHasKey( 'query', $data[0] ); $this->assertArrayHasKey( 'normalized', $data[0]['query'] ); @@ -42,10 +41,9 @@ class ApiQueryTest extends ApiTestCase { ), $data[0]['query']['normalized'][1] ); - } - function testTitlesAreRejectedIfInvalid() { + public function testTitlesAreRejectedIfInvalid() { $title = false; while ( !$title || Title::newFromText( $title )->exists() ) { $title = md5( mt_rand( 0, 10000 ) + rand( 0, 999000 ) ); @@ -65,5 +63,4 @@ class ApiQueryTest extends ApiTestCase { $this->assertArrayHasKey( 'missing', $data[0]['query']['pages'][-2] ); $this->assertArrayHasKey( 'invalid', $data[0]['query']['pages'][-1] ); } - } diff --git a/tests/phpunit/includes/api/query/ApiQueryTestBase.php b/tests/phpunit/includes/api/query/ApiQueryTestBase.php index 7b9f8ede..8ee8ea96 100644 --- a/tests/phpunit/includes/api/query/ApiQueryTestBase.php +++ b/tests/phpunit/includes/api/query/ApiQueryTestBase.php @@ -24,7 +24,6 @@ * @file */ - /** This class has some common functionality for testing query module */ abstract class ApiQueryTestBase extends ApiTestCase { @@ -43,11 +42,12 @@ STR; protected function merge( /*...*/ ) { $request = array(); $expected = array(); - foreach ( func_get_args() as $v ) { + foreach ( func_get_args() as $v ) { list( $req, $exp ) = $this->validateRequestExpectedPair( $v ); $request = array_merge_recursive( $request, $req ); $this->mergeExpected( $expected, $exp ); } + return array( $request, $expected ); } @@ -57,11 +57,12 @@ STR; */ private function validateRequestExpectedPair( $v ) { $this->assertType( 'array', $v, self::PARAM_ASSERT ); - $this->assertEquals( 2, count($v), self::PARAM_ASSERT ); + $this->assertEquals( 2, count( $v ), self::PARAM_ASSERT ); $this->assertArrayHasKey( 0, $v, self::PARAM_ASSERT ); $this->assertArrayHasKey( 1, $v, self::PARAM_ASSERT ); $this->assertType( 'array', $v[0], self::PARAM_ASSERT ); $this->assertType( 'array', $v[1], self::PARAM_ASSERT ); + return $v; } @@ -71,7 +72,7 @@ STR; private function mergeExpected( &$all, $item ) { foreach ( $item as $k => $v ) { if ( array_key_exists( $k, $all ) ) { - if ( is_array ( $all[$k] ) ) { + if ( is_array( $all[$k] ) ) { $this->mergeExpected( $all[$k], $v ); } else { $this->assertEquals( $all[$k], $v ); @@ -108,10 +109,10 @@ STR; if ( is_array( $message ) ) { $message = http_build_query( $message ); } - print( "\nRequest: $message\n" ); - print( "\nExpected:\n" ); + print "\nRequest: $message\n"; + print "\nExpected:\n"; print_r( $exp ); - print( "\nResult:\n" ); + print "\nResult:\n"; print_r( $result ); throw $e; // rethrow it } diff --git a/tests/phpunit/includes/cache/GenderCacheTest.php b/tests/phpunit/includes/cache/GenderCacheTest.php index ee3db3e8..ce2db5d7 100644 --- a/tests/phpunit/includes/cache/GenderCacheTest.php +++ b/tests/phpunit/includes/cache/GenderCacheTest.php @@ -46,8 +46,9 @@ class GenderCacheTest extends MediaWikiLangTestCase { * test usernames * * @dataProvider provideUserGenders + * @covers GenderCache::getGenderOf */ - function testUserName( $username, $expectedGender ) { + public function testUserName( $username, $expectedGender ) { $genderCache = GenderCache::singleton(); $gender = $genderCache->getGenderOf( $username ); $this->assertEquals( $gender, $expectedGender, "GenderCache normal" ); @@ -57,8 +58,9 @@ class GenderCacheTest extends MediaWikiLangTestCase { * genderCache should work with user objects, too * * @dataProvider provideUserGenders + * @covers GenderCache::getGenderOf */ - function testUserObjects( $username, $expectedGender ) { + public function testUserObjects( $username, $expectedGender ) { $genderCache = GenderCache::singleton(); $user = User::newFromName( $username ); $gender = $genderCache->getGenderOf( $user ); @@ -82,8 +84,9 @@ class GenderCacheTest extends MediaWikiLangTestCase { * against the never existing username * * @dataProvider provideStripSubpages + * @covers GenderCache::getGenderOf */ - function testStripSubpages( $pageWithSubpage, $expectedGender ) { + public function testStripSubpages( $pageWithSubpage, $expectedGender ) { $genderCache = GenderCache::singleton(); $gender = $genderCache->getGenderOf( $pageWithSubpage ); $this->assertEquals( $gender, $expectedGender, "GenderCache must strip of subpages" ); diff --git a/tests/phpunit/includes/cache/MessageCacheTest.php b/tests/phpunit/includes/cache/MessageCacheTest.php new file mode 100644 index 00000000..803acf73 --- /dev/null +++ b/tests/phpunit/includes/cache/MessageCacheTest.php @@ -0,0 +1,128 @@ +<?php + +/** + * @group Database + * @group Cache + * @covers MessageCache + */ +class MessageCacheTest extends MediaWikiLangTestCase { + + protected function setUp() { + parent::setUp(); + $this->configureLanguages(); + MessageCache::singleton()->enable(); + } + + /** + * Helper function -- setup site language for testing + */ + protected function configureLanguages() { + // for the test, we need the content language to be anything but English, + // let's choose e.g. German (de) + $langCode = 'de'; + $langObj = Language::factory( $langCode ); + + $this->setMwGlobals( array( + 'wgLanguageCode' => $langCode, + 'wgLang' => $langObj, + 'wgContLang' => $langObj, + ) ); + } + + function addDBData() { + $this->configureLanguages(); + + // Set up messages and fallbacks ab -> ru -> de + $this->makePage( 'FallbackLanguageTest-Full', 'ab' ); + $this->makePage( 'FallbackLanguageTest-Full', 'ru' ); + $this->makePage( 'FallbackLanguageTest-Full', 'de' ); + + // Fallbacks where ab does not exist + $this->makePage( 'FallbackLanguageTest-Partial', 'ru' ); + $this->makePage( 'FallbackLanguageTest-Partial', 'de' ); + + // Fallback to the content language + $this->makePage( 'FallbackLanguageTest-ContLang', 'de' ); + + // Add customizations for an existing message. + $this->makePage( 'sunday', 'ru' ); + + // Full key tests -- always want russian + $this->makePage( 'MessageCacheTest-FullKeyTest', 'ab' ); + $this->makePage( 'MessageCacheTest-FullKeyTest', 'ru' ); + + // In content language -- get base if no derivative + $this->makePage( 'FallbackLanguageTest-NoDervContLang', 'de', 'de/none', false ); + } + + /** + * Helper function for addDBData -- adds a simple page to the database + * + * @param string $title Title of page to be created + * @param string $lang Language and content of the created page + * @param string|null $content Content of the created page, or null for a generic string + * @param bool $createSubPage Set to false if a root page should be created + */ + protected function makePage( $title, $lang, $content = null, $createSubPage = true ) { + global $wgContLang; + + if ( $content === null ) { + $content = $lang; + } + if ( $lang !== $wgContLang->getCode() || $createSubPage ) { + $title = "$title/$lang"; + } + + $title = Title::newFromText( $title, NS_MEDIAWIKI ); + $wikiPage = new WikiPage( $title ); + $contentHandler = ContentHandler::makeContent( $content, $title ); + $wikiPage->doEditContent( $contentHandler, "$lang translation test case" ); + } + + /** + * Test message fallbacks, bug #1495 + * + * @dataProvider provideMessagesForFallback + */ + public function testMessageFallbacks( $message, $lang, $expectedContent ) { + $result = MessageCache::singleton()->get( $message, true, $lang ); + $this->assertEquals( $expectedContent, $result, "Message fallback failed." ); + } + + function provideMessagesForFallback() { + return array( + array( 'FallbackLanguageTest-Full', 'ab', 'ab' ), + array( 'FallbackLanguageTest-Partial', 'ab', 'ru' ), + array( 'FallbackLanguageTest-ContLang', 'ab', 'de' ), + array( 'FallbackLanguageTest-None', 'ab', false ), + + // Existing message with customizations on the fallbacks + array( 'sunday', 'ab', 'амҽыш' ), + + // bug 46579 + array( 'FallbackLanguageTest-NoDervContLang', 'de', 'de/none' ), + // UI language different from content language should only use de/none as last option + array( 'FallbackLanguageTest-NoDervContLang', 'fit', 'de/none' ), + ); + } + + /** + * There's a fallback case where the message key is given as fully qualified -- this + * should ignore the passed $lang and use the language from the key + * + * @dataProvider provideMessagesForFullKeys + */ + public function testFullKeyBehaviour( $message, $lang, $expectedContent ) { + $result = MessageCache::singleton()->get( $message, true, $lang, true ); + $this->assertEquals( $expectedContent, $result, "Full key message fallback failed." ); + } + + function provideMessagesForFullKeys() { + return array( + array( 'MessageCacheTest-FullKeyTest/ru', 'ru', 'ru' ), + array( 'MessageCacheTest-FullKeyTest/ru', 'ab', 'ru' ), + array( 'MessageCacheTest-FullKeyTest/ru/foo', 'ru', false ), + ); + } + +} diff --git a/tests/phpunit/includes/cache/ProcessCacheLRUTest.php b/tests/phpunit/includes/cache/ProcessCacheLRUTest.php index c7e75d99..d3793d83 100644 --- a/tests/phpunit/includes/cache/ProcessCacheLRUTest.php +++ b/tests/phpunit/includes/cache/ProcessCacheLRUTest.php @@ -52,13 +52,14 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { for ( $i = $firstKey; $i <= $lastKey; $i++ ) { $expected["cache-key-$i"] = array( "prop-$i" => "value-$i" ); } + return $expected; } /** * Highlight diff between assertEquals and assertNotSame */ - function testPhpUnitArrayEquality() { + public function testPhpUnitArrayEquality() { $one = array( 'A' => 1, 'B' => 2 ); $two = array( 'B' => 2, 'A' => 1 ); $this->assertEquals( $one, $two ); // == @@ -69,8 +70,8 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { * @dataProvider provideInvalidConstructorArg * @expectedException MWException */ - function testConstructorGivenInvalidValue( $maxSize ) { - $c = new ProcessCacheLRUTestable( $maxSize ); + public function testConstructorGivenInvalidValue( $maxSize ) { + new ProcessCacheLRUTestable( $maxSize ); } /** @@ -87,7 +88,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { ); } - function testAddAndGetAKey() { + public function testAddAndGetAKey() { $oneCache = new ProcessCacheLRUTestable( 1 ); $this->assertCacheEmpty( $oneCache ); @@ -98,7 +99,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { $this->assertEquals( 'value1', $oneCache->get( 'cache-key', 'prop1' ) ); } - function testDeleteOldKey() { + public function testDeleteOldKey() { $oneCache = new ProcessCacheLRUTestable( 1 ); $this->assertCacheEmpty( $oneCache ); @@ -116,7 +117,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { * @param $cacheMaxEntries Maximum entry the created cache will hold * @param $entryToFill Number of entries to insert in the created cache. */ - function testFillingCache( $cacheMaxEntries, $entryToFill, $msg = '' ) { + public function testFillingCache( $cacheMaxEntries, $entryToFill, $msg = '' ) { $cache = new ProcessCacheLRUTestable( $cacheMaxEntries ); $this->fillCache( $cache, $entryToFill ); @@ -125,7 +126,6 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { $cache->getCache(), "Filling a $cacheMaxEntries entries cache with $entryToFill entries" ); - } /** @@ -145,7 +145,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { * Create a cache with only one remaining entry then update * the first inserted entry. Should bump it to the top. */ - function testReplaceExistingKeyShouldBumpEntryToTop() { + public function testReplaceExistingKeyShouldBumpEntryToTop() { $maxEntries = 3; $cache = new ProcessCacheLRUTestable( $maxEntries ); @@ -164,7 +164,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { ); } - function testRecentlyAccessedKeyStickIn() { + public function testRecentlyAccessedKeyStickIn() { $cache = new ProcessCacheLRUTestable( 2 ); $cache->set( 'first', 'prop1', 'value1' ); $cache->set( 'second', 'prop2', 'value2' ); @@ -183,7 +183,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { * Given a cache having 1,2,3 as key, updating 2 should bump 2 to * the top of the queue with the new value: 1,3,2* (* = updated). */ - function testReplaceExistingKeyInAFullCacheShouldBumpToTop() { + public function testReplaceExistingKeyInAFullCacheShouldBumpToTop() { $maxEntries = 3; $cache = new ProcessCacheLRUTestable( $maxEntries ); @@ -204,7 +204,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { ); } - function testBumpExistingKeyToTop() { + public function testBumpExistingKeyToTop() { $cache = new ProcessCacheLRUTestable( 3 ); $this->fillCache( $cache, 3 ); @@ -218,9 +218,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { ), $cache->getCache() ); - } - } /** diff --git a/tests/phpunit/includes/content/ContentHandlerTest.php b/tests/phpunit/includes/content/ContentHandlerTest.php index 19ceadd5..aedf594d 100644 --- a/tests/phpunit/includes/content/ContentHandlerTest.php +++ b/tests/phpunit/includes/content/ContentHandlerTest.php @@ -10,9 +10,9 @@ */ class ContentHandlerTest extends MediaWikiTestCase { - public function setup() { + public function setUp() { global $wgContLang; - parent::setup(); + parent::setUp(); $this->setMwGlobals( array( 'wgExtraNamespaces' => array( @@ -70,6 +70,7 @@ class ContentHandlerTest extends MediaWikiTestCase { /** * @dataProvider dataGetDefaultModelFor + * @covers ContentHandler::getDefaultModelFor */ public function testGetDefaultModelFor( $title, $expectedModelId ) { $title = Title::newFromText( $title ); @@ -78,6 +79,7 @@ class ContentHandlerTest extends MediaWikiTestCase { /** * @dataProvider dataGetDefaultModelFor + * @covers ContentHandler::getForTitle */ public function testGetForTitle( $title, $expectedContentModel ) { $title = Title::newFromText( $title ); @@ -97,6 +99,7 @@ class ContentHandlerTest extends MediaWikiTestCase { /** * @dataProvider dataGetLocalizedName + * @covers ContentHandler::getLocalizedName */ public function testGetLocalizedName( $id, $expected ) { $name = ContentHandler::getLocalizedName( $id ); @@ -131,6 +134,7 @@ class ContentHandlerTest extends MediaWikiTestCase { /** * @dataProvider dataGetPageLanguage + * @covers ContentHandler::getPageLanguage */ public function testGetPageLanguage( $title, $expected ) { if ( is_string( $title ) ) { @@ -145,62 +149,81 @@ class ContentHandlerTest extends MediaWikiTestCase { $this->assertEquals( $expected->getCode(), $lang->getCode() ); } - public function testGetContentText_Null() { - global $wgContentHandlerTextFallback; + public static function dataGetContentText_Null() { + return array( + array( 'fail' ), + array( 'serialize' ), + array( 'ignore' ), + ); + } - $content = null; + /** + * @dataProvider dataGetContentText_Null + * @covers ContentHandler::getContentText + */ + public function testGetContentText_Null( $contentHandlerTextFallback ) { + $this->setMwGlobals( 'wgContentHandlerTextFallback', $contentHandlerTextFallback ); - $wgContentHandlerTextFallback = 'fail'; - $text = ContentHandler::getContentText( $content ); - $this->assertEquals( '', $text ); + $content = null; - $wgContentHandlerTextFallback = 'serialize'; $text = ContentHandler::getContentText( $content ); $this->assertEquals( '', $text ); + } - $wgContentHandlerTextFallback = 'ignore'; - $text = ContentHandler::getContentText( $content ); - $this->assertEquals( '', $text ); + public static function dataGetContentText_TextContent() { + return array( + array( 'fail' ), + array( 'serialize' ), + array( 'ignore' ), + ); } - public function testGetContentText_TextContent() { - global $wgContentHandlerTextFallback; + /** + * @dataProvider dataGetContentText_TextContent + * @covers ContentHandler::getContentText + */ + public function testGetContentText_TextContent( $contentHandlerTextFallback ) { + $this->setMwGlobals( 'wgContentHandlerTextFallback', $contentHandlerTextFallback ); $content = new WikitextContent( "hello world" ); - $wgContentHandlerTextFallback = 'fail'; - $text = ContentHandler::getContentText( $content ); - $this->assertEquals( $content->getNativeData(), $text ); - - $wgContentHandlerTextFallback = 'serialize'; - $text = ContentHandler::getContentText( $content ); - $this->assertEquals( $content->serialize(), $text ); - - $wgContentHandlerTextFallback = 'ignore'; $text = ContentHandler::getContentText( $content ); $this->assertEquals( $content->getNativeData(), $text ); } - public function testGetContentText_NonTextContent() { - global $wgContentHandlerTextFallback; + /** + * ContentHandler::getContentText should have thrown an exception for non-text Content object + * @expectedException MWException + * @covers ContentHandler::getContentText + */ + public function testGetContentText_NonTextContent_fail() { + $this->setMwGlobals( 'wgContentHandlerTextFallback', 'fail' ); $content = new DummyContentForTesting( "hello world" ); - $wgContentHandlerTextFallback = 'fail'; + ContentHandler::getContentText( $content ); + } - try { - $text = ContentHandler::getContentText( $content ); + /** + * @covers ContentHandler::getContentText + */ + public function testGetContentText_NonTextContent_serialize() { + $this->setMwGlobals( 'wgContentHandlerTextFallback', 'serialize' ); - $this->fail( "ContentHandler::getContentText should have thrown an exception for non-text Content object" ); - } catch ( MWException $ex ) { - // as expected - } + $content = new DummyContentForTesting( "hello world" ); - $wgContentHandlerTextFallback = 'serialize'; $text = ContentHandler::getContentText( $content ); $this->assertEquals( $content->serialize(), $text ); + } + + /** + * @covers ContentHandler::getContentText + */ + public function testGetContentText_NonTextContent_ignore() { + $this->setMwGlobals( 'wgContentHandlerTextFallback', 'ignore' ); + + $content = new DummyContentForTesting( "hello world" ); - $wgContentHandlerTextFallback = 'ignore'; $text = ContentHandler::getContentText( $content ); $this->assertNull( $text ); } @@ -231,6 +254,7 @@ class ContentHandlerTest extends MediaWikiTestCase { /** * @dataProvider dataMakeContent + * @covers ContentHandler::makeContent */ public function testMakeContent( $data, $title, $modelId, $format, $expectedModelId, $expectedNativeData, $shouldFail ) { $title = Title::newFromText( $title ); @@ -247,8 +271,7 @@ class ContentHandlerTest extends MediaWikiTestCase { } catch ( MWException $ex ) { if ( !$shouldFail ) { $this->fail( "ContentHandler::makeContent failed unexpectedly: " . $ex->getMessage() ); - } - else { + } else { // dummy, so we don't get the "test did not perform any assertions" message. $this->assertTrue( true ); } @@ -261,6 +284,9 @@ class ContentHandlerTest extends MediaWikiTestCase { } */ + /** + * @covers ContentHandler::runLegacyHooks + */ public function testRunLegacyHooks() { Hooks::register( 'testRunLegacyHooks', __CLASS__ . '::dummyHookHandler' ); @@ -308,6 +334,7 @@ class DummyContentHandlerForTesting extends ContentHandler { */ public function unserializeContent( $blob, $format = null ) { $d = unserialize( $blob ); + return new DummyContentForTesting( $d ); } diff --git a/tests/phpunit/includes/content/CssContentTest.php b/tests/phpunit/includes/content/CssContentTest.php index 8f53dd3e..bd6d41fe 100644 --- a/tests/phpunit/includes/content/CssContentTest.php +++ b/tests/phpunit/includes/content/CssContentTest.php @@ -50,12 +50,18 @@ class CssContentTest extends MediaWikiTestCase { ); } + /** + * @covers CssContent::getModel + */ public function testGetModel() { $content = $this->newContent( 'hello world.' ); $this->assertEquals( CONTENT_MODEL_CSS, $content->getModel() ); } + /** + * @covers CssContent::getContentHandler + */ public function testGetContentHandler() { $content = $this->newContent( 'hello world.' ); @@ -73,9 +79,9 @@ class CssContentTest extends MediaWikiTestCase { /** * @dataProvider dataEquals + * @covers CssContent::equals */ public function testEquals( Content $a, Content $b = null, $equal = false ) { $this->assertEquals( $equal, $a->equals( $b ) ); } - } diff --git a/tests/phpunit/includes/content/JavaScriptContentTest.php b/tests/phpunit/includes/content/JavaScriptContentTest.php index 2d693feb..c8616ff0 100644 --- a/tests/phpunit/includes/content/JavaScriptContentTest.php +++ b/tests/phpunit/includes/content/JavaScriptContentTest.php @@ -89,6 +89,9 @@ class JavaScriptContentTest extends TextContentTest { ); } + /** + * @covers JavaScriptContent::addSectionHeader + */ public function testAddSectionHeader() { $content = $this->newContent( 'hello world' ); $c = $content->addSectionHeader( 'test' ); @@ -137,7 +140,7 @@ class JavaScriptContentTest extends TextContentTest { } /** - * @todo: test needs database! + * @todo Test needs database! */ /* public function getRedirectChain() { @@ -147,7 +150,7 @@ class JavaScriptContentTest extends TextContentTest { */ /** - * @todo: test needs database! + * @todo Test needs database! */ /* public function getUltimateRedirectTarget() { @@ -233,6 +236,9 @@ class JavaScriptContentTest extends TextContentTest { ); } + /** + * @covers JavaScriptContent::matchMagicWord + */ public function testMatchMagicWord() { $mw = MagicWord::get( "staticredirect" ); @@ -240,6 +246,9 @@ class JavaScriptContentTest extends TextContentTest { $this->assertFalse( $content->matchMagicWord( $mw ), "should not have matched magic word, since it's not wikitext" ); } + /** + * @covers JavaScriptContent::updateRedirect + */ public function testUpdateRedirect() { $target = Title::newFromText( "testUpdateRedirect_target" ); @@ -249,12 +258,18 @@ class JavaScriptContentTest extends TextContentTest { $this->assertTrue( $content->equals( $newContent ), "content should be unchanged since it's not wikitext" ); } + /** + * @covers JavaScriptContent::getModel + */ public function testGetModel() { $content = $this->newContent( "hello world." ); $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $content->getModel() ); } + /** + * @covers JavaScriptContent::getContentHandler + */ public function testGetContentHandler() { $content = $this->newContent( "hello world." ); @@ -269,5 +284,4 @@ class JavaScriptContentTest extends TextContentTest { array( new JavaScriptContent( "hallo" ), new JavaScriptContent( "HALLO" ), false ), ); } - } diff --git a/tests/phpunit/includes/content/TextContentTest.php b/tests/phpunit/includes/content/TextContentTest.php index 382f71a8..a1f099f3 100644 --- a/tests/phpunit/includes/content/TextContentTest.php +++ b/tests/phpunit/includes/content/TextContentTest.php @@ -51,6 +51,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataGetParserOutput + * @covers TextContent::getParserOutput */ public function testGetParserOutput( $title, $model, $text, $expectedHtml, $expectedFields = null ) { $title = Title::newFromText( $title ); @@ -96,6 +97,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataPreSaveTransform + * @covers TextContent::preSaveTransform */ public function testPreSaveTransform( $text, $expected ) { global $wgContLang; @@ -119,6 +121,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataPreloadTransform + * @covers TextContent::preloadTransform */ public function testPreloadTransform( $text, $expected ) { global $wgContLang; @@ -140,6 +143,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataGetRedirectTarget + * @covers TextContent::getRedirectTarget */ public function testGetRedirectTarget( $text, $expected ) { $content = $this->newContent( $text ); @@ -154,6 +158,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataGetRedirectTarget + * @covers TextContent::isRedirect */ public function testIsRedirect( $text, $expected ) { $content = $this->newContent( $text ); @@ -162,7 +167,7 @@ class TextContentTest extends MediaWikiLangTestCase { } /** - * @todo: test needs database! Should be done by a test class in the Database group. + * @todo Test needs database! Should be done by a test class in the Database group. */ /* public function getRedirectChain() { @@ -172,7 +177,7 @@ class TextContentTest extends MediaWikiLangTestCase { */ /** - * @todo: test needs database! Should be done by a test class in the Database group. + * @todo Test needs database! Should be done by a test class in the Database group. */ /* public function getUltimateRedirectTarget() { @@ -209,17 +214,14 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataIsCountable * @group Database + * @covers TextContent::isCountable */ public function testIsCountable( $text, $hasLinks, $mode, $expected ) { - global $wgArticleCountMethod; - - $old = $wgArticleCountMethod; - $wgArticleCountMethod = $mode; + $this->setMwGlobals( 'wgArticleCountMethod', $mode ); $content = $this->newContent( $text ); $v = $content->isCountable( $hasLinks, $this->context->getTitle() ); - $wgArticleCountMethod = $old; $this->assertEquals( $expected, $v, 'isCountable() returned unexpected value ' . var_export( $v, true ) . ' instead of ' . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" ); @@ -244,6 +246,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataGetTextForSummary + * @covers TextContent::getTextForSummary */ public function testGetTextForSummary( $text, $maxlength, $expected ) { $content = $this->newContent( $text ); @@ -251,12 +254,18 @@ class TextContentTest extends MediaWikiLangTestCase { $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(); @@ -265,30 +274,45 @@ class TextContentTest extends MediaWikiLangTestCase { $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." ); @@ -306,6 +330,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataIsEmpty + * @covers TextContent::isEmpty */ public function testIsEmpty( $text, $empty ) { $content = $this->newContent( $text ); @@ -325,6 +350,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataEquals + * @covers TextContent::equals */ public function testEquals( Content $a, Content $b = null, $equal = false ) { $this->assertEquals( $equal, $a->equals( $b ) ); @@ -346,6 +372,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataGetDeletionUpdates + * @covers TextContent::getDeletionUpdates */ public function testDeletionUpdates( $title, $model, $text, $expectedStuff ) { $ns = $this->getDefaultWikitextNS(); @@ -414,6 +441,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider provideConvert + * @covers TextContent::convert */ public function testConvert( $text, $model, $lossy, $expectedNative ) { $content = $this->newContent( $text ); @@ -427,5 +455,4 @@ class TextContentTest extends MediaWikiLangTestCase { $this->assertEquals( $expectedNative, $converted->getNativeData() ); } } - } diff --git a/tests/phpunit/includes/content/WikitextContentHandlerTest.php b/tests/phpunit/includes/content/WikitextContentHandlerTest.php index 0f6a968b..75a72784 100644 --- a/tests/phpunit/includes/content/WikitextContentHandlerTest.php +++ b/tests/phpunit/includes/content/WikitextContentHandlerTest.php @@ -16,6 +16,9 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase { $this->handler = ContentHandler::getForModelID( CONTENT_MODEL_WIKITEXT ); } + /** + * @covers WikitextContentHandler::serializeContent + */ public function testSerializeContent() { $content = new WikitextContent( 'hello world' ); @@ -30,6 +33,9 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase { } } + /** + * @covers WikitextContentHandler::unserializeContent + */ public function testUnserializeContent() { $content = $this->handler->unserializeContent( 'hello world' ); $this->assertEquals( 'hello world', $content->getNativeData() ); @@ -45,6 +51,9 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase { } } + /** + * @covers WikitextContentHandler::makeEmptyContent + */ public function testMakeEmptyContent() { $content = $this->handler->makeEmptyContent(); @@ -61,7 +70,39 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase { } /** + * @dataProvider provideMakeRedirectContent + * @param Title|string $title Title object or string for Title::newFromText() + * @param string $expected Serialized form of the content object built + * @covers WikitextContentHandler::makeRedirectContent + */ + public function testMakeRedirectContent( $title, $expected ) { + global $wgContLang; + $wgContLang->resetNamespaces(); + + if ( is_string( $title ) ) { + $title = Title::newFromText( $title ); + } + $content = $this->handler->makeRedirectContent( $title ); + $this->assertEquals( $expected, $content->serialize() ); + } + + public static function provideMakeRedirectContent() { + return array( + array( 'Hello', '#REDIRECT [[Hello]]' ), + array( 'Template:Hello', '#REDIRECT [[Template:Hello]]' ), + array( 'Hello#section', '#REDIRECT [[Hello#section]]' ), + array( 'user:john_doe#section', '#REDIRECT [[User:John doe#section]]' ), + array( 'MEDIAWIKI:FOOBAR', '#REDIRECT [[MediaWiki:FOOBAR]]' ), + array( 'Category:Foo', '#REDIRECT [[:Category:Foo]]' ), + array( Title::makeTitle( NS_MAIN, 'en:Foo' ), '#REDIRECT [[en:Foo]]' ), + array( Title::makeTitle( NS_MAIN, 'Foo', '', 'en' ), '#REDIRECT [[:en:Foo]]' ), + array( Title::makeTitle( NS_MAIN, 'Bar', 'fragment', 'google' ), '#REDIRECT [[google:Bar#fragment]]' ), + ); + } + + /** * @dataProvider dataIsSupportedFormat + * @covers WikitextContentHandler::isSupportedFormat */ public function testIsSupportedFormat( $format, $supported ) { $this->assertEquals( $supported, $this->handler->isSupportedFormat( $format ) ); @@ -101,6 +142,7 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase { /** * @dataProvider dataMerge3 + * @covers WikitextContentHandler::merge3 */ public function testMerge3( $old, $mine, $yours, $expected ) { $this->checkHasDiff3(); @@ -158,6 +200,7 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase { /** * @dataProvider dataGetAutosummary + * @covers WikitextContentHandler::getAutosummary */ public function testGetAutosummary( $old, $new, $flags, $expected ) { $oldContent = is_null( $old ) ? null : new WikitextContent( $old ); @@ -181,5 +224,4 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase { /* public function testGetUndoContent( Revision $current, Revision $undo, Revision $undoafter = null ) {} */ - } diff --git a/tests/phpunit/includes/content/WikitextContentTest.php b/tests/phpunit/includes/content/WikitextContentTest.php index c9eecf7f..9f20073d 100644 --- a/tests/phpunit/includes/content/WikitextContentTest.php +++ b/tests/phpunit/includes/content/WikitextContentTest.php @@ -64,6 +64,7 @@ more stuff /** * @dataProvider dataGetSecondaryDataUpdates * @group Database + * @covers WikitextContent::getSecondaryDataUpdates */ public function testGetSecondaryDataUpdates( $title, $model, $text, $expectedStuff ) { $ns = $this->getDefaultWikitextNS(); @@ -116,6 +117,7 @@ just a test" /** * @dataProvider dataGetSection + * @covers WikitextContent::getSection */ public function testGetSection( $text, $sectionId, $expectedText ) { $content = $this->newContent( $text ); @@ -167,6 +169,7 @@ just a test" /** * @dataProvider dataReplaceSection + * @covers WikitextContent::replaceSection */ public function testReplaceSection( $text, $section, $with, $sectionTitle, $expected ) { $content = $this->newContent( $text ); @@ -175,6 +178,9 @@ just a test" $this->assertEquals( $expected, is_null( $c ) ? null : $c->getNativeData() ); } + /** + * @covers WikitextContent::addSectionHeader + */ public function testAddSectionHeader() { $content = $this->newContent( 'hello world' ); $content = $content->addSectionHeader( 'test' ); @@ -240,7 +246,7 @@ just a test" } /** - * @todo: test needs database! Should be done by a test class in the Database group. + * @todo Test needs database! Should be done by a test class in the Database group. */ /* public function getRedirectChain() { @@ -250,7 +256,7 @@ just a test" */ /** - * @todo: test needs database! Should be done by a test class in the Database group. + * @todo Test needs database! Should be done by a test class in the Database group. */ /* public function getUltimateRedirectTarget() { @@ -319,6 +325,9 @@ just a test" ); } + /** + * @covers WikitextContent::matchMagicWord + */ public function testMatchMagicWord() { $mw = MagicWord::get( "staticredirect" ); @@ -329,6 +338,9 @@ just a test" $this->assertFalse( $content->matchMagicWord( $mw ), "should not have matched magic word" ); } + /** + * @covers WikitextContent::updateRedirect + */ public function testUpdateRedirect() { $target = Title::newFromText( "testUpdateRedirect_target" ); @@ -348,12 +360,18 @@ just a test" $this->assertEquals( $target->getFullText(), $newContent->getRedirectTarget()->getFullText() ); } + /** + * @covers WikitextContent::getModel + */ public function testGetModel() { $content = $this->newContent( "hello world." ); $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getModel() ); } + /** + * @covers WikitextContent::getContentHandler + */ public function testGetContentHandler() { $content = $this->newContent( "hello world." ); @@ -380,7 +398,7 @@ just a test" CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n", array( 'LinksDeletionUpdate' => array() ) ), - // @todo: more...? + // @todo more...? ); } } diff --git a/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php b/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php new file mode 100644 index 00000000..ba63c091 --- /dev/null +++ b/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php @@ -0,0 +1,209 @@ +<?php +/** + * Holds tests for DatabaseMysqlBase MediaWiki class. + * + * @section LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @author Antoine Musso + * @author Bryan Davis + * @copyright © 2013 Antoine Musso + * @copyright © 2013 Bryan Davis + * @copyright © 2013 Wikimedia Foundation Inc. + */ + +/** + * Fake class around abstract class so we can call concrete methods. + */ +class FakeDatabaseMysqlBase extends DatabaseMysqlBase { + // From DatabaseBase + protected function closeConnection() {} + protected function doQuery( $sql ) {} + + // From DatabaseMysql + protected function mysqlConnect( $realServer ) {} + protected function mysqlFreeResult( $res ) {} + protected function mysqlFetchObject( $res ) {} + protected function mysqlFetchArray( $res ) {} + protected function mysqlNumRows( $res ) {} + protected function mysqlNumFields( $res ) {} + protected function mysqlFieldName( $res, $n ) {} + protected function mysqlDataSeek( $res, $row ) {} + protected function mysqlError( $conn = null ) {} + protected function mysqlFetchField( $res, $n ) {} + protected function mysqlPing() {} + + // From interface DatabaseType + function insertId() {} + function lastErrno() {} + function affectedRows() {} + function getServerVersion() {} +} + +class DatabaseMysqlBaseTest extends MediaWikiTestCase { + + /** + * @dataProvider provideDiapers + * @covers DatabaseMysqlBase::addIdentifierQuotes + */ + public function testAddIdentifierQuotes( $expected, $in ) { + $db = new FakeDatabaseMysqlBase(); + $quoted = $db->addIdentifierQuotes( $in ); + $this->assertEquals($expected, $quoted); + } + + + /** + * Feeds testAddIdentifierQuotes + * + * Named per bug 20281 convention. + */ + function provideDiapers() { + return array( + // Format: expected, input + array( '``', '' ), + + // Yeah I really hate loosely typed PHP idiocies nowadays + array( '``', null ), + + // Dear codereviewer, guess what addIdentifierQuotes() + // will return with thoses: + array( '``', false ), + array( '`1`', true ), + + // We never know what could happen + array( '`0`', 0 ), + array( '`1`', 1 ), + + // Whatchout! Should probably use something more meaningful + array( "`'`", "'" ), # single quote + array( '`"`', '"' ), # double quote + array( '````', '`' ), # backtick + array( '`’`', '’' ), # apostrophe (look at your encyclopedia) + + // sneaky NUL bytes are lurking everywhere + array( '``', "\0" ), + array( '`xyzzy`', "\0x\0y\0z\0z\0y\0" ), + + // unicode chars + array( + self::createUnicodeString( '`\u0001a\uFFFFb`' ), + self::createUnicodeString( '\u0001a\uFFFFb' ) + ), + array( + self::createUnicodeString( '`\u0001\uFFFF`' ), + self::createUnicodeString( '\u0001\u0000\uFFFF\u0000' ) + ), + array( '`☃`', '☃' ), + array( '`メインページ`', 'メインページ' ), + array( '`Басты_бет`', 'Басты_бет' ), + + // Real world: + array( '`Alix`', 'Alix' ), # while( ! $recovered ) { sleep(); } + array( '`Backtick: ```', 'Backtick: `' ), + array( '`This is a test`', 'This is a test' ), + ); + } + + private static function createUnicodeString($str) { + return json_decode( '"' . $str . '"' ); + } + + function getMockForViews() { + $db = $this->getMockBuilder( 'DatabaseMysql' ) + ->disableOriginalConstructor() + ->setMethods( array( 'fetchRow', 'query' ) ) + ->getMock(); + + $db->expects( $this->any() ) + ->method( 'query' ) + ->with( $this->anything() ) + ->will( + $this->returnValue( null ) + ); + + $db->expects( $this->any() ) + ->method( 'fetchRow' ) + ->with( $this->anything() ) + ->will( $this->onConsecutiveCalls( + array( 'Tables_in_' => 'view1' ), + array( 'Tables_in_' => 'view2' ), + array( 'Tables_in_' => 'myview' ), + false # no more rows + )); + return $db; + } + /** + * @covers DatabaseMysqlBase::listViews + */ + function testListviews() { + $db = $this->getMockForViews(); + + // The first call populate an internal cache of views + $this->assertEquals( array( 'view1', 'view2', 'myview'), + $db->listViews() ); + $this->assertEquals( array( 'view1', 'view2', 'myview'), + $db->listViews() ); + + // Prefix filtering + $this->assertEquals( array( 'view1', 'view2' ), + $db->listViews( 'view' ) ); + $this->assertEquals( array( 'myview' ), + $db->listViews( 'my' ) ); + $this->assertEquals( array(), + $db->listViews( 'UNUSED_PREFIX' ) ); + $this->assertEquals( array( 'view1', 'view2', 'myview'), + $db->listViews( '' ) ); + } + + /** + * @covers DatabaseMysqlBase::isView + * @dataProvider provideViewExistanceChecks + */ + function testIsView( $isView, $viewName ) { + $db = $this->getMockForViews(); + + switch( $isView ) { + case true: + $this->assertTrue( $db->isView( $viewName ), + "$viewName should be considered a view" ); + break; + + case false: + $this->assertFalse( $db->isView( $viewName ), + "$viewName has not been defined as a view" ); + break; + } + + } + + function provideViewExistanceChecks() { + return array( + // format: whether it is a view, view name + array( true, 'view1' ), + array( true, 'view2' ), + array( true, 'myview' ), + + array( false, 'user' ), + + array( false, 'view10' ), + array( false, 'my' ), + array( false, 'OH_MY_GOD' ), # they killed kenny! + ); + } + +} diff --git a/tests/phpunit/includes/db/DatabaseSQLTest.php b/tests/phpunit/includes/db/DatabaseSQLTest.php index 09792438..bdd567e7 100644 --- a/tests/phpunit/includes/db/DatabaseSQLTest.php +++ b/tests/phpunit/includes/db/DatabaseSQLTest.php @@ -2,35 +2,44 @@ /** * Test the abstract database layer - * Using Mysql for the sql at the moment TODO - * - * @group Database + * This is a non DBMS depending test. */ class DatabaseSQLTest extends MediaWikiTestCase { + /** + * @var DatabaseTestHelper + */ + private $database; + protected function setUp() { parent::setUp(); - // TODO support other DBMS or find another way to do it - if ( $this->db->getType() !== 'mysql' ) { - $this->markTestSkipped( 'No mysql database' ); - } + $this->database = new DatabaseTestHelper( __CLASS__ ); + } + + protected function assertLastSql( $sqlText ) { + $this->assertEquals( + $this->database->getLastSqls(), + $sqlText + ); } /** - * @dataProvider provideSelectSQLText + * @dataProvider provideSelect + * @covers DatabaseBase::select */ - function testSelectSQLText( $sql, $sqlText ) { - $this->assertEquals( trim( $this->db->selectSQLText( - isset( $sql['tables'] ) ? $sql['tables'] : array(), - isset( $sql['fields'] ) ? $sql['fields'] : array(), + public function testSelect( $sql, $sqlText ) { + $this->database->select( + $sql['tables'], + $sql['fields'], isset( $sql['conds'] ) ? $sql['conds'] : array(), __METHOD__, isset( $sql['options'] ) ? $sql['options'] : array(), isset( $sql['join_conds'] ) ? $sql['join_conds'] : array() - ) ), $sqlText ); + ); + $this->assertLastSql( $sqlText ); } - public static function provideSelectSQLText() { + public static function provideSelect() { return array( array( array( @@ -38,8 +47,8 @@ class DatabaseSQLTest extends MediaWikiTestCase { 'fields' => array( 'field', 'alias' => 'field2' ), 'conds' => array( 'alias' => 'text' ), ), - "SELECT field,field2 AS alias " . - "FROM `unittest_table` " . + "SELECT field,field2 AS alias " . + "FROM table " . "WHERE alias = 'text'" ), array( @@ -49,9 +58,9 @@ class DatabaseSQLTest extends MediaWikiTestCase { 'conds' => array( 'alias' => 'text' ), 'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ), ), - "SELECT field,field2 AS alias " . - "FROM `unittest_table` " . - "WHERE alias = 'text' " . + "SELECT field,field2 AS alias " . + "FROM table " . + "WHERE alias = 'text' " . "ORDER BY field " . "LIMIT 1" ), @@ -65,9 +74,9 @@ class DatabaseSQLTest extends MediaWikiTestCase { 'LEFT JOIN', 'tid = t2.id' ) ), ), - "SELECT tid,field,field2 AS alias,t2.id " . - "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id)) " . - "WHERE alias = 'text' " . + "SELECT tid,field,field2 AS alias,t2.id " . + "FROM table LEFT JOIN table2 t2 ON ((tid = t2.id)) " . + "WHERE alias = 'text' " . "ORDER BY field " . "LIMIT 1" ), @@ -81,9 +90,9 @@ class DatabaseSQLTest extends MediaWikiTestCase { 'LEFT JOIN', 'tid = t2.id' ) ), ), - "SELECT tid,field,field2 AS alias,t2.id " . - "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id)) " . - "WHERE alias = 'text' " . + "SELECT tid,field,field2 AS alias,t2.id " . + "FROM table LEFT JOIN table2 t2 ON ((tid = t2.id)) " . + "WHERE alias = 'text' " . "GROUP BY field HAVING COUNT(*) > 1 " . "LIMIT 1" ), @@ -97,20 +106,457 @@ class DatabaseSQLTest extends MediaWikiTestCase { 'LEFT JOIN', 'tid = t2.id' ) ), ), - "SELECT tid,field,field2 AS alias,t2.id " . - "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id)) " . - "WHERE alias = 'text' " . + "SELECT tid,field,field2 AS alias,t2.id " . + "FROM table LEFT JOIN table2 t2 ON ((tid = t2.id)) " . + "WHERE alias = 'text' " . "GROUP BY field,field2 HAVING (COUNT(*) > 1) AND field = '1' " . "LIMIT 1" ), + array( + array( + 'tables' => array( 'table' ), + 'fields' => array( 'alias' => 'field' ), + 'conds' => array( 'alias' => array( 1, 2, 3, 4 ) ), + ), + "SELECT field AS alias " . + "FROM table " . + "WHERE alias IN ('1','2','3','4')" + ), + ); + } + + /** + * @dataProvider provideUpdate + * @covers DatabaseBase::update + */ + public function testUpdate( $sql, $sqlText ) { + $this->database->update( + $sql['table'], + $sql['values'], + $sql['conds'], + __METHOD__, + isset( $sql['options'] ) ? $sql['options'] : array() + ); + $this->assertLastSql( $sqlText ); + } + + public static function provideUpdate() { + return array( + array( + array( + 'table' => 'table', + 'values' => array( 'field' => 'text', 'field2' => 'text2' ), + 'conds' => array( 'alias' => 'text' ), + ), + "UPDATE table " . + "SET field = 'text'" . + ",field2 = 'text2' " . + "WHERE alias = 'text'" + ), + array( + array( + 'table' => 'table', + 'values' => array( 'field = other', 'field2' => 'text2' ), + 'conds' => array( 'id' => '1' ), + ), + "UPDATE table " . + "SET field = other" . + ",field2 = 'text2' " . + "WHERE id = '1'" + ), + array( + array( + 'table' => 'table', + 'values' => array( 'field = other', 'field2' => 'text2' ), + 'conds' => '*', + ), + "UPDATE table " . + "SET field = other" . + ",field2 = 'text2'" + ), + ); + } + + /** + * @dataProvider provideDelete + * @covers DatabaseBase::delete + */ + public function testDelete( $sql, $sqlText ) { + $this->database->delete( + $sql['table'], + $sql['conds'], + __METHOD__ + ); + $this->assertLastSql( $sqlText ); + } + + public static function provideDelete() { + return array( + array( + array( + 'table' => 'table', + 'conds' => array( 'alias' => 'text' ), + ), + "DELETE FROM table " . + "WHERE alias = 'text'" + ), + array( + array( + 'table' => 'table', + 'conds' => '*', + ), + "DELETE FROM table" + ), + ); + } + + /** + * @dataProvider provideUpsert + * @covers DatabaseBase::upsert + */ + public function testUpsert( $sql, $sqlText ) { + $this->database->upsert( + $sql['table'], + $sql['rows'], + $sql['uniqueIndexes'], + $sql['set'], + __METHOD__ + ); + $this->assertLastSql( $sqlText ); + } + + public static function provideUpsert() { + return array( + array( + array( + 'table' => 'upsert_table', + 'rows' => array( 'field' => 'text', 'field2' => 'text2' ), + 'uniqueIndexes' => array( 'field' ), + 'set' => array( 'field' => 'set' ), + ), + "BEGIN; " . + "UPDATE upsert_table " . + "SET field = 'set' " . + "WHERE ((field = 'text')); " . + "INSERT IGNORE INTO upsert_table " . + "(field,field2) " . + "VALUES ('text','text2'); " . + "COMMIT" + ), + ); + } + + /** + * @dataProvider provideDeleteJoin + * @covers DatabaseBase::deleteJoin + */ + public function testDeleteJoin( $sql, $sqlText ) { + $this->database->deleteJoin( + $sql['delTable'], + $sql['joinTable'], + $sql['delVar'], + $sql['joinVar'], + $sql['conds'], + __METHOD__ + ); + $this->assertLastSql( $sqlText ); + } + + public static function provideDeleteJoin() { + return array( + array( + array( + 'delTable' => 'table', + 'joinTable' => 'table_join', + 'delVar' => 'field', + 'joinVar' => 'field_join', + 'conds' => array( 'alias' => 'text' ), + ), + "DELETE FROM table " . + "WHERE field IN (" . + "SELECT field_join FROM table_join WHERE alias = 'text'" . + ")" + ), + array( + array( + 'delTable' => 'table', + 'joinTable' => 'table_join', + 'delVar' => 'field', + 'joinVar' => 'field_join', + 'conds' => '*', + ), + "DELETE FROM table " . + "WHERE field IN (" . + "SELECT field_join FROM table_join " . + ")" + ), + ); + } + + /** + * @dataProvider provideInsert + * @covers DatabaseBase::insert + */ + public function testInsert( $sql, $sqlText ) { + $this->database->insert( + $sql['table'], + $sql['rows'], + __METHOD__, + isset( $sql['options'] ) ? $sql['options'] : array() + ); + $this->assertLastSql( $sqlText ); + } + + public static function provideInsert() { + return array( + array( + array( + 'table' => 'table', + 'rows' => array( 'field' => 'text', 'field2' => 2 ), + ), + "INSERT INTO table " . + "(field,field2) " . + "VALUES ('text','2')" + ), + array( + array( + 'table' => 'table', + 'rows' => array( 'field' => 'text', 'field2' => 2 ), + 'options' => 'IGNORE', + ), + "INSERT IGNORE INTO table " . + "(field,field2) " . + "VALUES ('text','2')" + ), + array( + array( + 'table' => 'table', + 'rows' => array( + array( 'field' => 'text', 'field2' => 2 ), + array( 'field' => 'multi', 'field2' => 3 ), + ), + 'options' => 'IGNORE', + ), + "INSERT IGNORE INTO table " . + "(field,field2) " . + "VALUES " . + "('text','2')," . + "('multi','3')" + ), + ); + } + + /** + * @dataProvider provideInsertSelect + * @covers DatabaseBase::insertSelect + */ + public function testInsertSelect( $sql, $sqlText ) { + $this->database->insertSelect( + $sql['destTable'], + $sql['srcTable'], + $sql['varMap'], + $sql['conds'], + __METHOD__, + isset( $sql['insertOptions'] ) ? $sql['insertOptions'] : array(), + isset( $sql['selectOptions'] ) ? $sql['selectOptions'] : array() + ); + $this->assertLastSql( $sqlText ); + } + + public static function provideInsertSelect() { + return array( + array( + array( + 'destTable' => 'insert_table', + 'srcTable' => 'select_table', + 'varMap' => array( 'field_insert' => 'field_select', 'field' => 'field2' ), + 'conds' => '*', + ), + "INSERT INTO insert_table " . + "(field_insert,field) " . + "SELECT field_select,field2 " . + "FROM select_table" + ), + array( + array( + 'destTable' => 'insert_table', + 'srcTable' => 'select_table', + 'varMap' => array( 'field_insert' => 'field_select', 'field' => 'field2' ), + 'conds' => array( 'field' => 2 ), + ), + "INSERT INTO insert_table " . + "(field_insert,field) " . + "SELECT field_select,field2 " . + "FROM select_table " . + "WHERE field = '2'" + ), + array( + array( + 'destTable' => 'insert_table', + 'srcTable' => 'select_table', + 'varMap' => array( 'field_insert' => 'field_select', 'field' => 'field2' ), + 'conds' => array( 'field' => 2 ), + 'insertOptions' => 'IGNORE', + 'selectOptions' => array( 'ORDER BY' => 'field' ), + ), + "INSERT IGNORE INTO insert_table " . + "(field_insert,field) " . + "SELECT field_select,field2 " . + "FROM select_table " . + "WHERE field = '2' " . + "ORDER BY field" + ), + ); + } + + /** + * @dataProvider provideReplace + * @covers DatabaseBase::replace + */ + public function testReplace( $sql, $sqlText ) { + $this->database->replace( + $sql['table'], + $sql['uniqueIndexes'], + $sql['rows'], + __METHOD__ + ); + $this->assertLastSql( $sqlText ); + } + + public static function provideReplace() { + return array( + array( + array( + 'table' => 'replace_table', + 'uniqueIndexes' => array( 'field' ), + 'rows' => array( 'field' => 'text', 'field2' => 'text2' ), + ), + "DELETE FROM replace_table " . + "WHERE ( field='text' ); " . + "INSERT INTO replace_table " . + "(field,field2) " . + "VALUES ('text','text2')" + ), + array( + array( + 'table' => 'module_deps', + 'uniqueIndexes' => array( array( 'md_module', 'md_skin' ) ), + 'rows' => array( + 'md_module' => 'module', + 'md_skin' => 'skin', + 'md_deps' => 'deps', + ), + ), + "DELETE FROM module_deps " . + "WHERE ( md_module='module' AND md_skin='skin' ); " . + "INSERT INTO module_deps " . + "(md_module,md_skin,md_deps) " . + "VALUES ('module','skin','deps')" + ), + array( + array( + 'table' => 'module_deps', + 'uniqueIndexes' => array( array( 'md_module', 'md_skin' ) ), + 'rows' => array( + array( + 'md_module' => 'module', + 'md_skin' => 'skin', + 'md_deps' => 'deps', + ), array( + 'md_module' => 'module2', + 'md_skin' => 'skin2', + 'md_deps' => 'deps2', + ), + ), + ), + "DELETE FROM module_deps " . + "WHERE ( md_module='module' AND md_skin='skin' ); " . + "INSERT INTO module_deps " . + "(md_module,md_skin,md_deps) " . + "VALUES ('module','skin','deps'); " . + "DELETE FROM module_deps " . + "WHERE ( md_module='module2' AND md_skin='skin2' ); " . + "INSERT INTO module_deps " . + "(md_module,md_skin,md_deps) " . + "VALUES ('module2','skin2','deps2')" + ), + array( + array( + 'table' => 'module_deps', + 'uniqueIndexes' => array( 'md_module', 'md_skin' ), + 'rows' => array( + array( + 'md_module' => 'module', + 'md_skin' => 'skin', + 'md_deps' => 'deps', + ), array( + 'md_module' => 'module2', + 'md_skin' => 'skin2', + 'md_deps' => 'deps2', + ), + ), + ), + "DELETE FROM module_deps " . + "WHERE ( md_module='module' ) OR ( md_skin='skin' ); " . + "INSERT INTO module_deps " . + "(md_module,md_skin,md_deps) " . + "VALUES ('module','skin','deps'); " . + "DELETE FROM module_deps " . + "WHERE ( md_module='module2' ) OR ( md_skin='skin2' ); " . + "INSERT INTO module_deps " . + "(md_module,md_skin,md_deps) " . + "VALUES ('module2','skin2','deps2')" + ), + array( + array( + 'table' => 'module_deps', + 'uniqueIndexes' => array(), + 'rows' => array( + 'md_module' => 'module', + 'md_skin' => 'skin', + 'md_deps' => 'deps', + ), + ), + "INSERT INTO module_deps " . + "(md_module,md_skin,md_deps) " . + "VALUES ('module','skin','deps')" + ), + ); + } + + /** + * @dataProvider provideNativeReplace + * @covers DatabaseBase::nativeReplace + */ + public function testNativeReplace( $sql, $sqlText ) { + $this->database->nativeReplace( + $sql['table'], + $sql['rows'], + __METHOD__ + ); + $this->assertLastSql( $sqlText ); + } + + public static function provideNativeReplace() { + return array( + array( + array( + 'table' => 'replace_table', + 'rows' => array( 'field' => 'text', 'field2' => 'text2' ), + ), + "REPLACE INTO replace_table " . + "(field,field2) " . + "VALUES ('text','text2')" + ), ); } /** * @dataProvider provideConditional + * @covers DatabaseBase::conditional */ - function testConditional( $sql, $sqlText ) { - $this->assertEquals( trim( $this->db->conditional( + public function testConditional( $sql, $sqlText ) { + $this->assertEquals( trim( $this->database->conditional( $sql['conds'], $sql['true'], $sql['false'] @@ -145,4 +591,131 @@ class DatabaseSQLTest extends MediaWikiTestCase { ), ); } + + /** + * @dataProvider provideBuildConcat + * @covers DatabaseBase::buildConcat + */ + public function testBuildConcat( $stringList, $sqlText ) { + $this->assertEquals( trim( $this->database->buildConcat( + $stringList + ) ), $sqlText ); + } + + public static function provideBuildConcat() { + return array( + array( + array( 'field', 'field2' ), + "CONCAT(field,field2)" + ), + array( + array( "'test'", 'field2' ), + "CONCAT('test',field2)" + ), + ); + } + + /** + * @dataProvider provideBuildLike + * @covers DatabaseBase::buildLike + */ + public function testBuildLike( $array, $sqlText ) { + $this->assertEquals( trim( $this->database->buildLike( + $array + ) ), $sqlText ); + } + + public static function provideBuildLike() { + return array( + array( + 'text', + "LIKE 'text'" + ), + array( + array( 'text', new LikeMatch( '%' ) ), + "LIKE 'text%'" + ), + array( + array( 'text', new LikeMatch( '%' ), 'text2' ), + "LIKE 'text%text2'" + ), + array( + array( 'text', new LikeMatch( '_' ) ), + "LIKE 'text_'" + ), + ); + } + + /** + * @dataProvider provideUnionQueries + * @covers DatabaseBase::unionQueries + */ + public function testUnionQueries( $sql, $sqlText ) { + $this->assertEquals( trim( $this->database->unionQueries( + $sql['sqls'], + $sql['all'] + ) ), $sqlText ); + } + + public static function provideUnionQueries() { + return array( + array( + array( + 'sqls' => array( 'RAW SQL', 'RAW2SQL' ), + 'all' => true, + ), + "(RAW SQL) UNION ALL (RAW2SQL)" + ), + array( + array( + 'sqls' => array( 'RAW SQL', 'RAW2SQL' ), + 'all' => false, + ), + "(RAW SQL) UNION (RAW2SQL)" + ), + array( + array( + 'sqls' => array( 'RAW SQL', 'RAW2SQL', 'RAW3SQL' ), + 'all' => false, + ), + "(RAW SQL) UNION (RAW2SQL) UNION (RAW3SQL)" + ), + ); + } + + /** + * @covers DatabaseBase::commit + */ + public function testTransactionCommit() { + $this->database->begin( __METHOD__ ); + $this->database->commit( __METHOD__ ); + $this->assertLastSql( 'BEGIN; COMMIT' ); + } + + /** + * @covers DatabaseBase::rollback + */ + public function testTransactionRollback() { + $this->database->begin( __METHOD__ ); + $this->database->rollback( __METHOD__ ); + $this->assertLastSql( 'BEGIN; ROLLBACK' ); + } + + /** + * @covers DatabaseBase::dropTable + */ + public function testDropTable() { + $this->database->setExistingTables( array( 'table' ) ); + $this->database->dropTable( 'table', __METHOD__ ); + $this->assertLastSql( 'DROP TABLE table' ); + } + + /** + * @covers DatabaseBase::dropTable + */ + public function testDropNonExistingTable() { + $this->assertFalse( + $this->database->dropTable( 'non_existing', __METHOD__ ) + ); + } } diff --git a/tests/phpunit/includes/db/DatabaseSqliteTest.php b/tests/phpunit/includes/db/DatabaseSqliteTest.php index 7b84d471..70ee9465 100644 --- a/tests/phpunit/includes/db/DatabaseSqliteTest.php +++ b/tests/phpunit/includes/db/DatabaseSqliteTest.php @@ -9,6 +9,7 @@ class MockDatabaseSqlite extends DatabaseSqliteStandalone { function query( $sql, $fname = '', $tempIgnore = false ) { $this->lastQuery = $sql; + return true; } @@ -26,6 +27,10 @@ class MockDatabaseSqlite extends DatabaseSqliteStandalone { * @group medium */ class DatabaseSqliteTest extends MediaWikiTestCase { + + /** + * @var MockDatabaseSqlite + */ var $db; protected function setUp() { @@ -82,6 +87,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase { /** * @dataProvider provideAddQuotes() + * @covers DatabaseSqlite::addQuotes */ public function testAddQuotes( $value, $expected ) { // check quoting @@ -104,6 +110,9 @@ class DatabaseSqliteTest extends MediaWikiTestCase { } } + /** + * @covers DatabaseSqlite::replaceVars + */ public function testReplaceVars() { $this->assertEquals( 'foo', $this->replaceVars( 'foo' ), "Don't break anything accidentally" ); @@ -142,6 +151,9 @@ class DatabaseSqliteTest extends MediaWikiTestCase { ); } + /** + * @covers DatabaseSqlite::tableName + */ public function testTableName() { // @todo Moar! $db = new DatabaseSqliteStandalone( ':memory:' ); @@ -152,6 +164,9 @@ class DatabaseSqliteTest extends MediaWikiTestCase { $this->assertEquals( 'foobar', $db->tableName( 'bar' ) ); } + /** + * @covers DatabaseSqlite::duplicateTableStructure + */ public function testDuplicateTableStructure() { $db = new DatabaseSqliteStandalone( ':memory:' ); $db->query( 'CREATE TABLE foo(foo, barfoo)' ); @@ -173,6 +188,9 @@ class DatabaseSqliteTest extends MediaWikiTestCase { ); } + /** + * @covers DatabaseSqlite::duplicateTableStructure + */ public function testDuplicateTableStructureVirtual() { $db = new DatabaseSqliteStandalone( ':memory:' ); if ( $db->getFulltextSearchModule() != 'FTS3' ) { @@ -193,6 +211,9 @@ class DatabaseSqliteTest extends MediaWikiTestCase { ); } + /** + * @covers DatabaseSqlite::deleteJoin + */ public function testDeleteJoin() { $db = new DatabaseSqliteStandalone( ':memory:' ); $db->query( 'CREATE TABLE a (a_1)', __METHOD__ ); @@ -232,7 +253,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase { /** * Runs upgrades of older databases and compares results with current schema - * @todo: currently only checks list of tables + * @todo Currently only checks list of tables */ public function testUpgrades() { global $IP, $wgVersion, $wgProfileToDatabase; @@ -305,13 +326,19 @@ class DatabaseSqliteTest extends MediaWikiTestCase { } } + /** + * @covers DatabaseSqlite::insertId + */ public function testInsertIdType() { $db = new DatabaseSqliteStandalone( ':memory:' ); - $this->assertInstanceOf( 'ResultWrapper', - $db->query( 'CREATE TABLE a ( a_1 )', __METHOD__ ), "Database creationg" ); - $this->assertTrue( $db->insert( 'a', array( 'a_1' => 10 ), __METHOD__ ), - "Insertion worked" ); - $this->assertEquals( "integer", gettype( $db->insertId() ), "Actual typecheck" ); + + $databaseCreation = $db->query( 'CREATE TABLE a ( a_1 )', __METHOD__ ); + $this->assertInstanceOf( 'ResultWrapper', $databaseCreation, "Database creation" ); + + $insertion = $db->insert( 'a', array( 'a_1' => 10 ), __METHOD__ ); + $this->assertTrue( $insertion, "Insertion worked" ); + + $this->assertInternalType( 'integer', $db->insertId(), "Actual typecheck" ); $this->assertTrue( $db->close(), "closing database" ); } @@ -327,12 +354,14 @@ class DatabaseSqliteTest extends MediaWikiTestCase { $db->sourceFile( "$IP/tests/phpunit/data/db/sqlite/tables-$version.sql" ); $updater = DatabaseUpdater::newForDB( $db, false, $maint ); $updater->doUpdates( array( 'core' ) ); + return $db; } private function getTables( $db ) { $list = array_flip( $db->listTables() ); $excluded = array( + 'external_user', // removed from core in 1.22 'math', // moved out of core in 1.18 'trackbacks', // removed from core in 1.19 'searchindex', @@ -348,6 +377,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase { } $list = array_flip( $list ); sort( $list ); + return $list; } @@ -359,6 +389,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase { $cols[$col->name] = $col; } ksort( $cols ); + return $cols; } @@ -376,10 +407,11 @@ class DatabaseSqliteTest extends MediaWikiTestCase { $indexes[$index->name] = $index; } ksort( $indexes ); + return $indexes; } - function testCaseInsensitiveLike() { + public function testCaseInsensitiveLike() { // TODO: Test this for all databases $db = new DatabaseSqliteStandalone( ':memory:' ); $res = $db->query( 'SELECT "a" LIKE "A" AS a' ); diff --git a/tests/phpunit/includes/db/DatabaseTest.php b/tests/phpunit/includes/db/DatabaseTest.php index 65c80d1d..301fc990 100644 --- a/tests/phpunit/includes/db/DatabaseTest.php +++ b/tests/phpunit/includes/db/DatabaseTest.php @@ -5,7 +5,11 @@ * @group DatabaseBase */ class DatabaseTest extends MediaWikiTestCase { - var $db, $functionTest = false; + /** + * @var DatabaseBase + */ + var $db; + var $functionTest = false; protected function setUp() { parent::setUp(); @@ -19,8 +23,10 @@ class DatabaseTest extends MediaWikiTestCase { $this->functionTest = false; } } - - function testAddQuotesNull() { + /** + * @covers DatabaseBase::dropTable + */ + public function testAddQuotesNull() { $check = "NULL"; if ( $this->db->getType() === 'sqlite' || $this->db->getType() === 'oracle' ) { $check = "''"; @@ -28,7 +34,7 @@ class DatabaseTest extends MediaWikiTestCase { $this->assertEquals( $check, $this->db->addQuotes( null ) ); } - function testAddQuotesInt() { + public function testAddQuotesInt() { # returning just "1234" should be ok too, though... # maybe $this->assertEquals( @@ -36,20 +42,20 @@ class DatabaseTest extends MediaWikiTestCase { $this->db->addQuotes( 1234 ) ); } - function testAddQuotesFloat() { + public function testAddQuotesFloat() { # returning just "1234.5678" would be ok too, though $this->assertEquals( "'1234.5678'", $this->db->addQuotes( 1234.5678 ) ); } - function testAddQuotesString() { + public function testAddQuotesString() { $this->assertEquals( "'string'", $this->db->addQuotes( 'string' ) ); } - function testAddQuotesStringQuote() { + public function testAddQuotesStringQuote() { $check = "'string''s cause trouble'"; if ( $this->db->getType() === 'mysql' ) { $check = "'string\'s cause trouble'"; @@ -84,36 +90,46 @@ class DatabaseTest extends MediaWikiTestCase { $quote = ''; } elseif ( $this->db->getType() === 'mysql' ) { $quote = '`'; + } elseif ( $this->db->getType() === 'oracle' ) { + $quote = '/*Q*/'; } else { $quote = '"'; } if ( $database !== null ) { - $database = $quote . $database . $quote . '.'; + if ( $this->db->getType() === 'oracle' ) { + $database = $quote . $database . '.'; + } else { + $database = $quote . $database . $quote . '.'; + } } if ( $prefix === null ) { $prefix = $this->dbPrefix(); } - return $database . $quote . $prefix . $table . $quote; + if ( $this->db->getType() === 'oracle' ) { + return strtoupper($database . $quote . $prefix . $table); + } else { + return $database . $quote . $prefix . $table . $quote; + } } - function testTableNameLocal() { + public function testTableNameLocal() { $this->assertEquals( $this->prefixAndQuote( 'tablename' ), $this->db->tableName( 'tablename' ) ); } - function testTableNameRawLocal() { + public function testTableNameRawLocal() { $this->assertEquals( $this->prefixAndQuote( 'tablename', null, null, 'raw' ), $this->db->tableName( 'tablename', 'raw' ) ); } - function testTableNameShared() { + public function testTableNameShared() { $this->assertEquals( $this->prefixAndQuote( 'tablename', 'sharedatabase', 'sh_' ), $this->getSharedTableName( 'tablename', 'sharedatabase', 'sh_' ) @@ -125,7 +141,7 @@ class DatabaseTest extends MediaWikiTestCase { ); } - function testTableNameRawShared() { + public function testTableNameRawShared() { $this->assertEquals( $this->prefixAndQuote( 'tablename', 'sharedatabase', 'sh_', 'raw' ), $this->getSharedTableName( 'tablename', 'sharedatabase', 'sh_', 'raw' ) @@ -137,21 +153,21 @@ class DatabaseTest extends MediaWikiTestCase { ); } - function testTableNameForeign() { + public function testTableNameForeign() { $this->assertEquals( $this->prefixAndQuote( 'tablename', 'databasename', '' ), $this->db->tableName( 'databasename.tablename' ) ); } - function testTableNameRawForeign() { + public function testTableNameRawForeign() { $this->assertEquals( $this->prefixAndQuote( 'tablename', 'databasename', '', 'raw' ), $this->db->tableName( 'databasename.tablename', 'raw' ) ); } - function testFillPreparedEmpty() { + public function testFillPreparedEmpty() { $sql = $this->db->fillPrepared( 'SELECT * FROM interwiki', array() ); $this->assertEquals( @@ -159,7 +175,7 @@ class DatabaseTest extends MediaWikiTestCase { $sql ); } - function testFillPreparedQuestion() { + public function testFillPreparedQuestion() { $sql = $this->db->fillPrepared( 'SELECT * FROM cur WHERE cur_namespace=? AND cur_title=?', array( 4, "Snicker's_paradox" ) ); @@ -171,7 +187,7 @@ class DatabaseTest extends MediaWikiTestCase { $this->assertEquals( $check, $sql ); } - function testFillPreparedBang() { + public function testFillPreparedBang() { $sql = $this->db->fillPrepared( 'SELECT user_id FROM ! WHERE user_name=?', array( '"user"', "Slash's Dot" ) ); @@ -183,7 +199,7 @@ class DatabaseTest extends MediaWikiTestCase { $this->assertEquals( $check, $sql ); } - function testFillPreparedRaw() { + public function testFillPreparedRaw() { $sql = $this->db->fillPrepared( "SELECT * FROM cur WHERE cur_title='This_\\&_that,_WTF\\?\\!'", array( '"user"', "Slash's Dot" ) ); @@ -192,7 +208,7 @@ class DatabaseTest extends MediaWikiTestCase { $sql ); } - function testStoredFunctions() { + public function testStoredFunctions() { if ( !in_array( wfGetDB( DB_MASTER )->getType(), array( 'mysql', 'postgres' ) ) ) { $this->markTestSkipped( 'MySQL or Postgres required' ); } @@ -209,4 +225,10 @@ class DatabaseTest extends MediaWikiTestCase { . ( $this->db->getType() == 'postgres' ? '()' : '' ) ); } + + public function testUnknownTableCorruptsResults() { + $res = $this->db->select( 'page', '*', array( 'page_id' => 1 ) ); + $this->assertFalse( $this->db->tableExists( 'foobarbaz' ) ); + $this->assertInternalType( 'int', $res->numRows() ); + } } diff --git a/tests/phpunit/includes/db/DatabaseTestHelper.php b/tests/phpunit/includes/db/DatabaseTestHelper.php new file mode 100644 index 00000000..790f273c --- /dev/null +++ b/tests/phpunit/includes/db/DatabaseTestHelper.php @@ -0,0 +1,166 @@ +<?php + +/** + * Helper for testing the methods from the DatabaseBase class + * @since 1.22 + */ +class DatabaseTestHelper extends DatabaseBase { + + /** + * __CLASS__ of the test suite, + * used to determine, if the function name is passed every time to query() + */ + protected $testName = array(); + + /** + * Array of lastSqls passed to query(), + * This is an array since some methods in DatabaseBase can do more than one + * query. Cleared when calling getLastSqls(). + */ + protected $lastSqls = array(); + + /** + * Array of tables to be considered as existing by tableExist() + * Use setExistingTables() to alter. + */ + protected $tablesExists; + + public function __construct( $testName ) { + $this->testName = $testName; + } + + /** + * Returns SQL queries grouped by '; ' + * Clear the list of queries that have been done so far. + */ + public function getLastSqls() { + $lastSqls = implode( '; ', $this->lastSqls ); + $this->lastSqls = array(); + + return $lastSqls; + } + + public function setExistingTables( $tablesExists ) { + $this->tablesExists = (array)$tablesExists; + } + + protected function addSql( $sql ) { + // clean up spaces before and after some words and the whole string + $this->lastSqls[] = trim( preg_replace( + '/\s{2,}(?=FROM|WHERE|GROUP BY|ORDER BY|LIMIT)|(?<=SELECT|INSERT|UPDATE)\s{2,}/', + ' ', $sql + ) ); + } + + protected function checkFunctionName( $fname ) { + if ( substr( $fname, 0, strlen( $this->testName ) ) !== $this->testName ) { + throw new MWException( 'function name does not start with test class. ' . + $fname . ' vs. ' . $this->testName . '. ' . + 'Please provide __METHOD__ to database methods.' ); + } + } + + function strencode( $s ) { + // Choose apos to avoid handling of escaping double quotes in quoted text + return str_replace( "'", "\'", $s ); + } + + public function addIdentifierQuotes( $s ) { + // no escaping to avoid handling of double quotes in quoted text + return $s; + } + + public function query( $sql, $fname = '', $tempIgnore = false ) { + $this->checkFunctionName( $fname ); + $this->addSql( $sql ); + + return parent::query( $sql, $fname, $tempIgnore ); + } + + public function tableExists( $table, $fname = __METHOD__ ) { + $this->checkFunctionName( $fname ); + + return in_array( $table, (array)$this->tablesExists ); + } + + // Redeclare parent method to make it public + public function nativeReplace( $table, $rows, $fname ) { + return parent::nativeReplace( $table, $rows, $fname ); + } + + function getType() { + return 'test'; + } + + function open( $server, $user, $password, $dbName ) { + return false; + } + + function fetchObject( $res ) { + return false; + } + + function fetchRow( $res ) { + return false; + } + + function numRows( $res ) { + return -1; + } + + function numFields( $res ) { + return -1; + } + + function fieldName( $res, $n ) { + return 'test'; + } + + function insertId() { + return -1; + } + + function dataSeek( $res, $row ) { + /* nop */ + } + + function lastErrno() { + return -1; + } + + function lastError() { + return 'test'; + } + + function fieldInfo( $table, $field ) { + return false; + } + + function indexInfo( $table, $index, $fname = 'Database::indexInfo' ) { + return false; + } + + function affectedRows() { + return -1; + } + + function getSoftwareLink() { + return 'test'; + } + + function getServerVersion() { + return 'test'; + } + + function getServerInfo() { + return 'test'; + } + + protected function closeConnection() { + return false; + } + + protected function doQuery( $sql ) { + return array(); + } +} diff --git a/tests/phpunit/includes/db/ORMRowTest.php b/tests/phpunit/includes/db/ORMRowTest.php index 596d0bd0..27d4d0e8 100644 --- a/tests/phpunit/includes/db/ORMRowTest.php +++ b/tests/phpunit/includes/db/ORMRowTest.php @@ -76,6 +76,7 @@ abstract class ORMRowTest extends \MediaWikiTestCase { */ protected function getRowInstance( array $data, $loadDefaults ) { $class = $this->getRowClass(); + return new $class( $this->getTableInstance(), $data, $loadDefaults ); } diff --git a/tests/phpunit/includes/db/ORMTableTest.php b/tests/phpunit/includes/db/ORMTableTest.php index 4cadf31c..e583d1bc 100644 --- a/tests/phpunit/includes/db/ORMTableTest.php +++ b/tests/phpunit/includes/db/ORMTableTest.php @@ -45,6 +45,7 @@ class ORMTableTest extends MediaWikiTestCase { */ public function getTable() { $class = $this->getTableClass(); + return $class::singleton(); } @@ -84,7 +85,6 @@ class ORMTableTest extends MediaWikiTestCase { $db->ignoreErrors( false ); } - } /** diff --git a/tests/phpunit/includes/db/TestORMRowTest.php b/tests/phpunit/includes/db/TestORMRowTest.php index 263553ac..f65642b8 100644 --- a/tests/phpunit/includes/db/TestORMRowTest.php +++ b/tests/phpunit/includes/db/TestORMRowTest.php @@ -64,23 +64,40 @@ class TestORMRowTest extends ORMRowTest { $dbw = wfGetDB( DB_MASTER ); $isSqlite = $GLOBALS['wgDBtype'] === 'sqlite'; + $isPostgres = $GLOBALS['wgDBtype'] === 'postgres'; $idField = $isSqlite ? 'INTEGER' : 'INT unsigned'; $primaryKey = $isSqlite ? 'PRIMARY KEY AUTOINCREMENT' : 'auto_increment PRIMARY KEY'; - $dbw->query( - 'CREATE TABLE IF NOT EXISTS ' . $dbw->tableName( 'orm_test' ) . '( - test_id ' . $idField . ' NOT NULL ' . $primaryKey . ', - test_name VARCHAR(255) NOT NULL, - test_age TINYINT unsigned NOT NULL, - test_height FLOAT NOT NULL, - test_awesome TINYINT unsigned NOT NULL, - test_stuff BLOB NOT NULL, - test_moarstuff BLOB NOT NULL, - test_time varbinary(14) NOT NULL - );', - __METHOD__ - ); + if ( $isPostgres ) { + $dbw->query( + 'CREATE TABLE IF NOT EXISTS ' . $dbw->tableName( 'orm_test' ) . "( + test_id serial PRIMARY KEY, + test_name TEXT NOT NULL DEFAULT '', + test_age INTEGER NOT NULL DEFAULT 0, + test_height REAL NOT NULL DEFAULT 0, + test_awesome INTEGER NOT NULL DEFAULT 0, + test_stuff BYTEA, + test_moarstuff BYTEA, + test_time TIMESTAMPTZ + );", + __METHOD__ + ); + } else { + $dbw->query( + 'CREATE TABLE IF NOT EXISTS ' . $dbw->tableName( 'orm_test' ) . '( + test_id ' . $idField . ' NOT NULL ' . $primaryKey . ', + test_name VARCHAR(255) NOT NULL, + test_age TINYINT unsigned NOT NULL, + test_height FLOAT NOT NULL, + test_awesome TINYINT unsigned NOT NULL, + test_stuff BLOB NOT NULL, + test_moarstuff BLOB NOT NULL, + test_time varbinary(14) NOT NULL + );', + __METHOD__ + ); + } } protected function tearDown() { @@ -91,11 +108,12 @@ class TestORMRowTest extends ORMRowTest { } public function constructorTestProvider() { + $dbw = wfGetDB( DB_MASTER ); return array( array( array( 'name' => 'Foobar', - 'time' => '20120101020202', + 'time' => $dbw->timestamp( '20120101020202' ), 'age' => 42, 'height' => 9000.1, 'awesome' => true, @@ -122,10 +140,10 @@ class TestORMRowTest extends ORMRowTest { 'blob' => new stdClass() ); } - } -class TestORMRow extends ORMRow {} +class TestORMRow extends ORMRow { +} class TestORMTable extends ORMTable { @@ -194,6 +212,4 @@ class TestORMTable extends ORMTable { protected function getFieldPrefix() { return 'test_'; } - - } diff --git a/tests/phpunit/includes/debug/MWDebugTest.php b/tests/phpunit/includes/debug/MWDebugTest.php index 9026cb90..6926b1c8 100644 --- a/tests/phpunit/includes/debug/MWDebugTest.php +++ b/tests/phpunit/includes/debug/MWDebugTest.php @@ -21,7 +21,7 @@ class MWDebugTest extends MediaWikiTestCase { parent::tearDown(); } - function testAddLog() { + public function testAddLog() { MWDebug::log( 'logging a string' ); $this->assertEquals( array( array( @@ -33,7 +33,7 @@ class MWDebugTest extends MediaWikiTestCase { ); } - function testAddWarning() { + public function testAddWarning() { MWDebug::warning( 'Warning message' ); $this->assertEquals( array( array( @@ -45,7 +45,7 @@ class MWDebugTest extends MediaWikiTestCase { ); } - function testAvoidDuplicateDeprecations() { + public function testAvoidDuplicateDeprecations() { MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); @@ -56,7 +56,7 @@ class MWDebugTest extends MediaWikiTestCase { ); } - function testAvoidNonConsecutivesDuplicateDeprecations() { + public function testAvoidNonConsecutivesDuplicateDeprecations() { MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); MWDebug::warning( 'some warning' ); MWDebug::log( 'we could have logged something too' ); diff --git a/tests/phpunit/includes/filebackend/FileBackendTest.php b/tests/phpunit/includes/filebackend/FileBackendTest.php index 9fbf7bb0..fcfa724f 100644 --- a/tests/phpunit/includes/filebackend/FileBackendTest.php +++ b/tests/phpunit/includes/filebackend/FileBackendTest.php @@ -6,14 +6,21 @@ * @group medium */ class FileBackendTest extends MediaWikiTestCase { - private $backend, $multiBackend; + + /** @var FileBackend */ + private $backend; + /** @var FileBackendMultiWrite */ + private $multiBackend; + /** @var FSFileBackend */ + public $singleBackend; private $filesToPrune = array(); private static $backendToUse; protected function setUp() { global $wgFileBackends; parent::setUp(); - $tmpPrefix = wfTempDir() . '/filebackend-unittest-' . time() . '-' . mt_rand(); + $uniqueId = time() . '-' . mt_rand(); + $tmpPrefix = wfTempDir() . '/filebackend-unittest-' . $uniqueId; if ( $this->getCliArg( 'use-filebackend=' ) ) { if ( self::$backendToUse ) { $this->singleBackend = self::$backendToUse; @@ -36,32 +43,34 @@ class FileBackendTest extends MediaWikiTestCase { } } else { $this->singleBackend = new FSFileBackend( array( - 'name' => 'localtesting', + 'name' => 'localtesting', 'lockManager' => 'fsLockManager', #'parallelize' => 'implicit', + 'wikiId' => wfWikiID() . $uniqueId, 'containerPaths' => array( 'unittest-cont1' => "{$tmpPrefix}-localtesting-cont1", 'unittest-cont2' => "{$tmpPrefix}-localtesting-cont2" ) ) ); } $this->multiBackend = new FileBackendMultiWrite( array( - 'name' => 'localtesting', + 'name' => 'localtesting', 'lockManager' => 'fsLockManager', 'parallelize' => 'implicit', - 'backends' => array( + 'wikiId' => wfWikiId() . $uniqueId, + 'backends' => array( array( - 'name' => 'localmultitesting1', - 'class' => 'FSFileBackend', - 'lockManager' => 'nullLockManager', + 'name' => 'localmultitesting1', + 'class' => 'FSFileBackend', + 'lockManager' => 'nullLockManager', 'containerPaths' => array( 'unittest-cont1' => "{$tmpPrefix}-localtestingmulti1-cont1", 'unittest-cont2' => "{$tmpPrefix}-localtestingmulti1-cont2" ), 'isMultiMaster' => false ), array( - 'name' => 'localmultitesting2', - 'class' => 'FSFileBackend', - 'lockManager' => 'nullLockManager', + 'name' => 'localmultitesting2', + 'class' => 'FSFileBackend', + 'lockManager' => 'nullLockManager', 'containerPaths' => array( 'unittest-cont1' => "{$tmpPrefix}-localtestingmulti2-cont1", 'unittest-cont2' => "{$tmpPrefix}-localtestingmulti2-cont2" ), @@ -82,13 +91,14 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testIsStoragePath + * @covers FileBackend::isStoragePath */ public function testIsStoragePath( $path, $isStorePath ) { $this->assertEquals( $isStorePath, FileBackend::isStoragePath( $path ), "FileBackend::isStoragePath on path '$path'" ); } - function provider_testIsStoragePath() { + public static function provider_testIsStoragePath() { return array( array( 'mwstore://', true ), array( 'mwstore://backend', true ), @@ -106,13 +116,14 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testSplitStoragePath + * @covers FileBackend::splitStoragePath */ public function testSplitStoragePath( $path, $res ) { $this->assertEquals( $res, FileBackend::splitStoragePath( $path ), "FileBackend::splitStoragePath on path '$path'" ); } - function provider_testSplitStoragePath() { + public static function provider_testSplitStoragePath() { return array( array( 'mwstore://backend/container', array( 'backend', 'container', '' ) ), array( 'mwstore://backend/container/', array( 'backend', 'container', '' ) ), @@ -130,13 +141,14 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_normalizeStoragePath + * @covers FileBackend::normalizeStoragePath */ public function testNormalizeStoragePath( $path, $res ) { $this->assertEquals( $res, FileBackend::normalizeStoragePath( $path ), "FileBackend::normalizeStoragePath on path '$path'" ); } - function provider_normalizeStoragePath() { + public static function provider_normalizeStoragePath() { return array( array( 'mwstore://backend/container', 'mwstore://backend/container' ), array( 'mwstore://backend/container/', 'mwstore://backend/container' ), @@ -156,13 +168,14 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testParentStoragePath + * @covers FileBackend::parentStoragePath */ public function testParentStoragePath( $path, $res ) { $this->assertEquals( $res, FileBackend::parentStoragePath( $path ), "FileBackend::parentStoragePath on path '$path'" ); } - function provider_testParentStoragePath() { + public static function provider_testParentStoragePath() { return array( array( 'mwstore://backend/container/path/to/obj', 'mwstore://backend/container/path/to' ), array( 'mwstore://backend/container/path/to', 'mwstore://backend/container/path' ), @@ -177,6 +190,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testExtensionFromPath + * @covers FileBackend::extensionFromPath */ public function testExtensionFromPath( $path, $res ) { $this->assertEquals( $res, FileBackend::extensionFromPath( $path ), @@ -210,6 +224,9 @@ class FileBackendTest extends MediaWikiTestCase { $this->tearDownFiles(); } + /** + * @covers FileBackend::doOperation + */ private function doTestStore( $op ) { $backendName = $this->backendClass(); @@ -281,6 +298,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testCopy + * @covers FileBackend::doOperation */ public function testCopy( $op ) { $this->backend = $this->singleBackend; @@ -312,6 +330,7 @@ class FileBackendTest extends MediaWikiTestCase { "Source file $source does not exist ($backendName)." ); $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $dest ) ), "Destination file $dest does not exist ($backendName)." ); + return; // done } @@ -400,6 +419,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testMove + * @covers FileBackend::doOperation */ public function testMove( $op ) { $this->backend = $this->singleBackend; @@ -431,6 +451,7 @@ class FileBackendTest extends MediaWikiTestCase { "Source file $source does not exist ($backendName)." ); $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $dest ) ), "Destination file $dest does not exist ($backendName)." ); + return; // done } @@ -520,6 +541,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testDelete + * @covers FileBackend::doOperation */ public function testDelete( $op, $withSource, $okStatus ) { $this->backend = $this->singleBackend; @@ -611,6 +633,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testDescribe + * @covers FileBackend::doOperation */ public function testDescribe( $op, $withSource, $okStatus ) { $this->backend = $this->singleBackend; @@ -678,6 +701,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testCreate + * @covers FileBackend::doOperation */ public function testCreate( $op, $alreadyExists, $okStatus, $newSize ) { $this->backend = $this->singleBackend; @@ -798,6 +822,9 @@ class FileBackendTest extends MediaWikiTestCase { return $cases; } + /** + * @covers FileBackend::doQuickOperations + */ public function testDoQuickOperations() { $this->backend = $this->singleBackend; $this->doTestDoQuickOperations(); @@ -817,32 +844,66 @@ class FileBackendTest extends MediaWikiTestCase { "$base/unittest-cont1/e/fileB.a", "$base/unittest-cont1/e/fileC.a" ); - $ops = array(); + $createOps = array(); $purgeOps = array(); foreach ( $files as $path ) { $status = $this->prepare( array( 'dir' => dirname( $path ) ) ); $this->assertGoodStatus( $status, "Preparing $path succeeded without warnings ($backendName)." ); - $ops[] = array( 'op' => 'create', 'dst' => $path, 'content' => mt_rand(0, 50000) ); + $createOps[] = array( 'op' => 'create', 'dst' => $path, 'content' => mt_rand( 0, 50000 ) ); + $copyOps[] = array( 'op' => 'copy', 'src' => $path, 'dst' => "$path-2" ); + $moveOps[] = array( 'op' => 'move', 'src' => "$path-2", 'dst' => "$path-3" ); $purgeOps[] = array( 'op' => 'delete', 'src' => $path ); + $purgeOps[] = array( 'op' => 'delete', 'src' => "$path-3" ); } $purgeOps[] = array( 'op' => 'null' ); - $status = $this->backend->doQuickOperations( $ops ); - $this->assertGoodStatus( $status, - "Creation of source files succeeded ($backendName)." ); + $this->assertGoodStatus( + $this->backend->doQuickOperations( $createOps ), + "Creation of source files succeeded ($backendName)." ); foreach ( $files as $file ) { $this->assertTrue( $this->backend->fileExists( array( 'src' => $file ) ), "File $file exists." ); } - $status = $this->backend->doQuickOperations( $purgeOps ); - $this->assertGoodStatus( $status, - "Quick deletion of source files succeeded ($backendName)." ); + $this->assertGoodStatus( + $this->backend->doQuickOperations( $copyOps ), + "Quick copy of source files succeeded ($backendName)." ); + foreach ( $files as $file ) { + $this->assertTrue( $this->backend->fileExists( array( 'src' => "$file-2" ) ), + "File $file-2 exists." ); + } + $this->assertGoodStatus( + $this->backend->doQuickOperations( $moveOps ), + "Quick move of source files succeeded ($backendName)." ); + foreach ( $files as $file ) { + $this->assertTrue( $this->backend->fileExists( array( 'src' => "$file-3" ) ), + "File $file-3 move in." ); + $this->assertFalse( $this->backend->fileExists( array( 'src' => "$file-2" ) ), + "File $file-2 moved away." ); + } + + $this->assertGoodStatus( + $this->backend->quickCopy( array( 'src' => $files[0], 'dst' => $files[0] ) ), + "Copy of file {$files[0]} over itself succeeded ($backendName)." ); + $this->assertTrue( $this->backend->fileExists( array( 'src' => $files[0] ) ), + "File {$files[0]} still exists." ); + + $this->assertGoodStatus( + $this->backend->quickMove( array( 'src' => $files[0], 'dst' => $files[0] ) ), + "Move of file {$files[0]} over itself succeeded ($backendName)." ); + $this->assertTrue( $this->backend->fileExists( array( 'src' => $files[0] ) ), + "File {$files[0]} still exists." ); + + $this->assertGoodStatus( + $this->backend->doQuickOperations( $purgeOps ), + "Quick deletion of source files succeeded ($backendName)." ); foreach ( $files as $file ) { $this->assertFalse( $this->backend->fileExists( array( 'src' => $file ) ), "File $file purged." ); + $this->assertFalse( $this->backend->fileExists( array( 'src' => "$file-3" ) ), + "File $file-3 purged." ); } } @@ -855,6 +916,7 @@ class FileBackendTest extends MediaWikiTestCase { $this->backend = $this->singleBackend; $this->tearDownFiles(); $this->doTestConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ); + $this->filesToPrune[] = $op['dst']; # avoid file leaking $this->tearDownFiles(); $this->backend = $this->multiBackend; @@ -873,8 +935,8 @@ class FileBackendTest extends MediaWikiTestCase { foreach ( $srcs as $i => $source ) { $this->prepare( array( 'dir' => dirname( $source ) ) ); $ops[] = array( - 'op' => 'create', // operation - 'dst' => $source, // source + 'op' => 'create', // operation + 'dst' => $source, // source 'content' => $srcsContent[$i] ); $expContent .= $srcsContent[$i]; @@ -927,7 +989,7 @@ class FileBackendTest extends MediaWikiTestCase { } } - function provider_testConcatenate() { + public static function provider_testConcatenate() { $cases = array(); $rand = mt_rand( 0, 2000000000 ) . time(); @@ -979,6 +1041,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testGetFileStat + * @covers FileBackend::getFileStat */ public function testGetFileStat( $path, $content, $alreadyExists ) { $this->backend = $this->singleBackend; @@ -1041,7 +1104,7 @@ class FileBackendTest extends MediaWikiTestCase { } } - function provider_testGetFileStat() { + public static function provider_testGetFileStat() { $cases = array(); $base = self::baseStorePath(); @@ -1054,6 +1117,8 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testGetFileContents + * @covers FileBackend::getFileContents + * @covers FileBackend::getFileContentsMulti */ public function testGetFileContents( $source, $content ) { $this->backend = $this->singleBackend; @@ -1096,7 +1161,7 @@ class FileBackendTest extends MediaWikiTestCase { } } - function provider_testGetFileContents() { + public static function provider_testGetFileContents() { $cases = array(); $base = self::baseStorePath(); @@ -1113,6 +1178,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testGetLocalCopy + * @covers FileBackend::getLocalCopy */ public function testGetLocalCopy( $source, $content ) { $this->backend = $this->singleBackend; @@ -1164,7 +1230,7 @@ class FileBackendTest extends MediaWikiTestCase { $tmpFile->bind( $obj ); } - function provider_testGetLocalCopy() { + public static function provider_testGetLocalCopy() { $cases = array(); $base = self::baseStorePath(); @@ -1182,6 +1248,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testGetLocalReference + * @covers FileBackend::getLocalReference */ public function testGetLocalReference( $source, $content ) { $this->backend = $this->singleBackend; @@ -1230,7 +1297,7 @@ class FileBackendTest extends MediaWikiTestCase { } } - function provider_testGetLocalReference() { + public static function provider_testGetLocalReference() { $cases = array(); $base = self::baseStorePath(); @@ -1246,6 +1313,10 @@ class FileBackendTest extends MediaWikiTestCase { return $cases; } + /** + * @covers FileBackend::getLocalCopy + * @covers FileBackend::getLocalReference + */ public function testGetLocalCopyAndReference404() { $this->backend = $this->singleBackend; $this->tearDownFiles(); @@ -1274,6 +1345,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testGetFileHttpUrl + * @covers FileBackend::getFileHttpUrl */ public function testGetFileHttpUrl( $source, $content ) { $this->backend = $this->singleBackend; @@ -1305,7 +1377,7 @@ class FileBackendTest extends MediaWikiTestCase { } } - function provider_testGetFileHttpUrl() { + public static function provider_testGetFileHttpUrl() { $cases = array(); $base = self::baseStorePath(); @@ -1318,6 +1390,8 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testPrepareAndClean + * @covers FileBackend::prepare + * @covers FileBackend::clean */ public function testPrepareAndClean( $path, $isOK ) { $this->backend = $this->singleBackend; @@ -1329,8 +1403,9 @@ class FileBackendTest extends MediaWikiTestCase { $this->tearDownFiles(); } - function provider_testPrepareAndClean() { + public static function provider_testPrepareAndClean() { $base = self::baseStorePath(); + return array( array( "$base/unittest-cont1/e/a/z/some_file1.txt", true ), array( "$base/unittest-cont2/a/z/some_file2.txt", true ), @@ -1375,6 +1450,9 @@ class FileBackendTest extends MediaWikiTestCase { $this->tearDownFiles(); } + /** + * @covers FileBackend::clean + */ private function doTestRecursiveClean() { $backendName = $this->backendClass(); @@ -1419,8 +1497,11 @@ class FileBackendTest extends MediaWikiTestCase { } } - // @TODO: testSecure + // @todo testSecure + /** + * @covers FileBackend::doOperations + */ public function testDoOperations() { $this->backend = $this->singleBackend; $this->tearDownFiles(); @@ -1508,6 +1589,9 @@ class FileBackendTest extends MediaWikiTestCase { "Correct file SHA-1 of $fileC" ); } + /** + * @covers FileBackend::doOperations + */ public function testDoOperationsPipeline() { $this->backend = $this->singleBackend; $this->tearDownFiles(); @@ -1607,6 +1691,9 @@ class FileBackendTest extends MediaWikiTestCase { "Correct file SHA-1 of $fileC" ); } + /** + * @covers FileBackend::doOperations + */ public function testDoOperationsFailing() { $this->backend = $this->singleBackend; $this->tearDownFiles(); @@ -1681,6 +1768,9 @@ class FileBackendTest extends MediaWikiTestCase { "Correct file SHA-1 of $fileA" ); } + /** + * @covers FileBackend::getFileList + */ public function testGetFileList() { $this->backend = $this->singleBackend; $this->tearDownFiles(); @@ -1729,7 +1819,7 @@ class FileBackendTest extends MediaWikiTestCase { $this->assertEquals( true, $status->isOK(), "Creation of files succeeded with OK status ($backendName)." ); - // Expected listing + // Expected listing at root $expected = array( "e/test1.txt", "e/test2.txt", @@ -1748,27 +1838,28 @@ class FileBackendTest extends MediaWikiTestCase { ); sort( $expected ); - // Actual listing (no trailing slash) - $list = array(); + // Actual listing (no trailing slash) at root $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } + $list = $this->listToArray( $iter ); sort( $list ); + $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." ); + // Actual listing (no trailing slash) at root with advise + $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1", 'adviseStat' => 1 ) ); + $list = $this->listToArray( $iter ); + sort( $list ); $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." ); - // Actual listing (with trailing slash) + // Actual listing (with trailing slash) at root $list = array(); $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/" ) ); foreach ( $iter as $file ) { $list[] = $file; } sort( $list ); - $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." ); - // Expected listing + // Expected listing at subdir $expected = array( "test1.txt", "test2.txt", @@ -1780,36 +1871,39 @@ class FileBackendTest extends MediaWikiTestCase { ); sort( $expected ); - // Actual listing (no trailing slash) - $list = array(); + // Actual listing (no trailing slash) at subdir $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } + $list = $this->listToArray( $iter ); sort( $list ); + $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." ); + // Actual listing (no trailing slash) at subdir with advise + $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir", 'adviseStat' => 1 ) ); + $list = $this->listToArray( $iter ); + sort( $list ); $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." ); - // Actual listing (with trailing slash) + // Actual listing (with trailing slash) at subdir $list = array(); $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir/" ) ); foreach ( $iter as $file ) { $list[] = $file; } sort( $list ); - $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." ); // Actual listing (using iterator second time) - $list = array(); - foreach ( $iter as $file ) { - $list[] = $file; - } + $list = $this->listToArray( $iter ); sort( $list ); - $this->assertEquals( $expected, $list, "Correct file listing ($backendName), second iteration." ); - // Expected listing (top files only) + // Actual listing (top files only) at root + $iter = $this->backend->getTopFileList( array( 'dir' => "$base/unittest-cont1" ) ); + $list = $this->listToArray( $iter ); + sort( $list ); + $this->assertEquals( array(), $list, "Correct top file listing ($backendName)." ); + + // Expected listing (top files only) at subdir $expected = array( "test1.txt", "test2.txt", @@ -1819,14 +1913,16 @@ class FileBackendTest extends MediaWikiTestCase { ); sort( $expected ); - // Actual listing (top files only) - $list = array(); + // Actual listing (top files only) at subdir $iter = $this->backend->getTopFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } + $list = $this->listToArray( $iter ); sort( $list ); + $this->assertEquals( $expected, $list, "Correct top file listing ($backendName)." ); + // Actual listing (top files only) at subdir with advise + $iter = $this->backend->getTopFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir", 'adviseStat' => 1 ) ); + $list = $this->listToArray( $iter ); + sort( $list ); $this->assertEquals( $expected, $list, "Correct top file listing ($backendName)." ); foreach ( $files as $file ) { // clean up @@ -1834,9 +1930,15 @@ class FileBackendTest extends MediaWikiTestCase { } $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/not/exists" ) ); - foreach ( $iter as $iter ) {} // no errors + foreach ( $iter as $iter ) { + // no errors + } } + /** + * @covers FileBackend::getTopDirectoryList + * @covers FileBackend::getDirectoryList + */ public function testGetDirectoryList() { $this->backend = $this->singleBackend; $this->tearDownFiles(); @@ -2023,7 +2125,7 @@ class FileBackendTest extends MediaWikiTestCase { $this->assertEquals( $expected, $list, "Correct dir listing ($backendName)." ); $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir1" ) ); - $items = is_array( $iter ) ? $iter : iterator_to_array( $iter ); + $items = $this->listToArray( $iter ); $this->assertEquals( array(), $items, "Directory listing is empty." ); foreach ( $files as $file ) { // clean up @@ -2031,15 +2133,22 @@ class FileBackendTest extends MediaWikiTestCase { } $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/not/exists" ) ); - foreach ( $iter as $file ) {} // no errors - $items = is_array( $iter ) ? $iter : iterator_to_array( $iter ); + foreach ( $iter as $file ) { + // no errors + } + + $items = $this->listToArray( $iter ); $this->assertEquals( array(), $items, "Directory listing is empty." ); $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/e/not/exists" ) ); - $items = is_array( $iter ) ? $iter : iterator_to_array( $iter ); + $items = $this->listToArray( $iter ); $this->assertEquals( array(), $items, "Directory listing is empty." ); } + /** + * @covers FileBackend::lockFiles + * @covers FileBackend::unlockFiles + */ public function testLockCalls() { $this->backend = $this->singleBackend; $this->doTestLockCalls(); @@ -2071,7 +2180,7 @@ class FileBackendTest extends MediaWikiTestCase { "subdir2/subdir/sub/120-px-file.txt", ); - for ( $i=0; $i<25; $i++ ) { + for ( $i = 0; $i < 25; $i++ ) { $status = $this->backend->lockFiles( $paths, LockManager::LOCK_EX ); $this->assertEquals( print_r( array(), true ), print_r( $status->errors, true ), "Locking of files succeeded ($backendName) ($i)." ); @@ -2141,6 +2250,11 @@ class FileBackendTest extends MediaWikiTestCase { "Scoped unlocking of files succeeded with OK status ($backendName)." ); } + // helper function + private function listToArray( $iter ) { + return is_array( $iter ) ? $iter : iterator_to_array( $iter ); + } + // test helper wrapper for backend prepare() function private function prepare( array $params ) { return $this->backend->prepare( $params ); @@ -2149,12 +2263,15 @@ class FileBackendTest extends MediaWikiTestCase { // test helper wrapper for backend prepare() function private function create( array $params ) { $params['op'] = 'create'; + return $this->backend->doQuickOperations( array( $params ) ); } function tearDownFiles() { foreach ( $this->filesToPrune as $file ) { - @unlink( $file ); + if ( is_file( $file ) ) { + unlink( $file ); + } } $containers = array( 'unittest-cont1', 'unittest-cont2' ); foreach ( $containers as $container ) { diff --git a/tests/phpunit/includes/filerepo/FileRepoTest.php b/tests/phpunit/includes/filerepo/FileRepoTest.php index 7cc25b1b..e3a75567 100644 --- a/tests/phpunit/includes/filerepo/FileRepoTest.php +++ b/tests/phpunit/includes/filerepo/FileRepoTest.php @@ -4,37 +4,44 @@ class FileRepoTest extends MediaWikiTestCase { /** * @expectedException MWException + * @covers FileRepo::__construct */ - function testFileRepoConstructionOptionCanNotBeNull() { - $f = new FileRepo(); + public function testFileRepoConstructionOptionCanNotBeNull() { + new FileRepo(); } /** * @expectedException MWException + * @covers FileRepo::__construct */ - function testFileRepoConstructionOptionCanNotBeAnEmptyArray() { - $f = new FileRepo( array() ); + public function testFileRepoConstructionOptionCanNotBeAnEmptyArray() { + new FileRepo( array() ); } /** * @expectedException MWException + * @covers FileRepo::__construct */ - function testFileRepoConstructionOptionNeedNameKey() { - $f = new FileRepo( array( + public function testFileRepoConstructionOptionNeedNameKey() { + new FileRepo( array( 'backend' => 'foobar' ) ); } /** * @expectedException MWException + * @covers FileRepo::__construct */ - function testFileRepoConstructionOptionNeedBackendKey() { - $f = new FileRepo( array( + public function testFileRepoConstructionOptionNeedBackendKey() { + new FileRepo( array( 'name' => 'foobar' ) ); } - function testFileRepoConstructionWithRequiredOptions() { + /** + * @covers FileRepo::__construct + */ + public function testFileRepoConstructionWithRequiredOptions() { $f = new FileRepo( array( 'name' => 'FileRepoTestRepository', 'backend' => new FSFileBackend( array( diff --git a/tests/phpunit/includes/filerepo/StoreBatchTest.php b/tests/phpunit/includes/filerepo/StoreBatchTest.php index a89ef98e..b33c1bbb 100644 --- a/tests/phpunit/includes/filerepo/StoreBatchTest.php +++ b/tests/phpunit/includes/filerepo/StoreBatchTest.php @@ -1,10 +1,16 @@ <?php + /** * @group FileRepo * @group medium */ class StoreBatchTest extends MediaWikiTestCase { + protected $createdFiles; + protected $date; + /** @var FileRepo */ + protected $repo; + protected function setUp() { global $wgFileBackends; parent::setUp(); @@ -60,6 +66,7 @@ class StoreBatchTest extends MediaWikiTestCase { * @param $originalName string The title of the image * @param $srcPath string The filepath or virtual URL * @param $flags integer Flags to pass into repo::store(). + * @return FileRepoStatus */ private function storeit( $originalName, $srcPath, $flags ) { $hashPath = $this->repo->getHashPath( $originalName ); @@ -69,6 +76,7 @@ class StoreBatchTest extends MediaWikiTestCase { $result = $this->repo->store( $srcPath, 'temp', $dstRel, $flags ); $result->value = $this->repo->getVirtualUrl( 'temp' ) . '/' . $dstUrlRel; $this->createdFiles[] = $result->value; + return $result; } @@ -78,7 +86,7 @@ class StoreBatchTest extends MediaWikiTestCase { * @param $fn string The title of the image * @param $infn string The name of the file (in the filesystem) * @param $otherfn string The name of the different file (in the filesystem) - * @param $fromrepo logical 'true' if we want to copy from a virtual URL out of the Repo. + * @param $fromrepo bool 'true' if we want to copy from a virtual URL out of the Repo. */ private function storecohort( $fn, $infn, $otherfn, $fromrepo ) { $f = $this->storeit( $fn, $infn, 0 ); @@ -115,6 +123,9 @@ class StoreBatchTest extends MediaWikiTestCase { $this->assertEquals( $f->successCount, 0, "counts wrong {$f->successCount} {$f->failCount}" ); } + /** + * @covers FileRepo::store + */ public function teststore() { global $IP; $this->storecohort( "Test1.png", "$IP/skins/monobook/wiki.png", "$IP/skins/monobook/video.png", false ); diff --git a/tests/phpunit/includes/installer/InstallDocFormatterTest.php b/tests/phpunit/includes/installer/InstallDocFormatterTest.php index 74b921a5..0e5f2671 100644 --- a/tests/phpunit/includes/installer/InstallDocFormatterTest.php +++ b/tests/phpunit/includes/installer/InstallDocFormatterTest.php @@ -1,5 +1,5 @@ <?php -/* +/* * To change this template, choose Tools | Templates * and open the template in the editor. */ @@ -9,7 +9,7 @@ class InstallDocFormatterTest extends MediaWikiTestCase { * @covers InstallDocFormatter::format * @dataProvider provideDocFormattingTests */ - function testFormat( $expected, $unformattedText, $message = '' ) { + public function testFormat( $expected, $unformattedText, $message = '' ) { $this->assertEquals( $expected, InstallDocFormatter::format( $unformattedText ), @@ -20,13 +20,14 @@ class InstallDocFormatterTest extends MediaWikiTestCase { /** * Provider for testFormat() */ - function provideDocFormattingTests() { + public static function provideDocFormattingTests() { # Format: (expected string, unformattedText string, optional message) return array( # Escape some wikitext array( 'Install <tag>', 'Install <tag>', 'Escaping <' ), array( 'Install {{template}}', 'Install {{template}}', 'Escaping [[' ), array( 'Install [[page]]', 'Install [[page]]', 'Escaping {{' ), + array( 'Install __TOC__', 'Install __TOC__', 'Escaping __' ), array( 'Install ', "Install \r", 'Removing \r' ), # Transform \t{1,2} into :{1,2} diff --git a/tests/phpunit/includes/installer/OracleInstallerTest.php b/tests/phpunit/includes/installer/OracleInstallerTest.php new file mode 100644 index 00000000..66e65592 --- /dev/null +++ b/tests/phpunit/includes/installer/OracleInstallerTest.php @@ -0,0 +1,48 @@ +<?php + +/** + * Tests for OracleInstaller + * + * @group Database + * @group Installer + */ + +class OracleInstallerTest extends MediaWikiTestCase { + + /** + * @dataProvider provideOracleConnectStrings + * @covers OracleInstaller::checkConnectStringFormat + */ + public function testCheckConnectStringFormat( $expected, $connectString, $msg = '' ) { + $validity = $expected ? 'should be valid' : 'should NOT be valid'; + $msg = "'$connectString' ($msg) $validity."; + $this->assertEquals( $expected, + OracleInstaller::checkConnectStringFormat( $connectString ), + $msg + ); + } + + /** + * Provider to test OracleInstaller::checkConnectStringFormat() + */ + function provideOracleConnectStrings() { + // expected result, connectString[, message] + return array( + array( true, 'simple_01', 'Simple TNS name' ), + array( true, 'simple_01.world', 'TNS name with domain' ), + array( true, 'simple_01.domain.net', 'TNS name with domain' ), + array( true, 'host123', 'Host only' ), + array( true, 'host123.domain.net', 'FQDN only' ), + array( true, '//host123.domain.net', 'FQDN URL only' ), + array( true, '123.223.213.132', 'Host IP only' ), + array( true, 'host:1521', 'Host and port' ), + array( true, 'host:1521/service', 'Host, port and service' ), + array( true, 'host:1521/service:shared', 'Host, port, service and shared server type' ), + array( true, 'host:1521/service:dedicated', 'Host, port, service and dedicated server type' ), + array( true, 'host:1521/service:pooled', 'Host, port, service and pooled server type' ), + array( true, 'host:1521/service:shared/instance1', 'Host, port, service, server type and instance' ), + array( true, 'host:1521//instance1', 'Host, port and instance' ), + ); + } + +} diff --git a/tests/phpunit/includes/jobqueue/JobQueueTest.php b/tests/phpunit/includes/jobqueue/JobQueueTest.php index 453cec31..4e51c4fc 100644 --- a/tests/phpunit/includes/jobqueue/JobQueueTest.php +++ b/tests/phpunit/includes/jobqueue/JobQueueTest.php @@ -8,19 +8,19 @@ class JobQueueTest extends MediaWikiTestCase { protected $key; protected $queueRand, $queueRandTTL, $queueFifo, $queueFifoTTL; - protected $old = array(); - function __construct( $name = null, array $data = array(), $dataName = '' ) { + function __construct( $name = null, array $data = array(), $dataName = '' ) { parent::__construct( $name, $data, $dataName ); $this->tablesUsed[] = 'job'; } protected function setUp() { - global $wgMemc, $wgJobTypeConf; + global $wgJobTypeConf; parent::setUp(); - $this->old['wgMemc'] = $wgMemc; - $wgMemc = new HashBagOStuff(); + + $this->setMwGlobals( 'wgMemc', new HashBagOStuff() ); + if ( $this->getCliArg( 'use-jobqueue=' ) ) { $name = $this->getCliArg( 'use-jobqueue=' ); if ( !isset( $wgJobTypeConf[$name] ) ) { @@ -32,44 +32,50 @@ class JobQueueTest extends MediaWikiTestCase { } $baseConfig['type'] = 'null'; $baseConfig['wiki'] = wfWikiID(); - $this->queueRand = JobQueue::factory( - array( 'order' => 'random', 'claimTTL' => 0 ) + $baseConfig ); - $this->queueRandTTL = JobQueue::factory( - array( 'order' => 'random', 'claimTTL' => 10 ) + $baseConfig ); - $this->queueFifo = JobQueue::factory( - array( 'order' => 'fifo', 'claimTTL' => 0 ) + $baseConfig ); - $this->queueFifoTTL = JobQueue::factory( - array( 'order' => 'fifo', 'claimTTL' => 10 ) + $baseConfig ); - if ( $baseConfig['class'] !== 'JobQueueDB' ) { // DB namespace with prefix or temp tables - foreach ( array( 'queueRand', 'queueRandTTL', 'queueFifo', 'queueFifoTTL' ) as $q ) { - $this->$q->setTestingPrefix( 'unittests-' . wfRandomString( 32 ) ); - } + $variants = array( + 'queueRand' => array( 'order' => 'random', 'claimTTL' => 0 ), + 'queueRandTTL' => array( 'order' => 'random', 'claimTTL' => 10 ), + 'queueTimestamp' => array( 'order' => 'timestamp', 'claimTTL' => 0 ), + 'queueTimestampTTL' => array( 'order' => 'timestamp', 'claimTTL' => 10 ), + 'queueFifo' => array( 'order' => 'fifo', 'claimTTL' => 0 ), + 'queueFifoTTL' => array( 'order' => 'fifo', 'claimTTL' => 10 ), + ); + foreach ( $variants as $q => $settings ) { + try { + $this->$q = JobQueue::factory( $settings + $baseConfig ); + if ( !( $this->$q instanceof JobQueueDB ) ) { + $this->$q->setTestingPrefix( 'unittests-' . wfRandomString( 32 ) ); + } + } catch ( MWException $e ) { + // unsupported? + // @todo What if it was another error? + }; } } protected function tearDown() { - global $wgMemc; parent::tearDown(); - foreach ( array( 'queueRand', 'queueRandTTL', 'queueFifo', 'queueFifoTTL' ) as $q ) { - do { - $job = $this->$q->pop(); - if ( $job ) { - $this->$q->ack( $job ); - } - } while ( $job ); + foreach ( + array( + 'queueRand', 'queueRandTTL', 'queueTimestamp', 'queueTimestampTTL', + 'queueFifo', 'queueFifoTTL' + ) as $q + ) { + if ( $this->$q ) { + $this->$q->delete(); + } + $this->$q = null; } - $this->queueRand = null; - $this->queueRandTTL = null; - $this->queueFifo = null; - $this->queueFifoTTL = null; - $wgMemc = $this->old['wgMemc']; } /** * @dataProvider provider_queueLists */ - function testProperties( $queue, $order, $recycles, $desc ) { + public function testProperties( $queue, $recycles, $desc ) { $queue = $this->$queue; + if ( !$queue ) { + $this->markTestSkipped( $desc ); + } $this->assertEquals( wfWikiID(), $queue->getWiki(), "Proper wiki ID ($desc)" ); $this->assertEquals( 'null', $queue->getType(), "Proper job type ($desc)" ); @@ -78,8 +84,12 @@ class JobQueueTest extends MediaWikiTestCase { /** * @dataProvider provider_queueLists */ - function testBasicOperations( $queue, $order, $recycles, $desc ) { + public function testBasicOperations( $queue, $recycles, $desc ) { $queue = $this->$queue; + if ( !$queue ) { + $this->markTestSkipped( $desc ); + } + $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); $queue->flushCaches(); @@ -94,6 +104,8 @@ class JobQueueTest extends MediaWikiTestCase { $queue->flushCaches(); $this->assertEquals( 2, $queue->getSize(), "Queue size is correct ($desc)" ); $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" ); + $jobs = iterator_to_array( $queue->getAllQueuedJobs() ); + $this->assertEquals( 2, count( $jobs ), "Queue iterator size is correct ($desc)" ); $job1 = $queue->pop(); $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" ); @@ -132,13 +144,25 @@ class JobQueueTest extends MediaWikiTestCase { $queue->flushCaches(); $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" ); + + $this->assertTrue( $queue->batchPush( array( $this->newJob(), $this->newJob() ) ), + "Push worked ($desc)" ); + $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" ); + + $queue->delete(); + $queue->flushCaches(); + $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); + $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" ); } /** * @dataProvider provider_queueLists */ - function testBasicDeduplication( $queue, $order, $recycles, $desc ) { + public function testBasicDeduplication( $queue, $recycles, $desc ) { $queue = $this->$queue; + if ( !$queue ) { + $this->markTestSkipped( $desc ); + } $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); @@ -146,8 +170,10 @@ class JobQueueTest extends MediaWikiTestCase { $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" ); $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" ); - $this->assertTrue( $queue->batchPush( - array( $this->newDedupedJob(), $this->newDedupedJob(), $this->newDedupedJob() ) ), + $this->assertTrue( + $queue->batchPush( + array( $this->newDedupedJob(), $this->newDedupedJob(), $this->newDedupedJob() ) + ), "Push worked ($desc)" ); $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" ); @@ -156,9 +182,12 @@ class JobQueueTest extends MediaWikiTestCase { $this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" ); $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" ); - $this->assertTrue( $queue->batchPush( - array( $this->newDedupedJob(), $this->newDedupedJob(), $this->newDedupedJob() ) ), - "Push worked ($desc)" ); + $this->assertTrue( + $queue->batchPush( + array( $this->newDedupedJob(), $this->newDedupedJob(), $this->newDedupedJob() ) + ), + "Push worked ($desc)" + ); $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" ); @@ -186,8 +215,11 @@ class JobQueueTest extends MediaWikiTestCase { /** * @dataProvider provider_queueLists */ - function testRootDeduplication( $queue, $order, $recycles, $desc ) { + public function testRootDeduplication( $queue, $recycles, $desc ) { $queue = $this->$queue; + if ( !$queue ) { + $this->markTestSkipped( $desc ); + } $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); @@ -236,8 +268,11 @@ class JobQueueTest extends MediaWikiTestCase { /** * @dataProvider provider_fifoQueueLists */ - function testJobOrder( $queue, $recycles, $desc ) { + public function testJobOrder( $queue, $recycles, $desc ) { $queue = $this->$queue; + if ( !$queue ) { + $this->markTestSkipped( $desc ); + } $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); @@ -264,16 +299,18 @@ class JobQueueTest extends MediaWikiTestCase { $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" ); } - function provider_queueLists() { + public static function provider_queueLists() { return array( - array( 'queueRand', 'rand', false, 'Random queue without ack()' ), - array( 'queueRandTTL', 'rand', true, 'Random queue with ack()' ), - array( 'queueFifo', 'fifo', false, 'Ordered queue without ack()' ), - array( 'queueFifoTTL', 'fifo', true, 'Ordered queue with ack()' ) + array( 'queueRand', false, 'Random queue without ack()' ), + array( 'queueRandTTL', true, 'Random queue with ack()' ), + array( 'queueTimestamp', false, 'Time ordered queue without ack()' ), + array( 'queueTimestampTTL', true, 'Time ordered queue with ack()' ), + array( 'queueFifo', false, 'FIFO ordered queue without ack()' ), + array( 'queueFifoTTL', true, 'FIFO ordered queue with ack()' ) ); } - function provider_fifoQueueLists() { + public static function provider_fifoQueueLists() { return array( array( 'queueFifo', false, 'Ordered queue without ack()' ), array( 'queueFifoTTL', true, 'Ordered queue with ack()' ) diff --git a/tests/phpunit/includes/json/FormatJsonTest.php b/tests/phpunit/includes/json/FormatJsonTest.php new file mode 100644 index 00000000..149be05b --- /dev/null +++ b/tests/phpunit/includes/json/FormatJsonTest.php @@ -0,0 +1,161 @@ +<?php + +class FormatJsonTest extends MediaWikiTestCase { + + public function testEncoderPrettyPrinting() { + $obj = array( + 'emptyObject' => new stdClass, + 'emptyArray' => array(), + 'string' => 'foobar\\', + 'filledArray' => array( + array( + 123, + 456, + ), + // Nested json works without problems + '"7":["8",{"9":"10"}]', + // Whitespace clean up doesn't touch strings that look alike + "{\n\t\"emptyObject\": {\n\t},\n\t\"emptyArray\": [ ]\n}", + ), + ); + + // 4 space indent, no trailing whitespace, no trailing linefeed + $json = '{ + "emptyObject": {}, + "emptyArray": [], + "string": "foobar\\\\", + "filledArray": [ + [ + 123, + 456 + ], + "\"7\":[\"8\",{\"9\":\"10\"}]", + "{\n\t\"emptyObject\": {\n\t},\n\t\"emptyArray\": [ ]\n}" + ] +}'; + + $json = str_replace( "\r", '', $json ); // Windows compat + $this->assertSame( $json, FormatJson::encode( $obj, true ) ); + } + + public static function provideEncodeDefault() { + return self::getEncodeTestCases( array() ); + } + + /** + * @dataProvider provideEncodeDefault + */ + public function testEncodeDefault( $from, $to ) { + $this->assertSame( $to, FormatJson::encode( $from ) ); + } + + public static function provideEncodeUtf8() { + return self::getEncodeTestCases( array( 'unicode' ) ); + } + + /** + * @dataProvider provideEncodeUtf8 + */ + public function testEncodeUtf8( $from, $to ) { + $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::UTF8_OK ) ); + } + + public static function provideEncodeXmlMeta() { + return self::getEncodeTestCases( array( 'xmlmeta' ) ); + } + + /** + * @dataProvider provideEncodeXmlMeta + */ + public function testEncodeXmlMeta( $from, $to ) { + $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::XMLMETA_OK ) ); + } + + public static function provideEncodeAllOk() { + return self::getEncodeTestCases( array( 'unicode', 'xmlmeta' ) ); + } + + /** + * @dataProvider provideEncodeAllOk + */ + public function testEncodeAllOk( $from, $to ) { + $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::ALL_OK ) ); + } + + public function testEncodePhpBug46944() { + $this->assertNotEquals( + '\ud840\udc00', + strtolower( FormatJson::encode( "\xf0\xa0\x80\x80" ) ), + 'Test encoding an broken json_encode character (U+20000)' + ); + } + + public function testDecodeReturnType() { + $this->assertInternalType( + 'object', + FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}' ), + 'Default to object' + ); + + $this->assertInternalType( + 'array', + FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}', true ), + 'Optional array' + ); + } + + /** + * Generate a set of test cases for a particular combination of encoder options. + * + * @param array $unescapedGroups List of character groups to leave unescaped + * @return array: Arrays of unencoded strings and corresponding encoded strings + */ + private static function getEncodeTestCases( array $unescapedGroups ) { + $groups = array( + 'always' => array( + // Forward slash (always unescaped) + '/' => '/', + + // Control characters + "\0" => '\u0000', + "\x08" => '\b', + "\t" => '\t', + "\n" => '\n', + "\r" => '\r', + "\f" => '\f', + "\x1f" => '\u001f', // representative example + + // Double quotes + '"' => '\"', + + // Backslashes + '\\' => '\\\\', + '\\\\' => '\\\\\\\\', + '\\u00e9' => '\\\u00e9', // security check for Unicode unescaping + + // Line terminators + "\xe2\x80\xa8" => '\u2028', + "\xe2\x80\xa9" => '\u2029', + ), + 'unicode' => array( + "\xc3\xa9" => '\u00e9', + "\xf0\x9d\x92\x9e" => '\ud835\udc9e', // U+1D49E, outside the BMP + ), + 'xmlmeta' => array( + '<' => '\u003C', // JSON_HEX_TAG uses uppercase hex digits + '>' => '\u003E', + '&' => '\u0026', + ), + ); + + $cases = array(); + foreach ( $groups as $name => $rules ) { + $leaveUnescaped = in_array( $name, $unescapedGroups ); + foreach ( $rules as $from => $to ) { + $cases[] = array( $from, '"' . ( $leaveUnescaped ? $from : $to ) . '"' ); + } + } + + return $cases; + } +} diff --git a/tests/phpunit/includes/json/ServicesJsonTest.php b/tests/phpunit/includes/json/ServicesJsonTest.php deleted file mode 100644 index 56dc6488..00000000 --- a/tests/phpunit/includes/json/ServicesJsonTest.php +++ /dev/null @@ -1,93 +0,0 @@ -<?php -/* - * Test cases for our Services_Json library. Requires PHP json support as well, - * so we can compare output - */ -class ServicesJsonTest extends MediaWikiTestCase { - /** - * Test to make sure core json_encode() and our Services_Json()->encode() - * produce the same output - * - * @dataProvider provideValuesToEncode - */ - public function testJsonEncode( $input, $desc ) { - if ( !function_exists( 'json_encode' ) ) { - $this->markTestIncomplete( 'No PHP json support, unable to test' ); - return; - } elseif ( strtolower( json_encode( "\xf0\xa0\x80\x80" ) ) != '"\ud840\udc00"' ) { - $this->markTestIncomplete( 'Have buggy PHP json support, unable to test' ); - return; - } else { - $jsonObj = new Services_JSON(); - $this->assertEquals( - $jsonObj->encode( $input ), - json_encode( $input ), - $desc - ); - } - } - - /** - * Test to make sure core json_decode() and our Services_Json()->decode() - * produce the same output - * - * @dataProvider provideValuesToDecode - */ - public function testJsonDecode( $input, $desc ) { - if ( !function_exists( 'json_decode' ) ) { - $this->markTestIncomplete( 'No PHP json support, unable to test' ); - return; - } else { - $jsonObj = new Services_JSON(); - $this->assertEquals( - $jsonObj->decode( $input ), - json_decode( $input ), - $desc - ); - } - } - - function provideValuesToEncode() { - $obj = new stdClass(); - $obj->property = 'value'; - $obj->property2 = null; - $obj->property3 = 1.234; - return array( - array( 1, 'basic integer' ), - array( -1, 'negative integer' ), - array( 1.1, 'basic float' ), - array( true, 'basic bool true' ), - array( false, 'basic bool false' ), - array( 'some string', 'basic string test' ), - array( "some string\nwith newline", 'newline string test' ), - array( '♥ü', 'unicode string test' ), - array( array( 'some', 'string', 'values' ), 'basic array of strings' ), - array( array( 'key1' => 'val1', 'key2' => 'val2' ), 'array with string keys' ), - array( array( 1 => 'val1', 3 => 'val2', '2' => 'val3' ), 'out of order numbered array test' ), - array( array(), 'empty array test' ), - array( $obj, 'basic object test' ), - array( new stdClass, 'empty object test' ), - array( null, 'null test' ), - ); - } - - function provideValuesToDecode() { - return array( - array( '1', 'basic integer' ), - array( '-1', 'negative integer' ), - array( '1.1', 'basic float' ), - array( '1.1e1', 'scientific float' ), - array( 'true', 'basic bool true' ), - array( 'false', 'basic bool false' ), - array( '"some string"', 'basic string test' ), - array( '"some string\nwith newline"', 'newline string test' ), - array( '"♥ü"', 'unicode character string test' ), - array( '"\u2665"', 'unicode \\u string test' ), - array( '["some","string","values"]', 'basic array of strings' ), - array( '[]', 'empty array test' ), - array( '{"key":"value"}', 'Basic key => value test' ), - array( '{}', 'empty object test' ), - array( 'null', 'null test' ), - ); - } -} diff --git a/tests/phpunit/includes/libs/CSSJanusTest.php b/tests/phpunit/includes/libs/CSSJanusTest.php index 26747b91..5a3c1619 100644 --- a/tests/phpunit/includes/libs/CSSJanusTest.php +++ b/tests/phpunit/includes/libs/CSSJanusTest.php @@ -4,12 +4,14 @@ * CSSJanus libary: * http://code.google.com/p/cssjanus/source/browse/trunk/cssjanus_test.py * Ported to PHP for ResourceLoader and has been extended since. + * + * @covers CSSJanus */ class CSSJanusTest extends MediaWikiTestCase { /** * @dataProvider provideTransformCases */ - function testTransform( $cssA, $cssB = null ) { + public function testTransform( $cssA, $cssB = null ) { if ( $cssB ) { $transformedA = CSSJanus::transform( $cssA ); @@ -28,7 +30,7 @@ class CSSJanusTest extends MediaWikiTestCase { /** * @dataProvider provideTransformAdvancedCases */ - function testTransformAdvanced( $code, $expectedOutput, $options = array() ) { + public function testTransformAdvanced( $code, $expectedOutput, $options = array() ) { $swapLtrRtlInURL = isset( $options['swapLtrRtlInURL'] ) ? $options['swapLtrRtlInURL'] : false; $swapLeftRightInURL = isset( $options['swapLeftRightInURL'] ) ? $options['swapLeftRightInURL'] : false; @@ -44,7 +46,7 @@ class CSSJanusTest extends MediaWikiTestCase { * @dataProvider provideTransformBrokenCases * @group Broken */ - function testTransformBroken( $code, $expectedOutput ) { + public function testTransformBroken( $code, $expectedOutput ) { $flipped = CSSJanus::transform( $code ); $this->assertEquals( $expectedOutput, $flipped, 'Test flipping' ); @@ -54,7 +56,7 @@ class CSSJanusTest extends MediaWikiTestCase { * These transform cases are tested *in both directions* * No need to declare a principle twice in both directions here. */ - function provideTransformCases() { + public static function provideTransformCases() { return array( // Property keys array( @@ -137,11 +139,16 @@ class CSSJanusTest extends MediaWikiTestCase { '.foo { padding: 1px inherit 3px auto; }', '.foo { padding: 1px auto 3px inherit; }' ), + // border-radius assigns different meanings to the values array( '.foo { border-radius: .25em 15px 0pt 0ex; }', - '.foo { border-radius: .25em 0ex 0pt 15px; }' + '.foo { border-radius: 15px .25em 0ex 0pt; }' ), array( + '.foo { border-radius: 0px 0px 5px 5px; }', + ), + // Ensure the rule doesn't break other stuff + array( '.foo { x-unknown: a b c d; }' ), array( @@ -151,14 +158,26 @@ class CSSJanusTest extends MediaWikiTestCase { '#settings td p strong' ), array( - # Not sure how 4+ values should behave, - # testing to make sure changes are detected - '.foo { x-unknown: 1 2 3 4 5; }', - '.foo { x-unknown: 1 4 3 2 5; }', + // Color names + '.foo { border-color: red green blue white }', + '.foo { border-color: red white blue green }', + ), + array( + // Color name, hexdecimal, RGB & RGBA + '.foo { border-color: red #f00 rgb(255, 0, 0) rgba(255, 0, 0, 0.5) }', + '.foo { border-color: red rgba(255, 0, 0, 0.5) rgb(255, 0, 0) #f00 }', + ), + array( + // Color name, hexdecimal, HSL & HSLA + '.foo { border-color: red #f00 hsl(0, 100%, 50%) hsla(0, 100%, 50%, 0.5) }', + '.foo { border-color: red hsla(0, 100%, 50%, 0.5) hsl(0, 100%, 50%) #f00 }', ), array( - '.foo { x-unknown: 1 2 3 4 5 6; }', - '.foo { x-unknown: 1 4 3 2 5 6; }', + // Do not mangle 5 or more values + '.foo { -x-unknown: 1 2 3 4 5; }' + ), + array( + '.foo { -x-unknown: 1 2 3 4 5 6; }' ), // Shorthand / Three notation @@ -179,6 +198,28 @@ class CSSJanusTest extends MediaWikiTestCase { '.foo { padding: 1px; }' ), + // text-shadow and box-shadow + array( + '.foo { box-shadow: -6px 3px 8px 5px rgba(0, 0, 0, 0.25); }', + '.foo { box-shadow: 6px 3px 8px 5px rgba(0, 0, 0, 0.25); }', + ), + array( + '.foo { box-shadow: inset -6px 3px 8px 5px rgba(0, 0, 0, 0.25); }', + '.foo { box-shadow: inset 6px 3px 8px 5px rgba(0, 0, 0, 0.25); }', + ), + array( + '.foo { text-shadow: orange 2px 0; }', + '.foo { text-shadow: orange -2px 0; }', + ), + array( + '.foo { text-shadow: 2px 0 orange; }', + '.foo { text-shadow: -2px 0 orange; }', + ), + array( + // Don't mangle zeroes + '.foo { text-shadow: orange 0 2px; }' + ), + // Direction // Note: This differs from the Python implementation, // see also CSSJanus::fixDirection for more info. @@ -377,6 +418,11 @@ class CSSJanusTest extends MediaWikiTestCase { '/* @noflip */ div { float: left; } .foo { float: right; }' ), array( + // support parentheses in selector + '/* @noflip */ .test:not(:first) { margin-right: -0.25em; margin-left: 0.25em; }', + '/* @noflip */ .test:not(:first) { margin-right: -0.25em; margin-left: 0.25em; }' + ), + array( // after multiple rules '.foo { float: left; } /* @noflip */ div { float: left; }', '.foo { float: right; } /* @noflip */ div { float: left; }' @@ -476,7 +522,7 @@ class CSSJanusTest extends MediaWikiTestCase { * If both ways can be tested, either put both versions in here or move * it to provideTransformCases(). */ - function provideTransformAdvancedCases() { + public static function provideTransformAdvancedCases() { $bgPairs = array( # [ - _ . ] <-> [ left right ltr rtl ] 'foo.jpg' => 'foo.jpg', @@ -542,7 +588,7 @@ class CSSJanusTest extends MediaWikiTestCase { * Cases that are currently failing, but * should be looked at in the future as enhancements and/or bug fix */ - function provideTransformBrokenCases() { + public static function provideTransformBrokenCases() { return array( // Guard against selectors that look flippable array( diff --git a/tests/phpunit/includes/libs/CSSMinTest.php b/tests/phpunit/includes/libs/CSSMinTest.php index 57017a84..951dd7b9 100644 --- a/tests/phpunit/includes/libs/CSSMinTest.php +++ b/tests/phpunit/includes/libs/CSSMinTest.php @@ -21,13 +21,13 @@ class CSSMinTest extends MediaWikiTestCase { /** * @dataProvider provideMinifyCases */ - function testMinify( $code, $expectedOutput ) { + public function testMinify( $code, $expectedOutput ) { $minified = CSSMin::minify( $code ); $this->assertEquals( $expectedOutput, $minified, 'Minified output should be in the form expected.' ); } - function provideMinifyCases() { + public static function provideMinifyCases() { return array( // Whitespace array( "\r\t\f \v\n\r", "" ), @@ -70,14 +70,14 @@ class CSSMinTest extends MediaWikiTestCase { /** * @dataProvider provideRemapCases */ - function testRemap( $message, $params, $expectedOutput ) { + public function testRemap( $message, $params, $expectedOutput ) { $remapped = call_user_func_array( 'CSSMin::remap', $params ); $messageAdd = " Case: $message"; $this->assertEquals( $expectedOutput, $remapped, 'CSSMin::remap should return the expected url form.' . $messageAdd ); } - function provideRemapCases() { + public static function provideRemapCases() { // Parameter signature: // CSSMin::remap( $code, $local, $remote, $embedData = true ) return array( @@ -115,11 +115,11 @@ class CSSMinTest extends MediaWikiTestCase { * @group Broken * @dataProvider provideStringCases */ - function testMinifyWithCSSStringValues( $code, $expectedOutput ) { + public function testMinifyWithCSSStringValues( $code, $expectedOutput ) { $this->testMinifyOutput( $code, $expectedOutput ); } - function provideStringCases() { + public static function provideStringCases() { return array( // String values should be respected // - More than one space in a string value diff --git a/tests/phpunit/includes/libs/GenericArrayObjectTest.php b/tests/phpunit/includes/libs/GenericArrayObjectTest.php index 37a9b347..7436c43c 100644 --- a/tests/phpunit/includes/libs/GenericArrayObjectTest.php +++ b/tests/phpunit/includes/libs/GenericArrayObjectTest.php @@ -73,6 +73,7 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase { */ protected function getNew( array $elements = array() ) { $class = $this->getInstanceClass(); + return new $class( $elements ); } @@ -197,6 +198,7 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase { public function testOffsetSet( array $elements ) { if ( $elements === array() ) { $this->assertTrue( true ); + return; } @@ -258,5 +260,4 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase { $this->assertArrayEquals( $list, $copy, true, true ); } - } diff --git a/tests/phpunit/includes/libs/IEUrlExtensionTest.php b/tests/phpunit/includes/libs/IEUrlExtensionTest.php index d04dd7d4..66fe915a 100644 --- a/tests/phpunit/includes/libs/IEUrlExtensionTest.php +++ b/tests/phpunit/includes/libs/IEUrlExtensionTest.php @@ -4,7 +4,7 @@ * Tests for IEUrlExtension::findIE6Extension */ class IEUrlExtensionTest extends MediaWikiTestCase { - function testSimple() { + public function testSimple() { $this->assertEquals( 'y', IEUrlExtension::findIE6Extension( 'x.y' ), @@ -12,7 +12,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testSimpleNoExt() { + public function testSimpleNoExt() { $this->assertEquals( '', IEUrlExtension::findIE6Extension( 'x' ), @@ -20,7 +20,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testEmpty() { + public function testEmpty() { $this->assertEquals( '', IEUrlExtension::findIE6Extension( '' ), @@ -28,7 +28,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testQuestionMark() { + public function testQuestionMark() { $this->assertEquals( '', IEUrlExtension::findIE6Extension( '?' ), @@ -36,7 +36,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testExtQuestionMark() { + public function testExtQuestionMark() { $this->assertEquals( 'x', IEUrlExtension::findIE6Extension( '.x?' ), @@ -44,7 +44,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testQuestionMarkExt() { + public function testQuestionMarkExt() { $this->assertEquals( 'x', IEUrlExtension::findIE6Extension( '?.x' ), @@ -52,7 +52,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testInvalidChar() { + public function testInvalidChar() { $this->assertEquals( '', IEUrlExtension::findIE6Extension( '.x*' ), @@ -60,7 +60,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testInvalidCharThenExtension() { + public function testInvalidCharThenExtension() { $this->assertEquals( 'x', IEUrlExtension::findIE6Extension( '*.x' ), @@ -68,7 +68,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testMultipleQuestionMarks() { + public function testMultipleQuestionMarks() { $this->assertEquals( 'c', IEUrlExtension::findIE6Extension( 'a?b?.c?.d?e?f' ), @@ -76,7 +76,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testExeException() { + public function testExeException() { $this->assertEquals( 'd', IEUrlExtension::findIE6Extension( 'a?b?.exe?.d?.e' ), @@ -84,7 +84,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testExeException2() { + public function testExeException2() { $this->assertEquals( 'exe', IEUrlExtension::findIE6Extension( 'a?b?.exe' ), @@ -92,7 +92,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testHash() { + public function testHash() { $this->assertEquals( '', IEUrlExtension::findIE6Extension( 'a#b.c' ), @@ -100,7 +100,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testHash2() { + public function testHash2() { $this->assertEquals( '', IEUrlExtension::findIE6Extension( 'a?#b.c' ), @@ -108,7 +108,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testDotAtEnd() { + public function testDotAtEnd() { $this->assertEquals( '', IEUrlExtension::findIE6Extension( '.' ), @@ -116,7 +116,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testTwoDots() { + public function testTwoDots() { $this->assertEquals( 'z', IEUrlExtension::findIE6Extension( 'x.y.z' ), diff --git a/tests/phpunit/includes/libs/JavaScriptMinifierTest.php b/tests/phpunit/includes/libs/JavaScriptMinifierTest.php index 1f550795..ab72e361 100644 --- a/tests/phpunit/includes/libs/JavaScriptMinifierTest.php +++ b/tests/phpunit/includes/libs/JavaScriptMinifierTest.php @@ -2,7 +2,7 @@ class JavaScriptMinifierTest extends MediaWikiTestCase { - function provideCases() { + public static function provideCases() { return array( // Basic whitespace and comments that should be stripped entirely @@ -119,7 +119,7 @@ class JavaScriptMinifierTest extends MediaWikiTestCase { /** * @dataProvider provideCases */ - function testJavaScriptMinifierOutput( $code, $expectedOutput ) { + public function testJavaScriptMinifierOutput( $code, $expectedOutput ) { $minified = JavaScriptMinifier::minify( $code ); // JSMin+'s parser will throw an exception if output is not valid JS. @@ -132,7 +132,7 @@ class JavaScriptMinifierTest extends MediaWikiTestCase { $this->assertEquals( $expectedOutput, $minified, "Minified output should be in the form expected." ); } - function provideBug32548() { + public static function provideBug32548() { return array( array( // This one gets interpreted all together by the prior code; @@ -153,7 +153,7 @@ class JavaScriptMinifierTest extends MediaWikiTestCase { /** * @dataProvider provideBug32548 */ - function testBug32548Exponent( $num ) { + public function testBug32548Exponent( $num ) { // Long line breaking was being incorrectly done between the base and // exponent part of a number, causing a syntax error. The line should // instead break at the start of the number. diff --git a/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php b/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php index b221b832..a0e63a8a 100644 --- a/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php +++ b/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php @@ -16,18 +16,17 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { * Basically the file has IPTC and XMP metadata, the * IPTC should override the XMP, except for the multilingual * translation (to en) where XMP should win. + * @covers BitmapMetadataHandler::Jpeg */ public function testMultilingualCascade() { - global $wgShowEXIF; - - if ( !wfDl( 'exif' ) ) { + if ( !extension_loaded( 'exif' ) ) { $this->markTestSkipped( "This test needs the exif extension." ); } - if ( !wfDl( 'xml' ) ) { + if ( !extension_loaded( 'xml' ) ) { $this->markTestSkipped( "This test needs the xml extension." ); } - $wgShowEXIF = true; + $this->setMwGlobals( 'wgShowEXIF', true ); $meta = BitmapMetadataHandler::Jpeg( $this->filePath . '/Xmp-exif-multilingual_test.jpg' ); @@ -50,6 +49,7 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { * * There's more extensive tests of comment extraction in * JpegMetadataExtractorTests.php + * @covers BitmapMetadataHandler::Jpeg */ public function testJpegComment() { $meta = BitmapMetadataHandler::Jpeg( $this->filePath . @@ -62,6 +62,7 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { /** * Make sure a bad iptc block doesn't stop the other metadata * from being extracted. + * @covers BitmapMetadataHandler::Jpeg */ public function testBadIPTC() { $meta = BitmapMetadataHandler::Jpeg( $this->filePath . @@ -69,6 +70,9 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { $this->assertEquals( 'Created with GIMP', $meta['JPEGFileComment'][0] ); } + /** + * @covers BitmapMetadataHandler::Jpeg + */ public function testIPTCDates() { $meta = BitmapMetadataHandler::Jpeg( $this->filePath . 'iptc-timetest.jpg' ); @@ -80,6 +84,7 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { /** * File has an invalid time (+ one valid but really weird time) * that shouldn't be included + * @covers BitmapMetadataHandler::Jpeg */ public function testIPTCDatesInvalid() { $meta = BitmapMetadataHandler::Jpeg( $this->filePath . @@ -93,6 +98,8 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { * XMP data should take priority over iptc data * when hash has been updated, but not when * the hash is wrong. + * @covers BitmapMetadataHandler::addMetadata + * @covers BitmapMetadataHandler::getMetadataArray */ public function testMerging() { $merger = new BitmapMetadataHandler(); @@ -116,8 +123,11 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { $this->assertEquals( $expected, $actual ); } + /** + * @covers BitmapMetadataHandler::png + */ public function testPNGXMP() { - if ( !wfDl( 'xml' ) ) { + if ( !extension_loaded( 'xml' ) ) { $this->markTestSkipped( "This test needs the xml extension." ); } $handler = new BitmapMetadataHandler(); @@ -136,6 +146,9 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { $this->assertEquals( $expected, $result ); } + /** + * @covers BitmapMetadataHandler::png + */ public function testPNGNative() { $handler = new BitmapMetadataHandler(); $result = $handler->png( $this->filePath . 'Png-native-test.png' ); @@ -143,10 +156,12 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { $this->assertEquals( $expected, $result['metadata']['Identifier']['x-default'] ); } + /** + * @covers BitmapMetadataHandler::getTiffByteOrder + */ public function testTiffByteOrder() { $handler = new BitmapMetadataHandler(); $res = $handler->getTiffByteOrder( $this->filePath . 'test.tiff' ); $this->assertEquals( 'LE', $res ); } - } diff --git a/tests/phpunit/includes/media/BitmapScalingTest.php b/tests/phpunit/includes/media/BitmapScalingTest.php index 3de60b73..9395b660 100644 --- a/tests/phpunit/includes/media/BitmapScalingTest.php +++ b/tests/phpunit/includes/media/BitmapScalingTest.php @@ -13,8 +13,9 @@ class BitmapScalingTest extends MediaWikiTestCase { /** * @dataProvider provideNormaliseParams + * @covers BitmapHandler::normaliseParams */ - function testNormaliseParams( $fileDimensions, $expectedParams, $params, $msg ) { + public function testNormaliseParams( $fileDimensions, $expectedParams, $params, $msg ) { $file = new FakeDimensionFile( $fileDimensions ); $handler = new BitmapHandler; $valid = $handler->normaliseParams( $file, $params ); @@ -22,7 +23,7 @@ class BitmapScalingTest extends MediaWikiTestCase { $this->assertEquals( $expectedParams, $params, $msg ); } - function provideNormaliseParams() { + public static function provideNormaliseParams() { return array( /* Regular resize operations */ array( @@ -102,7 +103,10 @@ class BitmapScalingTest extends MediaWikiTestCase { ); } - function testTooBigImage() { + /** + * @covers BitmapHandler::doTransform + */ + public function testTooBigImage() { $file = new FakeDimensionFile( array( 4000, 4000 ) ); $handler = new BitmapHandler; $params = array( 'width' => '3700' ); // Still bigger than max size. @@ -110,7 +114,10 @@ class BitmapScalingTest extends MediaWikiTestCase { get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) ); } - function testTooBigMustRenderImage() { + /** + * @covers BitmapHandler::doTransform + */ + public function testTooBigMustRenderImage() { $file = new FakeDimensionFile( array( 4000, 4000 ) ); $file->mustRender = true; $handler = new BitmapHandler; @@ -119,36 +126,12 @@ class BitmapScalingTest extends MediaWikiTestCase { get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) ); } - function testImageArea() { + /** + * @covers BitmapHandler::getImageArea + */ + public function testImageArea() { $file = new FakeDimensionFile( array( 7, 9 ) ); $handler = new BitmapHandler; $this->assertEquals( 63, $handler->getImageArea( $file ) ); } } - -class FakeDimensionFile extends File { - public $mustRender = false; - - public function __construct( $dimensions ) { - parent::__construct( Title::makeTitle( NS_FILE, 'Test' ), - new NullRepo( null ) ); - - $this->dimensions = $dimensions; - } - - public function getWidth( $page = 1 ) { - return $this->dimensions[0]; - } - - public function getHeight( $page = 1 ) { - return $this->dimensions[1]; - } - - public function mustRender() { - return $this->mustRender; - } - - public function getPath() { - return ''; - } -} diff --git a/tests/phpunit/includes/media/ExifBitmapTest.php b/tests/phpunit/includes/media/ExifBitmapTest.php index 1109c478..a2e0eb62 100644 --- a/tests/phpunit/includes/media/ExifBitmapTest.php +++ b/tests/phpunit/includes/media/ExifBitmapTest.php @@ -2,53 +2,79 @@ class ExifBitmapTest extends MediaWikiTestCase { + /** + * @var ExifBitmapHandler + */ + protected $handler; + protected function setUp() { parent::setUp(); + if ( !extension_loaded( 'exif' ) ) { + $this->markTestSkipped( "This test needs the exif extension." ); + } $this->setMwGlobals( 'wgShowEXIF', true ); $this->handler = new ExifBitmapHandler; - if ( !wfDl( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } + } + /** + * @covers ExifBitmapHandler::isMetadataValid + */ public function testIsOldBroken() { $res = $this->handler->isMetadataValid( null, ExifBitmapHandler::OLD_BROKEN_FILE ); $this->assertEquals( ExifBitmapHandler::METADATA_COMPATIBLE, $res ); } + /** + * @covers ExifBitmapHandler::isMetadataValid + */ public function testIsBrokenFile() { $res = $this->handler->isMetadataValid( null, ExifBitmapHandler::BROKEN_FILE ); $this->assertEquals( ExifBitmapHandler::METADATA_GOOD, $res ); } + /** + * @covers ExifBitmapHandler::isMetadataValid + */ public function testIsInvalid() { $res = $this->handler->isMetadataValid( null, 'Something Invalid Here.' ); $this->assertEquals( ExifBitmapHandler::METADATA_BAD, $res ); } + /** + * @covers ExifBitmapHandler::isMetadataValid + */ public function testGoodMetadata() { $meta = 'a:16:{s:10:"ImageWidth";i:20;s:11:"ImageLength";i:20;s:13:"BitsPerSample";a:3:{i:0;i:8;i:1;i:8;i:2;i:8;}s:11:"Compression";i:5;s:25:"PhotometricInterpretation";i:2;s:16:"ImageDescription";s:17:"Created with GIMP";s:12:"StripOffsets";i:8;s:11:"Orientation";i:1;s:15:"SamplesPerPixel";i:3;s:12:"RowsPerStrip";i:64;s:15:"StripByteCounts";i:238;s:11:"XResolution";s:19:"1207959552/16777216";s:11:"YResolution";s:19:"1207959552/16777216";s:19:"PlanarConfiguration";i:1;s:14:"ResolutionUnit";i:2;s:22:"MEDIAWIKI_EXIF_VERSION";i:2;}'; $res = $this->handler->isMetadataValid( null, $meta ); $this->assertEquals( ExifBitmapHandler::METADATA_GOOD, $res ); } + /** + * @covers ExifBitmapHandler::isMetadataValid + */ public function testIsOldGood() { $meta = 'a:16:{s:10:"ImageWidth";i:20;s:11:"ImageLength";i:20;s:13:"BitsPerSample";a:3:{i:0;i:8;i:1;i:8;i:2;i:8;}s:11:"Compression";i:5;s:25:"PhotometricInterpretation";i:2;s:16:"ImageDescription";s:17:"Created with GIMP";s:12:"StripOffsets";i:8;s:11:"Orientation";i:1;s:15:"SamplesPerPixel";i:3;s:12:"RowsPerStrip";i:64;s:15:"StripByteCounts";i:238;s:11:"XResolution";s:19:"1207959552/16777216";s:11:"YResolution";s:19:"1207959552/16777216";s:19:"PlanarConfiguration";i:1;s:14:"ResolutionUnit";i:2;s:22:"MEDIAWIKI_EXIF_VERSION";i:1;}'; $res = $this->handler->isMetadataValid( null, $meta ); $this->assertEquals( ExifBitmapHandler::METADATA_COMPATIBLE, $res ); } - // Handle metadata from paged tiff handler (gotten via instant commons) - // gracefully. + /** + * Handle metadata from paged tiff handler (gotten via instant commons) gracefully. + * @covers ExifBitmapHandler::isMetadataValid + */ public function testPagedTiffHandledGracefully() { $meta = 'a:6:{s:9:"page_data";a:1:{i:1;a:5:{s:5:"width";i:643;s:6:"height";i:448;s:5:"alpha";s:4:"true";s:4:"page";i:1;s:6:"pixels";i:288064;}}s:10:"page_count";i:1;s:10:"first_page";i:1;s:9:"last_page";i:1;s:4:"exif";a:9:{s:10:"ImageWidth";i:643;s:11:"ImageLength";i:448;s:11:"Compression";i:5;s:25:"PhotometricInterpretation";i:2;s:11:"Orientation";i:1;s:15:"SamplesPerPixel";i:4;s:12:"RowsPerStrip";i:50;s:19:"PlanarConfiguration";i:1;s:22:"MEDIAWIKI_EXIF_VERSION";i:1;}s:21:"TIFF_METADATA_VERSION";s:3:"1.4";}'; $res = $this->handler->isMetadataValid( null, $meta ); $this->assertEquals( ExifBitmapHandler::METADATA_BAD, $res ); } - function testConvertMetadataLatest() { + /** + * @covers ExifBitmapHandler::convertMetadataVersion + */ + public function testConvertMetadataLatest() { $metadata = array( 'foo' => array( 'First', 'Second', '_type' => 'ol' ), 'MEDIAWIKI_EXIF_VERSION' => 2 @@ -57,7 +83,10 @@ class ExifBitmapTest extends MediaWikiTestCase { $this->assertEquals( $metadata, $res ); } - function testConvertMetadataToOld() { + /** + * @covers ExifBitmapHandler::convertMetadataVersion + */ + public function testConvertMetadataToOld() { $metadata = array( 'foo' => array( 'First', 'Second', '_type' => 'ol' ), 'bar' => array( 'First', 'Second', '_type' => 'ul' ), @@ -76,7 +105,10 @@ class ExifBitmapTest extends MediaWikiTestCase { $this->assertEquals( $expected, $res ); } - function testConvertMetadataSoftware() { + /** + * @covers ExifBitmapHandler::convertMetadataVersion + */ + public function testConvertMetadataSoftware() { $metadata = array( 'Software' => array( array( 'GIMP', '1.1' ) ), 'MEDIAWIKI_EXIF_VERSION' => 2, @@ -89,7 +121,10 @@ class ExifBitmapTest extends MediaWikiTestCase { $this->assertEquals( $expected, $res ); } - function testConvertMetadataSoftwareNormal() { + /** + * @covers ExifBitmapHandler::convertMetadataVersion + */ + public function testConvertMetadataSoftwareNormal() { $metadata = array( 'Software' => array( "GIMP 1.2", "vim" ), 'MEDIAWIKI_EXIF_VERSION' => 2, diff --git a/tests/phpunit/includes/media/ExifRotationTest.php b/tests/phpunit/includes/media/ExifRotationTest.php index db29d17c..64276d92 100644 --- a/tests/phpunit/includes/media/ExifRotationTest.php +++ b/tests/phpunit/includes/media/ExifRotationTest.php @@ -3,11 +3,17 @@ * Tests related to auto rotation. * * @group medium + * + * @todo covers tags */ class ExifRotationTest extends MediaWikiTestCase { protected function setUp() { parent::setUp(); + if ( !extension_loaded( 'exif' ) ) { + $this->markTestSkipped( "This test needs the exif extension." ); + } + $this->handler = new BitmapHandler(); $filePath = __DIR__ . '/../../data/media'; @@ -22,31 +28,17 @@ class ExifRotationTest extends MediaWikiTestCase { 'containerPaths' => array( 'temp-thumb' => $tmpDir, 'data' => $filePath ) ) ) ) ); - if ( !wfDl( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } - global $wgShowEXIF; - $this->show = $wgShowEXIF; - $wgShowEXIF = true; - global $wgEnableAutoRotation; - $this->oldAuto = $wgEnableAutoRotation; - $wgEnableAutoRotation = true; - } - - protected function tearDown() { - global $wgShowEXIF, $wgEnableAutoRotation; - $wgShowEXIF = $this->show; - $wgEnableAutoRotation = $this->oldAuto; - - parent::tearDown(); + $this->setMwGlobals( array( + 'wgShowEXIF' => true, + 'wgEnableAutoRotation' => true, + ) ); } /** - * * @dataProvider provideFiles */ - function testMetadata( $name, $type, $info ) { + public function testMetadata( $name, $type, $info ) { if ( !BitmapHandler::canRotate() ) { $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." ); } @@ -59,7 +51,7 @@ class ExifRotationTest extends MediaWikiTestCase { * * @dataProvider provideFiles */ - function testRotationRendering( $name, $type, $info, $thumbs ) { + public function testRotationRendering( $name, $type, $info, $thumbs ) { if ( !BitmapHandler::canRotate() ) { $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." ); } @@ -138,24 +130,20 @@ class ExifRotationTest extends MediaWikiTestCase { * Same as before, but with auto-rotation disabled. * @dataProvider provideFilesNoAutoRotate */ - function testMetadataNoAutoRotate( $name, $type, $info ) { - global $wgEnableAutoRotation; - $wgEnableAutoRotation = false; + public function testMetadataNoAutoRotate( $name, $type, $info ) { + $this->setMwGlobals( 'wgEnableAutoRotation', false ); $file = $this->dataFile( $name, $type ); $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" ); $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" ); - - $wgEnableAutoRotation = true; } /** * * @dataProvider provideFilesNoAutoRotate */ - function testRotationRenderingNoAutoRotate( $name, $type, $info, $thumbs ) { - global $wgEnableAutoRotation; - $wgEnableAutoRotation = false; + public function testRotationRenderingNoAutoRotate( $name, $type, $info, $thumbs ) { + $this->setMwGlobals( 'wgEnableAutoRotation', false ); foreach ( $thumbs as $size => $out ) { if ( preg_match( '/^(\d+)px$/', $size, $matches ) ) { @@ -187,7 +175,6 @@ class ExifRotationTest extends MediaWikiTestCase { $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size" ); } } - $wgEnableAutoRotation = true; } public static function provideFilesNoAutoRotate() { @@ -230,7 +217,7 @@ class ExifRotationTest extends MediaWikiTestCase { /** * @dataProvider provideBitmapExtractPreRotationDimensions */ - function testBitmapExtractPreRotationDimensions( $rotation, $expected ) { + public function testBitmapExtractPreRotationDimensions( $rotation, $expected ) { $result = $this->handler->extractPreRotationDimensions( array( 'physicalWidth' => self::TEST_WIDTH, 'physicalHeight' => self::TEST_HEIGHT, @@ -238,7 +225,7 @@ class ExifRotationTest extends MediaWikiTestCase { $this->assertEquals( $expected, $result ); } - function provideBitmapExtractPreRotationDimensions() { + public static function provideBitmapExtractPreRotationDimensions() { return array( array( 0, diff --git a/tests/phpunit/includes/media/ExifTest.php b/tests/phpunit/includes/media/ExifTest.php index e7e95f7e..dea36b03 100644 --- a/tests/phpunit/includes/media/ExifTest.php +++ b/tests/phpunit/includes/media/ExifTest.php @@ -1,14 +1,18 @@ <?php class ExifTest extends MediaWikiTestCase { + /** @var string */ + protected $mediaPath; + protected function setUp() { parent::setUp(); + if ( !extension_loaded( 'exif' ) ) { + $this->markTestSkipped( "This test needs the exif extension." ); + } $this->mediaPath = __DIR__ . '/../../data/media/'; - if ( !wfDl( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } + $this->setMwGlobals( 'wgShowEXIF', true ); } @@ -39,6 +43,4 @@ class ExifTest extends MediaWikiTestCase { ); $this->assertEquals( $expected, $data ); } - - } diff --git a/tests/phpunit/includes/media/FakeDimensionFile.php b/tests/phpunit/includes/media/FakeDimensionFile.php new file mode 100644 index 00000000..7926000b --- /dev/null +++ b/tests/phpunit/includes/media/FakeDimensionFile.php @@ -0,0 +1,28 @@ +<?php + +class FakeDimensionFile extends File { + public $mustRender = false; + + public function __construct( $dimensions ) { + parent::__construct( Title::makeTitle( NS_FILE, 'Test' ), + new NullRepo( null ) ); + + $this->dimensions = $dimensions; + } + + public function getWidth( $page = 1 ) { + return $this->dimensions[0]; + } + + public function getHeight( $page = 1 ) { + return $this->dimensions[1]; + } + + public function mustRender() { + return $this->mustRender; + } + + public function getPath() { + return ''; + } +}
\ No newline at end of file diff --git a/tests/phpunit/includes/media/FormatMetadataTest.php b/tests/phpunit/includes/media/FormatMetadataTest.php index f26d27ee..a073e4ca 100644 --- a/tests/phpunit/includes/media/FormatMetadataTest.php +++ b/tests/phpunit/includes/media/FormatMetadataTest.php @@ -1,10 +1,19 @@ <?php + +/** + * @todo covers tags + */ class FormatMetadataTest extends MediaWikiTestCase { + /** @var FSFileBackend */ + protected $backend; + /** @var FSRepo */ + protected $repo; + protected function setUp() { parent::setUp(); - if ( !wfDl( 'exif' ) ) { + if ( !extension_loaded( 'exif' ) ) { $this->markTestSkipped( "This test needs the exif extension." ); } $filePath = __DIR__ . '/../../data/media'; diff --git a/tests/phpunit/includes/media/GIFMetadataExtractorTest.php b/tests/phpunit/includes/media/GIFMetadataExtractorTest.php index 86cf3465..9e3f9244 100644 --- a/tests/phpunit/includes/media/GIFMetadataExtractorTest.php +++ b/tests/phpunit/includes/media/GIFMetadataExtractorTest.php @@ -12,6 +12,7 @@ class GIFMetadataExtractorTest extends MediaWikiTestCase { * @param $filename String * @param $expected Array The extracted metadata. * @dataProvider provideGetMetadata + * @covers GIFMetadataExtractor::getMetadata */ public function testGetMetadata( $filename, $expected ) { $actual = GIFMetadataExtractor::getMetadata( $this->mediaPath . $filename ); diff --git a/tests/phpunit/includes/media/GIFTest.php b/tests/phpunit/includes/media/GIFTest.php index 7ea6b7ef..c8e729c8 100644 --- a/tests/phpunit/includes/media/GIFTest.php +++ b/tests/phpunit/includes/media/GIFTest.php @@ -1,6 +1,15 @@ <?php class GIFHandlerTest extends MediaWikiTestCase { + /** @var FSFileBackend */ + protected $backend; + /** @var GIFHandler */ + protected $handler; + /** @var FSRepo */ + protected $repo; + /** @var string */ + protected $filePath; + protected function setUp() { parent::setUp(); @@ -18,6 +27,9 @@ class GIFHandlerTest extends MediaWikiTestCase { $this->handler = new GIFHandler(); } + /** + * @covers GIFHandler::getMetadata + */ public function testInvalidFile() { $res = $this->handler->getMetadata( null, $this->filePath . '/README' ); $this->assertEquals( GIFHandler::BROKEN_FILE, $res ); @@ -27,6 +39,7 @@ class GIFHandlerTest extends MediaWikiTestCase { * @param $filename String basename of the file to check * @param $expected boolean Expected result. * @dataProvider provideIsAnimated + * @covers GIFHandler::isAnimatedImage */ public function testIsAnimanted( $filename, $expected ) { $file = $this->dataFile( $filename, 'image/gif' ); @@ -45,6 +58,7 @@ class GIFHandlerTest extends MediaWikiTestCase { * @param $filename String * @param $expected Integer Total image area * @dataProvider provideGetImageArea + * @covers GIFHandler::getImageArea */ public function testGetImageArea( $filename, $expected ) { $file = $this->dataFile( $filename, 'image/gif' ); @@ -63,6 +77,7 @@ class GIFHandlerTest extends MediaWikiTestCase { * @param $metadata String Serialized metadata * @param $expected Integer One of the class constants of GIFHandler * @dataProvider provideIsMetadataValid + * @covers GIFHandler::isMetadataValid */ public function testIsMetadataValid( $metadata, $expected ) { $actual = $this->handler->isMetadataValid( null, $metadata ); @@ -83,6 +98,7 @@ class GIFHandlerTest extends MediaWikiTestCase { * @param $filename String * @param $expected String Serialized array * @dataProvider provideGetMetadata + * @covers GIFHandler::getMetadata */ public function testGetMetadata( $filename, $expected ) { $file = $this->dataFile( $filename, 'image/gif' ); diff --git a/tests/phpunit/includes/media/IPTCTest.php b/tests/phpunit/includes/media/IPTCTest.php index c9648a79..81c1d287 100644 --- a/tests/phpunit/includes/media/IPTCTest.php +++ b/tests/phpunit/includes/media/IPTCTest.php @@ -1,11 +1,19 @@ <?php + class IPTCTest extends MediaWikiTestCase { + + /** + * @covers IPTC::getCharset + */ public function testRecognizeUtf8() { // utf-8 is the only one used in practise. $res = IPTC::getCharset( "\x1b%G" ); $this->assertEquals( 'UTF-8', $res ); } + /** + * @covers IPTC::Parse + */ public function testIPTCParseNoCharset88591() { // basically IPTC for keyword with value of 0xBC which is 1/4 in iso-8859-1 // This data doesn't specify a charset. We're supposed to guess @@ -15,17 +23,22 @@ class IPTCTest extends MediaWikiTestCase { $this->assertEquals( array( '¼' ), $res['Keywords'] ); } - /* This one contains a sequence that's valid iso 8859-1 but not valid utf8 */ - /* \xC3 = Ã, \xB8 = ¸ */ + /** + * @covers IPTC::Parse + */ public function testIPTCParseNoCharset88591b() { + /* This one contains a sequence that's valid iso 8859-1 but not valid utf8 */ + /* \xC3 = Ã, \xB8 = ¸ */ $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x09\x1c\x02\x19\x00\x04\xC3\xC3\xC3\xB8"; $res = IPTC::Parse( $iptcData ); $this->assertEquals( array( 'ÃÃø' ), $res['Keywords'] ); } - /* Same as testIPTCParseNoCharset88591b, but forcing the charset to utf-8. + /** + * Same as testIPTCParseNoCharset88591b, but forcing the charset to utf-8. * What should happen is the first "\xC3\xC3" should be dropped as invalid, * leaving \xC3\xB8, which is ø + * @covers IPTC::Parse */ public function testIPTCParseForcedUTFButInvalid() { $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x11\x1c\x02\x19\x00\x04\xC3\xC3\xC3\xB8" @@ -34,13 +47,19 @@ class IPTCTest extends MediaWikiTestCase { $this->assertEquals( array( 'ø' ), $res['Keywords'] ); } + /** + * @covers IPTC::Parse + */ public function testIPTCParseNoCharsetUTF8() { $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x07\x1c\x02\x19\x00\x02¼"; $res = IPTC::Parse( $iptcData ); $this->assertEquals( array( '¼' ), $res['Keywords'] ); } - // Testing something that has 2 values for keyword + /** + * Testing something that has 2 values for keyword + * @covers IPTC::Parse + */ public function testIPTCParseMulti() { $iptcData = /* identifier */ "Photoshop 3.0\08BIM\4\4" /* length */ . "\0\0\0\0\0\x0D" @@ -50,11 +69,13 @@ class IPTCTest extends MediaWikiTestCase { $this->assertEquals( array( '¼', '¼½' ), $res['Keywords'] ); } + /** + * @covers IPTC::Parse + */ public function testIPTCParseUTF8() { // This has the magic "\x1c\x01\x5A\x00\x03\x1B\x25\x47" which marks content as UTF8. $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x0F\x1c\x02\x19\x00\x02¼\x1c\x01\x5A\x00\x03\x1B\x25\x47"; $res = IPTC::Parse( $iptcData ); $this->assertEquals( array( '¼' ), $res['Keywords'] ); } - } diff --git a/tests/phpunit/includes/media/JpegMetadataExtractorTest.php b/tests/phpunit/includes/media/JpegMetadataExtractorTest.php index cae7137b..eafc8a2e 100644 --- a/tests/phpunit/includes/media/JpegMetadataExtractorTest.php +++ b/tests/phpunit/includes/media/JpegMetadataExtractorTest.php @@ -5,9 +5,12 @@ * serve as a very good "test". (Adobe photoshop probably creates such files * but it costs money). The implementation of it currently in MediaWiki is based * solely on reading the standard, without any real world test files. + * @todo covers tags */ class JpegMetadataExtractorTest extends MediaWikiTestCase { + protected $filePath; + protected function setUp() { parent::setUp(); @@ -18,7 +21,7 @@ class JpegMetadataExtractorTest extends MediaWikiTestCase { * We also use this test to test padding bytes don't * screw stuff up * - * @param $file filename + * @param string $file filename * * @dataProvider provideUtf8Comment */ diff --git a/tests/phpunit/includes/media/JpegTest.php b/tests/phpunit/includes/media/JpegTest.php index 05d3661e..9af4f1e1 100644 --- a/tests/phpunit/includes/media/JpegTest.php +++ b/tests/phpunit/includes/media/JpegTest.php @@ -1,14 +1,18 @@ <?php +/** + * @todo covers tags + */ class JpegTest extends MediaWikiTestCase { protected function setUp() { parent::setUp(); - - $this->filePath = __DIR__ . '/../../data/media/'; - if ( !wfDl( 'exif' ) ) { + if ( !extension_loaded( 'exif' ) ) { $this->markTestSkipped( "This test needs the exif extension." ); } + $this->filePath = __DIR__ . '/../../data/media/'; + + $this->setMwGlobals( 'wgShowEXIF', true ); } diff --git a/tests/phpunit/includes/media/MediaHandlerTest.php b/tests/phpunit/includes/media/MediaHandlerTest.php index 4e4c649f..c28898bb 100644 --- a/tests/phpunit/includes/media/MediaHandlerTest.php +++ b/tests/phpunit/includes/media/MediaHandlerTest.php @@ -1,7 +1,12 @@ <?php class MediaHandlerTest extends MediaWikiTestCase { - function testFitBoxWidth() { + + /** + * @covers MediaHandler::fitBoxWidth + * @todo split into a dataprovider and test method + */ + public function testFitBoxWidth() { $vals = array( array( 'width' => 50, diff --git a/tests/phpunit/includes/media/PNGMetadataExtractorTest.php b/tests/phpunit/includes/media/PNGMetadataExtractorTest.php index 1e912017..939f2cfc 100644 --- a/tests/phpunit/includes/media/PNGMetadataExtractorTest.php +++ b/tests/phpunit/includes/media/PNGMetadataExtractorTest.php @@ -1,4 +1,8 @@ <?php + +/** + * @todo covers tags + */ class PNGMetadataExtractorTest extends MediaWikiTestCase { protected function setUp() { @@ -9,7 +13,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase { /** * Tests zTXt tag (compressed textual metadata) */ - function testPngNativetZtxt() { + public function testPngNativetZtxt() { $this->checkPHPExtension( 'zlib' ); $meta = PNGMetadataExtractor::getMetadata( $this->filePath . @@ -26,7 +30,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase { /** * Test tEXt tag (Uncompressed textual metadata) */ - function testPngNativeText() { + public function testPngNativeText() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'Png-native-test.png' ); $expected = "Some long image desc"; @@ -43,7 +47,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase { * tEXt tags must be encoded iso-8859-1 (vs iTXt which are utf-8) * Make sure non-ascii characters get converted properly */ - function testPngNativeTextNonAscii() { + public function testPngNativeTextNonAscii() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'Png-native-test.png' ); @@ -52,7 +56,6 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase { // encoded as just \xA9. $expected = "© 2010 Bawolff"; - $this->assertArrayHasKey( 'text', $meta ); $meta = $meta['text']; $this->assertArrayHasKey( 'Copyright', $meta ); @@ -66,7 +69,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase { * actual resolution of the image is (aka in dots per meter). */ /* - function testPngPhysTag () { + public function testPngPhysTag() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'Png-native-test.png' ); @@ -82,7 +85,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase { /** * Given a normal static PNG, check the animation metadata returned. */ - function testStaticPngAnimationMetadata() { + public function testStaticPngAnimationMetadata() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'Png-native-test.png' ); @@ -95,7 +98,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase { * Given an animated APNG image file * check it gets animated metadata right. */ - function testApngAnimationMetadata() { + public function testApngAnimationMetadata() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'Animated_PNG_example_bouncing_beach_ball.png' ); @@ -105,49 +108,48 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase { $this->assertEquals( 1.5, $meta['duration'], '', 0.00001 ); } - function testPngBitDepth8() { + public function testPngBitDepth8() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'Png-native-test.png' ); $this->assertEquals( 8, $meta['bitDepth'] ); } - function testPngBitDepth1() { + public function testPngBitDepth1() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . '1bit-png.png' ); $this->assertEquals( 1, $meta['bitDepth'] ); } - function testPngIndexColour() { + public function testPngIndexColour() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'Png-native-test.png' ); $this->assertEquals( 'index-coloured', $meta['colorType'] ); } - function testPngRgbColour() { + public function testPngRgbColour() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'rgb-png.png' ); $this->assertEquals( 'truecolour-alpha', $meta['colorType'] ); } - function testPngRgbNoAlphaColour() { + public function testPngRgbNoAlphaColour() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'rgb-na-png.png' ); $this->assertEquals( 'truecolour', $meta['colorType'] ); } - function testPngGreyscaleColour() { + public function testPngGreyscaleColour() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'greyscale-png.png' ); $this->assertEquals( 'greyscale-alpha', $meta['colorType'] ); } - function testPngGreyscaleNoAlphaColour() { + public function testPngGreyscaleNoAlphaColour() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'greyscale-na-png.png' ); $this->assertEquals( 'greyscale', $meta['colorType'] ); } - } diff --git a/tests/phpunit/includes/media/PNGTest.php b/tests/phpunit/includes/media/PNGTest.php index 855780da..ad4c2493 100644 --- a/tests/phpunit/includes/media/PNGTest.php +++ b/tests/phpunit/includes/media/PNGTest.php @@ -1,6 +1,15 @@ <?php class PNGHandlerTest extends MediaWikiTestCase { + /** @var PNGHandler */ + protected $handler; + /** @var FSRepo */ + protected $repo; + /** @var FSFileBackend */ + protected $backend; + /** @var string */ + protected $filePath; + protected function setUp() { parent::setUp(); @@ -18,6 +27,9 @@ class PNGHandlerTest extends MediaWikiTestCase { $this->handler = new PNGHandler(); } + /** + * @covers PNGHandler::getMetadata + */ public function testInvalidFile() { $res = $this->handler->getMetadata( null, $this->filePath . '/README' ); $this->assertEquals( PNGHandler::BROKEN_FILE, $res ); @@ -27,6 +39,7 @@ class PNGHandlerTest extends MediaWikiTestCase { * @param $filename String basename of the file to check * @param $expected boolean Expected result. * @dataProvider provideIsAnimated + * @covers PNGHandler::isAnimatedImage */ public function testIsAnimanted( $filename, $expected ) { $file = $this->dataFile( $filename, 'image/png' ); @@ -45,6 +58,7 @@ class PNGHandlerTest extends MediaWikiTestCase { * @param $filename String * @param $expected Integer Total image area * @dataProvider provideGetImageArea + * @covers PNGHandler::getImageArea */ public function testGetImageArea( $filename, $expected ) { $file = $this->dataFile( $filename, 'image/png' ); @@ -65,6 +79,7 @@ class PNGHandlerTest extends MediaWikiTestCase { * @param $metadata String Serialized metadata * @param $expected Integer One of the class constants of PNGHandler * @dataProvider provideIsMetadataValid + * @covers PNGHandler::isMetadataValid */ public function testIsMetadataValid( $metadata, $expected ) { $actual = $this->handler->isMetadataValid( null, $metadata ); @@ -85,6 +100,7 @@ class PNGHandlerTest extends MediaWikiTestCase { * @param $filename String * @param $expected String Serialized array * @dataProvider provideGetMetadata + * @covers PNGHandler::getMetadata */ public function testGetMetadata( $filename, $expected ) { $file = $this->dataFile( $filename, 'image/png' ); diff --git a/tests/phpunit/includes/media/SVGMetadataExtractorTest.php b/tests/phpunit/includes/media/SVGMetadataExtractorTest.php index 97a0000d..257009b0 100644 --- a/tests/phpunit/includes/media/SVGMetadataExtractorTest.php +++ b/tests/phpunit/includes/media/SVGMetadataExtractorTest.php @@ -1,5 +1,8 @@ <?php +/** + * @todo covers tags + */ class SVGMetadataExtractorTest extends MediaWikiTestCase { protected function setUp() { @@ -10,17 +13,18 @@ class SVGMetadataExtractorTest extends MediaWikiTestCase { /** * @dataProvider provideSvgFiles */ - function testGetMetadata( $infile, $expected ) { + public function testGetMetadata( $infile, $expected ) { $this->assertMetadata( $infile, $expected ); } /** * @dataProvider provideSvgFilesWithXMLMetadata */ - function testGetXMLMetadata( $infile, $expected ) { + public function testGetXMLMetadata( $infile, $expected ) { $r = new XMLReader(); if ( !method_exists( $r, 'readInnerXML' ) ) { $this->markTestSkipped( 'XMLReader::readInnerXML() does not exist (libxml >2.6.20 needed).' ); + return; } $this->assertMetadata( $infile, $expected ); @@ -41,6 +45,7 @@ class SVGMetadataExtractorTest extends MediaWikiTestCase { public static function provideSvgFiles() { $base = __DIR__ . '/../../data/media'; + return array( array( "$base/Wikimedia-logo.svg", diff --git a/tests/phpunit/includes/media/TiffTest.php b/tests/phpunit/includes/media/TiffTest.php index 91c35c4b..8d74b98d 100644 --- a/tests/phpunit/includes/media/TiffTest.php +++ b/tests/phpunit/includes/media/TiffTest.php @@ -1,8 +1,16 @@ <?php class TiffTest extends MediaWikiTestCase { + /** @var TiffHandler */ + protected $handler; + /** @var string */ + protected $filePath; + protected function setUp() { parent::setUp(); + if ( !extension_loaded( 'exif' ) ) { + $this->markTestSkipped( "This test needs the exif extension." ); + } $this->setMwGlobals( 'wgShowEXIF', true ); @@ -10,18 +18,18 @@ class TiffTest extends MediaWikiTestCase { $this->handler = new TiffHandler; } + /** + * @covers TiffHandler::getMetadata + */ public function testInvalidFile() { - if ( !wfDl( 'exif' ) ) { - $this->markTestIncomplete( "This test needs the exif extension." ); - } $res = $this->handler->getMetadata( null, $this->filePath . 'README' ); $this->assertEquals( ExifBitmapHandler::BROKEN_FILE, $res ); } + /** + * @covers TiffHandler::getMetadata + */ public function testTiffMetadataExtraction() { - if ( !wfDl( 'exif' ) ) { - $this->markTestIncomplete( "This test needs the exif extension." ); - } $res = $this->handler->getMetadata( null, $this->filePath . 'test.tiff' ); $expected = 'a:16:{s:10:"ImageWidth";i:20;s:11:"ImageLength";i:20;s:13:"BitsPerSample";a:3:{i:0;i:8;i:1;i:8;i:2;i:8;}s:11:"Compression";i:5;s:25:"PhotometricInterpretation";i:2;s:16:"ImageDescription";s:17:"Created with GIMP";s:12:"StripOffsets";i:8;s:11:"Orientation";i:1;s:15:"SamplesPerPixel";i:3;s:12:"RowsPerStrip";i:64;s:15:"StripByteCounts";i:238;s:11:"XResolution";s:19:"1207959552/16777216";s:11:"YResolution";s:19:"1207959552/16777216";s:19:"PlanarConfiguration";i:1;s:14:"ResolutionUnit";i:2;s:22:"MEDIAWIKI_EXIF_VERSION";i:2;}'; // Re-unserialize in case there are subtle differences between how versions diff --git a/tests/phpunit/includes/media/XMPTest.php b/tests/phpunit/includes/media/XMPTest.php index 86c722b1..d12e9b00 100644 --- a/tests/phpunit/includes/media/XMPTest.php +++ b/tests/phpunit/includes/media/XMPTest.php @@ -1,9 +1,13 @@ <?php + +/** + * @todo covers tags + */ class XMPTest extends MediaWikiTestCase { protected function setUp() { parent::setUp(); - if ( !wfDl( 'xml' ) ) { + if ( !extension_loaded( 'xml' ) ) { $this->markTestSkipped( 'Requires libxml to do XMP parsing' ); } } @@ -15,6 +19,7 @@ class XMPTest extends MediaWikiTestCase { * @param $expected Array expected result of parsing the xmp. * @param $info String Short sentence on what's being tested. * + * @throws Exception * @dataProvider provideXMPParse */ public function testXMPParse( $xmp, $expected, $info ) { @@ -62,9 +67,10 @@ class XMPTest extends MediaWikiTestCase { // result array, but it seems kind of big to put directly in the test // file. $result = null; - include( $xmpPath . $file[0] . '.result.php' ); + include $xmpPath . $file[0] . '.result.php'; $data[] = array( $xmp, $result, '[' . $file[0] . '.xmp] ' . $file[1] ); } + return $data; } @@ -74,7 +80,7 @@ class XMPTest extends MediaWikiTestCase { * @todo This is based on what the standard says. Need to find a real * world example file to double check the support for this is right. */ - function testExtendedXMP() { + public function testExtendedXMP() { $xmpPath = __DIR__ . '/../../data/xmp/'; $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' ); $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' ); @@ -104,7 +110,7 @@ class XMPTest extends MediaWikiTestCase { * This test has an extended XMP block with a wrong guid (md5sum) * and thus should only return the StandardXMP, not the ExtendedXMP. */ - function testExtendedXMPWithWrongGUID() { + public function testExtendedXMPWithWrongGUID() { $xmpPath = __DIR__ . '/../../data/xmp/'; $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' ); $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' ); @@ -133,7 +139,7 @@ class XMPTest extends MediaWikiTestCase { * Have a high offset to simulate a missing packet, * which should cause it to ignore the ExtendedXMP packet. */ - function testExtendedXMPMissingPacket() { + public function testExtendedXMPMissingPacket() { $xmpPath = __DIR__ . '/../../data/xmp/'; $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' ); $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' ); @@ -157,5 +163,4 @@ class XMPTest extends MediaWikiTestCase { $this->assertEquals( $expected, $actual ); } - } diff --git a/tests/phpunit/includes/media/XMPValidateTest.php b/tests/phpunit/includes/media/XMPValidateTest.php index a2b4e1c2..96bf5e47 100644 --- a/tests/phpunit/includes/media/XMPValidateTest.php +++ b/tests/phpunit/includes/media/XMPValidateTest.php @@ -3,8 +3,9 @@ class XMPValidateTest extends MediaWikiTestCase { /** * @dataProvider provideDates + * @covers XMPValidate::validateDate */ - function testValidateDate( $value, $expected ) { + public function testValidateDate( $value, $expected ) { // The method should modify $value. XMPValidate::validateDate( array(), $value, true ); $this->assertEquals( $expected, $value ); @@ -41,7 +42,5 @@ class XMPValidateTest extends MediaWikiTestCase { array( '2001-05-12T15', null ), array( '2001-12T15:13', null ), ); - } - } diff --git a/tests/phpunit/includes/normal/CleanUpTest.php b/tests/phpunit/includes/normal/CleanUpTest.php index 99ec05dd..52dd2ef5 100644 --- a/tests/phpunit/includes/normal/CleanUpTest.php +++ b/tests/phpunit/includes/normal/CleanUpTest.php @@ -30,16 +30,20 @@ * * @ingroup UtfNormal * @group Large + * + * We ignore code coverage for this test suite until they are rewritten + * to use data providers (bug 46561). + * @codeCoverageIgnore */ class CleanUpTest extends MediaWikiTestCase { /** @todo document */ - function testAscii() { + public function testAscii() { $text = 'This is plain ASCII text.'; $this->assertEquals( $text, UtfNormal::cleanUp( $text ) ); } /** @todo document */ - function testNull() { + public function testNull() { $text = "a \x00 null"; $expect = "a \xef\xbf\xbd null"; $this->assertEquals( @@ -48,13 +52,13 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testLatin() { + public function testLatin() { $text = "L'\xc3\xa9cole"; $this->assertEquals( $text, UtfNormal::cleanUp( $text ) ); } /** @todo document */ - function testLatinNormal() { + public function testLatinNormal() { $text = "L'e\xcc\x81cole"; $expect = "L'\xc3\xa9cole"; $this->assertEquals( $expect, UtfNormal::cleanUp( $text ) ); @@ -101,7 +105,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testAllBytes() { + public function testAllBytes() { $this->doTestBytes( '', '' ); $this->doTestBytes( 'x', '' ); $this->doTestBytes( '', 'x' ); @@ -141,7 +145,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testDoubleBytes() { + public function testDoubleBytes() { $this->doTestDoubleBytes( '', '' ); $this->doTestDoubleBytes( 'x', '' ); $this->doTestDoubleBytes( '', 'x' ); @@ -194,7 +198,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testTripleBytes() { + public function testTripleBytes() { $this->doTestTripleBytes( '', '' ); $this->doTestTripleBytes( 'x', '' ); $this->doTestTripleBytes( '', 'x' ); @@ -272,7 +276,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testChunkRegression() { + public function testChunkRegression() { # Check for regression against a chunking bug $text = "\x46\x55\xb8" . "\xdc\x96" . @@ -295,7 +299,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testInterposeRegression() { + public function testInterposeRegression() { $text = "\x4e\x30" . "\xb1" . # bad tail "\x3a" . @@ -330,7 +334,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testOverlongRegression() { + public function testOverlongRegression() { $text = "\x67" . "\x1a" . # forbidden ascii "\xea" . # bad head @@ -355,7 +359,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testSurrogateRegression() { + public function testSurrogateRegression() { $text = "\xed\xb4\x96" . # surrogate 0xDD16 "\x83" . # bad tail "\xb4" . # bad tail @@ -370,7 +374,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testBomRegression() { + public function testBomRegression() { $text = "\xef\xbf\xbe" . # U+FFFE, illegal char "\xb2" . # bad tail "\xef" . # bad head @@ -385,7 +389,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testForbiddenRegression() { + public function testForbiddenRegression() { $text = "\xef\xbf\xbf"; # U+FFFF, illegal char $expect = "\xef\xbf\xbd"; $this->assertEquals( @@ -394,7 +398,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testHangulRegression() { + public function testHangulRegression() { $text = "\xed\x9c\xaf" . # Hangul char "\xe1\x87\x81"; # followed by another final jamo $expect = $text; # Should *not* change. diff --git a/tests/phpunit/includes/objectcache/BagOStuffTest.php b/tests/phpunit/includes/objectcache/BagOStuffTest.php index 88b07f0a..aa783943 100644 --- a/tests/phpunit/includes/objectcache/BagOStuffTest.php +++ b/tests/phpunit/includes/objectcache/BagOStuffTest.php @@ -15,7 +15,6 @@ class BagOStuffTest extends MediaWikiTestCase { $name = $this->getCliArg( 'use-bagostuff=' ); $this->cache = ObjectCache::newFromId( $name ); - } else { // no type defined - use simple hash $this->cache = new HashBagOStuff; @@ -119,6 +118,18 @@ class BagOStuffTest extends MediaWikiTestCase { $this->assertEquals( $this->cache->get( $key ), $value ); } + /** + * @covers BagOStuff::incr + */ + public function testIncr() { + $key = wfMemcKey( 'test' ); + $this->cache->add( $key, 0 ); + $this->cache->incr( $key ); + $expectedValue = 1; + $actualValue = $this->cache->get( $key ); + $this->assertEquals( $expectedValue, $actualValue, 'Value should be 1 after incrementing' ); + } + public function testGetMulti() { $value1 = array( 'this' => 'is', 'a' => 'test' ); $value2 = array( 'this' => 'is', 'another' => 'test' ); 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 @@ <?php -require_once( __DIR__ . '/NewParserTest.php' ); +require_once __DIR__ . '/NewParserTest.php'; /** * The UnitTest must be either a class that inherits from MediaWikiTestCase @@ -11,24 +11,110 @@ require_once( __DIR__ . '/NewParserTest.php' ); */ class MediaWikiParserTest { - public static function suite() { - global $wgParserTestFiles; + /** + * @defgroup filtering_constants Filtering constants + * + * Limit inclusion of parser tests files coming from MediaWiki core + * @{ + */ - $suite = new PHPUnit_Framework_TestSuite; + /** Include files shipped with MediaWiki core */ + const CORE_ONLY = 1; + /** Include non core files as set in $wgParserTestFiles */ + const NO_CORE = 2; + /** Include anything set via $wgParserTestFiles */ + const WITH_ALL = 3; # CORE_ONLY | NO_CORE + + /** @} */ + + /** + * Get a PHPUnit test suite of parser tests. Optionally filtered with + * $flags. + * + * @par Examples: + * Get a suite of parser tests shipped by MediaWiki core: + * @code + * MediaWikiParserTest::suite( MediaWikiParserTest::CORE_ONLY ); + * @endcode + * Get a suite of various parser tests, like extensions: + * @code + * MediaWikiParserTest::suite( MediaWikiParserTest::NO_CORE ); + * @endcode + * Get any test defined via $wgParserTestFiles: + * @code + * MediaWikiParserTest::suite( MediaWikiParserTest::WITH_ALL ); + * @endcode + * + * @param $flags bitwise flag to filter out the $wgParserTestFiles that + * will be included. Default: MediaWikiParserTest::CORE_ONLY + * + * @return PHPUnit_Framework_TestSuite + */ + public static function suite( $flags = self::CORE_ONLY ) { + if ( is_string( $flags ) ) { + $flags = self::CORE_ONLY; + } + global $wgParserTestFiles, $IP; + + $mwTestDir = $IP . '/tests/'; + + # Human friendly helpers + $wantsCore = ( $flags & self::CORE_ONLY ); + $wantsRest = ( $flags & self::NO_CORE ); + + # Will hold the .txt parser test files we will include + $filesToTest = array(); + + # Filter out .txt files + foreach ( $wgParserTestFiles as $parserTestFile ) { + $isCore = ( 0 === strpos( $parserTestFile, $mwTestDir ) ); + + if ( $isCore && $wantsCore ) { + self::debug( "included core parser tests: $parserTestFile" ); + $filesToTest[] = $parserTestFile; + } elseif ( !$isCore && $wantsRest ) { + self::debug( "included non core parser tests: $parserTestFile" ); + $filesToTest[] = $parserTestFile; + } else { + self::debug( "skipped parser tests: $parserTestFile" ); + } + } + self::debug( 'parser tests files: ' + . implode( ' ', $filesToTest ) ); - foreach ( $wgParserTestFiles as $filename ) { - $testsName = basename( $filename, '.txt' ); + $suite = new PHPUnit_Framework_TestSuite; + foreach ( $filesToTest as $fileName ) { + $testsName = basename( $fileName, '.txt' ); + $escapedFileName = strtr( $fileName, array( "'" => "\\'", '\\' => '\\\\' ) ); /* 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 = <<<EOT +/** + * @group Database + * @group Parser + * @group ParserTests + * @group ParserTests_$parserTestClassName + */ +class $parserTestClassName extends NewParserTest { + protected \$file = '$escapedFileName'; +} +EOT; - $parserTester = new $className( $testsName ); - $suite->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", + '<?xml version="1.0" encoding="utf-8"?>' . + '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"><text>Foo</text></svg>' ); + + $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<h2>bar</h2>\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 <h2> 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( '<pre>monospaced</pre>', '<pre>monospaced</pre>', @@ -49,7 +58,7 @@ class ParserPreloadTest extends MediaWikiTestCase { /** * @covers Parser::getPreloadText */ - function testPreloadedNowikiIsUnstripped() { + public function testPreloadedNowikiIsUnstripped() { $this->assertPreloaded( '<nowiki>[[Dummy title]]</nowiki>', '<nowiki>[[Dummy title]]</nowiki>', @@ -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 @@ <?php class PreprocessorTest extends MediaWikiTestCase { - var $mTitle = 'Page title'; - var $mPPNodeCount = 0; - var $mOptions; + protected $mTitle = 'Page title'; + protected $mPPNodeCount = 0; + /** + * @var ParserOptions + */ + protected $mOptions; + /** + * @var Preprocessor + */ + protected $mPreprocessor; protected function setUp() { global $wgParserConf, $wgContLang; @@ -18,7 +25,7 @@ class PreprocessorTest extends MediaWikiTestCase { return array( 'gallery', 'display map' /* Used by Maps, see r80025 CR */, '/foo' ); } - function provideCases() { + public static function provideCases() { return array( array( "Foo", "<root>Foo</root>" ), array( "<!-- Foo -->", "<root><comment><!-- Foo --></comment></root>" ), @@ -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></$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 ==<!--c1-->", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment></h></root>" ), array( "== h == <!--c1-->", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment></h></root>" ), @@ -209,11 +218,11 @@ class PreprocessorTest extends MediaWikiTestCase { array( "== h == <!--c1--> <!--c2--><!--c3--> ", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment> <comment><!--c2--></comment><comment><!--c3--></comment> </h></root>" ), array( "== h == <!--c1--><!--c2--> <!--c3--> ", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment><comment><!--c2--></comment> <comment><!--c3--></comment> </h></root>" ), array( "== h == <!--c1--> <!--c2--> <!--c3--> ", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment> <comment><!--c2--></comment> <comment><!--c3--></comment> </h></root>" ), + array( "== h ==<!--c1--> <!--c2-->", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment> <comment><!--c2--></comment></h></root>" ), + array( "== h == <!--c1--> <!--c2-->", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment> <comment><!--c2--></comment></h></root>" ), + array( "== h ==<!--c1--> <!--c2--> ", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment> <comment><!--c2--></comment> </h></root>" ), /* These are not working: */ - array( "== h ==<!--c1--> <!--c2-->", "<root>== h ==<comment><!--c1--></comment> <comment><!--c2--></comment></root>" ), - array( "== h == <!--c1--> <!--c2-->", "<root>== h == <comment><!--c1--></comment> <comment><!--c2--></comment></root>" ), - array( "== h ==<!--c1--> <!--c2--> ", "<root>== h ==<comment><!--c1--></comment> <comment><!--c2--></comment> </root>" ), array( "== h == x <!--c1--><!--c2--><!--c3--> ", "<root>== h == x <comment><!--c1--></comment><comment><!--c2--></comment><comment><!--c3--></comment> </root>" ), array( "== h ==<!--c1--> x <!--c2--><!--c3--> ", "<root>== h ==<comment><!--c1--></comment> x <comment><!--c2--></comment><comment><!--c3--></comment> </root>" ), array( "== h ==<!--c1--><!--c2--><!--c3--> x ", "<root>== h ==<comment><!--c1--></comment><comment><!--c2--></comment><comment><!--c3--></comment> x </root>" ), @@ -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 @@ +<?php + +/** + * @group Parser + */ +class TidyTest extends MediaWikiTestCase { + public function setUp() { + parent::setUp(); + $check = MWTidy::tidy( '' ); + if ( strpos( $check, '<!--' ) !== false ) { + $this->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 <p>s + $text = trim( preg_replace( '#</?p>#', '', $text ) ); + // Windows, we love you! + $text = str_replace( "\r", '', $text ); + $this->assertEquals( $expected, $text, $msg ); + } + + public function provideTestWrapping() { + return array( + array( + '<mw:editsection page="foo" section="bar">foo</mw:editsection>', + '<mw:editsection page="foo" section="bar">foo</mw:editsection>', + '<mw:editsection> should survive tidy' + ), + array( + '<editsection page="foo" section="bar">foo</editsection>', + '<editsection page="foo" section="bar">foo</editsection>', + '<editsection> should survive tidy' + ), + array( '<mw:toc>foo</mw:toc>', '<mw:toc>foo</mw:toc>', '<mw:toc> should survive tidy' ), + array( "<link foo=\"bar\" />\nfoo", '<link foo="bar"/>foo', '<link> should survive tidy' ), + array( "<meta foo=\"bar\" />\nfoo", '<meta foo="bar"/>foo', '<meta> should survive tidy' ), + ); + } +}
\ No newline at end of file diff --git a/tests/phpunit/includes/search/SearchEngineTest.php b/tests/phpunit/includes/search/SearchEngineTest.php index 6abca6d4..87067038 100644 --- a/tests/phpunit/includes/search/SearchEngineTest.php +++ b/tests/phpunit/includes/search/SearchEngineTest.php @@ -45,7 +45,7 @@ class SearchEngineTest extends MediaWikiLangTestCase { } if ( !$this->isWikitextNS( NS_MAIN ) ) { - //@todo: cover the case of non-wikitext content in the main namespace + // @todo cover the case of non-wikitext content in the main namespace return; } @@ -87,6 +87,7 @@ class SearchEngineTest extends MediaWikiLangTestCase { # sort them numerically so we will compare simply that we received # the expected matches. sort( $matches ); + return $matches; } @@ -114,7 +115,7 @@ class SearchEngineTest extends MediaWikiLangTestCase { return true; } - function testFullWidth() { + public function testFullWidth() { $this->assertEquals( array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), $this->fetchIds( $this->search->searchText( 'AZ' ) ), @@ -133,14 +134,14 @@ class SearchEngineTest extends MediaWikiLangTestCase { "Search for normalized from Full-width Lower" ); } - function testTextSearch() { + public function testTextSearch() { $this->assertEquals( array( 'Smithee' ), $this->fetchIds( $this->search->searchText( 'smithee' ) ), "Plain search failed" ); } - function testTextPowerSearch() { + public function testTextPowerSearch() { $this->search->setNamespaces( array( 0, 1, 4 ) ); $this->assertEquals( array( @@ -151,7 +152,7 @@ class SearchEngineTest extends MediaWikiLangTestCase { "Power search failed" ); } - function testTitleSearch() { + public function testTitleSearch() { $this->assertEquals( array( 'Alan Smithee', @@ -161,7 +162,7 @@ class SearchEngineTest extends MediaWikiLangTestCase { "Title search failed" ); } - function testTextTitlePowerSearch() { + public function testTextTitlePowerSearch() { $this->search->setNamespaces( array( 0, 1, 4 ) ); $this->assertEquals( array( @@ -172,5 +173,4 @@ class SearchEngineTest extends MediaWikiLangTestCase { $this->fetchIds( $this->search->searchTitle( 'smithee' ) ), "Title power search failed" ); } - } diff --git a/tests/phpunit/includes/search/SearchUpdateTest.php b/tests/phpunit/includes/search/SearchUpdateTest.php index 7d867bc4..2f4fd501 100644 --- a/tests/phpunit/includes/search/SearchUpdateTest.php +++ b/tests/phpunit/includes/search/SearchUpdateTest.php @@ -17,6 +17,7 @@ class MockSearch extends SearchEngine { /** * @group Search + * @group Database */ class SearchUpdateTest extends MediaWikiTestCase { @@ -25,19 +26,11 @@ class SearchUpdateTest extends MediaWikiTestCase { $this->setMwGlobals( 'wgSearchType', 'MockSearch' ); } - function update( $text, $title = 'Test', $id = 1 ) { - $u = new SearchUpdate( $id, $title, $text ); - $u->doUpdate(); - return array( MockSearch::$title, MockSearch::$text ); - } - function updateText( $text ) { - list( , $resultText ) = $this->update( $text ); - $resultText = trim( $resultText ); // abstract from some implementation details - return $resultText; + return trim( SearchUpdate::updateText( $text ) ); } - function testUpdateText() { + public function testUpdateText() { $this->assertEquals( 'test', $this->updateText( '<div>TeSt</div>' ), @@ -69,7 +62,7 @@ EOT ); } - function testBug32712() { + public function testBug32712() { $text = "text „http://example.com“ text"; $result = $this->updateText( $text ); $processed = preg_replace( '/Q/u', 'Q', $result ); diff --git a/tests/phpunit/includes/site/MediaWikiSiteTest.php b/tests/phpunit/includes/site/MediaWikiSiteTest.php index 0cecdeea..c5d52d33 100644 --- a/tests/phpunit/includes/site/MediaWikiSiteTest.php +++ b/tests/phpunit/includes/site/MediaWikiSiteTest.php @@ -54,6 +54,7 @@ class MediaWikiSiteTest extends SiteTest { /** * @dataProvider fileUrlProvider + * @covers MediaWikiSite::getFileUrl */ public function testGetFileUrl( $url, $filePath, $pathArgument, $expected ) { $site = new MediaWikiSite(); @@ -62,7 +63,7 @@ class MediaWikiSiteTest extends SiteTest { $this->assertEquals( $expected, $site->getFileUrl( $pathArgument ) ); } - public function provideGetPageUrl() { + public static function provideGetPageUrl() { return array( // path, page, expected substring array( 'http://acme.test/wiki/$1', 'Berlin', '/wiki/Berlin' ), @@ -77,6 +78,7 @@ class MediaWikiSiteTest extends SiteTest { /** * @dataProvider provideGetPageUrl + * @covers MediaWikiSite::getPageUrl */ public function testGetPageUrl( $path, $page, $expected ) { $site = new MediaWikiSite(); @@ -85,5 +87,4 @@ class MediaWikiSiteTest extends SiteTest { $this->assertContains( $path, $site->getPageUrl() ); $this->assertContains( $expected, $site->getPageUrl( $page ) ); } - } diff --git a/tests/phpunit/includes/site/SiteListTest.php b/tests/phpunit/includes/site/SiteListTest.php index c3298397..8af2fc1b 100644 --- a/tests/phpunit/includes/site/SiteListTest.php +++ b/tests/phpunit/includes/site/SiteListTest.php @@ -68,6 +68,7 @@ class SiteListTest extends MediaWikiTestCase { /** * @dataProvider siteListProvider * @param SiteList $sites + * @covers SiteList::isEmpty */ public function testIsEmpty( SiteList $sites ) { $this->assertEquals( count( $sites ) === 0, $sites->isEmpty() ); @@ -76,6 +77,7 @@ class SiteListTest extends MediaWikiTestCase { /** * @dataProvider siteListProvider * @param SiteList $sites + * @covers SiteList::getSite */ public function testGetSiteByGlobalId( SiteList $sites ) { if ( $sites->isEmpty() ) { @@ -93,6 +95,7 @@ class SiteListTest extends MediaWikiTestCase { /** * @dataProvider siteListProvider * @param SiteList $sites + * @covers SiteList::getSiteByInternalId */ public function testGetSiteByInternalId( $sites ) { /** @@ -110,6 +113,7 @@ class SiteListTest extends MediaWikiTestCase { /** * @dataProvider siteListProvider * @param SiteList $sites + * @covers SiteList::hasSite */ public function testHasGlobalId( $sites ) { $this->assertFalse( $sites->hasSite( 'non-existing-global-id' ) ); @@ -128,6 +132,7 @@ class SiteListTest extends MediaWikiTestCase { /** * @dataProvider siteListProvider * @param SiteList $sites + * @covers SiteList::hasInternalId */ public function testHasInternallId( $sites ) { /** @@ -145,6 +150,7 @@ class SiteListTest extends MediaWikiTestCase { /** * @dataProvider siteListProvider * @param SiteList $sites + * @covers SiteList::getGlobalIdentifiers */ public function testGetGlobalIdentifiers( SiteList $sites ) { $identifiers = $sites->getGlobalIdentifiers(); @@ -169,6 +175,8 @@ class SiteListTest extends MediaWikiTestCase { * @since 1.21 * * @param SiteList $list + * @covers SiteList::getSerializationData + * @covers SiteList::unserialize */ public function testSerialization( SiteList $list ) { $serialization = serialize( $list ); @@ -186,5 +194,4 @@ class SiteListTest extends MediaWikiTestCase { $this->assertTrue( $copy->hasInternalId( $site->getInternalId() ) ); } } - } diff --git a/tests/phpunit/includes/site/SiteSQLStoreTest.php b/tests/phpunit/includes/site/SiteSQLStoreTest.php index cf4ce945..6002c1a1 100644 --- a/tests/phpunit/includes/site/SiteSQLStoreTest.php +++ b/tests/phpunit/includes/site/SiteSQLStoreTest.php @@ -32,6 +32,9 @@ */ class SiteSQLStoreTest extends MediaWikiTestCase { + /** + * @covers SiteSQLStore::getSites + */ public function testGetSites() { $expectedSites = TestSites::getSites(); TestSites::insertIntoDb(); @@ -56,6 +59,9 @@ class SiteSQLStoreTest extends MediaWikiTestCase { } } + /** + * @covers SiteSQLStore::saveSites + */ public function testSaveSites() { $store = SiteSQLStore::newInstance(); @@ -86,6 +92,9 @@ class SiteSQLStoreTest extends MediaWikiTestCase { $this->assertTrue( $site->getInternalId() >= 0 ); } + /** + * @covers SiteSQLStore::reset + */ public function testReset() { $store1 = SiteSQLStore::newInstance(); $store2 = SiteSQLStore::newInstance(); @@ -109,6 +118,9 @@ class SiteSQLStoreTest extends MediaWikiTestCase { $this->assertNull( $site ); } + /** + * @covers SiteSQLStore::clear + */ public function testClear() { $store = SiteSQLStore::newInstance(); $this->assertTrue( $store->clear() ); @@ -119,5 +131,4 @@ class SiteSQLStoreTest extends MediaWikiTestCase { $sites = $store->getSites(); $this->assertEquals( 0, $sites->count() ); } - } diff --git a/tests/phpunit/includes/site/SiteTest.php b/tests/phpunit/includes/site/SiteTest.php index d20e2a52..29c1ff33 100644 --- a/tests/phpunit/includes/site/SiteTest.php +++ b/tests/phpunit/includes/site/SiteTest.php @@ -38,6 +38,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::getInterwikiIds */ public function testGetInterwikiIds( Site $site ) { $this->assertInternalType( 'array', $site->getInterwikiIds() ); @@ -46,6 +47,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::getNavigationIds */ public function testGetNavigationIds( Site $site ) { $this->assertInternalType( 'array', $site->getNavigationIds() ); @@ -54,6 +56,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::addNavigationId */ public function testAddNavigationId( Site $site ) { $site->addNavigationId( 'foobar' ); @@ -63,6 +66,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::addInterwikiId */ public function testAddInterwikiId( Site $site ) { $site->addInterwikiId( 'foobar' ); @@ -72,6 +76,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::getLanguageCode */ public function testGetLanguageCode( Site $site ) { $this->assertTypeOrValue( 'string', $site->getLanguageCode(), null ); @@ -80,6 +85,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::setLanguageCode */ public function testSetLanguageCode( Site $site ) { $site->setLanguageCode( 'en' ); @@ -89,6 +95,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::normalizePageName */ public function testNormalizePageName( Site $site ) { $this->assertInternalType( 'string', $site->normalizePageName( 'Foobar' ) ); @@ -97,6 +104,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::getGlobalId */ public function testGetGlobalId( Site $site ) { $this->assertTypeOrValue( 'string', $site->getGlobalId(), null ); @@ -105,6 +113,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::setGlobalId */ public function testSetGlobalId( Site $site ) { $site->setGlobalId( 'foobar' ); @@ -114,6 +123,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::getType */ public function testGetType( Site $site ) { $this->assertInternalType( 'string', $site->getType() ); @@ -122,6 +132,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::getPath */ public function testGetPath( Site $site ) { $this->assertTypeOrValue( 'string', $site->getPath( 'page_path' ), null ); @@ -132,6 +143,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::getAllPaths */ public function testGetAllPaths( Site $site ) { $this->assertInternalType( 'array', $site->getAllPaths() ); @@ -140,6 +152,8 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::setPath + * @covers Site::removePath */ public function testSetAndRemovePath( Site $site ) { $count = count( $site->getAllPaths() ); @@ -162,6 +176,9 @@ class SiteTest extends MediaWikiTestCase { $this->assertNull( $site->getPath( 'spam' ) ); } + /** + * @covers Site::setLinkPath + */ public function testSetLinkPath() { $site = new Site(); $path = "TestPath/$1"; @@ -170,6 +187,9 @@ class SiteTest extends MediaWikiTestCase { $this->assertEquals( $path, $site->getLinkPath() ); } + /** + * @covers Site::getLinkPathType + */ public function testGetLinkPathType() { $site = new Site(); @@ -182,6 +202,9 @@ class SiteTest extends MediaWikiTestCase { $this->assertEquals( $path, $site->getLinkPath() ); } + /** + * @covers Site::setPath + */ public function testSetPath() { $site = new Site(); @@ -191,6 +214,10 @@ class SiteTest extends MediaWikiTestCase { $this->assertEquals( $path, $site->getPath( 'foo' ) ); } + /** + * @covers Site::setPath + * @covers Site::getProtocol + */ public function testProtocolRelativePath() { $site = new Site(); @@ -201,7 +228,7 @@ class SiteTest extends MediaWikiTestCase { $this->assertEquals( '', $site->getProtocol() ); } - public function provideGetPageUrl() { + public static function provideGetPageUrl() { //NOTE: the assumption that the URL is built by replacing $1 // with the urlencoded version of $page // is true for Site but not guaranteed for subclasses. @@ -228,6 +255,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider provideGetPageUrl + * @covers Site::getPageUrl */ public function testGetPageUrl( $path, $page, $expected ) { $site = new Site(); @@ -252,6 +280,8 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::serialize + * @covers Site::unserialize */ public function testSerialization( Site $site ) { $this->assertInstanceOf( 'Serializable', $site ); @@ -263,5 +293,4 @@ class SiteTest extends MediaWikiTestCase { $this->assertEquals( $serialization, serialize( $newInstance ) ); } - } diff --git a/tests/phpunit/includes/site/TestSites.php b/tests/phpunit/includes/site/TestSites.php index a5656a73..f224b7d7 100644 --- a/tests/phpunit/includes/site/TestSites.php +++ b/tests/phpunit/includes/site/TestSites.php @@ -97,5 +97,4 @@ class TestSites { $sitesTable->clear(); $sitesTable->saveSites( TestSites::getSites() ); } - } diff --git a/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php b/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php index 3b82e07d..a806b4ac 100644 --- a/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php +++ b/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php @@ -51,7 +51,7 @@ class QueryAllSpecialPagesTest extends MediaWikiTestCase { * Test SQL for each of our QueryPages objects * @group Database */ - function testQuerypageSqlQuery() { + public function testQuerypageSqlQuery() { global $wgDBtype; foreach ( $this->queryPages as $page ) { diff --git a/tests/phpunit/includes/specials/SpecialPreferencesTest.php b/tests/phpunit/includes/specials/SpecialPreferencesTest.php new file mode 100644 index 00000000..6c637c65 --- /dev/null +++ b/tests/phpunit/includes/specials/SpecialPreferencesTest.php @@ -0,0 +1,60 @@ +<?php +/** + * Test class for SpecialPreferences class. + * + * Copyright © 2013, Antoine Musso + * Copyright © 2013, Wikimedia Foundation Inc. + * + */ + +class SpecialPreferencesTest extends MediaWikiTestCase { + + /** + * Make sure a nickname which is longer than $wgMaxSigChars + * is not throwing a fatal error. + * + * Test specifications by Alexandre "ialex" Emsenhuber. + */ + public function testBug41337() { + + // Set a low limit + $this->setMwGlobals( 'wgMaxSigChars', 2 ); + + $user = $this->getMock( 'User' ); + $user->expects( $this->any() ) + ->method( 'isAnon' ) + ->will( $this->returnValue( false ) ); + + # Yeah foreach requires an array, not NULL =( + $user->expects( $this->any() ) + ->method( 'getEffectiveGroups' ) + ->will( $this->returnValue( array() ) ); + + # The mocked user has a long nickname + $user->expects( $this->any() ) + ->method( 'getOption' ) + ->will( $this->returnValueMap( array( + array( 'nickname', null, false, 'superlongnickname' ), + ) + ) ); + + # Validate the mock (FIXME should probably be removed) + $this->assertFalse( $user->isAnon() ); + $this->assertEquals( array(), + $user->getEffectiveGroups() ); + $this->assertEquals( 'superlongnickname', + $user->getOption( 'nickname' ) ); + + # Forge a request to call the special page + $context = new RequestContext(); + $context->setRequest( new FauxRequest() ); + $context->setUser( $user ); + $context->setTitle( Title::newFromText( 'Test' ) ); + + # Do the call, should not spurt a fatal error. + $special = new SpecialPreferences(); + $special->setContext( $context ); + $special->execute( array() ); + } + +} diff --git a/tests/phpunit/includes/specials/SpecialRecentchangesTest.php b/tests/phpunit/includes/specials/SpecialRecentchangesTest.php index add830b0..436eb2e2 100644 --- a/tests/phpunit/includes/specials/SpecialRecentchangesTest.php +++ b/tests/phpunit/includes/specials/SpecialRecentchangesTest.php @@ -42,7 +42,6 @@ class SpecialRecentchangesTest extends MediaWikiTestCase { /** return false if condition begin with 'rc_timestamp ' */ private static function filterOutRcTimestampCondition( $var ) { return ( false === strpos( $var, 'rc_timestamp ' ) ); - } public function testRcNsFilter() { @@ -123,5 +122,4 @@ class SpecialRecentchangesTest extends MediaWikiTestCase { array( NS_TALK, NS_MAIN ), ); } - } diff --git a/tests/phpunit/includes/specials/SpecialSearchTest.php b/tests/phpunit/includes/specials/SpecialSearchTest.php index f5ef0fb7..17e883fd 100644 --- a/tests/phpunit/includes/specials/SpecialSearchTest.php +++ b/tests/phpunit/includes/specials/SpecialSearchTest.php @@ -18,7 +18,7 @@ class SpecialSearchTest extends MediaWikiTestCase { * @param $expectedProfile An expected search profile name * @param $expectedNs Array Expected namespaces */ - function testProfileAndNamespaceLoading( + public function testProfileAndNamespaceLoading( $requested, $userOptions, $expectedProfile, $expectedNS, $message = 'Profile name and namespaces mismatches!' ) { @@ -53,10 +53,9 @@ class SpecialSearchTest extends MediaWikiTestCase { ) , $message ); - } - function provideSearchOptionsTests() { + public static function provideSearchOptionsTests() { $defaultNS = SearchEngine::defaultNamespaces(); $EMPTY_REQUEST = array(); $NO_USER_PREF = null; @@ -105,6 +104,7 @@ class SpecialSearchTest extends MediaWikiTestCase { foreach ( $opt as $name => $value ) { $u->setOption( $name, $value ); } + return $u; } @@ -112,7 +112,7 @@ class SpecialSearchTest extends MediaWikiTestCase { * Verify we do not expand search term in <title> on search result page * https://gerrit.wikimedia.org/r/4841 */ - function testSearchTermIsNotExpanded() { + public function testSearchTermIsNotExpanded() { # Initialize [[Special::Search]] $search = new SpecialSearch(); @@ -135,6 +135,5 @@ class SpecialSearchTest extends MediaWikiTestCase { $pageTitle, "Search term '{$term}' should not be expanded in Special:Search <title>" ); - } } diff --git a/tests/phpunit/includes/upload/UploadTest.php b/tests/phpunit/includes/upload/UploadBaseTest.php index b809d320..982b46b2 100644 --- a/tests/phpunit/includes/upload/UploadTest.php +++ b/tests/phpunit/includes/upload/UploadBaseTest.php @@ -1,10 +1,12 @@ <?php + /** * @group Upload */ -class UploadTest extends MediaWikiTestCase { - protected $upload; +class UploadBaseTest extends MediaWikiTestCase { + /** @var UploadTestHandler */ + protected $upload; protected function setUp() { global $wgHooks; @@ -30,6 +32,7 @@ class UploadTest extends MediaWikiTestCase { * of UploadBase::getTitle() and then the actual returned title * * @dataProvider provideTestTitleValidation + * @covers UploadBase::getTitle */ public function testTitleValidation( $srcFilename, $dstFilename, $code, $msg ) { /* Check the result code */ @@ -82,6 +85,7 @@ class UploadTest extends MediaWikiTestCase { /** * Test the upload verification functions + * @covers UploadBase::verifyUpload */ public function testVerifyUpload() { /* Setup with zero file size */ @@ -108,7 +112,6 @@ class UploadTest extends MediaWikiTestCase { * * This method should be abstracted so we can test different settings. */ - public function testMaxUploadSize() { global $wgMaxUploadSize; $savedGlobal = $wgMaxUploadSize; // save global @@ -130,15 +133,15 @@ class UploadTest extends MediaWikiTestCase { } class UploadTestHandler extends UploadBase { - public function initializeFromRequest( &$request ) {} + public function initializeFromRequest( &$request ) { + } public function testTitleValidation( $name ) { $this->mTitle = false; $this->mDesiredDestName = $name; $this->mTitleError = UploadBase::OK; $this->getTitle(); + return $this->mTitleError; } - - } diff --git a/tests/phpunit/includes/upload/UploadFromUrlTest.php b/tests/phpunit/includes/upload/UploadFromUrlTest.php index 4d2d8ce3..a75fba69 100644 --- a/tests/phpunit/includes/upload/UploadFromUrlTest.php +++ b/tests/phpunit/includes/upload/UploadFromUrlTest.php @@ -6,14 +6,14 @@ * @group Database */ class UploadFromUrlTest extends ApiTestCase { - protected function setUp() { - global $wgEnableUploads, $wgAllowCopyUploads, $wgAllowAsyncCopyUploads; parent::setUp(); - $wgEnableUploads = true; - $wgAllowCopyUploads = true; - $wgAllowAsyncCopyUploads = true; + $this->setMwGlobals( array( + 'wgEnableUploads' => true, + 'wgAllowCopyUploads' => true, + 'wgAllowAsyncCopyUploads' => true, + ) ); wfSetupSession(); if ( wfLocalFile( 'UploadFromUrlTest.png' )->exists() ) { @@ -30,6 +30,7 @@ class UploadFromUrlTest extends ApiTestCase { $module->execute(); wfSetupSession( $sessionId ); + return array( $module->getResultData(), $req ); } @@ -174,7 +175,6 @@ class UploadFromUrlTest extends ApiTestCase { $this->user->addGroup( 'users' ); - $data = $this->doAsyncUpload( $token ); $this->assertEquals( $data[0]['upload']['result'], 'Warning' ); @@ -235,7 +235,7 @@ class UploadFromUrlTest extends ApiTestCase { $this->assertFalse( (bool)$talk->getArticleID( Title::GAID_FOR_UPDATE ), 'User talk does not exist' ); - $data = $this->doApiRequest( array( + $this->doApiRequest( array( 'action' => 'upload', 'filename' => 'UploadFromUrlTest.png', 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', @@ -259,7 +259,7 @@ class UploadFromUrlTest extends ApiTestCase { $exception = false; try { - $data = $this->doApiRequest( array( + $this->doApiRequest( array( 'action' => 'upload', 'filename' => 'UploadFromUrlTest.png', 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', @@ -277,7 +277,6 @@ class UploadFromUrlTest extends ApiTestCase { $this->assertFalse( $job ); return; - /* // Broken until using leavemessage with ignorewarnings is supported $job->run(); @@ -330,7 +329,6 @@ class UploadFromUrlTest extends ApiTestCase { return $data; } - /** * */ diff --git a/tests/phpunit/includes/upload/UploadStashTest.php b/tests/phpunit/includes/upload/UploadStashTest.php index 8fcaa214..7a0fea48 100644 --- a/tests/phpunit/includes/upload/UploadStashTest.php +++ b/tests/phpunit/includes/upload/UploadStashTest.php @@ -44,8 +44,7 @@ class UploadStashTest extends MediaWikiTestCase { } public function testBug29408() { - global $wgUser; - $wgUser = self::$users['uploader']->user; + $this->setMwGlobals( 'wgUser', self::$users['uploader']->user ); $repo = RepoGroup::singleton()->getLocalRepo(); $stash = new UploadStash( $repo ); diff --git a/tests/phpunit/install-phpunit.sh b/tests/phpunit/install-phpunit.sh index 36012748..1f602935 100644 --- a/tests/phpunit/install-phpunit.sh +++ b/tests/phpunit/install-phpunit.sh @@ -8,7 +8,7 @@ has_binary () { } if [ `id -u` -ne 0 ]; then - echo '*** ERROR' Must be root to run + echo '*** ERROR: Must be root to run' exit 1 fi diff --git a/tests/phpunit/languages/LanguageAmTest.php b/tests/phpunit/languages/LanguageAmTest.php index 9723e1e3..a644f5e0 100644 --- a/tests/phpunit/languages/LanguageAmTest.php +++ b/tests/phpunit/languages/LanguageAmTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/LanguageAm.php */ class LanguageAmTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), diff --git a/tests/phpunit/languages/LanguageArTest.php b/tests/phpunit/languages/LanguageArTest.php index 523ee7f6..7b48f236 100644 --- a/tests/phpunit/languages/LanguageArTest.php +++ b/tests/phpunit/languages/LanguageArTest.php @@ -6,8 +6,11 @@ /** Tests for MediaWiki languages/LanguageAr.php */ class LanguageArTest extends LanguageClassesTestCase { - - function testFormatNum() { + /** + * @covers Language::formatNum + * @todo split into a test and a dataprovider + */ + public function testFormatNum() { $this->assertEquals( '١٬٢٣٤٬٥٦٧', $this->getLang()->formatNum( '1234567' ) ); $this->assertEquals( '-١٢٫٨٩', $this->getLang()->formatNum( -12.89 ) ); } @@ -15,12 +18,13 @@ class LanguageArTest extends LanguageClassesTestCase { /** * Mostly to test the raw ascii feature. * @dataProvider providerSprintfDate + * @covers Language::sprintfDate */ - function testSprintfDate( $format, $date, $expected ) { + public function testSprintfDate( $format, $date, $expected ) { $this->assertEquals( $expected, $this->getLang()->sprintfDate( $format, $date ) ); } - function providerSprintfDate() { + public static function providerSprintfDate() { return array( array( 'xg "vs" g', @@ -45,13 +49,24 @@ class LanguageArTest extends LanguageClassesTestCase { ); } - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'zero', 'one', 'two', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'zero', 0 ), array( 'one', 1 ), diff --git a/tests/phpunit/languages/LanguageBeTest.php b/tests/phpunit/languages/LanguageBeTest.php index 0144941b..7bd586af 100644 --- a/tests/phpunit/languages/LanguageBeTest.php +++ b/tests/phpunit/languages/LanguageBeTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/LanguageBe.php */ class LanguageBeTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 1 ), array( 'many', 11 ), diff --git a/tests/phpunit/languages/LanguageBe_taraskTest.php b/tests/phpunit/languages/LanguageBe_taraskTest.php index 5b246d8e..d5822f4a 100644 --- a/tests/phpunit/languages/LanguageBe_taraskTest.php +++ b/tests/phpunit/languages/LanguageBe_taraskTest.php @@ -1,20 +1,22 @@ <?php class LanguageBe_taraskTest extends LanguageClassesTestCase { - /** * Make sure the language code we are given is indeed * be-tarask. This is to ensure LanguageClassesTestCase * does not give us the wrong language. */ - function testBeTaraskTestsUsesBeTaraskCode() { + public function testBeTaraskTestsUsesBeTaraskCode() { $this->assertEquals( 'be-tarask', $this->getLang()->getCode() ); } - /** see bug 23156 & r64981 */ - function testSearchRightSingleQuotationMarkAsApostroph() { + /** + * @see bug 23156 & r64981 + * @covers Language::commafy + */ + public function testSearchRightSingleQuotationMarkAsApostroph() { $this->assertEquals( "'", $this->getLang()->normalizeForSearch( '’' ), @@ -22,24 +24,41 @@ class LanguageBe_taraskTest extends LanguageClassesTestCase { ); } - /** see bug 23156 & r64981 */ - function testCommafy() { + /** + * @see bug 23156 & r64981 + * @covers Language::commafy + */ + public function testCommafy() { $this->assertEquals( '1,234,567', $this->getLang()->commafy( '1234567' ) ); $this->assertEquals( '12,345', $this->getLang()->commafy( '12345' ) ); } - /** see bug 23156 & r64981 */ - function testDoesNotCommafyFourDigitsNumber() { + /** + * @see bug 23156 & r64981 + * @covers Language::commafy + */ + public function testDoesNotCommafyFourDigitsNumber() { $this->assertEquals( '1234', $this->getLang()->commafy( '1234' ) ); } - /** @dataProvider providePluralFourForms */ - function testPluralFourForms( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralFourForms() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 1 ), array( 'many', 11 ), @@ -55,19 +74,21 @@ class LanguageBe_taraskTest extends LanguageClassesTestCase { ); } - /** @dataProvider providePluralTwoForms */ - function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'several' ); + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralTwoForms() { + public static function providePluralTwoForms() { return array( array( 'one', 1 ), - array( 'several', 11 ), - array( 'several', 91 ), - array( 'several', 121 ), + array( 'other', 11 ), + array( 'other', 91 ), + array( 'other', 121 ), ); } - } diff --git a/tests/phpunit/languages/LanguageBhoTest.php b/tests/phpunit/languages/LanguageBhoTest.php index c364917d..187bfbbc 100644 --- a/tests/phpunit/languages/LanguageBhoTest.php +++ b/tests/phpunit/languages/LanguageBhoTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/LanguageBho.php */ class LanguageBhoTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), @@ -22,5 +32,4 @@ class LanguageBhoTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageBsTest.php b/tests/phpunit/languages/LanguageBsTest.php index 76d00704..fb965b89 100644 --- a/tests/phpunit/languages/LanguageBsTest.php +++ b/tests/phpunit/languages/LanguageBsTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/LanguageBs.php */ class LanguageBsTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'many', 0 ), array( 'one', 1 ), @@ -29,5 +39,4 @@ class LanguageBsTest extends LanguageClassesTestCase { array( 'many', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageClassesTestCase.php b/tests/phpunit/languages/LanguageClassesTestCase.php index 6659dad1..632e037f 100644 --- a/tests/phpunit/languages/LanguageClassesTestCase.php +++ b/tests/phpunit/languages/LanguageClassesTestCase.php @@ -3,16 +3,7 @@ * Helping class to run tests using a clean language instance. * * This is intended for the MediaWiki language class tests under - * tests/phpunit/languages. You simply need to extends this test - * and set it up with a language code using setUpBeforeClass: - * - * @par Setting up a language: - * @code - * class LanguageFooTest extends LanguageClassesTestCase { - * public static function setUpBeforeClass() { - * self::setLang( 'Foo' ); - * } - * @endcode + * tests/phpunit/languages. * * Before each tests, a new language object is build which you * can retrieve in your test using the $this->getLang() method: @@ -28,19 +19,6 @@ * @endcode */ abstract class LanguageClassesTestCase extends MediaWikiTestCase { - - /** - * Regex used to find out the language code out of the class name - * used by setUpBeforeClass - */ - private static $reExtractLangFromClass = '/Language(.*)Test/'; - - /** - * Hold the language code we are going to use. This is extracted - * directly from the extending class. - */ - private static $LanguageClassCode; - /** * Internal language object * @@ -57,9 +35,19 @@ abstract class LanguageClassesTestCase extends MediaWikiTestCase { */ private $languageObject; - public static function setUpBeforeClass() { - $found = preg_match( self::$reExtractLangFromClass, - get_called_class(), $m ); + /** + * @return Language + */ + protected function getLang() { + return $this->languageObject; + } + + /** + * Create a new language object before each test. + */ + protected function setUp() { + parent::setUp(); + $found = preg_match( '/Language(.+)Test/', get_called_class(), $m ); if ( $found ) { # Normalize language code since classes uses underscores $m[1] = str_replace( '_', '-', $m[1] ); @@ -71,21 +59,8 @@ abstract class LanguageClassesTestCase extends MediaWikiTestCase { . "out of " . get_called_class() . " failling back to 'en'\n" ); } - // TODO: validate $m[1] which should be a valid language code - self::$LanguageClassCode = $m[1]; - } - - protected function getLang() { - return $this->languageObject; - } - - /** - * Create a new language object before each test. - */ - protected function setUp() { - parent::setUp(); - $this->languageObject = Language::factory( - self::$LanguageClassCode ); + // @todo validate $m[1] which should be a valid language code + $this->languageObject = Language::factory( $m[1] ); } /** @@ -96,5 +71,4 @@ abstract class LanguageClassesTestCase extends MediaWikiTestCase { unset( $this->languageObject ); parent::tearDown(); } - } diff --git a/tests/phpunit/languages/LanguageCsTest.php b/tests/phpunit/languages/LanguageCsTest.php index 884a129e..da9e6b88 100644 --- a/tests/phpunit/languages/LanguageCsTest.php +++ b/tests/phpunit/languages/LanguageCsTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/Languagecs.php */ class LanguageCsTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -28,5 +38,4 @@ class LanguageCsTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageCuTest.php b/tests/phpunit/languages/LanguageCuTest.php index e2394b35..07193172 100644 --- a/tests/phpunit/languages/LanguageCuTest.php +++ b/tests/phpunit/languages/LanguageCuTest.php @@ -7,27 +7,36 @@ /** Tests for MediaWiki languages/LanguageCu.php */ class LanguageCuTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'few', 'many', 'other' ); + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { + $forms = array( 'one', 'two', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), - array( 'few', 2 ), - array( 'many', 3 ), - array( 'many', 4 ), + array( 'two', 2 ), + array( 'few', 3 ), + array( 'few', 4 ), array( 'other', 5 ), array( 'one', 11 ), array( 'other', 20 ), - array( 'few', 22 ), - array( 'many', 223 ), + array( 'two', 22 ), + array( 'few', 223 ), array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageCyTest.php b/tests/phpunit/languages/LanguageCyTest.php index 2a7f4a92..eaf663a8 100644 --- a/tests/phpunit/languages/LanguageCyTest.php +++ b/tests/phpunit/languages/LanguageCyTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageCy.php */ class LanguageCyTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'zero', 'one', 'two', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'zero', 0 ), array( 'one', 1 ), @@ -30,5 +40,4 @@ class LanguageCyTest extends LanguageClassesTestCase { array( 'other', 200.00 ), ); } - } diff --git a/tests/phpunit/languages/LanguageDsbTest.php b/tests/phpunit/languages/LanguageDsbTest.php index 285ce648..94c11bcc 100644 --- a/tests/phpunit/languages/LanguageDsbTest.php +++ b/tests/phpunit/languages/LanguageDsbTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageDsb.php */ class LanguageDsbTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'two', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -28,5 +38,4 @@ class LanguageDsbTest extends LanguageClassesTestCase { array( 'other', 555 ), ); } - } diff --git a/tests/phpunit/languages/LanguageFrTest.php b/tests/phpunit/languages/LanguageFrTest.php index faf0de58..46b65011 100644 --- a/tests/phpunit/languages/LanguageFrTest.php +++ b/tests/phpunit/languages/LanguageFrTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageFr.php */ class LanguageFrTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), @@ -22,5 +32,4 @@ class LanguageFrTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageGaTest.php b/tests/phpunit/languages/LanguageGaTest.php index 2dbb088b..c009f56b 100644 --- a/tests/phpunit/languages/LanguageGaTest.php +++ b/tests/phpunit/languages/LanguageGaTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageGa.php */ class LanguageGaTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'two', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -22,5 +32,4 @@ class LanguageGaTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageGdTest.php b/tests/phpunit/languages/LanguageGdTest.php index 5de1e9d2..0b2612b2 100644 --- a/tests/phpunit/languages/LanguageGdTest.php +++ b/tests/phpunit/languages/LanguageGdTest.php @@ -7,15 +7,17 @@ /** Tests for MediaWiki languages/classes/LanguageGd.php */ class LanguageGdTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providerPlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'two', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { - return array ( + public static function providerPlural() { + return array( array( 'other', 0 ), array( 'one', 1 ), array( 'two', 2 ), @@ -27,22 +29,25 @@ class LanguageGdTest extends LanguageClassesTestCase { ); } - /** @dataProvider providerPluralExplicit */ - function testExplicitPlural( $result, $value ) { + /** + * @dataProvider providerPluralExplicit + * @covers Language::convertPlural + */ + public function testExplicitPlural( $result, $value ) { $forms = array( 'one', 'two', 'few', 'other', '11=Form11', '12=Form12' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPluralExplicit() { - return array ( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'two', 2 ), - array( 'Form11', 11 ), - array( 'Form12', 12 ), - array( 'few', 3 ), - array( 'few', 19 ), - array( 'other', 200 ), + public static function providerPluralExplicit() { + return array( + array( 'other', 0 ), + array( 'one', 1 ), + array( 'two', 2 ), + array( 'Form11', 11 ), + array( 'Form12', 12 ), + array( 'few', 3 ), + array( 'few', 19 ), + array( 'other', 200 ), ); } } diff --git a/tests/phpunit/languages/LanguageGvTest.php b/tests/phpunit/languages/LanguageGvTest.php index 4126e071..a0def628 100644 --- a/tests/phpunit/languages/LanguageGvTest.php +++ b/tests/phpunit/languages/LanguageGvTest.php @@ -7,15 +7,27 @@ /** Tests for MediaWiki languages/classes/LanguageGv.php */ class LanguageGvTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { // This is not compatible with CLDR plural rules http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#gv + // What does this mean? Is there a hard-coded override for gv somewhere? -Ryan Kaldari 2013-01-28 $forms = array( 'Form 1', 'Form 2', 'Form 3', 'Form 4' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->markTestSkipped( "This test won't work since convertPlural for gv doesn't seem to actually follow our plural rules." ); + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'Form 4', 0 ), array( 'Form 2', 1 ), @@ -28,5 +40,4 @@ class LanguageGvTest extends LanguageClassesTestCase { array( 'Form 4', 50 ), ); } - } diff --git a/tests/phpunit/languages/LanguageHeTest.php b/tests/phpunit/languages/LanguageHeTest.php index 6de88e59..8edc6ddf 100644 --- a/tests/phpunit/languages/LanguageHeTest.php +++ b/tests/phpunit/languages/LanguageHeTest.php @@ -7,70 +7,125 @@ /** Tests for MediaWiki languages/classes/LanguageHe.php */ class LanguageHeTest extends LanguageClassesTestCase { + /** + * The most common usage for the plural forms is two forms, + * for singular and plural. In this case, the second form + * is technically dual, but in practice it's used as plural. + * In some cases, usually with expressions of time, three forms + * are needed - singular, dual and plural. + * CLDR also specifies a fourth form for multiples of 10, + * which is very rare. It also has a mistake, because + * the number 10 itself is supposed to be just plural, + * so currently it's overridden in MediaWiki. + */ - /** @dataProvider providerPluralDual */ - function testPluralDual( $result, $value ) { + // @todo the below test*PluralForms test methods can be refactored + // to use a single test method and data provider.. + + /** + * @dataProvider provideTwoPluralForms + * @covers Language::convertPlural + */ + public function testTwoPluralForms( $result, $value ) { + $forms = array( 'one', 'other' ); + $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); + } + + /** + * @dataProvider provideThreePluralForms + * @covers Language::convertPlural + */ + public function testThreePluralForms( $result, $value ) { $forms = array( 'one', 'two', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPluralDual() { + /** + * @dataProvider provideFourPluralForms + * @covers Language::convertPlural + */ + public function testFourPluralForms( $result, $value ) { + $forms = array( 'one', 'two', 'many', 'other' ); + $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); + } + + /** + * @dataProvider provideFourPluralForms + * @covers Language::convertPlural + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function provideTwoPluralForms() { return array( - array( 'other', 0 ), // Zero -> plural + array( 'other', 0 ), // Zero - plural array( 'one', 1 ), // Singular - array( 'two', 2 ), // Dual - array( 'other', 3 ), // Plural + array( 'other', 2 ), // No third form provided, use it as plural + array( 'other', 3 ), // Plural - other + array( 'other', 10 ), // No fourth form provided, use it as plural + array( 'other', 20 ), // No fourth form provided, use it as plural ); } - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); + public static function provideThreePluralForms() { + return array( + array( 'other', 0 ), // Zero - plural + array( 'one', 1 ), // Singular + array( 'two', 2 ), // Dual + array( 'other', 3 ), // Plural - other + array( 'other', 10 ), // No fourth form provided, use it as plural + array( 'other', 20 ), // No fourth form provided, use it as plural + ); } - function providerPlural() { + public static function provideFourPluralForms() { return array( - array( 'other', 0 ), // Zero -> plural + array( 'other', 0 ), // Zero - plural array( 'one', 1 ), // Singular - array( 'other', 2 ), // Plural, no dual provided - array( 'other', 3 ), // Plural + array( 'two', 2 ), // Dual + array( 'other', 3 ), // Plural - other + array( 'other', 10 ), // 10 is supposed to be plural (other), not "many" + array( 'many', 20 ), // Fourth form provided - rare, but supported by CLDR ); } - /** @dataProvider providerGrammar */ - function testGrammar( $result, $word, $case ) { + /** + * @dataProvider provideGrammar + * @covers Language::convertGrammar + */ + public function testGrammar( $result, $word, $case ) { $this->assertEquals( $result, $this->getLang()->convertGrammar( $word, $case ) ); } // The comments in the beginning of the line help avoid RTL problems // with text editors. - function providerGrammar() { + public static function provideGrammar() { return array( array( - /* result */ 'וויקיפדיה', - /* word */ 'ויקיפדיה', - /* case */ 'תחילית', + /* result */'וויקיפדיה', + /* word */'ויקיפדיה', + /* case */'תחילית', ), array( - /* result */ 'וולפגנג', - /* word */ 'וולפגנג', - /* case */ 'prefixed', + /* result */'וולפגנג', + /* word */'וולפגנג', + /* case */'prefixed', ), array( - /* result */ 'קובץ', - /* word */ 'הקובץ', - /* case */ 'תחילית', + /* result */'קובץ', + /* word */'הקובץ', + /* case */'תחילית', ), array( - /* result */ '־Wikipedia', - /* word */ 'Wikipedia', - /* case */ 'תחילית', + /* result */'־Wikipedia', + /* word */'Wikipedia', + /* case */'תחילית', ), array( - /* result */ '־1995', - /* word */ '1995', - /* case */ 'תחילית', + /* result */'־1995', + /* word */'1995', + /* case */'תחילית', ), ); } diff --git a/tests/phpunit/languages/LanguageHiTest.php b/tests/phpunit/languages/LanguageHiTest.php index 86d6af58..f6d2c9e9 100644 --- a/tests/phpunit/languages/LanguageHiTest.php +++ b/tests/phpunit/languages/LanguageHiTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/LanguageHi.php */ class LanguageHiTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), @@ -22,5 +32,4 @@ class LanguageHiTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageHrTest.php b/tests/phpunit/languages/LanguageHrTest.php index 9dce4ea7..6ce4aff9 100644 --- a/tests/phpunit/languages/LanguageHrTest.php +++ b/tests/phpunit/languages/LanguageHrTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageHr.php */ class LanguageHrTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'many', 0 ), array( 'one', 1 ), @@ -29,5 +39,4 @@ class LanguageHrTest extends LanguageClassesTestCase { array( 'many', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageHsbTest.php b/tests/phpunit/languages/LanguageHsbTest.php index bec7d819..f95a43bf 100644 --- a/tests/phpunit/languages/LanguageHsbTest.php +++ b/tests/phpunit/languages/LanguageHsbTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageHsb.php */ class LanguageHsbTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'two', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -28,5 +38,4 @@ class LanguageHsbTest extends LanguageClassesTestCase { array( 'other', 555 ), ); } - } diff --git a/tests/phpunit/languages/LanguageHuTest.php b/tests/phpunit/languages/LanguageHuTest.php index 23d8e0ce..ee9197d7 100644 --- a/tests/phpunit/languages/LanguageHuTest.php +++ b/tests/phpunit/languages/LanguageHuTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/LanguageHu.php */ class LanguageHuTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -22,5 +32,4 @@ class LanguageHuTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageHyTest.php b/tests/phpunit/languages/LanguageHyTest.php index 7088d37b..896522b0 100644 --- a/tests/phpunit/languages/LanguageHyTest.php +++ b/tests/phpunit/languages/LanguageHyTest.php @@ -7,14 +7,25 @@ /** Tests for MediaWiki languages/LanguageHy.php */ class LanguageHyTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + // This fails for 0, but I'm not sure why. Some voodoo going on here. + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -22,5 +33,4 @@ class LanguageHyTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageKshTest.php b/tests/phpunit/languages/LanguageKshTest.php index 9b4a53ad..568a3780 100644 --- a/tests/phpunit/languages/LanguageKshTest.php +++ b/tests/phpunit/languages/LanguageKshTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageKsh.php */ class LanguageKshTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other', 'zero' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'zero', 0 ), array( 'one', 1 ), @@ -22,5 +32,4 @@ class LanguageKshTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageLnTest.php b/tests/phpunit/languages/LanguageLnTest.php index 669d8b0a..10b3234f 100644 --- a/tests/phpunit/languages/LanguageLnTest.php +++ b/tests/phpunit/languages/LanguageLnTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageLn.php */ class LanguageLnTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), @@ -22,5 +32,4 @@ class LanguageLnTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageLtTest.php b/tests/phpunit/languages/LanguageLtTest.php index 9d6428b8..30642f62 100644 --- a/tests/phpunit/languages/LanguageLtTest.php +++ b/tests/phpunit/languages/LanguageLtTest.php @@ -7,20 +7,24 @@ /** Tests for MediaWiki languages/LanguageLt.php */ class LanguageLtTest extends LanguageClassesTestCase { - - /** @dataProvider provideOneFewOtherCases */ - function testOneFewOtherPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - /** @dataProvider provideOneFewCases */ - function testOneFewPlural( $result, $value ) { - $forms = array( 'one', 'few' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); } - function provideOneFewOtherCases() { + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -36,10 +40,24 @@ class LanguageLtTest extends LanguageClassesTestCase { ); } - function provideOneFewCases() { + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testOneFewPlural( $result, $value ) { + $forms = array( 'one', 'other' ); + // This fails for 21, but not sure why. + $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); + } + + public static function providePluralTwoForms() { return array( array( 'one', 1 ), - array( 'few', 15 ), + array( 'other', 2 ), + array( 'other', 15 ), + array( 'other', 20 ), + array( 'one', 21 ), + array( 'other', 22 ), ); } } diff --git a/tests/phpunit/languages/LanguageLvTest.php b/tests/phpunit/languages/LanguageLvTest.php index bd0c759b..c4d8a6f0 100644 --- a/tests/phpunit/languages/LanguageLvTest.php +++ b/tests/phpunit/languages/LanguageLvTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageLv.php */ class LanguageLvTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'zero', 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'zero', 0 ), array( 'one', 1 ), @@ -27,5 +37,4 @@ class LanguageLvTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageMgTest.php b/tests/phpunit/languages/LanguageMgTest.php index c1e516bc..65e8fd7b 100644 --- a/tests/phpunit/languages/LanguageMgTest.php +++ b/tests/phpunit/languages/LanguageMgTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageMg.php */ class LanguageMgTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), @@ -23,5 +33,4 @@ class LanguageMgTest extends LanguageClassesTestCase { array( 'other', 123.3434 ), ); } - } diff --git a/tests/phpunit/languages/LanguageMkTest.php b/tests/phpunit/languages/LanguageMkTest.php index 5c241ba7..7d47b375 100644 --- a/tests/phpunit/languages/LanguageMkTest.php +++ b/tests/phpunit/languages/LanguageMkTest.php @@ -7,27 +7,34 @@ /** Tests for MediaWiki languages/classes/LanguageMk.php */ class LanguageMkTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } - function providerPlural() { + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), array( 'other', 11 ), array( 'one', 21 ), - array( 'other', 411 ), + array( 'one', 411 ), array( 'other', 12.345 ), array( 'other', 20 ), array( 'one', 31 ), array( 'other', 200 ), ); } - - } diff --git a/tests/phpunit/languages/LanguageMlTest.php b/tests/phpunit/languages/LanguageMlTest.php index 396114d9..4fa45ce3 100644 --- a/tests/phpunit/languages/LanguageMlTest.php +++ b/tests/phpunit/languages/LanguageMlTest.php @@ -8,13 +8,16 @@ /** Tests for MediaWiki languages/LanguageMl.php */ class LanguageMlTest extends LanguageClassesTestCase { - /** see bug 29495 */ - /** @dataProvider providerFormatNum */ - function testFormatNum( $result, $value ) { + /** + * @dataProvider providerFormatNum + * @see bug 29495 + * @covers Language::formatNum + */ + public function testFormatNum( $result, $value ) { $this->assertEquals( $result, $this->getLang()->formatNum( $value ) ); } - function providerFormatNum() { + public static function providerFormatNum() { return array( array( '12,34,567', '1234567' ), array( '12,345', '12345' ), diff --git a/tests/phpunit/languages/LanguageMoTest.php b/tests/phpunit/languages/LanguageMoTest.php index f7da1cd6..e0e54ca8 100644 --- a/tests/phpunit/languages/LanguageMoTest.php +++ b/tests/phpunit/languages/LanguageMoTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageMo.php */ class LanguageMoTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'few', 0 ), array( 'one', 1 ), diff --git a/tests/phpunit/languages/LanguageMtTest.php b/tests/phpunit/languages/LanguageMtTest.php index f2b881e7..96d2bc92 100644 --- a/tests/phpunit/languages/LanguageMtTest.php +++ b/tests/phpunit/languages/LanguageMtTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageMt.php */ class LanguageMtTest extends LanguageClassesTestCase { - - /** @dataProvider providerPluralAllForms */ - function testPluralAllForms( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPluralAllForms() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'few', 0 ), array( 'one', 1 ), @@ -35,30 +45,33 @@ class LanguageMtTest extends LanguageClassesTestCase { ); } - /** @dataProvider providerPluralTwoForms */ - function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'many' ); + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPluralTwoForms() { + public static function providePluralTwoForms() { return array( - array( 'many', 0 ), + array( 'other', 0 ), array( 'one', 1 ), - array( 'many', 2 ), - array( 'many', 10 ), - array( 'many', 11 ), - array( 'many', 19 ), - array( 'many', 20 ), - array( 'many', 99 ), - array( 'many', 100 ), - array( 'many', 101 ), - array( 'many', 102 ), - array( 'many', 110 ), - array( 'many', 111 ), - array( 'many', 119 ), - array( 'many', 120 ), - array( 'many', 201 ), + array( 'other', 2 ), + array( 'other', 10 ), + array( 'other', 11 ), + array( 'other', 19 ), + array( 'other', 20 ), + array( 'other', 99 ), + array( 'other', 100 ), + array( 'other', 101 ), + array( 'other', 102 ), + array( 'other', 110 ), + array( 'other', 111 ), + array( 'other', 119 ), + array( 'other', 120 ), + array( 'other', 201 ), ); } } diff --git a/tests/phpunit/languages/LanguageNlTest.php b/tests/phpunit/languages/LanguageNlTest.php index f783f2c0..26bd691a 100644 --- a/tests/phpunit/languages/LanguageNlTest.php +++ b/tests/phpunit/languages/LanguageNlTest.php @@ -8,7 +8,11 @@ /** Tests for MediaWiki languages/LanguageNl.php */ class LanguageNlTest extends LanguageClassesTestCase { - function testFormatNum() { + /** + * @covers Language::formatNum + * @todo split into a test and a dataprovider + */ + public function testFormatNum() { $this->assertEquals( '1.234.567', $this->getLang()->formatNum( '1234567' ) ); $this->assertEquals( '12.345', $this->getLang()->formatNum( '12345' ) ); $this->assertEquals( '1', $this->getLang()->formatNum( '1' ) ); diff --git a/tests/phpunit/languages/LanguageNsoTest.php b/tests/phpunit/languages/LanguageNsoTest.php index 9d80d138..18efd736 100644 --- a/tests/phpunit/languages/LanguageNsoTest.php +++ b/tests/phpunit/languages/LanguageNsoTest.php @@ -7,18 +7,28 @@ /** Tests for MediaWiki languages/classes/LanguageNso.php */ class LanguageNsoTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), - array( 'many', 2 ), + array( 'other', 2 ), ); } } diff --git a/tests/phpunit/languages/LanguagePlTest.php b/tests/phpunit/languages/LanguagePlTest.php index 1e36097b..d180037b 100644 --- a/tests/phpunit/languages/LanguagePlTest.php +++ b/tests/phpunit/languages/LanguagePlTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguagePl.php */ class LanguagePlTest extends LanguageClassesTestCase { - - /** @dataProvider providerPluralFourForms */ - function testPluralFourForms( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPluralFourForms() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'many', 0 ), array( 'one', 1 ), @@ -35,30 +45,33 @@ class LanguagePlTest extends LanguageClassesTestCase { ); } - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + public static function providePluralTwoForms() { return array( - array( 'many', 0 ), + array( 'other', 0 ), array( 'one', 1 ), - array( 'many', 2 ), - array( 'many', 3 ), - array( 'many', 4 ), - array( 'many', 5 ), - array( 'many', 9 ), - array( 'many', 10 ), - array( 'many', 11 ), - array( 'many', 21 ), - array( 'many', 22 ), - array( 'many', 23 ), - array( 'many', 24 ), - array( 'many', 25 ), - array( 'many', 200 ), - array( 'many', 201 ), + array( 'other', 2 ), + array( 'other', 3 ), + array( 'other', 4 ), + array( 'other', 5 ), + array( 'other', 9 ), + array( 'other', 10 ), + array( 'other', 11 ), + array( 'other', 21 ), + array( 'other', 22 ), + array( 'other', 23 ), + array( 'other', 24 ), + array( 'other', 25 ), + array( 'other', 200 ), + array( 'other', 201 ), ); } } diff --git a/tests/phpunit/languages/LanguageRoTest.php b/tests/phpunit/languages/LanguageRoTest.php index 916ea45d..ae7816bc 100644 --- a/tests/phpunit/languages/LanguageRoTest.php +++ b/tests/phpunit/languages/LanguageRoTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageRo.php */ class LanguageRoTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'few', 0 ), array( 'one', 1 ), diff --git a/tests/phpunit/languages/LanguageRuTest.php b/tests/phpunit/languages/LanguageRuTest.php index 0792f75b..e938be79 100644 --- a/tests/phpunit/languages/LanguageRuTest.php +++ b/tests/phpunit/languages/LanguageRuTest.php @@ -8,14 +8,24 @@ /** Tests for MediaWiki languages/classes/LanguageRu.php */ class LanguageRuTest extends LanguageClassesTestCase { - - /** @dataProvider providePluralFourForms */ - function testPluralFourForms( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralFourForms() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 1 ), array( 'many', 11 ), @@ -31,27 +41,33 @@ class LanguageRuTest extends LanguageClassesTestCase { ); } - /** @dataProvider providePluralTwoForms */ - function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'several' ); + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralTwoForms() { + public static function providePluralTwoForms() { return array( array( 'one', 1 ), - array( 'several', 11 ), - array( 'several', 91 ), - array( 'several', 121 ), + array( 'other', 11 ), + array( 'other', 91 ), + array( 'other', 121 ), ); } - /** @dataProvider providerGrammar */ - function testGrammar( $result, $word, $case ) { + /** + * @dataProvider providerGrammar + * @covers Language::convertGrammar + */ + public function testGrammar( $result, $word, $case ) { $this->assertEquals( $result, $this->getLang()->convertGrammar( $word, $case ) ); } - function providerGrammar() { + public static function providerGrammar() { return array( array( 'Википедии', diff --git a/tests/phpunit/languages/LanguageSeTest.php b/tests/phpunit/languages/LanguageSeTest.php index c7dd8020..533aa2bc 100644 --- a/tests/phpunit/languages/LanguageSeTest.php +++ b/tests/phpunit/languages/LanguageSeTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageSe.php */ class LanguageSeTest extends LanguageClassesTestCase { - - /** @dataProvider providerPluralThreeForms */ - function testPluralThreeForms( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'two', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPluralThreeForms() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -23,13 +33,16 @@ class LanguageSeTest extends LanguageClassesTestCase { ); } - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + public static function providePluralTwoForms() { return array( array( 'other', 0 ), array( 'one', 1 ), diff --git a/tests/phpunit/languages/LanguageSgsTest.php b/tests/phpunit/languages/LanguageSgsTest.php index 95e63462..bf6a14b1 100644 --- a/tests/phpunit/languages/LanguageSgsTest.php +++ b/tests/phpunit/languages/LanguageSgsTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageSgs.php */ class LanguageSgsTest extends LanguageClassesTestCase { - - /** @dataProvider providePluralAllForms */ - function testPluralAllForms( $result, $value ) { + /** + * @dataProvider providePluralAllForms + * @covers Language::convertPlural + */ + public function testPluralAllForms( $result, $value ) { $forms = array( 'one', 'two', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralAllForms() { + /** + * @dataProvider providePluralAllForms + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePluralAllForms() { return array( array( 'few', 0 ), array( 'one', 1 ), @@ -32,13 +42,16 @@ class LanguageSgsTest extends LanguageClassesTestCase { ); } - /** @dataProvider providePluralTwoForms */ - function testPluralTwoForms( $result, $value ) { + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralTwoForms() { + public static function providePluralTwoForms() { return array( array( 'other', 0 ), array( 'one', 1 ), diff --git a/tests/phpunit/languages/LanguageShTest.php b/tests/phpunit/languages/LanguageShTest.php index 282fd2f2..6d2e25a6 100644 --- a/tests/phpunit/languages/LanguageShTest.php +++ b/tests/phpunit/languages/LanguageShTest.php @@ -7,18 +7,36 @@ /** Tests for MediaWiki languages/classes/LanguageSh.php */ class LanguageShTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { + $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'many', 0 ), array( 'one', 1 ), - array( 'many', 2 ), + array( 'few', 2 ), + array( 'few', 4 ), + array( 'many', 5 ), + array( 'many', 10 ), + array( 'many', 11 ), + array( 'many', 12 ), + array( 'one', 101 ), + array( 'few', 102 ), + array( 'many', 111 ), ); } } diff --git a/tests/phpunit/languages/LanguageSkTest.php b/tests/phpunit/languages/LanguageSkTest.php index 89cbbf01..cb8a13b8 100644 --- a/tests/phpunit/languages/LanguageSkTest.php +++ b/tests/phpunit/languages/LanguageSkTest.php @@ -8,14 +8,24 @@ /** Tests for MediaWiki languages/classes/LanguageSk.php */ class LanguageSkTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), diff --git a/tests/phpunit/languages/LanguageSlTest.php b/tests/phpunit/languages/LanguageSlTest.php index 075e6af3..9783dd80 100644 --- a/tests/phpunit/languages/LanguageSlTest.php +++ b/tests/phpunit/languages/LanguageSlTest.php @@ -8,16 +8,26 @@ /** Tests for MediaWiki languages/classes/LanguageSl.php */ class LanguageSlTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'two', 'few', 'other', 'zero' ); + /** + * @dataProvider providerPlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { + $forms = array( 'one', 'two', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providerPlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providerPlural() { return array( - array( 'zero', 0 ), + array( 'other', 0 ), array( 'one', 1 ), array( 'two', 2 ), array( 'few', 3 ), diff --git a/tests/phpunit/languages/LanguageSmaTest.php b/tests/phpunit/languages/LanguageSmaTest.php index 6d655219..95cb333c 100644 --- a/tests/phpunit/languages/LanguageSmaTest.php +++ b/tests/phpunit/languages/LanguageSmaTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageSma.php */ class LanguageSmaTest extends LanguageClassesTestCase { - - /** @dataProvider providerPluralThreeForms */ - function testPluralThreeForms( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'two', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPluralThreeForms() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -23,13 +33,16 @@ class LanguageSmaTest extends LanguageClassesTestCase { ); } - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + public static function providePluralTwoForms() { return array( array( 'other', 0 ), array( 'one', 1 ), diff --git a/tests/phpunit/languages/LanguageSrTest.php b/tests/phpunit/languages/LanguageSrTest.php index 5611030b..ab4d4aba 100644 --- a/tests/phpunit/languages/LanguageSrTest.php +++ b/tests/phpunit/languages/LanguageSrTest.php @@ -10,16 +10,18 @@ * @author Antoine Musso <hashar at free dot fr> * @copyright Copyright © 2011, Antoine Musso <hashar at free dot fr> * @file + * + * @todo methods in test class should be tidied: + * - Should be split into separate test methods and data providers + * - Tests for LanguageConverter and Language should probably be separate.. */ -require_once dirname( __DIR__ ) . '/bootstrap.php'; - /** Tests for MediaWiki languages/LanguageSr.php */ class LanguageSrTest extends LanguageClassesTestCase { - - ##### TESTS ####################################################### - - function testEasyConversions() { + /** + * @covers LanguageConverter::convertTo + */ + public function testEasyConversions() { $this->assertCyrillic( 'шђчћжШЂЧЋЖ', 'Cyrillic guessing characters' @@ -30,7 +32,10 @@ class LanguageSrTest extends LanguageClassesTestCase { ); } - function testMixedConversions() { + /** + * @covers LanguageConverter::convertTo + */ + public function testMixedConversions() { $this->assertCyrillic( 'шђчћжШЂЧЋЖ - šđčćž', 'Mostly cyrillic characters' @@ -41,7 +46,10 @@ class LanguageSrTest extends LanguageClassesTestCase { ); } - function testSameAmountOfLatinAndCyrillicGetConverted() { + /** + * @covers LanguageConverter::convertTo + */ + public function testSameAmountOfLatinAndCyrillicGetConverted() { $this->assertConverted( '4 latin: šđčć | 4 cyrillic: шђчћ', 'sr-ec' @@ -54,8 +62,9 @@ class LanguageSrTest extends LanguageClassesTestCase { /** * @author Nikola Smolenski + * @covers LanguageConverter::convertTo */ - function testConversionToCyrillic() { + public function testConversionToCyrillic() { //A simple convertion of Latin to Cyrillic $this->assertEquals( 'абвг', $this->convertToCyrillic( 'abvg' ) @@ -94,7 +103,10 @@ class LanguageSrTest extends LanguageClassesTestCase { ); } - function testConversionToLatin() { + /** + * @covers LanguageConverter::convertTo + */ + public function testConversionToLatin() { //A simple convertion of Latin to Latin $this->assertEquals( 'abcd', $this->convertToLatin( 'abcd' ) @@ -113,13 +125,24 @@ class LanguageSrTest extends LanguageClassesTestCase { ); } - /** @dataProvider providePluralFourForms */ - function testPluralFourForms( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralFourForms() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 1 ), array( 'many', 11 ), @@ -135,18 +158,21 @@ class LanguageSrTest extends LanguageClassesTestCase { ); } - /** @dataProvider providePluralTwoForms */ - function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'several' ); + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralTwoForms() { + public static function providePluralTwoForms() { return array( array( 'one', 1 ), - array( 'several', 11 ), - array( 'several', 91 ), - array( 'several', 121 ), + array( 'other', 11 ), + array( 'other', 91 ), + array( 'other', 121 ), ); } @@ -157,7 +183,7 @@ class LanguageSrTest extends LanguageClassesTestCase { * @param $variant string Language variant 'sr-ec' or 'sr-el' * @param $msg string Optional message */ - function assertUnConverted( $text, $variant, $msg = '' ) { + protected function assertUnConverted( $text, $variant, $msg = '' ) { $this->assertEquals( $text, $this->convertTo( $text, $variant ), @@ -171,7 +197,7 @@ class LanguageSrTest extends LanguageClassesTestCase { * @param $variant string Language variant 'sr-ec' or 'sr-el' * @param $msg string Optional message */ - function assertConverted( $text, $variant, $msg = '' ) { + protected function assertConverted( $text, $variant, $msg = '' ) { $this->assertNotEquals( $text, $this->convertTo( $text, $variant ), @@ -184,7 +210,7 @@ class LanguageSrTest extends LanguageClassesTestCase { * using the cyrillic variant and converted to Latin when using * the Latin variant. */ - function assertCyrillic( $text, $msg = '' ) { + protected function assertCyrillic( $text, $msg = '' ) { $this->assertUnConverted( $text, 'sr-ec', $msg ); $this->assertConverted( $text, 'sr-el', $msg ); } @@ -194,26 +220,26 @@ class LanguageSrTest extends LanguageClassesTestCase { * using the Latin variant and converted to Cyrillic when using * the Cyrillic variant. */ - function assertLatin( $text, $msg = '' ) { + protected function assertLatin( $text, $msg = '' ) { $this->assertUnConverted( $text, 'sr-el', $msg ); $this->assertConverted( $text, 'sr-ec', $msg ); } /** Wrapper for converter::convertTo() method*/ - function convertTo( $text, $variant ) { + protected function convertTo( $text, $variant ) { return $this->getLang() ->mConverter ->convertTo( - $text, $variant - ); + $text, $variant + ); } - function convertToCyrillic( $text ) { + protected function convertToCyrillic( $text ) { return $this->convertTo( $text, 'sr-ec' ); } - function convertToLatin( $text ) { + protected function convertToLatin( $text ) { return $this->convertTo( $text, 'sr-el' ); } } diff --git a/tests/phpunit/languages/LanguageTest.php b/tests/phpunit/languages/LanguageTest.php index 76471445..78929e23 100644 --- a/tests/phpunit/languages/LanguageTest.php +++ b/tests/phpunit/languages/LanguageTest.php @@ -1,8 +1,11 @@ <?php class LanguageTest extends LanguageClassesTestCase { - - function testLanguageConvertDoubleWidthToSingleWidth() { + /** + * @covers Language::convertDoubleWidth + * @covers Language::normalizeForSearch + */ + public function testLanguageConvertDoubleWidthToSingleWidth() { $this->assertEquals( "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", $this->getLang()->normalizeForSearch( @@ -13,13 +16,14 @@ class LanguageTest extends LanguageClassesTestCase { } /** - * @dataProvider provideFormattableTimes + * @dataProvider provideFormattableTimes# + * @covers Language::formatTimePeriod */ - function testFormatTimePeriod( $seconds, $format, $expected, $desc ) { + public function testFormatTimePeriod( $seconds, $format, $expected, $desc ) { $this->assertEquals( $expected, $this->getLang()->formatTimePeriod( $seconds, $format ), $desc ); } - function provideFormattableTimes() { + public static function provideFormattableTimes() { return array( array( 9.45, @@ -202,10 +206,12 @@ class LanguageTest extends LanguageClassesTestCase { 'formatTimePeriod() rounding, recursion, (>48h)' ), ); - } - function testTruncate() { + /** + * @covers Language::truncate + */ + public function testTruncate() { $this->assertEquals( "XXX", $this->getLang()->truncate( "1234567890", 0, 'XXX' ), @@ -238,9 +244,10 @@ class LanguageTest extends LanguageClassesTestCase { } /** - * @dataProvider provideHTMLTruncateData() + * @dataProvider provideHTMLTruncateData + * @covers Language::truncateHTML */ - function testTruncateHtml( $len, $ellipsis, $input, $expected ) { + public function testTruncateHtml( $len, $ellipsis, $input, $expected ) { // Actual HTML... $this->assertEquals( $expected, @@ -249,9 +256,9 @@ class LanguageTest extends LanguageClassesTestCase { } /** - * Array format is ($len, $ellipsis, $input, $expected) + * @return array format is ($len, $ellipsis, $input, $expected) */ - function provideHTMLTruncateData() { + public static function provideHTMLTruncateData() { return array( array( 0, 'XXX', "1234567890", "XXX" ), array( 8, 'XXX', "1234567890", "12345XXX" ), @@ -310,8 +317,9 @@ class LanguageTest extends LanguageClassesTestCase { /** * Test Language::isWellFormedLanguageTag() * @dataProvider provideWellFormedLanguageTags + * @covers Language::isWellFormedLanguageTag */ - function testWellFormedLanguageTag( $code, $message = '' ) { + public function testWellFormedLanguageTag( $code, $message = '' ) { $this->assertTrue( Language::isWellFormedLanguageTag( $code ), "validating code $code $message" @@ -324,7 +332,7 @@ class LanguageTest extends LanguageClassesTestCase { * and distributed as free software, under the GNU General Public Licence. * http://www.bortzmeyer.org/gabuzomeu-parsing-language-tags.html */ - function provideWellFormedLanguageTags() { + public static function provideWellFormedLanguageTags() { return array( array( 'fr', 'two-letter code' ), array( 'fr-latn', 'two-letter code with lower case script code' ), @@ -361,8 +369,9 @@ class LanguageTest extends LanguageClassesTestCase { /** * Negative test for Language::isWellFormedLanguageTag() * @dataProvider provideMalformedLanguageTags + * @covers Language::isWellFormedLanguageTag */ - function testMalformedLanguageTag( $code, $message = '' ) { + public function testMalformedLanguageTag( $code, $message = '' ) { $this->assertFalse( Language::isWellFormedLanguageTag( $code ), "validating that code $code is a malformed language tag - $message" @@ -375,7 +384,7 @@ class LanguageTest extends LanguageClassesTestCase { * and distributed as free software, under the GNU General Public Licence. * http://www.bortzmeyer.org/gabuzomeu-parsing-language-tags.html */ - function provideMalformedLanguageTags() { + public static function provideMalformedLanguageTags() { return array( array( 'f', 'language too short' ), array( 'f-Latn', 'language too short with script' ), @@ -411,8 +420,9 @@ class LanguageTest extends LanguageClassesTestCase { /** * Negative test for Language::isWellFormedLanguageTag() + * @covers Language::isWellFormedLanguageTag */ - function testLenientLanguageTag() { + public function testLenientLanguageTag() { $this->assertTrue( Language::isWellFormedLanguageTag( 'pa_guru', true ), 'pa_guru is a well-formed language tag in lenient mode' @@ -422,22 +432,26 @@ class LanguageTest extends LanguageClassesTestCase { /** * Test Language::isValidBuiltInCode() * @dataProvider provideLanguageCodes + * @covers Language::isValidBuiltInCode */ - function testBuiltInCodeValidation( $code, $message = '' ) { + public function testBuiltInCodeValidation( $code, $message = '' ) { $this->assertTrue( (bool)Language::isValidBuiltInCode( $code ), "validating code $code $message" ); } - function testBuiltInCodeValidationRejectUnderscore() { + /** + * @covers Language::isValidBuiltInCode + */ + public function testBuiltInCodeValidationRejectUnderscore() { $this->assertFalse( (bool)Language::isValidBuiltInCode( 'be_tarask' ), "reject underscore in language code" ); } - function provideLanguageCodes() { + public static function provideLanguageCodes() { return array( array( 'fr', 'Two letters, minor case' ), array( 'EN', 'Two letters, upper case' ), @@ -452,15 +466,16 @@ class LanguageTest extends LanguageClassesTestCase { /** * Test Language::isKnownLanguageTag() * @dataProvider provideKnownLanguageTags + * @covers Language::isKnownLanguageTag */ - function testKnownLanguageTag( $code, $message = '' ) { + public function testKnownLanguageTag( $code, $message = '' ) { $this->assertTrue( (bool)Language::isKnownLanguageTag( $code ), "validating code $code - $message" ); } - function provideKnownLanguageTags() { + public static function provideKnownLanguageTags() { return array( array( 'fr', 'simple code' ), array( 'bat-smg', 'an MW legacy tag' ), @@ -469,9 +484,9 @@ class LanguageTest extends LanguageClassesTestCase { } /** - * Test Language::isKnownLanguageTag() + * @covers Language::isKnownLanguageTag */ - function testKnownCldrLanguageTag() { + public function testKnownCldrLanguageTag() { if ( !class_exists( 'LanguageNames' ) ) { $this->markTestSkipped( 'The LanguageNames class is not available. The cldr extension is probably not installed.' ); } @@ -485,24 +500,54 @@ class LanguageTest extends LanguageClassesTestCase { /** * Negative tests for Language::isKnownLanguageTag() * @dataProvider provideUnKnownLanguageTags + * @covers Language::isKnownLanguageTag */ - function testUnknownLanguageTag( $code, $message = '' ) { + public function testUnknownLanguageTag( $code, $message = '' ) { $this->assertFalse( (bool)Language::isKnownLanguageTag( $code ), "checking that code $code is invalid - $message" ); } - function provideUnknownLanguageTags() { + public static function provideUnknownLanguageTags() { return array( array( 'mw', 'non-existent two-letter code' ), + array( 'foo"<bar', 'very invalid language code' ), ); } /** + * Test too short timestamp + * @expectedException MWException + * @covers Language::sprintfDate + */ + public function testSprintfDateTooShortTimestamp() { + $this->getLang()->sprintfDate( 'xiY', '1234567890123' ); + } + + /** + * Test too long timestamp + * @expectedException MWException + * @covers Language::sprintfDate + */ + public function testSprintfDateTooLongTimestamp() { + $this->getLang()->sprintfDate( 'xiY', '123456789012345' ); + } + + /** + * Test too short timestamp + * @expectedException MWException + * @covers Language::sprintfDate + */ + public function testSprintfDateNotAllDigitTimestamp() { + $this->getLang()->sprintfDate( 'xiY', '-1234567890123' ); + } + + /** * @dataProvider provideSprintfDateSamples + * @covers Language::sprintfDate */ - function testSprintfDate( $format, $ts, $expected, $msg ) { + public function testSprintfDate( $format, $ts, $expected, $msg ) { $this->assertEquals( $expected, $this->getLang()->sprintfDate( $format, $ts ), @@ -511,10 +556,11 @@ class LanguageTest extends LanguageClassesTestCase { } /** - * bug 33454. sprintfDate should always use UTC. + * sprintfDate should always use UTC when no zone is given. * @dataProvider provideSprintfDateSamples + * @covers Language::sprintfDate */ - function testSprintfDateTZ( $format, $ts, $expected, $msg ) { + public function testSprintfDateNoZone( $format, $ts, $expected, $ignore, $msg ) { $oldTZ = date_default_timezone_get(); $res = date_default_timezone_set( 'Asia/Seoul' ); if ( !$res ) { @@ -530,42 +576,66 @@ class LanguageTest extends LanguageClassesTestCase { date_default_timezone_set( $oldTZ ); } - function provideSprintfDateSamples() { + /** + * sprintfDate should use passed timezone + * @dataProvider provideSprintfDateSamples + * @covers Language::sprintfDate + */ + public function testSprintfDateTZ( $format, $ts, $ignore, $expected, $msg ) { + $tz = new DateTimeZone( 'Asia/Seoul' ); + if ( !$tz ) { + $this->markTestSkipped( "Error getting Timezone" ); + } + + $this->assertEquals( + $expected, + $this->getLang()->sprintfDate( $format, $ts, $tz ), + "sprintfDate('$format', '$ts', 'Asia/Seoul'): $msg" + ); + } + + public static function provideSprintfDateSamples() { return array( array( 'xiY', '20111212000000', '1390', // note because we're testing English locale we get Latin-standard digits + '1390', 'Iranian calendar full year' ), array( 'xiy', '20111212000000', '90', + '90', 'Iranian calendar short year' ), array( 'o', '20120101235000', '2011', + '2011', 'ISO 8601 (week) year' ), array( 'W', '20120101235000', '52', + '52', 'Week number' ), array( 'W', '20120102235000', '1', + '1', 'Week number' ), array( 'o-\\WW-N', '20091231235000', '2009-W53-4', + '2009-W53-4', 'leap week' ), // What follows is mostly copied from http://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time @@ -573,252 +643,336 @@ class LanguageTest extends LanguageClassesTestCase { 'Y', '20120102090705', '2012', + '2012', 'Full year' ), array( 'y', '20120102090705', '12', + '12', '2 digit year' ), array( 'L', '20120102090705', '1', + '1', 'Leap year' ), array( 'n', '20120102090705', '1', + '1', 'Month index, not zero pad' ), array( 'N', '20120102090705', '01', + '01', 'Month index. Zero pad' ), array( 'M', '20120102090705', 'Jan', + 'Jan', 'Month abbrev' ), array( 'F', '20120102090705', 'January', + 'January', 'Full month' ), array( 'xg', '20120102090705', 'January', + 'January', 'Genitive month name (same in EN)' ), array( 'j', '20120102090705', '2', + '2', 'Day of month (not zero pad)' ), array( 'd', '20120102090705', '02', + '02', 'Day of month (zero-pad)' ), array( 'z', '20120102090705', '1', + '1', 'Day of year (zero-indexed)' ), array( 'D', '20120102090705', 'Mon', + 'Mon', 'Day of week (abbrev)' ), array( 'l', '20120102090705', 'Monday', + 'Monday', 'Full day of week' ), array( 'N', '20120101090705', '7', + '7', 'Day of week (Mon=1, Sun=7)' ), array( 'w', '20120101090705', '0', + '0', 'Day of week (Sun=0, Sat=6)' ), array( 'N', '20120102090705', '1', + '1', 'Day of week' ), array( 'a', '20120102090705', 'am', + 'am', 'am vs pm' ), array( 'A', '20120102120000', 'PM', + 'PM', 'AM vs PM' ), array( 'a', '20120102000000', 'am', + 'am', 'AM vs PM' ), array( 'g', '20120102090705', '9', + '9', '12 hour, not Zero' ), array( 'h', '20120102090705', '09', + '09', '12 hour, zero padded' ), array( 'G', '20120102090705', '9', + '9', '24 hour, not zero' ), array( 'H', '20120102090705', '09', + '09', '24 hour, zero' ), array( 'H', '20120102110705', '11', + '11', '24 hour, zero' ), array( 'i', '20120102090705', '07', + '07', 'Minutes' ), array( 's', '20120102090705', '05', + '05', 'seconds' ), array( 'U', '20120102090705', '1325495225', + '1325462825', 'unix time' ), array( 't', '20120102090705', '31', + '31', 'Days in current month' ), array( 'c', '20120102090705', '2012-01-02T09:07:05+00:00', + '2012-01-02T09:07:05+09:00', 'ISO 8601 timestamp' ), array( 'r', '20120102090705', 'Mon, 02 Jan 2012 09:07:05 +0000', + 'Mon, 02 Jan 2012 09:07:05 +0900', 'RFC 5322' ), array( + 'e', + '20120102090705', + 'UTC', + 'Asia/Seoul', + 'Timezone identifier' + ), + array( + 'I', + '19880602090705', + '0', + '1', + 'DST indicator' + ), + array( + 'O', + '20120102090705', + '+0000', + '+0900', + 'Timezone offset' + ), + array( + 'P', + '20120102090705', + '+00:00', + '+09:00', + 'Timezone offset with colon' + ), + array( + 'T', + '20120102090705', + 'UTC', + 'KST', + 'Timezone abbreviation' + ), + array( + 'Z', + '20120102090705', + '0', + '32400', + 'Timezone offset in seconds' + ), + array( 'xmj xmF xmn xmY', '20120102090705', '7 Safar 2 1433', + '7 Safar 2 1433', 'Islamic' ), array( 'xij xiF xin xiY', '20120102090705', '12 Dey 10 1390', + '12 Dey 10 1390', 'Iranian' ), array( 'xjj xjF xjn xjY', '20120102090705', '7 Tevet 4 5772', + '7 Tevet 4 5772', 'Hebrew' ), array( 'xjt', '20120102090705', '29', + '29', 'Hebrew number of days in month' ), array( 'xjx', '20120102090705', 'Tevet', + 'Tevet', 'Hebrew genitive month name (No difference in EN)' ), array( 'xkY', '20120102090705', '2555', + '2555', 'Thai year' ), array( 'xoY', '20120102090705', '101', + '101', 'Minguo' ), array( 'xtY', '20120102090705', '平成24', + '平成24', 'nengo' ), array( 'xrxkYY', '20120102090705', 'MMDLV2012', + 'MMDLV2012', 'Roman numerals' ), array( 'xhxjYY', '20120102090705', 'ה\'תשע"ב2012', + 'ה\'תשע"ב2012', 'Hebrew numberals' ), array( 'xnY', '20120102090705', '2012', + '2012', 'Raw numerals (doesn\'t mean much in EN)' ), array( '[[Y "(yea"\\r)]] \\"xx\\"', '20120102090705', '[[2012 (year)]] "x"', + '[[2012 (year)]] "x"', 'Various escaping' ), @@ -827,8 +981,9 @@ class LanguageTest extends LanguageClassesTestCase { /** * @dataProvider provideFormatSizes + * @covers Language::formatSize */ - function testFormatSize( $size, $expected, $msg ) { + public function testFormatSize( $size, $expected, $msg ) { $this->assertEquals( $expected, $this->getLang()->formatSize( $size ), @@ -836,7 +991,7 @@ class LanguageTest extends LanguageClassesTestCase { ); } - function provideFormatSizes() { + public static function provideFormatSizes() { return array( array( 0, @@ -889,8 +1044,9 @@ class LanguageTest extends LanguageClassesTestCase { /** * @dataProvider provideFormatBitrate + * @covers Language::formatBitrate */ - function testFormatBitrate( $bps, $expected, $msg ) { + public function testFormatBitrate( $bps, $expected, $msg ) { $this->assertEquals( $expected, $this->getLang()->formatBitrate( $bps ), @@ -898,7 +1054,7 @@ class LanguageTest extends LanguageClassesTestCase { ); } - function provideFormatBitrate() { + public static function provideFormatBitrate() { return array( array( 0, @@ -961,8 +1117,9 @@ class LanguageTest extends LanguageClassesTestCase { /** * @dataProvider provideFormatDuration + * @covers Language::formatDuration */ - function testFormatDuration( $duration, $expected, $intervals = array() ) { + public function testFormatDuration( $duration, $expected, $intervals = array() ) { $this->assertEquals( $expected, $this->getLang()->formatDuration( $duration, $intervals ), @@ -970,7 +1127,7 @@ class LanguageTest extends LanguageClassesTestCase { ); } - function provideFormatDuration() { + public static function provideFormatDuration() { return array( array( 0, @@ -1097,8 +1254,9 @@ class LanguageTest extends LanguageClassesTestCase { /** * @dataProvider provideCheckTitleEncodingData + * @covers Language::checkTitleEncoding */ - function testCheckTitleEncoding( $s ) { + public function testCheckTitleEncoding( $s ) { $this->assertEquals( $s, $this->getLang()->checkTitleEncoding( $s ), @@ -1106,7 +1264,7 @@ class LanguageTest extends LanguageClassesTestCase { ); } - function provideCheckTitleEncodingData() { + public static function provideCheckTitleEncodingData() { return array( array( "" ), array( "United States of America" ), // 7bit ASCII @@ -1161,8 +1319,9 @@ class LanguageTest extends LanguageClassesTestCase { /** * @dataProvider provideRomanNumeralsData + * @covers Language::romanNumeral */ - function testRomanNumerals( $num, $numerals ) { + public function testRomanNumerals( $num, $numerals ) { $this->assertEquals( $numerals, Language::romanNumeral( $num ), @@ -1170,7 +1329,7 @@ class LanguageTest extends LanguageClassesTestCase { ); } - function provideRomanNumeralsData() { + public static function provideRomanNumeralsData() { return array( array( 1, 'I' ), array( 2, 'II' ), @@ -1219,13 +1378,14 @@ class LanguageTest extends LanguageClassesTestCase { /** * @dataProvider providePluralData + * @covers Language::convertPlural */ - function testConvertPlural( $expected, $number, $forms ) { + public function testConvertPlural( $expected, $number, $forms ) { $chosen = $this->getLang()->convertPlural( $number, $forms ); $this->assertEquals( $expected, $chosen ); } - function providePluralData() { + public static function providePluralData() { // Params are: [expected text, number given, [the plural forms]] return array( array( 'plural', 0, array( @@ -1255,6 +1415,9 @@ class LanguageTest extends LanguageClassesTestCase { array( 'other', 2, array( 'kissa=kala', '1=2=3', 'other', ) ), + array( '', 2, array( + '0=explicit zero', '1=explicit one', + ) ), ); } @@ -1262,7 +1425,7 @@ class LanguageTest extends LanguageClassesTestCase { * @covers Language::translateBlockExpiry() * @dataProvider provideTranslateBlockExpiry */ - function testTranslateBlockExpiry( $expectedData, $str, $desc ) { + public function testTranslateBlockExpiry( $expectedData, $str, $desc ) { $lang = $this->getLang(); if ( is_array( $expectedData ) ) { list( $func, $arg ) = $expectedData; @@ -1273,7 +1436,7 @@ class LanguageTest extends LanguageClassesTestCase { $this->assertEquals( $expected, $lang->translateBlockExpiry( $str ), $desc ); } - function provideTranslateBlockExpiry() { + public static function provideTranslateBlockExpiry() { return array( array( '2 hours', '2 hours', 'simple data from ipboptions' ), array( 'indefinite', 'infinite', 'infinite from ipboptions' ), @@ -1294,7 +1457,7 @@ class LanguageTest extends LanguageClassesTestCase { * @covers Language::commafy() * @dataProvider provideCommafyData */ - function testCommafy( $number, $numbersWithCommas ) { + public function testCommafy( $number, $numbersWithCommas ) { $this->assertEquals( $numbersWithCommas, $this->getLang()->commafy( $number ), @@ -1302,7 +1465,7 @@ class LanguageTest extends LanguageClassesTestCase { ); } - function provideCommafyData() { + public static function provideCommafyData() { return array( array( 1, '1' ), array( 10, '10' ), @@ -1321,7 +1484,10 @@ class LanguageTest extends LanguageClassesTestCase { ); } - function testListToText() { + /** + * @covers Language::listToText + */ + public function testListToText() { $lang = $this->getLang(); $and = $lang->getMessageFromDB( 'and' ); $s = $lang->getMessageFromDB( 'word-separator' ); @@ -1336,12 +1502,13 @@ class LanguageTest extends LanguageClassesTestCase { /** * @dataProvider provideIsSupportedLanguage + * @covers Language::isSupportedLanguage */ - function testIsSupportedLanguage( $code, $expected, $comment ) { + public function testIsSupportedLanguage( $code, $expected, $comment ) { $this->assertEquals( $expected, Language::isSupportedLanguage( $code ), $comment ); } - static function provideIsSupportedLanguage() { + public static function provideIsSupportedLanguage() { return array( array( 'en', true, 'is supported language' ), array( 'fi', true, 'is supported language' ), @@ -1349,4 +1516,52 @@ class LanguageTest extends LanguageClassesTestCase { array( 'FI', false, 'is not supported language, input should be in lower case' ), ); } + + /** + * @dataProvider provideGetParentLanguage + * @covers Language::getParentLanguage + */ + public function testGetParentLanguage( $code, $expected, $comment ) { + $lang = Language::factory( $code ); + if ( is_null( $expected ) ) { + $this->assertNull( $lang->getParentLanguage(), $comment ); + } else { + $this->assertEquals( $expected, $lang->getParentLanguage()->getCode(), $comment ); + } + } + + public static function provideGetParentLanguage() { + return array( + array( 'zh-cn', 'zh', 'zh is the parent language of zh-cn' ), + array( 'zh', 'zh', 'zh is defined as the parent language of zh, because zh converter can convert zh-cn to zh' ), + array( 'zh-invalid', null, 'do not be fooled by arbitrarily composed language codes' ), + array( 'en-gb', null, 'en does not have converter' ), + array( 'en', null, 'en does not have converter. Although FakeConverter handles en -> en conversion but it is useless' ), + ); + } + + /** + * @dataProvider provideGetNamespaceAliases + * @covers Language::getNamespaceAliases + */ + public function testGetNamespaceAliases( $languageCode, $subset ) { + $language = Language::factory( $languageCode ); + $aliases = $language->getNamespaceAliases(); + foreach ( $subset as $alias => $nsId ) { + $this->assertEquals( $nsId, $aliases[$alias] ); + } + } + + public static function provideGetNamespaceAliases() { + // TODO: Add tests for NS_PROJECT_TALK and GenderNamespaces + return array( + array( + 'zh', + array( + '文件' => NS_FILE, + '檔案' => NS_FILE, + ), + ), + ); + } } diff --git a/tests/phpunit/languages/LanguageTiTest.php b/tests/phpunit/languages/LanguageTiTest.php index 8af0eee2..e225af97 100644 --- a/tests/phpunit/languages/LanguageTiTest.php +++ b/tests/phpunit/languages/LanguageTiTest.php @@ -7,18 +7,28 @@ /** Tests for MediaWiki languages/classes/LanguageTi.php */ class LanguageTiTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), - array( 'many', 2 ), + array( 'other', 2 ), ); } } diff --git a/tests/phpunit/languages/LanguageTlTest.php b/tests/phpunit/languages/LanguageTlTest.php index abd8581a..7ac51c69 100644 --- a/tests/phpunit/languages/LanguageTlTest.php +++ b/tests/phpunit/languages/LanguageTlTest.php @@ -7,18 +7,28 @@ /** Tests for MediaWiki languages/classes/LanguageTl.php */ class LanguageTlTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), - array( 'many', 2 ), + array( 'other', 2 ), ); } } diff --git a/tests/phpunit/languages/LanguageTrTest.php b/tests/phpunit/languages/LanguageTrTest.php index e93d49d9..8fc2795c 100644 --- a/tests/phpunit/languages/LanguageTrTest.php +++ b/tests/phpunit/languages/LanguageTrTest.php @@ -17,7 +17,7 @@ class LanguageTrTest extends LanguageClassesTestCase { * @see http://en.wikipedia.org/wiki/Dotted_and_dotless_I * @dataProvider provideDottedAndDotlessI */ - function testDottedAndDotlessI( $func, $input, $inputCase, $expected ) { + public function testDottedAndDotlessI( $func, $input, $inputCase, $expected ) { if ( $func == 'ucfirst' ) { $res = $this->getLang()->ucfirst( $input ); } elseif ( $func == 'lcfirst' ) { @@ -31,7 +31,7 @@ class LanguageTrTest extends LanguageClassesTestCase { $this->assertEquals( $expected, $res, $msg ); } - function provideDottedAndDotlessI() { + public static function provideDottedAndDotlessI() { return array( # function, input, input case, expected # Case changed: @@ -56,5 +56,4 @@ class LanguageTrTest extends LanguageClassesTestCase { ); } - } diff --git a/tests/phpunit/languages/LanguageUkTest.php b/tests/phpunit/languages/LanguageUkTest.php index 9bbfaf66..0783fcf6 100644 --- a/tests/phpunit/languages/LanguageUkTest.php +++ b/tests/phpunit/languages/LanguageUkTest.php @@ -8,14 +8,24 @@ /** Tests for MediaWiki languages/classes/LanguageUk.php */ class LanguageUkTest extends LanguageClassesTestCase { - - /** @dataProvider providePluralFourForms */ - function testPluralFourForms( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralFourForms() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 1 ), array( 'many', 11 ), @@ -31,18 +41,21 @@ class LanguageUkTest extends LanguageClassesTestCase { ); } - /** @dataProvider providePluralTwoForms */ - function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'several' ); + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralTwoForms() { + public static function providePluralTwoForms() { return array( array( 'one', 1 ), - array( 'several', 11 ), - array( 'several', 91 ), - array( 'several', 121 ), + array( 'other', 11 ), + array( 'other', 91 ), + array( 'other', 121 ), ); } } diff --git a/tests/phpunit/languages/LanguageUzTest.php b/tests/phpunit/languages/LanguageUzTest.php index 495c0be6..13f57c16 100644 --- a/tests/phpunit/languages/LanguageUzTest.php +++ b/tests/phpunit/languages/LanguageUzTest.php @@ -10,17 +10,20 @@ * @copyright Copyright © 2012, Robin Pepermans * @copyright Copyright © 2011, Antoine Musso <hashar at free dot fr> * @file + * + * @todo methods in test class should be tidied: + * - Should be split into separate test methods and data providers + * - Tests for LanguageConverter and Language should probably be separate.. */ -require_once dirname( __DIR__ ) . '/bootstrap.php'; - /** Tests for MediaWiki languages/LanguageUz.php */ class LanguageUzTest extends LanguageClassesTestCase { /** * @author Nikola Smolenski + * @covers LanguageConverter::convertTo */ - function testConversionToCyrillic() { + public function testConversionToCyrillic() { // A convertion of Latin to Cyrillic $this->assertEquals( 'абвгғ', $this->convertToCyrillic( 'abvggʻ' ) @@ -39,7 +42,10 @@ class LanguageUzTest extends LanguageClassesTestCase { ); } - function testConversionToLatin() { + /** + * @covers LanguageConverter::convertTo + */ + public function testConversionToLatin() { // A simple convertion of Latin to Latin $this->assertEquals( 'abdef', $this->convertToLatin( 'abdef' ) @@ -57,7 +63,7 @@ class LanguageUzTest extends LanguageClassesTestCase { * @param $variant string Language variant 'uz-cyrl' or 'uz-latn' * @param $msg string Optional message */ - function assertUnConverted( $text, $variant, $msg = '' ) { + protected function assertUnConverted( $text, $variant, $msg = '' ) { $this->assertEquals( $text, $this->convertTo( $text, $variant ), @@ -71,7 +77,7 @@ class LanguageUzTest extends LanguageClassesTestCase { * @param $variant string Language variant 'uz-cyrl' or 'uz-latn' * @param $msg string Optional message */ - function assertConverted( $text, $variant, $msg = '' ) { + protected function assertConverted( $text, $variant, $msg = '' ) { $this->assertNotEquals( $text, $this->convertTo( $text, $variant ), @@ -84,7 +90,7 @@ class LanguageUzTest extends LanguageClassesTestCase { * using the cyrillic variant and converted to Latin when using * the Latin variant. */ - function assertCyrillic( $text, $msg = '' ) { + protected function assertCyrillic( $text, $msg = '' ) { $this->assertUnConverted( $text, 'uz-cyrl', $msg ); $this->assertConverted( $text, 'uz-latn', $msg ); } @@ -94,22 +100,22 @@ class LanguageUzTest extends LanguageClassesTestCase { * using the Latin variant and converted to Cyrillic when using * the Cyrillic variant. */ - function assertLatin( $text, $msg = '' ) { + protected function assertLatin( $text, $msg = '' ) { $this->assertUnConverted( $text, 'uz-latn', $msg ); $this->assertConverted( $text, 'uz-cyrl', $msg ); } /** Wrapper for converter::convertTo() method*/ - function convertTo( $text, $variant ) { + protected function convertTo( $text, $variant ) { return $this->getLang()->mConverter->convertTo( $text, $variant ); } - function convertToCyrillic( $text ) { + protected function convertToCyrillic( $text ) { return $this->convertTo( $text, 'uz-cyrl' ); } - function convertToLatin( $text ) { + protected function convertToLatin( $text ) { return $this->convertTo( $text, 'uz-latn' ); } } diff --git a/tests/phpunit/languages/LanguageWaTest.php b/tests/phpunit/languages/LanguageWaTest.php index 28329fa3..d05196c0 100644 --- a/tests/phpunit/languages/LanguageWaTest.php +++ b/tests/phpunit/languages/LanguageWaTest.php @@ -7,18 +7,28 @@ /** Tests for MediaWiki languages/classes/LanguageWa.php */ class LanguageWaTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), - array( 'many', 2 ), + array( 'other', 2 ), ); } } diff --git a/tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php b/tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php index 73d5dcc0..3bf74146 100644 --- a/tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php +++ b/tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php @@ -89,7 +89,7 @@ class CLDRPluralRuleEvaluatorTest extends MediaWikiTestCase { array( 'n', 'just n' ), array( 'n is in 5', 'is in' ), ); + return $tests; } - } diff --git a/tests/phpunit/maintenance/DumpTestCase.php b/tests/phpunit/maintenance/DumpTestCase.php index 40d24fc5..83d8c71d 100644 --- a/tests/phpunit/maintenance/DumpTestCase.php +++ b/tests/phpunit/maintenance/DumpTestCase.php @@ -60,11 +60,14 @@ abstract class DumpTestCase extends MediaWikiLangTestCase { if ( $gzipped_contents === false ) { $this->fail( "Could not get contents of $fname" ); } - // We resort to use gzinflate instead of gzdecode, as gzdecode - // need not be available - $contents = gzinflate( substr( $gzipped_contents, 10, -8 ) ); - $this->assertEquals( strlen( $contents ), - file_put_contents( $fname, $contents ), "# bytes written" ); + + $contents = gzdecode( $gzipped_contents ); + + $this->assertEquals( + strlen( $contents ), + file_put_contents( $fname, $contents ), + '# bytes written' + ); } /** @@ -73,8 +76,6 @@ abstract class DumpTestCase extends MediaWikiLangTestCase { * Clears $wgUser, and reports errors from addDBData to PHPUnit */ protected function setUp() { - global $wgUser; - parent::setUp(); // Check if any Exception is stored for rethrowing from addDBData @@ -83,7 +84,7 @@ abstract class DumpTestCase extends MediaWikiLangTestCase { throw $this->exceptionFromAddDBData; } - $wgUser = new User(); + $this->setMwGlobals( 'wgUser', new User() ); } /** @@ -116,7 +117,7 @@ abstract class DumpTestCase extends MediaWikiLangTestCase { * @param $name string: name of the closing element to look for * (e.g.: "mediawiki" when looking for </mediawiki>) * - * @return bool: true iff the end node could be found. false otherwise. + * @return bool: true if the end node could be found. false otherwise. */ protected function skipToNodeEnd( $name ) { while ( $this->xml->read() ) { @@ -126,6 +127,7 @@ abstract class DumpTestCase extends MediaWikiLangTestCase { return true; } } + return false; } @@ -147,6 +149,7 @@ abstract class DumpTestCase extends MediaWikiLangTestCase { return true; } } + return false; } @@ -273,7 +276,6 @@ abstract class DumpTestCase extends MediaWikiLangTestCase { $this->assertTextNode( "title", $name ); $this->assertTextNode( "ns", $ns ); $this->assertTextNode( "id", $id ); - } /** @@ -301,8 +303,8 @@ abstract class DumpTestCase extends MediaWikiLangTestCase { * @param $parentid int|false: (optional) id of the parent revision */ protected function assertRevision( $id, $summary, $text_id, $text_bytes, $text_sha1, $text = false, $parentid = false, - $model = CONTENT_MODEL_WIKITEXT, $format = CONTENT_FORMAT_WIKITEXT ) { - + $model = CONTENT_MODEL_WIKITEXT, $format = CONTENT_FORMAT_WIKITEXT + ) { $this->assertNodeStart( "revision" ); $this->skipWhitespace(); diff --git a/tests/phpunit/maintenance/MaintenanceTest.php b/tests/phpunit/maintenance/MaintenanceTest.php index 741f8b7f..318ce0da 100644 --- a/tests/phpunit/maintenance/MaintenanceTest.php +++ b/tests/phpunit/maintenance/MaintenanceTest.php @@ -43,7 +43,7 @@ class MaintenanceFixup extends Maintenance { private $testCase; /** - * shutdownSimulated === true iff simulateShutdown has done it's work + * shutdownSimulated === true if simulateShutdown has done it's work * * @var bool */ @@ -128,7 +128,6 @@ class MaintenanceFixup extends Maintenance { public function execute() { $this->testCase->fail( __METHOD__ . " called unexpectedly" ); } - } class MaintenanceTest extends MediaWikiTestCase { @@ -186,7 +185,6 @@ class MaintenanceTest extends MediaWikiTestCase { // test.*Intermittent.* tests), the objective of these tests is not to describe // consistent behavior, but rather currently existing behavior. - function testOutputEmpty() { $this->m->output( "" ); $this->assertOutputPrePostShutdown( "", false ); @@ -815,6 +813,4 @@ class MaintenanceTest extends MediaWikiTestCase { $m2->simulateShutdown(); $this->assertOutputPrePostShutdown( "foobar\n\n", false ); } - - } diff --git a/tests/phpunit/maintenance/backupPrefetchTest.php b/tests/phpunit/maintenance/backupPrefetchTest.php index cc00e6e5..bc2d7375 100644 --- a/tests/phpunit/maintenance/backupPrefetchTest.php +++ b/tests/phpunit/maintenance/backupPrefetchTest.php @@ -36,7 +36,6 @@ class BaseDumpTest extends MediaWikiTestCase { private function assertPrefetchEquals( $expected, $page, $revision ) { $this->assertEquals( $expected, $this->dump->prefetch( $page, $revision ), "Prefetch of page $page revision $revision" ); - } function testSequential() { @@ -181,7 +180,6 @@ class BaseDumpTest extends MediaWikiTestCase { </siteinfo> '; - // An array holding the pages that are available for prefetch $available_pages = array(); @@ -274,5 +272,4 @@ class BaseDumpTest extends MediaWikiTestCase { return $fname; } - } diff --git a/tests/phpunit/maintenance/backupTextPassTest.php b/tests/phpunit/maintenance/backupTextPassTest.php index 09623445..653a1145 100644 --- a/tests/phpunit/maintenance/backupTextPassTest.php +++ b/tests/phpunit/maintenance/backupTextPassTest.php @@ -63,7 +63,7 @@ class TextPassDumperTest extends DumpTestCase { // Page from non-default namespace if ( $ns === NS_TALK ) { - //@todo: work around this. + // @todo work around this. throw new MWException( "The default wikitext namespace is the talk namespace. " . " We can't currently deal with that." ); } @@ -80,7 +80,6 @@ class TextPassDumperTest extends DumpTestCase { // DumpTestCase $this->exceptionFromAddDBData = $e; } - } protected function setUp() { @@ -94,7 +93,6 @@ class TextPassDumperTest extends DumpTestCase { array( $this->pageId2, $this->pageId3, $this->pageId4 ), array( $this->pageId1 + 1, $this->pageId2 + 1, $this->pageId3 + 1 ), "Page ids increasing without holes" ); - } function testPlain() { @@ -214,7 +212,6 @@ class TextPassDumperTest extends DumpTestCase { $this->assertPageEnd(); $this->assertDumpEnd(); - } /** @@ -239,7 +236,6 @@ class TextPassDumperTest extends DumpTestCase { $minDuration = 2; // We want the dump to take at least this many seconds $checkpointAfter = 0.5; // Generate checkpoint after this many seconds - // Until a dump takes at least $minDuration seconds, perform a dump and check // duration. If the dump did not take long enough increase the iteration // count, to generate a bigger stub file next time. @@ -579,6 +575,7 @@ class TextPassDumperTest extends DumpTestCase { $content .= $tail; $this->assertEquals( strlen( $content ), file_put_contents( $fname, $content ), "Length of prepared stub" ); + return $fname; } } diff --git a/tests/phpunit/maintenance/backup_LogTest.php b/tests/phpunit/maintenance/backup_LogTest.php index 5cf172e6..98d81653 100644 --- a/tests/phpunit/maintenance/backup_LogTest.php +++ b/tests/phpunit/maintenance/backup_LogTest.php @@ -39,6 +39,7 @@ class BackupDumperLoggerTest extends DumpTestCase { if ( $parameters !== null ) { $logEntry->setParameters( $parameters ); } + return $logEntry->insert(); } @@ -75,14 +76,12 @@ class BackupDumperLoggerTest extends DumpTestCase { $user2, NS_MAIN, "PageA", "SomeOtherComment", array( 'key1' => 1, 3 => 'value3' ) ); $this->assertGreaterThan( 0, $this->logId3 ); - } catch ( Exception $e ) { // We'd love to pass $e directly. However, ... see // documentation of exceptionFromAddDBData in // DumpTestCase $this->exceptionFromAddDBData = $e; } - } @@ -226,5 +225,4 @@ class BackupDumperLoggerTest extends DumpTestCase { // the following statement to catch good output $this->expectOutputString( '' ); } - } diff --git a/tests/phpunit/maintenance/backup_PageTest.php b/tests/phpunit/maintenance/backup_PageTest.php index 07c76705..99bd2700 100644 --- a/tests/phpunit/maintenance/backup_PageTest.php +++ b/tests/phpunit/maintenance/backup_PageTest.php @@ -34,7 +34,7 @@ class BackupDumperPageTest extends DumpTestCase { $this->talk_namespace = NS_TALK; if ( $this->namespace === $this->talk_namespace ) { - //@todo: work around this. + // @todo work around this. throw new MWException( "The default wikitext namespace is the talk namespace. " . " We can't currently deal with that." ); } @@ -79,7 +79,6 @@ class BackupDumperPageTest extends DumpTestCase { // DumpTestCase $this->exceptionFromAddDBData = $e; } - } protected function setUp() { @@ -93,7 +92,6 @@ class BackupDumperPageTest extends DumpTestCase { array( $this->pageId2, $this->pageId3, $this->pageId4 ), array( $this->pageId1 + 1, $this->pageId2 + 1, $this->pageId3 + 1 ), "Page ids increasing without holes" ); - } function testFullTextPlain() { @@ -403,6 +401,4 @@ class BackupDumperPageTest extends DumpTestCase { $this->expectETAOutput(); } - - } diff --git a/tests/phpunit/maintenance/fetchTextTest.php b/tests/phpunit/maintenance/fetchTextTest.php index 4d1d45d6..e8df199e 100644 --- a/tests/phpunit/maintenance/fetchTextTest.php +++ b/tests/phpunit/maintenance/fetchTextTest.php @@ -63,7 +63,6 @@ class SemiMockedFetchText extends FetchText { return fopen( 'data://text/plain,' . $this->mockStdinText, 'r' ); } - } /** @@ -236,5 +235,4 @@ class FetchTextTest extends MediaWikiTestCase { $this->textId3 . "\n23\nFetchTextTestPage2Text2" ) ) ); } - } diff --git a/tests/phpunit/maintenance/getSlaveServerTest.php b/tests/phpunit/maintenance/getSlaveServerTest.php index 699571b7..2c848862 100644 --- a/tests/phpunit/maintenance/getSlaveServerTest.php +++ b/tests/phpunit/maintenance/getSlaveServerTest.php @@ -64,6 +64,4 @@ class GetSlaveServerTest extends MediaWikiTestCase { $this->expectOutputRegex( "/^[[:space:]]*\[wgDBprefix\][[:space:]]*=> " . $wgDBprefix . "$/m" ); } - - } diff --git a/tests/phpunit/mocks/filebackend/MockFSFile.php b/tests/phpunit/mocks/filebackend/MockFSFile.php new file mode 100644 index 00000000..e0463281 --- /dev/null +++ b/tests/phpunit/mocks/filebackend/MockFSFile.php @@ -0,0 +1,69 @@ +<?php +/** + * Mock of a filesystem file. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @ingroup FileBackend + */ + +/** + * Class representing an in memory fake file. + * This is intended for unit testing / developement when you do not want + * to hit the filesystem. + * + * It reimplements abstract methods with some hardcoded values. Might + * not be suitable for all tests but is good enough for the parser tests. + * + * @ingroup FileBackend + */ +class MockFSFile extends FSFile { + protected $sha1Base36 = null; // File Sha1Base36 + + public function exists() { + return true; + } + + /** + * August 22 – The theft of the Mona Lisa is discovered in the Louvre." + * @bug 20281 + */ + public function getSize() { + return 1911; + } + + public function getTimestamp() { + return wfTimestamp( TS_MW ); + } + + public function getMimeType() { + return 'text/mock'; + } + + public function getProps( $ext = true ) { + return array( + 'fileExists' => $this->exists(), + 'size' => $this->getSize(), + 'file-mime' => $this->getMimeType(), + 'sha1' => $this->getSha1Base36(), + ); + } + + public function getSha1Base36( $recache = false ) { + return '1234567890123456789012345678901'; + } +} diff --git a/tests/phpunit/mocks/filebackend/MockFileBackend.php b/tests/phpunit/mocks/filebackend/MockFileBackend.php new file mode 100644 index 00000000..49aefbd1 --- /dev/null +++ b/tests/phpunit/mocks/filebackend/MockFileBackend.php @@ -0,0 +1,122 @@ +<?php +/** + * Simulation (mock) of a backend storage. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @ingroup FileBackend + * @author Antoine Musso <hashar@free.fr> + */ + +/** + * Class simulating a backend store. + * + * @ingroup FileBackend + * @since 1.22 + */ +class MockFileBackend extends FileBackendStore { + + protected $mocked = array(); + + /** Poor man debugging */ + protected function debug( $msg = '' ) { + wfDebug( wfGetCaller() . "$msg\n" ); + } + + public function isPathUsableInternal( $storagePath ) { + return true; + } + + protected function doCreateInternal( array $params ) { + if ( isset( $params['content'] ) ) { + $content = $params['content']; + } else { + $content = 'Default mocked file content'; + } + $this->debug( serialize( $params ) ); + $dst = $params['dst']; + $this->mocked[$dst] = $content; + return Status::newGood(); + } + + protected function doStoreInternal( array $params ) { + $this->debug( serialize( $params ) ); + return $this->doCreateInternal( $params ); + } + + protected function doCopyInternal( array $params ) { + $this->debug( serialize( $params ) ); + $src = $params['src']; + $dst = $params['dst']; + $this->mocked[$dst] = $this->mocked[$src]; + return Status::newGood(); + } + + protected function doDeleteInternal( array $params ) { + $this->debug( serialize( $params ) ); + $src = $params['src']; + unset( $this->mocked[$src] ); + return Status::newGood(); + } + + protected function doGetFileStat( array $params ) { + $src = $params['src']; + if ( array_key_exists( $src, $this->mocked ) ) { + $this->debug( "('$src') found" ); + return array( + 'mtime' => wfTimestamp( TS_MW ), + 'size' => strlen( $this->mocked[$src] ), + # No sha1, stat does not need it. + ); + } else { + $this->debug( "('$src') not found" ); + return false; + } + } + + protected function doGetLocalCopyMulti( array $params ) { + $tmpFiles = array(); // (path => MockFSFile) + + $this->debug( '(' . serialize( $params ) . ')' ); + foreach ( $params['srcs'] as $src ) { + $tmpFiles[$src] = new MockFSFile( + wfTempDir() . '/' . wfRandomString( 32 ) + ); + } + return $tmpFiles; + } + + protected function doDirectoryExists( $container, $dir, array $params ) { + $this->debug(); + return true; + } + + public function getDirectoryListInternal( $container, $dir, array $params ) { + $this->debug(); + return array(); + } + + public function getFileListInternal( $container, $dir, array $params ) { + $this->debug(); + return array(); + } + + protected function directoriesAreVirtual() { + $this->debug(); + return true; + } +} diff --git a/tests/phpunit/mocks/media/MockBitmapHandler.php b/tests/phpunit/mocks/media/MockBitmapHandler.php new file mode 100644 index 00000000..742b41e4 --- /dev/null +++ b/tests/phpunit/mocks/media/MockBitmapHandler.php @@ -0,0 +1,92 @@ +<?php +/** + * Fake handler for images. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @ingroup Media + */ + +class MockBitmapHandler extends BitmapHandler { + function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) { + return MockImageHandler::doFakeTransform( $this, $image, $dstPath, $dstUrl, $params, $flags ); + } + function doClientImage( $image, $scalerParams ) { + return $this->getClientScalingThumbnailImage( $image, $scalerParams ); + } +} +class MockSvgHandler extends SvgHandler { + function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) { + return MockImageHandler::doFakeTransform( $this, $image, $dstPath, $dstUrl, $params, $flags ); + } +} +/** + * Mock handler for images. + * + * This is really intended for unit testing. + * + * @ingroup Media + */ +class MockImageHandler { + + /** + * Override BitmapHandler::doTransform() making sure we do not generate + * a thumbnail at all. That is merely returning a ThumbnailImage that + * will be consumed by the unit test. There is no need to create a real + * thumbnail on the filesystem. + */ + static function doFakeTransform( $that, $image, $dstPath, $dstUrl, $params, $flags = 0 ) { + # Example of what we receive: + # $image: LocalFile + # $dstPath: /tmp/transform_7d0a7a2f1a09-1.jpg + # $dstUrl : http://example.com/images/thumb/0/09/Bad.jpg/320px-Bad.jpg + # $params: width: 320, descriptionUrl http://trunk.dev/wiki/File:Bad.jpg + + $that->normaliseParams( $image, $params ); + + $scalerParams = array( + # The size to which the image will be resized + 'physicalWidth' => $params['physicalWidth'], + 'physicalHeight' => $params['physicalHeight'], + 'physicalDimensions' => "{$params['physicalWidth']}x{$params['physicalHeight']}", + # The size of the image on the page + 'clientWidth' => $params['width'], + 'clientHeight' => $params['height'], + # Comment as will be added to the EXIF of the thumbnail + 'comment' => isset( $params['descriptionUrl'] ) ? + "File source: {$params['descriptionUrl']}" : '', + # Properties of the original image + 'srcWidth' => $image->getWidth(), + 'srcHeight' => $image->getHeight(), + 'mimeType' => $image->getMimeType(), + 'dstPath' => $dstPath, + 'dstUrl' => $dstUrl, + ); + + # In some cases, we do not bother generating a thumbnail. + if ( !$image->mustRender() && + $scalerParams['physicalWidth'] == $scalerParams['srcWidth'] + && $scalerParams['physicalHeight'] == $scalerParams['srcHeight'] + ) { + wfDebug( __METHOD__ . ": returning unscaled image\n" ); + // getClientScalingThumbnailImage is protected + return $that->doClientImage( $image, $scalerParams ); + } + + return new ThumbnailImage( $image, $dstUrl, false, $params ); + } +} diff --git a/tests/phpunit/phpunit.php b/tests/phpunit/phpunit.php index 2ec07440..1d65e521 100644 --- a/tests/phpunit/phpunit.php +++ b/tests/phpunit/phpunit.php @@ -12,7 +12,7 @@ define( 'MW_PHPUNIT_TEST', true ); // Start up MediaWiki in command-line mode -require_once( dirname( dirname( __DIR__ ) ) . "/maintenance/Maintenance.php" ); +require_once dirname( dirname( __DIR__ ) ) . "/maintenance/Maintenance.php"; class PHPUnitMaintClass extends Maintenance { @@ -33,6 +33,9 @@ class PHPUnitMaintClass extends Maintenance { global $wgLocaltimezone, $wgLocalisationCacheConf; global $wgDevelopmentWarnings; + // Inject test autoloader + require_once __DIR__ . '/../TestsAutoLoader.php'; + // wfWarn should cause tests to fail $wgDevelopmentWarnings = true; @@ -50,8 +53,11 @@ class PHPUnitMaintClass extends Maintenance { // Bug 44192 Do not attempt to send a real e-mail Hooks::clear( 'AlternateUserMailer' ); - Hooks::register( 'AlternateUserMailer', - function() { return false; } + Hooks::register( + 'AlternateUserMailer', + function () { + return false; + } ); } @@ -86,7 +92,6 @@ class PHPUnitMaintClass extends Maintenance { unset( $_SERVER['argv'][$key] ); // the option unset( $_SERVER['argv'][$key + 1] ); // its value $_SERVER['argv'] = array_values( $_SERVER['argv'] ); - } } @@ -96,16 +101,19 @@ class PHPUnitMaintClass extends Maintenance { } $maintClass = 'PHPUnitMaintClass'; -require( RUN_MAINTENANCE_IF_MAIN ); +require RUN_MAINTENANCE_IF_MAIN; -require_once( 'PHPUnit/Runner/Version.php' ); +if ( !class_exists( 'PHPUnit_Runner_Version' ) ) { + require_once 'PHPUnit/Runner/Version.php'; +} if ( PHPUnit_Runner_Version::id() !== '@package_version@' && version_compare( PHPUnit_Runner_Version::id(), '3.6.7', '<' ) ) { die( 'PHPUnit 3.6.7 or later required, you have ' . PHPUnit_Runner_Version::id() . ".\n" ); } -require_once( 'PHPUnit/Autoload.php' ); -require_once( "$IP/tests/TestsAutoLoader.php" ); +if ( !class_exists( 'PHPUnit_TextUI_Command' ) ) { + require_once 'PHPUnit/Autoload.php'; +} MediaWikiPHPUnitCommand::main(); diff --git a/tests/phpunit/skins/SideBarTest.php b/tests/phpunit/skins/SideBarTest.php index 3902b686..a385320f 100644 --- a/tests/phpunit/skins/SideBarTest.php +++ b/tests/phpunit/skins/SideBarTest.php @@ -5,7 +5,10 @@ */ class SideBarTest extends MediaWikiLangTestCase { - /** A skin template, reinitialized before each test */ + /** + * A skin template, reinitialized before each test + * @var SkinTemplate + */ private $skin; /** Local cache for sidebar messages */ private $messages; @@ -36,16 +39,12 @@ class SideBarTest extends MediaWikiLangTestCase { $this->skin->getContext()->setLanguage( Language::factory( 'en' ) ); } - protected function tearDown() { - parent::tearDown(); - $this->skin = null; - } - /** * Internal helper to test the sidebar * @param $expected * @param $text * @param $message (Default: '') + * @todo this assert method to should be converted to a test using a dataprovider.. */ private function assertSideBar( $expected, $text, $message = '' ) { $bar = array(); @@ -53,7 +52,10 @@ class SideBarTest extends MediaWikiLangTestCase { $this->assertEquals( $expected, $bar, $message ); } - function testSidebarWithOnlyTwoTitles() { + /** + * @covers SkinTemplate::addToSidebarPlain + */ + public function testSidebarWithOnlyTwoTitles() { $this->assertSideBar( array( 'Title1' => array(), @@ -65,7 +67,10 @@ class SideBarTest extends MediaWikiLangTestCase { ); } - function testExpandMessages() { + /** + * @covers SkinTemplate::addToSidebarPlain + */ + public function testExpandMessages() { $this->assertSidebar( array( 'Title' => array( array( @@ -81,7 +86,10 @@ class SideBarTest extends MediaWikiLangTestCase { ); } - function testExternalUrlsRequireADescription() { + /** + * @covers SkinTemplate::addToSidebarPlain + */ + public function testExternalUrlsRequireADescription() { $this->assertSidebar( array( 'Title' => array( # ** http://www.mediawiki.org/| Home @@ -100,14 +108,14 @@ class SideBarTest extends MediaWikiLangTestCase { ** http://valid.no.desc.org/ ' ); - } /** * bug 33321 - Make sure there's a | after transforming. * @group Database + * @covers SkinTemplate::addToSidebarPlain */ - function testTrickyPipe() { + public function testTrickyPipe() { $this->assertSidebar( array( 'Title' => array( # The first 2 are skipped @@ -116,13 +124,13 @@ class SideBarTest extends MediaWikiLangTestCase { # ** Baz|Fred array( 'text' => 'Fred', - 'href' => Title::newFromText( 'Baz' )->getLocalUrl(), + 'href' => Title::newFromText( 'Baz' )->getLocalURL(), 'id' => 'n-Fred', 'active' => null, ), array( 'text' => 'title-to-display', - 'href' => Title::newFromText( 'page-to-go-to' )->getLocalUrl(), + 'href' => Title::newFromText( 'page-to-go-to' )->getLocalURL(), 'id' => 'n-title-to-display', 'active' => null, ), @@ -151,11 +159,12 @@ class SideBarTest extends MediaWikiLangTestCase { /** * Simple test to verify our helper assertAttribs() is functional - * Please note this assume MediaWiki default settings: - * $wgNoFollowLinks = true - * $wgExternalLinkTarget = false */ - function testTestAttributesAssertionHelper() { + public function testTestAttributesAssertionHelper() { + $this->setMwGlobals( array( + 'wgNoFollowLinks' => true, + 'wgExternalLinkTarget' => false, + ) ); $attribs = $this->getAttribs(); $this->assertArrayHasKey( 'rel', $attribs ); @@ -167,39 +176,31 @@ class SideBarTest extends MediaWikiLangTestCase { /** * Test $wgNoFollowLinks in sidebar */ - function testRespectWgnofollowlinks() { - global $wgNoFollowLinks; - $saved = $wgNoFollowLinks; - $wgNoFollowLinks = false; + public function testRespectWgnofollowlinks() { + $this->setMwGlobals( 'wgNoFollowLinks', false ); $attribs = $this->getAttribs(); $this->assertArrayNotHasKey( 'rel', $attribs, 'External URL in sidebar do not have rel=nofollow when $wgNoFollowLinks = false' ); - - // Restore global - $wgNoFollowLinks = $saved; } /** * Test $wgExternaLinkTarget in sidebar + * @dataProvider dataRespectExternallinktarget */ - function testRespectExternallinktarget() { - global $wgExternalLinkTarget; - $saved = $wgExternalLinkTarget; + public function testRespectExternallinktarget( $externalLinkTarget ) { + $this->setMwGlobals( 'wgExternalLinkTarget', $externalLinkTarget ); - $wgExternalLinkTarget = '_blank'; $attribs = $this->getAttribs(); $this->assertArrayHasKey( 'target', $attribs ); - $this->assertEquals( $attribs['target'], '_blank' ); - - $wgExternalLinkTarget = '_self'; - $attribs = $this->getAttribs(); - $this->assertArrayHasKey( 'target', $attribs ); - $this->assertEquals( $attribs['target'], '_self' ); - - // Restore global - $wgExternalLinkTarget = $saved; + $this->assertEquals( $attribs['target'], $externalLinkTarget ); } + public static function dataRespectExternallinktarget() { + return array( + array( '_blank' ), + array( '_self' ), + ); + } } diff --git a/tests/phpunit/AutoLoaderTest.php b/tests/phpunit/structure/AutoLoaderTest.php index c8f38685..205ea360 100644 --- a/tests/phpunit/AutoLoaderTest.php +++ b/tests/phpunit/structure/AutoLoaderTest.php @@ -1,6 +1,12 @@ <?php class AutoLoaderTest extends MediaWikiTestCase { + /** + * Assert that there were no classes loaded that are not registered with the AutoLoader. + * + * For example foo.php having class Foo and class Bar but only registering Foo. + * This is important because we should not be relying on Foo being used before Bar. + */ public function testAutoLoadConfig() { $results = self::checkAutoLoadConf(); @@ -12,7 +18,6 @@ class AutoLoaderTest extends MediaWikiTestCase { protected static function checkAutoLoadConf() { global $wgAutoloadLocalClasses, $wgAutoloadClasses, $IP; - static $supportsParsekit; $supportsParsekit = function_exists( 'parsekit_compile_file' ); // wgAutoloadLocalClasses has precedence, just like in includes/AutoLoader.php diff --git a/tests/phpunit/resources/ResourcesTest.php b/tests/phpunit/structure/ResourcesTest.php index 71b8c676..fe823fa4 100644 --- a/tests/phpunit/resources/ResourcesTest.php +++ b/tests/phpunit/structure/ResourcesTest.php @@ -3,10 +3,15 @@ * Sanity checks for making sure registered resources are sane. * * @file - * @author Niklas Laxström, 2012 - * @author Antoine Musso, 2012 - * @author Santhosh Thottingal, 2012 - * @author Timo Tijhof, 2012 + * @author Antoine Musso + * @author Niklas Laxström + * @author Santhosh Thottingal + * @author Timo Tijhof + * @copyright © 2012, Antoine Musso + * @copyright © 2012, Niklas Laxström + * @copyright © 2012, Santhosh Thottingal + * @copyright © 2012, Timo Tijhof + * * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later */ class ResourcesTest extends MediaWikiTestCase { @@ -91,7 +96,7 @@ class ResourcesTest extends MediaWikiTestCase { $property = $reflectedModule->getProperty( $propName ); $property->setAccessible( true ); $lists = $property->getValue( $module ); - foreach ( $lists as $group => $list ) { + foreach ( $lists as $list ) { foreach ( $list as $key => $value ) { // We need the same filter as for 'lists', // due to 'skinStyles'. @@ -116,7 +121,6 @@ class ResourcesTest extends MediaWikiTestCase { $file, ); } - } // Restore settings @@ -124,5 +128,4 @@ class ResourcesTest extends MediaWikiTestCase { return $cases; } - } diff --git a/tests/phpunit/StructureTest.php b/tests/phpunit/structure/StructureTest.php index a9420981..df00d4df 100644 --- a/tests/phpunit/StructureTest.php +++ b/tests/phpunit/structure/StructureTest.php @@ -14,7 +14,7 @@ class StructureTest extends MediaWikiTestCase { if ( wfIsWindows() ) { $this->markTestSkipped( 'This test does not work on Windows' ); } - $rootPath = escapeshellarg( __DIR__ ); + $rootPath = escapeshellarg( __DIR__ . '/..' ); $testClassRegex = implode( '|', array( 'ApiFormatTestBase', 'ApiTestCase', @@ -58,6 +58,6 @@ class StructureTest extends MediaWikiTestCase { * Filter to remove testUnitTestFileNamesEndWithTest false positives. */ public function filterSuites( $filename ) { - return strpos( $filename, __DIR__ . '/suites/' ) !== 0; + return strpos( $filename, __DIR__ . '/../suites/' ) !== 0; } } diff --git a/tests/phpunit/suite.xml b/tests/phpunit/suite.xml index 8f7e977f..7a9122fa 100644 --- a/tests/phpunit/suite.xml +++ b/tests/phpunit/suite.xml @@ -2,17 +2,18 @@ <!-- colors don't work on Windows! --> <phpunit bootstrap="./bootstrap.php" - colors="true" - backupGlobals="false" - convertErrorsToExceptions="true" - convertNoticesToExceptions="true" - convertWarningsToExceptions="true" - stopOnFailure="false" - timeoutForSmallTests="10" - timeoutForMediumTests="30" - timeoutForLargeTests="60" - strict="true" - verbose="true"> + colors="true" + backupGlobals="false" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + forceCoversAnnotation="true" + stopOnFailure="false" + timeoutForSmallTests="10" + timeoutForMediumTests="30" + timeoutForLargeTests="60" + strict="true" + verbose="true"> <testsuites> <testsuite name="includes"> <directory>includes</directory> @@ -29,14 +30,14 @@ <directory>maintenance</directory> </testsuite> <testsuite name="structure"> - <file>AutoLoaderTest.php</file> - <file>StructureTest.php</file> + <directory>structure</directory> </testsuite> <testsuite name="uploadfromurl"> <file>suites/UploadFromUrlTestSuite.php</file> </testsuite> <testsuite name="extensions"> <file>suites/ExtensionsTestSuite.php</file> + <file>suites/ExtensionsParserTestSuite.php</file> </testsuite> </testsuites> <groups> diff --git a/tests/phpunit/suites/ExtensionsParserTestSuite.php b/tests/phpunit/suites/ExtensionsParserTestSuite.php new file mode 100644 index 00000000..3d68b241 --- /dev/null +++ b/tests/phpunit/suites/ExtensionsParserTestSuite.php @@ -0,0 +1,8 @@ +<?php +class ExtensionsParserTestSuite extends PHPUnit_Framework_TestSuite { + + public static function suite() { + return MediaWikiParserTest::suite( MediaWikiParserTest::NO_CORE ); + } + +} diff --git a/tests/phpunit/suites/UploadFromUrlTestSuite.php b/tests/phpunit/suites/UploadFromUrlTestSuite.php index 28d38ab4..7eb599e3 100644 --- a/tests/phpunit/suites/UploadFromUrlTestSuite.php +++ b/tests/phpunit/suites/UploadFromUrlTestSuite.php @@ -1,6 +1,6 @@ <?php -require_once( dirname( __DIR__ ) . '/includes/upload/UploadFromUrlTest.php' ); +require_once dirname( __DIR__ ) . '/includes/upload/UploadFromUrlTest.php'; class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite { public $savedGlobals = array(); @@ -16,16 +16,16 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite { } protected function setUp() { - global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, - $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache, - $wgNamespaceAliases, $wgNamespaceProtection, $parserMemc; + global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, $wgUser, + $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, + $wgEnableParserCache, $wgNamespaceAliases, $wgNamespaceProtection, + $parserMemc; $tmpGlobals = array(); $tmpGlobals['wgScript'] = '/index.php'; $tmpGlobals['wgScriptPath'] = '/'; $tmpGlobals['wgArticlePath'] = '/wiki/$1'; - $tmpGlobals['wgStyleSheetPath'] = '/skins'; $tmpGlobals['wgStylePath'] = '/skins'; $tmpGlobals['wgThumbnailScriptPath'] = false; $tmpGlobals['wgLocalFileRepo'] = array( @@ -56,7 +56,6 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite { $wgNamespaceAliases['Image'] = NS_FILE; $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; - $wgEnableParserCache = false; DeferredUpdates::clearPendingUpdates(); $wgMemc = wfGetMainCache(); @@ -184,6 +183,7 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite { if ( file_exists( $dir ) ) { wfDebug( "Already exists!\n" ); + return $dir; } @@ -201,6 +201,7 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite { // the UploadFromUrlTest class class_exists( 'UploadFromUrlTest' ); $suite = new UploadFromUrlTestSuite( 'UploadFromUrlTest' ); + return $suite; } } diff --git a/tests/qunit/QUnitTestResources.php b/tests/qunit/QUnitTestResources.php index 01072d83..c8743750 100644 --- a/tests/qunit/QUnitTestResources.php +++ b/tests/qunit/QUnitTestResources.php @@ -6,6 +6,7 @@ return array( 'mediawiki.tests.qunit.suites' => array( 'scripts' => array( + 'tests/qunit/suites/resources/startup.test.js', 'tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js', 'tests/qunit/suites/resources/jquery/jquery.byteLength.test.js', 'tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js', @@ -16,6 +17,7 @@ return array( 'tests/qunit/suites/resources/jquery/jquery.hidpi.test.js', 'tests/qunit/suites/resources/jquery/jquery.highlightText.test.js', 'tests/qunit/suites/resources/jquery/jquery.localize.test.js', + 'tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js', 'tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js', 'tests/qunit/suites/resources/jquery/jquery.tabIndex.test.js', 'tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js', @@ -45,6 +47,7 @@ return array( 'jquery.hidpi', 'jquery.highlightText', 'jquery.localize', + 'jquery.makeCollapsible', 'jquery.mwExtension', 'jquery.tabIndex', 'jquery.tablesorter', @@ -61,6 +64,5 @@ return array( 'mediawiki.language', 'mediawiki.cldr', ), - 'position' => 'top', ) ); diff --git a/tests/qunit/data/generateJqueryMsgData.php b/tests/qunit/data/generateJqueryMsgData.php index 604ede81..12e5a2dc 100644 --- a/tests/qunit/data/generateJqueryMsgData.php +++ b/tests/qunit/data/generateJqueryMsgData.php @@ -61,7 +61,7 @@ * </code> */ -require( __DIR__ . '/../../../maintenance/Maintenance.php' ); +require __DIR__ . '/../../../maintenance/Maintenance.php'; class GenerateJqueryMsgData extends Maintenance { @@ -147,4 +147,4 @@ class GenerateJqueryMsgData extends Maintenance { } $maintClass = "GenerateJqueryMsgData"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/tests/qunit/data/load.mock.php b/tests/qunit/data/load.mock.php index 7ff392ab..f6eff77a 100644 --- a/tests/qunit/data/load.mock.php +++ b/tests/qunit/data/load.mock.php @@ -24,6 +24,7 @@ */ header( 'Content-Type: text/javascript; charset=utf-8' ); +require_once __DIR__ . '/../../../includes/json/FormatJson.php'; require_once __DIR__ . '/../../../includes/Xml.php'; $moduleImplementations = array( @@ -50,7 +51,7 @@ if ( isset( $_GET['modules'] ) ) { if ( isset( $moduleImplementations[$module] ) ) { $response .= $moduleImplementations[$module]; } else { - $response .= Xml::encodeJsCall( 'mw.loader.state', array( $module, 'missing' ) ); + $response .= Xml::encodeJsCall( 'mw.loader.state', array( $module, 'missing' ), true ); } } } diff --git a/tests/qunit/data/testrunner.js b/tests/qunit/data/testrunner.js index 62dd81ac..1a2bfa10 100644 --- a/tests/qunit/data/testrunner.js +++ b/tests/qunit/data/testrunner.js @@ -38,6 +38,8 @@ tooltip: 'Enable debug mode in ResourceLoader' } ); + QUnit.config.requireExpects = true; + /** * Load TestSwarm agent */ @@ -48,13 +50,14 @@ // of MediaWiki has actually been configured with the required url to that inject.js // script. By default it is false. if ( QUnit.urlParams.swarmURL && mw.config.get( 'QUnitTestSwarmInjectJSPath' ) ) { - document.write( '<scr' + 'ipt src="' + QUnit.fixurl( mw.config.get( 'QUnitTestSwarmInjectJSPath' ) ) + '"></scr' + 'ipt>' ); + jQuery.getScript( QUnit.fixurl( mw.config.get( 'QUnitTestSwarmInjectJSPath' ) ) ); } /** * CompletenessTest + * + * Adds toggle checkbox to header */ - // Adds toggle checkbox to header QUnit.config.urlConfig.push( { id: 'completenesstest', label: 'Run CompletenessTest', @@ -93,8 +96,9 @@ /** * Test environment recommended for all QUnit test modules + * + * Whether to log environment changes to the console */ - // Whether to log environment changes to the console QUnit.config.urlConfig.push( 'mwlogenv' ); /** @@ -347,6 +351,25 @@ assert.equal( mw.messages.get( 'testMsg' ), 'Foo.', 'messages object restored and re-applied after test()' ); } ); + QUnit.test( 'Loader status', 2, function ( assert ) { + var i, len, state, + modules = mw.loader.getModuleNames(), + error = [], + missing = []; + + for ( i = 0, len = modules.length; i < len; i++ ) { + state = mw.loader.getState( modules[i] ); + if ( state === 'error' ) { + error.push( modules[i] ); + } else if ( state === 'missing' ) { + missing.push( modules[i] ); + } + } + + assert.deepEqual( error, [], 'Modules in error state' ); + assert.deepEqual( missing, [], 'Modules in missing state' ); + } ); + QUnit.test( 'htmlEqual', 8, function ( assert ) { assert.htmlEqual( '<div><p class="some classes" data-length="10">Child paragraph with <a href="http://example.com">A link</a></p>Regular text<span>A span</span></div>', diff --git a/tests/qunit/suites/resources/jquery/jquery.byteLength.test.js b/tests/qunit/suites/resources/jquery/jquery.byteLength.test.js index e4e579b0..e6aa3aa8 100644 --- a/tests/qunit/suites/resources/jquery/jquery.byteLength.test.js +++ b/tests/qunit/suites/resources/jquery/jquery.byteLength.test.js @@ -16,20 +16,22 @@ } ); - QUnit.test( 'Special text', 5, function ( assert ) { - // http://en.wikipedia.org/wiki/UTF-8 + QUnit.test( 'Special text', 4, function ( assert ) { + // https://en.wikipedia.org/wiki/UTF-8 var u0024 = '$', + // Cent symbol u00A2 = '\u00A2', + // Euro symbol u20AC = '\u20AC', - u024B62 = '\u024B62', - // The normal one doesn't display properly, try the below which is the same - // according to http://www.fileformat.info/info/unicode/char/24B62/index.htm - u024B62alt = '\uD852\uDF62'; + // Character \U00024B62 (Han script) can't be represented in javascript as a single + // code point, instead it is composed as a surrogate pair of two separate code units. + // http://codepoints.net/U+24B62 + // http://www.fileformat.info/info/unicode/char/24B62/index.htm + u024B62 = '\uD852\uDF62'; - assert.strictEqual( $.byteLength( u0024 ), 1, 'U+0024: 1 byte. $ (dollar sign)' ); - assert.strictEqual( $.byteLength( u00A2 ), 2, 'U+00A2: 2 bytes. \u00A2 (cent sign)' ); - assert.strictEqual( $.byteLength( u20AC ), 3, 'U+20AC: 3 bytes. \u20AC (euro sign)' ); - assert.strictEqual( $.byteLength( u024B62 ), 4, 'U+024B62: 4 bytes. \uD852\uDF62 (a Han character)' ); - assert.strictEqual( $.byteLength( u024B62alt ), 4, 'U+024B62: 4 bytes. \uD852\uDF62 (a Han character) - alternative method' ); + assert.strictEqual( $.byteLength( u0024 ), 1, 'U+0024' ); + assert.strictEqual( $.byteLength( u00A2 ), 2, 'U+00A2' ); + assert.strictEqual( $.byteLength( u20AC ), 3, 'U+20AC' ); + assert.strictEqual( $.byteLength( u024B62 ), 4, 'U+024B62 (surrogate pair: \\uD852\\uDF62)' ); } ); }( jQuery ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js b/tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js index c21844eb..22d2af19 100644 --- a/tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js +++ b/tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js @@ -31,55 +31,34 @@ /** * Test factory for $.fn.byteLimit * - * @param $input {jQuery} jQuery object in an input element - * @param hasLimit {Boolean} Wether a limit should apply at all - * @param limit {Number} Limit (if used) otherwise undefined - * The limit should be less than 20 (the sample data's length) + * @param {Object} options + * @param {string} options.description Test name + * @param {jQuery} options.$input jQuery object in an input element + * @param {string} options.sample Sequence of characters to simulate being + * added one by one + * @param {string} options.expected Expected final value of `$input` */ function byteLimitTest( options ) { var opt = $.extend( { description: '', $input: null, sample: '', - hasLimit: false, - expected: '', - limit: null + expected: '' }, options ); - QUnit.asyncTest( opt.description, opt.hasLimit ? 3 : 2, function ( assert ) { + QUnit.asyncTest( opt.description, 1, function ( assert ) { setTimeout( function () { - var rawVal, fn, effectiveVal; - opt.$input.appendTo( '#qunit-fixture' ); // Simulate pressing keys for each of the sample characters addChars( opt.$input, opt.sample ); - rawVal = opt.$input.val(); - fn = opt.$input.data( 'byteLimit.callback' ); - effectiveVal = fn ? fn( rawVal ) : rawVal; - - if ( opt.hasLimit ) { - assert.ltOrEq( - $.byteLength( effectiveVal ), - opt.limit, - 'Prevent keypresses after byteLimit was reached, length never exceeded the limit' - ); - assert.equal( - $.byteLength( rawVal ), - $.byteLength( opt.expected ), - 'Not preventing keypresses too early, length has reached the expected length' - ); - assert.equal( rawVal, opt.expected, 'New value matches the expected string' ); - - } else { - assert.equal( - $.byteLength( effectiveVal ), - $.byteLength( opt.expected ), - 'Unlimited scenarios are not affected, expected length reached' - ); - assert.equal( rawVal, opt.expected, 'New value matches the expected string' ); - } + assert.equal( + opt.$input.val(), + opt.expected, + 'New value matches the expected string' + ); + QUnit.start(); }, 10 ); } ); @@ -89,7 +68,6 @@ description: 'Plain text input', $input: $( '<input type="text"/>' ), sample: simpleSample, - hasLimit: false, expected: simpleSample } ); @@ -98,7 +76,6 @@ $input: $( '<input type="text"/>' ) .byteLimit(), sample: simpleSample, - hasLimit: false, expected: simpleSample } ); @@ -108,8 +85,6 @@ .attr( 'maxlength', '10' ) .byteLimit(), sample: simpleSample, - hasLimit: true, - limit: 10, expected: '1234567890' } ); @@ -118,8 +93,6 @@ $input: $( '<input type="text"/>' ) .byteLimit( 10 ), sample: simpleSample, - hasLimit: true, - limit: 10, expected: '1234567890' } ); @@ -129,8 +102,6 @@ .attr( 'maxlength', '10' ) .byteLimit( 15 ), sample: simpleSample, - hasLimit: true, - limit: 15, expected: '123456789012345' } ); @@ -139,8 +110,6 @@ $input: $( '<input type="text"/>' ) .byteLimit( 14 ), sample: mbSample, - hasLimit: true, - limit: 14, expected: '1234567890' + U_20AC + '1' } ); @@ -149,8 +118,6 @@ $input: $( '<input type="text"/>' ) .byteLimit( 12 ), sample: mbSample, - hasLimit: true, - limit: 12, expected: '1234567890' + '12' } ); @@ -158,17 +125,11 @@ description: 'Pass the limit and a callback as input filter', $input: $( '<input type="text"/>' ) .byteLimit( 6, function ( val ) { - // Invalid title - if ( val === '' ) { - return ''; - } - + var title = mw.Title.newFromText( String( val ) ); // Return without namespace prefix - return new mw.Title( String( val ) ).getMain(); + return title ? title.getMain() : ''; } ), sample: 'User:Sample', - hasLimit: true, - limit: 6, // 'Sample' length expected: 'User:Sample' } ); @@ -177,20 +138,53 @@ $input: $( '<input type="text"/>' ) .attr( 'maxlength', '6' ) .byteLimit( function ( val ) { - // Invalid title - if ( val === '' ) { - return ''; - } - + var title = mw.Title.newFromText( String( val ) ); // Return without namespace prefix - return new mw.Title( String( val ) ).getMain(); + return title ? title.getMain() : ''; } ), sample: 'User:Sample', - hasLimit: true, - limit: 6, // 'Sample' length expected: 'User:Sample' } ); + byteLimitTest( { + description: 'Pass the limit and a callback as input filter', + $input: $( '<input type="text"/>' ) + .byteLimit( 6, function ( val ) { + var title = mw.Title.newFromText( String( val ) ); + // Return without namespace prefix + return title ? title.getMain() : ''; + } ), + sample: 'User:Example', + // The callback alters the value to be used to calculeate + // the length. The altered value is "Exampl" which has + // a length of 6, the "e" would exceed the limit. + expected: 'User:Exampl' + } ); + + byteLimitTest( { + description: 'Input filter that increases the length', + $input: $( '<input type="text"/>' ) + .byteLimit( 10, function ( text ) { + return 'prefix' + text; + } ), + sample: simpleSample, + // Prefix adds 6 characters, limit is reached after 4 + expected: '1234' + } ); + + // Regression tests for bug 41450 + byteLimitTest( { + description: 'Input filter of which the base exceeds the limit', + $input: $( '<input type="text"/>' ) + .byteLimit( 3, function ( text ) { + return 'prefix' + text; + } ), + sample: simpleSample, + hasLimit: true, + limit: 6, // 'prefix' length + expected: '' + } ); + QUnit.test( 'Confirm properties and attributes set', 4, function ( assert ) { var $el, $elA, $elB; diff --git a/tests/qunit/suites/resources/jquery/jquery.client.test.js b/tests/qunit/suites/resources/jquery/jquery.client.test.js index 88bbf5c4..4c7c3022 100644 --- a/tests/qunit/suites/resources/jquery/jquery.client.test.js +++ b/tests/qunit/suites/resources/jquery/jquery.client.test.js @@ -1,16 +1,11 @@ ( function ( $ ) { - var uacount, uas, testMap; QUnit.module( 'jquery.client', QUnit.newMwEnvironment() ); - /** Number of user-agent defined */ - uacount = 0; - - uas = ( function () { - + var uacount = 0, // Object keyed by userAgent. Value is an array (human-readable name, client-profile object, navigator.platform value) // Info based on results from http://toolserver.org/~krinkle/testswarm/job/174/ - var uas = { + uas = { // Internet Explorer 6 // Internet Explorer 7 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)': { @@ -39,7 +34,7 @@ profile: { name: 'msie', layout: 'trident', - layoutVersion: 'unknown', // should be able to report 6? + layoutVersion: 6, platform: 'win', version: '10.0', versionBase: '10', @@ -50,6 +45,60 @@ rtl: true } }, + // Internet Explorer 11 + 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv 11.0) like Gecko': { + title: 'Internet Explorer 11', + platform: 'Win32', + profile: { + name: 'msie', + layout: 'trident', + layoutVersion: 7, + platform: 'win', + version: '11.0', + versionBase: '11', + versionNumber: 11 + }, + wikiEditor: { + ltr: true, + rtl: true + } + }, + // Internet Explorer 11 - Windows 8.1 x64 Modern UI + 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; Trident/7.0; rv:11.0) like Gecko': { + title: 'Internet Explorer 11', + platform: 'Win64', + profile: { + name: 'msie', + layout: 'trident', + layoutVersion: 7, + platform: 'win', + version: '11.0', + versionBase: '11', + versionNumber: 11 + }, + wikiEditor: { + ltr: true, + rtl: true + } + }, + // Internet Explorer 11 - Windows 8.1 x64 desktop UI + 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko': { + title: 'Internet Explorer 11', + platform: 'WOW64', + profile: { + name: 'msie', + layout: 'trident', + layoutVersion: 7, + platform: 'win', + version: '11.0', + versionBase: '11', + versionNumber: 11 + }, + wikiEditor: { + ltr: true, + rtl: true + } + }, // Firefox 2 // Firefox 3.5 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.19) Gecko/20110420 Firefox/3.5.19': { @@ -141,6 +190,24 @@ rtl: true } }, + // Iceweasel 15.0.1 + 'Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20100101 Firefox/15.0.1 Iceweasel/15.0.1': { + title: 'Iceweasel 15.0.1', + platform: 'Linux', + profile: { + name: 'iceweasel', + layout: 'gecko', + layoutVersion: 20100101, + platform: 'linux', + version: '15.0.1', + versionBase: '15', + versionNumber: 15 + }, + wikiEditor: { + ltr: true, + rtl: true + } + }, // Firefox 5 // Safari 3 // Safari 4 @@ -179,6 +246,42 @@ } }, // Safari 5 + // Safari 6 + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.29.13 (KHTML, like Gecko) Version/6.0.4 Safari/536.29.13': { + title: 'Safari 6', + platform: 'MacIntel', + profile: { + name: 'safari', + layout: 'webkit', + layoutVersion: 536, + platform: 'mac', + version: '6.0.4', + versionBase: '6', + versionNumber: 6 + }, + wikiEditor: { + ltr: true, + rtl: true + } + }, + // Safari 6.0.5+ (doesn't have the comma in "KHTML, like Gecko") + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 1084) AppleWebKit/536.30.1 (KHTML like Gecko) Version/6.0.5 Safari/536.30.1': { + title: 'Safari 6', + platform: 'MacIntel', + profile: { + name: 'safari', + layout: 'webkit', + layoutVersion: 536, + platform: 'mac', + version: '6.0.5', + versionBase: '6', + versionNumber: 6 + }, + wikiEditor: { + ltr: true, + rtl: true + } + }, // Opera 10+ 'Opera/9.80 (Windows NT 5.1)': { title: 'Opera 10+ (exact version unspecified)', @@ -215,6 +318,24 @@ rtl: true } }, + // Opera 15 (WebKit-based) + 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.52 Safari/537.36 OPR/15.0.1147.130': { + title: 'Opera 15', + platform: 'Win32', + profile: { + name: 'opera', + layout: 'webkit', + layoutVersion: 537, + platform: 'win', + version: '15.0.1147.130', + versionBase: '15', + versionNumber: 15 + }, + wikiEditor: { + ltr: true, + rtl: true + } + }, // Chrome 5 // Chrome 6 // Chrome 7 @@ -257,6 +378,24 @@ rtl: true } }, + // Android WebKit Browser 2.3 + 'Mozilla/5.0 (Linux; U; Android 2.3.5; en-us; HTC Vision Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1': { + title: 'Android WebKit Browser 2.3', + platform: 'Linux armv7l', + profile: { + name: 'android', + layout: 'webkit', + layoutVersion: 533, + platform: 'linux', + version: '2.3.5', + versionBase: '2', + versionNumber: 2.3 + }, + wikiEditor: { + ltr: true, + rtl: true + } + }, // Bug #34924 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.34 (KHTML, like Gecko) rekonq Safari/534.34': { title: 'Rekonq', @@ -275,28 +414,42 @@ rtl: true } } - }; - $.each( uas, function () { - uacount++; - } ); - return uas; - }() ); - - QUnit.test( 'profile userAgent support', uacount, function ( assert ) { - // Generate a client profile object and compare recursively - var uaTest = function ( rawUserAgent, data ) { - var ret = $.client.profile( { - userAgent: rawUserAgent, - platform: data.platform - } ); - assert.deepEqual( ret, data.profile, 'Client profile support check for ' + data.title + ' (' + data.platform + '): ' + rawUserAgent ); - }; + }, + testMap = { + // Example from WikiEditor + // Make sure to use raw numbers, a string like "7.0" would fail on a + // version 10 browser since in string comparaison "10" is before "7.0" :) + 'ltr': { + 'msie': [['>=', 7.0]], + 'firefox': [['>=', 2]], + 'opera': [['>=', 9.6]], + 'safari': [['>=', 3]], + 'chrome': [['>=', 3]], + 'netscape': [['>=', 9]], + 'blackberry': false, + 'ipod': false, + 'iphone': false + }, + 'rtl': { + 'msie': [['>=', 8]], + 'firefox': [['>=', 2]], + 'opera': [['>=', 9.6]], + 'safari': [['>=', 3]], + 'chrome': [['>=', 3]], + 'netscape': [['>=', 9]], + 'blackberry': false, + 'ipod': false, + 'iphone': false + } + } + ; - // Loop through and run tests - $.each( uas, uaTest ); + // Count test cases + $.each( uas, function () { + uacount++; } ); - QUnit.test( 'profile return validation for current user agent', 7, function ( assert ) { + QUnit.test( 'profile( navObject )', 7, function ( assert ) { var p = $.client.profile(); function unknownOrType( val, type, summary ) { @@ -312,44 +465,58 @@ assert.equal( typeof p.versionNumber, 'number', 'p.versionNumber is a number' ); } ); - // Example from WikiEditor - // Make sure to use raw numbers, a string like "7.0" would fail on a - // version 10 browser since in string comparaison "10" is before "7.0" :) - testMap = { - 'ltr': { - 'msie': [['>=', 7.0]], - 'firefox': [['>=', 2]], - 'opera': [['>=', 9.6]], - 'safari': [['>=', 3]], - 'chrome': [['>=', 3]], - 'netscape': [['>=', 9]], - 'blackberry': false, - 'ipod': false, - 'iphone': false - }, - 'rtl': { - 'msie': [['>=', 8]], - 'firefox': [['>=', 2]], - 'opera': [['>=', 9.6]], - 'safari': [['>=', 3]], - 'chrome': [['>=', 3]], - 'netscape': [['>=', 9]], - 'blackberry': false, - 'ipod': false, - 'iphone': false - } - }; + QUnit.test( 'profile( navObject ) - samples', uacount, function ( assert ) { + // Loop through and run tests + $.each( uas, function ( rawUserAgent, data ) { + // Generate a client profile object and compare recursively + var ret = $.client.profile( { + userAgent: rawUserAgent, + platform: data.platform + } ); + assert.deepEqual( ret, data.profile, 'Client profile support check for ' + data.title + ' (' + data.platform + '): ' + rawUserAgent ); + } ); + } ); - QUnit.test( 'test', 1, function ( assert ) { + QUnit.test( 'test( testMap )', 4, function ( assert ) { // .test() uses eval, make sure no exceptions are thrown // then do a basic return value type check - var testMatch = $.client.test( testMap ); + var testMatch = $.client.test( testMap ), + ie7Profile = $.client.profile( { + 'userAgent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)', + 'platform': '' + } ); + + assert.equal( typeof testMatch, 'boolean', 'map with ltr/rtl split returns a boolean value' ); + + testMatch = $.client.test( testMap.ltr ); + + assert.equal( typeof testMatch, 'boolean', 'simple map (without ltr/rtl split) returns a boolean value' ); + + assert.equal( $.client.test( { + 'msie': null + }, ie7Profile ), true, 'returns true if any version of a browser are allowed (null)' ); + + assert.equal( $.client.test( { + 'msie': false + }, ie7Profile ), false, 'returns false if all versions of a browser are not allowed (false)' ); + } ); + + QUnit.test( 'test( testMap, exactMatchOnly )', 2, function ( assert ) { + var ie7Profile = $.client.profile( { + 'userAgent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)', + 'platform': '' + } ); - assert.equal( typeof testMatch, 'boolean', 'test returns a boolean value' ); + assert.equal( $.client.test( { + 'firefox': [['>=', 2]] + }, ie7Profile, false ), true, 'returns true if browser not found and exactMatchOnly not set' ); + assert.equal( $.client.test( { + 'firefox': [['>=', 2]] + }, ie7Profile, true ), false, 'returns false if browser not found and exactMatchOnly is set' ); } ); - QUnit.test( 'User-agent matches against WikiEditor\'s compatibility map', uacount * 2, function ( assert ) { + QUnit.test( 'test( testMap) - WikiEditor sample', uacount * 2, function ( assert ) { var $body = $( 'body' ), bodyClasses = $body.attr( 'class' ); diff --git a/tests/qunit/suites/resources/jquery/jquery.localize.test.js b/tests/qunit/suites/resources/jquery/jquery.localize.test.js index d3877e05..3ef27903 100644 --- a/tests/qunit/suites/resources/jquery/jquery.localize.test.js +++ b/tests/qunit/suites/resources/jquery/jquery.localize.test.js @@ -38,7 +38,7 @@ // making sure it is actually using text() and attr() (or something with the same effect) // Text escaping - html = '<div><span><html:msg key="properfoo"></span></div>'; + html = '<div><span><html:msg key="properfoo" /></span></div>'; $lc = $( html ).localize().find( 'span' ); assert.strictEqual( $lc.text(), mw.msg( 'properfoo' ), 'Content is inserted as text, not as html.' ); @@ -63,7 +63,7 @@ var html, $lc, x, sitename = 'Wikipedia'; // Message key prefix - html = '<div><span title-msg="lorem"><html:msg key="ipsum"></span></div>'; + html = '<div><span title-msg="lorem"><html:msg key="ipsum" /></span></div>'; $lc = $( html ).localize( { prefix: 'foo-' } ).find( 'span' ); @@ -73,7 +73,7 @@ // Variable keys mapping x = 'bar'; - html = '<div><span title-msg="title"><html:msg key="label"></span></div>'; + html = '<div><span title-msg="title"><html:msg key="label" /></span></div>'; $lc = $( html ).localize( { keys: { 'title': 'foo-' + x + '-title', @@ -85,7 +85,7 @@ assert.strictEqual( $lc.text(), 'The Bars', 'Variable keys mapping - text' ); // Passing parameteters to mw.msg - html = '<div><span><html:msg key="foo-welcome"></span></div>'; + html = '<div><span><html:msg key="foo-welcome" /></span></div>'; $lc = $( html ).localize( { params: { 'foo-welcome': [sitename, 'yesterday'] @@ -96,7 +96,7 @@ // Combination of options prefix, params and keys x = 'bazz'; - html = '<div><span title-msg="title"><html:msg key="label"></span></div>'; + html = '<div><span title-msg="title"><html:msg key="label" /></span></div>'; $lc = $( html ).localize( { prefix: 'foo-', keys: { diff --git a/tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js b/tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js new file mode 100644 index 00000000..6da56ed2 --- /dev/null +++ b/tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js @@ -0,0 +1,287 @@ +( function ( mw, $ ) { + var loremIpsum = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.'; + + QUnit.module( 'jquery.makeCollapsible', QUnit.newMwEnvironment() ); + + function prepareCollapsible( html, options ) { + return $( $.parseHTML( html ) ) + .appendTo( '#qunit-fixture' ) + // options might be undefined here - this is okay + .makeCollapsible( options ); + } + + // This test is first because if it fails, then almost all of the latter tests are meaningless. + QUnit.asyncTest( 'testing hooks/triggers', 4, function ( assert ) { + var $collapsible, $content, $toggle; + $collapsible = prepareCollapsible( + '<div class="mw-collapsible">' + loremIpsum + '</div>' + ); + $content = $collapsible.find( '.mw-collapsible-content' ); + $toggle = $collapsible.find( '.mw-collapsible-toggle' ); + + // In one full collapse-expand cycle, each event will be fired once + + // On collapse... + $collapsible.on( 'beforeCollapse.mw-collapsible', function () { + assert.assertTrue( $content.is( ':visible' ), 'first beforeCollapseExpand: content is visible' ); + } ); + $collapsible.on( 'afterCollapse.mw-collapsible', function () { + assert.assertTrue( $content.is( ':hidden' ), 'first afterCollapseExpand: content is hidden' ); + + // On expand... + $collapsible.on( 'beforeExpand.mw-collapsible', function () { + assert.assertTrue( $content.is( ':hidden' ), 'second beforeCollapseExpand: content is hidden' ); + } ); + $collapsible.on( 'afterExpand.mw-collapsible', function () { + assert.assertTrue( $content.is( ':visible' ), 'second afterCollapseExpand: content is visible' ); + + QUnit.start(); + } ); + + // ...expanding happens here + $toggle.trigger( 'click' ); + } ); + + // ...collapsing happens here + $toggle.trigger( 'click' ); + } ); + + QUnit.asyncTest( 'basic operation (<div>)', 5, function ( assert ) { + var $collapsible, $content, $toggle; + $collapsible = prepareCollapsible( + '<div class="mw-collapsible">' + loremIpsum + '</div>' + ); + $content = $collapsible.find( '.mw-collapsible-content' ); + $toggle = $collapsible.find( '.mw-collapsible-toggle' ); + + assert.equal( $content.length, 1, 'content is present' ); + assert.equal( $content.find( $toggle ).length, 0, 'toggle is not a descendant of content' ); + + assert.assertTrue( $content.is( ':visible' ), 'content is visible' ); + + $collapsible.on( 'afterCollapse.mw-collapsible', function () { + assert.assertTrue( $content.is( ':hidden' ), 'after collapsing: content is hidden' ); + + $collapsible.on( 'afterExpand.mw-collapsible', function () { + assert.assertTrue( $content.is( ':visible' ), 'after expanding: content is visible' ); + QUnit.start(); + } ); + + $toggle.trigger( 'click' ); + } ); + + $toggle.trigger( 'click' ); + } ); + + QUnit.asyncTest( 'basic operation (<table>)', 7, function ( assert ) { + var $collapsible, $headerRow, $contentRow, $toggle; + $collapsible = prepareCollapsible( + '<table class="mw-collapsible">' + + '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' + + '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' + + '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' + + '</table>' + ); + $headerRow = $collapsible.find( 'tr:first' ); + $contentRow = $collapsible.find( 'tr:last' ); + + $toggle = $headerRow.find( 'td:last .mw-collapsible-toggle' ); + assert.equal( $toggle.length, 1, 'toggle is added to last cell of first row' ); + + assert.assertTrue( $headerRow.is( ':visible' ), 'headerRow is visible' ); + assert.assertTrue( $contentRow.is( ':visible' ), 'contentRow is visible' ); + + $collapsible.on( 'afterCollapse.mw-collapsible', function () { + assert.assertTrue( $headerRow.is( ':visible' ), 'after collapsing: headerRow is still visible' ); + assert.assertTrue( $contentRow.is( ':hidden' ), 'after collapsing: contentRow is hidden' ); + + $collapsible.on( 'afterExpand.mw-collapsible', function () { + assert.assertTrue( $headerRow.is( ':visible' ), 'after expanding: headerRow is still visible' ); + assert.assertTrue( $contentRow.is( ':visible' ), 'after expanding: contentRow is visible' ); + QUnit.start(); + } ); + + $toggle.trigger( 'click' ); + } ); + + $toggle.trigger( 'click' ); + } ); + + function listTest( listType, assert ) { + var $collapsible, $toggleItem, $contentItem, $toggle; + $collapsible = prepareCollapsible( + '<' + listType + ' class="mw-collapsible">' + + '<li>' + loremIpsum + '</li>' + + '<li>' + loremIpsum + '</li>' + + '</' + listType + '>' + ); + $toggleItem = $collapsible.find( 'li.mw-collapsible-toggle-li:first-child' ); + $contentItem = $collapsible.find( 'li:last' ); + + $toggle = $toggleItem.find( '.mw-collapsible-toggle' ); + assert.equal( $toggle.length, 1, 'toggle is present, added inside new zeroth list item' ); + + assert.assertTrue( $toggleItem.is( ':visible' ), 'toggleItem is visible' ); + assert.assertTrue( $contentItem.is( ':visible' ), 'contentItem is visible' ); + + $collapsible.on( 'afterCollapse.mw-collapsible', function () { + assert.assertTrue( $toggleItem.is( ':visible' ), 'after collapsing: toggleItem is still visible' ); + assert.assertTrue( $contentItem.is( ':hidden' ), 'after collapsing: contentItem is hidden' ); + + $collapsible.on( 'afterExpand.mw-collapsible', function () { + assert.assertTrue( $toggleItem.is( ':visible' ), 'after expanding: toggleItem is still visible' ); + assert.assertTrue( $contentItem.is( ':visible' ), 'after expanding: contentItem is visible' ); + QUnit.start(); + } ); + + $toggle.trigger( 'click' ); + } ); + + $toggle.trigger( 'click' ); + } + + QUnit.asyncTest( 'basic operation (<ul>)', 7, function ( assert ) { + listTest( 'ul', assert ); + } ); + + QUnit.asyncTest( 'basic operation (<ol>)', 7, function ( assert ) { + listTest( 'ol', assert ); + } ); + + QUnit.test( 'basic operation when synchronous (options.instantHide)', 2, function ( assert ) { + var $collapsible, $content; + $collapsible = prepareCollapsible( + '<div class="mw-collapsible">' + loremIpsum + '</div>', + { instantHide: true } + ); + $content = $collapsible.find( '.mw-collapsible-content' ); + + assert.assertTrue( $content.is( ':visible' ), 'content is visible' ); + + $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' ); + + assert.assertTrue( $content.is( ':hidden' ), 'after collapsing: content is hidden' ); + } ); + + QUnit.test( 'mw-made-collapsible data added', 1, function ( assert ) { + var $collapsible; + $collapsible = prepareCollapsible( + '<div>' + loremIpsum + '</div>' + ); + assert.equal( $collapsible.data( 'mw-made-collapsible' ), true, 'mw-made-collapsible data present' ); + } ); + + QUnit.test( 'mw-collapsible added when missing', 1, function ( assert ) { + var $collapsible; + $collapsible = prepareCollapsible( + '<div>' + loremIpsum + '</div>' + ); + assert.assertTrue( $collapsible.hasClass( 'mw-collapsible' ), 'mw-collapsible class present' ); + } ); + + QUnit.test( 'mw-collapsed added when missing', 1, function ( assert ) { + var $collapsible; + $collapsible = prepareCollapsible( + '<div>' + loremIpsum + '</div>', + { collapsed: true } + ); + assert.assertTrue( $collapsible.hasClass( 'mw-collapsed' ), 'mw-collapsed class present' ); + } ); + + QUnit.asyncTest( 'initial collapse (mw-collapsed class)', 2, function ( assert ) { + var $collapsible, $content; + $collapsible = prepareCollapsible( + '<div class="mw-collapsible mw-collapsed">' + loremIpsum + '</div>' + ); + $content = $collapsible.find( '.mw-collapsible-content' ); + + // Synchronous - mw-collapsed should cause instantHide: true to be used on initial collapsing + assert.assertTrue( $content.is( ':hidden' ), 'content is hidden' ); + + $collapsible.on( 'afterExpand.mw-collapsible', function () { + assert.assertTrue( $content.is( ':visible' ), 'after expanding: content is visible' ); + QUnit.start(); + } ); + + $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' ); + } ); + + QUnit.asyncTest( 'initial collapse (options.collapsed)', 2, function ( assert ) { + var $collapsible, $content; + $collapsible = prepareCollapsible( + '<div class="mw-collapsible">' + loremIpsum + '</div>', + { collapsed: true } + ); + $content = $collapsible.find( '.mw-collapsible-content' ); + + // Synchronous - collapsed: true should cause instantHide: true to be used on initial collapsing + assert.assertTrue( $content.is( ':hidden' ), 'content is hidden' ); + + $collapsible.on( 'afterExpand.mw-collapsible', function () { + assert.assertTrue( $content.is( ':visible' ), 'after expanding: content is visible' ); + QUnit.start(); + } ); + + $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' ); + } ); + + QUnit.test( 'clicks on links inside toggler pass through (options.linksPassthru)' , 2, function ( assert ) { + var $collapsible, $content; + + $collapsible = prepareCollapsible( + '<div class="mw-collapsible">' + + '<div class="mw-collapsible-toggle">' + + 'Toggle <a href="#top">toggle</a> toggle <b>toggle</b>' + + '</div>' + + '<div class="mw-collapsible-content">' + loremIpsum + '</div>' + + '</div>', + // Can't do asynchronous because we're testing that the event *doesn't* happen + { instantHide: true } + ); + $content = $collapsible.find( '.mw-collapsible-content' ); + + $collapsible.find( '.mw-collapsible-toggle a' ).trigger( 'click' ); + assert.assertTrue( $content.is( ':visible' ), 'click event on link inside toggle passes through (content not toggled)' ); + + $collapsible.find( '.mw-collapsible-toggle b' ).trigger( 'click' ); + assert.assertTrue( $content.is( ':hidden' ), 'click event on non-link inside toggle toggles content' ); + } ); + + QUnit.asyncTest( 'collapse/expand text (data-collapsetext, data-expandtext)', 2, function ( assert ) { + var $collapsible, $toggleLink; + $collapsible = prepareCollapsible( + '<div class="mw-collapsible" data-collapsetext="Collapse me!" data-expandtext="Expand me!">' + + loremIpsum + + '</div>' + ); + $toggleLink = $collapsible.find( '.mw-collapsible-toggle a' ); + + assert.equal( $toggleLink.text(), 'Collapse me!', 'data-collapsetext is respected' ); + + $collapsible.on( 'afterCollapse.mw-collapsible', function () { + assert.equal( $toggleLink.text(), 'Expand me!', 'data-expandtext is respected' ); + QUnit.start(); + } ); + + $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' ); + } ); + + QUnit.asyncTest( 'collapse/expand text (options.collapseText, options.expandText)', 2, function ( assert ) { + var $collapsible, $toggleLink; + $collapsible = prepareCollapsible( + '<div class="mw-collapsible">' + loremIpsum + '</div>', + { collapseText: 'Collapse me!', expandText: 'Expand me!' } + ); + $toggleLink = $collapsible.find( '.mw-collapsible-toggle a' ); + + assert.equal( $toggleLink.text(), 'Collapse me!', 'options.collapseText is respected' ); + + $collapsible.on( 'afterCollapse.mw-collapsible', function () { + assert.equal( $toggleLink.text(), 'Expand me!', 'options.expandText is respected' ); + QUnit.start(); + } ); + + $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' ); + } ); + +}( mediaWiki, jQuery ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js b/tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js index 307b0440..f73fd7bf 100644 --- a/tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js +++ b/tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js @@ -5,6 +5,8 @@ wgMonthNames: ['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], wgMonthNamesShort: ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], wgDefaultDateFormat: 'dmy', + wgSeparatorTransformTable: ['', ''], + wgDigitTransformTable: ['', ''], wgContentLanguage: 'en' }; @@ -180,6 +182,18 @@ } ); tableTest( + 'Basic planet table: ascending by name (multiple clicks)', + header, + planets, + ascendingName, + function ( $table ) { + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + $table.find( '.headerSort:eq(1)' ).click(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + tableTest( 'Basic planet table: descending by name', header, planets, @@ -273,6 +287,35 @@ $table.data( 'tablesorter' ).sort(); } ); + tableTest( + 'Sort via click event after having initialized the tablesorter with initial sorting', + header, + initial, + descasc, + function ( $table ) { + $table.tablesorter( + { sortList: [ { 0: 'asc' }, { 1: 'asc' } ] } + ); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + tableTest( + 'Multi-sort via click event after having initialized the tablesorter with initial sorting', + header, + initial, + asc, + function ( $table ) { + $table.tablesorter( + { sortList: [ { 0: 'desc' }, { 1: 'desc' } ] } + ); + $table.find( '.headerSort:eq(0)' ).click(); + + // Pretend to click while pressing the multi-sort key + var event = $.Event( 'click' ); + event[$table.data( 'tablesorter' ).config.sortMultiSortKey] = true; + $table.find( '.headerSort:eq(1)' ).trigger( event ); + } + ); QUnit.test( 'Reset sorting making table appear unsorted', 3, function ( assert ) { var $table = tableCreate( header, initial ); $table.tablesorter( @@ -319,12 +362,26 @@ function ( $table ) { // Make colspanned header for test $table.find( 'tr:eq(0) th:eq(1), tr:eq(0) th:eq(2)' ).remove(); - $table.find( 'tr:eq(0) th:eq(0)' ).prop( 'colspan', '3' ); + $table.find( 'tr:eq(0) th:eq(0)' ).attr( 'colspan', '3' ); $table.tablesorter(); $table.find( '.headerSort:eq(0)' ).click(); } ); + tableTest( 'Sorting with colspanned headers: sort spanned column twice', + header, + initial, + [ caa4, bbc2, abc3, aab5, aaa1 ], + function ( $table ) { + // Make colspanned header for test + $table.find( 'tr:eq(0) th:eq(1), tr:eq(0) th:eq(2)' ).remove(); + $table.find( 'tr:eq(0) th:eq(0)' ).attr( 'colspan', '3' ); + + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); tableTest( 'Sorting with colspanned headers: subsequent column', header, initial, @@ -332,12 +389,40 @@ function ( $table ) { // Make colspanned header for test $table.find( 'tr:eq(0) th:eq(1), tr:eq(0) th:eq(2)' ).remove(); - $table.find( 'tr:eq(0) th:eq(0)' ).prop( 'colspan', '3' ); + $table.find( 'tr:eq(0) th:eq(0)' ).attr( 'colspan', '3' ); $table.tablesorter(); $table.find( '.headerSort:eq(1)' ).click(); } ); + tableTest( 'Sorting with colspanned headers: sort subsequent column twice', + header, + initial, + [ aab5, caa4, abc3, bbc2, aaa1 ], + function ( $table ) { + // Make colspanned header for test + $table.find( 'tr:eq(0) th:eq(1), tr:eq(0) th:eq(2)' ).remove(); + $table.find( 'tr:eq(0) th:eq(0)' ).attr( 'colspan', '3' ); + + $table.tablesorter(); + $table.find( '.headerSort:eq(1)' ).click(); + $table.find( '.headerSort:eq(1)' ).click(); + } + ); + + + tableTest( + 'Basic planet table: one unsortable column', + header, + planets, + planets, + function ( $table ) { + $table.find( 'tr:eq(0) > th:eq(0)' ).addClass( 'unsortable' ); + + $table.tablesorter(); + $table.find( 'tr:eq(0) > th:eq(0)' ).click(); + } + ); // Regression tests! tableTest( @@ -489,12 +574,12 @@ $table.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove(); // - Set rowspan for 2nd cell of 3rd row to 3. // This covers the removed cell in the 4th and 5th row. - $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan', '3' ); + $table.find( 'tr:eq(2) td:eq(1)' ).attr( 'rowspan', '3' ); $table.tablesorter(); assert.equal( - $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan' ), + $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowSpan' ), 3, 'Rowspan not exploded' ); @@ -521,7 +606,7 @@ $table.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove(); // - Set rowspan for 2nd cell of 3rd row to 3. // This covers the removed cell in the 4th and 5th row. - $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan', '3' ); + $table.find( 'tr:eq(2) td:eq(1)' ).attr( 'rowspan', '3' ); $table.tablesorter(); $table.find( '.headerSort:eq(0)' ).click(); @@ -538,7 +623,7 @@ $table.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove(); // - Set rowspan for 2nd cell of 3rd row to 3. // This covers the removed cell in the 4th and 5th row. - $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan', '3' ); + $table.find( 'tr:eq(2) td:eq(1)' ).attr( 'rowspan', '3' ); $table.tablesorter( { sortList: [ { 0: 'asc' } @@ -556,7 +641,7 @@ $table.find( 'tr:eq(3) td:eq(0), tr:eq(4) td:eq(0)' ).remove(); // - Set rowspan for 1st cell of 3rd row to 3. // This covers the removed cell in the 4th and 5th row. - $table.find( 'tr:eq(2) td:eq(0)' ).prop( 'rowspan', '3' ); + $table.find( 'tr:eq(2) td:eq(0)' ).attr( 'rowspan', '3' ); $table.tablesorter(); $table.find( '.headerSort:eq(0)' ).click(); @@ -642,7 +727,7 @@ } ); - QUnit.test( 'Test detection routine', function ( assert ) { + QUnit.test( 'Test detection routine', 1, function ( assert ) { var $table; $table = $( '<table class="sortable">' + @@ -663,7 +748,7 @@ } ); /** FIXME: the diff output is not very readeable. */ - QUnit.test( 'bug 32047 - caption must be before thead', function ( assert ) { + QUnit.test( 'bug 32047 - caption must be before thead', 1, function ( assert ) { var $table; $table = $( '<table class="sortable">' + @@ -683,7 +768,7 @@ ); } ); - QUnit.test( 'data-sort-value attribute, when available, should override sorting position', function ( assert ) { + QUnit.test( 'data-sort-value attribute, when available, should override sorting position', 3, function ( assert ) { var $table, data; // Example 1: All cells except one cell without data-sort-value, @@ -953,7 +1038,7 @@ } ); - QUnit.test( 'Sorting images using alt text', function ( assert ) { + QUnit.test( 'Sorting images using alt text', 1, function ( assert ) { var $table = $( '<table class="sortable">' + '<tr><th>THEAD</th></tr>' + @@ -970,7 +1055,7 @@ ); } ); - QUnit.test( 'Sorting images using alt text (complex)', function ( assert ) { + QUnit.test( 'Sorting images using alt text (complex)', 1, function ( assert ) { var $table = $( '<table class="sortable">' + '<tr><th>THEAD</th></tr>' + @@ -991,7 +1076,7 @@ ); } ); - QUnit.test( 'Sorting images using alt text (with format autodetection)', function ( assert ) { + QUnit.test( 'Sorting images using alt text (with format autodetection)', 1, function ( assert ) { var $table = $( '<table class="sortable">' + '<tr><th>THEAD</th></tr>' + @@ -1010,6 +1095,61 @@ ); } ); + QUnit.test( 'bug 38911 - The row with the largest amount of columns should receive the sort indicators', 3, function ( assert ) { + var $table = $( + '<table class="sortable">' + + '<thead>' + + '<tr><th rowspan="2" id="A1">A1</th><th colspan="2">B2a</th></tr>' + + '<tr><th id="B2b">B2b</th><th id="C2b">C2b</th></tr>' + + '</thead>' + + '<tr><td>A</td><td>Aa</td><td>Ab</td></tr>' + + '<tr><td>B</td><td>Ba</td><td>Bb</td></tr>' + + '</table>' + ); + $table.tablesorter(); + + assert.equal( + $table.find( '#A1' ).attr( 'class' ), + 'headerSort', + 'The first column of the first row should be sortable' + ); + assert.equal( + $table.find( '#B2b' ).attr( 'class' ), + 'headerSort', + 'The th element of the 2nd row of the 2nd column should be sortable' + ); + assert.equal( + $table.find( '#C2b' ).attr( 'class' ), + 'headerSort', + 'The th element of the 2nd row of the 3rd column should be sortable' + ); + } ); + + QUnit.test( 'rowspans in table headers should prefer the last row when rows are equal in length', 2, function ( assert ) { + var $table = $( + '<table class="sortable">' + + '<thead>' + + '<tr><th rowspan="2" id="A1">A1</th><th>B2a</th></tr>' + + '<tr><th id="B2b">B2b</th></tr>' + + '</thead>' + + '<tr><td>A</td><td>Aa</td></tr>' + + '<tr><td>B</td><td>Ba</td></tr>' + + '</table>' + ); + $table.tablesorter(); + + assert.equal( + $table.find( '#A1' ).attr( 'class' ), + 'headerSort', + 'The first column of the first row should be sortable' + ); + assert.equal( + $table.find( '#B2b' ).attr( 'class' ), + 'headerSort', + 'The th element of the 2nd row of the 2nd column should be sortable' + ); + } ); + // bug 41889 - exploding rowspans in more complex cases tableTestHTML( 'Rowspan exploding with row headers', diff --git a/tests/qunit/suites/resources/jquery/jquery.textSelection.test.js b/tests/qunit/suites/resources/jquery/jquery.textSelection.test.js index ce03b697..5fe23944 100644 --- a/tests/qunit/suites/resources/jquery/jquery.textSelection.test.js +++ b/tests/qunit/suites/resources/jquery/jquery.textSelection.test.js @@ -48,13 +48,6 @@ var start = opt.before.start, end = opt.before.end; - if ( window.opera ) { - // Compensate for Opera's craziness converting \n to \r\n and counting that as two chars - var newLinesBefore = opt.before.text.substring( 0, start ).split( '\n' ).length - 1, - newLinesInside = opt.before.text.substring( start, end ).split( '\n' ).length - 1; - start += newLinesBefore; - end += newLinesBefore + newLinesInside; - } var options = $.extend( {}, opt.replace ); // Clone opt.replace options.selectionStart = start; diff --git a/tests/qunit/suites/resources/mediawiki.special/mediawiki.special.recentchanges.test.js b/tests/qunit/suites/resources/mediawiki.special/mediawiki.special.recentchanges.test.js index 9389651f..ee854aef 100644 --- a/tests/qunit/suites/resources/mediawiki.special/mediawiki.special.recentchanges.test.js +++ b/tests/qunit/suites/resources/mediawiki.special/mediawiki.special.recentchanges.test.js @@ -3,7 +3,7 @@ // TODO: verify checkboxes == [ 'nsassociated', 'nsinvert' ] - QUnit.test( '"all" namespace disable checkboxes', function ( assert ) { + QUnit.test( '"all" namespace disable checkboxes', 8, function ( assert ) { var selectHtml, $env, $options; // from Special:Recentchanges diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js index 30a31ef7..ab96f753 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js @@ -1,4 +1,4 @@ -( function ( mw ) { +( function ( mw, $ ) { // mw.Title relies on these three config vars // Restore them after each test run var config = { @@ -53,49 +53,184 @@ antarctic_waterfowl: 100 }, wgCaseSensitiveNamespaces: [] + }, + repeat = function ( input, multiplier ) { + return new Array( multiplier + 1 ).join( input ); + }, + cases = { + // See also TitleTest.php#testSecureAndSplit + valid: [ + 'Sandbox', + 'A "B"', + 'A \'B\'', + '.com', + '~', + '"', + '\'', + 'Talk:Sandbox', + 'Talk:Foo:Sandbox', + 'File:Example.svg', + 'File_talk:Example.svg', + 'Foo/.../Sandbox', + 'Sandbox/...', + 'A~~', + // Length is 256 total, but only title part matters + 'Category:' + repeat( 'x', 248 ), + repeat( 'x', 252 ) + ], + invalid: [ + '', + '__ __', + ' __ ', + // Bad characters forbidden regardless of wgLegalTitleChars + 'A [ B', + 'A ] B', + 'A { B', + 'A } B', + 'A < B', + 'A > B', + 'A | B', + // URL encoding + 'A%20B', + 'A%23B', + 'A%2523B', + // XML/HTML character entity references + // Note: The ones with # are commented out as those are interpreted as fragment and + // as such end up being valid. + 'A é B', + //'A é B', + //'A é B', + // Subject of NS_TALK does not roundtrip to NS_MAIN + 'Talk:File:Example.svg', + // Directory navigation + '.', + '..', + './Sandbox', + '../Sandbox', + 'Foo/./Sandbox', + 'Foo/../Sandbox', + 'Sandbox/.', + 'Sandbox/..', + // Tilde + 'A ~~~ Name', + 'A ~~~~ Signature', + 'A ~~~~~ Timestamp', + repeat( 'x', 256 ), + // Extension separation is a js invention, for length + // purposes it is part of the title + repeat( 'x', 252 ) + '.json', + // Namespace prefix without actual title + // ':', // bug 54044 + 'Talk:', + 'Category: ', + 'Category: #bar' + ] }; QUnit.module( 'mediawiki.Title', QUnit.newMwEnvironment( { config: config } ) ); - QUnit.test( 'Transformation', 8, function ( assert ) { + QUnit.test( 'constructor', cases.invalid.length, function ( assert ) { + var i, title; + for ( i = 0; i < cases.valid.length; i++ ) { + title = new mw.Title( cases.valid[i] ); + } + for ( i = 0; i < cases.invalid.length; i++ ) { + /*jshint loopfunc:true */ + title = cases.invalid[i]; + assert.throws( function () { + return new mw.Title( title ); + }, cases.invalid[i] ); + } + } ); + + QUnit.test( 'newFromText', cases.valid.length + cases.invalid.length, function ( assert ) { + var i; + for ( i = 0; i < cases.valid.length; i++ ) { + assert.equal( + $.type( mw.Title.newFromText( cases.valid[i] ) ), + 'object', + cases.valid[i] + ); + } + for ( i = 0; i < cases.invalid.length; i++ ) { + assert.equal( + $.type( mw.Title.newFromText( cases.invalid[i] ) ), + 'null', + cases.invalid[i] + ); + } + } ); + + QUnit.test( 'Basic parsing', 12, function ( assert ) { + var title; + title = new mw.Title( 'File:Foo_bar.JPG' ); + + assert.equal( title.getNamespaceId(), 6 ); + assert.equal( title.getNamespacePrefix(), 'File:' ); + assert.equal( title.getName(), 'Foo_bar' ); + assert.equal( title.getNameText(), 'Foo bar' ); + assert.equal( title.getExtension(), 'JPG' ); + assert.equal( title.getDotExtension(), '.JPG' ); + assert.equal( title.getMain(), 'Foo_bar.JPG' ); + assert.equal( title.getMainText(), 'Foo bar.JPG' ); + assert.equal( title.getPrefixedDb(), 'File:Foo_bar.JPG' ); + assert.equal( title.getPrefixedText(), 'File:Foo bar.JPG' ); + + title = new mw.Title( 'Foo#bar' ); + assert.equal( title.getPrefixedText(), 'Foo' ); + assert.equal( title.getFragment(), 'bar' ); + } ); + + QUnit.test( 'Transformation', 11, function ( assert ) { var title; title = new mw.Title( 'File:quux pif.jpg' ); - assert.equal( title.getName(), 'Quux_pif' ); + assert.equal( title.getNameText(), 'Quux pif', 'First character of title' ); title = new mw.Title( 'File:Glarg_foo_glang.jpg' ); - assert.equal( title.getNameText(), 'Glarg foo glang' ); + assert.equal( title.getNameText(), 'Glarg foo glang', 'Underscores' ); title = new mw.Title( 'User:ABC.DEF' ); - assert.equal( title.toText(), 'User:ABC.DEF' ); - assert.equal( title.getNamespaceId(), 2 ); - assert.equal( title.getNamespacePrefix(), 'User:' ); + assert.equal( title.toText(), 'User:ABC.DEF', 'Round trip text' ); + assert.equal( title.getNamespaceId(), 2, 'Parse canonical namespace prefix' ); + + title = new mw.Title( 'Image:quux pix.jpg' ); + assert.equal( title.getNamespacePrefix(), 'File:', 'Transform alias to canonical namespace' ); title = new mw.Title( 'uSEr:hAshAr' ); assert.equal( title.toText(), 'User:HAshAr' ); - assert.equal( title.getNamespaceId(), 2 ); + assert.equal( title.getNamespaceId(), 2, 'Case-insensitive namespace prefix' ); - title = new mw.Title( ' MediaWiki: Foo bar .js ' ); - // Don't ask why, it's the way the backend works. One space is kept of each set - assert.equal( title.getName(), 'Foo_bar_.js', 'Merge multiple spaces to a single space.' ); - } ); + // Don't ask why, it's the way the backend works. One space is kept of each set. + title = new mw.Title( 'Foo __ \t __ bar' ); + assert.equal( title.getMain(), 'Foo_bar', 'Merge multiple types of whitespace/underscores into a single underscore' ); - QUnit.test( 'Main text for filename', 8, function ( assert ) { - var title = new mw.Title( 'File:foo_bar.JPG' ); + // Regression test: Previously it would only detect an extension if there is no space after it + title = new mw.Title( 'Example.js ' ); + assert.equal( title.getExtension(), 'js', 'Space after an extension is stripped' ); - assert.equal( title.getNamespaceId(), 6 ); - assert.equal( title.getNamespacePrefix(), 'File:' ); - assert.equal( title.getName(), 'Foo_bar' ); - assert.equal( title.getNameText(), 'Foo bar' ); - assert.equal( title.getMain(), 'Foo_bar.JPG' ); - assert.equal( title.getMainText(), 'Foo bar.JPG' ); - assert.equal( title.getExtension(), 'JPG' ); - assert.equal( title.getDotExtension(), '.JPG' ); + title = new mw.Title( 'Example#foo' ); + assert.equal( title.getFragment(), 'foo', 'Fragment' ); + + title = new mw.Title( 'Example#_foo_bar baz_' ); + assert.equal( title.getFragment(), ' foo bar baz', 'Fragment' ); } ); - QUnit.test( 'Namespace detection and conversion', 6, function ( assert ) { + QUnit.test( 'Namespace detection and conversion', 10, function ( assert ) { var title; + title = new mw.Title( 'File:User:Example' ); + assert.equal( title.getNamespaceId(), 6, 'Titles can contain namespace prefixes, which are otherwise ignored' ); + + title = new mw.Title( 'Example', 6 ); + assert.equal( title.getNamespaceId(), 6, 'Default namespace passed is used' ); + + title = new mw.Title( 'User:Example', 6 ); + assert.equal( title.getNamespaceId(), 2, 'Included namespace prefix overrides the given default' ); + + title = new mw.Title( ':Example', 6 ); + assert.equal( title.getNamespaceId(), 0, 'Colon forces main namespace' ); + title = new mw.Title( 'something.PDF', 6 ); assert.equal( title.toString(), 'File:Something.PDF' ); @@ -189,10 +324,93 @@ mw.config.set( 'wgArticlePath', '/wiki/$1' ); title = new mw.Title( 'Foobar' ); - assert.equal( title.getUrl(), '/wiki/Foobar', 'Basic functionally, toString passing to wikiGetlink' ); + assert.equal( title.getUrl(), '/wiki/Foobar', 'Basic functionally, getUrl uses mw.util.getUrl' ); title = new mw.Title( 'John Doe', 3 ); assert.equal( title.getUrl(), '/wiki/User_talk:John_Doe', 'Escaping in title and namespace for urls' ); } ); -}( mediaWiki ) ); + QUnit.test( 'newFromImg', 28, function ( assert ) { + var title, i, thisCase, prefix, + cases = [ + { + url: '/wiki/images/thumb/9/91/Anticlockwise_heliotrope%27s.jpg/99px-Anticlockwise_heliotrope%27s.jpg', + typeOfUrl: 'Normal hashed directory thumbnail', + nameText: 'Anticlockwise heliotrope\'s', + prefixedText: 'File:Anticlockwise heliotrope\'s.jpg' + }, + + { + url: '//upload.wikimedia.org/wikipedia/commons/thumb/8/80/Wikipedia-logo-v2.svg/150px-Wikipedia-logo-v2.svg.png', + typeOfUrl: 'Commons thumbnail', + nameText: 'Wikipedia-logo-v2', + prefixedText: 'File:Wikipedia-logo-v2.svg' + }, + + { + url: '/wiki/images/9/91/Anticlockwise_heliotrope%27s.jpg', + typeOfUrl: 'Full image', + nameText: 'Anticlockwise heliotrope\'s', + prefixedText: 'File:Anticlockwise heliotrope\'s.jpg' + }, + + { + url: 'http://localhost/thumb.php?f=Stuffless_Figaro%27s.jpg&width=180', + typeOfUrl: 'thumb.php-based thumbnail', + nameText: 'Stuffless Figaro\'s', + prefixedText: 'File:Stuffless Figaro\'s.jpg' + }, + + { + url: '/wikipedia/commons/thumb/Wikipedia-logo-v2.svg/150px-Wikipedia-logo-v2.svg.png', + typeOfUrl: 'Commons unhashed thumbnail', + nameText: 'Wikipedia-logo-v2', + prefixedText: 'File:Wikipedia-logo-v2.svg' + }, + + { + url: '/wiki/images/Anticlockwise_heliotrope%27s.jpg', + typeOfUrl: 'Unhashed local file', + nameText: 'Anticlockwise heliotrope\'s', + prefixedText: 'File:Anticlockwise heliotrope\'s.jpg' + }, + + { + url: '', + typeOfUrl: 'Empty string' + }, + + { + url: 'foo', + typeOfUrl: 'String with only alphabet characters' + }, + + { + url: 'foobar.foobar', + typeOfUrl: 'Not a file path' + }, + + { + url: '/a/a0/blah blah blah', + typeOfUrl: 'Space characters' + } + ]; + + for ( i = 0; i < cases.length; i++ ) { + thisCase = cases[i]; + title = mw.Title.newFromImg( { src: thisCase.url } ); + + if ( thisCase.nameText !== undefined ) { + prefix = '[' + thisCase.typeOfUrl + ' URL' + '] '; + + assert.notStrictEqual( title, null, prefix + 'Parses successfully' ); + assert.equal( title.getNameText(), thisCase.nameText, prefix + 'Filename matches original' ); + assert.equal( title.getPrefixedText(), thisCase.prefixedText, prefix + 'File page title matches original' ); + assert.equal( title.getNamespaceId(), 6, prefix + 'Namespace ID matches File namespace' ); + } else { + assert.strictEqual( title, null, thisCase.typeOfUrl + ', should not produce an mw.Title object' ); + } + } + } ); + +}( mediaWiki, jQuery ) ); diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js index 0a9df966..be362e22 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js @@ -1,20 +1,17 @@ ( function ( mw, $ ) { - var mwLanguageCache = {}, oldGetOuterHtml, formatnumTests, specialCharactersPageName, + var mwLanguageCache = {}, formatText, formatParse, formatnumTests, specialCharactersPageName, expectedListUsers, expectedEntrypoints; + // When the expected result is the same in both modes + function assertBothModes( assert, parserArguments, expectedResult, assertMessage ) { + assert.equal( formatText.apply( null, parserArguments ), expectedResult, assertMessage + ' when format is \'text\'' ); + assert.equal( formatParse.apply( null, parserArguments ), expectedResult, assertMessage + ' when format is \'parse\'' ); + } + QUnit.module( 'mediawiki.jqueryMsg', QUnit.newMwEnvironment( { setup: function () { this.orgMwLangauge = mw.language; mw.language = $.extend( true, {}, this.orgMwLangauge ); - oldGetOuterHtml = $.fn.getOuterHtml; - $.fn.getOuterHtml = function () { - var $div = $( '<div>' ), html; - $div.append( $( this ).eq( 0 ).clone() ); - html = $div.html(); - $div.empty(); - $div = undefined; - return html; - }; // Messages that are reused in multiple tests mw.messages.set( { @@ -39,18 +36,26 @@ 'external-link-replace': 'Foo [$1 bar]' } ); + mw.config.set( { + wgArticlePath: '/wiki/$1' + } ); + specialCharactersPageName = '"Who" wants to be a millionaire & live on \'Exotic Island\'?'; - expectedListUsers = '注册' + $( '<a>' ).attr( { - title: 'Special:ListUsers', - href: mw.util.wikiGetlink( 'Special:ListUsers' ) - } ).text( '用户' ).getOuterHtml(); + expectedListUsers = '注册<a title="Special:ListUsers" href="/wiki/Special:ListUsers">用户</a>'; expectedEntrypoints = '<a href="https://www.mediawiki.org/wiki/Manual:index.php">index.php</a>'; + + formatText = mw.jqueryMsg.getMessageFunction( { + format: 'text' + } ); + + formatParse = mw.jqueryMsg.getMessageFunction( { + format: 'parse' + } ); }, teardown: function () { mw.language = this.orgMwLangauge; - $.fn.getOuterHtml = oldGetOuterHtml; } } ) ); @@ -82,18 +87,16 @@ } QUnit.test( 'Replace', 9, function ( assert ) { - var parser = mw.jqueryMsg.getMessageFunction(); - mw.messages.set( 'simple', 'Foo $1 baz $2' ); - assert.equal( parser( 'simple' ), 'Foo $1 baz $2', 'Replacements with no substitutes' ); - assert.equal( parser( 'simple', 'bar' ), 'Foo bar baz $2', 'Replacements with less substitutes' ); - assert.equal( parser( 'simple', 'bar', 'quux' ), 'Foo bar baz quux', 'Replacements with all substitutes' ); + assert.equal( formatParse( 'simple' ), 'Foo $1 baz $2', 'Replacements with no substitutes' ); + assert.equal( formatParse( 'simple', 'bar' ), 'Foo bar baz $2', 'Replacements with less substitutes' ); + assert.equal( formatParse( 'simple', 'bar', 'quux' ), 'Foo bar baz quux', 'Replacements with all substitutes' ); mw.messages.set( 'plain-input', '<foo foo="foo">x$1y<</foo>z' ); assert.equal( - parser( 'plain-input', 'bar' ), + formatParse( 'plain-input', 'bar' ), '<foo foo="foo">xbary&lt;</foo>z', 'Input is not considered html' ); @@ -101,7 +104,7 @@ mw.messages.set( 'plain-replace', 'Foo $1' ); assert.equal( - parser( 'plain-replace', '<bar bar="bar">></bar>' ), + formatParse( 'plain-replace', '<bar bar="bar">></bar>' ), 'Foo <bar bar="bar">&gt;</bar>', 'Replacement is not considered html' ); @@ -109,71 +112,68 @@ mw.messages.set( 'object-replace', 'Foo $1' ); assert.equal( - parser( 'object-replace', $( '<div class="bar">></div>' ) ), + formatParse( 'object-replace', $( '<div class="bar">></div>' ) ), 'Foo <div class="bar">></div>', 'jQuery objects are preserved as raw html' ); assert.equal( - parser( 'object-replace', $( '<div class="bar">></div>' ).get( 0 ) ), + formatParse( 'object-replace', $( '<div class="bar">></div>' ).get( 0 ) ), 'Foo <div class="bar">></div>', 'HTMLElement objects are preserved as raw html' ); assert.equal( - parser( 'object-replace', $( '<div class="bar">></div>' ).toArray() ), + formatParse( 'object-replace', $( '<div class="bar">></div>' ).toArray() ), 'Foo <div class="bar">></div>', 'HTMLElement[] arrays are preserved as raw html' ); assert.equal( - parser( 'external-link-replace', 'http://example.org/?x=y&z' ), + formatParse( 'external-link-replace', 'http://example.org/?x=y&z' ), 'Foo <a href="http://example.org/?x=y&z">bar</a>', 'Href is not double-escaped in wikilink function' ); } ); QUnit.test( 'Plural', 3, function ( assert ) { - var parser = mw.jqueryMsg.getMessageFunction(); - - assert.equal( parser( 'plural-msg', 0 ), 'Found 0 items', 'Plural test for english with zero as count' ); - assert.equal( parser( 'plural-msg', 1 ), 'Found 1 item', 'Singular test for english' ); - assert.equal( parser( 'plural-msg', 2 ), 'Found 2 items', 'Plural test for english' ); + assert.equal( formatParse( 'plural-msg', 0 ), 'Found 0 items', 'Plural test for english with zero as count' ); + assert.equal( formatParse( 'plural-msg', 1 ), 'Found 1 item', 'Singular test for english' ); + assert.equal( formatParse( 'plural-msg', 2 ), 'Found 2 items', 'Plural test for english' ); } ); QUnit.test( 'Gender', 11, function ( assert ) { // TODO: These tests should be for mw.msg once mw.msg integrated with mw.jqueryMsg // TODO: English may not be the best language for these tests. Use a language like Arabic or Russian - var user = mw.user, - parser = mw.jqueryMsg.getMessageFunction(); + var user = mw.user; user.options.set( 'gender', 'male' ); assert.equal( - parser( 'gender-msg', 'Bob', 'male' ), + formatParse( 'gender-msg', 'Bob', 'male' ), 'Bob: blue', 'Masculine from string "male"' ); assert.equal( - parser( 'gender-msg', 'Bob', user ), + formatParse( 'gender-msg', 'Bob', user ), 'Bob: blue', 'Masculine from mw.user object' ); user.options.set( 'gender', 'unknown' ); assert.equal( - parser( 'gender-msg', 'Foo', user ), + formatParse( 'gender-msg', 'Foo', user ), 'Foo: green', 'Neutral from mw.user object' ); assert.equal( - parser( 'gender-msg', 'Alice', 'female' ), + formatParse( 'gender-msg', 'Alice', 'female' ), 'Alice: pink', 'Feminine from string "female"' ); assert.equal( - parser( 'gender-msg', 'User' ), + formatParse( 'gender-msg', 'User' ), 'User: green', 'Neutral when no parameter given' ); assert.equal( - parser( 'gender-msg', 'User', 'unknown' ), + formatParse( 'gender-msg', 'User', 'unknown' ), 'User: green', 'Neutral from string "unknown"' ); @@ -181,43 +181,41 @@ mw.messages.set( 'gender-msg-one-form', '{{GENDER:$1|User}}: $2 {{PLURAL:$2|edit|edits}}' ); assert.equal( - parser( 'gender-msg-one-form', 'male', 10 ), + formatParse( 'gender-msg-one-form', 'male', 10 ), 'User: 10 edits', 'Gender neutral and plural form' ); assert.equal( - parser( 'gender-msg-one-form', 'female', 1 ), + formatParse( 'gender-msg-one-form', 'female', 1 ), 'User: 1 edit', 'Gender neutral and singular form' ); mw.messages.set( 'gender-msg-lowercase', '{{gender:$1|he|she}} is awesome' ); assert.equal( - parser( 'gender-msg-lowercase', 'male' ), + formatParse( 'gender-msg-lowercase', 'male' ), 'he is awesome', 'Gender masculine' ); assert.equal( - parser( 'gender-msg-lowercase', 'female' ), + formatParse( 'gender-msg-lowercase', 'female' ), 'she is awesome', 'Gender feminine' ); mw.messages.set( 'gender-msg-wrong', '{{gender}} test' ); assert.equal( - parser( 'gender-msg-wrong', 'female' ), + formatParse( 'gender-msg-wrong', 'female' ), ' test', 'Invalid syntax should result in {{gender}} simply being stripped away' ); } ); QUnit.test( 'Grammar', 2, function ( assert ) { - var parser = mw.jqueryMsg.getMessageFunction(); - - assert.equal( parser( 'grammar-msg' ), 'Przeszukaj ' + mw.config.get( 'wgSiteName' ), 'Grammar Test with sitename' ); + assert.equal( formatParse( 'grammar-msg' ), 'Przeszukaj ' + mw.config.get( 'wgSiteName' ), 'Grammar Test with sitename' ); mw.messages.set( 'grammar-msg-wrong-syntax', 'Przeszukaj {{GRAMMAR:grammar_case_xyz}}' ); - assert.equal( parser( 'grammar-msg-wrong-syntax' ), 'Przeszukaj ', 'Grammar Test with wrong grammar template syntax' ); + assert.equal( formatParse( 'grammar-msg-wrong-syntax' ), 'Przeszukaj ', 'Grammar Test with wrong grammar template syntax' ); } ); QUnit.test( 'Match PHP parser', mw.libs.phpParserData.tests.length, function ( assert ) { @@ -242,8 +240,7 @@ } ); QUnit.test( 'Links', 6, function ( assert ) { - var parser = mw.jqueryMsg.getMessageFunction(), - expectedDisambiguationsText, + var expectedDisambiguationsText, expectedMultipleBars, expectedSpecialCharacters; @@ -252,26 +249,24 @@ the bold was removed because it is not yet implemented. */ - assert.equal( - parser( 'jquerymsg-test-statistics-users' ), + assert.htmlEqual( + formatParse( 'jquerymsg-test-statistics-users' ), expectedListUsers, 'Piped wikilink' ); expectedDisambiguationsText = 'The following pages contain at least one link to a disambiguation page.\nThey may have to link to a more appropriate page instead.\nA page is treated as a disambiguation page if it uses a template that is linked from ' + - $( '<a>' ).attr( { - title: 'MediaWiki:Disambiguationspage', - href: mw.util.wikiGetlink( 'MediaWiki:Disambiguationspage' ) - } ).text( 'MediaWiki:Disambiguationspage' ).getOuterHtml() + '.'; + '<a title="MediaWiki:Disambiguationspage" href="/wiki/MediaWiki:Disambiguationspage">MediaWiki:Disambiguationspage</a>.'; + mw.messages.set( 'disambiguations-text', 'The following pages contain at least one link to a disambiguation page.\nThey may have to link to a more appropriate page instead.\nA page is treated as a disambiguation page if it uses a template that is linked from [[MediaWiki:Disambiguationspage]].' ); - assert.equal( - parser( 'disambiguations-text' ), + assert.htmlEqual( + formatParse( 'disambiguations-text' ), expectedDisambiguationsText, 'Wikilink without pipe' ); - assert.equal( - parser( 'jquerymsg-test-version-entrypoints-index-php' ), + assert.htmlEqual( + formatParse( 'jquerymsg-test-version-entrypoints-index-php' ), expectedEntrypoints, 'External link' ); @@ -279,30 +274,24 @@ // Pipe trick is not supported currently, but should not parse as text either. mw.messages.set( 'pipe-trick', '[[Tampa, Florida|]]' ); assert.equal( - parser( 'pipe-trick' ), + formatParse( 'pipe-trick' ), 'pipe-trick: Parse error at position 0 in input: [[Tampa, Florida|]]', 'Pipe trick should return error string.' ); - expectedMultipleBars = $( '<a>' ).attr( { - title: 'Main Page', - href: mw.util.wikiGetlink( 'Main Page' ) - } ).text( 'Main|Page' ).getOuterHtml(); + expectedMultipleBars = '<a title="Main Page" href="/wiki/Main_Page">Main|Page</a>'; mw.messages.set( 'multiple-bars', '[[Main Page|Main|Page]]' ); - assert.equal( - parser( 'multiple-bars' ), + assert.htmlEqual( + formatParse( 'multiple-bars' ), expectedMultipleBars, 'Bar in anchor' ); - expectedSpecialCharacters = $( '<a>' ).attr( { - title: specialCharactersPageName, - href: mw.util.wikiGetlink( specialCharactersPageName ) - } ).text( specialCharactersPageName ).getOuterHtml(); + expectedSpecialCharacters = '<a title=""Who" wants to be a millionaire & live on 'Exotic Island'?" href="/wiki/%22Who%22_wants_to_be_a_millionaire_%26_live_on_%27Exotic_Island%27%3F">"Who" wants to be a millionaire & live on 'Exotic Island'?</a>'; mw.messages.set( 'special-characters', '[[' + specialCharactersPageName + ']]' ); - assert.equal( - parser( 'special-characters' ), + assert.htmlEqual( + formatParse( 'special-characters' ), expectedSpecialCharacters, 'Special characters' ); @@ -310,32 +299,16 @@ // Tests that {{-transformation vs. general parsing are done as requested QUnit.test( 'Curly brace transformation', 14, function ( assert ) { - var formatText, formatParse, oldUserLang; - - oldUserLang = mw.config.get( 'wgUserLanguage' ); - - formatText = mw.jqueryMsg.getMessageFunction( { - format: 'text' - } ); - - formatParse = mw.jqueryMsg.getMessageFunction( { - format: 'parse' - } ); - - // When the expected result is the same in both modes - function assertBothModes( parserArguments, expectedResult, assertMessage ) { - assert.equal( formatText.apply( null, parserArguments ), expectedResult, assertMessage + ' when format is \'text\'' ); - assert.equal( formatParse.apply( null, parserArguments ), expectedResult, assertMessage + ' when format is \'parse\'' ); - } + var oldUserLang = mw.config.get( 'wgUserLanguage' ); - assertBothModes( ['gender-msg', 'Bob', 'male'], 'Bob: blue', 'gender is resolved' ); + assertBothModes( assert, ['gender-msg', 'Bob', 'male'], 'Bob: blue', 'gender is resolved' ); - assertBothModes( ['plural-msg', 5], 'Found 5 items', 'plural is resolved' ); + assertBothModes( assert, ['plural-msg', 5], 'Found 5 items', 'plural is resolved' ); - assertBothModes( ['grammar-msg'], 'Przeszukaj ' + mw.config.get( 'wgSiteName' ), 'grammar is resolved' ); + assertBothModes( assert, ['grammar-msg'], 'Przeszukaj ' + mw.config.get( 'wgSiteName' ), 'grammar is resolved' ); mw.config.set( 'wgUserLanguage', 'en' ); - assertBothModes( ['formatnum-msg', '987654321.654321'], '987,654,321.654', 'formatnum is resolved' ); + assertBothModes( assert, ['formatnum-msg', '987654321.654321'], '987,654,321.654', 'formatnum is resolved' ); // Test non-{{ wikitext, where behavior differs @@ -345,7 +318,7 @@ mw.messages.get( 'jquerymsg-test-statistics-users' ), 'Internal link message unchanged when format is \'text\'' ); - assert.equal( + assert.htmlEqual( formatParse( 'jquerymsg-test-statistics-users' ), expectedListUsers, 'Internal link message parsed when format is \'parse\'' @@ -357,7 +330,7 @@ mw.messages.get( 'jquerymsg-test-version-entrypoints-index-php' ), 'External link message unchanged when format is \'text\'' ); - assert.equal( + assert.htmlEqual( formatParse( 'jquerymsg-test-version-entrypoints-index-php' ), expectedEntrypoints, 'External link message processed when format is \'parse\'' @@ -369,7 +342,7 @@ 'Foo [http://example.com bar]', 'External link message only substitutes parameter when format is \'text\'' ); - assert.equal( + assert.htmlEqual( formatParse( 'external-link-replace', 'http://example.com' ), 'Foo <a href="http://example.com">bar</a>', 'External link message processed when format is \'parse\'' @@ -379,28 +352,25 @@ } ); QUnit.test( 'Int', 4, function ( assert ) { - var parser = mw.jqueryMsg.getMessageFunction(), - newarticletextSource = 'You have followed a link to a page that does not exist yet. To create the page, start typing in the box below (see the [[{{Int:Helppage}}|help page]] for more info). If you are here by mistake, click your browser\'s back button.', - expectedNewarticletext; + var newarticletextSource = 'You have followed a link to a page that does not exist yet. To create the page, start typing in the box below (see the [[{{Int:Helppage}}|help page]] for more info). If you are here by mistake, click your browser\'s back button.', + expectedNewarticletext, + helpPageTitle = 'Help:Contents'; - mw.messages.set( 'helppage', 'Help:Contents' ); + mw.messages.set( 'helppage', helpPageTitle ); expectedNewarticletext = 'You have followed a link to a page that does not exist yet. To create the page, start typing in the box below (see the ' + - $( '<a>' ).attr( { - title: mw.msg( 'helppage' ), - href: mw.util.wikiGetlink( mw.msg( 'helppage' ) ) - } ).text( 'help page' ).getOuterHtml() + ' for more info). If you are here by mistake, click your browser\'s back button.'; + '<a title="Help:Contents" href="/wiki/Help:Contents">help page</a> for more info). If you are here by mistake, click your browser\'s back button.'; mw.messages.set( 'newarticletext', newarticletextSource ); - assert.equal( - parser( 'newarticletext' ), + assert.htmlEqual( + formatParse( 'newarticletext' ), expectedNewarticletext, 'Link with nested message' ); assert.equal( - parser( 'see-portal-url' ), + formatParse( 'see-portal-url' ), 'Project:Community portal is an important community page.', 'Nested message' ); @@ -408,8 +378,8 @@ mw.messages.set( 'newarticletext-lowercase', newarticletextSource.replace( 'Int:Helppage', 'int:helppage' ) ); - assert.equal( - parser( 'newarticletext-lowercase' ), + assert.htmlEqual( + formatParse( 'newarticletext-lowercase' ), expectedNewarticletext, 'Link with nested message, lowercase include' ); @@ -417,7 +387,7 @@ mw.messages.set( 'uses-missing-int', '{{int:doesnt-exist}}' ); assert.equal( - parser( 'uses-missing-int' ), + formatParse( 'uses-missing-int' ), '[doesnt-exist]', 'int: where nested message does not exist' ); @@ -596,4 +566,149 @@ QUnit.test( 'formatnum', formatnumTests.length, function ( assert ) { } ); } ); +// HTML in wikitext +QUnit.test( 'HTML', 26, function ( assert ) { + mw.messages.set( 'jquerymsg-italics-msg', '<i>Very</i> important' ); + + assertBothModes( assert, ['jquerymsg-italics-msg'], mw.messages.get( 'jquerymsg-italics-msg' ), 'Simple italics unchanged' ); + + mw.messages.set( 'jquerymsg-bold-msg', '<b>Strong</b> speaker' ); + assertBothModes( assert, ['jquerymsg-bold-msg'], mw.messages.get( 'jquerymsg-bold-msg' ), 'Simple bold unchanged' ); + + mw.messages.set( 'jquerymsg-bold-italics-msg', 'It is <b><i>key</i></b>' ); + assertBothModes( assert, ['jquerymsg-bold-italics-msg'], mw.messages.get( 'jquerymsg-bold-italics-msg' ), 'Bold and italics nesting order preserved' ); + + mw.messages.set( 'jquerymsg-italics-bold-msg', 'It is <i><b>vital</b></i>' ); + assertBothModes( assert, ['jquerymsg-italics-bold-msg'], mw.messages.get( 'jquerymsg-italics-bold-msg' ), 'Italics and bold nesting order preserved' ); + + mw.messages.set( 'jquerymsg-italics-with-link', 'An <i>italicized [[link|wiki-link]]</i>' ); + + assert.htmlEqual( + formatParse( 'jquerymsg-italics-with-link' ), + 'An <i>italicized <a title="link" href="' + mw.html.escape( mw.util.getUrl( 'link' ) ) + '">wiki-link</i>', + 'Italics with link inside in parse mode' + ); + + assert.equal( + formatText( 'jquerymsg-italics-with-link' ), + mw.messages.get( 'jquerymsg-italics-with-link' ), + 'Italics with link unchanged in text mode' + ); + + mw.messages.set( 'jquerymsg-italics-id-class', '<i id="foo" class="bar">Foo</i>' ); + assert.htmlEqual( + formatParse( 'jquerymsg-italics-id-class' ), + mw.messages.get( 'jquerymsg-italics-id-class' ), + 'ID and class are allowed' + ); + + mw.messages.set( 'jquerymsg-italics-onclick', '<i onclick="alert(\'foo\')">Foo</i>' ); + assert.htmlEqual( + formatParse( 'jquerymsg-italics-onclick' ), + '<i onclick="alert(\'foo\')">Foo</i>', + 'element with onclick is escaped because it is not allowed' + ); + + mw.messages.set( 'jquerymsg-script-msg', '<script >alert( "Who put this tag here?" );</script>' ); + assert.htmlEqual( + formatParse( 'jquerymsg-script-msg' ), + '<script >alert( "Who put this tag here?" );</script>', + 'Tag outside whitelist escaped in parse mode' + ); + + assert.equal( + formatText( 'jquerymsg-script-msg' ), + mw.messages.get( 'jquerymsg-script-msg' ), + 'Tag outside whitelist unchanged in text mode' + ); + + mw.messages.set( 'jquerymsg-script-link-msg', '<script>[[Foo|bar]]</script>' ); + assert.htmlEqual( + formatParse( 'jquerymsg-script-link-msg' ), + '<script><a title="Foo" href="' + mw.html.escape( mw.util.getUrl( 'Foo' ) ) + '">bar</a></script>', + 'Script tag text is escaped because that element is not allowed, but link inside is still HTML' + ); + + mw.messages.set( 'jquerymsg-mismatched-html', '<i class="important">test</b>' ); + assert.htmlEqual( + formatParse( 'jquerymsg-mismatched-html' ), + '<i class="important">test</b>', + 'Mismatched HTML start and end tag treated as text' + ); + + // TODO (mattflaschen, 2013-03-18): It's not a security issue, but there's no real + // reason the htmlEmitter span needs to be here. It's an artifact of how emitting works. + mw.messages.set( 'jquerymsg-script-and-external-link', '<script>alert( "jquerymsg-script-and-external-link test" );</script> [http://example.com <i>Foo</i> bar]' ); + assert.htmlEqual( + formatParse( 'jquerymsg-script-and-external-link' ), + '<script>alert( "jquerymsg-script-and-external-link test" );</script> <a href="http://example.com"><span class="mediaWiki_htmlEmitter"><i>Foo</i> bar</span></a>', + 'HTML tags in external links not interfering with escaping of other tags' + ); + + mw.messages.set( 'jquerymsg-link-script', '[http://example.com <script>alert( "jquerymsg-link-script test" );</script>]' ); + assert.htmlEqual( + formatParse( 'jquerymsg-link-script' ), + '<a href="http://example.com"><span class="mediaWiki_htmlEmitter"><script>alert( "jquerymsg-link-script test" );</script></span></a>', + 'Non-whitelisted HTML tag in external link anchor treated as text' + ); + + // Intentionally not using htmlEqual for the quote tests + mw.messages.set( 'jquerymsg-double-quotes-preserved', '<i id="double">Double</i>' ); + assert.equal( + formatParse( 'jquerymsg-double-quotes-preserved' ), + mw.messages.get( 'jquerymsg-double-quotes-preserved' ), + 'Attributes with double quotes are preserved as such' + ); + + mw.messages.set( 'jquerymsg-single-quotes-normalized-to-double', '<i id=\'single\'>Single</i>' ); + assert.equal( + formatParse( 'jquerymsg-single-quotes-normalized-to-double' ), + '<i id="single">Single</i>', + 'Attributes with single quotes are normalized to double' + ); + + mw.messages.set( 'jquerymsg-escaped-double-quotes-attribute', '<i style="font-family:"Arial"">Styled</i>' ); + assert.htmlEqual( + formatParse( 'jquerymsg-escaped-double-quotes-attribute' ), + mw.messages.get( 'jquerymsg-escaped-double-quotes-attribute' ), + 'Escaped attributes are parsed correctly' + ); + + mw.messages.set( 'jquerymsg-escaped-single-quotes-attribute', '<i style=\'font-family:'Arial'\'>Styled</i>' ); + assert.htmlEqual( + formatParse( 'jquerymsg-escaped-single-quotes-attribute' ), + mw.messages.get( 'jquerymsg-escaped-single-quotes-attribute' ), + 'Escaped attributes are parsed correctly' + ); + + + mw.messages.set( 'jquerymsg-wikitext-contents-parsed', '<i>[http://example.com Example]</i>' ); + assert.htmlEqual( + formatParse( 'jquerymsg-wikitext-contents-parsed' ), + '<i><a href="http://example.com">Example</a></i>', + 'Contents of valid tag are treated as wikitext, so external link is parsed' + ); + + mw.messages.set( 'jquerymsg-wikitext-contents-script', '<i><script>Script inside</script></i>' ); + assert.htmlEqual( + formatParse( 'jquerymsg-wikitext-contents-script' ), + '<i><span class="mediaWiki_htmlEmitter"><script>Script inside</script></span></i>', + 'Contents of valid tag are treated as wikitext, so invalid HTML element is treated as text' + ); + + mw.messages.set( 'jquerymsg-unclosed-tag', 'Foo<tag>bar' ); + assert.htmlEqual( + formatParse( 'jquerymsg-unclosed-tag' ), + 'Foo<tag>bar', + 'Nonsupported unclosed tags are escaped' + ); + + mw.messages.set( 'jquerymsg-self-closing-tag', 'Foo<tag/>bar' ); + assert.htmlEqual( + formatParse( 'jquerymsg-self-closing-tag' ), + 'Foo<tag/>bar', + 'Self-closing tags don\'t cause a parse error' + ); +} ); + }( mediaWiki, jQuery ) ); diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.test.js index 01e78f61..bd4d1d21 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.test.js @@ -15,11 +15,17 @@ 'gender-plural-msg': '{{GENDER:$1|he|she|they}} {{PLURAL:$2|is|are}} awesome', 'grammar-msg': 'Przeszukaj {{GRAMMAR:grammar_case_foo|{{SITENAME}}}}', 'formatnum-msg': '{{formatnum:$1}}', - 'int-msg': 'Some {{int:other-message}}' + 'int-msg': 'Some {{int:other-message}}', + 'mediawiki-test-version-entrypoints-index-php': '[https://www.mediawiki.org/wiki/Manual:index.php index.php]', + 'external-link-replace': 'Foo [$1 bar]' } ); - // For formatnum tests - mw.config.set( 'wgUserLanguage', 'en' ); + mw.config.set( { + wgArticlePath: '/wiki/$1', + + // For formatnum tests + wgUserLanguage: 'en' + } ); specialCharactersPageName = '"Who" wants to be a millionaire & live on \'Exotic Island\'?'; } @@ -124,7 +130,7 @@ assert.ok( mw.config instanceof mw.Map, 'mw.config instance of mw.Map' ); } ); - QUnit.test( 'mw.message & mw.messages', 54, function ( assert ) { + QUnit.test( 'mw.message & mw.messages', 100, function ( assert ) { var goodbye, hello; // Convenience method for asserting the same result for multiple formats @@ -158,11 +164,24 @@ assert.equal( hello.escaped(), 'Hello <b>awesome</b> world', 'Message.escaped returns the escaped message' ); assert.equal( hello.format, 'escaped', 'Message.escaped correctly updated the "format" property' ); - assert.ok( mw.messages.set( 'escaped-with-curly-brace', '"{{SITENAME}}" is the home of {{int:other-message}}' ) ); - assert.equal( mw.message( 'escaped-with-curly-brace' ).escaped(), mw.html.escape( '"' + mw.config.get( 'wgSiteName' ) + '" is the home of Other Message' ), 'Escaped format works correctly for curly brace message' ); + assert.ok( mw.messages.set( 'multiple-curly-brace', '"{{SITENAME}}" is the home of {{int:other-message}}' ), 'mw.messages.set: Register' ); + assertMultipleFormats( ['multiple-curly-brace'], ['text', 'parse'], '"' + mw.config.get( 'wgSiteName') + '" is the home of Other Message', 'Curly brace format works correctly' ); + assert.equal( mw.message( 'multiple-curly-brace' ).plain(), mw.messages.get( 'multiple-curly-brace' ), 'Plain format works correctly for curly brace message' ); + assert.equal( mw.message( 'multiple-curly-brace' ).escaped(), mw.html.escape( '"' + mw.config.get( 'wgSiteName') + '" is the home of Other Message' ), 'Escaped format works correctly for curly brace message' ); + + assert.ok( mw.messages.set( 'multiple-square-brackets-and-ampersand', 'Visit the [[Project:Community portal|community portal]] & [[Project:Help desk|help desk]]' ), 'mw.messages.set: Register' ); + assertMultipleFormats( ['multiple-square-brackets-and-ampersand'], ['plain', 'text'], mw.messages.get( 'multiple-square-brackets-and-ampersand' ), 'Square bracket message is not processed' ); + assert.equal( mw.message( 'multiple-square-brackets-and-ampersand' ).escaped(), 'Visit the [[Project:Community portal|community portal]] & [[Project:Help desk|help desk]]', 'Escaped format works correctly for square bracket message' ); + assert.htmlEqual( mw.message( 'multiple-square-brackets-and-ampersand' ).parse(), 'Visit the ' + + '<a title="Project:Community portal" href="/wiki/Project:Community_portal">community portal</a>' + + ' & <a title="Project:Help desk" href="/wiki/Project:Help_desk">help desk</a>', 'Internal links work with parse' ); - assert.ok( mw.messages.set( 'escaped-with-square-brackets', 'Visit the [[Project:Community portal|community portal]] & [[Project:Help desk|help desk]]' ) ); - assert.equal( mw.message( 'escaped-with-square-brackets' ).escaped(), 'Visit the [[Project:Community portal|community portal]] & [[Project:Help desk|help desk]]', 'Escaped format works correctly for square bracket message' ); + assertMultipleFormats( ['mediawiki-test-version-entrypoints-index-php'], ['plain', 'text', 'escaped'], mw.messages.get( 'mediawiki-test-version-entrypoints-index-php' ), 'External link markup is unprocessed' ); + assert.htmlEqual( mw.message( 'mediawiki-test-version-entrypoints-index-php' ).parse(), '<a href="https://www.mediawiki.org/wiki/Manual:index.php">index.php</a>', 'External link works correctly in parse mode' ); + + assertMultipleFormats( ['external-link-replace', 'http://example.org/?x=y&z'], ['plain', 'text'] , 'Foo [http://example.org/?x=y&z bar]', 'Parameters are substituted but external link is not processed' ); + assert.equal( mw.message( 'external-link-replace', 'http://example.org/?x=y&z' ).escaped(), 'Foo [http://example.org/?x=y&z bar]', 'In escaped mode, parameters are substituted and ampersand is escaped, but external link is not processed' ); + assert.htmlEqual( mw.message( 'external-link-replace', 'http://example.org/?x=y&z' ).parse(), 'Foo <a href="http://example.org/?x=y&z">bar</a>', 'External link with replacement works in parse mode without double-escaping' ); hello.parse(); assert.equal( hello.format, 'parse', 'Message.parse correctly updated the "format" property' ); @@ -186,6 +205,16 @@ assertMultipleFormats( ['plural-test-msg', 6], ['text', 'parse', 'escaped'], 'There are 6 results', 'plural get resolved' ); assert.equal( mw.message( 'plural-test-msg', 6 ).plain(), 'There {{PLURAL:6|is|are}} 6 {{PLURAL:6|result|results}}', 'Parameter is substituted but plural is not resolved in plain' ); + assert.ok( mw.messages.set( 'plural-test-msg-explicit', 'There {{plural:$1|is one car|are $1 cars|0=are no cars|12=are a dozen cars}}' ), 'mw.messages.set: Register message with explicit plural forms' ); + assertMultipleFormats( ['plural-test-msg-explicit', 12], ['text', 'parse', 'escaped'], 'There are a dozen cars', 'explicit plural get resolved' ); + + assert.ok( mw.messages.set( 'plural-test-msg-explicit-beginning', 'Basket has {{plural:$1|0=no eggs|12=a dozen eggs|6=half a dozen eggs|one egg|$1 eggs}}' ), 'mw.messages.set: Register message with explicit plural forms' ); + assertMultipleFormats( ['plural-test-msg-explicit-beginning', 1], ['text', 'parse', 'escaped'], 'Basket has one egg', 'explicit plural given at beginning get resolved for singular' ); + assertMultipleFormats( ['plural-test-msg-explicit-beginning', 4], ['text', 'parse', 'escaped'], 'Basket has 4 eggs', 'explicit plural given at beginning get resolved for plural' ); + assertMultipleFormats( ['plural-test-msg-explicit-beginning', 6], ['text', 'parse', 'escaped'], 'Basket has half a dozen eggs', 'explicit plural given at beginning get resolved for 6' ); + assertMultipleFormats( ['plural-test-msg-explicit-beginning', 0], ['text', 'parse', 'escaped'], 'Basket has no eggs', 'explicit plural given at beginning get resolved for 0' ); + + assertMultipleFormats( ['mediawiki-test-pagetriage-del-talk-page-notify-summary'], ['plain', 'text'], mw.messages.get( 'mediawiki-test-pagetriage-del-talk-page-notify-summary' ), 'Double square brackets with no parameters unchanged' ); assertMultipleFormats( ['mediawiki-test-pagetriage-del-talk-page-notify-summary', specialCharactersPageName], ['plain', 'text'], 'Notifying author of deletion nomination for [[' + specialCharactersPageName + ']]', 'Double square brackets with one parameter' ); @@ -196,7 +225,7 @@ assert.ok( mw.messages.set( 'mediawiki-test-categorytree-collapse-bullet', '[<b>−</b>]' ), 'mw.messages.set: Register' ); assert.equal( mw.message( 'mediawiki-test-categorytree-collapse-bullet' ).plain(), mw.messages.get( 'mediawiki-test-categorytree-collapse-bullet' ), 'Single square brackets unchanged in plain mode' ); - assert.ok( mw.messages.set( 'mediawiki-test-wikieditor-toolbar-help-content-signature-result', '<a href=\'#\' title=\'{{#special:mypage}}\'>Username</a> (<a href=\'#\' title=\'{{#special:mytalk}}\'>talk</a>)' ) ); + assert.ok( mw.messages.set( 'mediawiki-test-wikieditor-toolbar-help-content-signature-result', '<a href=\'#\' title=\'{{#special:mypage}}\'>Username</a> (<a href=\'#\' title=\'{{#special:mytalk}}\'>talk</a>)' ), 'mw.messages.set: Register' ); assert.equal( mw.message( 'mediawiki-test-wikieditor-toolbar-help-content-signature-result' ).plain(), mw.messages.get( 'mediawiki-test-wikieditor-toolbar-help-content-signature-result' ), 'HTML message with curly braces is not changed in plain mode' ); assertMultipleFormats( ['gender-plural-msg', 'male', 1], ['text', 'parse', 'escaped'], 'he is awesome', 'Gender and plural are resolved' ); @@ -211,6 +240,42 @@ assertMultipleFormats( ['int-msg'], ['text', 'parse', 'escaped'], 'Some Other Message', 'int is resolved' ); assert.equal( mw.message( 'int-msg' ).plain(), mw.messages.get( 'int-msg' ), 'int is not resolved in plain mode' ); + + assert.ok( mw.messages.set( 'mediawiki-italics-msg', '<i>Very</i> important' ), 'mw.messages.set: Register' ); + assertMultipleFormats( ['mediawiki-italics-msg'], ['plain', 'text', 'parse'], mw.messages.get( 'mediawiki-italics-msg' ), 'Simple italics unchanged' ); + assert.htmlEqual( + mw.message( 'mediawiki-italics-msg' ).escaped(), + '<i>Very</i> important', + 'Italics are escaped in escaped mode' + ); + + assert.ok( mw.messages.set( 'mediawiki-italics-with-link', 'An <i>italicized [[link|wiki-link]]</i>' ), 'mw.messages.set: Register' ); + assertMultipleFormats( ['mediawiki-italics-with-link'], ['plain', 'text'], mw.messages.get( 'mediawiki-italics-with-link' ), 'Italics with link unchanged' ); + assert.htmlEqual( + mw.message( 'mediawiki-italics-with-link' ).escaped(), + 'An <i>italicized [[link|wiki-link]]</i>', + 'Italics and link unchanged except for escaping in escaped mode' + ); + assert.htmlEqual( + mw.message( 'mediawiki-italics-with-link' ).parse(), + 'An <i>italicized <a title="link" href="' + mw.util.getUrl( 'link' ) + '">wiki-link</i>', + 'Italics with link inside in parse mode' + ); + + assert.ok( mw.messages.set( 'mediawiki-script-msg', '<script >alert( "Who put this script here?" );</script>' ), 'mw.messages.set: Register' ); + assertMultipleFormats( ['mediawiki-script-msg'], ['plain', 'text'], mw.messages.get( 'mediawiki-script-msg' ), 'Script unchanged' ); + assert.htmlEqual( + mw.message( 'mediawiki-script-msg' ).escaped(), + '<script >alert( "Who put this script here?" );</script>', + 'Script escaped when using escaped format' + ); + assert.htmlEqual( + mw.message( 'mediawiki-script-msg' ).parse(), + '<script >alert( "Who put this script here?" );</script>', + 'Script escaped when using parse format' + ); + + } ); QUnit.test( 'mw.msg', 14, function ( assert ) { @@ -218,7 +283,7 @@ assert.equal( mw.msg( 'hello' ), 'Hello <b>awesome</b> world', 'Gets message with default options (existing message)' ); assert.equal( mw.msg( 'goodbye' ), '<goodbye>', 'Gets message with default options (nonexistent message)' ); - assert.ok( mw.messages.set( 'plural-item', 'Found $1 {{PLURAL:$1|item|items}}' ) ); + assert.ok( mw.messages.set( 'plural-item' , 'Found $1 {{PLURAL:$1|item|items}}' ), 'mw.messages.set: Register' ); assert.equal( mw.msg( 'plural-item', 5 ), 'Found 5 items', 'Apply plural for count 5' ); assert.equal( mw.msg( 'plural-item', 0 ), 'Found 0 items', 'Apply plural for count 0' ); assert.equal( mw.msg( 'plural-item', 1 ), 'Found 1 item', 'Apply plural for count 1' ); @@ -762,4 +827,90 @@ } ); + QUnit.test( 'mw.hook', 10, function ( assert ) { + var hook, add, fire, chars, callback; + + mw.hook( 'test.hook.unfired' ).add( function () { + assert.ok( false, 'Unfired hook' ); + } ); + + mw.hook( 'test.hook.basic' ).add( function () { + assert.ok( true, 'Basic callback' ); + } ); + mw.hook( 'test.hook.basic' ).fire(); + + mw.hook( 'test.hook.data' ).add( function ( data1, data2 ) { + assert.equal( data1, 'example', 'Fire with data (string param)' ); + assert.deepEqual( data2, ['two'], 'Fire with data (array param)' ); + } ); + mw.hook( 'test.hook.data' ).fire( 'example', ['two'] ); + + mw.hook( 'test.hook.chainable' ).add( function () { + assert.ok( true, 'Chainable' ); + } ).fire(); + + hook = mw.hook( 'test.hook.detach' ); + add = hook.add; + fire = hook.fire; + add( function ( x, y ) { + assert.deepEqual( [x, y], ['x', 'y'], 'Detached (contextless) with data' ); + } ); + fire( 'x', 'y' ); + + mw.hook( 'test.hook.fireBefore' ).fire().add( function () { + assert.ok( true, 'Invoke handler right away if it was fired before' ); + } ); + + mw.hook( 'test.hook.fireTwiceBefore' ).fire().fire().add( function () { + assert.ok( true, 'Invoke handler right away if it was fired before (only last one)' ); + } ); + + chars = []; + + mw.hook( 'test.hook.many' ) + .add( function ( chr ) { + chars.push( chr ); + } ) + .fire( 'x' ).fire( 'y' ).fire( 'z' ) + .add( function ( chr ) { + assert.equal( chr, 'z', 'Adding callback later invokes right away with last data' ); + } ); + + assert.deepEqual( chars, ['x', 'y', 'z'], 'Multiple callbacks with multiple fires' ); + + chars = []; + callback = function ( chr ) { + chars.push( chr ); + }; + + mw.hook( 'test.hook.variadic' ) + .add( + callback, + callback, + function ( chr ) { + chars.push( chr ); + }, + callback + ) + .fire( 'x' ) + .remove( + function () { + 'not-added'; + }, + callback + ) + .fire( 'y' ) + .remove( callback ) + .fire( 'z' ); + + assert.deepEqual( + chars, + ['x', 'x', 'x', 'x', 'y', 'z'], + '"add" and "remove" support variadic arguments. ' + + '"add" does not filter unique. ' + + '"remove" removes all equal by reference. ' + + '"remove" is silent if the function is not found' + ); + } ); + }( mediaWiki, jQuery ) ); diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.user.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.user.test.js index 875ab91a..96be3d1f 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.user.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.user.test.js @@ -5,7 +5,7 @@ assert.ok( mw.user.options instanceof mw.Map, 'options instance of mw.Map' ); } ); - QUnit.test( 'user status', 9, function ( assert ) { + QUnit.test( 'user status', 11, function ( assert ) { /** * Tests can be run under three different conditions: * 1) From tests/qunit/index.html, user will be anonymous. @@ -15,19 +15,23 @@ // Forge an anonymous user: mw.config.set( 'wgUserName', null ); + delete mw.config.values.wgUserId; assert.strictEqual( mw.user.getName(), null, 'user.getName() returns null when anonymous' ); assert.strictEqual( mw.user.name(), null, 'user.name() compatibility' ); assert.assertTrue( mw.user.isAnon(), 'user.isAnon() returns true when anonymous' ); assert.assertTrue( mw.user.anonymous(), 'user.anonymous() compatibility' ); + assert.strictEqual( mw.user.getId(), 0, 'user.getId() returns 0 when anonymous' ); // Not part of startUp module mw.config.set( 'wgUserName', 'John' ); + mw.config.set( 'wgUserId', 123 ); assert.equal( mw.user.getName(), 'John', 'user.getName() returns username when logged-in' ); assert.equal( mw.user.name(), 'John', 'user.name() compatibility' ); assert.assertFalse( mw.user.isAnon(), 'user.isAnon() returns false when logged-in' ); assert.assertFalse( mw.user.anonymous(), 'user.anonymous() compatibility' ); + assert.strictEqual( mw.user.getId(), 123, 'user.getId() returns correct ID when logged-in' ); assert.equal( mw.user.id(), 'John', 'user.id Returns username when logged-in' ); } ); diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js index 6fc0731c..9216f0af 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js @@ -1,5 +1,13 @@ ( function ( mw, $ ) { - QUnit.module( 'mediawiki.util', QUnit.newMwEnvironment() ); + QUnit.module( 'mediawiki.util', QUnit.newMwEnvironment( { + setup: function () { + this.taPrefix = mw.util.tooltipAccessKeyPrefix; + mw.util.tooltipAccessKeyPrefix = 'ctrl-alt-'; + }, + teardown: function () { + mw.util.tooltipAccessKeyPrefix = this.taPrefix; + } + } ) ); QUnit.test( 'rawurlencode', 1, function ( assert ) { assert.equal( mw.util.rawurlencode( 'Test:A & B/Here' ), 'Test%3AA%20%26%20B%2FHere' ); @@ -9,20 +17,24 @@ assert.equal( mw.util.wikiUrlencode( 'Test:A & B/Here' ), 'Test:A_%26_B/Here' ); } ); - QUnit.test( 'wikiGetlink', 3, function ( assert ) { + QUnit.test( 'getUrl', 4, function ( assert ) { // Not part of startUp module mw.config.set( 'wgArticlePath', '/wiki/$1' ); mw.config.set( 'wgPageName', 'Foobar' ); - var href = mw.util.wikiGetlink( 'Sandbox' ); + var href = mw.util.getUrl( 'Sandbox' ); assert.equal( href, '/wiki/Sandbox', 'Simple title; Get link for "Sandbox"' ); - href = mw.util.wikiGetlink( 'Foo:Sandbox ? 5+5=10 ! (test)/subpage' ); + href = mw.util.getUrl( 'Foo:Sandbox ? 5+5=10 ! (test)/subpage' ); assert.equal( href, '/wiki/Foo:Sandbox_%3F_5%2B5%3D10_%21_%28test%29/subpage', 'Advanced title; Get link for "Foo:Sandbox ? 5+5=10 ! (test)/subpage"' ); - href = mw.util.wikiGetlink(); + href = mw.util.getUrl(); assert.equal( href, '/wiki/Foobar', 'Default title; Get link for current page ("Foobar")' ); + + href = mw.util.getUrl( 'Sandbox', { action: 'edit' } ); + assert.equal( href, '/wiki/Sandbox?action=edit', + 'Simple title with query string; Get link for "Sandbox" with action=edit' ); } ); QUnit.test( 'wikiScript', 4, function ( assert ) { @@ -76,13 +88,13 @@ assert.strictEqual( mw.util.toggleToc(), null, 'Return null if there is no table of contents on the page.' ); - tocHtml = '<table id="toc" class="toc"><tr><td>' + + tocHtml = '<div id="toc" class="toc">' + '<div id="toctitle">' + '<h2>Contents</h2>' + '<span class="toctoggle"> [<a href="#" class="internal" id="togglelink">Hide</a> ]</span>' + '</div>' + '<ul><li></li></ul>' + - '</td></tr></table>'; + '</div>'; $( tocHtml ).appendTo( '#qunit-fixture' ); $toggleLink = $( '#togglelink' ); @@ -108,10 +120,14 @@ assert.strictEqual( mw.util.getParamValue( 'TEST', url ), 'a b+c d', 'Bug 30441: getParamValue must understand "+" encoding of space (multiple spaces)' ); } ); - QUnit.test( 'tooltipAccessKey', 3, function ( assert ) { - assert.equal( typeof mw.util.tooltipAccessKeyPrefix, 'string', 'mw.util.tooltipAccessKeyPrefix must be a string' ); - assert.ok( mw.util.tooltipAccessKeyRegexp instanceof RegExp, 'mw.util.tooltipAccessKeyRegexp instance of RegExp' ); - assert.ok( mw.util.updateTooltipAccessKeys, 'mw.util.updateTooltipAccessKeys' ); + QUnit.test( 'tooltipAccessKey', 4, function ( assert ) { + assert.equal( typeof mw.util.tooltipAccessKeyPrefix, 'string', 'tooltipAccessKeyPrefix must be a string' ); + assert.equal( $.type( mw.util.tooltipAccessKeyRegexp ), 'regexp', 'tooltipAccessKeyRegexp is a regexp' ); + assert.ok( mw.util.updateTooltipAccessKeys, 'updateTooltipAccessKeys is non-empty' ); + + 'Example [a]'.replace( mw.util.tooltipAccessKeyRegexp, function ( sub, m1, m2, m3, m4, m5, m6 ) { + assert.equal( m6, 'a', 'tooltipAccessKeyRegexp finds the accesskey hint' ); + } ); } ); QUnit.test( '$content', 2, function ( assert ) { @@ -125,17 +141,18 @@ * Previously, test elements where invisible to the selector since only * one element can have a given id. */ - QUnit.test( 'addPortletLink', 8, function ( assert ) { - var pTestTb, pCustom, vectorTabs, tbRL, cuQuux, $cuQuux, tbMW, $tbMW, tbRLDM, caFoo; + QUnit.test( 'addPortletLink', 13, function ( assert ) { + var pTestTb, pCustom, vectorTabs, tbRL, cuQuux, $cuQuux, tbMW, $tbMW, tbRLDM, caFoo, + addedAfter, tbRLDMnonexistentid, tbRLDMemptyjquery; pTestTb = '\ <div class="portlet" id="p-test-tb">\ - <h5>Toolbox</h5>\ + <h3>Toolbox</h3>\ <ul class="body"></ul>\ </div>'; pCustom = '\ <div class="portlet" id="p-test-custom">\ - <h5>Views</h5>\ + <h3>Views</h3>\ <ul class="body">\ <li id="c-foo"><a href="#">Foo</a></li>\ <li id="c-barmenu">\ @@ -147,14 +164,15 @@ </div>'; vectorTabs = '\ <div id="p-test-views" class="vectorTabs">\ - <h5>Views</h5>\ + <h3>Views</h3>\ <ul></ul>\ </div>'; $( '#qunit-fixture' ).append( pTestTb, pCustom, vectorTabs ); tbRL = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/ResourceLoader', - 'ResourceLoader', 't-rl', 'More info about ResourceLoader on MediaWiki.org ', 'l' ); + 'ResourceLoader', 't-rl', 'More info about ResourceLoader on MediaWiki.org ', 'l' + ); assert.ok( $.isDomElement( tbRL ), 'addPortletLink returns a valid DOM Element according to $.isDomElement' ); @@ -162,14 +180,32 @@ 'MediaWiki.org', 't-mworg', 'Go to MediaWiki.org ', 'm', tbRL ); $tbMW = $( tbMW ); + assert.propEqual( + $tbMW.getAttrs(), + { + id: 't-mworg' + }, + 'Validate attributes of created element' + ); + + assert.propEqual( + $tbMW.find( 'a' ).getAttrs(), + { + href: '//mediawiki.org/', + title: 'Go to MediaWiki.org [ctrl-alt-m]', + accesskey: 'm' + }, + 'Validate attributes of anchor tag in created element' + ); - assert.equal( $tbMW.attr( 'id' ), 't-mworg', 'Link has correct ID set' ); assert.equal( $tbMW.closest( '.portlet' ).attr( 'id' ), 'p-test-tb', 'Link was inserted within correct portlet' ); - assert.equal( $tbMW.next().attr( 'id' ), 't-rl', 'Link is in the correct position (by passing nextnode)' ); + assert.strictEqual( $tbMW.next()[0], tbRL, 'Link is in the correct position (by passing nextnode)' ); - cuQuux = mw.util.addPortletLink( 'p-test-custom', '#', 'Quux' ); + cuQuux = mw.util.addPortletLink( 'p-test-custom', '#', 'Quux', null, 'Example [shift-x]', 'q' ); $cuQuux = $( cuQuux ); + assert.equal( $cuQuux.find( 'a' ).attr( 'title' ), 'Example [ctrl-alt-q]', 'Existing accesskey is stripped and updated' ); + assert.equal( $( '#p-test-custom #c-barmenu ul li' ).length, 1, @@ -185,6 +221,21 @@ assert.strictEqual( $tbMW.find( 'span' ).length, 0, 'No <span> element should be added for porlets without vectorTabs class.' ); assert.strictEqual( $( caFoo ).find( 'span' ).length, 1, 'A <span> element should be added for porlets with vectorTabs class.' ); + + addedAfter = mw.util.addPortletLink( 'p-test-tb', '#', 'After foo', 'post-foo', 'After foo', null, $( tbRL ) ); + assert.strictEqual( $( addedAfter ).next()[0], tbRL, 'Link is in the correct position (by passing a jQuery object as nextnode)' ); + + // test case - nonexistent id as next node + tbRLDMnonexistentid = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM', + 'Default modules', 't-rldm-nonexistent', 'List of all default modules ', 'd', '#t-rl-nonexistent' ); + + assert.equal( tbRLDMnonexistentid, $( '#p-test-tb li:last' )[0], 'Nonexistent id as nextnode adds the portlet at end' ); + + // test case - empty jquery object as next node + tbRLDMemptyjquery = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM', + 'Default modules', 't-rldm-empty-jquery', 'List of all default modules ', 'd', $( '#t-rl-nonexistent' ) ); + + assert.equal( tbRLDMemptyjquery, $( '#p-test-tb li:last' )[0], 'Empty jquery as nextnode adds the portlet at end' ); } ); QUnit.test( 'jsMessage', 1, function ( assert ) { diff --git a/tests/qunit/suites/resources/startup.test.js b/tests/qunit/suites/resources/startup.test.js new file mode 100644 index 00000000..76f32f7e --- /dev/null +++ b/tests/qunit/suites/resources/startup.test.js @@ -0,0 +1,129 @@ +/*global isCompatible: true */ +( function ( $ ) { + var testcases = { + // Supported: Compatible + gradeA: [ + // Chrome + 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16', + // Firefox 4+ + 'Mozilla/5.0 (Windows NT 6.1.1; rv:5.0) Gecko/20100101 Firefox/5.0', + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:9.0) Gecko/20100101 Firefox/9.0', + 'Mozilla/5.0 (Macintosh; I; Intel Mac OS X 11_7_9; de-LI; rv:1.9b4) Gecko/2012010317 Firefox/10.0a4', + 'Mozilla/5.0 (Windows NT 6.1; rv:12.0) Gecko/20120403211507 Firefox/12.0', + 'Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:16.0.1) Gecko/20121011 Firefox/16.0.1', + // Kindle Fire + 'Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Kindle Fire Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Safari/533.1', + // Safari 5.0+ + 'Mozilla/5.0 (Macintosh; I; Intel Mac OS X 10_6_7; ru-ru) AppleWebKit/534.31+ (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1', + // Opera 11+ + 'Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.8.131 Version/11.10', + // Internet Explorer 6+ + 'Mozilla/5.0 (compatible; MSIE 6.0; Windows NT 5.1)', + 'Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.0; en-US)', + 'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; Media Center PC 4.0; SLCC1; .NET CLR 3.0.04320)', + 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0)', + 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)', + // IE Mobile + 'Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; NOKIA; Lumia 800)', + // BlackBerry 6+ + 'Mozilla/5.0 (BlackBerry; U; BlackBerry 9300; en) AppleWebKit/534.8+ (KHTML, like Gecko) Version/6.0.0.570 Mobile Safari/534.8+', + 'Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.1.0.346 Mobile Safari/534.11+', + 'Mozilla/5.0 (BB10; Touch) AppleWebKit/537.3+ (KHTML, like Gecko) Version/10.0.9.386 Mobile Safari/537.3+', + // Open WebOS 1.4+ (HP Veer 4G) + 'Mozilla/5.0 (webOS/2.1.2; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 P160UNA/1.0', + // Firefox Mobile + 'Mozilla/5.0 (Mobile; rv:14.0) Gecko/14.0 Firefox/14.0', + // iOS + 'Mozilla/5.0 (ipod: U;CPU iPhone OS 2_2 like Mac OS X: es_es) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.0 Mobile/3B48b Safari/419.3', + 'Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3B48b Safari/419.3', + // Android + 'Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17' + ], + // Supported: Uncompatible, serve basic content + gradeB: [ + // Internet Explorer < 6 + 'Mozilla/2.0 (compatible; MSIE 3.03; Windows 3.1)', + 'Mozilla/4.0 (compatible; MSIE 4.01; Windows 95)', + 'Mozilla/4.0 (compatible; MSIE 5.0; Windows 98;)', + 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)', + // Firefox < 3.6 + 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.2) Gecko/20060308 Firefox/1.5.0.2', + 'Mozilla/5.0 (X11; U; Linux i686; nl; rv:1.8.1.1) Gecko/20070311 Firefox/2.0.0.1', + // BlackBerry < 6 + 'BlackBerry9300/5.0.0.716 Profile/MIDP-2.1 Configuration/CLDC-1.1 VendorID/133', + 'BlackBerry7250/4.0.0 Profile/MIDP-2.0 Configuration/CLDC-1.1', + // Open WebOS < 1.5 (Palm Pre, Palm Pixi) + 'Mozilla/5.0 (webOS/1.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/1.0', + 'Mozilla/5.0 (webOS/1.4.0; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 Pixi/1.1 ', + // SymbianOS + 'NokiaN95_8GB-3;Mozilla/5.0 SymbianOS/9.2;U;Series60/3.1 NokiaN95_8GB-3/11.2.011 Profile/MIDP-2.0 Configuration/CLDC-1.1 AppleWebKit/413 (KHTML, like Gecko)', + 'Nokia7610/2.0 (5.0509.0) SymbianOS/7.0s Series60/2.1 Profile/MIDP-2.0 Configuration/CLDC-1.0 ', + 'Mozilla/5.0 (SymbianOS/9.1; U; [en]; SymbianOS/91 Series60/3.0) AppleWebKit/413 (KHTML, like Gecko) Safari/413', + 'Mozilla/5.0 (SymbianOS/9.3; Series60/3.2 NokiaE52-2/091.003; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/533.4 (KHTML, like Gecko) NokiaBrowser/7.3.1.34 Mobile Safari/533.4', + // NetFront + 'Mozilla/4.0 (compatible; Linux 2.6.10) NetFront/3.3 Kindle/1.0 (screen 600x800)', + 'Mozilla/4.0 (compatible; Linux 2.6.22) NetFront/3.4 Kindle/2.0 (screen 824x1200; rotate)', + 'Mozilla/4.08 (Windows; Mobile Content Viewer/1.0) NetFront/3.2', + // Opera Mini + 'Opera/9.80 (J2ME/MIDP; Opera Mini/3.1.10423/22.387; U; en) Presto/2.5.25 Version/10.54', + 'Opera/9.50 (J2ME/MIDP; Opera Mini/4.0.10031/298; U; en)', + 'Opera/9.80 (J2ME/MIDP; Opera Mini/6.24093/26.1305; U; en) Presto/2.8.119 Version/10.54', + 'Opera/9.80 (Android; Opera Mini/7.29530/27.1407; U; en) Presto/2.8.119 Version/11.10', + // Ovi Browser + 'Mozilla/5.0 (Series40; NokiaX3-02/05.60; Profile/MIDP-2.1 Configuration/CLDC-1.1) Gecko/20100401 S40OviBrowser/3.2.0.0.6', + 'Mozilla/5.0 (Series40; Nokia305/05.92; Profile/MIDP-2.1 Configuration/CLDC-1.1) Gecko/20100401 S40OviBrowser/3.7.0.0.11' + ], + // No explicit support for or against these browsers, they're + // given a shot at Grade A at their own risk. + gradeX: [ + // Firefox 3.6 + 'Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3', + // Gecko + 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.7) Gecko/20060928 (Debian|Debian-1.8.0.7-1) Epiphany/2.14', + 'Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.8.1.6) Gecko/20070817 IceWeasel/2.0.0.6-g2', + // KHTML + 'Mozilla/5.0 (compatible; Konqueror/4.3; Linux) KHTML/4.3.5 (like Gecko)', + // Text browsers + 'Links (2.1pre33; Darwin 8.11.0 Power Macintosh; x)', + 'Links (6.9; Unix 6.9-astral sparc; 80x25)', + 'Lynx/2.8.6rel.4 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/0.9.8g', + 'w3m/0.5.1', + // Bots + 'Googlebot/2.1 (+http://www.google.com/bot.html)', + 'Mozilla/5.0 (compatible; googlebot/2.1; +http://www.google.com/bot.html)', + 'Mozilla/5.0 (compatible; YandexBot/3.0)', + // Scripts + 'curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5', + 'Wget/1.9', + 'Wget/1.10.1 (Red Hat modified)', + // Unknown + 'I\'m an unknown browser', + // Empty + '' + ] + }; + + QUnit.module( 'startup', QUnit.newMwEnvironment() ); + + QUnit.test( 'isCompatible( Grade A )', testcases.gradeA.length, function ( assert ) { + $.each( testcases.gradeA, function ( i, ua ) { + assert.strictEqual( isCompatible( ua ), true, ua ); + } + ); + } ); + + QUnit.test( 'isCompatible( Grade B )', testcases.gradeB.length, function ( assert ) { + $.each( testcases.gradeB, function ( i, ua ) { + assert.strictEqual( isCompatible( ua ), false, ua ); + } + ); + } ); + + QUnit.test( 'isCompatible( Grade X )', testcases.gradeX.length, function ( assert ) { + $.each( testcases.gradeX, function ( i, ua ) { + assert.strictEqual( isCompatible( ua ), true, ua ); + } + ); + } ); + +}( jQuery ) ); diff --git a/tests/selenium/Selenium.php b/tests/selenium/Selenium.php deleted file mode 100644 index 07f98671..00000000 --- a/tests/selenium/Selenium.php +++ /dev/null @@ -1,191 +0,0 @@ -<?php -/** - * Selenium connector - * This is implemented as a singleton. - */ - -require( 'Testing/Selenium.php' ); - -class Selenium { - protected static $_instance = null; - - public $isStarted = false; - public $tester; - - protected $port; - protected $host; - protected $browser; - protected $browsers; - protected $logger; - protected $user; - protected $pass; - protected $timeout = 30000; - protected $verbose; - protected $junitlogfile; //processed by phpUnderControl - protected $runagainstgrid = false; - - /** - * @todo this shouldn't have to be static - */ - static protected $url; - - /** - * Override parent - */ - public function __construct() { - /** - * @todo this is an ugly hack to make information available to - * other tests. It should be fixed. - */ - if ( null === self::$_instance ) { - self::$_instance = $this; - } else { - throw new MWException( "Already have one Selenium instance." ); - } - } - - public function start() { - $this->tester = new Testing_Selenium( $this->browser, self::$url, $this->host, - $this->port, $this->timeout ); - if ( method_exists( $this->tester, "setVerbose" ) ) { - $this->tester->setVerbose( $this->verbose ); - } - - $this->tester->start(); - $this->isStarted = true; - } - - public function stop() { - $this->tester->stop(); - $this->tester = null; - $this->isStarted = false; - } - - public function login() { - if ( strlen( $this->user ) == 0 ) { - return; - } - $this->open( self::$url . '/index.php?title=Special:Userlogin' ); - $this->type( 'wpName1', $this->user ); - $this->type( 'wpPassword1', $this->pass ); - $this->click( "//input[@id='wpLoginAttempt']" ); - $this->waitForPageToLoad( 10000 ); - - // after login we redirect to the main page. So check whether the "Prefernces" top menu item exists - $value = $this->isElementPresent( "//li[@id='pt-preferences']" ); - - if ( $value != true ) { - throw new Testing_Selenium_Exception( "Login Failed" ); - } - - } - - public static function getInstance() { - if ( null === self::$_instance ) { - throw new MWException( "No instance set yet" ); - } - - return self::$_instance; - } - - public function loadPage( $title, $action ) { - $this->open( self::$url . '/index.php?title=' . $title . '&action=' . $action ); - } - - public function setLogger( $logger ) { - $this->logger = $logger; - } - - public function getLogger() { - return $this->logger; - } - - public function log( $message ) { - $this->logger->write( $message ); - } - - public function setUrl( $url ) { - self::$url = $url; - } - - public static function getUrl() { - return self::$url; - } - - public function setPort( $port ) { - $this->port = $port; - } - - public function getPort() { - return $this->port; - } - - public function setUser( $user ) { - $this->user = $user; - } - - // Function to get username - public function getUser() { - return $this->user; - } - - - public function setPass( $pass ) { - $this->pass = $pass; - } - - //add function to get password - public function getPass() { - return $this->pass; - } - - public function setHost( $host ) { - $this->host = $host; - } - - public function setVerbose( $verbose ) { - $this->verbose = $verbose; - } - - public function setAvailableBrowsers( $availableBrowsers ) { - $this->browsers = $availableBrowsers; - } - - public function setJUnitLogfile( $junitlogfile ) { - $this->junitlogfile = $junitlogfile; - } - - public function getJUnitLogfile() { - return $this->junitlogfile; - } - - public function setRunAgainstGrid( $runagainstgrid ) { - $this->runagainstgrid = $runagainstgrid; - } - - public function setBrowser( $b ) { - if ( $this->runagainstgrid ) { - $this->browser = $b; - return true; - } - if ( !isset( $this->browsers[$b] ) ) { - throw new MWException( "Invalid Browser: $b.\n" ); - } - - $this->browser = $this->browsers[$b]; - } - - public function getAvailableBrowsers() { - return $this->browsers; - } - - public function __call( $name, $args ) { - $t = call_user_func_array( array( $this->tester, $name ), $args ); - return $t; - } - - // Prevent external cloning - protected function __clone() {} - // Prevent external construction - // protected function __construct() {} -} diff --git a/tests/selenium/SeleniumConfig.php b/tests/selenium/SeleniumConfig.php deleted file mode 100644 index 0823275c..00000000 --- a/tests/selenium/SeleniumConfig.php +++ /dev/null @@ -1,80 +0,0 @@ -<?php -if ( !defined( 'SELENIUMTEST' ) ) { - die( 1 ); -} - -class SeleniumConfig { - - /** - * Retreives the Selenium configuration values from an ini file. - * See sample config file in selenium_settings.ini.sample - * - */ - public static function getSeleniumSettings( &$seleniumSettings, - &$seleniumBrowsers, - &$seleniumTestSuites, - $seleniumConfigFile = null ) { - if ( strlen( $seleniumConfigFile ) == 0 ) { - global $wgSeleniumConfigFile; - if ( isset( $wgSeleniumConfigFile ) ) { - $seleniumConfigFile = $wgSeleniumConfigFile; - } - } - - if ( strlen( $seleniumConfigFile ) == 0 || !file_exists( $seleniumConfigFile ) ) { - throw new MWException( "Unable to read local Selenium Settings from " . $seleniumConfigFile . "\n" ); - } - - $configArray = parse_ini_file( $seleniumConfigFile, true ); - if ( $configArray === false ) { - throw new MWException( "Error parsing " . $seleniumConfigFile . "\n" ); - } - - if ( array_key_exists( 'SeleniumSettings', $configArray ) ) { - wfSuppressWarnings(); - //we may need to change how this is set. But for now leave it in the ini file - $seleniumBrowsers = $configArray['SeleniumSettings']['browsers']; - - $seleniumSettings['host'] = $configArray['SeleniumSettings']['host']; - $seleniumSettings['port'] = $configArray['SeleniumSettings']['port']; - $seleniumSettings['wikiUrl'] = $configArray['SeleniumSettings']['wikiUrl']; - $seleniumSettings['username'] = $configArray['SeleniumSettings']['username']; - $seleniumSettings['userPassword'] = $configArray['SeleniumSettings']['userPassword']; - $seleniumSettings['testBrowser'] = $configArray['SeleniumSettings']['testBrowser']; - $seleniumSettings['startserver'] = $configArray['SeleniumSettings']['startserver']; - $seleniumSettings['stopserver'] = $configArray['SeleniumSettings']['stopserver']; - $seleniumSettings['seleniumserverexecpath'] = $configArray['SeleniumSettings']['seleniumserverexecpath']; - $seleniumSettings['jUnitLogFile'] = $configArray['SeleniumSettings']['jUnitLogFile']; - $seleniumSettings['runAgainstGrid'] = $configArray['SeleniumSettings']['runAgainstGrid']; - - wfRestoreWarnings(); - } - if ( array_key_exists( 'SeleniumTests', $configArray ) ) { - wfSuppressWarnings(); - $seleniumTestSuites = $configArray['SeleniumTests']['testSuite']; - wfRestoreWarnings(); - } - return true; - } - - private static function parse_ini_line( $iniLine ) { - static $specialValues = array( 'false' => false, 'true' => true, 'null' => null ); - list( $key, $value ) = explode( '=', $iniLine, 2 ); - $key = trim( $key ); - $value = trim( $value ); - - if ( isset( $specialValues[$value] ) ) { - $value = $specialValues[$value]; - } else { - $value = trim( $value, '"' ); - } - - /* Support one-level arrays */ - if ( preg_match( '/^([A-Za-z]+)\[([A-Za-z]+)\]/', $key, $m ) ) { - $key = $m[1]; - $value = array( $m[2] => $value ); - } - - return array( $key => $value ); - } -} diff --git a/tests/selenium/SeleniumLoader.php b/tests/selenium/SeleniumLoader.php deleted file mode 100644 index 8d5e7713..00000000 --- a/tests/selenium/SeleniumLoader.php +++ /dev/null @@ -1,9 +0,0 @@ -<?php - -class SeleniumLoader { - static function load() { - require_once( 'Testing/Selenium.php' ); - require_once( 'PHPUnit/Framework.php' ); - require_once( 'PHPUnit/Extensions/SeleniumTestCase.php' ); - } -} diff --git a/tests/selenium/SeleniumServerManager.php b/tests/selenium/SeleniumServerManager.php deleted file mode 100644 index 9efa509a..00000000 --- a/tests/selenium/SeleniumServerManager.php +++ /dev/null @@ -1,252 +0,0 @@ -<?php -/** - * Selenium server manager - * - * @file - * @ingroup Testing - * Copyright (C) 2010 Dan Nessett <dnessett@yahoo.com> - * http://citizendium.org/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -class SeleniumServerManager { - private $SeleniumStartServer = false; - private $OS = ''; - private $SeleniumServerPid = 'NaN'; - private $SeleniumServerPort = 4444; - private $SeleniumServerStartTimeout = 10; // 10 secs. - private $SeleniumServerExecPath; - - public function __construct( $startServer, - $serverPort, - $serverExecPath ) { - $this->OS = (string)PHP_OS; - - if ( isset( $startServer ) ) { - $this->SeleniumStartServer = $startServer; - } - - if ( isset( $serverPort ) ) { - $this->SeleniumServerPort = $serverPort; - } - - if ( isset( $serverExecPath ) ) { - $this->SeleniumServerExecPath = $serverExecPath; - } - - return; - } - - // Getters for certain private attributes. No setters, since they - // should not change after the manager object is created. - - public function getSeleniumStartServer() { - return $this->SeleniumStartServer; - } - - public function getSeleniumServerPort() { - return $this->SeleniumServerPort; - } - - public function getSeleniumServerPid() { - return $this->SeleniumServerPid; - } - - // Changing value of SeleniumStartServer allows starting server after - // creation of the class instance. Only allow setting SeleniumStartServer - // to true, since after server is started, it is shut down by stop(). - - public function setSeleniumStartServer( $startServer ) { - if ( $startServer == true ) { - $this->SeleniumStartServer = true; - } - } - - // return values are: 1) started - server started, 2) failed - - // server not started, 3) running - instructed to start server, but - // server already running - - public function start() { - - if ( !$this->SeleniumStartServer ) { - return 'failed'; - } - - // commented out cases are untested - - switch ( $this->OS ) { - case "Linux": -# case' CYGWIN_NT-5.1': - case 'Darwin': -# case 'FreeBSD': -# case 'HP-UX': -# case 'IRIX64': -# case 'NetBSD': -# case 'OpenBSD': -# case 'SunOS': -# case 'Unix': - // *nix based OS - return $this->startServerOnUnix(); - break; - case "Windows": - case "WIN32": - case "WINNT": - // Windows - return $this->startServerOnWindows(); - break; - default: - // An untested OS - return 'failed'; - break; - } - } - - public function stop() { - - // commented out cases are untested - - switch ( $this->OS ) { - case "Linux": -# case' CYGWIN_NT-5.1': - case 'Darwin': -# case 'FreeBSD': -# case 'HP-UX': -# case 'IRIX64': -# case 'NetBSD': -# case 'OpenBSD': -# case 'SunOS': -# case 'Unix': - // *nix based OS - return $this->stopServerOnUnix(); - break; - case "Windows": - case "WIN32": - case "WINNT": - // Windows - return $this->stopServerOnWindows(); - break; - default: - // An untested OS - return 'failed'; - break; - } - } - - private function startServerOnUnix() { - - $output = array(); - $user = $_ENV['USER']; - // @todo FIXME: This should be a little more generalized :) - if ( PHP_OS == 'Darwin' ) { - // Mac OS X's ps barfs on the 'w' param, but doesn't need it. - $ps = "ps -U %s"; - } else { - // Good on Linux - $ps = "ps -U %s w"; - } - $psCommand = sprintf( $ps, escapeshellarg( $user ) ); - exec( $psCommand . " | grep -i selenium-server", $output ); - - // Start server. If there is already a server running, - // return running. - - if ( isset( $this->SeleniumServerExecPath ) ) { - $found = 0; - foreach ( $output as $string ) { - $found += preg_match( - '~^(.*)java(.+)-jar(.+)selenium-server~', - $string ); - } - if ( $found == 0 ) { - - // Didn't find the selenium server. Start it up. - // First set up comamand line suffix. - // NB: $! is pid of last job run in background - // The echo guarentees it is put into $op when - // the exec command is run. - - $commandSuffix = ' > /dev/null 2>&1' . ' & echo $!'; - $portText = ' -port ' . $this->SeleniumServerPort; - $command = "java -jar " . - escapeshellarg( $this->SeleniumServerExecPath ) . - $portText . $commandSuffix; - exec( $command, $op ); - $pid = (int)$op[0]; - if ( $pid != "" ) { - $this->SeleniumServerPid = $pid; - } else { - $this->SeleniumServerPid = 'NaN'; - // Server start failed. - return 'failed'; - } - // Wait for the server to startup and listen - // on its port. Note: this solution kinda - // stinks, since it uses a wait loop - dnessett - - wfSuppressWarnings(); - for ( $cnt = 1; - $cnt <= $this->SeleniumServerStartTimeout; - $cnt++ ) { - $fp = fsockopen( 'localhost', - $this->SeleniumServerPort, - $errno, $errstr, 0 ); - if ( !$fp ) { - sleep( 1 ); - continue; - // Server start succeeded. - } else { - fclose( $fp ); - return 'started'; - } - } - wfRestoreWarnings(); - echo ( "Starting Selenium server timed out.\n" ); - return 'failed'; - } else { - // server already running. - return 'running'; - } - - } - - // No Server execution path defined. - return 'failed'; - } - - private function startServerOnWindows() { - // Unimplemented. - return 'failed'; - } - - private function stopServerOnUnix() { - - if ( !empty( $this->SeleniumServerPid ) && - $this->SeleniumServerPid != 'NaN' - ) { - exec( "kill -9 " . $this->SeleniumServerPid ); - return 'stopped'; - } else { - return 'failed'; - } - } - - private function stopServerOnWindows() { - // Unimplemented. - return 'failed'; - - } -} diff --git a/tests/selenium/SeleniumTestCase.php b/tests/selenium/SeleniumTestCase.php deleted file mode 100644 index 5346b1be..00000000 --- a/tests/selenium/SeleniumTestCase.php +++ /dev/null @@ -1,127 +0,0 @@ -<?php -include( "SeleniumTestConstants.php" ); - -class SeleniumTestCase extends PHPUnit_Framework_TestCase { // PHPUnit_Extensions_SeleniumTestCase - protected $selenium; - - public function setUp() { - set_time_limit( 60 ); - $this->selenium = Selenium::getInstance(); - } - - public function tearDown() { - - } - - public function __call( $method, $args ) { - return call_user_func_array( array( $this->selenium, $method ), $args ); - } - - public function assertSeleniumAttributeEquals( $attribute, $value ) { - $attr = $this->getAttribute( $attribute ); - $this->assertEquals( $attr, $value ); - } - - public function assertSeleniumHTMLContains( $element, $text ) { - $innerHTML = $this->getText( $element ); - // or assertContains - $this->assertRegExp( "/$text/", $innerHTML ); - } - - - /** - * Create a test fixture page if one does not exist - * @param $pageName The fixture page name. If none is supplied, it uses SeleniumTestConstants::WIKI_INTERNAL_LINK - */ - function createTestPageIfMissing( $pageName = null ) { - if ( $pageName == null ) { - $pageName = SeleniumTestConstants::WIKI_INTERNAL_LINK; - } - $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, $pageName ); - $this->click( SeleniumTestConstants::BUTTON_SEARCH ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->click( SeleniumTestConstants::LINK_START . $pageName ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $location = $this->getLocation() . "\n"; - if ( strpos( $location, '&redlink=1' ) !== false ) { - $this->type( SeleniumTestConstants::TEXT_EDITOR, "Test fixture page. No real content here" ); - $this->click( SeleniumTestConstants::BUTTON_SAVE ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->assertTrue( $this->isTextPresent( $pageName ), - $this->getText( SeleniumTestConstants::TEXT_PAGE_HEADING ) ); - } - } - - /** - * Create a test page using date as part of the name so that it is unique - * @param $pagePrefix The prefix to use for the page name. The current date will be appended to this to make it unique - * @param $watchThis Whether to add the page to my watchlist. Defaults to false. - */ - function createNewTestPage( $pagePrefix, $watchThis = false ) { - $pageName = $pagePrefix . date( "Ymd-His" ); - $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, $pageName ); - $this->click( SeleniumTestConstants::BUTTON_SEARCH ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->click( SeleniumTestConstants::LINK_START . $pageName ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $location = $this->getLocation() . "\n"; - $this->assertContains( '&redlink=1', $location ) . - $this->type( SeleniumTestConstants::TEXT_EDITOR, "Test fixture page. No real content here" ); - if ( $watchThis ) { - $this->click( "wpWatchthis" ); - } - $this->click( SeleniumTestConstants::BUTTON_SAVE ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->assertTrue( $this->isTextPresent( $pageName ), - $this->getText( SeleniumTestConstants::TEXT_PAGE_HEADING ) ); - return $pageName; - } - - public function getExistingPage() { - $this->open( $this->getUrl() . - '/index.php?title=Main_Page&action=edit' ); - $this->type( "searchInput", "new" ); - $this->click( "searchGoButton" ); - $this->waitForPageToLoad( "30000" ); - } - - public function getNewPage( $pageName ) { - - $this->open( $this->getUrl() . - '/index.php?title=Main_Page&action=edit' ); - $this->type( "searchInput", $pageName ); - $this->click( "searchGoButton" ); - $this->waitForPageToLoad( "30000" ); - $this->click( "link=" . $pageName ); - $this->waitForPageToLoad( "600000" ); - - - } - - // Loading the mediawiki editor - public function loadWikiEditor() { - $this->open( $this->getUrl() . - '/index.php?title=Main_Page&action=edit' ); - } - - // Clear the content of the mediawiki editor - public function clearWikiEditor() { - $this->type( "wpTextbox1", "" ); - } - - // Click on the 'Show preview' button of the mediawiki editor - public function clickShowPreviewBtn() { - $this->click( "wpPreview" ); - } - - // Click on the 'Save Page' button of the mediawiki editor - public function clickSavePageBtn() { - $this->click( "wpSave" ); - } - - // Click on the 'Edit' link - public function clickEditLink() { - $this->click( "link=Edit" ); - $this->waitForPageToLoad( "30000" ); - } -} diff --git a/tests/selenium/SeleniumTestConsoleLogger.php b/tests/selenium/SeleniumTestConsoleLogger.php deleted file mode 100644 index b6f5496c..00000000 --- a/tests/selenium/SeleniumTestConsoleLogger.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php - -class SeleniumTestConsoleLogger { - public function __construct() { - // Prepare testsuite for immediate output - @ini_set( 'zlib.output_compression', 0 ); - @ini_set( 'implicit_flush', 1 ); - for ( $i = 0; $i < ob_get_level(); $i++ ) { - ob_end_flush(); - } - ob_implicit_flush( 1 ); - } - - public function write( $message, $mode = false ) { - $out = ''; - // if ( $mode == SeleniumTestSuite::RESULT_OK ) $out .= '<font color="green">'; - $out .= htmlentities( $message ); - // if ( $mode == SeleniumTestSuite::RESULT_OK ) $out .= '</font>'; - if ( $mode != SeleniumTestSuite::CONTINUE_LINE ) { - $out .= "\n"; - } - - echo $out; - } -} diff --git a/tests/selenium/SeleniumTestConstants.php b/tests/selenium/SeleniumTestConstants.php deleted file mode 100644 index 1defb73c..00000000 --- a/tests/selenium/SeleniumTestConstants.php +++ /dev/null @@ -1,24 +0,0 @@ -<?php - -class SeleniumTestConstants { - const WIKI_TEST_WAIT_TIME = 3000; // Waiting time - - //commonly used links - const LINK_MAIN_PAGE = 'link=Main page'; - const LINK_RANDOM_PAGE = 'link=Random article'; - const TEXT_PAGE_HEADING = 'firstHeading'; - - const LINK_START = 'link='; - const TEXT_EDITOR = 'wpTextbox1'; - const LINK_PREVIEW = 'wpPreview'; - const LINK_EDIT = 'link=Edit'; - - const WIKI_SEARCH_PAGE = 'Hair (musical)'; // Page name to search - const WIKI_TEXT_SEARCH = 'TV'; // Text to search - const WIKI_INTERNAL_LINK = 'Wikieditor-Fixture-Page'; // Exisiting page name to add as an internal tag - - const INPUT_SEARCH_BOX = 'searchInput'; - const BUTTON_SEARCH = 'mw-searchButton'; - const BUTTON_SAVE = 'wpSave'; -} - diff --git a/tests/selenium/SeleniumTestHTMLLogger.php b/tests/selenium/SeleniumTestHTMLLogger.php deleted file mode 100644 index 21332cf0..00000000 --- a/tests/selenium/SeleniumTestHTMLLogger.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php - -class SeleniumTestHTMLLogger { - public function setHeaders() { - global $wgOut; - $wgOut->addHeadItem( 'selenium', '<style type="text/css"> - .selenium pre { - overflow-x: auto; /* Use horizontal scroller if needed; for Firefox 2, not needed in Firefox 3 */ - white-space: pre-wrap; /* css-3 */ - white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ - white-space: -pre-wrap; /* Opera 4-6 */ - white-space: -o-pre-wrap; /* Opera 7 */ - /* width: 99%; */ - word-wrap: break-word; /* Internet Explorer 5.5+ */ - } - .selenium-success { color: green } - </style>' ); - } - - public function write( $message, $mode = false ) { - global $wgOut; - $out = ''; - if ( $mode == SeleniumTestSuite::RESULT_OK ) { - $out .= '<span class="selenium-success">'; - } - $out .= htmlspecialchars( $message ); - if ( $mode == SeleniumTestSuite::RESULT_OK ) { - $out .= '</span>'; - } - if ( $mode != SeleniumTestSuite::CONTINUE_LINE ) { - $out .= '<br />'; - } - - $wgOut->addHTML( $out ); - } -} diff --git a/tests/selenium/SeleniumTestListener.php b/tests/selenium/SeleniumTestListener.php deleted file mode 100644 index dc0ac66c..00000000 --- a/tests/selenium/SeleniumTestListener.php +++ /dev/null @@ -1,65 +0,0 @@ -<?php - -class SeleniumTestListener implements PHPUnit_Framework_TestListener { - private $logger; - private $tests_ok = 0; - private $tests_failed = 0; - - public function __construct( $loggerInstance ) { - $this->logger = $loggerInstance; - } - - public function addError( PHPUnit_Framework_Test $test, Exception $e, $time ) { - $this->logger->write( 'Error: ' . $e->getMessage() ); - $this->tests_failed++; - } - - public function addFailure( PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time ) { - $this->logger->write( 'Failed: ' . $e->getMessage() ); - $this->tests_failed++; - } - - public function addIncompleteTest( PHPUnit_Framework_Test $test, Exception $e, $time ) { - $this->logger->write( 'Incomplete.' ); - $this->tests_failed++; - } - - public function addSkippedTest( PHPUnit_Framework_Test $test, Exception $e, $time ) { - $this->logger->write( 'Skipped.' ); - $this->tests_failed++; - } - - public function startTest( PHPUnit_Framework_Test $test ) { - $this->logger->write( - 'Testing ' . $test->getName() . ' ... ', - SeleniumTestSuite::CONTINUE_LINE - ); - } - - public function endTest( PHPUnit_Framework_Test $test, $time ) { - if ( !$test->hasFailed() ) { - $this->logger->write( 'OK', SeleniumTestSuite::RESULT_OK ); - $this->tests_ok++; - } - } - - public function startTestSuite( PHPUnit_Framework_TestSuite $suite ) { - $this->logger->write( 'Testsuite ' . $suite->getName() . ' started.' ); - $this->tests_ok = 0; - $this->tests_failed = 0; - } - - public function endTestSuite( PHPUnit_Framework_TestSuite $suite ) { - $this->logger->write( 'Testsuite ' . $suite->getName() . ' ended.' ); - if ( $this->tests_ok > 0 || $this->tests_failed > 0 ) { - $this->logger->write( ' OK: ' . $this->tests_ok . ' Failed: ' . $this->tests_failed ); - } - $this->tests_ok = 0; - $this->tests_failed = 0; - } - - public function statusMessage( $message ) { - $this->logger->write( $message ); - } -} - diff --git a/tests/selenium/SeleniumTestSuite.php b/tests/selenium/SeleniumTestSuite.php deleted file mode 100644 index 8c21f21c..00000000 --- a/tests/selenium/SeleniumTestSuite.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php - -abstract class SeleniumTestSuite extends PHPUnit_Framework_TestSuite { - private $selenium; - private $isSetUp = false; - private $loginBeforeTests = true; - private $triggerClientTestResources = true; - - // Do not add line break after test output - const CONTINUE_LINE = 1; - const RESULT_OK = 2; - const RESULT_ERROR = 3; - - abstract public function addTests(); - - public function setUp() { - // Hack because because PHPUnit version 3.0.6 which is on prototype does not - // run setUp as part of TestSuite::run - if ( $this->isSetUp ) { - return; - } - $this->isSetUp = true; - $this->selenium = Selenium::getInstance(); - $this->selenium->start(); - if ( $this->triggerClientTestResources ) { - $this->selenium->open( $this->selenium->getUrl() . '/index.php?setupTestSuite=' . $this->getName() ); - //wait a little longer for the db operation - $this->selenium->waitForPageToLoad( 6000 ); - } - if ( $this->loginBeforeTests ) { - $this->login(); - } - } - - public function tearDown() { - if ( $this->triggerClientTestResources ) { - $this->selenium->open( $this->selenium->getUrl() . '/index.php?clearTestSuite=' . $this->getName() ); - } - $this->selenium->stop(); - } - - public function login() { - $this->selenium->login(); - } - - public function loadPage( $title, $action ) { - $this->selenium->loadPage( $title, $action ); - } - - protected function setLoginBeforeTests( $loginBeforeTests = true ) { - $this->loginBeforeTests = $loginBeforeTests; - } - - protected function setTriggerClientTestResources( $triggerClientTestResources = true ) { - $this->triggerClientTestResources = $triggerClientTestResources; - } -} diff --git a/tests/selenium/data/SimpleSeleniumTestDB.sql b/tests/selenium/data/SimpleSeleniumTestDB.sql deleted file mode 100644 index 99ae4779..00000000 --- a/tests/selenium/data/SimpleSeleniumTestDB.sql +++ /dev/null @@ -1,1453 +0,0 @@ --- MySQL dump 10.13 Distrib 5.1.41, for debian-linux-gnu (x86_64) --- --- Host: localhost Database: test_wiki --- ------------------------------------------------------ --- Server version 5.1.41-3ubuntu12.7 - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- --- Table structure for table `mw_archive` --- - -DROP TABLE IF EXISTS `mw_archive`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_archive` ( - `ar_namespace` int(11) NOT NULL DEFAULT '0', - `ar_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `ar_text` mediumblob NOT NULL, - `ar_comment` tinyblob NOT NULL, - `ar_user` int(10) unsigned NOT NULL DEFAULT '0', - `ar_user_text` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - `ar_timestamp` binary(14) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `ar_minor_edit` tinyint(4) NOT NULL DEFAULT '0', - `ar_flags` tinyblob NOT NULL, - `ar_rev_id` int(10) unsigned DEFAULT NULL, - `ar_text_id` int(10) unsigned DEFAULT NULL, - `ar_deleted` tinyint(3) unsigned NOT NULL DEFAULT '0', - `ar_len` int(10) unsigned DEFAULT NULL, - `ar_page_id` int(10) unsigned DEFAULT NULL, - `ar_parent_id` int(10) unsigned DEFAULT NULL, - KEY `name_title_timestamp` (`ar_namespace`,`ar_title`,`ar_timestamp`), - KEY `usertext_timestamp` (`ar_user_text`,`ar_timestamp`), - KEY `ar_revid` (`ar_rev_id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_archive` --- - -LOCK TABLES `mw_archive` WRITE; -/*!40000 ALTER TABLE `mw_archive` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_archive` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_category` --- - -DROP TABLE IF EXISTS `mw_category`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_category` ( - `cat_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `cat_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - `cat_pages` int(11) NOT NULL DEFAULT '0', - `cat_subcats` int(11) NOT NULL DEFAULT '0', - `cat_files` int(11) NOT NULL DEFAULT '0', - `cat_hidden` tinyint(3) unsigned NOT NULL DEFAULT '0', - PRIMARY KEY (`cat_id`), - UNIQUE KEY `cat_title` (`cat_title`), - KEY `cat_pages` (`cat_pages`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_category` --- - -LOCK TABLES `mw_category` WRITE; -/*!40000 ALTER TABLE `mw_category` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_category` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_categorylinks` --- - -DROP TABLE IF EXISTS `mw_categorylinks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_categorylinks` ( - `cl_from` int(10) unsigned NOT NULL DEFAULT '0', - `cl_to` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `cl_sortkey` varbinary(230) NOT NULL DEFAULT '', - `cl_sortkey_prefix` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `cl_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - `cl_collation` varbinary(32) NOT NULL DEFAULT '', - `cl_type` enum('page','subcat','file') NOT NULL DEFAULT 'page', - UNIQUE KEY `cl_from` (`cl_from`,`cl_to`), - KEY `cl_sortkey` (`cl_to`,`cl_type`,`cl_sortkey`,`cl_from`), - KEY `cl_timestamp` (`cl_to`,`cl_timestamp`), - KEY `cl_collation` (`cl_collation`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_categorylinks` --- - -LOCK TABLES `mw_categorylinks` WRITE; -/*!40000 ALTER TABLE `mw_categorylinks` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_categorylinks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_change_tag` --- - -DROP TABLE IF EXISTS `mw_change_tag`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_change_tag` ( - `ct_rc_id` int(11) DEFAULT NULL, - `ct_log_id` int(11) DEFAULT NULL, - `ct_rev_id` int(11) DEFAULT NULL, - `ct_tag` varchar(255) NOT NULL, - `ct_params` blob, - UNIQUE KEY `change_tag_rc_tag` (`ct_rc_id`,`ct_tag`), - UNIQUE KEY `change_tag_log_tag` (`ct_log_id`,`ct_tag`), - UNIQUE KEY `change_tag_rev_tag` (`ct_rev_id`,`ct_tag`), - KEY `change_tag_tag_id` (`ct_tag`,`ct_rc_id`,`ct_rev_id`,`ct_log_id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_change_tag` --- - -LOCK TABLES `mw_change_tag` WRITE; -/*!40000 ALTER TABLE `mw_change_tag` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_change_tag` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_external_user` --- - -DROP TABLE IF EXISTS `mw_external_user`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_external_user` ( - `eu_local_id` int(10) unsigned NOT NULL, - `eu_external_id` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - PRIMARY KEY (`eu_local_id`), - UNIQUE KEY `eu_external_id` (`eu_external_id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_external_user` --- - -LOCK TABLES `mw_external_user` WRITE; -/*!40000 ALTER TABLE `mw_external_user` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_external_user` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_externallinks` --- - -DROP TABLE IF EXISTS `mw_externallinks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_externallinks` ( - `el_from` int(10) unsigned NOT NULL DEFAULT '0', - `el_to` blob NOT NULL, - `el_index` blob NOT NULL, - KEY `el_from` (`el_from`,`el_to`(40)), - KEY `el_to` (`el_to`(60),`el_from`), - KEY `el_index` (`el_index`(60)) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_externallinks` --- - -LOCK TABLES `mw_externallinks` WRITE; -/*!40000 ALTER TABLE `mw_externallinks` DISABLE KEYS */; -INSERT INTO `mw_externallinks` VALUES (1,'http://meta.wikimedia.org/wiki/Help:Contents','http://org.wikimedia.meta./wiki/Help:Contents'),(1,'http://www.mediawiki.org/wiki/Manual:Configuration_settings','http://org.mediawiki.www./wiki/Manual:Configuration_settings'),(1,'http://www.mediawiki.org/wiki/Manual:FAQ','http://org.mediawiki.www./wiki/Manual:FAQ'),(1,'https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce','https://org.wikimedia.lists./mailman/listinfo/mediawiki-announce'); -/*!40000 ALTER TABLE `mw_externallinks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_filearchive` --- - -DROP TABLE IF EXISTS `mw_filearchive`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_filearchive` ( - `fa_id` int(11) NOT NULL AUTO_INCREMENT, - `fa_name` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `fa_archive_name` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT '', - `fa_storage_group` varbinary(16) DEFAULT NULL, - `fa_storage_key` varbinary(64) DEFAULT '', - `fa_deleted_user` int(11) DEFAULT NULL, - `fa_deleted_timestamp` binary(14) DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `fa_deleted_reason` text, - `fa_size` int(10) unsigned DEFAULT '0', - `fa_width` int(11) DEFAULT '0', - `fa_height` int(11) DEFAULT '0', - `fa_metadata` mediumblob, - `fa_bits` int(11) DEFAULT '0', - `fa_media_type` enum('UNKNOWN','BITMAP','DRAWING','AUDIO','VIDEO','MULTIMEDIA','OFFICE','TEXT','EXECUTABLE','ARCHIVE') DEFAULT NULL, - `fa_major_mime` enum('unknown','application','audio','image','text','video','message','model','multipart') DEFAULT 'unknown', - `fa_minor_mime` varbinary(100) DEFAULT 'unknown', - `fa_description` tinyblob, - `fa_user` int(10) unsigned DEFAULT '0', - `fa_user_text` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, - `fa_timestamp` binary(14) DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `fa_deleted` tinyint(3) unsigned NOT NULL DEFAULT '0', - PRIMARY KEY (`fa_id`), - KEY `fa_name` (`fa_name`,`fa_timestamp`), - KEY `fa_storage_group` (`fa_storage_group`,`fa_storage_key`), - KEY `fa_deleted_timestamp` (`fa_deleted_timestamp`), - KEY `fa_user_timestamp` (`fa_user_text`,`fa_timestamp`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_filearchive` --- - -LOCK TABLES `mw_filearchive` WRITE; -/*!40000 ALTER TABLE `mw_filearchive` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_filearchive` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_hitcounter` --- - -DROP TABLE IF EXISTS `mw_hitcounter`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_hitcounter` ( - `hc_id` int(10) unsigned NOT NULL -) ENGINE=MEMORY DEFAULT CHARSET=latin1 MAX_ROWS=25000; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_hitcounter` --- - -LOCK TABLES `mw_hitcounter` WRITE; -/*!40000 ALTER TABLE `mw_hitcounter` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_hitcounter` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_image` --- - -DROP TABLE IF EXISTS `mw_image`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_image` ( - `img_name` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `img_size` int(10) unsigned NOT NULL DEFAULT '0', - `img_width` int(11) NOT NULL DEFAULT '0', - `img_height` int(11) NOT NULL DEFAULT '0', - `img_metadata` mediumblob NOT NULL, - `img_bits` int(11) NOT NULL DEFAULT '0', - `img_media_type` enum('UNKNOWN','BITMAP','DRAWING','AUDIO','VIDEO','MULTIMEDIA','OFFICE','TEXT','EXECUTABLE','ARCHIVE') DEFAULT NULL, - `img_major_mime` enum('unknown','application','audio','image','text','video','message','model','multipart') NOT NULL DEFAULT 'unknown', - `img_minor_mime` varbinary(100) NOT NULL DEFAULT 'unknown', - `img_description` tinyblob NOT NULL, - `img_user` int(10) unsigned NOT NULL DEFAULT '0', - `img_user_text` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - `img_timestamp` varbinary(14) NOT NULL DEFAULT '', - `img_sha1` varbinary(32) NOT NULL DEFAULT '', - PRIMARY KEY (`img_name`), - KEY `img_usertext_timestamp` (`img_user_text`,`img_timestamp`), - KEY `img_size` (`img_size`), - KEY `img_timestamp` (`img_timestamp`), - KEY `img_sha1` (`img_sha1`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_image` --- - -LOCK TABLES `mw_image` WRITE; -/*!40000 ALTER TABLE `mw_image` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_image` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_imagelinks` --- - -DROP TABLE IF EXISTS `mw_imagelinks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_imagelinks` ( - `il_from` int(10) unsigned NOT NULL DEFAULT '0', - `il_to` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - UNIQUE KEY `il_from` (`il_from`,`il_to`), - UNIQUE KEY `il_to` (`il_to`,`il_from`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_imagelinks` --- - -LOCK TABLES `mw_imagelinks` WRITE; -/*!40000 ALTER TABLE `mw_imagelinks` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_imagelinks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_interwiki` --- - -DROP TABLE IF EXISTS `mw_interwiki`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_interwiki` ( - `iw_prefix` varchar(32) NOT NULL, - `iw_url` blob NOT NULL, - `iw_api` blob NOT NULL, - `iw_wikiid` varchar(64) NOT NULL, - `iw_local` tinyint(1) NOT NULL, - `iw_trans` tinyint(4) NOT NULL DEFAULT '0', - UNIQUE KEY `iw_prefix` (`iw_prefix`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_interwiki` --- - -LOCK TABLES `mw_interwiki` WRITE; -/*!40000 ALTER TABLE `mw_interwiki` DISABLE KEYS */; -INSERT INTO `mw_interwiki` VALUES ('acronym','http://www.acronymfinder.com/af-query.asp?String=exact&Acronym=$1','','',0,0),('advogato','http://www.advogato.org/$1','','',0,0),('annotationwiki','http://www.seedwiki.com/page.cfm?wikiid=368&doc=$1','','',0,0),('arxiv','http://www.arxiv.org/abs/$1','','',0,0),('c2find','http://c2.com/cgi/wiki?FindPage&value=$1','','',0,0),('cache','http://www.google.com/search?q=cache:$1','','',0,0),('commons','http://commons.wikimedia.org/wiki/$1','','',0,0),('corpknowpedia','http://corpknowpedia.org/wiki/index.php/$1','','',0,0),('dictionary','http://www.dict.org/bin/Dict?Database=*&Form=Dict1&Strategy=*&Query=$1','','',0,0),('disinfopedia','http://www.disinfopedia.org/wiki.phtml?title=$1','','',0,0),('docbook','http://wiki.docbook.org/topic/$1','','',0,0),('doi','http://dx.doi.org/$1','','',0,0),('drumcorpswiki','http://www.drumcorpswiki.com/index.php/$1','','',0,0),('dwjwiki','http://www.suberic.net/cgi-bin/dwj/wiki.cgi?$1','','',0,0),('elibre','http://enciclopedia.us.es/index.php/$1','','',0,0),('emacswiki','http://www.emacswiki.org/cgi-bin/wiki.pl?$1','','',0,0),('foldoc','http://foldoc.org/?$1','','',0,0),('foxwiki','http://fox.wikis.com/wc.dll?Wiki~$1','','',0,0),('freebsdman','http://www.FreeBSD.org/cgi/man.cgi?apropos=1&query=$1','','',0,0),('gej','http://www.esperanto.de/cgi-bin/aktivikio/wiki.pl?$1','','',0,0),('gentoo-wiki','http://gentoo-wiki.com/$1','','',0,0),('google','http://www.google.com/search?q=$1','','',0,0),('googlegroups','http://groups.google.com/groups?q=$1','','',0,0),('hammondwiki','http://www.dairiki.org/HammondWiki/$1','','',0,0),('hewikisource','http://he.wikisource.org/wiki/$1','','',1,0),('hrwiki','http://www.hrwiki.org/index.php/$1','','',0,0),('imdb','http://us.imdb.com/Title?$1','','',0,0),('jargonfile','http://sunir.org/apps/meta.pl?wiki=JargonFile&redirect=$1','','',0,0),('jspwiki','http://www.jspwiki.org/wiki/$1','','',0,0),('keiki','http://kei.ki/en/$1','','',0,0),('kmwiki','http://kmwiki.wikispaces.com/$1','','',0,0),('linuxwiki','http://linuxwiki.de/$1','','',0,0),('lojban','http://www.lojban.org/tiki/tiki-index.php?page=$1','','',0,0),('lqwiki','http://wiki.linuxquestions.org/wiki/$1','','',0,0),('lugkr','http://lug-kr.sourceforge.net/cgi-bin/lugwiki.pl?$1','','',0,0),('mathsongswiki','http://SeedWiki.com/page.cfm?wikiid=237&doc=$1','','',0,0),('meatball','http://www.usemod.com/cgi-bin/mb.pl?$1','','',0,0),('mediawikiwiki','http://www.mediawiki.org/wiki/$1','','',0,0),('mediazilla','https://bugzilla.wikimedia.org/$1','','',1,0),('memoryalpha','http://www.memory-alpha.org/en/index.php/$1','','',0,0),('metawiki','http://sunir.org/apps/meta.pl?$1','','',0,0),('metawikimedia','http://meta.wikimedia.org/wiki/$1','','',0,0),('moinmoin','http://purl.net/wiki/moin/$1','','',0,0),('mozillawiki','http://wiki.mozilla.org/index.php/$1','','',0,0),('mw','http://www.mediawiki.org/wiki/$1','','',0,0),('oeis','http://www.research.att.com/cgi-bin/access.cgi/as/njas/sequences/eisA.cgi?Anum=$1','','',0,0),('openfacts','http://openfacts.berlios.de/index.phtml?title=$1','','',0,0),('openwiki','http://openwiki.com/?$1','','',0,0),('pmeg','http://www.bertilow.com/pmeg/$1.php','','',0,0),('ppr','http://c2.com/cgi/wiki?$1','','',0,0),('pythoninfo','http://wiki.python.org/moin/$1','','',0,0),('rfc','http://www.rfc-editor.org/rfc/rfc$1.txt','','',0,0),('s23wiki','http://is-root.de/wiki/index.php/$1','','',0,0),('seattlewiki','http://seattle.wikia.com/wiki/$1','','',0,0),('seattlewireless','http://seattlewireless.net/?$1','','',0,0),('senseislibrary','http://senseis.xmp.net/?$1','','',0,0),('sourceforge','http://sourceforge.net/$1','','',0,0),('squeak','http://wiki.squeak.org/squeak/$1','','',0,0),('susning','http://www.susning.nu/$1','','',0,0),('svgwiki','http://wiki.svg.org/$1','','',0,0),('tavi','http://tavi.sourceforge.net/$1','','',0,0),('tejo','http://www.tejo.org/vikio/$1','','',0,0),('theopedia','http://www.theopedia.com/$1','','',0,0),('tmbw','http://www.tmbw.net/wiki/$1','','',0,0),('tmnet','http://www.technomanifestos.net/?$1','','',0,0),('tmwiki','http://www.EasyTopicMaps.com/?page=$1','','',0,0),('twiki','http://twiki.org/cgi-bin/view/$1','','',0,0),('uea','http://www.tejo.org/uea/$1','','',0,0),('unreal','http://wiki.beyondunreal.com/wiki/$1','','',0,0),('usemod','http://www.usemod.com/cgi-bin/wiki.pl?$1','','',0,0),('vinismo','http://vinismo.com/en/$1','','',0,0),('webseitzwiki','http://webseitz.fluxent.com/wiki/$1','','',0,0),('why','http://clublet.com/c/c/why?$1','','',0,0),('wiki','http://c2.com/cgi/wiki?$1','','',0,0),('wikia','http://www.wikia.com/wiki/$1','','',0,0),('wikibooks','http://en.wikibooks.org/wiki/$1','','',1,0),('wikicities','http://www.wikia.com/wiki/$1','','',0,0),('wikif1','http://www.wikif1.org/$1','','',0,0),('wikihow','http://www.wikihow.com/$1','','',0,0),('wikimedia','http://wikimediafoundation.org/wiki/$1','','',0,0),('wikinews','http://en.wikinews.org/wiki/$1','','',1,0),('wikinfo','http://www.wikinfo.org/index.php/$1','','',0,0),('wikipedia','http://en.wikipedia.org/wiki/$1','','',1,0),('wikiquote','http://en.wikiquote.org/wiki/$1','','',1,0),('wikisource','http://wikisource.org/wiki/$1','','',1,0),('wikispecies','http://species.wikimedia.org/wiki/$1','','',1,0),('wikitravel','http://wikitravel.org/en/$1','','',0,0),('wikiversity','http://en.wikiversity.org/wiki/$1','','',1,0),('wikt','http://en.wiktionary.org/wiki/$1','','',1,0),('wiktionary','http://en.wiktionary.org/wiki/$1','','',1,0),('wlug','http://www.wlug.org.nz/$1','','',0,0),('zwiki','http://zwiki.org/$1','','',0,0),('zzz wiki','http://wiki.zzz.ee/index.php/$1','','',0,0); -/*!40000 ALTER TABLE `mw_interwiki` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_ipblocks` --- - -DROP TABLE IF EXISTS `mw_ipblocks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_ipblocks` ( - `ipb_id` int(11) NOT NULL AUTO_INCREMENT, - `ipb_address` tinyblob NOT NULL, - `ipb_user` int(10) unsigned NOT NULL DEFAULT '0', - `ipb_by` int(10) unsigned NOT NULL DEFAULT '0', - `ipb_by_text` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `ipb_reason` tinyblob NOT NULL, - `ipb_timestamp` binary(14) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `ipb_auto` tinyint(1) NOT NULL DEFAULT '0', - `ipb_anon_only` tinyint(1) NOT NULL DEFAULT '0', - `ipb_create_account` tinyint(1) NOT NULL DEFAULT '1', - `ipb_enable_autoblock` tinyint(1) NOT NULL DEFAULT '1', - `ipb_expiry` varbinary(14) NOT NULL DEFAULT '', - `ipb_range_start` tinyblob NOT NULL, - `ipb_range_end` tinyblob NOT NULL, - `ipb_deleted` tinyint(1) NOT NULL DEFAULT '0', - `ipb_block_email` tinyint(1) NOT NULL DEFAULT '0', - `ipb_allow_usertalk` tinyint(1) NOT NULL DEFAULT '0', - PRIMARY KEY (`ipb_id`), - UNIQUE KEY `ipb_address` (`ipb_address`(255),`ipb_user`,`ipb_auto`,`ipb_anon_only`), - KEY `ipb_user` (`ipb_user`), - KEY `ipb_range` (`ipb_range_start`(8),`ipb_range_end`(8)), - KEY `ipb_timestamp` (`ipb_timestamp`), - KEY `ipb_expiry` (`ipb_expiry`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_ipblocks` --- - -LOCK TABLES `mw_ipblocks` WRITE; -/*!40000 ALTER TABLE `mw_ipblocks` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_ipblocks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_iwlinks` --- - -DROP TABLE IF EXISTS `mw_iwlinks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_iwlinks` ( - `iwl_from` int(10) unsigned NOT NULL DEFAULT '0', - `iwl_prefix` varbinary(20) NOT NULL DEFAULT '', - `iwl_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - UNIQUE KEY `iwl_from` (`iwl_from`,`iwl_prefix`,`iwl_title`), - UNIQUE KEY `iwl_prefix_title_from` (`iwl_prefix`,`iwl_title`,`iwl_from`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_iwlinks` --- - -LOCK TABLES `mw_iwlinks` WRITE; -/*!40000 ALTER TABLE `mw_iwlinks` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_iwlinks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_job` --- - -DROP TABLE IF EXISTS `mw_job`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_job` ( - `job_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `job_cmd` varbinary(60) NOT NULL DEFAULT '', - `job_namespace` int(11) NOT NULL, - `job_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - `job_params` blob NOT NULL, - PRIMARY KEY (`job_id`), - KEY `job_cmd` (`job_cmd`,`job_namespace`,`job_title`,`job_params`(128)) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_job` --- - -LOCK TABLES `mw_job` WRITE; -/*!40000 ALTER TABLE `mw_job` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_job` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_l10n_cache` --- - -DROP TABLE IF EXISTS `mw_l10n_cache`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_l10n_cache` ( - `lc_lang` varbinary(32) NOT NULL, - `lc_key` varchar(255) NOT NULL, - `lc_value` mediumblob NOT NULL, - KEY `lc_lang_key` (`lc_lang`,`lc_key`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_l10n_cache` --- - -LOCK TABLES `mw_l10n_cache` WRITE; -/*!40000 ALTER TABLE `mw_l10n_cache` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_l10n_cache` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_langlinks` --- - -DROP TABLE IF EXISTS `mw_langlinks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_langlinks` ( - `ll_from` int(10) unsigned NOT NULL DEFAULT '0', - `ll_lang` varbinary(20) NOT NULL DEFAULT '', - `ll_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - UNIQUE KEY `ll_from` (`ll_from`,`ll_lang`), - KEY `ll_lang` (`ll_lang`,`ll_title`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_langlinks` --- - -LOCK TABLES `mw_langlinks` WRITE; -/*!40000 ALTER TABLE `mw_langlinks` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_langlinks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_log_search` --- - -DROP TABLE IF EXISTS `mw_log_search`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_log_search` ( - `ls_field` varbinary(32) NOT NULL, - `ls_value` varchar(255) NOT NULL, - `ls_log_id` int(10) unsigned NOT NULL DEFAULT '0', - UNIQUE KEY `ls_field_val` (`ls_field`,`ls_value`,`ls_log_id`), - KEY `ls_log_id` (`ls_log_id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_log_search` --- - -LOCK TABLES `mw_log_search` WRITE; -/*!40000 ALTER TABLE `mw_log_search` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_log_search` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_logging` --- - -DROP TABLE IF EXISTS `mw_logging`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_logging` ( - `log_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `log_type` varbinary(32) NOT NULL DEFAULT '', - `log_action` varbinary(32) NOT NULL DEFAULT '', - `log_timestamp` binary(14) NOT NULL DEFAULT '19700101000000', - `log_user` int(10) unsigned NOT NULL DEFAULT '0', - `log_user_text` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `log_namespace` int(11) NOT NULL DEFAULT '0', - `log_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `log_page` int(10) unsigned DEFAULT NULL, - `log_comment` varchar(255) NOT NULL DEFAULT '', - `log_params` blob NOT NULL, - `log_deleted` tinyint(3) unsigned NOT NULL DEFAULT '0', - PRIMARY KEY (`log_id`), - KEY `type_time` (`log_type`,`log_timestamp`), - KEY `user_time` (`log_user`,`log_timestamp`), - KEY `page_time` (`log_namespace`,`log_title`,`log_timestamp`), - KEY `times` (`log_timestamp`), - KEY `log_user_type_time` (`log_user`,`log_type`,`log_timestamp`), - KEY `log_page_id_time` (`log_page`,`log_timestamp`) -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_logging` --- - -LOCK TABLES `mw_logging` WRITE; -/*!40000 ALTER TABLE `mw_logging` DISABLE KEYS */; -INSERT INTO `mw_logging` VALUES (1,'patrol','patrol','20110110173131',1,'WikiSysop',0,'TestResources',2,'','2\n0\n1',0); -/*!40000 ALTER TABLE `mw_logging` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_math` --- - -DROP TABLE IF EXISTS `mw_math`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_math` ( - `math_inputhash` varbinary(16) NOT NULL, - `math_outputhash` varbinary(16) NOT NULL, - `math_html_conservativeness` tinyint(4) NOT NULL, - `math_html` text, - `math_mathml` text, - UNIQUE KEY `math_inputhash` (`math_inputhash`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_math` --- - -LOCK TABLES `mw_math` WRITE; -/*!40000 ALTER TABLE `mw_math` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_math` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_module_deps` --- - -DROP TABLE IF EXISTS `mw_module_deps`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_module_deps` ( - `md_module` varbinary(255) NOT NULL, - `md_skin` varbinary(32) NOT NULL, - `md_deps` mediumblob NOT NULL, - UNIQUE KEY `md_module_skin` (`md_module`,`md_skin`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_module_deps` --- - -LOCK TABLES `mw_module_deps` WRITE; -/*!40000 ALTER TABLE `mw_module_deps` DISABLE KEYS */; -INSERT INTO `mw_module_deps` VALUES ('ext.vector.collapsibleNav','vector','[\"\\/home\\/pdhanda\\/deployment\\/extensions\\/Vector\\/modules\\/.\\/images\\/portal-break.png\",\"\\/home\\/pdhanda\\/deployment\\/extensions\\/Vector\\/modules\\/.\\/images\\/open.png\",\"\\/home\\/pdhanda\\/deployment\\/extensions\\/Vector\\/modules\\/.\\/images\\/closed-ltr.png\"]'),('jquery.wikiEditor','vector','[\"\\/home\\/pdhanda\\/deployment\\/extensions\\/WikiEditor\\/modules\\/.\\/images\\/toolbar\\/loading.gif\"]'),('jquery.wikiEditor.toolbar','vector','{\"0\":\"\\/home\\/pdhanda\\/deployment\\/extensions\\/WikiEditor\\/modules\\/.\\/images\\/toolbar\\/base.png\",\"1\":\"\\/home\\/pdhanda\\/deployment\\/extensions\\/WikiEditor\\/modules\\/.\\/images\\/toolbar\\/loading.gif\",\"2\":\"\\/home\\/pdhanda\\/deployment\\/extensions\\/WikiEditor\\/modules\\/.\\/images\\/toolbar\\/button-sprite.png\",\"3\":\"\\/home\\/pdhanda\\/deployment\\/extensions\\/WikiEditor\\/modules\\/.\\/images\\/toolbar\\/arrow-right.png\",\"4\":\"\\/home\\/pdhanda\\/deployment\\/extensions\\/WikiEditor\\/modules\\/.\\/images\\/toolbar\\/arrow-left.png\",\"5\":\"\\/home\\/pdhanda\\/deployment\\/extensions\\/WikiEditor\\/modules\\/.\\/images\\/toolbar\\/arrow-down.png\",\"7\":\"\\/home\\/pdhanda\\/deployment\\/extensions\\/WikiEditor\\/modules\\/.\\/images\\/toolbar\\/loading-small.gif\"}'),('mediawiki.legacy.shared','vector','[\"\\/home\\/pdhanda\\/deployment\\/skins\\/common\\/images\\/feed-icon.png\",\"\\/home\\/pdhanda\\/deployment\\/skins\\/common\\/images\\/remove.png\",\"\\/home\\/pdhanda\\/deployment\\/skins\\/common\\/images\\/add.png\",\"\\/home\\/pdhanda\\/deployment\\/skins\\/common\\/images\\/ajax-loader.gif\",\"\\/home\\/pdhanda\\/deployment\\/skins\\/common\\/images\\/spinner.gif\",\"\\/home\\/pdhanda\\/deployment\\/skins\\/common\\/images\\/help-question.gif\",\"\\/home\\/pdhanda\\/deployment\\/skins\\/common\\/images\\/help-question-hover.gif\"]'),('skins.vector','vector','{\"0\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/page-base.png\",\"1\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/border.png\",\"2\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/page-fade.png\",\"4\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/tab-break.png\",\"5\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/tab-normal-fade.png\",\"6\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/tab-current-fade.png\",\"8\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/arrow-down-icon.png\",\"11\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/search-fade.png\",\"12\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/portal-break.png\",\"14\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/preferences-break.png\",\"16\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/preferences-fade.png\",\"17\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/preferences-base.png\",\"18\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/bullet-icon.png\",\"19\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/external-link-ltr-icon.png\",\"20\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/lock-icon.png\",\"21\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/mail-icon.png\",\"22\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/news-icon.png\",\"23\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/file-icon.png\",\"24\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/talk-icon.png\",\"25\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/audio-icon.png\",\"26\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/video-icon.png\",\"27\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/document-icon.png\",\"28\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/user-icon.png\",\"29\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/watch-icons.png\",\"30\":\"\\/home\\/pdhanda\\/deployment\\/skins\\/vector\\/images\\/watch-icon-loading.gif\"}'); -/*!40000 ALTER TABLE `mw_module_deps` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_msg_resource` --- - -DROP TABLE IF EXISTS `mw_msg_resource`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_msg_resource` ( - `mr_resource` varbinary(255) NOT NULL, - `mr_lang` varbinary(32) NOT NULL, - `mr_blob` mediumblob NOT NULL, - `mr_timestamp` binary(14) NOT NULL, - UNIQUE KEY `mr_resource_lang` (`mr_resource`,`mr_lang`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_msg_resource` --- - -LOCK TABLES `mw_msg_resource` WRITE; -/*!40000 ALTER TABLE `mw_msg_resource` DISABLE KEYS */; -INSERT INTO `mw_msg_resource` VALUES ('ext.vector.collapsibleNav','en','{\"vector-collapsiblenav-more\":\"More languages\"}','20110108005000'),('ext.vector.collapsibleTabs','en','{}','20110108005000'),('ext.vector.simpleSearch','en','{\"vector-simplesearch-search\":\"Search\",\"vector-simplesearch-containing\":\"containing...\"}','20110108005000'),('ext.wikiEditor','en','{}','20110110172914'),('ext.wikiEditor.toolbar','en','{\"wikieditor-toolbar-loading\":\"Loading...\",\"wikieditor-toolbar-tool-bold\":\"Bold\",\"wikieditor-toolbar-tool-bold-example\":\"Bold text\",\"wikieditor-toolbar-tool-italic\":\"Italic\",\"wikieditor-toolbar-tool-italic-example\":\"Italic text\",\"wikieditor-toolbar-tool-ilink\":\"Internal link\",\"wikieditor-toolbar-tool-ilink-example\":\"Link title\",\"wikieditor-toolbar-tool-xlink\":\"External link (remember http:\\/\\/ prefix)\",\"wikieditor-toolbar-tool-xlink-example\":\"http:\\/\\/www.example.com link title\",\"wikieditor-toolbar-tool-link\":\"Link\",\"wikieditor-toolbar-tool-link-title\":\"Insert link\",\"wikieditor-toolbar-tool-link-int\":\"To a wiki page\",\"wikieditor-toolbar-tool-link-int-target\":\"Target page or URL:\",\"wikieditor-toolbar-tool-link-int-target-tooltip\":\"Page title or URL\",\"wikieditor-toolbar-tool-link-int-text\":\"Text to display:\",\"wikieditor-toolbar-tool-link-int-text-tooltip\":\"Text to be displayed\",\"wikieditor-toolbar-tool-link-ext\":\"To an external web page\",\"wikieditor-toolbar-tool-link-ext-target\":\"Link URL:\",\"wikieditor-toolbar-tool-link-ext-text\":\"Link text:\",\"wikieditor-toolbar-tool-link-insert\":\"Insert link\",\"wikieditor-toolbar-tool-link-cancel\":\"Cancel\",\"wikieditor-toolbar-tool-link-int-target-status-exists\":\"Page exists\",\"wikieditor-toolbar-tool-link-int-target-status-notexists\":\"Page does not exist\",\"wikieditor-toolbar-tool-link-int-target-status-invalid\":\"Invalid title\",\"wikieditor-toolbar-tool-link-int-target-status-external\":\"External link\",\"wikieditor-toolbar-tool-link-int-target-status-loading\":\"Checking page existence...\",\"wikieditor-toolbar-tool-link-int-invalid\":\"The title you specified is invalid.\",\"wikieditor-toolbar-tool-link-lookslikeinternal\":\"The URL you specified looks like it was intended as a link to another wiki page.\\nDo you want to make it an internal link?\",\"wikieditor-toolbar-tool-link-lookslikeinternal-int\":\"Internal link\",\"wikieditor-toolbar-tool-link-lookslikeinternal-ext\":\"External link\",\"wikieditor-toolbar-tool-link-empty\":\"You did not enter anything to link to.\",\"wikieditor-toolbar-tool-file\":\"Embedded file\",\"wikieditor-toolbar-tool-file-pre\":\"$1{{ns:file}}:\",\"wikieditor-toolbar-tool-file-example\":\"Example.jpg\",\"wikieditor-toolbar-tool-reference\":\"Reference\",\"wikieditor-toolbar-tool-reference-title\":\"Insert reference\",\"wikieditor-toolbar-tool-reference-cancel\":\"Cancel\",\"wikieditor-toolbar-tool-reference-text\":\"Reference text\",\"wikieditor-toolbar-tool-reference-insert\":\"Insert\",\"wikieditor-toolbar-tool-reference-example\":\"Insert footnote text here\",\"wikieditor-toolbar-tool-signature\":\"Signature and timestamp\",\"wikieditor-toolbar-section-advanced\":\"Advanced\",\"wikieditor-toolbar-tool-heading\":\"Heading\",\"wikieditor-toolbar-tool-heading-1\":\"Level 1\",\"wikieditor-toolbar-tool-heading-2\":\"Level 2\",\"wikieditor-toolbar-tool-heading-3\":\"Level 3\",\"wikieditor-toolbar-tool-heading-4\":\"Level 4\",\"wikieditor-toolbar-tool-heading-5\":\"Level 5\",\"wikieditor-toolbar-tool-heading-example\":\"Heading text\",\"wikieditor-toolbar-group-format\":\"Format\",\"wikieditor-toolbar-tool-ulist\":\"Bulleted list\",\"wikieditor-toolbar-tool-ulist-example\":\"Bulleted list item\",\"wikieditor-toolbar-tool-olist\":\"Numbered list\",\"wikieditor-toolbar-tool-olist-example\":\"Numbered list item\",\"wikieditor-toolbar-tool-indent\":\"Indentation\",\"wikieditor-toolbar-tool-indent-example\":\"Indented line\",\"wikieditor-toolbar-tool-nowiki\":\"No wiki formatting\",\"wikieditor-toolbar-tool-nowiki-example\":\"Insert non-formatted text here\",\"wikieditor-toolbar-tool-redirect\":\"Redirect\",\"wikieditor-toolbar-tool-redirect-example\":\"Target page name\",\"wikieditor-toolbar-tool-big\":\"Big\",\"wikieditor-toolbar-tool-big-example\":\"Big text\",\"wikieditor-toolbar-tool-small\":\"Small\",\"wikieditor-toolbar-tool-small-example\":\"Small text\",\"wikieditor-toolbar-tool-superscript\":\"Superscript\",\"wikieditor-toolbar-tool-superscript-example\":\"Superscript text\",\"wikieditor-toolbar-tool-subscript\":\"Subscript\",\"wikieditor-toolbar-tool-subscript-example\":\"Subscript text\",\"wikieditor-toolbar-group-insert\":\"Insert\",\"wikieditor-toolbar-tool-gallery\":\"Picture gallery\",\"wikieditor-toolbar-tool-gallery-example\":\"{{ns:file}}:Example.jpg|Caption1\\n{{ns:file}}:Example.jpg|Caption2\",\"wikieditor-toolbar-tool-newline\":\"New line\",\"wikieditor-toolbar-tool-table\":\"Table\",\"wikieditor-toolbar-tool-table-example-old\":\"-\\n! header 1\\n! header 2\\n! header 3\\n|-\\n| row 1, cell 1\\n| row 1, cell 2\\n| row 1, cell 3\\n|-\\n| row 2, cell 1\\n| row 2, cell 2\\n| row 2, cell 3\",\"wikieditor-toolbar-tool-table-example-cell-text\":\"Cell text\",\"wikieditor-toolbar-tool-table-example\":\"Example\",\"wikieditor-toolbar-tool-table-example-header\":\"Header text\",\"wikieditor-toolbar-tool-table-title\":\"Insert table\",\"wikieditor-toolbar-tool-table-dimensions-rows\":\"Rows\",\"wikieditor-toolbar-tool-table-dimensions-columns\":\"Columns\",\"wikieditor-toolbar-tool-table-dimensions-header\":\"Add header row\",\"wikieditor-toolbar-tool-table-wikitable\":\"Style with borders\",\"wikieditor-toolbar-tool-table-sortable\":\"Make table sortable\",\"wikieditor-toolbar-tool-table-insert\":\"Insert\",\"wikieditor-toolbar-tool-table-cancel\":\"Cancel\",\"wikieditor-toolbar-tool-table-example-text\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut nec purus diam. Sed aliquam imperdiet nunc quis lacinia. Donec rutrum consectetur placerat. Sed volutpat neque non purus faucibus id ultricies enim euismod.\",\"wikieditor-toolbar-tool-table-toomany\":\"Inserting a table with more than $1 cells is not possible with this dialog.\",\"wikieditor-toolbar-tool-table-invalidnumber\":\"You have not entered a valid number of rows or columns.\",\"wikieditor-toolbar-tool-table-zero\":\"You cannot insert a table with zero rows or columns.\",\"wikieditor-toolbar-tool-replace\":\"Search and replace\",\"wikieditor-toolbar-tool-replace-title\":\"Search and replace\",\"wikieditor-toolbar-tool-replace-search\":\"Search for:\",\"wikieditor-toolbar-tool-replace-replace\":\"Replace with:\",\"wikieditor-toolbar-tool-replace-case\":\"Match case\",\"wikieditor-toolbar-tool-replace-regex\":\"Treat search string as a regular expression\",\"wikieditor-toolbar-tool-replace-button-findnext\":\"Find next\",\"wikieditor-toolbar-tool-replace-button-replacenext\":\"Replace next\",\"wikieditor-toolbar-tool-replace-button-replaceall\":\"Replace all\",\"wikieditor-toolbar-tool-replace-close\":\"Close\",\"wikieditor-toolbar-tool-replace-nomatch\":\"Your search did not match anything.\",\"wikieditor-toolbar-tool-replace-success\":\"$1 replacement(s) made.\",\"wikieditor-toolbar-tool-replace-emptysearch\":\"You did not enter anything to search for.\",\"wikieditor-toolbar-tool-replace-invalidregex\":\"The regular expression you entered is invalid: $1\",\"wikieditor-toolbar-section-characters\":\"Special characters\",\"wikieditor-toolbar-characters-page-latin\":\"Latin\",\"wikieditor-toolbar-characters-page-latinextended\":\"Latin extended\",\"wikieditor-toolbar-characters-page-ipa\":\"IPA\",\"wikieditor-toolbar-characters-page-symbols\":\"Symbols\",\"wikieditor-toolbar-characters-page-greek\":\"Greek\",\"wikieditor-toolbar-characters-page-cyrillic\":\"Cyrillic\",\"wikieditor-toolbar-characters-page-arabic\":\"Arabic\",\"wikieditor-toolbar-characters-page-persian\":\"Persian\",\"wikieditor-toolbar-characters-page-hebrew\":\"Hebrew\",\"wikieditor-toolbar-characters-page-bangla\":\"Bangla\",\"wikieditor-toolbar-characters-page-telugu\":\"Telugu\",\"wikieditor-toolbar-characters-page-sinhala\":\"Sinhala\",\"wikieditor-toolbar-characters-page-gujarati\":\"Gujarati\",\"wikieditor-toolbar-characters-page-thai\":\"Thai\",\"wikieditor-toolbar-characters-page-lao\":\"Lao\",\"wikieditor-toolbar-characters-page-khmer\":\"Khmer\",\"wikieditor-toolbar-section-help\":\"Help\",\"wikieditor-toolbar-help-heading-description\":\"Description\",\"wikieditor-toolbar-help-heading-syntax\":\"What you type\",\"wikieditor-toolbar-help-heading-result\":\"What you get\",\"wikieditor-toolbar-help-page-format\":\"Formatting\",\"wikieditor-toolbar-help-page-link\":\"Links\",\"wikieditor-toolbar-help-page-heading\":\"Headings\",\"wikieditor-toolbar-help-page-list\":\"Lists\",\"wikieditor-toolbar-help-page-file\":\"Files\",\"wikieditor-toolbar-help-page-reference\":\"References\",\"wikieditor-toolbar-help-page-discussion\":\"Discussion\",\"wikieditor-toolbar-help-content-bold-description\":\"Bold\",\"wikieditor-toolbar-help-content-bold-syntax\":\"\'\'\'Bold text\'\'\'\",\"wikieditor-toolbar-help-content-bold-result\":\"<strong>Bold text<\\/strong>\",\"wikieditor-toolbar-help-content-italic-description\":\"Italic\",\"wikieditor-toolbar-help-content-italic-syntax\":\"\'\'Italic text\'\'\",\"wikieditor-toolbar-help-content-italic-result\":\"<em>Italic text<\\/em>\",\"wikieditor-toolbar-help-content-bolditalic-description\":\"Bold & italic\",\"wikieditor-toolbar-help-content-bolditalic-syntax\":\"\'\'\'\'\'Bold & italic text\'\'\'\'\'\",\"wikieditor-toolbar-help-content-bolditalic-result\":\"<strong><em>Bold & italic text<\\/em><\\/strong>\",\"wikieditor-toolbar-help-content-ilink-description\":\"Internal link\",\"wikieditor-toolbar-help-content-ilink-syntax\":\"[[Page title|Link label]]<br \\/>[[Page title]]\",\"wikieditor-toolbar-help-content-ilink-result\":\"<a href=\'#\'>Link label<\\/a><br \\/><a href=\'#\'>Page title<\\/a>\",\"wikieditor-toolbar-help-content-xlink-description\":\"External link\",\"wikieditor-toolbar-help-content-xlink-syntax\":\"[http:\\/\\/www.example.org Link label]<br \\/>[http:\\/\\/www.example.org]<br \\/>http:\\/\\/www.example.org\",\"wikieditor-toolbar-help-content-xlink-result\":\"<a href=\'#\' class=\'external\'>Link label<\\/a><br \\/><a href=\'#\' class=\'external autonumber\'>[1]<\\/a><br \\/><a href=\'#\' class=\'external\'>http:\\/\\/www.example.org<\\/a>\",\"wikieditor-toolbar-help-content-heading1-description\":\"<wikieditor-toolbar-help-content-heading1-description>\",\"wikieditor-toolbar-help-content-heading1-syntax\":\"<wikieditor-toolbar-help-content-heading1-syntax>\",\"wikieditor-toolbar-help-content-heading1-result\":\"<wikieditor-toolbar-help-content-heading1-result>\",\"wikieditor-toolbar-help-content-heading2-description\":\"2nd level heading\",\"wikieditor-toolbar-help-content-heading2-syntax\":\"== Heading text ==\",\"wikieditor-toolbar-help-content-heading2-result\":\"<h2>Heading text<\\/h2>\",\"wikieditor-toolbar-help-content-heading3-description\":\"3rd level heading\",\"wikieditor-toolbar-help-content-heading3-syntax\":\"=== Heading text ===\",\"wikieditor-toolbar-help-content-heading3-result\":\"<h3>Heading text<\\/h3>\",\"wikieditor-toolbar-help-content-heading4-description\":\"4th level heading\",\"wikieditor-toolbar-help-content-heading4-syntax\":\"==== Heading text ====\",\"wikieditor-toolbar-help-content-heading4-result\":\"<h4>Heading text<\\/h4>\",\"wikieditor-toolbar-help-content-heading5-description\":\"5th level heading\",\"wikieditor-toolbar-help-content-heading5-syntax\":\"===== Heading text =====\",\"wikieditor-toolbar-help-content-heading5-result\":\"<h5>Heading text<\\/h5>\",\"wikieditor-toolbar-help-content-ulist-description\":\"Bulleted list\",\"wikieditor-toolbar-help-content-ulist-syntax\":\"* List item<br \\/>* List item\",\"wikieditor-toolbar-help-content-ulist-result\":\"<ul><li>List item<\\/li><li>List item<\\/li><\\/ul>\",\"wikieditor-toolbar-help-content-olist-description\":\"Numbered list\",\"wikieditor-toolbar-help-content-olist-syntax\":\"# List item<br \\/># List item\",\"wikieditor-toolbar-help-content-olist-result\":\"<ol><li>List item<\\/li><li>List item<\\/li><\\/ol>\",\"wikieditor-toolbar-help-content-file-description\":\"Embedded file\",\"wikieditor-toolbar-help-content-file-syntax\":\"[[{{ns:file}}:Example.png|thumb|Caption text]]\",\"wikieditor-toolbar-help-content-file-result\":\"<div style=\'width:104px;\' class=\'thumbinner\'><a title=\'Caption text\' class=\'image\' href=\'#\'><img height=\'50\' width=\'100\' border=\'0\' class=\'thumbimage\' src=\'extensions\\/UsabilityInitiative\\/images\\/wikiEditor\\/toolbar\\/example-image.png\' alt=\'\'\\/><\\/a><div class=\'thumbcaption\'><div class=\'magnify\'><a title=\'Enlarge\' class=\'internal\' href=\'#\'><img height=\'11\' width=\'15\' alt=\'\' src=\'$1\\/common\\/images\\/magnify-clip.png\'\\/><\\/a><\\/div>Caption text<\\/div><\\/div>\",\"wikieditor-toolbar-help-content-reference-description\":\"Reference\",\"wikieditor-toolbar-help-content-reference-syntax\":\"Page text.<ref name=\\\"test\\\">[http:\\/\\/www.example.org Link text], additional text.<\\/ref>\",\"wikieditor-toolbar-help-content-reference-result\":\"Page text.<sup><a href=\'#\'>[1]<\\/a><\\/sup>\",\"wikieditor-toolbar-help-content-rereference-description\":\"Additional use of same reference\",\"wikieditor-toolbar-help-content-rereference-syntax\":\"<ref name=\\\"test\\\" \\/>\",\"wikieditor-toolbar-help-content-rereference-result\":\"Page text.<sup><a href=\'#\'>[1]<\\/a><\\/sup>\",\"wikieditor-toolbar-help-content-showreferences-description\":\"Display references\",\"wikieditor-toolbar-help-content-showreferences-syntax\":\"<references \\/>\",\"wikieditor-toolbar-help-content-showreferences-result\":\"<ol class=\'references\'><li id=\'cite_note-test-0\'><b><a title=\'\' href=\'#\'>^<\\/a><\\/b> <a rel=\'nofollow\' title=\'http:\\/\\/www.example.org\' class=\'external text\' href=\'#\'>Link text<\\/a>, additional text.<\\/li><\\/ol>\",\"wikieditor-toolbar-help-content-signaturetimestamp-description\":\"Signature with timestamp\",\"wikieditor-toolbar-help-content-signaturetimestamp-syntax\":\"~~~~\",\"wikieditor-toolbar-help-content-signaturetimestamp-result\":\"<a href=\'#\' title=\'{{#special:mypage}}\'>Username<\\/a> (<a href=\'#\' title=\'{{#special:mytalk}}\'>talk<\\/a>) 15:54, 10 June 2009 (UTC)\",\"wikieditor-toolbar-help-content-signature-description\":\"Signature\",\"wikieditor-toolbar-help-content-signature-syntax\":\"~~~\",\"wikieditor-toolbar-help-content-signature-result\":\"<a href=\'#\' title=\'{{#special:mypage}}\'>Username<\\/a> (<a href=\'#\' title=\'{{#special:mytalk}}\'>talk<\\/a>)\",\"wikieditor-toolbar-help-content-indent-description\":\"Indent\",\"wikieditor-toolbar-help-content-indent-syntax\":\"Normal text<br \\/>:Indented text<br \\/>::Indented text\",\"wikieditor-toolbar-help-content-indent-result\":\"Normal text<dl><dd>Indented text<dl><dd>Indented text<\\/dd><\\/dl><\\/dd><\\/dl>\"}','20110110172914'),('jquery.async','en','{}','20110110172915'),('jquery.autoEllipsis','en','{}','20110110172915'),('jquery.checkboxShiftClick','en','{}','20110110172915'),('jquery.client','en','{}','20110110172915'),('jquery.cookie','en','{}','20110110172915'),('jquery.delayedBind','en','{}','20110110172915'),('jquery.highlightText','en','{}','20110110172915'),('jquery.makeCollapsible','en','{\"collapsible-expand\":\"Expand\",\"collapsible-collapse\":\"Collapse\"}','20110110172915'),('jquery.placeholder','en','{}','20110110172915'),('jquery.suggestions','en','{}','20110110172915'),('jquery.tabIndex','en','{}','20110110172915'),('jquery.textSelection','en','{}','20110110172915'),('jquery.wikiEditor','en','{\"wikieditor-wikitext-tab\":\"Wikitext\",\"wikieditor-loading\":\"Loading\"}','20110110172914'),('jquery.wikiEditor.toolbar','en','{}','20110110172914'),('mediawiki.action.watch.ajax','en','{}','20110110172915'),('mediawiki.language','en','{}','20110110172915'),('mediawiki.legacy.ajax','en','{\"watch\":\"Watch\",\"unwatch\":\"Unwatch\",\"watching\":\"Watching...\",\"unwatching\":\"Unwatching...\",\"tooltip-ca-watch\":\"Add this page to your watchlist\",\"tooltip-ca-unwatch\":\"Remove this page from your watchlist\"}','20110110172915'),('mediawiki.legacy.edit','en','{}','20110110172915'),('mediawiki.legacy.wikibits','en','{\"showtoc\":\"show\",\"hidetoc\":\"hide\"}','20110110172915'),('mediawiki.util','en','{}','20110110172915'); -/*!40000 ALTER TABLE `mw_msg_resource` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_msg_resource_links` --- - -DROP TABLE IF EXISTS `mw_msg_resource_links`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_msg_resource_links` ( - `mrl_resource` varbinary(255) NOT NULL, - `mrl_message` varbinary(255) NOT NULL, - UNIQUE KEY `mrl_message_resource` (`mrl_message`,`mrl_resource`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_msg_resource_links` --- - -LOCK TABLES `mw_msg_resource_links` WRITE; -/*!40000 ALTER TABLE `mw_msg_resource_links` DISABLE KEYS */; -INSERT INTO `mw_msg_resource_links` VALUES ('jquery.makeCollapsible','collapsible-collapse'),('jquery.makeCollapsible','collapsible-expand'),('mediawiki.legacy.wikibits','hidetoc'),('mediawiki.legacy.wikibits','showtoc'),('mediawiki.legacy.ajax','tooltip-ca-unwatch'),('mediawiki.legacy.ajax','tooltip-ca-watch'),('mediawiki.legacy.ajax','unwatch'),('mediawiki.legacy.ajax','unwatching'),('ext.vector.collapsibleNav','vector-collapsiblenav-more'),('ext.vector.simpleSearch','vector-simplesearch-containing'),('ext.vector.simpleSearch','vector-simplesearch-search'),('mediawiki.legacy.ajax','watch'),('mediawiki.legacy.ajax','watching'),('jquery.wikiEditor','wikieditor-loading'),('ext.wikiEditor.toolbar','wikieditor-toolbar-characters-page-arabic'),('ext.wikiEditor.toolbar','wikieditor-toolbar-characters-page-bangla'),('ext.wikiEditor.toolbar','wikieditor-toolbar-characters-page-cyrillic'),('ext.wikiEditor.toolbar','wikieditor-toolbar-characters-page-greek'),('ext.wikiEditor.toolbar','wikieditor-toolbar-characters-page-gujarati'),('ext.wikiEditor.toolbar','wikieditor-toolbar-characters-page-hebrew'),('ext.wikiEditor.toolbar','wikieditor-toolbar-characters-page-ipa'),('ext.wikiEditor.toolbar','wikieditor-toolbar-characters-page-khmer'),('ext.wikiEditor.toolbar','wikieditor-toolbar-characters-page-lao'),('ext.wikiEditor.toolbar','wikieditor-toolbar-characters-page-latin'),('ext.wikiEditor.toolbar','wikieditor-toolbar-characters-page-latinextended'),('ext.wikiEditor.toolbar','wikieditor-toolbar-characters-page-persian'),('ext.wikiEditor.toolbar','wikieditor-toolbar-characters-page-sinhala'),('ext.wikiEditor.toolbar','wikieditor-toolbar-characters-page-symbols'),('ext.wikiEditor.toolbar','wikieditor-toolbar-characters-page-telugu'),('ext.wikiEditor.toolbar','wikieditor-toolbar-characters-page-thai'),('ext.wikiEditor.toolbar','wikieditor-toolbar-group-format'),('ext.wikiEditor.toolbar','wikieditor-toolbar-group-insert'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-bold-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-bold-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-bold-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-bolditalic-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-bolditalic-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-bolditalic-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-file-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-file-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-file-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-heading1-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-heading1-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-heading1-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-heading2-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-heading2-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-heading2-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-heading3-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-heading3-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-heading3-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-heading4-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-heading4-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-heading4-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-heading5-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-heading5-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-heading5-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-ilink-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-ilink-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-ilink-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-indent-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-indent-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-indent-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-italic-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-italic-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-italic-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-olist-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-olist-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-olist-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-reference-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-reference-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-reference-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-rereference-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-rereference-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-rereference-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-showreferences-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-showreferences-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-showreferences-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-signature-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-signature-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-signature-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-signaturetimestamp-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-signaturetimestamp-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-signaturetimestamp-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-ulist-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-ulist-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-ulist-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-xlink-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-xlink-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-content-xlink-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-heading-description'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-heading-result'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-heading-syntax'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-page-discussion'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-page-file'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-page-format'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-page-heading'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-page-link'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-page-list'),('ext.wikiEditor.toolbar','wikieditor-toolbar-help-page-reference'),('ext.wikiEditor.toolbar','wikieditor-toolbar-loading'),('ext.wikiEditor.toolbar','wikieditor-toolbar-section-advanced'),('ext.wikiEditor.toolbar','wikieditor-toolbar-section-characters'),('ext.wikiEditor.toolbar','wikieditor-toolbar-section-help'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-big'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-big-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-bold'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-bold-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-file'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-file-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-file-pre'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-gallery'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-gallery-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-heading'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-heading-1'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-heading-2'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-heading-3'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-heading-4'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-heading-5'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-heading-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-ilink'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-ilink-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-indent'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-indent-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-italic'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-italic-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-cancel'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-empty'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-ext'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-ext-target'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-ext-text'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-insert'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-int'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-int-invalid'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-int-target'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-int-target-status-exists'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-int-target-status-external'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-int-target-status-invalid'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-int-target-status-loading'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-int-target-status-notexists'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-int-target-tooltip'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-int-text'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-int-text-tooltip'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-lookslikeinternal'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-lookslikeinternal-ext'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-lookslikeinternal-int'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-link-title'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-newline'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-nowiki'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-nowiki-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-olist'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-olist-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-redirect'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-redirect-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-reference'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-reference-cancel'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-reference-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-reference-insert'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-reference-text'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-reference-title'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-replace'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-replace-button-findnext'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-replace-button-replaceall'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-replace-button-replacenext'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-replace-case'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-replace-close'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-replace-emptysearch'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-replace-invalidregex'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-replace-nomatch'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-replace-regex'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-replace-replace'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-replace-search'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-replace-success'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-replace-title'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-signature'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-small'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-small-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-subscript'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-subscript-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-superscript'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-superscript-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table-cancel'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table-dimensions-columns'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table-dimensions-header'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table-dimensions-rows'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table-example-cell-text'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table-example-header'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table-example-old'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table-example-text'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table-insert'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table-invalidnumber'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table-sortable'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table-title'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table-toomany'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table-wikitable'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-table-zero'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-ulist'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-ulist-example'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-xlink'),('ext.wikiEditor.toolbar','wikieditor-toolbar-tool-xlink-example'),('jquery.wikiEditor','wikieditor-wikitext-tab'); -/*!40000 ALTER TABLE `mw_msg_resource_links` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_objectcache` --- - -DROP TABLE IF EXISTS `mw_objectcache`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_objectcache` ( - `keyname` varbinary(255) NOT NULL DEFAULT '', - `value` mediumblob, - `exptime` datetime DEFAULT NULL, - PRIMARY KEY (`keyname`), - KEY `exptime` (`exptime`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_objectcache` --- - -LOCK TABLES `mw_objectcache` WRITE; -/*!40000 ALTER TABLE `mw_objectcache` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_objectcache` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_oldimage` --- - -DROP TABLE IF EXISTS `mw_oldimage`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_oldimage` ( - `oi_name` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `oi_archive_name` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `oi_size` int(10) unsigned NOT NULL DEFAULT '0', - `oi_width` int(11) NOT NULL DEFAULT '0', - `oi_height` int(11) NOT NULL DEFAULT '0', - `oi_bits` int(11) NOT NULL DEFAULT '0', - `oi_description` tinyblob NOT NULL, - `oi_user` int(10) unsigned NOT NULL DEFAULT '0', - `oi_user_text` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - `oi_timestamp` binary(14) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `oi_metadata` mediumblob NOT NULL, - `oi_media_type` enum('UNKNOWN','BITMAP','DRAWING','AUDIO','VIDEO','MULTIMEDIA','OFFICE','TEXT','EXECUTABLE','ARCHIVE') DEFAULT NULL, - `oi_major_mime` enum('unknown','application','audio','image','text','video','message','model','multipart') NOT NULL DEFAULT 'unknown', - `oi_minor_mime` varbinary(100) NOT NULL DEFAULT 'unknown', - `oi_deleted` tinyint(3) unsigned NOT NULL DEFAULT '0', - `oi_sha1` varbinary(32) NOT NULL DEFAULT '', - KEY `oi_usertext_timestamp` (`oi_user_text`,`oi_timestamp`), - KEY `oi_name_timestamp` (`oi_name`,`oi_timestamp`), - KEY `oi_name_archive_name` (`oi_name`,`oi_archive_name`(14)), - KEY `oi_sha1` (`oi_sha1`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_oldimage` --- - -LOCK TABLES `mw_oldimage` WRITE; -/*!40000 ALTER TABLE `mw_oldimage` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_oldimage` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_page` --- - -DROP TABLE IF EXISTS `mw_page`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_page` ( - `page_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `page_namespace` int(11) NOT NULL, - `page_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - `page_restrictions` tinyblob NOT NULL, - `page_counter` bigint(20) unsigned NOT NULL DEFAULT '0', - `page_is_redirect` tinyint(3) unsigned NOT NULL DEFAULT '0', - `page_is_new` tinyint(3) unsigned NOT NULL DEFAULT '0', - `page_random` double unsigned NOT NULL, - `page_touched` binary(14) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `page_latest` int(10) unsigned NOT NULL, - `page_len` int(10) unsigned NOT NULL, - PRIMARY KEY (`page_id`), - UNIQUE KEY `name_title` (`page_namespace`,`page_title`), - KEY `page_random` (`page_random`), - KEY `page_len` (`page_len`) -) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_page` --- - -LOCK TABLES `mw_page` WRITE; -/*!40000 ALTER TABLE `mw_page` DISABLE KEYS */; -INSERT INTO `mw_page` VALUES (1,0,'Main_Page','',3,0,1,0.045389076294,'20110107184113',1,438),(2,0,'TestResources','',0,0,1,0.227355086893,'20110110173217',2,57); -/*!40000 ALTER TABLE `mw_page` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_page_props` --- - -DROP TABLE IF EXISTS `mw_page_props`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_page_props` ( - `pp_page` int(11) NOT NULL, - `pp_propname` varbinary(60) NOT NULL, - `pp_value` blob NOT NULL, - UNIQUE KEY `pp_page_propname` (`pp_page`,`pp_propname`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_page_props` --- - -LOCK TABLES `mw_page_props` WRITE; -/*!40000 ALTER TABLE `mw_page_props` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_page_props` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_page_restrictions` --- - -DROP TABLE IF EXISTS `mw_page_restrictions`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_page_restrictions` ( - `pr_page` int(11) NOT NULL, - `pr_type` varbinary(60) NOT NULL, - `pr_level` varbinary(60) NOT NULL, - `pr_cascade` tinyint(4) NOT NULL, - `pr_user` int(11) DEFAULT NULL, - `pr_expiry` varbinary(14) DEFAULT NULL, - `pr_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - PRIMARY KEY (`pr_id`), - UNIQUE KEY `pr_pagetype` (`pr_page`,`pr_type`), - KEY `pr_typelevel` (`pr_type`,`pr_level`), - KEY `pr_level` (`pr_level`), - KEY `pr_cascade` (`pr_cascade`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_page_restrictions` --- - -LOCK TABLES `mw_page_restrictions` WRITE; -/*!40000 ALTER TABLE `mw_page_restrictions` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_page_restrictions` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_pagelinks` --- - -DROP TABLE IF EXISTS `mw_pagelinks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_pagelinks` ( - `pl_from` int(10) unsigned NOT NULL DEFAULT '0', - `pl_namespace` int(11) NOT NULL DEFAULT '0', - `pl_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - UNIQUE KEY `pl_from` (`pl_from`,`pl_namespace`,`pl_title`), - UNIQUE KEY `pl_namespace` (`pl_namespace`,`pl_title`,`pl_from`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_pagelinks` --- - -LOCK TABLES `mw_pagelinks` WRITE; -/*!40000 ALTER TABLE `mw_pagelinks` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_pagelinks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_protected_titles` --- - -DROP TABLE IF EXISTS `mw_protected_titles`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_protected_titles` ( - `pt_namespace` int(11) NOT NULL, - `pt_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - `pt_user` int(10) unsigned NOT NULL, - `pt_reason` tinyblob, - `pt_timestamp` binary(14) NOT NULL, - `pt_expiry` varbinary(14) NOT NULL DEFAULT '', - `pt_create_perm` varbinary(60) NOT NULL, - UNIQUE KEY `pt_namespace_title` (`pt_namespace`,`pt_title`), - KEY `pt_timestamp` (`pt_timestamp`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_protected_titles` --- - -LOCK TABLES `mw_protected_titles` WRITE; -/*!40000 ALTER TABLE `mw_protected_titles` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_protected_titles` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_querycache` --- - -DROP TABLE IF EXISTS `mw_querycache`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_querycache` ( - `qc_type` varbinary(32) NOT NULL, - `qc_value` int(10) unsigned NOT NULL DEFAULT '0', - `qc_namespace` int(11) NOT NULL DEFAULT '0', - `qc_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - KEY `qc_type` (`qc_type`,`qc_value`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_querycache` --- - -LOCK TABLES `mw_querycache` WRITE; -/*!40000 ALTER TABLE `mw_querycache` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_querycache` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_querycache_info` --- - -DROP TABLE IF EXISTS `mw_querycache_info`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_querycache_info` ( - `qci_type` varbinary(32) NOT NULL DEFAULT '', - `qci_timestamp` binary(14) NOT NULL DEFAULT '19700101000000', - UNIQUE KEY `qci_type` (`qci_type`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_querycache_info` --- - -LOCK TABLES `mw_querycache_info` WRITE; -/*!40000 ALTER TABLE `mw_querycache_info` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_querycache_info` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_querycachetwo` --- - -DROP TABLE IF EXISTS `mw_querycachetwo`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_querycachetwo` ( - `qcc_type` varbinary(32) NOT NULL, - `qcc_value` int(10) unsigned NOT NULL DEFAULT '0', - `qcc_namespace` int(11) NOT NULL DEFAULT '0', - `qcc_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `qcc_namespacetwo` int(11) NOT NULL DEFAULT '0', - `qcc_titletwo` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - KEY `qcc_type` (`qcc_type`,`qcc_value`), - KEY `qcc_title` (`qcc_type`,`qcc_namespace`,`qcc_title`), - KEY `qcc_titletwo` (`qcc_type`,`qcc_namespacetwo`,`qcc_titletwo`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_querycachetwo` --- - -LOCK TABLES `mw_querycachetwo` WRITE; -/*!40000 ALTER TABLE `mw_querycachetwo` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_querycachetwo` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_recentchanges` --- - -DROP TABLE IF EXISTS `mw_recentchanges`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_recentchanges` ( - `rc_id` int(11) NOT NULL AUTO_INCREMENT, - `rc_timestamp` varbinary(14) NOT NULL DEFAULT '', - `rc_cur_time` varbinary(14) NOT NULL DEFAULT '', - `rc_user` int(10) unsigned NOT NULL DEFAULT '0', - `rc_user_text` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - `rc_namespace` int(11) NOT NULL DEFAULT '0', - `rc_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `rc_comment` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `rc_minor` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rc_bot` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rc_new` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rc_cur_id` int(10) unsigned NOT NULL DEFAULT '0', - `rc_this_oldid` int(10) unsigned NOT NULL DEFAULT '0', - `rc_last_oldid` int(10) unsigned NOT NULL DEFAULT '0', - `rc_type` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rc_moved_to_ns` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rc_moved_to_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `rc_patrolled` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rc_ip` varbinary(40) NOT NULL DEFAULT '', - `rc_old_len` int(11) DEFAULT NULL, - `rc_new_len` int(11) DEFAULT NULL, - `rc_deleted` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rc_logid` int(10) unsigned NOT NULL DEFAULT '0', - `rc_log_type` varbinary(255) DEFAULT NULL, - `rc_log_action` varbinary(255) DEFAULT NULL, - `rc_params` blob, - PRIMARY KEY (`rc_id`), - KEY `rc_timestamp` (`rc_timestamp`), - KEY `rc_namespace_title` (`rc_namespace`,`rc_title`), - KEY `rc_cur_id` (`rc_cur_id`), - KEY `new_name_timestamp` (`rc_new`,`rc_namespace`,`rc_timestamp`), - KEY `rc_ip` (`rc_ip`), - KEY `rc_ns_usertext` (`rc_namespace`,`rc_user_text`), - KEY `rc_user_text` (`rc_user_text`,`rc_timestamp`) -) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_recentchanges` --- - -LOCK TABLES `mw_recentchanges` WRITE; -/*!40000 ALTER TABLE `mw_recentchanges` DISABLE KEYS */; -INSERT INTO `mw_recentchanges` VALUES (1,'20110107184113','20110107184113',0,'MediaWiki Default',0,'Main_Page','',0,0,1,1,1,0,1,0,'',0,'::1',0,438,0,0,NULL,'',''),(2,'20110110173131','20110110173131',1,'WikiSysop',0,'TestResources','Created page with \"Test the the SimpleSelenium database was loaded correctly\"',0,0,1,2,2,0,1,0,'',1,'::1',0,57,0,0,NULL,'',''); -/*!40000 ALTER TABLE `mw_recentchanges` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_redirect` --- - -DROP TABLE IF EXISTS `mw_redirect`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_redirect` ( - `rd_from` int(10) unsigned NOT NULL DEFAULT '0', - `rd_namespace` int(11) NOT NULL DEFAULT '0', - `rd_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `rd_interwiki` varchar(32) DEFAULT NULL, - `rd_fragment` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, - PRIMARY KEY (`rd_from`), - KEY `rd_ns_title` (`rd_namespace`,`rd_title`,`rd_from`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_redirect` --- - -LOCK TABLES `mw_redirect` WRITE; -/*!40000 ALTER TABLE `mw_redirect` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_redirect` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_revision` --- - -DROP TABLE IF EXISTS `mw_revision`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_revision` ( - `rev_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `rev_page` int(10) unsigned NOT NULL, - `rev_text_id` int(10) unsigned NOT NULL, - `rev_comment` tinyblob NOT NULL, - `rev_user` int(10) unsigned NOT NULL DEFAULT '0', - `rev_user_text` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `rev_timestamp` binary(14) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `rev_minor_edit` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rev_deleted` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rev_len` int(10) unsigned DEFAULT NULL, - `rev_parent_id` int(10) unsigned DEFAULT NULL, - PRIMARY KEY (`rev_id`), - UNIQUE KEY `rev_page_id` (`rev_page`,`rev_id`), - KEY `rev_timestamp` (`rev_timestamp`), - KEY `page_timestamp` (`rev_page`,`rev_timestamp`), - KEY `user_timestamp` (`rev_user`,`rev_timestamp`), - KEY `usertext_timestamp` (`rev_user_text`,`rev_timestamp`) -) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 MAX_ROWS=10000000 AVG_ROW_LENGTH=1024; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_revision` --- - -LOCK TABLES `mw_revision` WRITE; -/*!40000 ALTER TABLE `mw_revision` DISABLE KEYS */; -INSERT INTO `mw_revision` VALUES (1,1,1,'',0,'MediaWiki Default','20110107184113',0,0,438,0),(2,2,2,'Created page with \"Test the the SimpleSelenium database was loaded correctly\"',1,'WikiSysop','20110110173131',0,0,57,0); -/*!40000 ALTER TABLE `mw_revision` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_searchindex` --- - -DROP TABLE IF EXISTS `mw_searchindex`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_searchindex` ( - `si_page` int(10) unsigned NOT NULL, - `si_title` varchar(255) NOT NULL DEFAULT '', - `si_text` mediumtext NOT NULL, - UNIQUE KEY `si_page` (`si_page`), - FULLTEXT KEY `si_title` (`si_title`), - FULLTEXT KEY `si_text` (`si_text`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_searchindex` --- - -LOCK TABLES `mw_searchindex` WRITE; -/*!40000 ALTER TABLE `mw_searchindex` DISABLE KEYS */; -INSERT INTO `mw_searchindex` VALUES (1,'main page',' mediawiki hasu800 been successfully installed. consult theu800 user user\'su800 guide foru800 information onu800 using theu800 wiki software. getting started getting started getting started configuration settings list mediawiki faqu800 mediawiki release mailing list '),(2,'testresources',' test theu800 theu800 simpleselenium database wasu800 loaded correctly '); -/*!40000 ALTER TABLE `mw_searchindex` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_site_stats` --- - -DROP TABLE IF EXISTS `mw_site_stats`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_site_stats` ( - `ss_row_id` int(10) unsigned NOT NULL, - `ss_total_views` bigint(20) unsigned DEFAULT '0', - `ss_total_edits` bigint(20) unsigned DEFAULT '0', - `ss_good_articles` bigint(20) unsigned DEFAULT '0', - `ss_total_pages` bigint(20) DEFAULT '-1', - `ss_users` bigint(20) DEFAULT '-1', - `ss_active_users` bigint(20) DEFAULT '-1', - `ss_admins` int(11) DEFAULT '-1', - `ss_images` int(11) DEFAULT '0', - UNIQUE KEY `ss_row_id` (`ss_row_id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_site_stats` --- - -LOCK TABLES `mw_site_stats` WRITE; -/*!40000 ALTER TABLE `mw_site_stats` DISABLE KEYS */; -INSERT INTO `mw_site_stats` VALUES (1,3,2,1,2,1,-1,-1,0); -/*!40000 ALTER TABLE `mw_site_stats` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_tag_summary` --- - -DROP TABLE IF EXISTS `mw_tag_summary`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_tag_summary` ( - `ts_rc_id` int(11) DEFAULT NULL, - `ts_log_id` int(11) DEFAULT NULL, - `ts_rev_id` int(11) DEFAULT NULL, - `ts_tags` blob NOT NULL, - UNIQUE KEY `tag_summary_rc_id` (`ts_rc_id`), - UNIQUE KEY `tag_summary_log_id` (`ts_log_id`), - UNIQUE KEY `tag_summary_rev_id` (`ts_rev_id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_tag_summary` --- - -LOCK TABLES `mw_tag_summary` WRITE; -/*!40000 ALTER TABLE `mw_tag_summary` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_tag_summary` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_templatelinks` --- - -DROP TABLE IF EXISTS `mw_templatelinks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_templatelinks` ( - `tl_from` int(10) unsigned NOT NULL DEFAULT '0', - `tl_namespace` int(11) NOT NULL DEFAULT '0', - `tl_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - UNIQUE KEY `tl_from` (`tl_from`,`tl_namespace`,`tl_title`), - UNIQUE KEY `tl_namespace` (`tl_namespace`,`tl_title`,`tl_from`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_templatelinks` --- - -LOCK TABLES `mw_templatelinks` WRITE; -/*!40000 ALTER TABLE `mw_templatelinks` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_templatelinks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_text` --- - -DROP TABLE IF EXISTS `mw_text`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_text` ( - `old_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `old_text` mediumblob NOT NULL, - `old_flags` tinyblob NOT NULL, - PRIMARY KEY (`old_id`) -) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 MAX_ROWS=10000000 AVG_ROW_LENGTH=10240; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_text` --- - -LOCK TABLES `mw_text` WRITE; -/*!40000 ALTER TABLE `mw_text` DISABLE KEYS */; -INSERT INTO `mw_text` VALUES (1,'\'\'\'MediaWiki has been successfully installed.\'\'\'\n\nConsult the [http://meta.wikimedia.org/wiki/Help:Contents User\'s Guide] for information on using the wiki software.\n\n== Getting started ==\n* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]\n* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]','utf-8'),(2,'Test the the SimpleSelenium database was loaded correctly','utf-8'); -/*!40000 ALTER TABLE `mw_text` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_trackbacks` --- - -DROP TABLE IF EXISTS `mw_trackbacks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_trackbacks` ( - `tb_id` int(11) NOT NULL AUTO_INCREMENT, - `tb_page` int(11) DEFAULT NULL, - `tb_title` varchar(255) NOT NULL, - `tb_url` blob NOT NULL, - `tb_ex` text, - `tb_name` varchar(255) DEFAULT NULL, - PRIMARY KEY (`tb_id`), - KEY `tb_page` (`tb_page`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_trackbacks` --- - -LOCK TABLES `mw_trackbacks` WRITE; -/*!40000 ALTER TABLE `mw_trackbacks` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_trackbacks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_transcache` --- - -DROP TABLE IF EXISTS `mw_transcache`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_transcache` ( - `tc_url` varbinary(255) NOT NULL, - `tc_contents` text, - `tc_time` binary(14) DEFAULT NULL, - UNIQUE KEY `tc_url_idx` (`tc_url`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_transcache` --- - -LOCK TABLES `mw_transcache` WRITE; -/*!40000 ALTER TABLE `mw_transcache` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_transcache` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_updatelog` --- - -DROP TABLE IF EXISTS `mw_updatelog`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_updatelog` ( - `ul_key` varchar(255) NOT NULL, - `ul_value` blob, - PRIMARY KEY (`ul_key`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_updatelog` --- - -LOCK TABLES `mw_updatelog` WRITE; -/*!40000 ALTER TABLE `mw_updatelog` DISABLE KEYS */; -INSERT INTO `mw_updatelog` VALUES ('cl_fields_update',NULL),('convert transcache field',NULL),('mime_minor_length',NULL),('populate category',NULL),('populate rev_len',NULL),('populate rev_parent_id',NULL),('updatelist-1.18alpha-1294425799','a:128:{i:0;a:4:{i:0;s:8:\"addField\";i:1;s:8:\"ipblocks\";i:2;s:6:\"ipb_id\";i:3;s:18:\"patch-ipblocks.sql\";}i:1;a:4:{i:0;s:8:\"addField\";i:1;s:8:\"ipblocks\";i:2;s:10:\"ipb_expiry\";i:3;s:20:\"patch-ipb_expiry.sql\";}i:2;a:1:{i:0;s:17:\"doInterwikiUpdate\";}i:3;a:1:{i:0;s:13:\"doIndexUpdate\";}i:4;a:3:{i:0;s:8:\"addTable\";i:1;s:10:\"hitcounter\";i:2;s:20:\"patch-hitcounter.sql\";}i:5;a:4:{i:0;s:8:\"addField\";i:1;s:13:\"recentchanges\";i:2;s:7:\"rc_type\";i:3;s:17:\"patch-rc_type.sql\";}i:6;a:4:{i:0;s:8:\"addField\";i:1;s:4:\"user\";i:2;s:14:\"user_real_name\";i:3;s:23:\"patch-user-realname.sql\";}i:7;a:3:{i:0;s:8:\"addTable\";i:1;s:10:\"querycache\";i:2;s:20:\"patch-querycache.sql\";}i:8;a:3:{i:0;s:8:\"addTable\";i:1;s:11:\"objectcache\";i:2;s:21:\"patch-objectcache.sql\";}i:9;a:3:{i:0;s:8:\"addTable\";i:1;s:13:\"categorylinks\";i:2;s:23:\"patch-categorylinks.sql\";}i:10;a:1:{i:0;s:16:\"doOldLinksUpdate\";}i:11;a:1:{i:0;s:22:\"doFixAncientImagelinks\";}i:12;a:4:{i:0;s:8:\"addField\";i:1;s:13:\"recentchanges\";i:2;s:5:\"rc_ip\";i:3;s:15:\"patch-rc_ip.sql\";}i:13;a:4:{i:0;s:8:\"addIndex\";i:1;s:5:\"image\";i:2;s:7:\"PRIMARY\";i:3;s:28:\"patch-image_name_primary.sql\";}i:14;a:4:{i:0;s:8:\"addField\";i:1;s:13:\"recentchanges\";i:2;s:5:\"rc_id\";i:3;s:15:\"patch-rc_id.sql\";}i:15;a:4:{i:0;s:8:\"addField\";i:1;s:13:\"recentchanges\";i:2;s:12:\"rc_patrolled\";i:3;s:19:\"patch-rc-patrol.sql\";}i:16;a:3:{i:0;s:8:\"addTable\";i:1;s:7:\"logging\";i:2;s:17:\"patch-logging.sql\";}i:17;a:4:{i:0;s:8:\"addField\";i:1;s:4:\"user\";i:2;s:10:\"user_token\";i:3;s:20:\"patch-user_token.sql\";}i:18;a:4:{i:0;s:8:\"addField\";i:1;s:9:\"watchlist\";i:2;s:24:\"wl_notificationtimestamp\";i:3;s:28:\"patch-email-notification.sql\";}i:19;a:1:{i:0;s:17:\"doWatchlistUpdate\";}i:20;a:4:{i:0;s:9:\"dropField\";i:1;s:4:\"user\";i:2;s:33:\"user_emailauthenticationtimestamp\";i:3;s:30:\"patch-email-authentication.sql\";}i:21;a:1:{i:0;s:21:\"doSchemaRestructuring\";}i:22;a:4:{i:0;s:8:\"addField\";i:1;s:7:\"logging\";i:2;s:10:\"log_params\";i:3;s:20:\"patch-log_params.sql\";}i:23;a:4:{i:0;s:8:\"checkBin\";i:1;s:7:\"logging\";i:2;s:9:\"log_title\";i:3;s:23:\"patch-logging-title.sql\";}i:24;a:4:{i:0;s:8:\"addField\";i:1;s:7:\"archive\";i:2;s:9:\"ar_rev_id\";i:3;s:24:\"patch-archive-rev_id.sql\";}i:25;a:4:{i:0;s:8:\"addField\";i:1;s:4:\"page\";i:2;s:8:\"page_len\";i:3;s:18:\"patch-page_len.sql\";}i:26;a:4:{i:0;s:9:\"dropField\";i:1;s:8:\"revision\";i:2;s:17:\"inverse_timestamp\";i:3;s:27:\"patch-inverse_timestamp.sql\";}i:27;a:4:{i:0;s:8:\"addField\";i:1;s:8:\"revision\";i:2;s:11:\"rev_text_id\";i:3;s:21:\"patch-rev_text_id.sql\";}i:28;a:4:{i:0;s:8:\"addField\";i:1;s:8:\"revision\";i:2;s:11:\"rev_deleted\";i:3;s:21:\"patch-rev_deleted.sql\";}i:29;a:4:{i:0;s:8:\"addField\";i:1;s:5:\"image\";i:2;s:9:\"img_width\";i:3;s:19:\"patch-img_width.sql\";}i:30;a:4:{i:0;s:8:\"addField\";i:1;s:5:\"image\";i:2;s:12:\"img_metadata\";i:3;s:22:\"patch-img_metadata.sql\";}i:31;a:4:{i:0;s:8:\"addField\";i:1;s:4:\"user\";i:2;s:16:\"user_email_token\";i:3;s:26:\"patch-user_email_token.sql\";}i:32;a:4:{i:0;s:8:\"addField\";i:1;s:7:\"archive\";i:2;s:10:\"ar_text_id\";i:3;s:25:\"patch-archive-text_id.sql\";}i:33;a:1:{i:0;s:15:\"doNamespaceSize\";}i:34;a:4:{i:0;s:8:\"addField\";i:1;s:5:\"image\";i:2;s:14:\"img_media_type\";i:3;s:24:\"patch-img_media_type.sql\";}i:35;a:1:{i:0;s:17:\"doPagelinksUpdate\";}i:36;a:4:{i:0;s:9:\"dropField\";i:1;s:5:\"image\";i:2;s:8:\"img_type\";i:3;s:23:\"patch-drop_img_type.sql\";}i:37;a:1:{i:0;s:18:\"doUserUniqueUpdate\";}i:38;a:1:{i:0;s:18:\"doUserGroupsUpdate\";}i:39;a:4:{i:0;s:8:\"addField\";i:1;s:10:\"site_stats\";i:2;s:14:\"ss_total_pages\";i:3;s:27:\"patch-ss_total_articles.sql\";}i:40;a:3:{i:0;s:8:\"addTable\";i:1;s:12:\"user_newtalk\";i:2;s:22:\"patch-usernewtalk2.sql\";}i:41;a:3:{i:0;s:8:\"addTable\";i:1;s:10:\"transcache\";i:2;s:20:\"patch-transcache.sql\";}i:42;a:4:{i:0;s:8:\"addField\";i:1;s:9:\"interwiki\";i:2;s:8:\"iw_trans\";i:3;s:25:\"patch-interwiki-trans.sql\";}i:43;a:3:{i:0;s:8:\"addTable\";i:1;s:10:\"trackbacks\";i:2;s:20:\"patch-trackbacks.sql\";}i:44;a:1:{i:0;s:15:\"doWatchlistNull\";}i:45;a:4:{i:0;s:8:\"addIndex\";i:1;s:7:\"logging\";i:2;s:5:\"times\";i:3;s:29:\"patch-logging-times-index.sql\";}i:46;a:4:{i:0;s:8:\"addField\";i:1;s:8:\"ipblocks\";i:2;s:15:\"ipb_range_start\";i:3;s:25:\"patch-ipb_range_start.sql\";}i:47;a:1:{i:0;s:18:\"doPageRandomUpdate\";}i:48;a:4:{i:0;s:8:\"addField\";i:1;s:4:\"user\";i:2;s:17:\"user_registration\";i:3;s:27:\"patch-user_registration.sql\";}i:49;a:1:{i:0;s:21:\"doTemplatelinksUpdate\";}i:50;a:3:{i:0;s:8:\"addTable\";i:1;s:13:\"externallinks\";i:2;s:23:\"patch-externallinks.sql\";}i:51;a:3:{i:0;s:8:\"addTable\";i:1;s:3:\"job\";i:2;s:13:\"patch-job.sql\";}i:52;a:4:{i:0;s:8:\"addField\";i:1;s:10:\"site_stats\";i:2;s:9:\"ss_images\";i:3;s:19:\"patch-ss_images.sql\";}i:53;a:3:{i:0;s:8:\"addTable\";i:1;s:9:\"langlinks\";i:2;s:19:\"patch-langlinks.sql\";}i:54;a:3:{i:0;s:8:\"addTable\";i:1;s:15:\"querycache_info\";i:2;s:24:\"patch-querycacheinfo.sql\";}i:55;a:3:{i:0;s:8:\"addTable\";i:1;s:11:\"filearchive\";i:2;s:21:\"patch-filearchive.sql\";}i:56;a:4:{i:0;s:8:\"addField\";i:1;s:8:\"ipblocks\";i:2;s:13:\"ipb_anon_only\";i:3;s:23:\"patch-ipb_anon_only.sql\";}i:57;a:4:{i:0;s:8:\"addIndex\";i:1;s:13:\"recentchanges\";i:2;s:14:\"rc_ns_usertext\";i:3;s:31:\"patch-recentchanges-utindex.sql\";}i:58;a:4:{i:0;s:8:\"addIndex\";i:1;s:13:\"recentchanges\";i:2;s:12:\"rc_user_text\";i:3;s:28:\"patch-rc_user_text-index.sql\";}i:59;a:4:{i:0;s:8:\"addField\";i:1;s:4:\"user\";i:2;s:17:\"user_newpass_time\";i:3;s:27:\"patch-user_newpass_time.sql\";}i:60;a:3:{i:0;s:8:\"addTable\";i:1;s:8:\"redirect\";i:2;s:18:\"patch-redirect.sql\";}i:61;a:3:{i:0;s:8:\"addTable\";i:1;s:13:\"querycachetwo\";i:2;s:23:\"patch-querycachetwo.sql\";}i:62;a:4:{i:0;s:8:\"addField\";i:1;s:8:\"ipblocks\";i:2;s:20:\"ipb_enable_autoblock\";i:3;s:32:\"patch-ipb_optional_autoblock.sql\";}i:63;a:1:{i:0;s:26:\"doBacklinkingIndicesUpdate\";}i:64;a:4:{i:0;s:8:\"addField\";i:1;s:13:\"recentchanges\";i:2;s:10:\"rc_old_len\";i:3;s:16:\"patch-rc_len.sql\";}i:65;a:4:{i:0;s:8:\"addField\";i:1;s:4:\"user\";i:2;s:14:\"user_editcount\";i:3;s:24:\"patch-user_editcount.sql\";}i:66;a:1:{i:0;s:20:\"doRestrictionsUpdate\";}i:67;a:4:{i:0;s:8:\"addField\";i:1;s:7:\"logging\";i:2;s:6:\"log_id\";i:3;s:16:\"patch-log_id.sql\";}i:68;a:4:{i:0;s:8:\"addField\";i:1;s:8:\"revision\";i:2;s:13:\"rev_parent_id\";i:3;s:23:\"patch-rev_parent_id.sql\";}i:69;a:4:{i:0;s:8:\"addField\";i:1;s:17:\"page_restrictions\";i:2;s:5:\"pr_id\";i:3;s:35:\"patch-page_restrictions_sortkey.sql\";}i:70;a:4:{i:0;s:8:\"addField\";i:1;s:8:\"revision\";i:2;s:7:\"rev_len\";i:3;s:17:\"patch-rev_len.sql\";}i:71;a:4:{i:0;s:8:\"addField\";i:1;s:13:\"recentchanges\";i:2;s:10:\"rc_deleted\";i:3;s:20:\"patch-rc_deleted.sql\";}i:72;a:4:{i:0;s:8:\"addField\";i:1;s:7:\"logging\";i:2;s:11:\"log_deleted\";i:3;s:21:\"patch-log_deleted.sql\";}i:73;a:4:{i:0;s:8:\"addField\";i:1;s:7:\"archive\";i:2;s:10:\"ar_deleted\";i:3;s:20:\"patch-ar_deleted.sql\";}i:74;a:4:{i:0;s:8:\"addField\";i:1;s:8:\"ipblocks\";i:2;s:11:\"ipb_deleted\";i:3;s:21:\"patch-ipb_deleted.sql\";}i:75;a:4:{i:0;s:8:\"addField\";i:1;s:11:\"filearchive\";i:2;s:10:\"fa_deleted\";i:3;s:20:\"patch-fa_deleted.sql\";}i:76;a:4:{i:0;s:8:\"addField\";i:1;s:7:\"archive\";i:2;s:6:\"ar_len\";i:3;s:16:\"patch-ar_len.sql\";}i:77;a:4:{i:0;s:8:\"addField\";i:1;s:8:\"ipblocks\";i:2;s:15:\"ipb_block_email\";i:3;s:22:\"patch-ipb_emailban.sql\";}i:78;a:1:{i:0;s:28:\"doCategorylinksIndicesUpdate\";}i:79;a:4:{i:0;s:8:\"addField\";i:1;s:8:\"oldimage\";i:2;s:11:\"oi_metadata\";i:3;s:21:\"patch-oi_metadata.sql\";}i:80;a:4:{i:0;s:8:\"addIndex\";i:1;s:7:\"archive\";i:2;s:18:\"usertext_timestamp\";i:3;s:28:\"patch-archive-user-index.sql\";}i:81;a:4:{i:0;s:8:\"addIndex\";i:1;s:5:\"image\";i:2;s:22:\"img_usertext_timestamp\";i:3;s:26:\"patch-image-user-index.sql\";}i:82;a:4:{i:0;s:8:\"addIndex\";i:1;s:8:\"oldimage\";i:2;s:21:\"oi_usertext_timestamp\";i:3;s:29:\"patch-oldimage-user-index.sql\";}i:83;a:4:{i:0;s:8:\"addField\";i:1;s:7:\"archive\";i:2;s:10:\"ar_page_id\";i:3;s:25:\"patch-archive-page_id.sql\";}i:84;a:4:{i:0;s:8:\"addField\";i:1;s:5:\"image\";i:2;s:8:\"img_sha1\";i:3;s:18:\"patch-img_sha1.sql\";}i:85;a:3:{i:0;s:8:\"addTable\";i:1;s:16:\"protected_titles\";i:2;s:26:\"patch-protected_titles.sql\";}i:86;a:4:{i:0;s:8:\"addField\";i:1;s:8:\"ipblocks\";i:2;s:11:\"ipb_by_text\";i:3;s:21:\"patch-ipb_by_text.sql\";}i:87;a:3:{i:0;s:8:\"addTable\";i:1;s:10:\"page_props\";i:2;s:20:\"patch-page_props.sql\";}i:88;a:3:{i:0;s:8:\"addTable\";i:1;s:9:\"updatelog\";i:2;s:19:\"patch-updatelog.sql\";}i:89;a:3:{i:0;s:8:\"addTable\";i:1;s:8:\"category\";i:2;s:18:\"patch-category.sql\";}i:90;a:1:{i:0;s:20:\"doCategoryPopulation\";}i:91;a:4:{i:0;s:8:\"addField\";i:1;s:7:\"archive\";i:2;s:12:\"ar_parent_id\";i:3;s:22:\"patch-ar_parent_id.sql\";}i:92;a:4:{i:0;s:8:\"addField\";i:1;s:12:\"user_newtalk\";i:2;s:19:\"user_last_timestamp\";i:3;s:29:\"patch-user_last_timestamp.sql\";}i:93;a:1:{i:0;s:18:\"doPopulateParentId\";}i:94;a:4:{i:0;s:8:\"checkBin\";i:1;s:16:\"protected_titles\";i:2;s:8:\"pt_title\";i:3;s:27:\"patch-pt_title-encoding.sql\";}i:95;a:1:{i:0;s:28:\"doMaybeProfilingMemoryUpdate\";}i:96;a:1:{i:0;s:26:\"doFilearchiveIndicesUpdate\";}i:97;a:4:{i:0;s:8:\"addField\";i:1;s:10:\"site_stats\";i:2;s:15:\"ss_active_users\";i:3;s:25:\"patch-ss_active_users.sql\";}i:98;a:1:{i:0;s:17:\"doActiveUsersInit\";}i:99;a:4:{i:0;s:8:\"addField\";i:1;s:8:\"ipblocks\";i:2;s:18:\"ipb_allow_usertalk\";i:3;s:28:\"patch-ipb_allow_usertalk.sql\";}i:100;a:1:{i:0;s:14:\"doUniquePlTlIl\";}i:101;a:3:{i:0;s:8:\"addTable\";i:1;s:10:\"change_tag\";i:2;s:20:\"patch-change_tag.sql\";}i:102;a:3:{i:0;s:8:\"addTable\";i:1;s:11:\"tag_summary\";i:2;s:20:\"patch-change_tag.sql\";}i:103;a:3:{i:0;s:8:\"addTable\";i:1;s:9:\"valid_tag\";i:2;s:20:\"patch-change_tag.sql\";}i:104;a:3:{i:0;s:8:\"addTable\";i:1;s:15:\"user_properties\";i:2;s:25:\"patch-user_properties.sql\";}i:105;a:3:{i:0;s:8:\"addTable\";i:1;s:10:\"log_search\";i:2;s:20:\"patch-log_search.sql\";}i:106;a:1:{i:0;s:21:\"doLogSearchPopulation\";}i:107;a:4:{i:0;s:8:\"addField\";i:1;s:7:\"logging\";i:2;s:13:\"log_user_text\";i:3;s:23:\"patch-log_user_text.sql\";}i:108;a:3:{i:0;s:8:\"addTable\";i:1;s:10:\"l10n_cache\";i:2;s:20:\"patch-l10n_cache.sql\";}i:109;a:3:{i:0;s:8:\"addTable\";i:1;s:13:\"external_user\";i:2;s:23:\"patch-external_user.sql\";}i:110;a:4:{i:0;s:8:\"addIndex\";i:1;s:10:\"log_search\";i:2;s:12:\"ls_field_val\";i:3;s:33:\"patch-log_search-rename-index.sql\";}i:111;a:4:{i:0;s:8:\"addIndex\";i:1;s:10:\"change_tag\";i:2;s:17:\"change_tag_rc_tag\";i:3;s:28:\"patch-change_tag-indexes.sql\";}i:112;a:4:{i:0;s:8:\"addField\";i:1;s:8:\"redirect\";i:2;s:12:\"rd_interwiki\";i:3;s:22:\"patch-rd_interwiki.sql\";}i:113;a:1:{i:0;s:23:\"doUpdateTranscacheField\";}i:114;a:1:{i:0;s:14:\"renameEuWikiId\";}i:115;a:1:{i:0;s:22:\"doUpdateMimeMinorField\";}i:116;a:1:{i:0;s:16:\"doPopulateRevLen\";}i:117;a:3:{i:0;s:8:\"addTable\";i:1;s:7:\"iwlinks\";i:2;s:17:\"patch-iwlinks.sql\";}i:118;a:4:{i:0;s:8:\"addIndex\";i:1;s:7:\"iwlinks\";i:2;s:21:\"iwl_prefix_title_from\";i:3;s:27:\"patch-rename-iwl_prefix.sql\";}i:119;a:4:{i:0;s:8:\"addField\";i:1;s:9:\"updatelog\";i:2;s:8:\"ul_value\";i:3;s:18:\"patch-ul_value.sql\";}i:120;a:4:{i:0;s:8:\"addField\";i:1;s:9:\"interwiki\";i:2;s:6:\"iw_api\";i:3;s:27:\"patch-iw_api_and_wikiid.sql\";}i:121;a:4:{i:0;s:9:\"dropIndex\";i:1;s:7:\"iwlinks\";i:2;s:10:\"iwl_prefix\";i:3;s:25:\"patch-kill-iwl_prefix.sql\";}i:122;a:4:{i:0;s:9:\"dropIndex\";i:1;s:7:\"iwlinks\";i:2;s:21:\"iwl_prefix_from_title\";i:3;s:22:\"patch-kill-iwl_pft.sql\";}i:123;a:4:{i:0;s:8:\"addField\";i:1;s:13:\"categorylinks\";i:2;s:12:\"cl_collation\";i:3;s:40:\"patch-categorylinks-better-collation.sql\";}i:124;a:1:{i:0;s:16:\"doClFieldsUpdate\";}i:125;a:1:{i:0;s:17:\"doCollationUpdate\";}i:126;a:3:{i:0;s:8:\"addTable\";i:1;s:12:\"msg_resource\";i:2;s:22:\"patch-msg_resource.sql\";}i:127;a:3:{i:0;s:8:\"addTable\";i:1;s:11:\"module_deps\";i:2;s:21:\"patch-module_deps.sql\";}}'); -/*!40000 ALTER TABLE `mw_updatelog` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_user` --- - -DROP TABLE IF EXISTS `mw_user`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_user` ( - `user_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `user_name` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `user_real_name` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `user_password` tinyblob NOT NULL, - `user_newpassword` tinyblob NOT NULL, - `user_newpass_time` binary(14) DEFAULT NULL, - `user_email` tinytext NOT NULL, - `user_touched` binary(14) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `user_token` binary(32) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `user_email_authenticated` binary(14) DEFAULT NULL, - `user_email_token` binary(32) DEFAULT NULL, - `user_email_token_expires` binary(14) DEFAULT NULL, - `user_registration` binary(14) DEFAULT NULL, - `user_editcount` int(11) DEFAULT NULL, - PRIMARY KEY (`user_id`), - UNIQUE KEY `user_name` (`user_name`), - KEY `user_email_token` (`user_email_token`) -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_user` --- - -LOCK TABLES `mw_user` WRITE; -/*!40000 ALTER TABLE `mw_user` DISABLE KEYS */; -INSERT INTO `mw_user` VALUES (1,'WikiSysop','',':B:9c595470:df2c1237ae75896744457e7dfbeb7f90','',NULL,'','','20110110173136','5e3b582786fa8150118cfa78f18de0c5',NULL,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',NULL,'20110107184113',1); -/*!40000 ALTER TABLE `mw_user` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_user_groups` --- - -DROP TABLE IF EXISTS `mw_user_groups`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_user_groups` ( - `ug_user` int(10) unsigned NOT NULL DEFAULT '0', - `ug_group` varbinary(16) NOT NULL DEFAULT '', - UNIQUE KEY `ug_user_group` (`ug_user`,`ug_group`), - KEY `ug_group` (`ug_group`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_user_groups` --- - -LOCK TABLES `mw_user_groups` WRITE; -/*!40000 ALTER TABLE `mw_user_groups` DISABLE KEYS */; -INSERT INTO `mw_user_groups` VALUES (1,'bureaucrat'),(1,'sysop'); -/*!40000 ALTER TABLE `mw_user_groups` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_user_newtalk` --- - -DROP TABLE IF EXISTS `mw_user_newtalk`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_user_newtalk` ( - `user_id` int(11) NOT NULL DEFAULT '0', - `user_ip` varbinary(40) NOT NULL DEFAULT '', - `user_last_timestamp` binary(14) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - KEY `user_id` (`user_id`), - KEY `user_ip` (`user_ip`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_user_newtalk` --- - -LOCK TABLES `mw_user_newtalk` WRITE; -/*!40000 ALTER TABLE `mw_user_newtalk` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_user_newtalk` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_user_properties` --- - -DROP TABLE IF EXISTS `mw_user_properties`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_user_properties` ( - `up_user` int(11) NOT NULL, - `up_property` varbinary(32) NOT NULL, - `up_value` blob, - UNIQUE KEY `user_properties_user_property` (`up_user`,`up_property`), - KEY `user_properties_property` (`up_property`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_user_properties` --- - -LOCK TABLES `mw_user_properties` WRITE; -/*!40000 ALTER TABLE `mw_user_properties` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_user_properties` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_valid_tag` --- - -DROP TABLE IF EXISTS `mw_valid_tag`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_valid_tag` ( - `vt_tag` varchar(255) NOT NULL, - PRIMARY KEY (`vt_tag`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_valid_tag` --- - -LOCK TABLES `mw_valid_tag` WRITE; -/*!40000 ALTER TABLE `mw_valid_tag` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_valid_tag` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_watchlist` --- - -DROP TABLE IF EXISTS `mw_watchlist`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_watchlist` ( - `wl_user` int(10) unsigned NOT NULL, - `wl_namespace` int(11) NOT NULL DEFAULT '0', - `wl_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `wl_notificationtimestamp` varbinary(14) DEFAULT NULL, - UNIQUE KEY `wl_user` (`wl_user`,`wl_namespace`,`wl_title`), - KEY `namespace_title` (`wl_namespace`,`wl_title`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_watchlist` --- - -LOCK TABLES `mw_watchlist` WRITE; -/*!40000 ALTER TABLE `mw_watchlist` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_watchlist` ENABLE KEYS */; -UNLOCK TABLES; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - --- Dump completed on 2011-01-10 9:34:34 diff --git a/tests/selenium/data/SimpleSeleniumTestImages.zip b/tests/selenium/data/SimpleSeleniumTestImages.zip Binary files differdeleted file mode 100644 index 0374a1fb..00000000 --- a/tests/selenium/data/SimpleSeleniumTestImages.zip +++ /dev/null diff --git a/tests/selenium/data/Wikipedia-logo-v2-de.png b/tests/selenium/data/Wikipedia-logo-v2-de.png Binary files differdeleted file mode 100644 index 70385243..00000000 --- a/tests/selenium/data/Wikipedia-logo-v2-de.png +++ /dev/null diff --git a/tests/selenium/data/mediawiki118_fresh_installation.sql b/tests/selenium/data/mediawiki118_fresh_installation.sql deleted file mode 100644 index 7beb9e6a..00000000 --- a/tests/selenium/data/mediawiki118_fresh_installation.sql +++ /dev/null @@ -1,1543 +0,0 @@ --- MySQL dump 10.13 Distrib 5.1.41, for Win32 (ia32) --- --- Host: localhost Database: test_wiki --- ------------------------------------------------------ --- Server version 5.1.41 - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- --- Table structure for table `mw_archive` --- - -DROP TABLE IF EXISTS `mw_archive`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_archive` ( - `ar_namespace` int(11) NOT NULL DEFAULT '0', - `ar_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `ar_text` mediumblob NOT NULL, - `ar_comment` tinyblob NOT NULL, - `ar_user` int(10) unsigned NOT NULL DEFAULT '0', - `ar_user_text` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - `ar_timestamp` binary(14) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `ar_minor_edit` tinyint(4) NOT NULL DEFAULT '0', - `ar_flags` tinyblob NOT NULL, - `ar_rev_id` int(10) unsigned DEFAULT NULL, - `ar_text_id` int(10) unsigned DEFAULT NULL, - `ar_deleted` tinyint(3) unsigned NOT NULL DEFAULT '0', - `ar_len` int(10) unsigned DEFAULT NULL, - `ar_page_id` int(10) unsigned DEFAULT NULL, - `ar_parent_id` int(10) unsigned DEFAULT NULL, - KEY `name_title_timestamp` (`ar_namespace`,`ar_title`,`ar_timestamp`), - KEY `usertext_timestamp` (`ar_user_text`,`ar_timestamp`), - KEY `ar_page_revid` (`ar_namespace`,`ar_title`,`ar_rev_id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_archive` --- - -LOCK TABLES `mw_archive` WRITE; -/*!40000 ALTER TABLE `mw_archive` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_archive` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_category` --- - -DROP TABLE IF EXISTS `mw_category`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_category` ( - `cat_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `cat_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - `cat_pages` int(11) NOT NULL DEFAULT '0', - `cat_subcats` int(11) NOT NULL DEFAULT '0', - `cat_files` int(11) NOT NULL DEFAULT '0', - `cat_hidden` tinyint(3) unsigned NOT NULL DEFAULT '0', - PRIMARY KEY (`cat_id`), - UNIQUE KEY `cat_title` (`cat_title`), - KEY `cat_pages` (`cat_pages`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_category` --- - -LOCK TABLES `mw_category` WRITE; -/*!40000 ALTER TABLE `mw_category` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_category` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_categorylinks` --- - -DROP TABLE IF EXISTS `mw_categorylinks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_categorylinks` ( - `cl_from` int(10) unsigned NOT NULL DEFAULT '0', - `cl_to` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `cl_sortkey` varbinary(230) NOT NULL DEFAULT '', - `cl_sortkey_prefix` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `cl_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - `cl_collation` varbinary(32) NOT NULL DEFAULT '', - `cl_type` enum('page','subcat','file') NOT NULL DEFAULT 'page', - UNIQUE KEY `cl_from` (`cl_from`,`cl_to`), - KEY `cl_sortkey` (`cl_to`,`cl_type`,`cl_sortkey`,`cl_from`), - KEY `cl_timestamp` (`cl_to`,`cl_timestamp`), - KEY `cl_collation` (`cl_collation`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_categorylinks` --- - -LOCK TABLES `mw_categorylinks` WRITE; -/*!40000 ALTER TABLE `mw_categorylinks` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_categorylinks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_change_tag` --- - -DROP TABLE IF EXISTS `mw_change_tag`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_change_tag` ( - `ct_rc_id` int(11) DEFAULT NULL, - `ct_log_id` int(11) DEFAULT NULL, - `ct_rev_id` int(11) DEFAULT NULL, - `ct_tag` varchar(255) NOT NULL, - `ct_params` blob, - UNIQUE KEY `change_tag_rc_tag` (`ct_rc_id`,`ct_tag`), - UNIQUE KEY `change_tag_log_tag` (`ct_log_id`,`ct_tag`), - UNIQUE KEY `change_tag_rev_tag` (`ct_rev_id`,`ct_tag`), - KEY `change_tag_tag_id` (`ct_tag`,`ct_rc_id`,`ct_rev_id`,`ct_log_id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_change_tag` --- - -LOCK TABLES `mw_change_tag` WRITE; -/*!40000 ALTER TABLE `mw_change_tag` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_change_tag` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_external_user` --- - -DROP TABLE IF EXISTS `mw_external_user`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_external_user` ( - `eu_local_id` int(10) unsigned NOT NULL, - `eu_external_id` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - PRIMARY KEY (`eu_local_id`), - UNIQUE KEY `eu_external_id` (`eu_external_id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_external_user` --- - -LOCK TABLES `mw_external_user` WRITE; -/*!40000 ALTER TABLE `mw_external_user` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_external_user` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_externallinks` --- - -DROP TABLE IF EXISTS `mw_externallinks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_externallinks` ( - `el_from` int(10) unsigned NOT NULL DEFAULT '0', - `el_to` blob NOT NULL, - `el_index` blob NOT NULL, - KEY `el_from` (`el_from`,`el_to`(40)), - KEY `el_to` (`el_to`(60),`el_from`), - KEY `el_index` (`el_index`(60)) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_externallinks` --- - -LOCK TABLES `mw_externallinks` WRITE; -/*!40000 ALTER TABLE `mw_externallinks` DISABLE KEYS */; -INSERT INTO `mw_externallinks` VALUES (1,'http://meta.wikimedia.org/wiki/Help:Contents','http://org.wikimedia.meta./wiki/Help:Contents'); -INSERT INTO `mw_externallinks` VALUES (1,'http://www.mediawiki.org/wiki/Manual:Configuration_settings','http://org.mediawiki.www./wiki/Manual:Configuration_settings'); -INSERT INTO `mw_externallinks` VALUES (1,'http://www.mediawiki.org/wiki/Manual:FAQ','http://org.mediawiki.www./wiki/Manual:FAQ'); -INSERT INTO `mw_externallinks` VALUES (1,'https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce','https://org.wikimedia.lists./mailman/listinfo/mediawiki-announce'); -/*!40000 ALTER TABLE `mw_externallinks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_filearchive` --- - -DROP TABLE IF EXISTS `mw_filearchive`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_filearchive` ( - `fa_id` int(11) NOT NULL AUTO_INCREMENT, - `fa_name` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `fa_archive_name` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT '', - `fa_storage_group` varbinary(16) DEFAULT NULL, - `fa_storage_key` varbinary(64) DEFAULT '', - `fa_deleted_user` int(11) DEFAULT NULL, - `fa_deleted_timestamp` binary(14) DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `fa_deleted_reason` text, - `fa_size` int(10) unsigned DEFAULT '0', - `fa_width` int(11) DEFAULT '0', - `fa_height` int(11) DEFAULT '0', - `fa_metadata` mediumblob, - `fa_bits` int(11) DEFAULT '0', - `fa_media_type` enum('UNKNOWN','BITMAP','DRAWING','AUDIO','VIDEO','MULTIMEDIA','OFFICE','TEXT','EXECUTABLE','ARCHIVE') DEFAULT NULL, - `fa_major_mime` enum('unknown','application','audio','image','text','video','message','model','multipart') DEFAULT 'unknown', - `fa_minor_mime` varbinary(100) DEFAULT 'unknown', - `fa_description` tinyblob, - `fa_user` int(10) unsigned DEFAULT '0', - `fa_user_text` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, - `fa_timestamp` binary(14) DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `fa_deleted` tinyint(3) unsigned NOT NULL DEFAULT '0', - PRIMARY KEY (`fa_id`), - KEY `fa_name` (`fa_name`,`fa_timestamp`), - KEY `fa_storage_group` (`fa_storage_group`,`fa_storage_key`), - KEY `fa_deleted_timestamp` (`fa_deleted_timestamp`), - KEY `fa_user_timestamp` (`fa_user_text`,`fa_timestamp`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_filearchive` --- - -LOCK TABLES `mw_filearchive` WRITE; -/*!40000 ALTER TABLE `mw_filearchive` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_filearchive` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_hitcounter` --- - -DROP TABLE IF EXISTS `mw_hitcounter`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_hitcounter` ( - `hc_id` int(10) unsigned NOT NULL -) ENGINE=MEMORY DEFAULT CHARSET=latin1 MAX_ROWS=25000; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_hitcounter` --- - -LOCK TABLES `mw_hitcounter` WRITE; -/*!40000 ALTER TABLE `mw_hitcounter` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_hitcounter` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_image` --- - -DROP TABLE IF EXISTS `mw_image`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_image` ( - `img_name` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `img_size` int(10) unsigned NOT NULL DEFAULT '0', - `img_width` int(11) NOT NULL DEFAULT '0', - `img_height` int(11) NOT NULL DEFAULT '0', - `img_metadata` mediumblob NOT NULL, - `img_bits` int(11) NOT NULL DEFAULT '0', - `img_media_type` enum('UNKNOWN','BITMAP','DRAWING','AUDIO','VIDEO','MULTIMEDIA','OFFICE','TEXT','EXECUTABLE','ARCHIVE') DEFAULT NULL, - `img_major_mime` enum('unknown','application','audio','image','text','video','message','model','multipart') NOT NULL DEFAULT 'unknown', - `img_minor_mime` varbinary(100) NOT NULL DEFAULT 'unknown', - `img_description` tinyblob NOT NULL, - `img_user` int(10) unsigned NOT NULL DEFAULT '0', - `img_user_text` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - `img_timestamp` varbinary(14) NOT NULL DEFAULT '', - `img_sha1` varbinary(32) NOT NULL DEFAULT '', - PRIMARY KEY (`img_name`), - KEY `img_usertext_timestamp` (`img_user_text`,`img_timestamp`), - KEY `img_size` (`img_size`), - KEY `img_timestamp` (`img_timestamp`), - KEY `img_sha1` (`img_sha1`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_image` --- - -LOCK TABLES `mw_image` WRITE; -/*!40000 ALTER TABLE `mw_image` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_image` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_imagelinks` --- - -DROP TABLE IF EXISTS `mw_imagelinks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_imagelinks` ( - `il_from` int(10) unsigned NOT NULL DEFAULT '0', - `il_to` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - UNIQUE KEY `il_from` (`il_from`,`il_to`), - UNIQUE KEY `il_to` (`il_to`,`il_from`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_imagelinks` --- - -LOCK TABLES `mw_imagelinks` WRITE; -/*!40000 ALTER TABLE `mw_imagelinks` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_imagelinks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_interwiki` --- - -DROP TABLE IF EXISTS `mw_interwiki`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_interwiki` ( - `iw_prefix` varchar(32) NOT NULL, - `iw_url` blob NOT NULL, - `iw_api` blob NOT NULL, - `iw_wikiid` varchar(64) NOT NULL, - `iw_local` tinyint(1) NOT NULL, - `iw_trans` tinyint(4) NOT NULL DEFAULT '0', - UNIQUE KEY `iw_prefix` (`iw_prefix`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_interwiki` --- - -LOCK TABLES `mw_interwiki` WRITE; -/*!40000 ALTER TABLE `mw_interwiki` DISABLE KEYS */; -INSERT INTO `mw_interwiki` VALUES ('acronym','http://www.acronymfinder.com/af-query.asp?String=exact&Acronym=$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('advogato','http://www.advogato.org/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('annotationwiki','http://www.seedwiki.com/page.cfm?wikiid=368&doc=$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('arxiv','http://www.arxiv.org/abs/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('c2find','http://c2.com/cgi/wiki?FindPage&value=$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('cache','http://www.google.com/search?q=cache:$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('commons','http://commons.wikimedia.org/wiki/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('corpknowpedia','http://corpknowpedia.org/wiki/index.php/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('dictionary','http://www.dict.org/bin/Dict?Database=*&Form=Dict1&Strategy=*&Query=$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('disinfopedia','http://www.disinfopedia.org/wiki.phtml?title=$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('docbook','http://wiki.docbook.org/topic/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('doi','http://dx.doi.org/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('drumcorpswiki','http://www.drumcorpswiki.com/index.php/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('dwjwiki','http://www.suberic.net/cgi-bin/dwj/wiki.cgi?$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('elibre','http://enciclopedia.us.es/index.php/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('emacswiki','http://www.emacswiki.org/cgi-bin/wiki.pl?$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('foldoc','http://foldoc.org/?$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('foxwiki','http://fox.wikis.com/wc.dll?Wiki~$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('freebsdman','http://www.FreeBSD.org/cgi/man.cgi?apropos=1&query=$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('gej','http://www.esperanto.de/cgi-bin/aktivikio/wiki.pl?$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('gentoo-wiki','http://gentoo-wiki.com/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('google','http://www.google.com/search?q=$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('googlegroups','http://groups.google.com/groups?q=$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('hammondwiki','http://www.dairiki.org/HammondWiki/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('hewikisource','http://he.wikisource.org/wiki/$1','','',1,0); -INSERT INTO `mw_interwiki` VALUES ('hrwiki','http://www.hrwiki.org/index.php/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('imdb','http://us.imdb.com/Title?$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('jargonfile','http://sunir.org/apps/meta.pl?wiki=JargonFile&redirect=$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('jspwiki','http://www.jspwiki.org/wiki/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('keiki','http://kei.ki/en/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('kmwiki','http://kmwiki.wikispaces.com/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('linuxwiki','http://linuxwiki.de/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('lojban','http://www.lojban.org/tiki/tiki-index.php?page=$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('lqwiki','http://wiki.linuxquestions.org/wiki/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('lugkr','http://lug-kr.sourceforge.net/cgi-bin/lugwiki.pl?$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('mathsongswiki','http://SeedWiki.com/page.cfm?wikiid=237&doc=$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('meatball','http://www.usemod.com/cgi-bin/mb.pl?$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('mediawikiwiki','http://www.mediawiki.org/wiki/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('mediazilla','https://bugzilla.wikimedia.org/$1','','',1,0); -INSERT INTO `mw_interwiki` VALUES ('memoryalpha','http://www.memory-alpha.org/en/index.php/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('metawiki','http://sunir.org/apps/meta.pl?$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('metawikimedia','http://meta.wikimedia.org/wiki/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('moinmoin','http://purl.net/wiki/moin/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('mozillawiki','http://wiki.mozilla.org/index.php/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('mw','http://www.mediawiki.org/wiki/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('oeis','http://www.research.att.com/cgi-bin/access.cgi/as/njas/sequences/eisA.cgi?Anum=$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('openfacts','http://openfacts.berlios.de/index.phtml?title=$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('openwiki','http://openwiki.com/?$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('pmeg','http://www.bertilow.com/pmeg/$1.php','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('ppr','http://c2.com/cgi/wiki?$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('pythoninfo','http://wiki.python.org/moin/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('rfc','http://www.rfc-editor.org/rfc/rfc$1.txt','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('s23wiki','http://is-root.de/wiki/index.php/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('seattlewiki','http://seattle.wikia.com/wiki/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('seattlewireless','http://seattlewireless.net/?$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('senseislibrary','http://senseis.xmp.net/?$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('sourceforge','http://sourceforge.net/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('squeak','http://wiki.squeak.org/squeak/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('susning','http://www.susning.nu/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('svgwiki','http://wiki.svg.org/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('tavi','http://tavi.sourceforge.net/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('tejo','http://www.tejo.org/vikio/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('theopedia','http://www.theopedia.com/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('tmbw','http://www.tmbw.net/wiki/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('tmnet','http://www.technomanifestos.net/?$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('tmwiki','http://www.EasyTopicMaps.com/?page=$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('twiki','http://twiki.org/cgi-bin/view/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('uea','http://www.tejo.org/uea/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('unreal','http://wiki.beyondunreal.com/wiki/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('usemod','http://www.usemod.com/cgi-bin/wiki.pl?$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('vinismo','http://vinismo.com/en/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('webseitzwiki','http://webseitz.fluxent.com/wiki/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('why','http://clublet.com/c/c/why?$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('wiki','http://c2.com/cgi/wiki?$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('wikia','http://www.wikia.com/wiki/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('wikibooks','http://en.wikibooks.org/wiki/$1','','',1,0); -INSERT INTO `mw_interwiki` VALUES ('wikicities','http://www.wikia.com/wiki/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('wikif1','http://www.wikif1.org/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('wikihow','http://www.wikihow.com/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('wikimedia','http://wikimediafoundation.org/wiki/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('wikinews','http://en.wikinews.org/wiki/$1','','',1,0); -INSERT INTO `mw_interwiki` VALUES ('wikinfo','http://www.wikinfo.org/index.php/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('wikipedia','http://en.wikipedia.org/wiki/$1','','',1,0); -INSERT INTO `mw_interwiki` VALUES ('wikiquote','http://en.wikiquote.org/wiki/$1','','',1,0); -INSERT INTO `mw_interwiki` VALUES ('wikisource','http://wikisource.org/wiki/$1','','',1,0); -INSERT INTO `mw_interwiki` VALUES ('wikispecies','http://species.wikimedia.org/wiki/$1','','',1,0); -INSERT INTO `mw_interwiki` VALUES ('wikitravel','http://wikitravel.org/en/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('wikiversity','http://en.wikiversity.org/wiki/$1','','',1,0); -INSERT INTO `mw_interwiki` VALUES ('wikt','http://en.wiktionary.org/wiki/$1','','',1,0); -INSERT INTO `mw_interwiki` VALUES ('wiktionary','http://en.wiktionary.org/wiki/$1','','',1,0); -INSERT INTO `mw_interwiki` VALUES ('wlug','http://www.wlug.org.nz/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('zwiki','http://zwiki.org/$1','','',0,0); -INSERT INTO `mw_interwiki` VALUES ('zzz wiki','http://wiki.zzz.ee/index.php/$1','','',0,0); -/*!40000 ALTER TABLE `mw_interwiki` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_ipblocks` --- - -DROP TABLE IF EXISTS `mw_ipblocks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_ipblocks` ( - `ipb_id` int(11) NOT NULL AUTO_INCREMENT, - `ipb_address` tinyblob NOT NULL, - `ipb_user` int(10) unsigned NOT NULL DEFAULT '0', - `ipb_by` int(10) unsigned NOT NULL DEFAULT '0', - `ipb_by_text` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `ipb_reason` tinyblob NOT NULL, - `ipb_timestamp` binary(14) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `ipb_auto` tinyint(1) NOT NULL DEFAULT '0', - `ipb_anon_only` tinyint(1) NOT NULL DEFAULT '0', - `ipb_create_account` tinyint(1) NOT NULL DEFAULT '1', - `ipb_enable_autoblock` tinyint(1) NOT NULL DEFAULT '1', - `ipb_expiry` varbinary(14) NOT NULL DEFAULT '', - `ipb_range_start` tinyblob NOT NULL, - `ipb_range_end` tinyblob NOT NULL, - `ipb_deleted` tinyint(1) NOT NULL DEFAULT '0', - `ipb_block_email` tinyint(1) NOT NULL DEFAULT '0', - `ipb_allow_usertalk` tinyint(1) NOT NULL DEFAULT '0', - PRIMARY KEY (`ipb_id`), - UNIQUE KEY `ipb_address` (`ipb_address`(255),`ipb_user`,`ipb_auto`,`ipb_anon_only`), - KEY `ipb_user` (`ipb_user`), - KEY `ipb_range` (`ipb_range_start`(8),`ipb_range_end`(8)), - KEY `ipb_timestamp` (`ipb_timestamp`), - KEY `ipb_expiry` (`ipb_expiry`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_ipblocks` --- - -LOCK TABLES `mw_ipblocks` WRITE; -/*!40000 ALTER TABLE `mw_ipblocks` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_ipblocks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_iwlinks` --- - -DROP TABLE IF EXISTS `mw_iwlinks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_iwlinks` ( - `iwl_from` int(10) unsigned NOT NULL DEFAULT '0', - `iwl_prefix` varbinary(20) NOT NULL DEFAULT '', - `iwl_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - UNIQUE KEY `iwl_from` (`iwl_from`,`iwl_prefix`,`iwl_title`), - UNIQUE KEY `iwl_prefix_title_from` (`iwl_prefix`,`iwl_title`,`iwl_from`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_iwlinks` --- - -LOCK TABLES `mw_iwlinks` WRITE; -/*!40000 ALTER TABLE `mw_iwlinks` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_iwlinks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_job` --- - -DROP TABLE IF EXISTS `mw_job`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_job` ( - `job_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `job_cmd` varbinary(60) NOT NULL DEFAULT '', - `job_namespace` int(11) NOT NULL, - `job_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - `job_params` blob NOT NULL, - PRIMARY KEY (`job_id`), - KEY `job_cmd` (`job_cmd`,`job_namespace`,`job_title`,`job_params`(128)) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_job` --- - -LOCK TABLES `mw_job` WRITE; -/*!40000 ALTER TABLE `mw_job` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_job` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_l10n_cache` --- - -DROP TABLE IF EXISTS `mw_l10n_cache`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_l10n_cache` ( - `lc_lang` varbinary(32) NOT NULL, - `lc_key` varchar(255) NOT NULL, - `lc_value` mediumblob NOT NULL, - KEY `lc_lang_key` (`lc_lang`,`lc_key`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - - - --- --- Table structure for table `mw_langlinks` --- - -DROP TABLE IF EXISTS `mw_langlinks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_langlinks` ( - `ll_from` int(10) unsigned NOT NULL DEFAULT '0', - `ll_lang` varbinary(20) NOT NULL DEFAULT '', - `ll_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - UNIQUE KEY `ll_from` (`ll_from`,`ll_lang`), - KEY `ll_lang` (`ll_lang`,`ll_title`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_langlinks` --- - -LOCK TABLES `mw_langlinks` WRITE; -/*!40000 ALTER TABLE `mw_langlinks` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_langlinks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_log_search` --- - -DROP TABLE IF EXISTS `mw_log_search`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_log_search` ( - `ls_field` varbinary(32) NOT NULL, - `ls_value` varchar(255) NOT NULL, - `ls_log_id` int(10) unsigned NOT NULL DEFAULT '0', - UNIQUE KEY `ls_field_val` (`ls_field`,`ls_value`,`ls_log_id`), - KEY `ls_log_id` (`ls_log_id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_log_search` --- - -LOCK TABLES `mw_log_search` WRITE; -/*!40000 ALTER TABLE `mw_log_search` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_log_search` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_logging` --- - -DROP TABLE IF EXISTS `mw_logging`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_logging` ( - `log_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `log_type` varbinary(32) NOT NULL DEFAULT '', - `log_action` varbinary(32) NOT NULL DEFAULT '', - `log_timestamp` binary(14) NOT NULL DEFAULT '19700101000000', - `log_user` int(10) unsigned NOT NULL DEFAULT '0', - `log_user_text` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `log_namespace` int(11) NOT NULL DEFAULT '0', - `log_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `log_page` int(10) unsigned DEFAULT NULL, - `log_comment` varchar(255) NOT NULL DEFAULT '', - `log_params` blob NOT NULL, - `log_deleted` tinyint(3) unsigned NOT NULL DEFAULT '0', - PRIMARY KEY (`log_id`), - KEY `type_time` (`log_type`,`log_timestamp`), - KEY `user_time` (`log_user`,`log_timestamp`), - KEY `page_time` (`log_namespace`,`log_title`,`log_timestamp`), - KEY `times` (`log_timestamp`), - KEY `log_user_type_time` (`log_user`,`log_type`,`log_timestamp`), - KEY `log_page_id_time` (`log_page`,`log_timestamp`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_logging` --- - -LOCK TABLES `mw_logging` WRITE; -/*!40000 ALTER TABLE `mw_logging` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_logging` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_math` --- - -DROP TABLE IF EXISTS `mw_math`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_math` ( - `math_inputhash` varbinary(16) NOT NULL, - `math_outputhash` varbinary(16) NOT NULL, - `math_html_conservativeness` tinyint(4) NOT NULL, - `math_html` text, - `math_mathml` text, - UNIQUE KEY `math_inputhash` (`math_inputhash`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_math` --- - -LOCK TABLES `mw_math` WRITE; -/*!40000 ALTER TABLE `mw_math` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_math` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_module_deps` --- - -DROP TABLE IF EXISTS `mw_module_deps`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_module_deps` ( - `md_module` varbinary(255) NOT NULL, - `md_skin` varbinary(32) NOT NULL, - `md_deps` mediumblob NOT NULL, - UNIQUE KEY `md_module_skin` (`md_module`,`md_skin`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_module_deps` --- - -LOCK TABLES `mw_module_deps` WRITE; -/*!40000 ALTER TABLE `mw_module_deps` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_module_deps` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_msg_resource` --- - -DROP TABLE IF EXISTS `mw_msg_resource`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_msg_resource` ( - `mr_resource` varbinary(255) NOT NULL, - `mr_lang` varbinary(32) NOT NULL, - `mr_blob` mediumblob NOT NULL, - `mr_timestamp` binary(14) NOT NULL, - UNIQUE KEY `mr_resource_lang` (`mr_resource`,`mr_lang`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_msg_resource` --- - -LOCK TABLES `mw_msg_resource` WRITE; -/*!40000 ALTER TABLE `mw_msg_resource` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_msg_resource` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_msg_resource_links` --- - -DROP TABLE IF EXISTS `mw_msg_resource_links`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_msg_resource_links` ( - `mrl_resource` varbinary(255) NOT NULL, - `mrl_message` varbinary(255) NOT NULL, - UNIQUE KEY `mrl_message_resource` (`mrl_message`,`mrl_resource`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_msg_resource_links` --- - -LOCK TABLES `mw_msg_resource_links` WRITE; -/*!40000 ALTER TABLE `mw_msg_resource_links` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_msg_resource_links` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_objectcache` --- - -DROP TABLE IF EXISTS `mw_objectcache`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_objectcache` ( - `keyname` varbinary(255) NOT NULL DEFAULT '', - `value` mediumblob, - `exptime` datetime DEFAULT NULL, - PRIMARY KEY (`keyname`), - KEY `exptime` (`exptime`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_objectcache` --- - -LOCK TABLES `mw_objectcache` WRITE; -/*!40000 ALTER TABLE `mw_objectcache` DISABLE KEYS */; -INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:messages:en','K�2��.�2�R\ns\r\n���S�δ2��\0','2010-12-31 13:16:31'); -INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:pcache:idhash:1-0!*!*!!en!*','�V[o�F�g~�����B��P��m)$TK�U��\0�����8$��9�a\rI�l��X>��ܹ�q�Sa,��ʕ�x��?[~ʃ|�.Z��$�8Y�\'�I�Y�K��-\04�U����J�\'&�uB)�:I������E�m�sk`�`k�Q�v��a���\rZ��t�0����+P%GE�ـ�JX;\n-s�P�@�B�b���8~�첒$��ea�υ��f��+���0[,�F�x��d�\'�z�0��BJ���=���J��c�\\��:��&B��T��\'��C��Fdÿ׆Fq����Gd����%8G�0��A�I��; Ԙ`�7�5�LI\r��(���{�c�����g+��8Qr�&�ͦ��A)�V��ЕPT��\\UƧtn��Z�e�SfJZ(V�P�}����0��O�N �=j�\\H��y�\\�U[h]T:���bd��u��+�j%\'�6k��f:E�;�@Yך��4���Ȁ��q���Z�º6<b�3��TU(d��,\n���Y|�e�\'�5��T�fU�8}�\"��m���/���}Uk�9o��;����|*R?�n��� 3d��g1��y�\\f8gk�����w��=��:/Y7���ۋ�^<�Ō����v#���i����C�#��6\Z�.0�Ua$4�=\Z���;��4����Y=���5���:kpΐq��Ŧ4��X���C��qYߵ-��Lj�����D�f�����:����(3t��14C��J�#����������WXT���Δy:�^�6�v�7����I�U�Ee��(�p0��ga�6Mj��Sc�,ѫ@��ޅ+R����A��xХ\'6���utǷbۛ��`j�8ؚ�G�IC<KS��5�|�krJ\ry�\\b3xP�����ua�@����$SS�`��tQ.gwW��\r@\'���w�� ��xZ(�>5{����dw�>�=J)\r�6t ��X����M���B�\n�ŖT����b>�qg����7��z�n7��vwr�-%u�-Qi�iX1��Ne���A#�v��ӧ�3��?','2010-12-31 13:16:31'); -INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:pcache:idoptions:1','E���@D��`�\"v�ƣ��Wh��,�b�!�⭙7�L+�|}�t��I�$�<���F\rpSl�4����OJN`\r\Z����ծ���)��PY��$�K����գ9�Vjp72��E���c�Wp�2��cVxu7�� ����p#�r=.���[>y)Zp��','2010-12-31 13:16:31'); -INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:resourceloader:filter:minify-css:3832ee25d9c44988461f5f339b9b6a48','+�26�Rr�MM�LTH�ɩV\0�Z(��(3�(R�d\r\0','2038-01-19 03:14:07'); -INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:resourceloader:filter:minify-css:aa0df16258ad99a1d249e796b5067ed9','+�2��Rr�MM�LTH�ɩN��K-�Q.,�L�NJ,R\0��s�\r���V�\Z\0','2038-01-19 03:14:07'); -INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:resourceloader:filter:minify-js:22814eeadc9cf0a9ebcd844e14198e66','m��r�0��y����r�&Qޡמ!\n�qQ�Xq;}���$��ވ� �c!]]].o5S�\n�)Fq��L^��?�s�F�!�O�M\\�������\0���N��Ɂ���լ����:��-�j��F��{ۅ�G�\"i�� \Z�6�K����!��Y]=�F[�~竍���䶃����`��9N�Ǵ���@�K��|z�?1�A��@J#_ԁ�7\'�l�1)J�͵�).�3z�f�T�A���Hњ�[#)�BzRA�7��\"T�*~SW���/P���B�Ŏ;\Z�ay�6����+U��?.$�6��-uT�v@h��s�&�����Nإb�fJ�~�]6��p��/q)�>�E�1��͔A\ne�L�g\ZE�`cW�����`fJ�E�a��>��b\n�ӑd�.u�do��[�\nt��b�+���l\Z?X*��Y�(�օ;�L�Jqťɝ���d$�\"�WzG�-@b~+�#�kǞَ�Ƃ~������P)B ����q�Җ2���r�Rl����`z �4�����ÝX�m�;�X݁t;r.�sA��R��y)�kA�\nR�JT��J�U��*�W��_ߟ�4@�vt��f���>����x���','2038-01-19 03:14:07'); -INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:resourceloader:filter:minify-js:dd9440c19c575629ac5ec90e489cf62e','+�21�R���Ԕ�����L���Ĕ�\"��ĒT�j��̒T%+���ĔJ�ZMk.%k\0','2038-01-19 03:14:07'); -/*!40000 ALTER TABLE `mw_objectcache` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_oldimage` --- - -DROP TABLE IF EXISTS `mw_oldimage`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_oldimage` ( - `oi_name` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `oi_archive_name` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `oi_size` int(10) unsigned NOT NULL DEFAULT '0', - `oi_width` int(11) NOT NULL DEFAULT '0', - `oi_height` int(11) NOT NULL DEFAULT '0', - `oi_bits` int(11) NOT NULL DEFAULT '0', - `oi_description` tinyblob NOT NULL, - `oi_user` int(10) unsigned NOT NULL DEFAULT '0', - `oi_user_text` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - `oi_timestamp` binary(14) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `oi_metadata` mediumblob NOT NULL, - `oi_media_type` enum('UNKNOWN','BITMAP','DRAWING','AUDIO','VIDEO','MULTIMEDIA','OFFICE','TEXT','EXECUTABLE','ARCHIVE') DEFAULT NULL, - `oi_major_mime` enum('unknown','application','audio','image','text','video','message','model','multipart') NOT NULL DEFAULT 'unknown', - `oi_minor_mime` varbinary(100) NOT NULL DEFAULT 'unknown', - `oi_deleted` tinyint(3) unsigned NOT NULL DEFAULT '0', - `oi_sha1` varbinary(32) NOT NULL DEFAULT '', - KEY `oi_usertext_timestamp` (`oi_user_text`,`oi_timestamp`), - KEY `oi_name_timestamp` (`oi_name`,`oi_timestamp`), - KEY `oi_name_archive_name` (`oi_name`,`oi_archive_name`(14)), - KEY `oi_sha1` (`oi_sha1`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_oldimage` --- - -LOCK TABLES `mw_oldimage` WRITE; -/*!40000 ALTER TABLE `mw_oldimage` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_oldimage` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_page` --- - -DROP TABLE IF EXISTS `mw_page`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_page` ( - `page_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `page_namespace` int(11) NOT NULL, - `page_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - `page_restrictions` tinyblob NOT NULL, - `page_counter` bigint(20) unsigned NOT NULL DEFAULT '0', - `page_is_redirect` tinyint(3) unsigned NOT NULL DEFAULT '0', - `page_is_new` tinyint(3) unsigned NOT NULL DEFAULT '0', - `page_random` double unsigned NOT NULL, - `page_touched` binary(14) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `page_latest` int(10) unsigned NOT NULL, - `page_len` int(10) unsigned NOT NULL, - PRIMARY KEY (`page_id`), - UNIQUE KEY `name_title` (`page_namespace`,`page_title`), - KEY `page_random` (`page_random`), - KEY `page_len` (`page_len`) -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_page` --- - -LOCK TABLES `mw_page` WRITE; -/*!40000 ALTER TABLE `mw_page` DISABLE KEYS */; -INSERT INTO `mw_page` VALUES (1,0,'Main_Page','',1,0,1,0.334989576352,'20101230131547',1,438); -/*!40000 ALTER TABLE `mw_page` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_page_props` --- - -DROP TABLE IF EXISTS `mw_page_props`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_page_props` ( - `pp_page` int(11) NOT NULL, - `pp_propname` varbinary(60) NOT NULL, - `pp_value` blob NOT NULL, - UNIQUE KEY `pp_page_propname` (`pp_page`,`pp_propname`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_page_props` --- - -LOCK TABLES `mw_page_props` WRITE; -/*!40000 ALTER TABLE `mw_page_props` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_page_props` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_page_restrictions` --- - -DROP TABLE IF EXISTS `mw_page_restrictions`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_page_restrictions` ( - `pr_page` int(11) NOT NULL, - `pr_type` varbinary(60) NOT NULL, - `pr_level` varbinary(60) NOT NULL, - `pr_cascade` tinyint(4) NOT NULL, - `pr_user` int(11) DEFAULT NULL, - `pr_expiry` varbinary(14) DEFAULT NULL, - `pr_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - PRIMARY KEY (`pr_id`), - UNIQUE KEY `pr_pagetype` (`pr_page`,`pr_type`), - KEY `pr_typelevel` (`pr_type`,`pr_level`), - KEY `pr_level` (`pr_level`), - KEY `pr_cascade` (`pr_cascade`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_page_restrictions` --- - -LOCK TABLES `mw_page_restrictions` WRITE; -/*!40000 ALTER TABLE `mw_page_restrictions` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_page_restrictions` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_pagelinks` --- - -DROP TABLE IF EXISTS `mw_pagelinks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_pagelinks` ( - `pl_from` int(10) unsigned NOT NULL DEFAULT '0', - `pl_namespace` int(11) NOT NULL DEFAULT '0', - `pl_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - UNIQUE KEY `pl_from` (`pl_from`,`pl_namespace`,`pl_title`), - UNIQUE KEY `pl_namespace` (`pl_namespace`,`pl_title`,`pl_from`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_pagelinks` --- - -LOCK TABLES `mw_pagelinks` WRITE; -/*!40000 ALTER TABLE `mw_pagelinks` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_pagelinks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_protected_titles` --- - -DROP TABLE IF EXISTS `mw_protected_titles`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_protected_titles` ( - `pt_namespace` int(11) NOT NULL, - `pt_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - `pt_user` int(10) unsigned NOT NULL, - `pt_reason` tinyblob, - `pt_timestamp` binary(14) NOT NULL, - `pt_expiry` varbinary(14) NOT NULL DEFAULT '', - `pt_create_perm` varbinary(60) NOT NULL, - UNIQUE KEY `pt_namespace_title` (`pt_namespace`,`pt_title`), - KEY `pt_timestamp` (`pt_timestamp`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_protected_titles` --- - -LOCK TABLES `mw_protected_titles` WRITE; -/*!40000 ALTER TABLE `mw_protected_titles` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_protected_titles` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_querycache` --- - -DROP TABLE IF EXISTS `mw_querycache`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_querycache` ( - `qc_type` varbinary(32) NOT NULL, - `qc_value` int(10) unsigned NOT NULL DEFAULT '0', - `qc_namespace` int(11) NOT NULL DEFAULT '0', - `qc_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - KEY `qc_type` (`qc_type`,`qc_value`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_querycache` --- - -LOCK TABLES `mw_querycache` WRITE; -/*!40000 ALTER TABLE `mw_querycache` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_querycache` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_querycache_info` --- - -DROP TABLE IF EXISTS `mw_querycache_info`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_querycache_info` ( - `qci_type` varbinary(32) NOT NULL DEFAULT '', - `qci_timestamp` binary(14) NOT NULL DEFAULT '19700101000000', - UNIQUE KEY `qci_type` (`qci_type`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_querycache_info` --- - -LOCK TABLES `mw_querycache_info` WRITE; -/*!40000 ALTER TABLE `mw_querycache_info` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_querycache_info` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_querycachetwo` --- - -DROP TABLE IF EXISTS `mw_querycachetwo`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_querycachetwo` ( - `qcc_type` varbinary(32) NOT NULL, - `qcc_value` int(10) unsigned NOT NULL DEFAULT '0', - `qcc_namespace` int(11) NOT NULL DEFAULT '0', - `qcc_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `qcc_namespacetwo` int(11) NOT NULL DEFAULT '0', - `qcc_titletwo` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - KEY `qcc_type` (`qcc_type`,`qcc_value`), - KEY `qcc_title` (`qcc_type`,`qcc_namespace`,`qcc_title`), - KEY `qcc_titletwo` (`qcc_type`,`qcc_namespacetwo`,`qcc_titletwo`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_querycachetwo` --- - -LOCK TABLES `mw_querycachetwo` WRITE; -/*!40000 ALTER TABLE `mw_querycachetwo` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_querycachetwo` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_recentchanges` --- - -DROP TABLE IF EXISTS `mw_recentchanges`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_recentchanges` ( - `rc_id` int(11) NOT NULL AUTO_INCREMENT, - `rc_timestamp` varbinary(14) NOT NULL DEFAULT '', - `rc_cur_time` varbinary(14) NOT NULL DEFAULT '', - `rc_user` int(10) unsigned NOT NULL DEFAULT '0', - `rc_user_text` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - `rc_namespace` int(11) NOT NULL DEFAULT '0', - `rc_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `rc_comment` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `rc_minor` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rc_bot` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rc_new` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rc_cur_id` int(10) unsigned NOT NULL DEFAULT '0', - `rc_this_oldid` int(10) unsigned NOT NULL DEFAULT '0', - `rc_last_oldid` int(10) unsigned NOT NULL DEFAULT '0', - `rc_type` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rc_moved_to_ns` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rc_moved_to_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `rc_patrolled` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rc_ip` varbinary(40) NOT NULL DEFAULT '', - `rc_old_len` int(11) DEFAULT NULL, - `rc_new_len` int(11) DEFAULT NULL, - `rc_deleted` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rc_logid` int(10) unsigned NOT NULL DEFAULT '0', - `rc_log_type` varbinary(255) DEFAULT NULL, - `rc_log_action` varbinary(255) DEFAULT NULL, - `rc_params` blob, - PRIMARY KEY (`rc_id`), - KEY `rc_timestamp` (`rc_timestamp`), - KEY `rc_namespace_title` (`rc_namespace`,`rc_title`), - KEY `rc_cur_id` (`rc_cur_id`), - KEY `new_name_timestamp` (`rc_new`,`rc_namespace`,`rc_timestamp`), - KEY `rc_ip` (`rc_ip`), - KEY `rc_ns_usertext` (`rc_namespace`,`rc_user_text`), - KEY `rc_user_text` (`rc_user_text`,`rc_timestamp`) -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_recentchanges` --- - -LOCK TABLES `mw_recentchanges` WRITE; -/*!40000 ALTER TABLE `mw_recentchanges` DISABLE KEYS */; -INSERT INTO `mw_recentchanges` VALUES (1,'20101230131547','20101230131547',0,'MediaWiki Default',0,'Main_Page','',0,0,1,1,1,0,1,0,'',0,'::1',0,438,0,0,NULL,'',''); -/*!40000 ALTER TABLE `mw_recentchanges` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_redirect` --- - -DROP TABLE IF EXISTS `mw_redirect`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_redirect` ( - `rd_from` int(10) unsigned NOT NULL DEFAULT '0', - `rd_namespace` int(11) NOT NULL DEFAULT '0', - `rd_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `rd_interwiki` varchar(32) DEFAULT NULL, - `rd_fragment` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, - PRIMARY KEY (`rd_from`), - KEY `rd_ns_title` (`rd_namespace`,`rd_title`,`rd_from`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_redirect` --- - -LOCK TABLES `mw_redirect` WRITE; -/*!40000 ALTER TABLE `mw_redirect` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_redirect` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_revision` --- - -DROP TABLE IF EXISTS `mw_revision`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_revision` ( - `rev_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `rev_page` int(10) unsigned NOT NULL, - `rev_text_id` int(10) unsigned NOT NULL, - `rev_comment` tinyblob NOT NULL, - `rev_user` int(10) unsigned NOT NULL DEFAULT '0', - `rev_user_text` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `rev_timestamp` binary(14) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `rev_minor_edit` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rev_deleted` tinyint(3) unsigned NOT NULL DEFAULT '0', - `rev_len` int(10) unsigned DEFAULT NULL, - `rev_parent_id` int(10) unsigned DEFAULT NULL, - PRIMARY KEY (`rev_id`), - UNIQUE KEY `rev_page_id` (`rev_page`,`rev_id`), - KEY `rev_timestamp` (`rev_timestamp`), - KEY `page_timestamp` (`rev_page`,`rev_timestamp`), - KEY `user_timestamp` (`rev_user`,`rev_timestamp`), - KEY `usertext_timestamp` (`rev_user_text`,`rev_timestamp`) -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 MAX_ROWS=10000000 AVG_ROW_LENGTH=1024; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_revision` --- - -LOCK TABLES `mw_revision` WRITE; -/*!40000 ALTER TABLE `mw_revision` DISABLE KEYS */; -INSERT INTO `mw_revision` VALUES (1,1,1,'',0,'MediaWiki Default','20101230131547',0,0,438,0); -/*!40000 ALTER TABLE `mw_revision` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_searchindex` --- - -DROP TABLE IF EXISTS `mw_searchindex`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_searchindex` ( - `si_page` int(10) unsigned NOT NULL, - `si_title` varchar(255) NOT NULL DEFAULT '', - `si_text` mediumtext NOT NULL, - UNIQUE KEY `si_page` (`si_page`), - FULLTEXT KEY `si_title` (`si_title`), - FULLTEXT KEY `si_text` (`si_text`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_searchindex` --- - -LOCK TABLES `mw_searchindex` WRITE; -/*!40000 ALTER TABLE `mw_searchindex` DISABLE KEYS */; -INSERT INTO `mw_searchindex` VALUES (1,'main page',' mediawiki hasu800 been successfully installed. consult theu800 user user\'su800 guide foru800 information onu800 using theu800 wiki software. getting started getting started getting started configuration settings list mediawiki faqu800 mediawiki release mailing list '); -/*!40000 ALTER TABLE `mw_searchindex` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_site_stats` --- - -DROP TABLE IF EXISTS `mw_site_stats`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_site_stats` ( - `ss_row_id` int(10) unsigned NOT NULL, - `ss_total_views` bigint(20) unsigned DEFAULT '0', - `ss_total_edits` bigint(20) unsigned DEFAULT '0', - `ss_good_articles` bigint(20) unsigned DEFAULT '0', - `ss_total_pages` bigint(20) DEFAULT '-1', - `ss_users` bigint(20) DEFAULT '-1', - `ss_active_users` bigint(20) DEFAULT '-1', - `ss_admins` int(11) DEFAULT '-1', - `ss_images` int(11) DEFAULT '0', - UNIQUE KEY `ss_row_id` (`ss_row_id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_site_stats` --- - -LOCK TABLES `mw_site_stats` WRITE; -/*!40000 ALTER TABLE `mw_site_stats` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_site_stats` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_tag_summary` --- - -DROP TABLE IF EXISTS `mw_tag_summary`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_tag_summary` ( - `ts_rc_id` int(11) DEFAULT NULL, - `ts_log_id` int(11) DEFAULT NULL, - `ts_rev_id` int(11) DEFAULT NULL, - `ts_tags` blob NOT NULL, - UNIQUE KEY `tag_summary_rc_id` (`ts_rc_id`), - UNIQUE KEY `tag_summary_log_id` (`ts_log_id`), - UNIQUE KEY `tag_summary_rev_id` (`ts_rev_id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_tag_summary` --- - -LOCK TABLES `mw_tag_summary` WRITE; -/*!40000 ALTER TABLE `mw_tag_summary` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_tag_summary` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_templatelinks` --- - -DROP TABLE IF EXISTS `mw_templatelinks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_templatelinks` ( - `tl_from` int(10) unsigned NOT NULL DEFAULT '0', - `tl_namespace` int(11) NOT NULL DEFAULT '0', - `tl_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - UNIQUE KEY `tl_from` (`tl_from`,`tl_namespace`,`tl_title`), - UNIQUE KEY `tl_namespace` (`tl_namespace`,`tl_title`,`tl_from`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_templatelinks` --- - -LOCK TABLES `mw_templatelinks` WRITE; -/*!40000 ALTER TABLE `mw_templatelinks` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_templatelinks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_text` --- - -DROP TABLE IF EXISTS `mw_text`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_text` ( - `old_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `old_text` mediumblob NOT NULL, - `old_flags` tinyblob NOT NULL, - PRIMARY KEY (`old_id`) -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 MAX_ROWS=10000000 AVG_ROW_LENGTH=10240; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_text` --- - -LOCK TABLES `mw_text` WRITE; -/*!40000 ALTER TABLE `mw_text` DISABLE KEYS */; -INSERT INTO `mw_text` VALUES (1,'\'\'\'MediaWiki has been successfully installed.\'\'\'\n\nConsult the [http://meta.wikimedia.org/wiki/Help:Contents User\'s Guide] for information on using the wiki software.\n\n== Getting started ==\n* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]\n* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]','utf-8'); -/*!40000 ALTER TABLE `mw_text` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_trackbacks` --- - -DROP TABLE IF EXISTS `mw_trackbacks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_trackbacks` ( - `tb_id` int(11) NOT NULL AUTO_INCREMENT, - `tb_page` int(11) DEFAULT NULL, - `tb_title` varchar(255) NOT NULL, - `tb_url` blob NOT NULL, - `tb_ex` text, - `tb_name` varchar(255) DEFAULT NULL, - PRIMARY KEY (`tb_id`), - KEY `tb_page` (`tb_page`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_trackbacks` --- - -LOCK TABLES `mw_trackbacks` WRITE; -/*!40000 ALTER TABLE `mw_trackbacks` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_trackbacks` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_transcache` --- - -DROP TABLE IF EXISTS `mw_transcache`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_transcache` ( - `tc_url` varbinary(255) NOT NULL, - `tc_contents` text, - `tc_time` binary(14) NOT NULL, - UNIQUE KEY `tc_url_idx` (`tc_url`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_transcache` --- - -LOCK TABLES `mw_transcache` WRITE; -/*!40000 ALTER TABLE `mw_transcache` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_transcache` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_updatelog` --- - -DROP TABLE IF EXISTS `mw_updatelog`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_updatelog` ( - `ul_key` varchar(255) NOT NULL, - `ul_value` blob, - PRIMARY KEY (`ul_key`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_updatelog` --- - -LOCK TABLES `mw_updatelog` WRITE; -/*!40000 ALTER TABLE `mw_updatelog` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_updatelog` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_user` --- - -DROP TABLE IF EXISTS `mw_user`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_user` ( - `user_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `user_name` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `user_real_name` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `user_password` tinyblob NOT NULL, - `user_newpassword` tinyblob NOT NULL, - `user_newpass_time` binary(14) DEFAULT NULL, - `user_email` tinytext NOT NULL, - `user_touched` binary(14) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `user_token` binary(32) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - `user_email_authenticated` binary(14) DEFAULT NULL, - `user_email_token` binary(32) DEFAULT NULL, - `user_email_token_expires` binary(14) DEFAULT NULL, - `user_registration` binary(14) DEFAULT NULL, - `user_editcount` int(11) DEFAULT NULL, - PRIMARY KEY (`user_id`), - UNIQUE KEY `user_name` (`user_name`), - KEY `user_email_token` (`user_email_token`) -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_user` --- - -LOCK TABLES `mw_user` WRITE; -/*!40000 ALTER TABLE `mw_user` DISABLE KEYS */; -INSERT INTO `mw_user` VALUES (1,'WikiSysop','',':B:b1373470:f7e87db0c9596055f39a1225b0c31508','',NULL,'','','20101230131552','de4ddde7c4eef6e3609f4287324a0a18',NULL,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',NULL,'20101230131547',0); -/*!40000 ALTER TABLE `mw_user` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_user_groups` --- - -DROP TABLE IF EXISTS `mw_user_groups`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_user_groups` ( - `ug_user` int(10) unsigned NOT NULL DEFAULT '0', - `ug_group` varbinary(16) NOT NULL DEFAULT '', - UNIQUE KEY `ug_user_group` (`ug_user`,`ug_group`), - KEY `ug_group` (`ug_group`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_user_groups` --- - -LOCK TABLES `mw_user_groups` WRITE; -/*!40000 ALTER TABLE `mw_user_groups` DISABLE KEYS */; -INSERT INTO `mw_user_groups` VALUES (1,'bureaucrat'); -INSERT INTO `mw_user_groups` VALUES (1,'sysop'); -/*!40000 ALTER TABLE `mw_user_groups` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_user_newtalk` --- - -DROP TABLE IF EXISTS `mw_user_newtalk`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_user_newtalk` ( - `user_id` int(11) NOT NULL DEFAULT '0', - `user_ip` varbinary(40) NOT NULL DEFAULT '', - `user_last_timestamp` binary(14) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - KEY `user_id` (`user_id`), - KEY `user_ip` (`user_ip`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_user_newtalk` --- - -LOCK TABLES `mw_user_newtalk` WRITE; -/*!40000 ALTER TABLE `mw_user_newtalk` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_user_newtalk` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_user_properties` --- - -DROP TABLE IF EXISTS `mw_user_properties`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_user_properties` ( - `up_user` int(11) NOT NULL, - `up_property` varbinary(32) NOT NULL, - `up_value` blob, - UNIQUE KEY `user_properties_user_property` (`up_user`,`up_property`), - KEY `user_properties_property` (`up_property`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_user_properties` --- - -LOCK TABLES `mw_user_properties` WRITE; -/*!40000 ALTER TABLE `mw_user_properties` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_user_properties` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_valid_tag` --- - -DROP TABLE IF EXISTS `mw_valid_tag`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_valid_tag` ( - `vt_tag` varchar(255) NOT NULL, - PRIMARY KEY (`vt_tag`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_valid_tag` --- - -LOCK TABLES `mw_valid_tag` WRITE; -/*!40000 ALTER TABLE `mw_valid_tag` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_valid_tag` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `mw_watchlist` --- - -DROP TABLE IF EXISTS `mw_watchlist`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mw_watchlist` ( - `wl_user` int(10) unsigned NOT NULL, - `wl_namespace` int(11) NOT NULL DEFAULT '0', - `wl_title` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', - `wl_notificationtimestamp` varbinary(14) DEFAULT NULL, - UNIQUE KEY `wl_user` (`wl_user`,`wl_namespace`,`wl_title`), - KEY `namespace_title` (`wl_namespace`,`wl_title`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `mw_watchlist` --- - -LOCK TABLES `mw_watchlist` WRITE; -/*!40000 ALTER TABLE `mw_watchlist` DISABLE KEYS */; -/*!40000 ALTER TABLE `mw_watchlist` ENABLE KEYS */; -UNLOCK TABLES; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - --- Dump completed on 2010-12-31 1:20:11 diff --git a/tests/selenium/installer/MediaWikiButtonsAvailabilityTestCase.php b/tests/selenium/installer/MediaWikiButtonsAvailabilityTestCase.php deleted file mode 100644 index 4583360d..00000000 --- a/tests/selenium/installer/MediaWikiButtonsAvailabilityTestCase.php +++ /dev/null @@ -1,90 +0,0 @@ -<?php -/** - * MediaWikiButtonsAvailabilityTestCase - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' ); - -/** - * Test Case ID : 30 (http://www.mediawiki.org/wiki/New_installer/Test_plan) - * Test Case Name :'Back' and 'Continue' button availability - * Version : MediaWiki 1.18alpha - */ -class MediaWikiButtonsAvailabilityTestCase extends MediaWikiInstallationCommonFunction { - function setUp() { - parent::setUp(); - } - - // Verify only 'Continue' button available on 'Language' page - public function testOnlyContinueButtonAvailability() { - parent::navigateLanguagePage(); - - // Verify only 'Continue' button avaialble - $this->assertTrue( $this->isElementPresent( "submit-continue" ) ); - - // 'Back' button is not avaialble - $this->assertElementNotPresent( "submit-back" ); - } - - // Verify 'Continue' and 'Back' buttons availability - public function testBothButtonsAvailability() { - // Verify buttons availability on 'Welcome to MediaWiki' page - parent::navigateWelcometoMediaWikiPage(); - $this->assertTrue( $this->isElementPresent( "submit-back" ) ); - $this->assertTrue( $this->isElementPresent( "submit-continue" ) ); - parent::restartInstallation(); - - // Verify buttons availability on 'Connect to Database' page - parent::navigateConnetToDatabasePage(); - $this->assertTrue( $this->isElementPresent( "submit-back" ) ); - $this->assertTrue( $this->isElementPresent( "submit-continue" ) ); - parent::restartInstallation(); - - // Verify buttons availability on 'Database settings' page - $databaseName = DB_NAME_PREFIX . "_db_settings"; - parent::navigateDatabaseSettingsPage( $databaseName ); - $this->assertTrue( $this->isElementPresent( "submit-back" ) ); - $this->assertTrue( $this->isElementPresent( "submit-continue" ) ); - parent::restartInstallation(); - - // Verify buttons availability on 'Name' page - $databaseName = DB_NAME_PREFIX . "_name"; - parent::navigateNamePage( $databaseName ); - $this->assertTrue( $this->isElementPresent( "submit-back" ) ); - $this->assertTrue( $this->isElementPresent( "submit-continue" ) ); - parent::restartInstallation(); - - // Verify buttons availability on 'Options' page - $databaseName = DB_NAME_PREFIX . "_options"; - parent::navigateOptionsPage( $databaseName ); - $this->assertTrue( $this->isElementPresent( "submit-back" ) ); - $this->assertTrue( $this->isElementPresent( "submit-continue" ) ); - parent::restartInstallation(); - - // Verify buttons availability on 'Install' page - $databaseName = DB_NAME_PREFIX . "_install"; - parent::navigateInstallPage( $databaseName ); - $this->assertTrue( $this->isElementPresent( "submit-back" ) ); - $this->assertTrue( $this->isElementPresent( "submit-continue" ) ); - } -} diff --git a/tests/selenium/installer/MediaWikiDifferentDatabaseAccountTestCase.php b/tests/selenium/installer/MediaWikiDifferentDatabaseAccountTestCase.php deleted file mode 100644 index 6375d660..00000000 --- a/tests/selenium/installer/MediaWikiDifferentDatabaseAccountTestCase.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php -/** - * MediaWikiDifferentDatabaseAccountTestCase - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' ); - -/** - * Test Case ID : 04 (http://www.mediawiki.org/wiki/New_installer/Test_plan) - * Test Case Name : Install MediaWiki with different Database accounts for web access. - * Version : MediaWiki 1.18alpha - */ -class MediaWikiDifferentDatabaseAccountTestCase extends MediaWikiInstallationCommonFunction { - function setUp() { - parent::setUp(); - } - - // Install Mediawiki using 'MySQL' database type. - public function testDifferentDatabaseAccount() { - $databaseName = DB_NAME_PREFIX . "_dif_accounts"; - - // Navigate to the 'Database settings' page - parent::navigateDatabaseSettingsPage( $databaseName ); - - // Click on the 'Use the same account as for installation' check box - $this->click( "mysql__SameAccount" ); - - // Change the 'Database username' - $this->type( "mysql_wgDBuser", DB_WEB_USER ); - - // Enter 'Database password:' - $this->type( "mysql_wgDBpassword", DB_WEB_USER_PASSWORD ); - - // Select 'Create the account if it does not already exist' check box - $this->click( "mysql__CreateDBAccount" ); - parent::clickContinueButton(); - - // 'Name' page - parent::completeNamePage(); - - // 'Options' page - parent::clickContinueButton(); - - // 'Install' page - $this->assertEquals( "Creating database user... done", - $this->getText( LINK_FORM . "ul/li[3]" ) ); - parent::clickContinueButton(); - - // 'Complete' page - parent::completePageSuccessfull(); - $this->chooseCancelOnNextConfirmation(); - } -} diff --git a/tests/selenium/installer/MediaWikiDifferntDatabasePrefixTestCase.php b/tests/selenium/installer/MediaWikiDifferntDatabasePrefixTestCase.php deleted file mode 100644 index fad4e06f..00000000 --- a/tests/selenium/installer/MediaWikiDifferntDatabasePrefixTestCase.php +++ /dev/null @@ -1,88 +0,0 @@ -<?php -/** - * MediaWikiDifferntDatabasePrefixTestCase - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' ); - -/** - * Test Case ID : 02 (http://www.mediawiki.org/wiki/New_installer/Test_plan) - * Test Case Name : Install MediaWiki with the same database and the different - * database prefixes(Share one database between multiple wikis). - * Version : MediaWiki 1.18alpha - */ -class MediaWikiDifferntDatabasePrefixTestCase extends MediaWikiInstallationCommonFunction { - function setUp() { - parent::setUp(); - } - - // Install Mediawiki using 'MySQL' database type. - public function testDifferentDatabasePrefix() { - $databaseName = DB_NAME_PREFIX . "_db_prefix"; - parent::navigateInstallPage( $databaseName ); - - // To 'Options' page - parent::clickBackButton(); - - // To 'Name' page - parent::clickBackButton(); - - // To 'Database settings' page - parent::clickBackButton(); - - // To 'Connect to database' page - parent::clickBackButton(); - - // From 'Connect to database' page without database prefix - parent::clickContinueButton(); - - // Verify upgrade existing message - $this->assertEquals( "Upgrade existing installation", - $this->getText( LINK_DIV . "h2" ) ); - - // To 'Connect to database' page - parent::clickBackButton(); - - // Input the database prefix - $this->type( "mysql_wgDBprefix", DATABASE_PREFIX ); - - // From 'Connect to database' page with database prefix - parent::clickContinueButton(); - - // To 'Complete' page - parent::clickContinueButton(); - parent::completeNamePage(); - parent::clickContinueButton(); - - // Verify already installed warning message - $this->assertEquals( "Install", - $this->getText( LINK_DIV . "h2" ) ); - $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.", - $this->getText( LINK_FORM . "div[1]" ) ); - - parent::clickContinueButton(); - parent::completePageSuccessfull(); - $this->chooseCancelOnNextConfirmation(); - parent::restartInstallation(); - } -} diff --git a/tests/selenium/installer/MediaWikiErrorsConnectToDatabasePageTestCase.php b/tests/selenium/installer/MediaWikiErrorsConnectToDatabasePageTestCase.php deleted file mode 100644 index 37f5af2f..00000000 --- a/tests/selenium/installer/MediaWikiErrorsConnectToDatabasePageTestCase.php +++ /dev/null @@ -1,131 +0,0 @@ -<?php -/** - * MediaWikiErrorsConnectToDatabasePageTestCase - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - - -require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' ); - -/** - * Test Case ID : 09 (http://www.mediawiki.org/wiki/New_installer/Test_plan) - * Test Case Name : Invalid/ blank values for fields in 'Connect to database' page. - * Version : MediaWiki 1.18alpha - */ - -class MediaWikiErrorsConnectToDatabasePageTestCase extends MediaWikiInstallationCommonFunction { - - function setUp() { - parent::setUp(); - } - - // Verify warning messages for the 'Connet to database' page - public function testErrorsConnectToDatabasePage() { - parent::navigateConnetToDatabasePage(); - - // Verify warning mesage for invalid database host - $this->type( "mysql_wgDBserver", INVALID_DB_HOST ); - parent::clickContinueButton(); - $this->assertEquals( "DB connection error: php_network_getaddresses: getaddrinfo failed: No such host is known. (" . INVALID_DB_HOST . ").", - $this->getText( LINK_DIV . "div[2]/div[2]/p[1]" ) ); - $this->assertEquals( "Check the host, username and password below and try again.", - $this->getText( LINK_DIV . "div[2]/div[2]/p[2]" ) ); - // Verify warning message for the blank database host - $this->type( "mysql_wgDBserver", "" ); - parent::clickContinueButton(); - $this->assertEquals( "MySQL 4.0.14 or later is required, you have .", - $this->getText( LINK_DIV . "div[2]/div[2]" ) ); - - // Valid Database Host - $this->type( "mysql_wgDBserver", VALID_DB_HOST ); - - // Verify warning message for the invalid database name - $this->type( "mysql_wgDBname", INVALID_DB_NAME ); - parent::clickContinueButton(); - $this->assertEquals( "Invalid database name \"" . INVALID_DB_NAME . "\". Use only ASCII letters (a-z, A-Z), numbers (0-9) and underscores (_).", - $this->getText( LINK_DIV . "div[2]/div[2]/p" ) ); - - // Verify warning message for the blank database name - $this->type( "mysql_wgDBname", "" ); - parent::clickContinueButton(); - $this->assertEquals( "You must enter a value for \"Database name\"", - $this->getText( LINK_DIV . "div[2]/div[2]" ) ); - - // valid Database name - $this->type( "mysql_wgDBname", VALID_DB_NAME ); - - // Verify warning message for the invalid databaase prefix - $this->type( "mysql_wgDBprefix", INVALID_DB_PREFIX ); - parent::clickContinueButton(); - $this->assertEquals( "Invalid database prefix \"" . INVALID_DB_PREFIX . "\". Use only ASCII letters (a-z, A-Z), numbers (0-9) and underscores (_).", - $this->getText( LINK_DIV . "div[2]/div[2]" ) ); - - // Valid Database prefix - $this->type( "mysql_wgDBprefix", VALID_DB_PREFIX ); - - // Verify warning message for the invalid database user name - $this->type( "mysql__InstallUser", INVALID_DB_USER_NAME ); - parent::clickContinueButton(); - $this->assertEquals( "DB connection error: Access denied for user '" . INVALID_DB_USER_NAME . "'@'localhost' (using password: NO) (localhost).", - $this->getText( LINK_DIV . "div[2]/div[2]/p[1]" ) ); - $this->assertEquals( "Check the host, username and password below and try again.", - $this->getText( LINK_DIV . "div[2]/div[2]/p[2]" ) ); - - // Verify warning message for the blank database user name - $this->type( "mysql__InstallUser", "" ); - parent::clickContinueButton(); - $this->assertEquals( "DB connection error: Access denied for user 'SYSTEM'@'localhost' (using password: NO) (localhost).", - $this->getText( LINK_DIV . "div[2]/div[2]/p[1]" ) ); - $this->assertEquals( "Check the host, username and password below and try again.", - $this->getText( LINK_DIV . "div[2]/div[2]/p[2]" ) ); - - // Valid Database username - $this->type( "mysql__InstallUser", VALID_DB_USER_NAME ); - - // Verify warning message for the invalid password - $this->type( "mysql__InstallPassword", INVALID_DB_PASSWORD ); - parent::clickContinueButton(); - - $this->assertEquals( "DB connection error: Access denied for user 'root'@'localhost' (using password: YES) (localhost).", - $this->getText( LINK_DIV . "div[2]/div[2]/p[1]" ) ); - $this->assertEquals( "Check the host, username and password below and try again.", - $this->getText( LINK_DIV . "div[2]/div[2]/p[2]" ) ); - - // Verify warning message for the invalid username and password - $this->type( "mysql__InstallUser", INVALID_DB_USER_NAME ); - $this->type( "mysql__InstallPassword", INVALID_DB_PASSWORD ); - parent::clickContinueButton(); - $this->assertEquals( "DB connection error: Access denied for user '" . INVALID_DB_USER_NAME . "'@'localhost' (using password: YES) (localhost).", - $this->getText( LINK_DIV . "div[2]/div[2]/p[1]" ) ); - $this->assertEquals( "Check the host, username and password below and try again.", - $this->getText( LINK_DIV . "div[2]/div[2]/p[2]" ) ); - - // Valid username and valid password - $this->type( "mysql__InstallUser", VALID_DB_USER_NAME ); - $this->type( "mysql__InstallPassword", "" ); - parent::clickContinueButton(); - - // successfully completes the 'Connect to database' page - $this->assertEquals( "Database settings", - $this->getText( LINK_DIV . "h2" ) ); - } -} diff --git a/tests/selenium/installer/MediaWikiErrorsNamepageTestCase.php b/tests/selenium/installer/MediaWikiErrorsNamepageTestCase.php deleted file mode 100644 index 536ceb66..00000000 --- a/tests/selenium/installer/MediaWikiErrorsNamepageTestCase.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php -/** - * MediaWikiErrorsNamepageTestCase - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' ); - -/** - * Test Case ID : 10 (http://www.mediawiki.org/wiki/New_installer/Test_plan) - * Test Case Name : Invalid/ blank values for fields in 'Name' page. - * Version : MediaWiki 1.18alpha - */ -class MediaWikiErrorsNamepageTestCase extends MediaWikiInstallationCommonFunction { - function setUp() { - parent::setUp(); - } - - // Verify warning message for the 'Name' page - public function testErrorsNamePage() { - - $databaseName = DB_NAME_PREFIX . "_error_name"; - - parent::navigateNamePage( $databaseName ); - - // Verify warning message for all blank fields - parent::clickContinueButton(); - $this->assertEquals( "Enter a site name.", - $this->getText( LINK_DIV . "div[2]/div[2]" ) ); - $this->assertEquals( "Enter an administrator username.", - $this->getText( LINK_DIV . "div[3]/div[2]" ) ); - $this->assertEquals( "Enter a password for the administrator account.", - $this->getText( LINK_DIV . "div[4]/div[2]" ) ); - - // Verify warning message for the blank 'Site name' - $this->type( "config__AdminName", VALID_YOUR_NAME ); - $this->type( "config__AdminPassword", VALID_PASSWORD ); - $this->type( "config__AdminPassword2", VALID_PASSWORD_AGAIN ); - parent::clickContinueButton(); - $this->assertEquals( "Enter a site name.", - $this->getText( LINK_DIV . "div[2]/div[2]" ) ); - - // Input valid 'Site name' - $this->type( "config_wgSitename", VALID_WIKI_NAME ); - - // Verify warning message for the invalid "Project namespace' - $this->click( "config__NamespaceType_other" ); - $this->type( "config_wgMetaNamespace", INVALID_NAMESPACE ); - parent::clickContinueButton(); - $this->assertEquals( "The specified namespace \"\" is invalid. Specify a different project namespace.", - $this->getText( LINK_DIV . "div[2]/div[2]" ) ); - - // Verify warning message for the blank 'Project namespace' - $this->type( "config_wgSitename", VALID_WIKI_NAME ); - $this->click( "config__NamespaceType_other" ); - $this->type( "config_wgMetaNamespace", "" ); - parent::clickContinueButton(); - $this->assertEquals( "The specified namespace \"\" is invalid. Specify a different project namespace.", - $this->getText( LINK_DIV . "div[2]/div[2]" ) ); - - // Valid 'Project namespace' - $this->click( "config__NamespaceType_other" ); - $this->type( "config_wgMetaNamespace", VALID_NAMESPACE ); - parent::clickContinueButton(); - - // Valid 'Site name' - $this->click( "config__NamespaceType_site-name" ); - $this->type( "config_wgSitename", VALID_WIKI_NAME ); - - // Verify warning message for blank 'Your name' - $this->type( "config__AdminName", " " ); - parent::clickContinueButton(); - $this->assertEquals( "Enter an administrator username.", - $this->getText( LINK_DIV . "div[2]/div[2]" ) ); - - $this->type( "config_wgSitename", VALID_WIKI_NAME ); - // Verify warning message for blank 'Password' - $this->type( "config__AdminName", VALID_YOUR_NAME ); - $this->type( "config__AdminPassword", " " ); - parent::clickContinueButton(); - $this->assertEquals( "Enter a password for the administrator account.", - $this->getText( LINK_DIV . "div[2]/div[2]" ) ); - - // Verify warning message for the blank 'Password again' - $this->type( "config_wgSitename", VALID_WIKI_NAME ); - $this->type( "config__AdminPassword", VALID_PASSWORD ); - $this->type( "config__AdminPassword2", " " ); - parent::clickContinueButton(); - $this->assertEquals( "The two passwords you entered do not match.", - $this->getText( LINK_DIV . "div[2]/div[2]" ) ); - - // Verify warning message for the different'Password' and 'Password again' - $this->type( "config_wgSitename", VALID_WIKI_NAME ); - $this->type( "config__AdminPassword", VALID_PASSWORD ); - $this->type( "config__AdminPassword2", INVALID_PASSWORD_AGAIN ); - parent::clickContinueButton(); - $this->assertEquals( "The two passwords you entered do not match.", - $this->getText( LINK_DIV . "div[2]/div[2]" ) ); - } -} diff --git a/tests/selenium/installer/MediaWikiHelpFieldHintTestCase.php b/tests/selenium/installer/MediaWikiHelpFieldHintTestCase.php deleted file mode 100644 index f0efce6e..00000000 --- a/tests/selenium/installer/MediaWikiHelpFieldHintTestCase.php +++ /dev/null @@ -1,128 +0,0 @@ -<?php -/** - * MediaWikiHelpFieldHintTestCase - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' ); - -/** - * Test Case ID : 29 (http://www.mediawiki.org/wiki/New_installer/Test_plan) - * Test Case Name : Help field hint availability for the fields. - * Version : MediaWiki 1.18alpha - */ -class MediaWikiHelpFieldHintTestCase extends MediaWikiInstallationCommonFunction { - function setUp() { - parent::setUp(); - } - - // Verify help field availability for the fields - public function testMySQLConnectToDatabaseFieldHint() { - - parent::navigateConnetToDatabasePage(); - - // Verify help field for 'Database host' - $this->click( "//div[@id='DB_wrapper_mysql']/div/div[1]/div/span[1]" ); - $this->assertEquals( MYSQL_DATABASE_HOST_HELP, - $this->getText( "//div[@id='DB_wrapper_mysql']/div/div[1]/div/span[2]" ) ); - - // Verify help field for 'Database name' - $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/div/span[1]" ); - $this->assertEquals( MYSQL_DATABASE_NAME_HELP, - $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/div/span[2]" ) ); - - - // Verify help field for 'Database table prefix' - $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[2]/div[1]/div/span[1]" ); - $this->assertEquals( MYSQL_DATABASE_TABLE_PREFIX_HELP, - $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/div/span[2]/p[1]" ) ); - - // Verify help field for 'Database username' - $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[1]/div[1]/div/span[1]" ); - $this->assertEquals( MYSQL_DATBASE_USERNAME_HELP, - $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[1]/div[1]/div/span[2]" ) ); - - // Verify help field for 'Database password' - $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[2]/div[1]/div/span[1]" ); - $this->assertEquals( MYSQL_DATABASE_PASSWORD_HELP, - $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[2]/div[1]/div/span[2]/p" ) ); - } - - public function testSQLiteConnectToDatabaseFieldHint() { - parent::navigateConnetToDatabasePage(); - $this->click( "DBType_sqlite" ); - - // Verify help field for 'SQLite data directory' - $this->click( "//div[@id='DB_wrapper_sqlite']/div[1]/div[1]/div/span[1]" ); - $this->assertEquals( SQLITE_DATA_DIRECTORY_HELP, - $this->getText( "//div[@id='DB_wrapper_sqlite']/div[1]/div[1]/div/span[2]" ) ); - - // Verify help field for 'Database name' - $this->click( "//div[@id='DB_wrapper_sqlite']/div[2]/div[1]/div/span[1]" ); - $this->assertEquals( SQLITE_DATABASE_NAME_HELP, $this->getText( "//div[@id='DB_wrapper_sqlite']/div[2]/div[1]/div/span[2]/p" ) ); - } - - public function testDatabaseSettingsFieldHint() { - - $databaseName = DB_NAME_PREFIX . "_db_field"; - parent::navigateDatabaseSettingsPage( $databaseName ); - - // Verify help field for 'Search engine' - $this->click( LINK_FORM . "div[2]/span[1]" ); - $this->assertEquals( SEARCH_ENGINE_HELP, - $this->getText( LINK_FORM . "div[2]/span[2]" ) ); - - // Verify help field for 'Database character set' - $this->click( LINK_FORM . "div[4]/span[1]" ); - $this->assertEquals( DATABASE_CHARACTER_SET_HELP, - $this->getText( LINK_FORM . "div[4]/span[2]" ) ); - parent::restartInstallation(); - } - - public function testNameFieldHint() { - $databaseName = DB_NAME_PREFIX . "_name_field"; - parent::navigateNamePage( $databaseName ); - - // Verify help field for 'Name of Wiki' - $this->click( LINK_FORM . "div[1]/div[1]/div/span[1]" ); - $this->assertEquals( NAME_OF_WIKI_HELP, - $this->getText( LINK_FORM . "div[1]/div[1]/div/span[2]/p" ) ); - - // Verify help field for 'Project namespace' - $this->click( LINK_FORM . "div[2]/div[1]/div/span[1]" ); - $this->assertEquals( PROJECT_NAMESPACE_HELP, - $this->getText( LINK_FORM . "div[2]/div[1]/div/span[2]/p" ) ); - - // Verify help field for 'Your Name' - $this->click( LINK_FORM . "fieldset/div[1]/div[1]/div/span[1]" ); - $this->assertEquals( USER_NAME_HELP, - $this->getText( LINK_FORM . "fieldset/div[1]/div[1]/div/span[2]/p" ) ); - - // Verify help field for 'E mail address' - $this->click( LINK_FORM . "fieldset/div[4]/div[1]/div/span[1]" ); - $this->assertEquals( EMAIL_ADDRESS_HELP, - $this->getText( LINK_FORM . "fieldset/div[4]/div[1]/div/span[2]/p" ) ); - - parent::restartInstallation(); - } -} - diff --git a/tests/selenium/installer/MediaWikiInstallationCommonFunction.php b/tests/selenium/installer/MediaWikiInstallationCommonFunction.php deleted file mode 100644 index a9a8fc38..00000000 --- a/tests/selenium/installer/MediaWikiInstallationCommonFunction.php +++ /dev/null @@ -1,259 +0,0 @@ -<?php -/** - * MediaWikiInstallationCommonFunction - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -require_once 'PHPUnit/Extensions/SeleniumTestCase.php'; -require_once ( __DIR__ . '/MediaWikiInstallationConfig.php' ); -require_once ( __DIR__ . '/MediaWikiInstallationMessage.php' ); -require_once ( __DIR__ . '/MediaWikiInstallationVariables.php' ); - -class MediaWikiInstallationCommonFunction extends PHPUnit_Extensions_SeleniumTestCase { - function setUp() { - $this->setBrowser( TEST_BROWSER ); - $this->setBrowserUrl( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/" ); - } - - public function navigateInitialpage() { - $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/" ); - } - - // Navigate to the 'Language' page - public function navigateLanguagePage() { - $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" ); - } - - // Navigate to the 'Welcome to MediaWiki' page - public function navigateWelcometoMediaWikiPage() { - $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" ); - $this->click( "submit-continue " ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - } - - // Navigate yo 'Connect to Database' page - public function navigateConnetToDatabasePage() { - $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" ); - - // 'Welcome to MediaWiki!' page - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // 'Connect to Database' page - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - } - - // Navigate to the 'Database Settings' page - public function navigateDatabaseSettingsPage( $databaseName ) { - $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" ); - - // 'Welcome to MediaWiki!' page - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // 'Connect to Database' page - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - $this->type( "mysql_wgDBname", $databaseName ); - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - } - - // Navigate to the 'Name' page - public function navigateNamePage( $databaseName ) { - $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" ); - - // 'Welcome to MediaWiki!' page - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // 'Connect to Database' page - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - $this->type( "mysql_wgDBname", $databaseName ); - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // Database settings - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - } - - // Navigate 'Options' page - public function navigateOptionsPage( $databaseName ) { - $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" ); - - // 'Welcome to MediaWiki!' page - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // 'Connect to Database' page - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - $this->type( "mysql_wgDBname", $databaseName ); - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // Database settings - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // Name - $this->type( "config_wgSitename", NAME_OF_WIKI ); - $this->type( "config__AdminName", ADMIN_USER_NAME ); - $this->type( "config__AdminPassword", ADMIN_PASSWORD ); - $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD ); - $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS ); - - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - } - - // Navigate 'Install' page - public function navigateInstallPage( $databaseName ) { - $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" ); - - // 'Welcome to MediaWiki!' page - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // 'Connect to Database' page - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - $this->type( "mysql_wgDBname", $databaseName ); - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // Database settings - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // Name - $this->type( "config_wgSitename", NAME_OF_WIKI ); - $this->type( "config__AdminName", ADMIN_USER_NAME ); - $this->type( "config__AdminPassword", ADMIN_PASSWORD ); - $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD ); - $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS ); - - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // Options page - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - } - - // Navigate to 'Complete' page - public function navigateCompletePage( $databaseName ) { - $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" ); - - // 'Welcome to MediaWiki!' page - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // 'Connect to Database' page - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - $this->type( "mysql_wgDBname", $databaseName ); - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // Database settings - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // Name - $this->type( "config_wgSitename", NAME_OF_WIKI ); - $this->type( "config__AdminName", ADMIN_USER_NAME ); - $this->type( "config__AdminPassword", ADMIN_PASSWORD ); - $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD ); - $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS ); - - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // Options page - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // Install page - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - $this->chooseCancelOnNextConfirmation(); - } - - // Complete the Name page fields - public function completeNamePage() { - $this->type( "config_wgSitename", NAME_OF_WIKI ); - $this->type( "config__AdminName", ADMIN_USER_NAME ); - $this->type( "config__AdminPassword", ADMIN_PASSWORD ); - $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD ); - $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS ); - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - } - - // Clicking on the 'Continue' button in any MediaWiki page - public function clickContinueButton() { - $this->click( "submit-continue" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - } - - // Clicking on the 'Back' button in any MediaWiki page - public function clickBackButton() { - $this->click( "submit-back" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - } - - // Restarting the installation - public function restartInstallation() { - $this->click( "link=Restart installation" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - $this->click( "submit-restart" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - } - - // Verify 'MediaWiki' logo available in the initial screen - public function mediaWikiLogoPresentInitialScreen() { - $this->assertTrue( $this->isElementPresent( "//img[@alt='The MediaWiki logo']" ) ); - } - - // Verify 'MediaWiki' logo available - public function mediaWikiLogoPresent() { - $this->assertTrue( $this->isElementPresent( "//div[@id='p-logo']/a" ) ); - } - - public function completePageSuccessfull() { - $this->assertEquals( "Complete!", - $this->getText( "//div[@id='bodyContent']/div/div/h2" ) ); - - // 'Congratulations!' text should be available in the 'Complete!' page. - $this->assertEquals( "Congratulations!", - $this->getText( "//div[@id='bodyContent']/div/div/div[2]/form/div[1]/div[2]/p[1]/b" ) ); - } -} diff --git a/tests/selenium/installer/MediaWikiInstallationConfig.php b/tests/selenium/installer/MediaWikiInstallationConfig.php deleted file mode 100644 index 86a46247..00000000 --- a/tests/selenium/installer/MediaWikiInstallationConfig.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php -/** - * MediaWikiInstallationConfig - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - - -/** - * MediaWikiInstallerTestSuite.php can be run one time successfully - * with current value of the 'DB_NAME_PREFIX'. - * If you wish to run the suite more than one time, you need to change - * the value of the 'DB_NAME_PREFIX'. - */ -define( 'DB_NAME_PREFIX', "database_name" ); -define( 'DIRECTORY_NAME', "mediawiki" ); -define( 'PORT', "8080" ); -define( 'HOST_NAME', "localhost" ); - -/** - * Use the followings to run the test suite in different browsers. - * Firefox : *firefox - * IE : *iexplore - * Google chrome : *googlechrome - * Opera : *opera - */ -define ( 'TEST_BROWSER', "*firefox" ); diff --git a/tests/selenium/installer/MediaWikiInstallationMessage.php b/tests/selenium/installer/MediaWikiInstallationMessage.php deleted file mode 100644 index 2b7d48ef..00000000 --- a/tests/selenium/installer/MediaWikiInstallationMessage.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -/** - * MediaWikiInstallationConfig - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - - -// 'MySQL' database type help field hint -define( 'MYSQL_DATABASE_HOST_HELP', "If your database server is on different server, enter the host name or IP address here. \nIf you are using shared web hosting, your hosting provider should give you the correct host name in their documentation. \nIf you are installing on a Windows server and using MySQL, using \"localhost\" may not work for the server name. If it does not, try \"127.0.0.1\" for the local IP address." ); -define( 'MYSQL_DATABASE_NAME_HELP', "Choose a name that identifies your wiki. It should not contain spaces or hyphens. \nIf you are using shared web hosting, your hosting provider will either give you a specific database name to use or let you create databases via a control panel." ); -define( 'MYSQL_DATABASE_TABLE_PREFIX_HELP', "Choose a name that identifies your wiki. It should not contain spaces or hyphens." ); -define( 'MYSQL_DATBASE_USERNAME_HELP', "Enter the username that will be used to connect to the database during the installation process. This is not the username of the MediaWiki account; this is the username for your database." ); -define( 'MYSQL_DATABASE_PASSWORD_HELP', "Enter the password that will be used to connect to the database during the installation process. This is not the password for the MediaWiki account; this is the password for your database." ); - - -// 'SQLite' database type help field hint -define( 'SQLITE_DATA_DIRECTORY_HELP', "SQLite stores all data in a single file. \nThe directory you provide must be writable by the webserver during installation. \nIt should not be accessible via the web, this is why we're not putting it where your PHP files are. \nThe installer will write a .htaccess file along with it, but if that fails someone can gain access to your raw database. That includes raw user data (e-mail addresses, hashed passwords) as well as deleted revisions and other restricted data on the wiki. \nConsider putting the database somewhere else altogether, for example in /var/lib/mediawiki/yourwiki." ); -define( 'SQLITE_DATABASE_NAME_HELP', "Choose a name that identifies your wiki. Do not use spaces or hyphens. This will be used for the SQLite data file name." ); - - -// 'Database settings' page hel0p field hint -define( 'SEARCH_ENGINE_HELP', "InnoDB is almost always the best option, since it has good concurrency support. \nMyISAM may be faster in single-user or read-only installations. MyISAM databases tend to get corrupted more often than InnoDB databases." ); -define( 'DATABASE_CHARACTER_SET_HELP', "In binary mode, MediaWiki stores UTF-8 text to the database in binary fields. This is more efficient than MySQL's UTF-8 mode, and allows you to use the full range of Unicode characters. \nIn UTF-8 mode, MySQL will know what character set your data is in, and can present and convert it appropriately, but it will not let you store characters above the Basic Multilingual Plane." ); - - -// 'Name' page help field hint -define( 'NAME_OF_WIKI_HELP', "This will appear in the title bar of the browser and in various other places." ); -define( 'PROJECT_NAMESPACE_HELP', "Following Wikipedia's example, many wikis keep their policy pages separate from their content pages, in a \"project namespace\". All page titles in this namespace start with a certain prefix, which you can specify here. Traditionally, this prefix is derived from the name of the wiki, but it cannot contain punctuation characters such as \"#\" or \":\"." ); -define( 'USER_NAME_HELP', "Enter your preferred username here, for example \"Joe Bloggs\". This is the name you will use to log in to the wiki." ); -define( 'EMAIL_ADDRESS_HELP', "Enter an e-mail address here to allow you to receive e-mail from other users on the wiki, reset your password, and be notified of changes to pages on your watchlist." ); -define( 'SUBSCRIBE_MAILING_LIST_HELP', "This is a low-volume mailing list used for release announcements, including important security announcements. You should subscribe to it and update your MediaWiki installation when new versions come out." ); - - - diff --git a/tests/selenium/installer/MediaWikiInstallationVariables.php b/tests/selenium/installer/MediaWikiInstallationVariables.php deleted file mode 100644 index 3d7996be..00000000 --- a/tests/selenium/installer/MediaWikiInstallationVariables.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php -/** - * MediaWikiInstallationConfig - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - - -// Common variables -define( 'PAGE_LOAD_TIME', "80000" ); - -// Common links -define( 'LINK_DIV', "//div[@id='bodyContent']/div/div/" ); -define( 'LINK_FORM', "//div[@id='bodyContent']/div/div/div[2]/form/" ); -define( 'LINK_RIGHT_FRAMEWORK', "//div[@id='bodyContent']/div/div/div[1]/ul[1]/" ); - -// 'Name' page input values -define( 'NAME_OF_WIKI', "Site Name" ); -define( 'ADMIN_USER_NAME', "My Name" ); -define( 'ADMIN_PASSWORD', "12345" ); -define ( 'ADMIN_RETYPE_PASSWORD', "12345" ); -define ( 'ADMIN_EMAIL_ADDRESS', "admin@example.com" ); - - -// 'Name' page input values for warning messages -define( 'VALID_WIKI_NAME', "MyWiki" ); -define( 'VALID_YOUR_NAME', "FirstName LastName" ); -define( 'VALID_PASSWORD', "12345" ); -define( 'VALID_PASSWORD_AGAIN', "12345" ); -define( 'INVALID_PASSWORD_AGAIN', "123" ); -define( 'VALID_NAMESPACE', "Mynamespace" ); -define( 'INVALID_NAMESPACE', "##..##" ); - - -// 'Database settings' page input values -define( 'DB_WEB_USER', "different" ); -define( 'DB_WEB_USER_PASSWORD', "12345" ); - - -// 'Connet to database' page input values -define( 'DATABASE_PREFIX', "databaseprefix" ); - - -// 'Connet to database' page input values for warning messages -define( 'VALID_DB_HOST', "localhost" ); -define( 'INVALID_DB_HOST', "local" ); -define( 'INVALID_DB_NAME', "my-wiki" ); -define( 'VALID_DB_NAME', "my_wiki1" ); -define( 'INVALID_DB_PREFIX', "database prefix" ); -define( 'VALID_DB_PREFIX', "database_prefix" ); -define( 'INVALID_DB_USER_NAME', "roots" ); -define( 'VALID_DB_USER_NAME', "root" ); -define( 'INVALID_DB_PASSWORD', "12345" ); - - diff --git a/tests/selenium/installer/MediaWikiInstallerTestSuite.php b/tests/selenium/installer/MediaWikiInstallerTestSuite.php deleted file mode 100644 index 6946cc75..00000000 --- a/tests/selenium/installer/MediaWikiInstallerTestSuite.php +++ /dev/null @@ -1,49 +0,0 @@ -<?php -/** - * MediaWikiInstallerTestSuite - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -if ( PHP_SAPI != 'cli' ) { - die( "Run me from the command line please.\n" ); -} - -require_once 'PHPUnit/Framework/TestSuite.php'; - -require_once ( __DIR__ . '/MediaWikiUserInterfaceTestCase.php' ); -require_once ( __DIR__ . '/MediaWikiButtonsAvailabilityTestCase.php' ); -require_once ( __DIR__ . '/MediaWikiHelpFieldHintTestCase.php' ); -require_once ( __DIR__ . '/MediaWikiRightFrameworkLinksTestCase.php' ); -require_once ( __DIR__ . '/MediaWikiRestartInstallationTestCase.php' ); -require_once ( __DIR__ . '/MediaWikiErrorsConnectToDatabasePageTestCase.php' ); -require_once ( __DIR__ . '/MediaWikiErrorsNamepageTestCase.php' ); -require_once ( __DIR__ . '/MediaWikiMySQLDataBaseTestCase.php' ); -require_once ( __DIR__ . '/MediaWikiMySQLiteDataBaseTestCase.php' ); -require_once ( __DIR__ . '/MediaWikiUpgradeExistingDatabaseTestCase.php' ); -require_once ( __DIR__ . '/MediaWikiDifferntDatabasePrefixTestCase.php' ); -require_once ( __DIR__ . '/MediaWikiDifferentDatabaseAccountTestCase.php' ); -require_once ( __DIR__ . '/MediaWikiOnAlreadyInstalledTestCase.php' ); - -$suite = new PHPUnit_Framework_TestSuite( 'ArrayTest' ); -$result = new PHPUnit_Framework_TestResult; - -$suite->run( $result ); diff --git a/tests/selenium/installer/MediaWikiMySQLDataBaseTestCase.php b/tests/selenium/installer/MediaWikiMySQLDataBaseTestCase.php deleted file mode 100644 index 92f26d05..00000000 --- a/tests/selenium/installer/MediaWikiMySQLDataBaseTestCase.php +++ /dev/null @@ -1,71 +0,0 @@ -<?php -/** - * MediaWikiOnAlreadyInstalledTestCase - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' ); - -/** - * Test Case ID : 01 (http://www.mediawiki.org/wiki/New_installer/Test_plan) - * Test Case Name : Install Mediawiki using 'MySQL' database type successfully - * Version : MediaWiki 1.18alpha - */ - -class MediaWikiMySQLDataBaseTestCase extends MediaWikiInstallationCommonFunction { - function setUp() { - parent::setUp(); - } - - // Verify MediaWiki installation using 'MySQL' database type - public function testMySQLDatabaseSuccess() { - $databaseName = DB_NAME_PREFIX . "_sql_db"; - - parent::navigateConnetToDatabasePage(); - - // Verify 'MySQL" is selected as the default database type - $this->assertEquals( "MySQL settings", $this->getText( "//div[@id='DB_wrapper_mysql']/h3" ) ); - - // Change 'Database name' - $defaultDbName = $this->getText( "mysql_wgDBname" ); - $this->type( "mysql_wgDBname", " " ); - $this->type( "mysql_wgDBname", $databaseName ); - $this->assertNotEquals( $defaultDbName, $databaseName ); - - // 'Database settings' page - parent::clickContinueButton(); - - // 'Name' page - parent::clickContinueButton(); - parent::completeNamePage(); - - // 'Options page - parent::clickContinueButton(); - - // 'Install' page - parent::clickContinueButton(); - - // 'Complete' page - parent::completePageSuccessfull(); - parent::restartInstallation(); - } -} diff --git a/tests/selenium/installer/MediaWikiMySQLiteDataBaseTestCase.php b/tests/selenium/installer/MediaWikiMySQLiteDataBaseTestCase.php deleted file mode 100644 index e9be3704..00000000 --- a/tests/selenium/installer/MediaWikiMySQLiteDataBaseTestCase.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php -/** - * MediaWikiMySQLiteataBaseTestCase - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - - -require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' ); - -/** - * Test Case ID : 06 (http://www.mediawiki.org/wiki/New_installer/Test_plan) - * Test Case Name : Install Mediawiki using 'MySQL' database type successfully - * Version : MediaWiki 1.18alpha - */ - -class MediaWikiMySQLiteDataBaseTestCase extends MediaWikiInstallationCommonFunction { - function setUp() { - parent::setUp(); - } - - // Verify MediaWiki installation using 'MySQL' database type - public function testMySQLDatabaseSuccess() { - $databaseName = DB_NAME_PREFIX . "_sqlite_db"; - - parent::navigateConnetToDatabasePage(); - $this->click( "DBType_sqlite" ); - - // Select 'SQLite' database type - $this->assertEquals( "SQLite settings", $this->getText( "//div[@id='DB_wrapper_sqlite']/h3" ) ); - - // Change database name - $defaultDbName = $this->getText( "sqlite_wgDBname" ); - $this->type( "sqlite_wgDBname", " " ); - $this->type( "sqlite_wgDBname", $databaseName ); - $this->assertNotEquals( $defaultDbName, $databaseName ); - - // 'Database settings' page - parent::clickContinueButton(); - - // 'Name' page - parent::clickContinueButton(); - parent::completeNamePage(); - - // 'Options page - parent::clickContinueButton(); - - // 'Install' page - parent::clickContinueButton(); - - // 'Complete' page - parent::completePageSuccessfull(); - parent::restartInstallation(); - } -} diff --git a/tests/selenium/installer/MediaWikiOnAlreadyInstalledTestCase.php b/tests/selenium/installer/MediaWikiOnAlreadyInstalledTestCase.php deleted file mode 100644 index ce27500b..00000000 --- a/tests/selenium/installer/MediaWikiOnAlreadyInstalledTestCase.php +++ /dev/null @@ -1,65 +0,0 @@ -<?php -/** - * Selenium server manager - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - - -require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' ); - - -/** - * Test Case ID : 03 (http://www.mediawiki.org/wiki/New_installer/Test_plan) - * Test Case Name : Install mediawiki on a already installed Mediawiki.] - * Version : MediaWiki 1.18alpha - */ - -class MediaWikiOnAlreadyInstalledTestCase extends MediaWikiInstallationCommonFunction { - function setUp() { - parent::setUp(); - } - - // Install Mediawiki using 'MySQL' database type. - public function testInstallOnAlreadyInstalled() { - $databaseName = DB_NAME_PREFIX . "_already_installed"; - parent::navigateInstallPage( $databaseName ); - - // 'Options' page - parent::clickBackButton(); - - // Install page - parent::clickContinueButton(); - - // 'Install' page should display after the 'Option' page - $this->assertEquals( "Install", $this->getText( LINK_DIV . "h2" ) ); - - // Verify warning text displayed - $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.", - $this->getText( LINK_FORM . "div[1]/div[2]" ) ); - - // Complete page - parent::clickContinueButton(); - parent::completePageSuccessfull(); - $this->chooseCancelOnNextConfirmation(); - parent::restartInstallation(); - } -} diff --git a/tests/selenium/installer/MediaWikiRestartInstallationTestCase.php b/tests/selenium/installer/MediaWikiRestartInstallationTestCase.php deleted file mode 100644 index f34210cb..00000000 --- a/tests/selenium/installer/MediaWikiRestartInstallationTestCase.php +++ /dev/null @@ -1,104 +0,0 @@ -<?php -/** - * MediaWikiRestartInstallationTestCase - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' ); - -/** - * Test Case ID : 11, 12 (http://www.mediawiki.org/wiki/New_installer/Test_plan) - * Test Case Name : Install mediawiki on a already installed Mediawiki. - * Version : MediaWiki 1.18alpha - */ -class MediaWikiRestartInstallationTestCase extends MediaWikiInstallationCommonFunction { - function setUp() { - parent::setUp(); - } - - // Verify restarting the installation - public function testSuccessRestartInstallation() { - $dbNameBeforeRestart = DB_NAME_PREFIX . "_db_before"; - parent::navigateDatabaseSettingsPage( $dbNameBeforeRestart ); - - // Verify 'Restart installation' link available - $this->assertTrue( $this->isElementPresent( "link=Restart installation" ) ); - - // Click 'Restart installation' - $this->click( "link=Restart installation " ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // 'Restart Installation' page displayed - $this->assertEquals( "Restart installation", $this->getText( LINK_DIV . "h2" ) ); - - // Restart warning message displayed - $this->assertTrue( $this->isTextPresent( "exact:Do you want to clear all saved data that you have entered and restart the installation process?" ) ); - - // Click on the 'Yes, restart' button - $this->click( "submit-restart" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // Navigate to the initial installation page(Language). - $this->assertEquals( "Language", $this->getText( LINK_DIV . "h2" ) ); - - // 'Welcome to MediaWiki!' page - parent::clickContinueButton(); - - // 'Connect to database' page - parent::clickContinueButton(); - - // saved data should be deleted - $dbNameAfterRestart = $this->getValue( "mysql_wgDBname" ); - $this->assertNotEquals( $dbNameBeforeRestart, $dbNameAfterRestart ); - } - - // Verify cancelling restart - public function testCancelRestartInstallation() { - $dbNameBeforeRestart = DB_NAME_PREFIX . "_cancel_restart"; - - parent::navigateDatabaseSettingsPage( $dbNameBeforeRestart ); - // Verify 'Restart installation' link available - $this->assertTrue( $this->isElementPresent( "link=Restart installation" ) ); - - $this->click( "link=Restart installation" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // 'Restart Installation' page displayed - $this->assertEquals( "Restart installation", $this->getText( LINK_DIV . "h2" ) ); - - // Restart warning message displayed - $this->assertTrue( $this->isTextPresent( "Do you want to clear all saved data that you have entered and restart the installation process?" ) ); - - // Click on the 'Back' button - parent::clickBackButton(); - - // Navigates to the previous page - $this->assertEquals( "Database settings", $this->getText( LINK_DIV . "h2" ) ); - - // 'Connect to database' page - parent::clickBackButton(); - - // Saved data remain on the page. - $dbNameAfterRestart = $this->getValue( "mysql_wgDBname" ); - $this->assertEquals( $dbNameBeforeRestart, $dbNameAfterRestart ); - } -} diff --git a/tests/selenium/installer/MediaWikiRightFrameworkLinksTestCase.php b/tests/selenium/installer/MediaWikiRightFrameworkLinksTestCase.php deleted file mode 100644 index 039d71a4..00000000 --- a/tests/selenium/installer/MediaWikiRightFrameworkLinksTestCase.php +++ /dev/null @@ -1,83 +0,0 @@ -<?php -/** - * MediaWikiRightFrameworkLinksTestCase - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' ); - -/** - * Test Case ID : 14, 15, 16, 17 (http://www.mediawiki.org/wiki/New_installer/Test_plan) - * Test Case Name : User selects 'Read me' link. - * User selects 'Release notes' link. - * User selects 'Copying' link. - * User selects 'Upgrading' link. - * Version : MediaWiki 1.18alpha - */ -class MediaWikiRightFrameworkLinksTestCase extends MediaWikiInstallationCommonFunction { - function setUp() { - parent::setUp(); - } - - public function testLinksAvailability() { - $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" ); - - // Verify 'Read me' link availability - $this->assertTrue( $this->isElementPresent( "link=Read me" ) ); - - // Verify 'Release notes' link availability - $this->assertTrue( $this->isElementPresent( "link=Release notes" ) ); - - // Verify 'Copying' link availability - $this->assertTrue( $this->isElementPresent( "link=Copying" ) ); - } - - public function testPageNavigation() { - $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" ); - - // Navigate to the 'Read me' page - $this->click( "link=Read me" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - $this->assertEquals( "Read me", $this->getText( LINK_DIV . "h2[1]" ) ); - $this->assertTrue( $this->isElementPresent( "submit-back" ) ); - parent::clickBackButton(); - - // Navigate to the 'Release notes' page - $this->click( "link=Release notes" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - $this->assertEquals( "Release notes", $this->getText( LINK_DIV . "h2[1]" ) ); - $this->assertTrue( $this->isElementPresent( "submit-back" ) ); - parent::clickBackButton(); - - // Navigate to the 'Copying' page - $this->click( "link=Copying" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - $this->assertEquals( "Copying", $this->getText( LINK_DIV . "h2[1]" ) ); - $this->assertTrue( $this->isElementPresent( "submit-back" ) ); - parent::clickBackButton(); - - // Navigate to the 'Upgrading' page - $this->click( "link=Upgrading" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - $this->assertEquals( "Upgrading", $this->getText( LINK_DIV . "h2[1]" ) ); - } -} diff --git a/tests/selenium/installer/MediaWikiUpgradeExistingDatabaseTestCase.php b/tests/selenium/installer/MediaWikiUpgradeExistingDatabaseTestCase.php deleted file mode 100644 index cd901d18..00000000 --- a/tests/selenium/installer/MediaWikiUpgradeExistingDatabaseTestCase.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php -/** - * MediaWikiUpgradeExistingDatabaseTestCase - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' ); - -/** - * Test Case ID : 05 (http://www.mediawiki.org/wiki/New_installer/Test_plan) - * Test Case Name : Install Mediawiki by updating the existing database. - * Version : MediaWiki 1.18alpha - */ -class MediaWikiUpgradeExistingDatabaseTestCase extends MediaWikiInstallationCommonFunction { - function setUp() { - parent::setUp(); - } - - // Install Mediawiki using 'MySQL' database type. - public function testUpgradeExistingDatabase() { - - $databaseName = DB_NAME_PREFIX . "_upgrade_existing"; - parent::navigateInstallPage( $databaseName ); - - $this->open( "http://localhost:" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" ); - $this->assertEquals( "Install", $this->getText( LINK_DIV . "h2" ) ); - $this->assertEquals( - "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.", - $this->getText( LINK_DIV . "div[2]/form/div[1]/div[2]" ) - ); - - // 'Optionis' page - parent::clickBackButton(); - - // 'Name' page - parent::clickBackButton(); - - // 'Database settings' page - parent::clickBackButton(); - - // 'Connect to database' page - parent::clickBackButton(); - $this->type( "mysql_wgDBname", $databaseName ); - parent::clickContinueButton(); - - // 'Upgrade existing installation' page displayed next to the 'Connect to database' page. - $this->assertEquals( "Upgrade existing installation", $this->getText( LINK_DIV . "h2" ) ); - - // Warning message displayed. - $this->assertEquals( "There are MediaWiki tables in this database. To upgrade them to MediaWiki 1.18alpha, click Continue.", - $this->getText( LINK_DIV . "div[2]/form/div[1]/div[2]" ) ); - - parent::clickContinueButton(); - $this->assertEquals( "Upgrade existing installation", - $this->getText( LINK_DIV . "h2" ) ); - - // 'Upgrade complete.' text display - $this->assertEquals( "Upgrade complete.", - $this->getText( "//div[@id='bodyContent']/div/div[1]/div[4]/form/div[1]/div[2]/p[1]" ) ); - - $this->assertEquals( "You can now Folder/index.php start using your wiki.", - $this->getText( "//div[@id='bodyContent']/div/div[1]/div[4]/form/div[1]/div[2]/p[2]" ) ); - - $this->assertEquals( "Folder/index.php start using your wiki", - $this->getText( "link=Folder/index.php start using your wiki" ) ); - - $this->assertTrue( $this->isElementPresent( "submit-regenerate" ) ); - $this->click( "submit-regenerate" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - $this->assertEquals( "Database settings", - $this->getText( LINK_DIV . "h2" ) ); - - // 'Database settings' page - parent::clickContinueButton(); - - // Name page - parent::completeNamePage(); - - // Options page - parent::clickContinueButton(); - - // Install page - $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.", - $this->getText( LINK_FORM . "div[1]/div[2]" ) ); - parent::clickContinueButton(); - - // complete - parent::completePageSuccessfull(); - $this->chooseCancelOnNextConfirmation(); - parent::restartInstallation(); - } -} diff --git a/tests/selenium/installer/MediaWikiUserInterfaceTestCase.php b/tests/selenium/installer/MediaWikiUserInterfaceTestCase.php deleted file mode 100644 index 97331523..00000000 --- a/tests/selenium/installer/MediaWikiUserInterfaceTestCase.php +++ /dev/null @@ -1,494 +0,0 @@ -<?php -/** - * MediaWikiUserInterfaceTestCase - * - * @file - * @ingroup Maintenance - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' ); - -/** - * Test Case ID : 18 - 27 (http://www.mediawiki.org/wiki/New_installer/Test_plan) - * Test Case Name : UI of MediaWiki initial/ Language/ Welcome to MediaWiki!/ Connect to database/ - * Database settings/ Name/ Options/ Install/ Complete/ Restart Inslation pages - * Version : MediaWiki 1.18alpha - */ -class MediaWikiUserInterfaceTestCase extends MediaWikiInstallationCommonFunction { - function setUp() { - parent::setUp(); - } - - public function testInitialPageUI() { - - parent::navigateInitialpage(); - - // MediaWiki logo available - $this->assertTrue( $this->isElementPresent( "//img[@alt='The MediaWiki logo']" ) ); - - // 'MediaWiki 1.18alpha' text available - $this->assertEquals( "MediaWiki 1.18alpha", $this->getText( "//h1" ) ); - - // 'LocalSettings.php not found.' text available - $this->assertEquals( "LocalSettings.php not found.", $this->getText( "//p[1]" ) ); - - // 'Please set up the wiki first' text available - $this->assertEquals( "Please set up the wiki first.", $this->getText( "//p[2]" ) ); - - // 'set up the wiki' link available - $this->assertTrue( $this->isElementPresent( "link=set up the wiki" ) ); - } - - public function testlanguagePageUI() { - parent::navigateLanguagePage(); - - // Verify 'Language' heading - $this->assertEquals( "Language", $this->getText( LINK_DIV . "h2" ) ); - - // 'Your language' label available - $this->assertEquals( "Your language:", - $this->getText( LINK_FORM . "div[1]/div[1]/label" ) ); - - // 'Your language' dropdown available - $this->assertTrue( $this->isElementPresent( "UserLang" ) ); - - // 'Wiki language' label available - $this->assertEquals( "Wiki language:", - $this->getText( LINK_FORM . "div[2]/div[1]/label" ) ); - - // 'Wiki language' dropdown available - $this->assertTrue( $this->isElementPresent( "ContLang" ) ); - } - - public function testWelcometoMediaWikiUI() { - parent::navigateWelcometoMediaWikiPage(); - - // Verify 'Welcome to MediaWiki!' heading - $this->assertEquals( "Welcome to MediaWiki!", - $this->getText( LINK_DIV . "h2" ) ); - - // Verify environment ok text displayed. - $this->assertEquals( "The environment has been checked.You can install MediaWiki.", - $this->getText( LINK_DIV . "div[6]/span" ) ); - } - - public function testConnectToDatabaseUI() { - parent::navigateConnetToDatabasePage(); - - // 'MYSQL radio button available - $this->assertEquals( "MySQL", - $this->getText( LINK_FORM . "div[2]/div[2]/ul/li[1]/label" ) ); - $this->assertTrue( $this->isElementPresent( LINK_FORM . "div[2]/div[2]/ul/li[1]" ) ); - - // 'SQLite' radio button available - $this->assertTrue( $this->isElementPresent( LINK_FORM . "div[2]/div[2]/ul/li[2]" ) ); - $this->assertEquals( "SQLite", $this->getText( LINK_FORM . "div[2]/div[2]/ul/li[2]/label " ) ); - - // 'Database host' label available - $this->assertEquals( "Database host:", $this->getText( "//div[@id='DB_wrapper_mysql']/div/div[1]/label" ) ); - - // 'Database host' text box default to 'localhost' - $this->assertEquals( "localhost", $this->getValue( "mysql_wgDBserver" ) ); - - // 'Identify this wiki' section available - $this->assertTrue( $this->isElementPresent( "//div[@id='DB_wrapper_mysql']/fieldset[1]/legend" ) ); - - // 'Identify this wiki' label available - $this->assertEquals( "Identify this wiki", $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/legend" ) ); - - // 'Database name' lable available - $this->assertEquals( "Database name:", - $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/label" ) ); - - // Verify 'Database name:' text box is default to 'my_wiki' - $this->assertEquals( "my_wiki", $this->getValue( "mysql_wgDBname" ) ); - - // Verify 'Database table prefix:' label available - $this->assertEquals( "Database table prefix:", - $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[2]/div[1]/label" ) ); - - // 'User account for installation' section available - $this->assertTrue( $this->isElementPresent( "//div[@id='DB_wrapper_mysql']/fieldset[2]/legend" ) ); - - // 'User account for installation' label available - $this->assertEquals( "User account for installation", $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/legend" ) ); - - // 'Database username' label available - $this->assertEquals( "Database username:", - $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[1]/div[1]/label" ) ); - - // 'Database username' text box defaults to 'root' - $this->assertEquals( "root", $this->getValue( "mysql__InstallUser" ) ); - - // 'Database password' label available - $this->assertEquals( "Database password:", - $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[2]/div[1]/label" ) ); - } - - public function testDatabaseSettingsUI() { - $databaseName = DB_NAME_PREFIX . "_db_settings_UI"; - parent::navigateDatabaseSettingsPage( $databaseName ); - - // 'Database settings' text available. - $this->assertEquals( "Database settings", $this->getText( LINK_DIV . "h2" ) ); - - // 'Database account for web access' section available - $this->assertTrue( $this->isElementPresent( LINK_FORM . "fieldset" ) ); - - // 'Database account for web access' label available - $this->assertEquals( "Database account for web access", $this->getText( LINK_FORM . "fieldset/legend" ) ); - - // 'Use the same account as for installation' check box available - $this->assertEquals( "Use the same account as for installation", $this->getText( LINK_FORM . "fieldset/div[1]/label" ) ); - - // 'Use the same account as for installation' check box is selected by default - $this->assertEquals( "on", $this->getValue( "mysql__SameAccount" ) ); - - // 'Use the same account as for installation' check box deselected - $this->click( "mysql__SameAccount" ); - - // verify 'Use the same account as for installation' check box is not selected - $this->assertEquals( "off", $this->getValue( "mysql__SameAccount" ) ); - - // 'Database username' label available - $this->assertEquals( "Database username:", $this->getText( "//div[@id='dbOtherAccount']/div[1]/div[1]/label" ) ); - - // 'Database username' text box is default to the 'wikiuser' - $this->assertEquals( "wikiuser", $this->getValue( "mysql_wgDBuser" ) ); - - // 'Database password' label available - $this->assertEquals( "Database password:", $this->getText( "//div[@id='dbOtherAccount']/div[2]/div[1]/label" ) ); - - // 'Create the account if it does not already exist' label available - $this->assertEquals( "Create the account if it does not already exist", $this->getText( "//div[@id='dbOtherAccount']/div[4]/label" ) ); - - // 'Create the account if it does not already exist' check box is not selected by default - $this->assertEquals( "off", $this->getValue( "mysql__CreateDBAccount" ) ); - - // 'Create the account if it does not already exist' check box selected - $this->click( "mysql__CreateDBAccount" ); - - // Verify 'Create the account if it does not already exist' check box is selected - $this->assertEquals( "on", $this->getValue( "mysql__CreateDBAccount" ) ); - $this->click( "mysql__SameAccount" ); - $this->assertEquals( "on", $this->getValue( "mysql__SameAccount" ) ); - - // 'Storage engine' label available - $this->assertEquals( "Storage engine:", - $this->getText( LINK_FORM . "div[1]/div[1]/label" ) ); - - // 'InnoDB' label available - $this->assertEquals( "InnoDB", - $this->getText( LINK_FORM . "div[1]/div[2]/ul/li[1]/label" ) ); - - // 'InnoDB' radio button available - $this->assertTrue( $this->isElementPresent( "mysql__MysqlEngine_InnoDB" ) ); - - // 'MyISAM' label available - $this->assertEquals( "MyISAM", $this->getText( LINK_FORM . "div[1]/div[2]/ul/li[2]/label" ) ); - - // 'MyISAM' radio button available - $this->assertTrue( $this->isElementPresent( "mysql__MysqlEngine_MyISAM" ) ); - - // 'Database character set' label available - $this->assertEquals( "Database character set:", - $this->getText( LINK_FORM . "div[3]/div[1]/label" ) ); - - // 'Binary' radio button available - $this->assertTrue( $this->isElementPresent( "mysql__MysqlCharset_binary" ) ); - - // 'Binary' radio button available - $this->assertEquals( "Binary", $this->getText( LINK_FORM . "div[3]/div[2]/ul/li[1]/label" ) ); - - // 'UTF-8' radio button available - $this->assertTrue( $this->isElementPresent( "mysql__MysqlCharset_utf8" ) ); - - // 'UTF-8' label available - $this->assertEquals( "UTF-8", $this->getText( LINK_FORM . "div[3]/div[2]/ul/li[2]/label" ) ); - - // 'Binary' radio button is selected - $this->assertEquals( "on", $this->getValue( "mysql__MysqlCharset_binary" ) ); - } - - public function testNamePageUI() { - $databaseName = DB_NAME_PREFIX . "_name_UI"; - parent::navigateNamePage( $databaseName ); - - // 'Name of wiki' text box available - $this->assertEquals( "Name of wiki:", - $this->getText( LINK_FORM . "div[1]/div[1]/label" ) ); - - $this->assertTrue( $this->isElementPresent( "config_wgSitename" ) ); - - // 'Project namespace' label available - $this->assertEquals( "Project namespace:", - $this->getText( LINK_FORM . "div[2]/div[1]/label" ) ); - - // 'Same as the wiki name' radio button available - $this->assertTrue( $this->isElementPresent( "config__NamespaceType_site-name" ) ); - - // 'Project' radio button available - $this->assertTrue( $this->isElementPresent( "config__NamespaceType_generic" ) ); - - // 'Project' radio button available - $this->assertTrue( $this->isElementPresent( "config__NamespaceType_other" ) ); - - // 'Same as the wiki name' label available - $this->assertEquals( "Same as the wiki name:", - $this->getText( LINK_FORM . "div[2]/div[2]/ul/li[1]/label" ) ); - - // 'Project' label available - $this->assertEquals( "Project", - $this->getText( LINK_FORM . "div[2]/div[2]/ul/li[2]/label" ) ); - - // 'Project' label available - $this->assertEquals( "Other (specify)", - $this->getText( LINK_FORM . "div[2]/div[2]/ul/li[3]/label" ) ); - - // 'Same as the wiki name' radio button selected by default - $this->assertEquals( "on", $this->getValue( "config__NamespaceType_site-name" ) ); - - // 'Administrator account' section available - $this->assertTrue( $this->isElementPresent( LINK_FORM . "fieldset" ) ); - - // 'Administrator account' label available - $this->assertEquals( "Administrator account", - $this->getText( LINK_FORM . "fieldset/legend" ) ); - - // 'Your Name' label available - $this->assertEquals( "Your name:", - $this->getText( LINK_FORM . "fieldset/div[1]/div[1]/label" ) ); - - // 'Your Name' text box available - $this->assertTrue( $this->isElementPresent( "config__AdminName" ) ); - - // 'Password' label available - $this->assertEquals( "Password:", - $this->getText( LINK_FORM . "fieldset/div[2]/div[1]/label" ) ); - - // 'Password' text box available - $this->assertTrue( $this->isElementPresent( "config__AdminPassword" ) ); - - // 'Password again' label available - $this->assertEquals( "Password again:", - $this->getText( LINK_FORM . "fieldset/div[3]/div[1]/label" ) ); - - // 'Password again' text box available - $this->assertTrue( $this->isElementPresent( "config__AdminPassword2" ) ); - - // 'Email address' label avaialble - $this->assertEquals( "E-mail address:", - $this->getText( LINK_FORM . "fieldset/div[4]/div[1]/label" ) ); - - // 'Email address' text box available - $this->assertTrue( $this->isElementPresent( "config__AdminEmail" ) ); - - // Message displayed - $this->assertEquals( "You are almost done! You can now skip the remaining configuration and install the wiki right now.", - $this->getText( LINK_FORM . "/div[4]/div[2]/p" ) ); - - // 'Ask me more questions.' radio button available - $this->assertTrue( $this->isElementPresent( "config__SkipOptional_continue" ) ); - - // 'Ask me more questions.' label available - $this->assertEquals( "Ask me more questions.", - $this->getText( LINK_FORM . "div[5]/div[2]/ul/li[1]/label" ) ); - - // 'I'm bored already, just install the wiki' radio button is avaiable - $this->assertTrue( $this->isElementPresent( "config__SkipOptional_skip" ) ); - - // 'I'm bored already, just install the wiki' label available - $this->assertEquals( "I'm bored already, just install the wiki.", - $this->getText( LINK_FORM . "div[5]/div[2]/ul/li[2]/label" ) ); - - // 'Ask me more questions.' radio button is default selected - $this->assertEquals( "on", $this->getValue( "config__SkipOptional_continue" ) ); - } - - public function testOptionPageUI() { - $databaseName = DB_NAME_PREFIX . "_options_UI"; - parent::navigateOptionsPage( $databaseName ); - - // 'Options' label available - $this->assertEquals( "Options", $this->getText( LINK_DIV . "h2" ) ); - - // 'Return e-mail address' label available - $this->assertEquals( "Return e-mail address:", $this->getText( "//div[@id='emailwrapper']/div[1]/div[1]/label" ) ); - - // 'Return e-mail address' text box available - $this->assertTrue( $this->isElementPresent( "config_wgPasswordSender" ) ); - - // Text 'apache@localhost' is default value of the 'Return e-mail address' text box - $this->assertEquals( "apache@localhost", $this->getValue( "config_wgPasswordSender" ) ); - - // 'Logo URL' label available - $this->assertEquals( "Logo URL:", $this->getText( LINK_FORM . "fieldset[2]/div[3]/div[1]/label" ) ); - - // 'Logo URL' text box available - $this->assertTrue( $this->isElementPresent( "config_wgLogo" ) ); - - // Correct path available in the 'Logo URL' text box - $this->assertEquals( "/wiki/skins/common/images/wiki.png", $this->getValue( "config_wgLogo" ) ); - - // 'Enable file uploads' radio button available - $this->assertTrue( $this->isElementPresent( "config_wgEnableUploads" ) ); - - // 'Enable file uploads' label available - $this->assertEquals( "Enable file uploads", - $this->getText( LINK_FORM . "fieldset[2]/div[1]/label" ) ); - - // 'Enable file uploads' check box is not selected - $this->assertEquals( "off", $this->getValue( "config_wgEnableUploads" ) ); - - $this->click( "config_wgEnableUploads" ); - - // 'Directory for deleted files' label available - $this->assertEquals( "Directory for deleted files:", - $this->getText( "//div[@id='uploadwrapper']/div/div[1]/label" ) ); - - // 'Directory for deleted files' text box available - $this->assertTrue( $this->isElementPresent( "config_wgDeletedDirectory" ) ); - - // Correct path available in the 'Directory for deleted files' text box - $this->assertEquals( "C:\\wamp\\www\\" . DIRECTORY_NAME . "/images/deleted", - $this->getValue( "config_wgDeletedDirectory" ) ); - } - - public function testInstallPageUI() { - $databaseName = DB_NAME_PREFIX . "_install_UI"; - parent::navigateInstallPage( $databaseName ); - - // Verify installation done messages display - $this->assertEquals( "Setting up database... done", - $this->getText( LINK_FORM . "ul/li[1]" ) ); - $this->assertEquals( "Creating tables... done", - $this->getText( LINK_FORM . "ul/li[2]" ) ); - $this->assertEquals( "Creating database user... done", - $this->getText( LINK_FORM . "ul/li[3]" ) ); - $this->assertEquals( "Populating default interwiki table... done", - $this->getText( LINK_FORM . "ul/li[4]" ) ); - $this->assertEquals( "Generating secret key... done", - $this->getText( LINK_FORM . "ul/li[5]" ) ); - $this->assertEquals( "Generating default upgrade key... done", - $this->getText( LINK_FORM . "ul/li[6]" ) ); - $this->assertEquals( "Creating administrator user account... done", - $this->getText( LINK_FORM . "ul/li[7]" ) ); - $this->assertEquals( "Creating main page with default content... done", - $this->getText( LINK_FORM . "ul/li[8]" ) ); - } - - public function testCompletePageUI() { - $databaseName = DB_NAME_PREFIX . "_complete_UI"; - parent::navigateCompletePage( $databaseName ); - - // 'Congratulations!' text display - $this->assertEquals( "Congratulations!", - $this->getText( LINK_FORM . "div[1]/div[2]/p[1]/b" ) ); - // 'LocalSettings.php' generated message display - $this->assertEquals( "The installer has generated a LocalSettings.php file. It contains all your configuration.", - $this->getText( LINK_FORM . "div[1]/div[2]/p[2]" ) ); - - // 'Download LocalSettings.php'' link available - $this->assertTrue( $this->isElementPresent( "link=Download LocalSettings.php" ) ); - - // 'enter your wiki' link available - $this->assertTrue( $this->isElementPresent( "link=Folder/index.php enter your wiki" ) ); - } - - public function testRestartInstallation() { - parent::navigateConnetToDatabasePage(); - $this->click( "link=Restart installation" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // Restart installation' label should be available. - $this->assertEquals( "Restart installation", $this->getText( LINK_DIV . "h2" ) ); - - //'Do you want to clear all saved data that you have entered and restart the installation process?' label available - $this->assertEquals( "Do you want to clear all saved data that you have entered and restart the installation process?", - $this->getText( "//*[@id='bodyContent']/div/div/div[2]/form/div[1]/div[2]" ) ); - // 'Back' button available - $this->assertTrue( $this->isElementPresent( "submit-back" ) ); - - // 'Restart' button available - $this->assertTrue( $this->isElementPresent( "submit-restart" ) ); - } - - public function testMediaWikiLogoAvailability() { - $databaseName = DB_NAME_PREFIX . "_mediawiki_logo"; - parent::navigateInitialpage(); - parent::mediaWikiLogoPresentInitialScreen(); - $this->click( "link=set up the wiki" ); - $this->waitForPageToLoad( PAGE_LOAD_TIME ); - - // 'Language' page - parent::mediaWikiLogoPresent(); - parent::clickContinueButton(); - - // 'Welcome to MediaWiki' page - parent::mediaWikiLogoPresent(); - parent::clickContinueButton(); - - // 'Connet to database' page - parent::mediaWikiLogoPresent(); - $this->type( "mysql_wgDBname", $databaseName ); - parent::clickContinueButton(); - - // 'Database setting' page - parent::mediaWikiLogoPresent(); - parent::clickContinueButton(); - - // 'Name' page - parent::mediaWikiLogoPresent(); - parent::completeNamePage(); - parent::clickContinueButton(); - - // 'Options' page - parent::mediaWikiLogoPresent(); - parent::clickContinueButton(); - - // 'Install' page - parent::mediaWikiLogoPresent(); - } - - public function testRightFramework() { - parent::navigateLanguagePage(); - // Verfy right framework texts display - $this->assertEquals( "Language", - $this->getText( LINK_RIGHT_FRAMEWORK . "li[1]" ) ); - $this->assertEquals( "Existing wiki", - $this->getText( LINK_RIGHT_FRAMEWORK . "li[2]" ) ); - $this->assertEquals( "Welcome to MediaWiki!", - $this->getText( LINK_RIGHT_FRAMEWORK . "li[3]" ) ); - $this->assertEquals( "Connect to database", - $this->getText( LINK_RIGHT_FRAMEWORK . "li[4]" ) ); - $this->assertEquals( "Upgrade existing installation", - $this->getText( LINK_RIGHT_FRAMEWORK . "li[5]" ) ); - $this->assertEquals( "Database settings", - $this->getText( LINK_RIGHT_FRAMEWORK . "li[6]" ) ); - $this->assertEquals( "Name", - $this->getText( LINK_RIGHT_FRAMEWORK . "li[7]" ) ); - $this->assertEquals( "Options", - $this->getText( LINK_RIGHT_FRAMEWORK . "li[8]" ) ); - $this->assertEquals( "Install", - $this->getText( LINK_RIGHT_FRAMEWORK . "li[9]" ) ); - $this->assertEquals( "Complete!", - $this->getText( LINK_RIGHT_FRAMEWORK . "li[10]/span" ) ); - } -} diff --git a/tests/selenium/installer/README.txt b/tests/selenium/installer/README.txt deleted file mode 100644 index bc880a8b..00000000 --- a/tests/selenium/installer/README.txt +++ /dev/null @@ -1,32 +0,0 @@ -== Details== - -Automated Selenium test scripts written for MediaWiki Installer is available at https://gerrit.wikimedia.org/r/gitweb?p=mediawiki/core.git;a=tree;f=tests/selenium/installer;hb=HEAD. -Detailed test cases available at http://www.mediawiki.org/wiki/New_installer/Test_plan. - -Version : MediaWiki 1.18alpha -Date : 27/12/2010 - -== Running tests == - -Test cases can be run independently or can run all the test cases using MediaWikiInstallerTestSuite.php within PHPUnit/Selenium. - - -== Dependencies == - -MediaWikiInstallationConfig.php - -Value of the 'DB_NAME_PREFIX' should be replace with the database name prefix. Several DB instances will get created to cover different installation scenarios starting with the above prefix. -You need to change the value of the 'DB_NAME_PREFIX' in MediaWikiInstallationConfig everytime you planned to -run the tests. -'DIRECTORY_NAME', 'PORT' and the 'HOST_NAME' should be replaced with your local values. -You may specify the test browser you wish to run the test using 'TEST_BROWSER'. Default browser is Firefox. - -Note : MediaWikiInstallerTestSuite.php has no dependency on 'Selenium' test framework. - - -== Known problems == - -If you run the MediaWikiInstallerTestSuite.php twice without changing the name of the database, the second run should be falied. -(Please read the more information on how to change the database name which is avaialable under 'Dependencies' section) - - diff --git a/tests/selenium/selenium_settings.ini.sample b/tests/selenium/selenium_settings.ini.sample deleted file mode 100644 index b1d88193..00000000 --- a/tests/selenium/selenium_settings.ini.sample +++ /dev/null @@ -1,32 +0,0 @@ -[SeleniumSettings] - -; Set up the available browsers that Selenium can control. -browsers[firefox] = "*firefox" -browsers[iexplorer] = "*iexploreproxy" -browsers[chrome] = "*chrome" - -; The simple configurations above usually work on Linux, but Windows and -; Mac OS X hosts may need to specify a full path: -;browsers[firefox] = "*firefox /Applications/Firefox.app/Contents/MacOS/firefox-bin" -;browsers[firefox] = "*firefox C:\Program Files\Mozilla Firefox\firefox.exe" - -host = "localhost" -port = "4444" -wikiUrl = "http://localhost/deployment" -username = "wikiuser" -userPassword = "wikipass" -testBrowser = "firefox" -startserver = -stopserver = -jUnitLogFile = -runAgainstGrid = false - -; To let the test runner start and stop the selenium server, it needs the full -; path to selenium-server.jar from the selenium-remote-control package. -seleniumserverexecpath = "/opt/local/selenium-remote-control-1.0.3/selenium-server-1.0.3/selenium-server.jar" - -[SeleniumTests] - -testSuite[SimpleSeleniumTestSuite] = "tests/selenium/suites/SimpleSeleniumTestSuite.php" -testSuite[WikiEditorTestSuite] = "extensions/WikiEditor/selenium/WikiEditorTestSuite.php" - diff --git a/tests/selenium/selenium_settings_grid.ini.sample b/tests/selenium/selenium_settings_grid.ini.sample deleted file mode 100644 index 3bbd534a..00000000 --- a/tests/selenium/selenium_settings_grid.ini.sample +++ /dev/null @@ -1,16 +0,0 @@ -[SeleniumSettings] - -host = "grid.tesla.usability.wikimedia.org" -port = "4444" -wikiUrl = "http://208.80.152.253:5001" -username = "wikiuser" -userPassword = "wikipass" -testBrowser = "Safari on OS X Snow Leopard" -jUnitLogFile = -runAgainstGrid = true -startserver = false -stopserver = false - -[SeleniumTests] - -testSuite[SimpleSeleniumTestSuite] = "tests/selenium/suites/SimpleSeleniumTestSuite.php" diff --git a/tests/selenium/suites/AddContentToNewPageTestCase.php b/tests/selenium/suites/AddContentToNewPageTestCase.php deleted file mode 100644 index 2803ff2a..00000000 --- a/tests/selenium/suites/AddContentToNewPageTestCase.php +++ /dev/null @@ -1,173 +0,0 @@ -<?php -/** - * Selenium server manager - * - * @file - * @ingroup Testing - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -class AddContentToNewPageTestCase extends SeleniumTestCase { - // Add bold text and verify output - public function testAddBoldText() { - $this->getExistingPage(); - $this->clickEditLink(); - $this->loadWikiEditor(); - $this->clearWikiEditor(); - $this->click( "//*[@id='mw-editbutton-bold']" ); - $this->clickShowPreviewBtn(); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify bold text displayed on mediawiki preview - $this->assertTrue( $this->isElementPresent( "//div[@id='wikiPreview']/p/b" ) ); - $this->assertTrue( $this->isTextPresent( "Bold text" ) ); - } - - // Add italic text and verify output - public function testAddItalicText() { - $this->getExistingPage(); - $this->clickEditLink(); - $this->loadWikiEditor(); - $this->clearWikiEditor(); - $this->click( "//*[@id='mw-editbutton-italic']" ); - $this->clickShowPreviewBtn(); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify italic text displayed on mediawiki preview - $this->assertTrue( $this->isElementPresent( "//div[@id='wikiPreview']/p/i" ) ); - $this->assertTrue( $this->isTextPresent( "Italic text" ) ); - } - - // Add internal link for a new page and verify output in the preview - public function testAddInternalLinkNewPage() { - $this->getExistingPage(); - $this->clickEditLink(); - $this->loadWikiEditor(); - $this->clearWikiEditor(); - $this->click( "//*[@id='mw-editbutton-link']" ); - $this->clickShowPreviewBtn(); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify internal link displayed on mediawiki preview - $source = $this->getText( "//*[@id='wikiPreview']/p/a" ); - $correct = strstr( $source, "Link title" ); - $this->assertEquals( $correct, true ); - - $this->click( SeleniumTestConstants::LINK_START . "Link title" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify internal link open as a new page - editing mode - $source = $this->getText( "firstHeading" ); - $correct = strstr( $source, "Editing Link title" ); - $this->assertEquals( $correct, true ); - } - - // Add external link and verify output in the preview - public function testAddExternalLink() { - $this->getExistingPage(); - $this->clickEditLink(); - $this->loadWikiEditor(); - $this->clearWikiEditor(); - $this->click( "//*[@id='mw-editbutton-extlink']" ); - $this->type( SeleniumTestConstants::TEXT_EDITOR, "[http://www.google.com Google]" ); - $this->clickShowPreviewBtn(); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify external links displayed on mediawiki preview - $source = $this->getText( "//*[@id='wikiPreview']/p/a" ); - $correct = strstr( $source, "Google" ); - $this->assertEquals( $correct, true ); - - $this->click( SeleniumTestConstants::LINK_START . "Google" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify external link opens - $source = $this->getTitle(); - $correct = strstr( $source, "Google" ); - $this->assertEquals( $correct, true ); - } - - // Add level 2 headline and verify output in the preview - public function testAddLevel2HeadLine() { - $blnElementPresent = false; - $blnTextPresent = false; - $this->getExistingPage(); - $this->clickEditLink(); - $this->loadWikiEditor(); - $this->clearWikiEditor(); - $this->click( "mw-editbutton-headline" ); - $this->clickShowPreviewBtn(); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->assertTrue( $this->isElementPresent( "//div[@id='wikiPreview']/h2" ) ); - - // Verify level 2 headline displayed on mediawiki preview - $source = $this->getText( "//*[@id='Headline_text']" ); - $correct = strstr( $source, "Headline text" ); - $this->assertEquals( $correct, true ); - } - - // Add text with ignore wiki format and verify output the preview - public function testAddNoWikiFormat() { - $this->getExistingPage(); - $this->clickEditLink(); - $this->loadWikiEditor(); - $this->clearWikiEditor(); - $this->click( "//*[@id='mw-editbutton-nowiki']" ); - $this->clickShowPreviewBtn(); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify ignore wiki format text displayed on mediawiki preview - $source = $this->getText( "//div[@id='wikiPreview']/p" ); - $correct = strstr( $source, "Insert non-formatted text here" ); - $this->assertEquals( $correct, true ); - } - - // Add signature and verify output in the preview - public function testAddUserSignature() { - $this->getExistingPage(); - $this->clickEditLink(); - $this->loadWikiEditor(); - $this->clearWikiEditor(); - $this->click( "mw-editbutton-signature" ); - $this->clickShowPreviewBtn(); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify signature displayed on mediawiki preview - $source = $this->getText( "//*[@id='wikiPreview']/p/a" ); - $username = $this->getText( "//*[@id='pt-userpage']/a" ); - $correct = strstr( $source, $username ); - $this->assertEquals( $correct, true ); - } - - // Add horizontal line and verify output in the preview - public function testHorizontalLine() { - $this->getExistingPage(); - $this->clickEditLink(); - $this->loadWikiEditor(); - $this->clearWikiEditor(); - $this->click( "mw-editbutton-hr" ); - - $this->clickShowPreviewBtn(); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify horizontal line displayed on mediawiki preview - $this->assertTrue( $this->isElementPresent( "//div[@id='wikiPreview']/hr" ) ); - $this->deletePage( "new" ); - } -} diff --git a/tests/selenium/suites/AddNewPageTestCase.php b/tests/selenium/suites/AddNewPageTestCase.php deleted file mode 100644 index c70af339..00000000 --- a/tests/selenium/suites/AddNewPageTestCase.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php -/** - * Selenium server manager - * - * @file - * @ingroup Testing - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -class AddNewPageTestCase extends SeleniumTestCase { - // Verify adding a new page - public function testAddNewPage() { - $newPage = "new"; - $displayName = "New"; - $this->open( $this->getUrl() . - '/index.php?title=Main_Page&action=edit' ); - $this->type( "searchInput", $newPage ); - $this->click( "searchGoButton" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify 'Search results' text available - $source = $this->gettext( "firstHeading" ); - $correct = strstr( $source, "Search results" ); - $this->assertEquals( $correct, true ); - - // Verify 'Create the page "<page name>" on this wiki' text available - $source = $this->gettext( "//div[@id='bodyContent']/div[4]/p/b" ); - $correct = strstr( $source, "Create the page \"New\" on this wiki!" ); - $this->assertEquals( $correct, true ); - - $this->click( SeleniumTestConstants::LINK_START . $displayName ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->assertTrue( $this->isElementPresent( SeleniumTestConstants::LINK_START . "Create" ) ); - $this->type( "wpTextbox1", "add new test page" ); - $this->click( SeleniumTestConstants::BUTTON_SAVE ); - - // Verify new page added - $source = $this->gettext( "firstHeading" ); - $correct = strstr( $source, $displayName ); - $this->assertEquals( $correct, true ); - } -} diff --git a/tests/selenium/suites/CreateAccountTestCase.php b/tests/selenium/suites/CreateAccountTestCase.php deleted file mode 100644 index a603f995..00000000 --- a/tests/selenium/suites/CreateAccountTestCase.php +++ /dev/null @@ -1,109 +0,0 @@ -<?php -/** - * Selenium server manager - * - * @file - * @ingroup Testing - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -Class CreateAccountTestCase extends SeleniumTestCase { - // Change these values before run the test - private $userName = "yourname4000"; - private $password = "yourpass4000"; - - // Verify 'Log in/create account' link existance in Main page. - public function testMainPageLink() { - - $this->click( "link=Log out" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->open( $this->getUrl() . '/index.php?title=Main_Page' ); - $this->assertTrue( $this->isElementPresent( "link=Log in / create account" ) ); - } - - // Verify 'Create an account' link existance in 'Log in / create account' Page. - public function testCreateAccountPageLink() { - - $this->click( "link=Log out" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->open( $this->getUrl() . '/index.php?title=Main_Page' ); - - // click Log in / create account link to open Log in / create account' page - $this->click( "link=Log in / create account" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->assertTrue( $this->isElementPresent( "link=Create an account" ) ); - } - - // Verify Create account - public function testCreateAccount() { - - $this->click( "link=Log out" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->open( $this->getUrl() . '/index.php?title=Main_Page' ); - - $this->click( "link=Log in / create account" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->click( "link=Create an account" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify for blank user name - $this->type( "wpName2", "" ); - $this->click( "wpCreateaccount" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->assertEquals( "Login error\n You have not specified a valid user name.", - $this->getText( "//div[@id='bodyContent']/div[4]" ) ); - - // Verify for invalid user name - $this->type( "wpName2", "@" ); - $this->click( "wpCreateaccount" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->assertEquals( "Login error\n You have not specified a valid user name.", - $this->getText( "//div[@id='bodyContent']/div[4]" ) ); - - // start of test for blank password - $this->type( "wpName2", $this->userName ); - $this->type( "wpPassword2", "" ); - $this->click( "wpCreateaccount" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->assertEquals( "Login error\n Passwords must be at least 1 character.", - $this->getText( "//div[@id='bodyContent']/div[4]" ) ); - - $this->type( "wpName2", $this->userName ); - $this->type( "wpPassword2", $this->password ); - $this->click( "wpCreateaccount" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->assertEquals( "Login error\n The passwords you entered do not match.", - $this->getText( "//div[@id='bodyContent']/div[4]" ) ); - - $this->type( "wpName2", $this->userName ); - $this->type( "wpPassword2", $this->password ); - $this->type( "wpRetype", $this->password ); - $this->click( "wpCreateaccount" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify successful account creation for valid combination of 'Username', 'Password', 'Retype password' - $this->assertEquals( "Welcome, " . ucfirst( $this->userName ) . "!", - $this->getText( "Welcome,_" . ucfirst( $this->userName ) . "!" ) ); - } -} - diff --git a/tests/selenium/suites/DeletePageAdminTestCase.php b/tests/selenium/suites/DeletePageAdminTestCase.php deleted file mode 100644 index f0005cde..00000000 --- a/tests/selenium/suites/DeletePageAdminTestCase.php +++ /dev/null @@ -1,82 +0,0 @@ -<?php -/** - * Selenium server manager - * - * @file - * @ingroup Testing - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -class DeletePageAdminTestCase extends SeleniumTestCase { - // Verify adding a new page - public function testDeletePage() { - - $newPage = "new"; - $displayName = "New"; - - $this->open( $this->getUrl() . '/index.php?title=Main_Page' ); - - $this->type( "searchInput", $newPage ); - $this->click( "searchGoButton" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->click( SeleniumTestConstants::LINK_START . $displayName ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->type( SeleniumTestConstants::TEXT_EDITOR, $newPage . " text" ); - $this->click( SeleniumTestConstants::BUTTON_SAVE ); - - $this->open( $this->getUrl() . - '/index.php?title=Main_Page&action=edit' ); - $this->click( SeleniumTestConstants::LINK_START . "Log out" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->click( SeleniumTestConstants::LINK_START . "Log in / create account" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->type( "wpName1", $this->selenium->getUser() ); - $this->type( "wpPassword1", $this->selenium->getPass() ); - $this->click( "wpLoginAttempt" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->type( "searchInput", "new" ); - $this->click( "searchGoButton" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify 'Delete' link displayed - $source = $this->gettext( SeleniumTestConstants::LINK_START . "Delete" ); - $correct = strstr( $source, "Delete" ); - $this->assertEquals( $correct, true ); - - $this->click( SeleniumTestConstants::LINK_START . "Delete" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify 'Delete' button available - $this->assertTrue( $this->isElementPresent( "wpConfirmB" ) ); - - $this->click( "wpConfirmB" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify 'Action complete' text displayed - $source = $this->gettext( "firstHeading" ); - $correct = strstr( $source, "Action complete" ); - $this->assertEquals( $correct, true ); - - // Verify '<Page Name> has been deleted. See deletion log for a record of recent deletions.' text displayed - $source = $this->gettext( "//div[@id='bodyContent']/p[1]" ); - $correct = strstr( $source, "\"New\" has been deleted. See deletion log for a record of recent deletions." ); - $this->assertEquals( $correct, true ); - } -} diff --git a/tests/selenium/suites/EmailPasswordTestCase.php b/tests/selenium/suites/EmailPasswordTestCase.php deleted file mode 100644 index 77282e47..00000000 --- a/tests/selenium/suites/EmailPasswordTestCase.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php -/** - * Selenium server manager - * - * @file - * @ingroup Testing - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -class EmailPasswordTestCase extends SeleniumTestCase { - // change user name for each and every test (with in 24 hours) - private $userName = "test1"; - - public function testEmailPasswordButton() { - $this->click( SeleniumTestConstants::LINK_START . "Log out" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->open( $this->getUrl() . '/index.php?title=Main_Page' ); - - // click Log in / create account link to open Log in / create account' page - $this->click( SeleniumTestConstants::LINK_START . "Log in / create account" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->assertTrue( $this->isElementPresent( "wpMailmypassword" ) ); - } - - // Verify Email password functionality - public function testEmailPasswordMessages() { - $this->click( SeleniumTestConstants::LINK_START . "Log out" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->open( $this->getUrl() . '/index.php?title=Main_Page' ); - - // click Log in / create account link to open Log in / create account' page - $this->click( SeleniumTestConstants::LINK_START . "Log in / create account" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->type( "wpName1", "" ); - $this->click( "wpMailmypassword" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->assertEquals( "Login error\n You have not specified a valid user name.", - $this->getText( "//div[@id='bodyContent']/div[4]" ) ); - - $this->type( "wpName1", $this->userName ); - $this->click( "wpMailmypassword" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Can not run on localhost - $this->assertEquals( "A new password has been sent to the e-mail address registered for " . ucfirst( $this->userName ) . ". Please log in again after you receive it.", - $this->getText( "//div[@id='bodyContent']/div[4]" ) ); - - $this->type( "wpName1", $this->userName ); - $this->click( "wpMailmypassword" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->assertEquals( "Login error\n A password reminder has already been sent, within the last 24 hours. To prevent abuse, only one password reminder will be sent per 24 hours.", - $this->getText( "//div[@id='bodyContent']/div[4]" ) ); - } -} - diff --git a/tests/selenium/suites/MediaWikiEditorConfig.php b/tests/selenium/suites/MediaWikiEditorConfig.php deleted file mode 100644 index 7fd8e075..00000000 --- a/tests/selenium/suites/MediaWikiEditorConfig.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php -/** - * Selenium server manager - * - * @file - * @ingroup Testing - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -class MediaWikiEditorConfig { - public static function getSettings( &$includeFiles, &$globalConfigs ) { - $includes = array( - //files that needed to be included would go here - //commenting out because this does not exist - //'tests/selenium/suites/MediaWikiCommonFunction.php' - ); - $configs = array( - 'wgPageLoadTime' => "600000" - ); - $includeFiles = array_merge( $includeFiles, $includes ); - $globalConfigs = array_merge( $globalConfigs, $configs ); - return true; - } -} - diff --git a/tests/selenium/suites/MediaWikiEditorTestSuite.php b/tests/selenium/suites/MediaWikiEditorTestSuite.php deleted file mode 100644 index f9cfb7fb..00000000 --- a/tests/selenium/suites/MediaWikiEditorTestSuite.php +++ /dev/null @@ -1,19 +0,0 @@ -<?php - -class MediaWikiEditorTestSuite extends SeleniumTestSuite { - public function setUp() { - $this->setLoginBeforeTests( true ); - parent::setUp(); - } - - public function addTests() { - $testFiles = array( - 'tests/selenium/suites/AddNewPageTestCase.php', - 'tests/selenium/suites/AddContentToNewPageTestCase.php', - 'tests/selenium/suites/PreviewPageTestCase.php', - 'tests/selenium/suites/SavePageTestCase.php', - ); - parent::addTestFiles( $testFiles ); - } -} - diff --git a/tests/selenium/suites/MediaWikiExtraTestSuite.php b/tests/selenium/suites/MediaWikiExtraTestSuite.php deleted file mode 100644 index 8993907a..00000000 --- a/tests/selenium/suites/MediaWikiExtraTestSuite.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -class MediaWikiExtraTestSuite extends SeleniumTestSuite { - public function setUp() { - $this->setLoginBeforeTests( true ); - parent::setUp(); - } - - public function addTests() { - $testFiles = array( - 'tests/selenium/suites/MyContributionsTestCase.php', - 'tests/selenium/suites/MyWatchListTestCase.php', - 'tests/selenium/suites/UserPreferencesTestCase.php', - 'tests/selenium/suites/MovePageTestCase.php', - 'tests/selenium/suites/PageSearchTestCase.php', - 'tests/selenium/suites/EmailPasswordTestCase.php', - 'tests/selenium/suites/CreateAccountTestCase.php' - ); - parent::addTestFiles( $testFiles ); - } -} diff --git a/tests/selenium/suites/MediawikiCoreSmokeTestCase.php b/tests/selenium/suites/MediawikiCoreSmokeTestCase.php deleted file mode 100644 index 4491afd2..00000000 --- a/tests/selenium/suites/MediawikiCoreSmokeTestCase.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php -/* - * Stub of tests be need as part of the hack-a-ton - */ -class MediawikiCoreSmokeTestCase extends SeleniumTestCase { - public function testUserLogin() { - - } - - public function testChangeUserPreference() { - - } - - /** - * TODO: generalize this test to be reusable for different skins - */ - public function testCreateNewPageVector() { - - } - - /** - * TODO: generalize this test to be reusable for different skins - */ - public function testEditExistingPageVector() { - - } - - /** - * TODO: generalize this test to be reusable for different skins - */ - public function testCreateNewPageMonobook() { - - } - - /** - * TODO: generalize this test to be reusable for different skins - */ - public function testEditExistingPageMonobook() { - - } - - public function testImageUpload() { - $this->login(); - $this->open( $this->getUrl() . - '/index.php?title=Special:Upload' ); - $this->type( 'wpUploadFile', __DIR__ . - "\\..\\data\\Wikipedia-logo-v2-de.png" ); - $this->check( 'wpIgnoreWarning' ); - $this->click( 'wpUpload' ); - $this->waitForPageToLoad( 30000 ); - - $this->assertSeleniumHTMLContains( - '//h1[@class="firstHeading"]', "Wikipedia-logo-v2-de.png" - ); - - /* - $this->open( $this->getUrl() . '/index.php?title=Image:' - . ucfirst( $this->filename ) . '&action=delete' ); - $this->type( 'wpReason', 'Remove test file' ); - $this->click( 'mw-filedelete-submit' ); - $this->waitForPageToLoad( 10000 ); - - // Todo: This message is localized - $this->assertSeleniumHTMLContains( '//div[@id="bodyContent"]/p', - ucfirst( $this->filename ) . '.*has been deleted.' ); - */ - } - - -} diff --git a/tests/selenium/suites/MediawikiCoreSmokeTestSuite.php b/tests/selenium/suites/MediawikiCoreSmokeTestSuite.php deleted file mode 100644 index fc69e3c3..00000000 --- a/tests/selenium/suites/MediawikiCoreSmokeTestSuite.php +++ /dev/null @@ -1,19 +0,0 @@ -<?php -/** - * Stubs for now. We're going to start populating this test. - */ -class MediawikiCoreSmokeTestSuite extends SeleniumTestSuite { - public function setUp() { - $this->setLoginBeforeTests( false ); - parent::setUp(); - } - - public function addTests() { - $testFiles = array( - 'tests/selenium/suites/MediawikiCoreSmokeTestCase.php' - ); - parent::addTestFiles( $testFiles ); - } - - -} diff --git a/tests/selenium/suites/MovePageTestCase.php b/tests/selenium/suites/MovePageTestCase.php deleted file mode 100644 index d2eaa40d..00000000 --- a/tests/selenium/suites/MovePageTestCase.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php -/** - * Selenium server manager - * - * @file - * @ingroup Testing - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -class MovePageTestCase extends SeleniumTestCase { - // Verify move(rename) wiki page - public function testMovePage() { - $newPage = "mypage99"; - $displayName = "Mypage99"; - - $this->open( $this->getUrl() . - '/index.php?title=Main_Page&action=edit' ); - $this->type( "searchInput", $newPage ); - $this->click( "searchGoButton" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->click( "link=" . $displayName ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->type( SeleniumTestConstants::TEXT_EDITOR, $newPage . " text" ); - $this->click( SeleniumTestConstants::BUTTON_SAVE ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify link 'Move' available - $this->assertTrue( $this->isElementPresent( "link=Move" ) ); - - $this->click( "link=Move" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify correct page name displayed under 'Move Page' field - $this->assertEquals( $displayName, - $this->getText( "//table[@id='mw-movepage-table']/tbody/tr[1]/td[2]/strong/a" ) ); - $movePageName = $this->getText( "//table[@id='mw-movepage-table']/tbody/tr[1]/td[2]/strong/a" ); - - // Verify 'To new title' field has current page name as the default name - $newTitle = $this->getValue( "wpNewTitle" ); - $correct = strstr( $movePageName, $newTitle ); - $this->assertEquals( $correct, true ); - - $this->type( "wpNewTitle", $displayName ); - $this->click( "wpMove" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify warning message for the same source and destination titles - $this->assertEquals( "Source and destination titles are the same; cannot move a page over itself.", - $this->getText( "//div[@id='bodyContent']/p[4]/strong" ) ); - - // Verify warning message for the blank title - $this->type( "wpNewTitle", "" ); - $this->click( "wpMove" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify warning message for the blank title - $this->assertEquals( "The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title. It may contain one or more characters which cannot be used in titles.", - $this->getText( "//div[@id='bodyContent']/p[4]/strong" ) ); - - // Verify warning messages for the invalid titles - $this->type( "wpNewTitle", "# < > [ ] | { }" ); - $this->click( "wpMove" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->assertEquals( "The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title. It may contain one or more characters which cannot be used in titles.", - $this->getText( "//div[@id='bodyContent']/p[4]/strong" ) ); - - $this->type( "wpNewTitle", $displayName . "move" ); - $this->click( "wpMove" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify move success message displayed correctly - $this->assertEquals( "\"" . $displayName . "\" has been moved to \"" . $displayName . "move" . "\"", - $this->getText( "//div[@id='bodyContent']/p[1]/b" ) ); - - $this->type( "searchInput", $newPage . "move" ); - $this->click( "searchGoButton" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify search using new page name - $this->assertEquals( $displayName . "move", $this->getText( "firstHeading" ) ); - - $this->type( "searchInput", $newPage ); - $this->click( "searchGoButton" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify search using old page name - $redirectPageName = $this->getText( "//*[@id='contentSub']" ); - $this->assertEquals( "(Redirected from " . $displayName . ")", $redirectPageName ); - - // newpage delete - $this->deletePage( $newPage . "move" ); - $this->deletePage( $newPage ); - } -} - diff --git a/tests/selenium/suites/MyContributionsTestCase.php b/tests/selenium/suites/MyContributionsTestCase.php deleted file mode 100644 index 81e3a4da..00000000 --- a/tests/selenium/suites/MyContributionsTestCase.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php -/** - * Selenium server manager - * - * @file - * @ingroup Testing - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -require_once dirname( __DIR__ ) . '/SeleniumTestConstants.php'; - -class MyContributionsTestCase extends SeleniumTestCase { - // Verify user contributions - public function testRecentChangesAvailability() { - $newPage = $this->createNewTestPage( "MyContributionsTest" ); - - // Verify My contributions Link available - $this->assertTrue( $this->isElementPresent( "link=Contributions" ) ); - - - $this->click( "link=Contributions" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify recent page adding available on My Contributions list - $this->assertEquals( $newPage, $this->getText( "link=" . $newPage ) ); - - $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, $newPage ); - $this->click( SeleniumTestConstants::BUTTON_SEARCH ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->click( SeleniumTestConstants::LINK_EDIT ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->type( SeleniumTestConstants::TEXT_EDITOR, $newPage . " text changed" ); - $this->click( SeleniumTestConstants::BUTTON_SAVE ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->click( "link=Contributions" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify recent page changes available on My Contributions - $this->assertTrue( $this->isTextPresent( $newPage ) ); - } -} - diff --git a/tests/selenium/suites/MyWatchListTestCase.php b/tests/selenium/suites/MyWatchListTestCase.php deleted file mode 100644 index 842108fa..00000000 --- a/tests/selenium/suites/MyWatchListTestCase.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php -/** - * Selenium server manager - * - * @file - * @ingroup Testing - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -require_once dirname( __DIR__ ) . '/SeleniumTestConstants.php'; - -class MyWatchListTestCase extends SeleniumTestCase { - // Verify user watchlist - public function testMyWatchlist() { - $pageName = $this->createNewTestPage( "MyWatchListTest", true ); - // Verify link 'My Watchlist' available - $this->assertTrue( $this->isElementPresent( SeleniumTestConstants::LINK_START . "Watchlist" ) ); - - $this->click( SeleniumTestConstants::LINK_START . "Watchlist" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify newly added page to the watchlist is available - $this->assertEquals( $pageName, $this->getText( SeleniumTestConstants::LINK_START . $pageName ) ); - - $this->click( SeleniumTestConstants::LINK_START . $pageName ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->click( SeleniumTestConstants::LINK_EDIT ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->click( "wpWatchthis" ); - $this->click( SeleniumTestConstants::BUTTON_SAVE ); - $this->assertFalse( $this->isElementPresent( SeleniumTestConstants::LINK_START . $pageName ) ); - //todo watch using the dropdown menu - } -} - diff --git a/tests/selenium/suites/PageDeleteTestSuite.php b/tests/selenium/suites/PageDeleteTestSuite.php deleted file mode 100644 index e43ffa80..00000000 --- a/tests/selenium/suites/PageDeleteTestSuite.php +++ /dev/null @@ -1,15 +0,0 @@ -<?php - -class PageDeleteTestSuite extends SeleniumTestSuite { - public function setUp() { - $this->setLoginBeforeTests( true ); - parent::setUp(); - } - - public function addTests() { - $testFiles = array( - 'tests/selenium/suites/DeletePageAdminTestCase.php' - ); - parent::addTestFiles( $testFiles ); - } -} diff --git a/tests/selenium/suites/PageSearchTestCase.php b/tests/selenium/suites/PageSearchTestCase.php deleted file mode 100644 index 5fdc5c80..00000000 --- a/tests/selenium/suites/PageSearchTestCase.php +++ /dev/null @@ -1,98 +0,0 @@ -<?php -/** - * Selenium server manager - * - * @file - * @ingroup Testing - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -class PageSearchTestCase extends SeleniumTestCase { - // Verify the functionality of the 'Go' button - public function testPageSearchBtnGo() { - - $this->open( $this->getUrl() . - '/index.php?title=Main_Page&action=edit' ); - $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "calcey qa" ); - $this->click( "searchGoButton" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify no page matched with the entered search text - $source = $this->gettext( "//div[@id='bodyContent']/div[4]/p/b" ); - $correct = strstr( $source, "Create the page \"Calcey qa\" on this wiki!" ); - $this->assertEquals( $correct, true ); - - $this->click( "link=Calcey qa" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->type( SeleniumTestConstants::TEXT_EDITOR, "Calcey QA team" ); - $this->click( "wpSave" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - } - - // Verify the functionality of the 'Search' button - public function testPageSearchBtnSearch() { - $this->open( $this->getUrl() . - '/index.php?title=Main_Page&action=edit' ); - $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "Calcey web" ); - $this->click( SeleniumTestConstants::BUTTON_SEARCH ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify no page is available as the search text - $source = $this->gettext( "//div[@id='bodyContent']/div[4]/p[2]/b" ); - $correct = strstr( $source, "Create the page \"Calcey web\" on this wiki!" ); - $this->assertEquals( $correct, true ); - - $this->click( "link=Calcey web" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->type( SeleniumTestConstants::TEXT_EDITOR, "Calcey web team" ); - $this->click( SeleniumTestConstants::BUTTON_SAVE ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify saved page is opened when the exact page name is given - $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "Calcey web" ); - $this->click( SeleniumTestConstants::BUTTON_SEARCH ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify exact page matched with the entered search text using 'Search' button - $source = $this->getText( "//*[@id='bodyContent']/div[4]/p/b" ); - $correct = strstr( $source, "There is a page named \"Calcey web\" on this wiki." ); - $this->assertEquals( $correct, true ); - - // Verify resutls available when partial page name is entered as the search text - $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "Calcey" ); - $this->click( SeleniumTestConstants::BUTTON_SEARCH ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify text avaialble in the search result under the page titles - if ( $this->isElementPresent( "Page_title_matches" ) ) { - $textPageTitle = $this->getText( "//*[@id='bodyContent']/div[4]/ul[1]/li[1]/div[1]/a" ); - $this->assertContains( 'Calcey', $textPageTitle ); - } - - // Verify text avaialble in the search result under the page text - if ( $this->isElementPresent( "Page_text_matches" ) ) { - $textPageText = $this->getText( "//*[@id='bodyContent']/div[4]/ul[2]/li[2]/div[2]/span" ); - $this->assertContains( 'Calcey', $textPageText ); - } - $this->deletePage( "Calcey QA" ); - $this->deletePage( "Calcey web" ); - } -} diff --git a/tests/selenium/suites/PreviewPageTestCase.php b/tests/selenium/suites/PreviewPageTestCase.php deleted file mode 100644 index 036201f0..00000000 --- a/tests/selenium/suites/PreviewPageTestCase.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php -/** - * Selenium server manager - * - * @file - * @ingroup Testing - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -class PreviewPageTestCase extends SeleniumTestCase { - // Verify adding a new page - public function testPreviewPage() { - $wikiText = "Adding this page to test the \n Preview button functionality"; - $newPage = "Test Preview Page"; - $this->open( $this->getUrl() . - '/index.php?title=Main_Page&action=edit' ); - $this->getNewPage( $newPage ); - $this->type( SeleniumTestConstants::TEXT_EDITOR, $wikiText . "" ); - $this->assertTrue( $this->isElementPresent( "//*[@id='wpPreview']" ) ); - - $this->click( "wpPreview" ); - - // Verify saved page available - $source = $this->gettext( "firstHeading" ); - $correct = strstr( $source, "Test Preview Page" ); - $this->assertEquals( $correct, true ); - - // Verify page content previewed succesfully - $contentOfPreviewPage = $this->getText( "//*[@id='content']" ); - $this->assertContains( $wikiText, $contentOfPreviewPage ); - } -} diff --git a/tests/selenium/suites/SavePageTestCase.php b/tests/selenium/suites/SavePageTestCase.php deleted file mode 100644 index 1e4cc2df..00000000 --- a/tests/selenium/suites/SavePageTestCase.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -/** - * Selenium server manager - * - * @file - * @ingroup Testing - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -class SavePageTestCase extends SeleniumTestCase { - // Verify adding a new page - public function testSavePage() { - $wikiText = "Adding this page to test the Save button functionality"; - $newPage = "Test Save Page"; - - $this->open( $this->getUrl() . - '/index.php?title=Main_Page&action=edit' ); - $this->getNewPage( $newPage ); - $this->type( SeleniumTestConstants::TEXT_EDITOR, $wikiText ); - - // verify 'Save' button available - $this->assertTrue( $this->isElementPresent( SeleniumTestConstants::BUTTON_SAVE ) ); - $this->click( SeleniumTestConstants::BUTTON_SAVE ); - - // Verify saved page available - $source = $this->gettext( "firstHeading" ); - $correct = strstr( $source, "Test Save Page" ); - - // Verify Saved page name displayed correctly - $this->assertEquals( $correct, true ); - - // Verify page content saved succesfully - $contentOfSavedPage = $this->getText( "//*[@id='content']" ); - $this->assertContains( $wikiText, $contentOfSavedPage ); - $this->deletePage( $newPage ); - } -} diff --git a/tests/selenium/suites/SimpleSeleniumConfig.php b/tests/selenium/suites/SimpleSeleniumConfig.php deleted file mode 100644 index a6935114..00000000 --- a/tests/selenium/suites/SimpleSeleniumConfig.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -class SimpleSeleniumConfig { - - public static function getSettings( &$includeFiles, &$globalConfigs, &$resourceFiles ) { - global $IP; - $includes = array( - //files that needed to be included would go here - ); - $configs = array( - 'wgDBprefix' => 'mw_', - 'wgDBTableOptions' => 'ENGINE=InnoDB, DEFAULT CHARSET=binary', - 'wgDBmysql5' => 'false', - 'wgMainCacheType' => 'CACHE_NONE', - 'wgParserCacheType' => 'CACHE_NONE', - 'wgMemCachedServers' => array(), - 'wgLanguageCode' => 'en', - 'wgSitename' => 'test_wiki', - 'wgDefaultSkin' => 'chick' - ); - $resources = array( - 'db' => "$IP/tests/selenium/data/SimpleSeleniumTestDB.sql", - 'images' => "$IP/tests/selenium/data/SimpleSeleniumTestImages.zip" - ); - - $includeFiles = array_merge( $includeFiles, $includes ); - $globalConfigs = array_merge( $globalConfigs, $configs ); - $resourceFiles = array_merge( $resourceFiles, $resources ); - return true; - } -} diff --git a/tests/selenium/suites/SimpleSeleniumTestCase.php b/tests/selenium/suites/SimpleSeleniumTestCase.php deleted file mode 100644 index 14c9e6b9..00000000 --- a/tests/selenium/suites/SimpleSeleniumTestCase.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php -/* - * This test case is part of the SimpleSeleniumTestSuite. - * Configuration for these tests are documented as part of SimpleSeleniumTestSuite.php - */ -class SimpleSeleniumTestCase extends SeleniumTestCase { - public function testBasic() { - $this->open( $this->getUrl() . - '/index.php?title=Selenium&action=edit' ); - $this->type( "wpTextbox1", "This is a basic test" ); - $this->click( "wpPreview" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // check result - $source = $this->getText( "//div[@id='wikiPreview']/p" ); - $correct = strstr( $source, "This is a basic test" ); - $this->assertEquals( $correct, true ); - } - - /** - * All this test really does is verify that a global var was set. - * It depends on $wgDefaultSkin = 'chick'; being set - */ - public function testGlobalVariableForDefaultSkin() { - $this->open( $this->getUrl() . '/index.php' ); - $bodyClass = $this->getAttribute( "//body/@class" ); - $this->assertContains( 'skin-chick', $bodyClass, 'Chick skin not set' ); - } - - /** - * Just verify that the test db was loaded correctly - */ - public function testDatabaseResourceLoadedCorrectly() { - $this->open( $this->getUrl() . '/index.php/TestResources?action=purge' ); - $testString = $this->gettext( "//body//*[@id='firstHeading']" ); - $this->assertEquals( 'TestResources', $testString, 'Article that should be present in the test db was not found.' ); - } - -} diff --git a/tests/selenium/suites/SimpleSeleniumTestSuite.php b/tests/selenium/suites/SimpleSeleniumTestSuite.php deleted file mode 100644 index 446836a2..00000000 --- a/tests/selenium/suites/SimpleSeleniumTestSuite.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php -/** - * Sample test suite. - * Two ways to configure MW for these tests - * 1) If you are running multiple test suites, add the following in LocalSettings.php - * require_once("tests/selenium/SimpleSeleniumConfig.php"); - * $wgSeleniumTestConfigs['SimpleSeleniumTestSuite'] = 'SimpleSeleniumConfig::getSettings'; - * OR - * 2) Add the following to your Localsettings.php - * $wgDefaultSkin = 'chick'; - */ -class SimpleSeleniumTestSuite extends SeleniumTestSuite { - public function setUp() { - $this->setLoginBeforeTests( false ); - parent::setUp(); - } - - public function addTests() { - $testFiles = array( - 'selenium/suites/SimpleSeleniumTestCase.php' - ); - parent::addTestFiles( $testFiles ); - } - - -} diff --git a/tests/selenium/suites/UserPreferencesTestCase.php b/tests/selenium/suites/UserPreferencesTestCase.php deleted file mode 100644 index c70e38fb..00000000 --- a/tests/selenium/suites/UserPreferencesTestCase.php +++ /dev/null @@ -1,170 +0,0 @@ -<?php -/** - * Selenium server manager - * - * @file - * @ingroup Testing - * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com> - * http://www.calcey.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -class UserPreferencesTestCase extends SeleniumTestCase { - // Verify user information - public function testUserInfoDisplay() { - - $this->open( $this->getUrl() . - '/index.php?title=Main_Page&action=edit' ); - $this->click( SeleniumTestConstants::LINK_START . "My preferences" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify correct username displayed in User Preferences - $this->assertEquals( $this->getText( "//li[@id='pt-userpage']/a" ), - $this->getText( "//table[@id='mw-htmlform-info']/tbody/tr[1]/td[2]" ) ); - - // Verify existing Signature Displayed correctly - $this->assertEquals( $this->selenium->getUser(), - $this->getTable( "mw-htmlform-signature.0.1" ) ); - } - - // Verify change password - public function testChangePassword() { - - $this->open( $this->getUrl() . - '/index.php?title=Main_Page&action=edit' ); - $this->click( SeleniumTestConstants::LINK_START . "My preferences" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->click( SeleniumTestConstants::LINK_START . "Change password" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->type( "wpPassword", "12345" ); - $this->type( "wpNewPassword", "54321" ); - $this->type( "wpRetype", "54321" ); - $this->click( "//input[@value='Change password']" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->assertEquals( "Preferences", $this->getText( "firstHeading" ) ); - - $this->click( SeleniumTestConstants::LINK_START . "Change password" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->type( "wpPassword", "54321" ); - $this->type( "wpNewPassword", "12345" ); - $this->type( "wpRetype", "12345" ); - $this->click( "//input[@value='Change password']" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->assertEquals( "Preferences", $this->getText( "firstHeading" ) ); - - $this->click( SeleniumTestConstants::LINK_START . "Change password" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->type( "wpPassword", "54321" ); - $this->type( "wpNewPassword", "12345" ); - $this->type( "wpRetype", "12345" ); - $this->click( "//input[@value='Change password']" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - } - - // Verify successful preferences save - public function testSuccessfullSave() { - - $this->open( $this->getUrl() . - '/index.php?title=Main_Page&action=edit' ); - $this->click( SeleniumTestConstants::LINK_START . "My preferences" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->type( "mw-input-realname", "Test User" ); - $this->click( "prefcontrol" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify "Your preferences have been saved." message - $this->assertEquals( "Your preferences have been saved.", - $this->getText( "//div[@id='bodyContent']/div[4]/strong/p" ) ); - $this->type( "mw-input-realname", "" ); - $this->click( "prefcontrol" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - } - - // Verify change signature - public function testChangeSignature() { - $this->open( $this->getUrl() . - '/index.php?title=Main_Page&action=edit' ); - $this->click( SeleniumTestConstants::LINK_START . "My preferences" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->type( "mw-input-nickname", "TestSignature" ); - $this->click( "prefcontrol" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify change user signature - $this->assertEquals( "TestSignature", $this->getText( SeleniumTestConstants::LINK_START . "TestSignature" ) ); - $this->type( "mw-input-nickname", "Test" ); - $this->click( "prefcontrol" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - } - - // Verify change date format - public function testChangeDateFormatTimeZone() { - $this->open( $this->getUrl() . - '/index.php?title=Main_Page&action=edit' ); - - $this->click( SeleniumTestConstants::LINK_START . "My preferences" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - $this->click( SeleniumTestConstants::LINK_START . "Date and time" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - $this->click( "mw-input-date-dmy" ); - $this->select( "mw-input-timecorrection", "label=Asia/Colombo" ); - $this->click( "prefcontrol" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify Date format and time zome saved - $this->assertEquals( "Your preferences have been saved.", - $this->getText( "//div[@id='bodyContent']/div[4]/strong/p" ) ); - } - - // Verify restoring all default settings - public function testSetAllDefault() { - $this->open( $this->getUrl() . - '/index.php?title=Main_Page&action=edit' ); - $this->click( SeleniumTestConstants::LINK_START . "My preferences" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify restoring all default settings - $this->assertEquals( "Restore all default settings", - $this->getText( SeleniumTestConstants::LINK_START . "Restore all default settings" ) ); - - $this->click( "//*[@id='preferences']/div/a" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify 'This can not be undone' warning message displayed - $this->assertTrue( $this->isElementPresent( "//input[@value='Restore all default settings']" ) ); - - // Verify 'Restore all default settings' button available - $this->assertEquals( "You can use this page to reset your preferences to the site defaults. This cannot be undone.", - $this->getText( "//div[@id='bodyContent']/p" ) ); - - $this->click( "//input[@value='Restore all default settings']" ); - $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME ); - - // Verify preferences saved successfully - $this->assertEquals( "Your preferences have been saved.", - $this->getText( "//div[@id='bodyContent']/div[4]/strong/p" ) ); - } -} - diff --git a/tests/testHelpers.inc b/tests/testHelpers.inc index 02fcf24c..88e5885b 100644 --- a/tests/testHelpers.inc +++ b/tests/testHelpers.inc @@ -21,7 +21,36 @@ * @ingroup Testing */ -class TestRecorder { +/** + * Interface to record parser test results. + * + * The ITestRecorder is a very simple interface to record the result of + * MediaWiki parser tests. One should call start() before running the + * full parser tests and end() once all the tests have been finished. + * After each test, you should use record() to keep track of your tests + * results. Finally, report() is used to generate a summary of your + * test run, one could dump it to the console for human consumption or + * register the result in a database for tracking purposes. + * + * @since 1.22 + */ +interface ITestRecorder { + + /** Called at beginning of the parser test run */ + public function start(); + + /** Called after each test */ + public function record( $test, $result ); + + /** Called before finishing the test run */ + public function report(); + + /** Called at the end of the parser test run */ + public function end(); + +} + +class TestRecorder implements ITestRecorder { var $parent; var $term; @@ -481,7 +510,7 @@ class TestFileIterator implements Iterator { return true; } - if ( isset ( $this->sectionData[$this->section] ) ) { + if ( isset( $this->sectionData[$this->section] ) ) { throw new MWException( "duplicate section '$this->section' at line {$this->lineNum} of $this->file\n" ); } |