diff options
Diffstat (limited to 'tests/phpunit')
363 files changed, 0 insertions, 49070 deletions
diff --git a/tests/phpunit/Makefile b/tests/phpunit/Makefile deleted file mode 100644 index c3e2a303..00000000 --- a/tests/phpunit/Makefile +++ /dev/null @@ -1,91 +0,0 @@ -.PHONY: help test phpunit install coverage warning destructive parser noparser safe databaseless list-groups -.DEFAULT: warning - -SHELL = /bin/sh -CONFIG_FILE = ${PWD}/suite.xml -PHP = php -PU = ${PHP} phpunit.php --configuration ${CONFIG_FILE} ${FLAGS} - -all test: warning - -warning: - @echo "Run 'make help' to get usage" - @echo "" - @echo "WARNING -- some tests are DESTRUCTIVE and will alter your wiki." - @echo "DO NOT RUN THESE TESTS on a production wiki." - @echo "" - @echo "Until the default tests are made non-destructive, you can run" - @echo "the destructive tests like so:" - @echo "" - @echo " make destructive" - @echo "" - @echo "Some tests are expected to be safe, you can run them with" - @echo "" - @echo " make safe" - @echo "" - @echo "You are recommended to run the tests with read-only credentials." - @echo "" - @echo "If you don't have a database running, you can still run" - @echo "" - @echo " make databaseless" - @echo "" - -destructive: phpunit - -phpunit: - ${PU} - -install: - ./install-phpunit.sh - -tap: - ${PU} --tap - -coverage: - ${PU} --coverage-html ../../docs/code-coverage - -parser: - ${PU} --group Parser -parserfuzz: - @echo "******************************************************************" - @echo "* This WILL kill your computer by eating all memory AND all swap *" - @echo "* *" - @echo "* If you are on a production machine. ABORT NOW!! *" - @echo "* Press control+C to stop *" - @echo "* *" - @echo "******************************************************************" - ${PU} --group Parser,ParserFuzz -noparser: - ${PU} --exclude-group Parser,Broken,ParserFuzz,Stub - -safe: - ${PU} --exclude-group Broken,ParserFuzz,Destructive,Stub - -databaseless: - ${PU} --exclude-group Broken,ParserFuzz,Destructive,Database,Stub - -database: - ${PU} --exclude-group Broken,ParserFuzz,Destructive,Stub --group Database - -list-groups: - ${PU} --list-groups - -help: - # Usage: - # make <target> [OPTION=value] - # - # Targets: - # phpunit (default) Run all the tests with phpunit - # install Install PHPUnit from phpunit.de - # tap Run the tests individually through Test::Harness's prove(1) - # help You're looking at it! - # coverage Run the tests and generates an HTML code coverage report - # You will need the Xdebug PHP extension for the later. - # [no]parser Skip or only run Parser tests - # - # list-groups List availabe Tests groups. - # - # Options: - # CONFIG_FILE Path to a PHPUnit configuration file (default: suite.xml) - # FLAGS Additional flags to pass to PHPUnit - # PHP Path to php diff --git a/tests/phpunit/MediaWikiLangTestCase.php b/tests/phpunit/MediaWikiLangTestCase.php deleted file mode 100644 index 1131385f..00000000 --- a/tests/phpunit/MediaWikiLangTestCase.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php - -/** - * Base class that store and restore the Language objects - */ -abstract class MediaWikiLangTestCase extends MediaWikiTestCase { - - protected function setUp() { - global $wgLanguageCode, $wgContLang; - parent::setUp(); - - if ( $wgLanguageCode != $wgContLang->getCode() ) { - throw new MWException( "Error in MediaWikiLangTestCase::setUp(): " . - "\$wgLanguageCode ('$wgLanguageCode') is different from " . - "\$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 ); - - $this->setMwGlobals( array( - 'wgLanguageCode' => $langCode, - 'wgLang' => $langObj, - 'wgContLang' => $langObj, - ) ); - - MessageCache::singleton()->disable(); - } -} diff --git a/tests/phpunit/MediaWikiPHPUnitCommand.php b/tests/phpunit/MediaWikiPHPUnitCommand.php deleted file mode 100644 index 042956a9..00000000 --- a/tests/phpunit/MediaWikiPHPUnitCommand.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php - -class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command { - - public static $additionalOptions = array( - 'regex=' => false, - 'file=' => false, - 'use-filebackend=' => false, - 'use-bagostuff=' => false, - 'use-jobqueue=' => false, - 'keep-uploads' => false, - '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 ) { - $command = new self; - - if ( wfIsWindows() ) { - # Windows does not come anymore with ANSI.SYS loaded by default - # PHPUnit uses the suite.xml parameters to enable/disable colors - # which can be then forced to be enabled with --colors. - # The below code inject a parameter just like if the user called - # phpunit with a --no-color option (which does not exist). It - # overrides the suite.xml setting. - # Probably fix bug 29226 - $command->arguments['colors'] = false; - } - - # Makes MediaWiki PHPUnit directory includable so the PHPUnit will - # be able to resolve relative files inclusion such as suites/* - # PHPUnit uses stream_resolve_include_path() internally - # See bug 32022 - set_include_path( - __DIR__ - . PATH_SEPARATOR - . get_include_path() - ); - - $command->run( $_SERVER['argv'], $exit ); - } - - public function __call( $func, $args ) { - - if ( substr( $func, -7 ) == 'Handler' ) { - if ( is_null( $args[0] ) ) { - $args[0] = true; - } //Booleans - self::$additionalOptions[substr( $func, 0, -7 )] = $args[0]; - } - } - - public function run( array $argv, $exit = true ) { - wfProfileIn( __METHOD__ ); - - $ret = parent::run( $argv, false ); - - wfProfileOut( __METHOD__ ); - - // Return to real wiki db, so profiling data is preserved - MediaWikiTestCase::teardownTestDB(); - - // Log profiling data, e.g. in the database or UDP - wfLogProfilingData(); - - if ( $exit ) { - exit( $ret ); - } else { - return $ret; - } - } - - public function showHelp() { - parent::showHelp(); - - print <<<EOT - -ParserTest-specific options: - - --regex="<regex>" Only run parser tests that match the given regex - --file="<filename>" File describing parser tests - --keep-uploads Re-use the same upload directory for each test, don't delete it - - -Database options: - --use-normal-tables Use normal DB tables. - --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 deleted file mode 100644 index 7237ef32..00000000 --- a/tests/phpunit/MediaWikiPHPUnitTestListener.php +++ /dev/null @@ -1,114 +0,0 @@ -<?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 deleted file mode 100644 index 6ce78b56..00000000 --- a/tests/phpunit/MediaWikiTestCase.php +++ /dev/null @@ -1,948 +0,0 @@ -<?php - -abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { - public $suite; - public $regex = ''; - public $runDisabled = false; - - /** - * $called tracks whether the setUp and tearDown method has been called. - * class extending MediaWikiTestCase usually override setUp and tearDown - * but forget to call the parent. - * - * The array format takes a method name as key and anything as a value. - * By asserting the key exist, we know the child class has called the - * parent. - * - * This property must be private, we do not want child to override it, - * they should call the appropriate parent method instead. - */ - private $called = array(); - - /** - * @var Array of TestUser - */ - public static $users; - - /** - * @var DatabaseBase - */ - protected $db; - protected $tablesUsed = array(); // tables with data - - private static $useTemporaryTables = true; - private static $reuseDB = false; - private static $dbSetup = false; - private static $oldTablePrefix = false; - - /** - * Holds the paths of temporary files/directories created through getNewTempFile, - * and getNewTempDirectory - * - * @var array - */ - private $tmpfiles = array(); - - /** - * Holds original values of MediaWiki configuration settings - * to be restored in tearDown(). - * See also setMwGlobal(). - * @var array - */ - private $mwGlobals = array(); - - /** - * Table name prefixes. Oracle likes it shorter. - */ - const DB_PREFIX = 'unittest_'; - const ORA_DB_PREFIX = 'ut_'; - - protected $supportedDBs = array( - 'mysql', - 'sqlite', - 'postgres', - 'oracle' - ); - - function __construct( $name = null, array $data = array(), $dataName = '' ) { - parent::__construct( $name, $data, $dataName ); - - $this->backupGlobals = false; - $this->backupStaticAttributes = false; - } - - function run( PHPUnit_Framework_TestResult $result = null ) { - /* Some functions require some kind of caching, and will end up using the db, - * which we can't allow, as that would open a new connection for mysql. - * Replace with a HashBag. They would not be going to persist anyway. - */ - ObjectCache::$instances[CACHE_DB] = new HashBagOStuff; - - $needsResetDB = false; - $logName = get_class( $this ) . '::' . $this->getName( false ); - - if ( $this->needsDB() ) { - // set up a DB connection for this test to use - - self::$useTemporaryTables = !$this->getCliArg( 'use-normal-tables' ); - self::$reuseDB = $this->getCliArg( 'reuse-db' ); - - $this->db = wfGetDB( DB_MASTER ); - - $this->checkDbIsSupported(); - - if ( !self::$dbSetup ) { - wfProfileIn( $logName . ' (clone-db)' ); - - // switch to a temporary clone of the database - self::setupTestDB( $this->db, $this->dbPrefix() ); - - if ( ( $this->db->getType() == 'oracle' || !self::$useTemporaryTables ) && self::$reuseDB ) { - $this->resetDB(); - } - - wfProfileOut( $logName . ' (clone-db)' ); - } - - wfProfileIn( $logName . ' (prepare-db)' ); - $this->addCoreDBData(); - $this->addDBData(); - wfProfileOut( $logName . ' (prepare-db)' ); - - $needsResetDB = true; - } - - wfProfileIn( $logName ); - parent::run( $result ); - wfProfileOut( $logName ); - - if ( $needsResetDB ) { - wfProfileIn( $logName . ' (reset-db)' ); - $this->resetDB(); - wfProfileOut( $logName . ' (reset-db)' ); - } - } - - function usesTemporaryTables() { - return self::$useTemporaryTables; - } - - /** - * obtains a new temporary file name - * - * The obtained filename is enlisted to be removed upon tearDown - * - * @return string: absolute name of the temporary file - */ - protected function getNewTempFile() { - $fname = tempnam( wfTempDir(), 'MW_PHPUnit_' . get_class( $this ) . '_' ); - $this->tmpfiles[] = $fname; - - return $fname; - } - - /** - * obtains a new temporary directory - * - * The obtained directory is enlisted to be removed (recursively with all its contained - * files) upon tearDown. - * - * @return string: absolute name of the temporary directory - */ - protected function getNewTempDirectory() { - // Starting of with a temporary /file/. - $fname = $this->getNewTempFile(); - - // Converting the temporary /file/ to a /directory/ - // - // The following is not atomic, but at least we now have a single place, - // where temporary directory creation is bundled and can be improved - unlink( $fname ); - $this->assertTrue( wfMkdirParents( $fname ) ); - - return $fname; - } - - /** - * setUp and tearDown should (where significant) - * happen in reverse order. - */ - protected function setUp() { - wfProfileIn( __METHOD__ ); - parent::setUp(); - $this->called['setUp'] = 1; - - /* - // @todo global variables to restore for *every* test - array( - 'wgLang', - 'wgContLang', - 'wgLanguageCode', - 'wgUser', - 'wgTitle', - ); - */ - - // Cleaning up temporary files - foreach ( $this->tmpfiles as $fname ) { - if ( is_file( $fname ) || ( is_link( $fname ) ) ) { - unlink( $fname ); - } elseif ( is_dir( $fname ) ) { - wfRecursiveRemoveDir( $fname ); - } - } - - if ( $this->needsDB() && $this->db ) { - // Clean up open transactions - while ( $this->db->trxLevel() > 0 ) { - $this->db->rollback(); - } - - // don't ignore DB errors - $this->db->ignoreErrors( false ); - } - - wfProfileOut( __METHOD__ ); - } - - protected function tearDown() { - wfProfileIn( __METHOD__ ); - - // Cleaning up temporary files - foreach ( $this->tmpfiles as $fname ) { - if ( is_file( $fname ) || ( is_link( $fname ) ) ) { - unlink( $fname ); - } elseif ( is_dir( $fname ) ) { - wfRecursiveRemoveDir( $fname ); - } - } - - if ( $this->needsDB() && $this->db ) { - // Clean up open transactions - while ( $this->db->trxLevel() > 0 ) { - $this->db->rollback(); - } - - // don't ignore DB errors - $this->db->ignoreErrors( false ); - } - - // Restore mw globals - foreach ( $this->mwGlobals as $key => $value ) { - $GLOBALS[$key] = $value; - } - $this->mwGlobals = array(); - - parent::tearDown(); - wfProfileOut( __METHOD__ ); - } - - /** - * Make sure MediaWikiTestCase extending classes have called their - * parent setUp method - */ - final public function testMediaWikiTestCaseParentSetupCalled() { - $this->assertArrayHasKey( 'setUp', $this->called, - get_called_class() . "::setUp() must call parent::setUp()" - ); - } - - /** - * Individual test functions may override globals (either directly or through this - * setMwGlobals() function), however one must call this method at least once for - * each key within the setUp(). - * That way the key is added to the array of globals that will be reset afterwards - * in the tearDown(). And, equally important, that way all other tests are executed - * with the same settings (instead of using the unreliable local settings for most - * tests and fix it only for some tests). - * - * @example - * <code> - * protected function setUp() { - * $this->setMwGlobals( 'wgRestrictStuff', true ); - * } - * - * function testFoo() {} - * - * function testBar() {} - * $this->assertTrue( self::getX()->doStuff() ); - * - * $this->setMwGlobals( 'wgRestrictStuff', false ); - * $this->assertTrue( self::getX()->doStuff() ); - * } - * - * function testQuux() {} - * </code> - * - * @param array|string $pairs Key to the global variable, or an array - * of key/value pairs. - * @param mixed $value Value to set the global to (ignored - * if an array is given as first argument). - */ - protected function setMwGlobals( $pairs, $value = null ) { - - // Normalize (string, value) to an array - if ( is_string( $pairs ) ) { - $pairs = array( $pairs => $value ); - } - - foreach ( $pairs as $key => $value ) { - // NOTE: make sure we only save the global once or a second call to - // setMwGlobals() on the same global would override the original - // value. - if ( !array_key_exists( $key, $this->mwGlobals ) ) { - $this->mwGlobals[$key] = $GLOBALS[$key]; - } - - // Override the global - $GLOBALS[$key] = $value; - } - } - - /** - * Merges the given values into a MW global array variable. - * Useful for setting some entries in a configuration array, instead of - * setting the entire array. - * - * @param String $name The name of the global, as in wgFooBar - * @param Array $values The array containing the entries to set in that global - * - * @throws MWException if the designated global is not an array. - */ - protected function mergeMwGlobalArrayValue( $name, $values ) { - if ( !isset( $GLOBALS[$name] ) ) { - $merged = $values; - } else { - if ( !is_array( $GLOBALS[$name] ) ) { - throw new MWException( "MW global $name is not an array." ); - } - - // NOTE: do not use array_merge, it screws up for numeric keys. - $merged = $GLOBALS[$name]; - foreach ( $values as $k => $v ) { - $merged[$k] = $v; - } - } - - $this->setMwGlobals( $name, $merged ); - } - - function dbPrefix() { - return $this->db->getType() == 'oracle' ? self::ORA_DB_PREFIX : self::DB_PREFIX; - } - - function needsDB() { - # if the test says it uses database tables, it needs the database - if ( $this->tablesUsed ) { - return true; - } - - # if the test says it belongs to the Database group, it needs the database - $rc = new ReflectionClass( $this ); - if ( preg_match( '/@group +Database/im', $rc->getDocComment() ) ) { - return true; - } - - return false; - } - - /** - * Stub. If a test needs to add additional data to the database, it should - * implement this method and do so - */ - function addDBData() { - } - - private function addCoreDBData() { - # disabled for performance - #$this->tablesUsed[] = 'page'; - #$this->tablesUsed[] = 'revision'; - - if ( $this->db->getType() == 'oracle' ) { - - # Insert 0 user to prevent FK violations - # Anonymous user - $this->db->insert( 'user', array( - 'user_id' => 0, - 'user_name' => 'Anonymous' ), __METHOD__, array( 'IGNORE' ) ); - - # Insert 0 page to prevent FK violations - # Blank page - $this->db->insert( 'page', array( - 'page_id' => 0, - 'page_namespace' => 0, - 'page_title' => ' ', - 'page_restrictions' => null, - 'page_counter' => 0, - 'page_is_redirect' => 0, - 'page_is_new' => 0, - 'page_random' => 0, - 'page_touched' => $this->db->timestamp(), - 'page_latest' => 0, - 'page_len' => 0 ), __METHOD__, array( 'IGNORE' ) ); - } - - User::resetIdByNameCache(); - - //Make sysop user - $user = User::newFromName( 'UTSysop' ); - - if ( $user->idForName() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTSysopPassword' ); - - $user->addGroup( 'sysop' ); - $user->addGroup( 'bureaucrat' ); - $user->saveSettings(); - } - - //Make 1 page with 1 revision - $page = WikiPage::factory( Title::newFromText( 'UTPage' ) ); - if ( !$page->getId() == 0 ) { - $page->doEditContent( - new WikitextContent( 'UTContent' ), - 'UTPageSummary', - EDIT_NEW, - false, - User::newFromName( 'UTSysop' ) ); - } - } - - /** - * Restores MediaWiki to using the table set (table prefix) it was using before - * setupTestDB() was called. Useful if we need to perform database operations - * after the test run has finished (such as saving logs or profiling info). - */ - public static function teardownTestDB() { - if ( !self::$dbSetup ) { - return; - } - - CloneDatabase::changePrefix( self::$oldTablePrefix ); - - self::$oldTablePrefix = false; - self::$dbSetup = false; - } - - /** - * Creates an empty skeleton of the wiki database by cloning its structure - * to equivalent tables using the given $prefix. Then sets MediaWiki to - * use the new set of tables (aka schema) instead of the original set. - * - * This is used to generate a dummy table set, typically consisting of temporary - * tables, that will be used by tests instead of the original wiki database tables. - * - * @note: the original table prefix is stored in self::$oldTablePrefix. This is used - * by teardownTestDB() to return the wiki to using the original table set. - * - * @note: this method only works when first called. Subsequent calls have no effect, - * 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). - * - * @throws MWException if the database table prefix is already $prefix - */ - public static function setupTestDB( DatabaseBase $db, $prefix ) { - global $wgDBprefix; - if ( $wgDBprefix === $prefix ) { - throw new MWException( 'Cannot run unit tests, the database prefix is already "' . $prefix . '"' ); - } - - if ( self::$dbSetup ) { - return; - } - - $tablesCloned = self::listTables( $db ); - $dbClone = new CloneDatabase( $db, $tablesCloned, $prefix ); - $dbClone->useTemporaryTables( self::$useTemporaryTables ); - - self::$dbSetup = true; - self::$oldTablePrefix = $wgDBprefix; - - if ( ( $db->getType() == 'oracle' || !self::$useTemporaryTables ) && self::$reuseDB ) { - CloneDatabase::changePrefix( $prefix ); - - return; - } else { - $dbClone->cloneTableStructure(); - } - - if ( $db->getType() == 'oracle' ) { - $db->query( 'BEGIN FILL_WIKI_INFO; END;' ); - } - } - - /** - * Empty all tables so they can be repopulated for tests - */ - private function resetDB() { - if ( $this->db ) { - if ( $this->db->getType() == 'oracle' ) { - if ( self::$useTemporaryTables ) { - wfGetLB()->closeAll(); - $this->db = wfGetDB( DB_MASTER ); - } else { - foreach ( $this->tablesUsed as $tbl ) { - if ( $tbl == 'interwiki' ) { - continue; - } - $this->db->query( 'TRUNCATE TABLE ' . $this->db->tableName( $tbl ), __METHOD__ ); - } - } - } else { - foreach ( $this->tablesUsed as $tbl ) { - if ( $tbl == 'interwiki' || $tbl == 'user' ) { - continue; - } - $this->db->delete( $tbl, '*', __METHOD__ ); - } - } - } - } - - function __call( $func, $args ) { - static $compatibility = array( - 'assertInternalType' => 'assertType', - 'assertNotInternalType' => 'assertNotType', - 'assertInstanceOf' => 'assertType', - 'assertEmpty' => 'assertEmpty2', - ); - - if ( method_exists( $this->suite, $func ) ) { - return call_user_func_array( array( $this->suite, $func ), $args ); - } elseif ( isset( $compatibility[$func] ) ) { - return call_user_func_array( array( $this, $compatibility[$func] ), $args ); - } else { - throw new MWException( "Called non-existant $func method on " - . get_class( $this ) ); - } - } - - private function assertEmpty2( $value, $msg ) { - return $this->assertTrue( $value == '', $msg ); - } - - private static function unprefixTable( $tableName ) { - global $wgDBprefix; - - return substr( $tableName, strlen( $wgDBprefix ) ); - } - - private static function isNotUnittest( $table ) { - return strpos( $table, 'unittest_' ) !== 0; - } - - public static function listTables( $db ) { - 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 - $tables = array_filter( $tables, array( __CLASS__, 'isNotUnittest' ) ); - - if ( $db->getType() == 'sqlite' ) { - $tables = array_flip( $tables ); - // these are subtables of searchindex and don't need to be duped/dropped separately - unset( $tables['searchindex_content'] ); - unset( $tables['searchindex_segdir'] ); - unset( $tables['searchindex_segments'] ); - $tables = array_flip( $tables ); - } - - return $tables; - } - - protected function checkDbIsSupported() { - if ( !in_array( $this->db->getType(), $this->supportedDBs ) ) { - throw new MWException( $this->db->getType() . " is not currently supported for unit testing." ); - } - } - - public function getCliArg( $offset ) { - - if ( isset( MediaWikiPHPUnitCommand::$additionalOptions[$offset] ) ) { - return MediaWikiPHPUnitCommand::$additionalOptions[$offset]; - } - } - - public function setCliArg( $offset, $value ) { - - MediaWikiPHPUnitCommand::$additionalOptions[$offset] = $value; - } - - /** - * Don't throw a warning if $function is deprecated and called later - * - * @param $function String - * @return null - */ - function hideDeprecated( $function ) { - wfSuppressWarnings(); - wfDeprecated( $function ); - wfRestoreWarnings(); - } - - /** - * Asserts that the given database query yields the rows given by $expectedRows. - * The expected rows should be given as indexed (not associative) arrays, with - * the values given in the order of the columns in the $fields parameter. - * Note that the rows are sorted by the columns given in $fields. - * - * @since 1.20 - * - * @param $table String|Array the table(s) to query - * @param $fields String|Array the columns to include in the result (and to sort by) - * @param $condition String|Array "where" condition(s) - * @param $expectedRows Array - an array of arrays giving the expected rows. - * - * @throws MWException if this test cases's needsDB() method doesn't return true. - * Test cases can use "@group Database" to enable database test support, - * or list the tables under testing in $this->tablesUsed, or override the - * needsDB() method. - */ - protected function assertSelect( $table, $fields, $condition, array $expectedRows ) { - if ( !$this->needsDB() ) { - throw new MWException( 'When testing database state, the test cases\'s needDB()' . - ' method should return true. Use @group Database or $this->tablesUsed.' ); - } - - $db = wfGetDB( DB_SLAVE ); - - $res = $db->select( $table, $fields, $condition, wfGetCaller(), array( 'ORDER BY' => $fields ) ); - $this->assertNotEmpty( $res, "query failed: " . $db->lastError() ); - - $i = 0; - - foreach ( $expectedRows as $expected ) { - $r = $res->fetchRow(); - self::stripStringKeys( $r ); - - $i += 1; - $this->assertNotEmpty( $r, "row #$i missing" ); - - $this->assertEquals( $expected, $r, "row #$i mismatches" ); - } - - $r = $res->fetchRow(); - self::stripStringKeys( $r ); - - $this->assertFalse( $r, "found extra row (after #$i)" ); - } - - /** - * Utility method taking an array of elements and wrapping - * each element in it's own array. Useful for data providers - * that only return a single argument. - * - * @since 1.20 - * - * @param array $elements - * - * @return array - */ - protected function arrayWrap( array $elements ) { - return array_map( - function ( $element ) { - return array( $element ); - }, - $elements - ); - } - - /** - * Assert that two arrays are equal. By default this means that both arrays need to hold - * the same set of values. Using additional arguments, order and associated key can also - * be set as relevant. - * - * @since 1.20 - * - * @param array $expected - * @param array $actual - * @param boolean $ordered If the order of the values should match - * @param boolean $named If the keys should match - */ - protected function assertArrayEquals( array $expected, array $actual, $ordered = false, $named = false ) { - if ( !$ordered ) { - $this->objectAssociativeSort( $expected ); - $this->objectAssociativeSort( $actual ); - } - - if ( !$named ) { - $expected = array_values( $expected ); - $actual = array_values( $actual ); - } - - call_user_func_array( - array( $this, 'assertEquals' ), - array_merge( array( $expected, $actual ), array_slice( func_get_args(), 4 ) ) - ); - } - - /** - * Put each HTML element on its own line and then equals() the results - * - * Use for nicely formatting of PHPUnit diff output when comparing very - * simple HTML - * - * @since 1.20 - * - * @param String $expected HTML on oneline - * @param String $actual HTML on oneline - * @param String $msg Optional message - */ - protected function assertHTMLEquals( $expected, $actual, $msg = '' ) { - $expected = str_replace( '>', ">\n", $expected ); - $actual = str_replace( '>', ">\n", $actual ); - - $this->assertEquals( $expected, $actual, $msg ); - } - - /** - * Does an associative sort that works for objects. - * - * @since 1.20 - * - * @param array $array - */ - protected function objectAssociativeSort( array &$array ) { - uasort( - $array, - function ( $a, $b ) { - return serialize( $a ) > serialize( $b ) ? 1 : -1; - } - ); - } - - /** - * Utility function for eliminating all string keys from an array. - * Useful to turn a database result row as returned by fetchRow() into - * a pure indexed array. - * - * @since 1.20 - * - * @param $r mixed the array to remove string keys from. - */ - protected static function stripStringKeys( &$r ) { - if ( !is_array( $r ) ) { - return; - } - - foreach ( $r as $k => $v ) { - if ( is_string( $k ) ) { - unset( $r[$k] ); - } - } - } - - /** - * Asserts that the provided variable is of the specified - * internal type or equals the $value argument. This is useful - * for testing return types of functions that return a certain - * type or *value* when not set or on error. - * - * @since 1.20 - * - * @param string $type - * @param mixed $actual - * @param mixed $value - * @param string $message - */ - protected function assertTypeOrValue( $type, $actual, $value = false, $message = '' ) { - if ( $actual === $value ) { - $this->assertTrue( true, $message ); - } else { - $this->assertType( $type, $actual, $message ); - } - } - - /** - * Asserts the type of the provided value. This can be either - * in internal type such as boolean or integer, or a class or - * interface the value extends or implements. - * - * @since 1.20 - * - * @param string $type - * @param mixed $actual - * @param string $message - */ - protected function assertType( $type, $actual, $message = '' ) { - if ( class_exists( $type ) || interface_exists( $type ) ) { - $this->assertInstanceOf( $type, $actual, $message ); - } else { - $this->assertInternalType( $type, $actual, $message ); - } - } - - /** - * Returns true if the given namespace defaults to Wikitext - * according to $wgNamespaceContentModels - * - * @param int $ns The namespace ID to check - * - * @return bool - * @since 1.21 - */ - protected function isWikitextNS( $ns ) { - global $wgNamespaceContentModels; - - if ( isset( $wgNamespaceContentModels[$ns] ) ) { - return $wgNamespaceContentModels[$ns] === CONTENT_MODEL_WIKITEXT; - } - - return true; - } - - /** - * Returns the ID of a namespace that defaults to Wikitext. - * Throws an MWException if there is none. - * - * @return int the ID of the wikitext Namespace - * @since 1.21 - */ - protected function getDefaultWikitextNS() { - global $wgNamespaceContentModels; - - static $wikitextNS = null; // this is not going to change - if ( $wikitextNS !== null ) { - return $wikitextNS; - } - - // quickly short out on most common case: - if ( !isset( $wgNamespaceContentModels[NS_MAIN] ) ) { - return NS_MAIN; - } - - // NOTE: prefer content namespaces - $namespaces = array_unique( array_merge( - MWNamespace::getContentNamespaces(), - array( NS_MAIN, NS_HELP, NS_PROJECT ), // prefer these - MWNamespace::getValidNamespaces() - ) ); - - $namespaces = array_diff( $namespaces, array( - NS_FILE, NS_CATEGORY, NS_MEDIAWIKI, NS_USER // don't mess with magic namespaces - ) ); - - $talk = array_filter( $namespaces, function ( $ns ) { - return MWNamespace::isTalk( $ns ); - } ); - - // prefer non-talk pages - $namespaces = array_diff( $namespaces, $talk ); - $namespaces = array_merge( $namespaces, $talk ); - - // check default content model of each namespace - foreach ( $namespaces as $ns ) { - if ( !isset( $wgNamespaceContentModels[$ns] ) || - $wgNamespaceContentModels[$ns] === CONTENT_MODEL_WIKITEXT - ) { - - $wikitextNS = $ns; - - return $wikitextNS; - } - } - - // give up - // @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!" ); - } - - /** - * Check, if $wgDiff3 is set and ready to merge - * Will mark the calling test as skipped, if not ready - * - * @since 1.21 - */ - protected function checkHasDiff3() { - global $wgDiff3; - - # This check may also protect against code injection in - # case of broken installations. - wfSuppressWarnings(); - $haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 ); - wfRestoreWarnings(); - - if ( !$haveDiff3 ) { - $this->markTestSkipped( "Skip test, since diff3 is not configured" ); - } - } - - /** - * Check whether we have the 'gzip' commandline utility, will skip - * the test whenever "gzip -V" fails. - * - * Result is cached at the process level. - * - * @return bool - * - * @since 1.21 - */ - protected function checkHasGzip() { - static $haveGzip; - - if ( $haveGzip === null ) { - $retval = null; - wfShellExec( 'gzip -V', $retval ); - $haveGzip = ( $retval === 0 ); - } - - if ( !$haveGzip ) { - $this->markTestSkipped( "Skip test, requires the gzip utility in PATH" ); - } - - return $haveGzip; - } - - /** - * Check if $extName is a loaded PHP extension, will skip the - * test whenever it is not loaded. - * - * @since 1.21 - */ - protected function checkPHPExtension( $extName ) { - $loaded = extension_loaded( $extName ); - if ( !$loaded ) { - $this->markTestSkipped( "PHP extension '$extName' is not loaded, skipping." ); - } - - return $loaded; - } - - /** - * Asserts that an exception of the specified type occurs when running - * the provided code. - * - * @since 1.21 - * @deprecated since 1.22 Use setExpectedException - * - * @param callable $code - * @param string $expected - * @param string $message - */ - protected function assertException( $code, $expected = 'Exception', $message = '' ) { - $pokemons = null; - - try { - call_user_func( $code ); - } catch ( Exception $pokemons ) { - // Gotta Catch 'Em All! - } - - if ( $message === '' ) { - $message = 'An exception of type "' . $expected . '" should have been thrown'; - } - - $this->assertInstanceOf( $expected, $pokemons, $message ); - } -} diff --git a/tests/phpunit/README b/tests/phpunit/README deleted file mode 100644 index 0a32ba17..00000000 --- a/tests/phpunit/README +++ /dev/null @@ -1,53 +0,0 @@ -== MediaWiki PHPUnit Tests == - -The unit tests for MediaWiki are implemented using the PHPUnit testing -framework and require PHPUnit to run. - - -=== WARNING === - -Some of the unit tests are DESTRUCTIVE and WILL ALTER YOUR WIKI'S CONTENTS. - -DO NOT RUN THESE TESTS ON A PRODUCTION SYSTEM OR ON ANY SYSTEM WHERE YOU NEED -TO RETAIN YOUR DATA. - - -== Installation == - -If PHPUnit is not installed, follow the installation instructions in the -PHPUnit Manual at: - - http://www.phpunit.de/manual/current/en/installation.html - -- or - - -On Unix-like operating systems, run: - - make install - - -== Running tests == - -The tests are run from your operating system's command line. - -Ensure that you are in the tests/phpunit directory of your MediaWiki -installation. - - -On Unix-like operating systems, the tests runs are controlled with a makefile. -Run command: - - make help - -for a full list of options for running tests. - - -On Windows-family operating systems, run the 'run-tests.bat' batch file. - - -=== Writing tests === - -A guide to writing unit tests for MediaWiki can be found at: - - http://mediawiki.org/wiki/Unit_Testing - diff --git a/tests/phpunit/TODO b/tests/phpunit/TODO deleted file mode 100644 index b2fa7fb6..00000000 --- a/tests/phpunit/TODO +++ /dev/null @@ -1,10 +0,0 @@ -== Things To Do == -* Most of the tests are named poorly; naming should describe a use case in story-like language, not simply identify the -unit under test. An example would be the difference between testCalculate and testAddingIntegersTogetherWorks. -* Many of the tests make multiple assertions, and are thus not unitary tests. By using data-providers and more use-case -oriented test selection nearly all of these cases can be easily resolved. -* Some of the test files are either incorrectly named or in the wrong folder. Tests should be organized in a mirrored -structure to the source they are testing, and named the same, with the exception of the word "Test" at the end. -* Shared set-up code or base classes are present, but usually named improperly or appear to be poorly factored. Support -code should share as much of the same naming as the code it's supporting, and test and test-case depenencies should be -considered to resolve other shared needs. diff --git a/tests/phpunit/bootstrap.php b/tests/phpunit/bootstrap.php deleted file mode 100644 index d929b79d..00000000 --- a/tests/phpunit/bootstrap.php +++ /dev/null @@ -1,15 +0,0 @@ -<?php -/** - * Bootstrapping for MediaWiki PHPUnit tests - * This file is included by phpunit and is NOT in the global scope. - * - * @file - */ - -if ( !defined( 'MW_PHPUNIT_TEST' ) ) { - echo <<<EOF -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"; -} diff --git a/tests/phpunit/data/db/mysql/functions.sql b/tests/phpunit/data/db/mysql/functions.sql deleted file mode 100644 index 9e5e470f..00000000 --- a/tests/phpunit/data/db/mysql/functions.sql +++ /dev/null @@ -1,12 +0,0 @@ --- MySQL test file for DatabaseTest::testStoredFunctions() - -DELIMITER // - -CREATE FUNCTION mw_test_function() -RETURNS int DETERMINISTIC -BEGIN - SET @foo = 21; - RETURN @foo * 2; -END// - -DELIMITER // diff --git a/tests/phpunit/data/db/postgres/functions.sql b/tests/phpunit/data/db/postgres/functions.sql deleted file mode 100644 index 3086d4d5..00000000 --- a/tests/phpunit/data/db/postgres/functions.sql +++ /dev/null @@ -1,12 +0,0 @@ --- Postgres test file for DatabaseTest::testStoredFunctions() - -CREATE FUNCTION mw_test_function() -RETURNS INTEGER -LANGUAGE plpgsql AS -$mw$ -DECLARE foo INTEGER; -BEGIN - foo := 21; - RETURN foo * 2; -END -$mw$; diff --git a/tests/phpunit/data/db/sqlite/tables-1.13.sql b/tests/phpunit/data/db/sqlite/tables-1.13.sql deleted file mode 100644 index 66847ab1..00000000 --- a/tests/phpunit/data/db/sqlite/tables-1.13.sql +++ /dev/null @@ -1,342 +0,0 @@ --- This is a copy of SQLite schema from MediaWiki 1.13 used for updater testing - -CREATE TABLE /*$wgDBprefix*/user ( - user_id INTEGER PRIMARY KEY AUTOINCREMENT, - user_name varchar(255) default '', - user_real_name varchar(255) default '', - user_password tinyblob , - user_newpassword tinyblob , - user_newpass_time BLOB, - user_email tinytext , - user_options blob , - user_touched BLOB default '', - user_token BLOB default '', - user_email_authenticated BLOB, - user_email_token BLOB, - user_email_token_expires BLOB, - user_registration BLOB, - user_editcount int) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/user_groups ( - ug_user INTEGER default '0', - ug_group varBLOB default '') /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/user_newtalk ( - user_id INTEGER default '0', - user_ip varBLOB default '', - user_last_timestamp BLOB default '') /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/page ( - page_id INTEGER PRIMARY KEY AUTOINCREMENT, - page_namespace INTEGER , - page_title varchar(255) , - page_restrictions tinyblob , - page_counter bigint default '0', - page_is_redirect tinyint default '0', - page_is_new tinyint default '0', - page_random real , - page_touched BLOB default '', - page_latest INTEGER , - page_len INTEGER ) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/revision ( - rev_id INTEGER PRIMARY KEY AUTOINCREMENT, - rev_page INTEGER , - rev_text_id INTEGER , - rev_comment tinyblob , - rev_user INTEGER default '0', - rev_user_text varchar(255) default '', - rev_timestamp BLOB default '', - rev_minor_edit tinyint default '0', - rev_deleted tinyint default '0', - rev_len int, - rev_parent_id INTEGER default NULL) /*$wgDBTableOptions*/ ; - -CREATE TABLE /*$wgDBprefix*/text ( - old_id INTEGER PRIMARY KEY AUTOINCREMENT, - old_text mediumblob , - old_flags tinyblob ) /*$wgDBTableOptions*/ ; - -CREATE TABLE /*$wgDBprefix*/archive ( - ar_namespace INTEGER default '0', - ar_title varchar(255) default '', - ar_text mediumblob , - ar_comment tinyblob , - ar_user INTEGER default '0', - ar_user_text varchar(255) , - ar_timestamp BLOB default '', - ar_minor_edit tinyint default '0', - ar_flags tinyblob , - ar_rev_id int, - ar_text_id int, - ar_deleted tinyint default '0', - ar_len int, - ar_page_id int, - ar_parent_id INTEGER default NULL) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/pagelinks ( - pl_from INTEGER default '0', - pl_namespace INTEGER default '0', - pl_title varchar(255) default '') /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/templatelinks ( - tl_from INTEGER default '0', - tl_namespace INTEGER default '0', - tl_title varchar(255) default '') /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/imagelinks ( - il_from INTEGER default '0', - il_to varchar(255) default '') /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/categorylinks ( - cl_from INTEGER default '0', - cl_to varchar(255) default '', - cl_sortkey varchar(70) default '', - cl_timestamp timestamp ) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/category ( - cat_id INTEGER PRIMARY KEY AUTOINCREMENT, - cat_title varchar(255) , - cat_pages INTEGER signed default 0, - cat_subcats INTEGER signed default 0, - cat_files INTEGER signed default 0, - cat_hidden tinyint default 0) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/externallinks ( - el_from INTEGER default '0', - el_to blob , - el_index blob ) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/langlinks ( - ll_from INTEGER default '0', - ll_lang varBLOB default '', - ll_title varchar(255) default '') /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/site_stats ( - ss_row_id INTEGER , - ss_total_views bigint default '0', - ss_total_edits bigint default '0', - ss_good_articles bigint default '0', - ss_total_pages bigint default '-1', - ss_users bigint default '-1', - ss_admins INTEGER default '-1', - ss_images INTEGER default '0') /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/hitcounter ( - hc_id INTEGER -) ; - -CREATE TABLE /*$wgDBprefix*/ipblocks ( - ipb_id INTEGER PRIMARY KEY AUTOINCREMENT, - ipb_address tinyblob , - ipb_user INTEGER default '0', - ipb_by INTEGER default '0', - ipb_by_text varchar(255) default '', - ipb_reason tinyblob , - ipb_timestamp BLOB default '', - ipb_auto bool default 0, - ipb_anon_only bool default 0, - ipb_create_account bool default 1, - ipb_enable_autoblock bool default '1', - ipb_expiry varBLOB default '', - ipb_range_start tinyblob , - ipb_range_end tinyblob , - ipb_deleted bool default 0, - ipb_block_email bool default 0) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/image ( - img_name varchar(255) default '', - img_size INTEGER default '0', - img_width INTEGER default '0', - img_height INTEGER default '0', - img_metadata mediumblob , - img_bits INTEGER default '0', - img_media_type TEXT default NULL, - img_major_mime TEXT default "unknown", - img_minor_mime varBLOB default "unknown", - img_description tinyblob , - img_user INTEGER default '0', - img_user_text varchar(255) , - img_timestamp varBLOB default '', - img_sha1 varBLOB default '') /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/oldimage ( - oi_name varchar(255) default '', - oi_archive_name varchar(255) default '', - oi_size INTEGER default 0, - oi_width INTEGER default 0, - oi_height INTEGER default 0, - oi_bits INTEGER default 0, - oi_description tinyblob , - oi_user INTEGER default '0', - oi_user_text varchar(255) , - oi_timestamp BLOB default '', - oi_metadata mediumblob , - oi_media_type TEXT default NULL, - oi_major_mime TEXT default "unknown", - oi_minor_mime varBLOB default "unknown", - oi_deleted tinyint default '0', - oi_sha1 varBLOB default '') /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/filearchive ( - fa_id INTEGER PRIMARY KEY AUTOINCREMENT, - fa_name varchar(255) default '', - fa_archive_name varchar(255) default '', - fa_storage_group varBLOB, - fa_storage_key varBLOB default '', - fa_deleted_user int, - fa_deleted_timestamp BLOB default '', - fa_deleted_reason text, - fa_size INTEGER default '0', - fa_width INTEGER default '0', - fa_height INTEGER default '0', - fa_metadata mediumblob, - fa_bits INTEGER default '0', - fa_media_type TEXT default NULL, - fa_major_mime TEXT default "unknown", - fa_minor_mime varBLOB default "unknown", - fa_description tinyblob, - fa_user INTEGER default '0', - fa_user_text varchar(255) , - fa_timestamp BLOB default '', - fa_deleted tinyint default '0') /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/recentchanges ( - rc_id INTEGER PRIMARY KEY AUTOINCREMENT, - rc_timestamp varBLOB default '', - rc_cur_time varBLOB default '', - rc_user INTEGER default '0', - rc_user_text varchar(255) , - rc_namespace INTEGER default '0', - rc_title varchar(255) default '', - rc_comment varchar(255) default '', - rc_minor tinyint default '0', - rc_bot tinyint default '0', - rc_new tinyint default '0', - rc_cur_id INTEGER default '0', - rc_this_oldid INTEGER default '0', - rc_last_oldid INTEGER default '0', - rc_type tinyint default '0', - rc_moved_to_ns tinyint default '0', - rc_moved_to_title varchar(255) default '', - rc_patrolled tinyint default '0', - rc_ip varBLOB default '', - rc_old_len int, - rc_new_len int, - rc_deleted tinyint default '0', - rc_logid INTEGER default '0', - rc_log_type varBLOB NULL default NULL, - rc_log_action varBLOB NULL default NULL, - rc_params blob NULL) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/watchlist ( - wl_user INTEGER , - wl_namespace INTEGER default '0', - wl_title varchar(255) default '', - wl_notificationtimestamp varBLOB) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/math ( - math_inputhash varBLOB , - math_outputhash varBLOB , - math_html_conservativeness tinyint , - math_html text, - math_mathml text) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/searchindex ( - si_page INTEGER , - si_title varchar(255) default '', - si_text mediumtext ) ; - -CREATE TABLE /*$wgDBprefix*/interwiki ( - iw_prefix varchar(32) , - iw_url blob , - iw_local bool , - iw_trans tinyint default 0) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/querycache ( - qc_type varBLOB , - qc_value INTEGER default '0', - qc_namespace INTEGER default '0', - qc_title varchar(255) default '') /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/objectcache ( - keyname varBLOB default '', - value mediumblob, - exptime datetime) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/transcache ( - tc_url varBLOB , - tc_contents text, - tc_time INTEGER ) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/logging ( - log_id INTEGER PRIMARY KEY AUTOINCREMENT, - log_type varBLOB default '', - log_action varBLOB default '', - log_timestamp BLOB default '19700101000000', - log_user INTEGER default 0, - log_namespace INTEGER default 0, - log_title varchar(255) default '', - log_comment varchar(255) default '', - log_params blob , - log_deleted tinyint default '0') /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/trackbacks ( - tb_id INTEGER PRIMARY KEY AUTOINCREMENT, - tb_page INTEGER REFERENCES /*$wgDBprefix*/page(page_id) ON DELETE CASCADE, - tb_title varchar(255) , - tb_url blob , - tb_ex text, - tb_name varchar(255)) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/job ( - job_id INTEGER PRIMARY KEY AUTOINCREMENT, - job_cmd varBLOB default '', - job_namespace INTEGER , - job_title varchar(255) , - job_params blob ) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/querycache_info ( - qci_type varBLOB default '', - qci_timestamp BLOB default '19700101000000') /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/redirect ( - rd_from INTEGER default '0', - rd_namespace INTEGER default '0', - rd_title varchar(255) default '') /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/querycachetwo ( - qcc_type varBLOB , - qcc_value INTEGER default '0', - qcc_namespace INTEGER default '0', - qcc_title varchar(255) default '', - qcc_namespacetwo INTEGER default '0', - qcc_titletwo varchar(255) default '') /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/page_restrictions ( - pr_page INTEGER , - pr_type varBLOB , - pr_level varBLOB , - pr_cascade tinyint , - pr_user INTEGER NULL, - pr_expiry varBLOB NULL, - pr_id INTEGER PRIMARY KEY AUTOINCREMENT) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/protected_titles ( - pt_namespace INTEGER , - pt_title varchar(255) , - pt_user INTEGER , - pt_reason tinyblob, - pt_timestamp BLOB , - pt_expiry varBLOB default '', - pt_create_perm varBLOB ) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/page_props ( - pp_page INTEGER , - pp_propname varBLOB , - pp_value blob ) /*$wgDBTableOptions*/; - -CREATE TABLE /*$wgDBprefix*/updatelog ( - ul_key varchar(255) ) /*$wgDBTableOptions*/; - - diff --git a/tests/phpunit/data/db/sqlite/tables-1.15.sql b/tests/phpunit/data/db/sqlite/tables-1.15.sql deleted file mode 100644 index 6b3a628e..00000000 --- a/tests/phpunit/data/db/sqlite/tables-1.15.sql +++ /dev/null @@ -1,454 +0,0 @@ --- This is a copy of MediaWiki 1.15 schema shared by MySQL and SQLite. --- It is used for updater testing. Comments are stripped to decrease --- file size, as we don't need to maintain it. - -CREATE TABLE /*_*/user ( - user_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - user_name varchar(255) binary NOT NULL default '', - user_real_name varchar(255) binary NOT NULL default '', - user_password tinyblob NOT NULL, - user_newpassword tinyblob NOT NULL, - user_newpass_time binary(14), - user_email tinytext NOT NULL, - user_options blob NOT NULL, - user_touched binary(14) NOT NULL default '', - user_token binary(32) NOT NULL default '', - user_email_authenticated binary(14), - user_email_token binary(32), - user_email_token_expires binary(14), - user_registration binary(14), - user_editcount int -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/user_name ON /*_*/user (user_name); -CREATE INDEX /*i*/user_email_token ON /*_*/user (user_email_token); -CREATE TABLE /*_*/user_groups ( - ug_user int unsigned NOT NULL default 0, - ug_group varbinary(16) NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ug_user_group ON /*_*/user_groups (ug_user,ug_group); -CREATE INDEX /*i*/ug_group ON /*_*/user_groups (ug_group); -CREATE TABLE /*_*/user_newtalk ( - user_id int NOT NULL default 0, - user_ip varbinary(40) NOT NULL default '', - user_last_timestamp binary(14) NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/un_user_id ON /*_*/user_newtalk (user_id); -CREATE INDEX /*i*/un_user_ip ON /*_*/user_newtalk (user_ip); -CREATE TABLE /*_*/page ( - page_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - page_namespace int NOT NULL, - page_title varchar(255) binary NOT NULL, - page_restrictions tinyblob NOT NULL, - page_counter bigint unsigned NOT NULL default 0, - page_is_redirect tinyint unsigned NOT NULL default 0, - page_is_new tinyint unsigned NOT NULL default 0, - page_random real unsigned NOT NULL, - page_touched binary(14) NOT NULL default '', - page_latest int unsigned NOT NULL, - page_len int unsigned NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/name_title ON /*_*/page (page_namespace,page_title); -CREATE INDEX /*i*/page_random ON /*_*/page (page_random); -CREATE INDEX /*i*/page_len ON /*_*/page (page_len); -CREATE TABLE /*_*/revision ( - rev_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - rev_page int unsigned NOT NULL, - rev_text_id int unsigned NOT NULL, - rev_comment tinyblob NOT NULL, - rev_user int unsigned NOT NULL default 0, - rev_user_text varchar(255) binary NOT NULL default '', - rev_timestamp binary(14) NOT NULL default '', - rev_minor_edit tinyint unsigned NOT NULL default 0, - rev_deleted tinyint unsigned NOT NULL default 0, - rev_len int unsigned, - rev_parent_id int unsigned default NULL -) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=1024; -CREATE UNIQUE INDEX /*i*/rev_page_id ON /*_*/revision (rev_page, rev_id); -CREATE INDEX /*i*/rev_timestamp ON /*_*/revision (rev_timestamp); -CREATE INDEX /*i*/page_timestamp ON /*_*/revision (rev_page,rev_timestamp); -CREATE INDEX /*i*/user_timestamp ON /*_*/revision (rev_user,rev_timestamp); -CREATE INDEX /*i*/usertext_timestamp ON /*_*/revision (rev_user_text,rev_timestamp); -CREATE TABLE /*_*/text ( - old_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - old_text mediumblob NOT NULL, - old_flags tinyblob NOT NULL -) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=10240; -CREATE TABLE /*_*/archive ( - ar_namespace int NOT NULL default 0, - ar_title varchar(255) binary NOT NULL default '', - ar_text mediumblob NOT NULL, - ar_comment tinyblob NOT NULL, - ar_user int unsigned NOT NULL default 0, - ar_user_text varchar(255) binary NOT NULL, - ar_timestamp binary(14) NOT NULL default '', - ar_minor_edit tinyint NOT NULL default 0, - ar_flags tinyblob NOT NULL, - ar_rev_id int unsigned, - ar_text_id int unsigned, - ar_deleted tinyint unsigned NOT NULL default 0, - ar_len int unsigned, - ar_page_id int unsigned, - ar_parent_id int unsigned default NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp); -CREATE INDEX /*i*/ar_usertext_timestamp ON /*_*/archive (ar_user_text,ar_timestamp); -CREATE TABLE /*_*/pagelinks ( - pl_from int unsigned NOT NULL default 0, - pl_namespace int NOT NULL default 0, - pl_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/pl_from ON /*_*/pagelinks (pl_from,pl_namespace,pl_title); -CREATE UNIQUE INDEX /*i*/pl_namespace ON /*_*/pagelinks (pl_namespace,pl_title,pl_from); -CREATE TABLE /*_*/templatelinks ( - tl_from int unsigned NOT NULL default 0, - tl_namespace int NOT NULL default 0, - tl_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/tl_from ON /*_*/templatelinks (tl_from,tl_namespace,tl_title); -CREATE UNIQUE INDEX /*i*/tl_namespace ON /*_*/templatelinks (tl_namespace,tl_title,tl_from); -CREATE TABLE /*_*/imagelinks ( - il_from int unsigned NOT NULL default 0, - il_to varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/il_from ON /*_*/imagelinks (il_from,il_to); -CREATE UNIQUE INDEX /*i*/il_to ON /*_*/imagelinks (il_to,il_from); -CREATE TABLE /*_*/categorylinks ( - cl_from int unsigned NOT NULL default 0, - cl_to varchar(255) binary NOT NULL default '', - cl_sortkey varchar(70) binary NOT NULL default '', - cl_timestamp timestamp NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/cl_from ON /*_*/categorylinks (cl_from,cl_to); -CREATE INDEX /*i*/cl_sortkey ON /*_*/categorylinks (cl_to,cl_sortkey,cl_from); -CREATE INDEX /*i*/cl_timestamp ON /*_*/categorylinks (cl_to,cl_timestamp); -CREATE TABLE /*_*/category ( - cat_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - cat_title varchar(255) binary NOT NULL, - cat_pages int signed NOT NULL default 0, - cat_subcats int signed NOT NULL default 0, - cat_files int signed NOT NULL default 0, - cat_hidden tinyint unsigned NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/cat_title ON /*_*/category (cat_title); -CREATE INDEX /*i*/cat_pages ON /*_*/category (cat_pages); -CREATE TABLE /*_*/externallinks ( - el_from int unsigned NOT NULL default 0, - el_to blob NOT NULL, - el_index blob NOT NULL -) /*$wgDBTableOptions*/; -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 /*_*/langlinks ( - ll_from int unsigned NOT NULL default 0, - - ll_lang varbinary(20) NOT NULL default '', - ll_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ll_from ON /*_*/langlinks (ll_from, ll_lang); -CREATE INDEX /*i*/ll_lang ON /*_*/langlinks (ll_lang, ll_title); -CREATE TABLE /*_*/site_stats ( - ss_row_id int unsigned NOT NULL, - ss_total_views bigint unsigned default 0, - ss_total_edits bigint unsigned default 0, - ss_good_articles bigint unsigned default 0, - ss_total_pages bigint default '-1', - ss_users bigint default '-1', - ss_active_users bigint default '-1', - ss_admins int default '-1', - ss_images int default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ss_row_id ON /*_*/site_stats (ss_row_id); -CREATE TABLE /*_*/hitcounter ( - hc_id int unsigned NOT NULL -) ENGINE=HEAP MAX_ROWS=25000; -CREATE TABLE /*_*/ipblocks ( - ipb_id int NOT NULL PRIMARY KEY AUTO_INCREMENT, - ipb_address tinyblob NOT NULL, - ipb_user int unsigned NOT NULL default 0, - ipb_by int unsigned NOT NULL default 0, - ipb_by_text varchar(255) binary NOT NULL default '', - ipb_reason tinyblob NOT NULL, - ipb_timestamp binary(14) NOT NULL default '', - ipb_auto bool NOT NULL default 0, - ipb_anon_only bool NOT NULL default 0, - ipb_create_account bool NOT NULL default 1, - ipb_enable_autoblock bool 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 bool NOT NULL default 0, - ipb_block_email bool NOT NULL default 0, - ipb_allow_usertalk bool NOT NULL default 0 -) /*$wgDBTableOptions*/; - -CREATE UNIQUE INDEX /*i*/ipb_address ON /*_*/ipblocks (ipb_address(255), ipb_user, ipb_auto, ipb_anon_only); -CREATE INDEX /*i*/ipb_user ON /*_*/ipblocks (ipb_user); -CREATE INDEX /*i*/ipb_range ON /*_*/ipblocks (ipb_range_start(8), ipb_range_end(8)); -CREATE INDEX /*i*/ipb_timestamp ON /*_*/ipblocks (ipb_timestamp); -CREATE INDEX /*i*/ipb_expiry ON /*_*/ipblocks (ipb_expiry); -CREATE TABLE /*_*/image ( - img_name varchar(255) binary NOT NULL default '' PRIMARY KEY, - img_size int unsigned NOT NULL default 0, - img_width int NOT NULL default 0, - img_height int NOT NULL default 0, - img_metadata mediumblob NOT NULL, - img_bits int 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(32) NOT NULL default "unknown", - img_description tinyblob NOT NULL, - img_user int unsigned NOT NULL default 0, - img_user_text varchar(255) binary NOT NULL, - img_timestamp varbinary(14) NOT NULL default '', - img_sha1 varbinary(32) NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/img_usertext_timestamp ON /*_*/image (img_user_text,img_timestamp); -CREATE INDEX /*i*/img_size ON /*_*/image (img_size); -CREATE INDEX /*i*/img_timestamp ON /*_*/image (img_timestamp); -CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1); -CREATE TABLE /*_*/oldimage ( - oi_name varchar(255) binary NOT NULL default '', - oi_archive_name varchar(255) binary NOT NULL default '', - oi_size int unsigned NOT NULL default 0, - oi_width int NOT NULL default 0, - oi_height int NOT NULL default 0, - oi_bits int NOT NULL default 0, - oi_description tinyblob NOT NULL, - oi_user int unsigned NOT NULL default 0, - oi_user_text varchar(255) binary NOT NULL, - oi_timestamp binary(14) NOT NULL default '', - 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(32) NOT NULL default "unknown", - oi_deleted tinyint unsigned NOT NULL default 0, - oi_sha1 varbinary(32) NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/oi_usertext_timestamp ON /*_*/oldimage (oi_user_text,oi_timestamp); -CREATE INDEX /*i*/oi_name_timestamp ON /*_*/oldimage (oi_name,oi_timestamp); -CREATE INDEX /*i*/oi_name_archive_name ON /*_*/oldimage (oi_name,oi_archive_name(14)); -CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1); -CREATE TABLE /*_*/filearchive ( - fa_id int NOT NULL PRIMARY KEY AUTO_INCREMENT, - fa_name varchar(255) binary NOT NULL default '', - fa_archive_name varchar(255) binary default '', - fa_storage_group varbinary(16), - fa_storage_key varbinary(64) default '', - fa_deleted_user int, - fa_deleted_timestamp binary(14) default '', - fa_deleted_reason text, - fa_size int unsigned default 0, - fa_width int default 0, - fa_height int default 0, - fa_metadata mediumblob, - fa_bits int 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(32) default "unknown", - fa_description tinyblob, - fa_user int unsigned default 0, - fa_user_text varchar(255) binary, - fa_timestamp binary(14) default '', - fa_deleted tinyint unsigned NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/fa_name ON /*_*/filearchive (fa_name, fa_timestamp); -CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_storage_key); -CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp); -CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp); -CREATE TABLE /*_*/recentchanges ( - rc_id int NOT NULL PRIMARY KEY AUTO_INCREMENT, - rc_timestamp varbinary(14) NOT NULL default '', - rc_cur_time varbinary(14) NOT NULL default '', - rc_user int unsigned NOT NULL default 0, - rc_user_text varchar(255) binary NOT NULL, - rc_namespace int NOT NULL default 0, - rc_title varchar(255) binary NOT NULL default '', - rc_comment varchar(255) binary NOT NULL default '', - rc_minor tinyint unsigned NOT NULL default 0, - rc_bot tinyint unsigned NOT NULL default 0, - rc_new tinyint unsigned NOT NULL default 0, - rc_cur_id int unsigned NOT NULL default 0, - rc_this_oldid int unsigned NOT NULL default 0, - rc_last_oldid int unsigned NOT NULL default 0, - rc_type tinyint unsigned NOT NULL default 0, - rc_moved_to_ns tinyint unsigned NOT NULL default 0, - rc_moved_to_title varchar(255) binary NOT NULL default '', - rc_patrolled tinyint unsigned NOT NULL default 0, - rc_ip varbinary(40) NOT NULL default '', - rc_old_len int, - rc_new_len int, - rc_deleted tinyint unsigned NOT NULL default 0, - rc_logid int unsigned NOT NULL default 0, - rc_log_type varbinary(255) NULL default NULL, - rc_log_action varbinary(255) NULL default NULL, - rc_params blob NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/rc_timestamp ON /*_*/recentchanges (rc_timestamp); -CREATE INDEX /*i*/rc_namespace_title ON /*_*/recentchanges (rc_namespace, rc_title); -CREATE INDEX /*i*/rc_cur_id ON /*_*/recentchanges (rc_cur_id); -CREATE INDEX /*i*/new_name_timestamp ON /*_*/recentchanges (rc_new,rc_namespace,rc_timestamp); -CREATE INDEX /*i*/rc_ip ON /*_*/recentchanges (rc_ip); -CREATE INDEX /*i*/rc_ns_usertext ON /*_*/recentchanges (rc_namespace, rc_user_text); -CREATE INDEX /*i*/rc_user_text ON /*_*/recentchanges (rc_user_text, rc_timestamp); -CREATE TABLE /*_*/watchlist ( - wl_user int unsigned NOT NULL, - wl_namespace int NOT NULL default 0, - wl_title varchar(255) binary NOT NULL default '', - wl_notificationtimestamp varbinary(14) -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/wl_user ON /*_*/watchlist (wl_user, wl_namespace, wl_title); -CREATE INDEX /*i*/namespace_title ON /*_*/watchlist (wl_namespace, wl_title); -CREATE TABLE /*_*/math ( - math_inputhash varbinary(16) NOT NULL, - math_outputhash varbinary(16) NOT NULL, - math_html_conservativeness tinyint NOT NULL, - math_html text, - math_mathml text -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/math_inputhash ON /*_*/math (math_inputhash); -CREATE TABLE /*_*/searchindex ( - si_page int unsigned NOT NULL, - si_title varchar(255) NOT NULL default '', - si_text mediumtext NOT NULL -) ENGINE=MyISAM; -CREATE UNIQUE INDEX /*i*/si_page ON /*_*/searchindex (si_page); -CREATE FULLTEXT INDEX /*i*/si_title ON /*_*/searchindex (si_title); -CREATE FULLTEXT INDEX /*i*/si_text ON /*_*/searchindex (si_text); -CREATE TABLE /*_*/interwiki ( - iw_prefix varchar(32) NOT NULL, - iw_url blob NOT NULL, - iw_local bool NOT NULL, - iw_trans tinyint NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/iw_prefix ON /*_*/interwiki (iw_prefix); -CREATE TABLE /*_*/querycache ( - qc_type varbinary(32) NOT NULL, - qc_value int unsigned NOT NULL default 0, - qc_namespace int NOT NULL default 0, - qc_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/qc_type ON /*_*/querycache (qc_type,qc_value); -CREATE TABLE /*_*/objectcache ( - keyname varbinary(255) NOT NULL default '' PRIMARY KEY, - value mediumblob, - exptime datetime -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/exptime ON /*_*/objectcache (exptime); -CREATE TABLE /*_*/transcache ( - tc_url varbinary(255) NOT NULL, - tc_contents text, - tc_time int NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/tc_url_idx ON /*_*/transcache (tc_url); -CREATE TABLE /*_*/logging ( - log_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - log_type varbinary(10) NOT NULL default '', - log_action varbinary(10) NOT NULL default '', - log_timestamp binary(14) NOT NULL default '19700101000000', - log_user int unsigned NOT NULL default 0, - log_namespace int NOT NULL default 0, - log_title varchar(255) binary NOT NULL default '', - log_comment varchar(255) NOT NULL default '', - log_params blob NOT NULL, - log_deleted tinyint unsigned NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/type_time ON /*_*/logging (log_type, log_timestamp); -CREATE INDEX /*i*/user_time ON /*_*/logging (log_user, log_timestamp); -CREATE INDEX /*i*/page_time ON /*_*/logging (log_namespace, log_title, log_timestamp); -CREATE INDEX /*i*/times ON /*_*/logging (log_timestamp); -CREATE TABLE /*_*/trackbacks ( - tb_id int PRIMARY KEY AUTO_INCREMENT, - tb_page int REFERENCES /*_*/page(page_id) ON DELETE CASCADE, - tb_title varchar(255) NOT NULL, - tb_url blob NOT NULL, - tb_ex text, - tb_name varchar(255) -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/tb_page ON /*_*/trackbacks (tb_page); -CREATE TABLE /*_*/job ( - job_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - job_cmd varbinary(60) NOT NULL default '', - job_namespace int NOT NULL, - job_title varchar(255) binary NOT NULL, - job_params blob NOT NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/job_cmd ON /*_*/job (job_cmd, job_namespace, job_title); -CREATE TABLE /*_*/querycache_info ( - qci_type varbinary(32) NOT NULL default '', - qci_timestamp binary(14) NOT NULL default '19700101000000' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/qci_type ON /*_*/querycache_info (qci_type); -CREATE TABLE /*_*/redirect ( - rd_from int unsigned NOT NULL default 0 PRIMARY KEY, - rd_namespace int NOT NULL default 0, - rd_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/rd_ns_title ON /*_*/redirect (rd_namespace,rd_title,rd_from); -CREATE TABLE /*_*/querycachetwo ( - qcc_type varbinary(32) NOT NULL, - qcc_value int unsigned NOT NULL default 0, - qcc_namespace int NOT NULL default 0, - qcc_title varchar(255) binary NOT NULL default '', - qcc_namespacetwo int NOT NULL default 0, - qcc_titletwo varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/qcc_type ON /*_*/querycachetwo (qcc_type,qcc_value); -CREATE INDEX /*i*/qcc_title ON /*_*/querycachetwo (qcc_type,qcc_namespace,qcc_title); -CREATE INDEX /*i*/qcc_titletwo ON /*_*/querycachetwo (qcc_type,qcc_namespacetwo,qcc_titletwo); -CREATE TABLE /*_*/page_restrictions ( - pr_page int NOT NULL, - pr_type varbinary(60) NOT NULL, - pr_level varbinary(60) NOT NULL, - pr_cascade tinyint NOT NULL, - pr_user int NULL, - pr_expiry varbinary(14) NULL, - pr_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/pr_pagetype ON /*_*/page_restrictions (pr_page,pr_type); -CREATE INDEX /*i*/pr_typelevel ON /*_*/page_restrictions (pr_type,pr_level); -CREATE INDEX /*i*/pr_level ON /*_*/page_restrictions (pr_level); -CREATE INDEX /*i*/pr_cascade ON /*_*/page_restrictions (pr_cascade); -CREATE TABLE /*_*/protected_titles ( - pt_namespace int NOT NULL, - pt_title varchar(255) binary NOT NULL, - pt_user int 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 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/pt_namespace_title ON /*_*/protected_titles (pt_namespace,pt_title); -CREATE INDEX /*i*/pt_timestamp ON /*_*/protected_titles (pt_timestamp); -CREATE TABLE /*_*/page_props ( - pp_page int NOT NULL, - pp_propname varbinary(60) NOT NULL, - pp_value blob NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/pp_page_propname ON /*_*/page_props (pp_page,pp_propname); -CREATE TABLE /*_*/updatelog ( - ul_key varchar(255) NOT NULL PRIMARY KEY -) /*$wgDBTableOptions*/; -CREATE TABLE /*_*/change_tag ( - ct_rc_id int NULL, - ct_log_id int NULL, - ct_rev_id int NULL, - ct_tag varchar(255) NOT NULL, - ct_params blob NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/change_tag_rc_tag ON /*_*/change_tag (ct_rc_id,ct_tag); -CREATE UNIQUE INDEX /*i*/change_tag_log_tag ON /*_*/change_tag (ct_log_id,ct_tag); -CREATE UNIQUE INDEX /*i*/change_tag_rev_tag ON /*_*/change_tag (ct_rev_id,ct_tag); -CREATE INDEX /*i*/change_tag_tag_id ON /*_*/change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id); -CREATE TABLE /*_*/tag_summary ( - ts_rc_id int NULL, - ts_log_id int NULL, - ts_rev_id int NULL, - ts_tags blob NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/tag_summary_rc_id ON /*_*/tag_summary (ts_rc_id); -CREATE UNIQUE INDEX /*i*/tag_summary_log_id ON /*_*/tag_summary (ts_log_id); -CREATE UNIQUE INDEX /*i*/tag_summary_rev_id ON /*_*/tag_summary (ts_rev_id); -CREATE TABLE /*_*/valid_tag ( - vt_tag varchar(255) NOT NULL PRIMARY KEY -) /*$wgDBTableOptions*/; diff --git a/tests/phpunit/data/db/sqlite/tables-1.16.sql b/tests/phpunit/data/db/sqlite/tables-1.16.sql deleted file mode 100644 index 7e8f30ec..00000000 --- a/tests/phpunit/data/db/sqlite/tables-1.16.sql +++ /dev/null @@ -1,478 +0,0 @@ --- This is a copy of MediaWiki 1.16 schema shared by MySQL and SQLite. --- It is used for updater testing. Comments are stripped to decrease --- file size, as we don't need to maintain it. - -CREATE TABLE /*_*/user ( - user_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - user_name varchar(255) binary NOT NULL default '', - user_real_name varchar(255) binary NOT NULL default '', - user_password tinyblob NOT NULL, - user_newpassword tinyblob NOT NULL, - user_newpass_time binary(14), - user_email tinytext NOT NULL, - user_options blob NOT NULL, - user_touched binary(14) NOT NULL default '', - user_token binary(32) NOT NULL default '', - user_email_authenticated binary(14), - user_email_token binary(32), - user_email_token_expires binary(14), - user_registration binary(14), - user_editcount int -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/user_name ON /*_*/user (user_name); -CREATE INDEX /*i*/user_email_token ON /*_*/user (user_email_token); -CREATE TABLE /*_*/user_groups ( - ug_user int unsigned NOT NULL default 0, - ug_group varbinary(16) NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ug_user_group ON /*_*/user_groups (ug_user,ug_group); -CREATE INDEX /*i*/ug_group ON /*_*/user_groups (ug_group); -CREATE TABLE /*_*/user_newtalk ( - user_id int NOT NULL default 0, - user_ip varbinary(40) NOT NULL default '', - user_last_timestamp binary(14) NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/un_user_id ON /*_*/user_newtalk (user_id); -CREATE INDEX /*i*/un_user_ip ON /*_*/user_newtalk (user_ip); -CREATE TABLE /*_*/user_properties ( - up_user int NOT NULL, - up_property varbinary(32) NOT NULL, - up_value blob -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/user_properties_user_property ON /*_*/user_properties (up_user,up_property); -CREATE INDEX /*i*/user_properties_property ON /*_*/user_properties (up_property); -CREATE TABLE /*_*/page ( - page_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - page_namespace int NOT NULL, - page_title varchar(255) binary NOT NULL, - page_restrictions tinyblob NOT NULL, - page_counter bigint unsigned NOT NULL default 0, - page_is_redirect tinyint unsigned NOT NULL default 0, - page_is_new tinyint unsigned NOT NULL default 0, - page_random real unsigned NOT NULL, - page_touched binary(14) NOT NULL default '', - page_latest int unsigned NOT NULL, - page_len int unsigned NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/name_title ON /*_*/page (page_namespace,page_title); -CREATE INDEX /*i*/page_random ON /*_*/page (page_random); -CREATE INDEX /*i*/page_len ON /*_*/page (page_len); -CREATE TABLE /*_*/revision ( - rev_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - rev_page int unsigned NOT NULL, - rev_text_id int unsigned NOT NULL, - rev_comment tinyblob NOT NULL, - rev_user int unsigned NOT NULL default 0, - rev_user_text varchar(255) binary NOT NULL default '', - rev_timestamp binary(14) NOT NULL default '', - rev_minor_edit tinyint unsigned NOT NULL default 0, - rev_deleted tinyint unsigned NOT NULL default 0, - rev_len int unsigned, - rev_parent_id int unsigned default NULL -) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=1024; -CREATE UNIQUE INDEX /*i*/rev_page_id ON /*_*/revision (rev_page, rev_id); -CREATE INDEX /*i*/rev_timestamp ON /*_*/revision (rev_timestamp); -CREATE INDEX /*i*/page_timestamp ON /*_*/revision (rev_page,rev_timestamp); -CREATE INDEX /*i*/user_timestamp ON /*_*/revision (rev_user,rev_timestamp); -CREATE INDEX /*i*/usertext_timestamp ON /*_*/revision (rev_user_text,rev_timestamp); -CREATE TABLE /*_*/text ( - old_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - old_text mediumblob NOT NULL, - old_flags tinyblob NOT NULL -) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=10240; -CREATE TABLE /*_*/archive ( - ar_namespace int NOT NULL default 0, - ar_title varchar(255) binary NOT NULL default '', - ar_text mediumblob NOT NULL, - ar_comment tinyblob NOT NULL, - ar_user int unsigned NOT NULL default 0, - ar_user_text varchar(255) binary NOT NULL, - ar_timestamp binary(14) NOT NULL default '', - ar_minor_edit tinyint NOT NULL default 0, - ar_flags tinyblob NOT NULL, - ar_rev_id int unsigned, - ar_text_id int unsigned, - ar_deleted tinyint unsigned NOT NULL default 0, - ar_len int unsigned, - ar_page_id int unsigned, - ar_parent_id int unsigned default NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp); -CREATE INDEX /*i*/ar_usertext_timestamp ON /*_*/archive (ar_user_text,ar_timestamp); -CREATE TABLE /*_*/pagelinks ( - pl_from int unsigned NOT NULL default 0, - pl_namespace int NOT NULL default 0, - pl_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/pl_from ON /*_*/pagelinks (pl_from,pl_namespace,pl_title); -CREATE UNIQUE INDEX /*i*/pl_namespace ON /*_*/pagelinks (pl_namespace,pl_title,pl_from); -CREATE TABLE /*_*/templatelinks ( - tl_from int unsigned NOT NULL default 0, - tl_namespace int NOT NULL default 0, - tl_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/tl_from ON /*_*/templatelinks (tl_from,tl_namespace,tl_title); -CREATE UNIQUE INDEX /*i*/tl_namespace ON /*_*/templatelinks (tl_namespace,tl_title,tl_from); -CREATE TABLE /*_*/imagelinks ( - il_from int unsigned NOT NULL default 0, - il_to varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/il_from ON /*_*/imagelinks (il_from,il_to); -CREATE UNIQUE INDEX /*i*/il_to ON /*_*/imagelinks (il_to,il_from); -CREATE TABLE /*_*/categorylinks ( - cl_from int unsigned NOT NULL default 0, - cl_to varchar(255) binary NOT NULL default '', - cl_sortkey varchar(70) binary NOT NULL default '', - cl_timestamp timestamp NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/cl_from ON /*_*/categorylinks (cl_from,cl_to); -CREATE INDEX /*i*/cl_sortkey ON /*_*/categorylinks (cl_to,cl_sortkey,cl_from); -CREATE INDEX /*i*/cl_timestamp ON /*_*/categorylinks (cl_to,cl_timestamp); -CREATE TABLE /*_*/category ( - cat_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - cat_title varchar(255) binary NOT NULL, - cat_pages int signed NOT NULL default 0, - cat_subcats int signed NOT NULL default 0, - cat_files int signed NOT NULL default 0, - cat_hidden tinyint unsigned NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/cat_title ON /*_*/category (cat_title); -CREATE INDEX /*i*/cat_pages ON /*_*/category (cat_pages); -CREATE TABLE /*_*/externallinks ( - el_from int unsigned NOT NULL default 0, - el_to blob NOT NULL, - el_index blob NOT NULL -) /*$wgDBTableOptions*/; -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 /*_*/langlinks ( - ll_from int unsigned NOT NULL default 0, - ll_lang varbinary(20) NOT NULL default '', - ll_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ll_from ON /*_*/langlinks (ll_from, ll_lang); -CREATE INDEX /*i*/ll_lang ON /*_*/langlinks (ll_lang, ll_title); -CREATE TABLE /*_*/site_stats ( - ss_row_id int unsigned NOT NULL, - ss_total_views bigint unsigned default 0, - ss_total_edits bigint unsigned default 0, - ss_good_articles bigint unsigned default 0, - ss_total_pages bigint default '-1', - ss_users bigint default '-1', - ss_active_users bigint default '-1', - ss_admins int default '-1', - ss_images int default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ss_row_id ON /*_*/site_stats (ss_row_id); -CREATE TABLE /*_*/hitcounter ( - hc_id int unsigned NOT NULL -) ENGINE=HEAP MAX_ROWS=25000; -CREATE TABLE /*_*/ipblocks ( - ipb_id int NOT NULL PRIMARY KEY AUTO_INCREMENT, - ipb_address tinyblob NOT NULL, - ipb_user int unsigned NOT NULL default 0, - ipb_by int unsigned NOT NULL default 0, - ipb_by_text varchar(255) binary NOT NULL default '', - ipb_reason tinyblob NOT NULL, - ipb_timestamp binary(14) NOT NULL default '', - ipb_auto bool NOT NULL default 0, - ipb_anon_only bool NOT NULL default 0, - ipb_create_account bool NOT NULL default 1, - ipb_enable_autoblock bool 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 bool NOT NULL default 0, - ipb_block_email bool NOT NULL default 0, - ipb_allow_usertalk bool NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ipb_address ON /*_*/ipblocks (ipb_address(255), ipb_user, ipb_auto, ipb_anon_only); -CREATE INDEX /*i*/ipb_user ON /*_*/ipblocks (ipb_user); -CREATE INDEX /*i*/ipb_range ON /*_*/ipblocks (ipb_range_start(8), ipb_range_end(8)); -CREATE INDEX /*i*/ipb_timestamp ON /*_*/ipblocks (ipb_timestamp); -CREATE INDEX /*i*/ipb_expiry ON /*_*/ipblocks (ipb_expiry); -CREATE TABLE /*_*/image ( - img_name varchar(255) binary NOT NULL default '' PRIMARY KEY, - img_size int unsigned NOT NULL default 0, - img_width int NOT NULL default 0, - img_height int NOT NULL default 0, - img_metadata mediumblob NOT NULL, - img_bits int 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 unsigned NOT NULL default 0, - img_user_text varchar(255) binary NOT NULL, - img_timestamp varbinary(14) NOT NULL default '', - img_sha1 varbinary(32) NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/img_usertext_timestamp ON /*_*/image (img_user_text,img_timestamp); -CREATE INDEX /*i*/img_size ON /*_*/image (img_size); -CREATE INDEX /*i*/img_timestamp ON /*_*/image (img_timestamp); -CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1); -CREATE TABLE /*_*/oldimage ( - oi_name varchar(255) binary NOT NULL default '', - oi_archive_name varchar(255) binary NOT NULL default '', - oi_size int unsigned NOT NULL default 0, - oi_width int NOT NULL default 0, - oi_height int NOT NULL default 0, - oi_bits int NOT NULL default 0, - oi_description tinyblob NOT NULL, - oi_user int unsigned NOT NULL default 0, - oi_user_text varchar(255) binary NOT NULL, - oi_timestamp binary(14) NOT NULL default '', - 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 unsigned NOT NULL default 0, - oi_sha1 varbinary(32) NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/oi_usertext_timestamp ON /*_*/oldimage (oi_user_text,oi_timestamp); -CREATE INDEX /*i*/oi_name_timestamp ON /*_*/oldimage (oi_name,oi_timestamp); -CREATE INDEX /*i*/oi_name_archive_name ON /*_*/oldimage (oi_name,oi_archive_name(14)); -CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1); -CREATE TABLE /*_*/filearchive ( - fa_id int NOT NULL PRIMARY KEY AUTO_INCREMENT, - fa_name varchar(255) binary NOT NULL default '', - fa_archive_name varchar(255) binary default '', - fa_storage_group varbinary(16), - fa_storage_key varbinary(64) default '', - fa_deleted_user int, - fa_deleted_timestamp binary(14) default '', - fa_deleted_reason text, - fa_size int unsigned default 0, - fa_width int default 0, - fa_height int default 0, - fa_metadata mediumblob, - fa_bits int 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 unsigned default 0, - fa_user_text varchar(255) binary, - fa_timestamp binary(14) default '', - fa_deleted tinyint unsigned NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/fa_name ON /*_*/filearchive (fa_name, fa_timestamp); -CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_storage_key); -CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp); -CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp); -CREATE TABLE /*_*/recentchanges ( - rc_id int NOT NULL PRIMARY KEY AUTO_INCREMENT, - rc_timestamp varbinary(14) NOT NULL default '', - rc_cur_time varbinary(14) NOT NULL default '', - rc_user int unsigned NOT NULL default 0, - rc_user_text varchar(255) binary NOT NULL, - rc_namespace int NOT NULL default 0, - rc_title varchar(255) binary NOT NULL default '', - rc_comment varchar(255) binary NOT NULL default '', - rc_minor tinyint unsigned NOT NULL default 0, - rc_bot tinyint unsigned NOT NULL default 0, - rc_new tinyint unsigned NOT NULL default 0, - rc_cur_id int unsigned NOT NULL default 0, - rc_this_oldid int unsigned NOT NULL default 0, - rc_last_oldid int unsigned NOT NULL default 0, - rc_type tinyint unsigned NOT NULL default 0, - rc_moved_to_ns tinyint unsigned NOT NULL default 0, - rc_moved_to_title varchar(255) binary NOT NULL default '', - rc_patrolled tinyint unsigned NOT NULL default 0, - rc_ip varbinary(40) NOT NULL default '', - rc_old_len int, - rc_new_len int, - rc_deleted tinyint unsigned NOT NULL default 0, - rc_logid int unsigned NOT NULL default 0, - rc_log_type varbinary(255) NULL default NULL, - rc_log_action varbinary(255) NULL default NULL, - rc_params blob NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/rc_timestamp ON /*_*/recentchanges (rc_timestamp); -CREATE INDEX /*i*/rc_namespace_title ON /*_*/recentchanges (rc_namespace, rc_title); -CREATE INDEX /*i*/rc_cur_id ON /*_*/recentchanges (rc_cur_id); -CREATE INDEX /*i*/new_name_timestamp ON /*_*/recentchanges (rc_new,rc_namespace,rc_timestamp); -CREATE INDEX /*i*/rc_ip ON /*_*/recentchanges (rc_ip); -CREATE INDEX /*i*/rc_ns_usertext ON /*_*/recentchanges (rc_namespace, rc_user_text); -CREATE INDEX /*i*/rc_user_text ON /*_*/recentchanges (rc_user_text, rc_timestamp); -CREATE TABLE /*_*/watchlist ( - wl_user int unsigned NOT NULL, - wl_namespace int NOT NULL default 0, - wl_title varchar(255) binary NOT NULL default '', - wl_notificationtimestamp varbinary(14) -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/wl_user ON /*_*/watchlist (wl_user, wl_namespace, wl_title); -CREATE INDEX /*i*/namespace_title ON /*_*/watchlist (wl_namespace, wl_title); -CREATE TABLE /*_*/math ( - math_inputhash varbinary(16) NOT NULL, - math_outputhash varbinary(16) NOT NULL, - math_html_conservativeness tinyint NOT NULL, - math_html text, - math_mathml text -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/math_inputhash ON /*_*/math (math_inputhash); -CREATE TABLE /*_*/searchindex ( - si_page int unsigned NOT NULL, - si_title varchar(255) NOT NULL default '', - si_text mediumtext NOT NULL -) ENGINE=MyISAM; -CREATE UNIQUE INDEX /*i*/si_page ON /*_*/searchindex (si_page); -CREATE FULLTEXT INDEX /*i*/si_title ON /*_*/searchindex (si_title); -CREATE FULLTEXT INDEX /*i*/si_text ON /*_*/searchindex (si_text); -CREATE TABLE /*_*/interwiki ( - iw_prefix varchar(32) NOT NULL, - iw_url blob NOT NULL, - iw_local bool NOT NULL, - iw_trans tinyint NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/iw_prefix ON /*_*/interwiki (iw_prefix); -CREATE TABLE /*_*/querycache ( - qc_type varbinary(32) NOT NULL, - qc_value int unsigned NOT NULL default 0, - qc_namespace int NOT NULL default 0, - qc_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/qc_type ON /*_*/querycache (qc_type,qc_value); -CREATE TABLE /*_*/objectcache ( - keyname varbinary(255) NOT NULL default '' PRIMARY KEY, - value mediumblob, - exptime datetime -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/exptime ON /*_*/objectcache (exptime); -CREATE TABLE /*_*/transcache ( - tc_url varbinary(255) NOT NULL, - tc_contents text, - tc_time binary(14) NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/tc_url_idx ON /*_*/transcache (tc_url); -CREATE TABLE /*_*/logging ( - log_id int unsigned NOT NULL PRIMARY KEY 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 unsigned NOT NULL default 0, - log_user_text varchar(255) binary NOT NULL default '', - log_namespace int NOT NULL default 0, - log_title varchar(255) binary NOT NULL default '', - log_page int unsigned NULL, - log_comment varchar(255) NOT NULL default '', - log_params blob NOT NULL, - log_deleted tinyint unsigned NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/type_time ON /*_*/logging (log_type, log_timestamp); -CREATE INDEX /*i*/user_time ON /*_*/logging (log_user, log_timestamp); -CREATE INDEX /*i*/page_time ON /*_*/logging (log_namespace, log_title, log_timestamp); -CREATE INDEX /*i*/times ON /*_*/logging (log_timestamp); -CREATE INDEX /*i*/log_user_type_time ON /*_*/logging (log_user, log_type, log_timestamp); -CREATE INDEX /*i*/log_page_id_time ON /*_*/logging (log_page,log_timestamp); -CREATE TABLE /*_*/log_search ( - ls_field varbinary(32) NOT NULL, - ls_value varchar(255) NOT NULL, - ls_log_id int unsigned NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ls_field_val ON /*_*/log_search (ls_field,ls_value,ls_log_id); -CREATE INDEX /*i*/ls_log_id ON /*_*/log_search (ls_log_id); -CREATE TABLE /*_*/trackbacks ( - tb_id int PRIMARY KEY AUTO_INCREMENT, - tb_page int REFERENCES /*_*/page(page_id) ON DELETE CASCADE, - tb_title varchar(255) NOT NULL, - tb_url blob NOT NULL, - tb_ex text, - tb_name varchar(255) -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/tb_page ON /*_*/trackbacks (tb_page); -CREATE TABLE /*_*/job ( - job_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - job_cmd varbinary(60) NOT NULL default '', - job_namespace int NOT NULL, - job_title varchar(255) binary NOT NULL, - job_params blob NOT NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/job_cmd ON /*_*/job (job_cmd, job_namespace, job_title, job_params(128)); -CREATE TABLE /*_*/querycache_info ( - qci_type varbinary(32) NOT NULL default '', - qci_timestamp binary(14) NOT NULL default '19700101000000' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/qci_type ON /*_*/querycache_info (qci_type); -CREATE TABLE /*_*/redirect ( - rd_from int unsigned NOT NULL default 0 PRIMARY KEY, - rd_namespace int NOT NULL default 0, - rd_title varchar(255) binary NOT NULL default '', - rd_interwiki varchar(32) default NULL, - rd_fragment varchar(255) binary default NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/rd_ns_title ON /*_*/redirect (rd_namespace,rd_title,rd_from); -CREATE TABLE /*_*/querycachetwo ( - qcc_type varbinary(32) NOT NULL, - qcc_value int unsigned NOT NULL default 0, - qcc_namespace int NOT NULL default 0, - qcc_title varchar(255) binary NOT NULL default '', - qcc_namespacetwo int NOT NULL default 0, - qcc_titletwo varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/qcc_type ON /*_*/querycachetwo (qcc_type,qcc_value); -CREATE INDEX /*i*/qcc_title ON /*_*/querycachetwo (qcc_type,qcc_namespace,qcc_title); -CREATE INDEX /*i*/qcc_titletwo ON /*_*/querycachetwo (qcc_type,qcc_namespacetwo,qcc_titletwo); -CREATE TABLE /*_*/page_restrictions ( - pr_page int NOT NULL, - pr_type varbinary(60) NOT NULL, - pr_level varbinary(60) NOT NULL, - pr_cascade tinyint NOT NULL, - pr_user int NULL, - pr_expiry varbinary(14) NULL, - pr_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/pr_pagetype ON /*_*/page_restrictions (pr_page,pr_type); -CREATE INDEX /*i*/pr_typelevel ON /*_*/page_restrictions (pr_type,pr_level); -CREATE INDEX /*i*/pr_level ON /*_*/page_restrictions (pr_level); -CREATE INDEX /*i*/pr_cascade ON /*_*/page_restrictions (pr_cascade); -CREATE TABLE /*_*/protected_titles ( - pt_namespace int NOT NULL, - pt_title varchar(255) binary NOT NULL, - pt_user int 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 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/pt_namespace_title ON /*_*/protected_titles (pt_namespace,pt_title); -CREATE INDEX /*i*/pt_timestamp ON /*_*/protected_titles (pt_timestamp); -CREATE TABLE /*_*/page_props ( - pp_page int NOT NULL, - pp_propname varbinary(60) NOT NULL, - pp_value blob NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/pp_page_propname ON /*_*/page_props (pp_page,pp_propname); -CREATE TABLE /*_*/updatelog ( - ul_key varchar(255) NOT NULL PRIMARY KEY -) /*$wgDBTableOptions*/; -CREATE TABLE /*_*/change_tag ( - ct_rc_id int NULL, - ct_log_id int NULL, - ct_rev_id int NULL, - ct_tag varchar(255) NOT NULL, - ct_params blob NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/change_tag_rc_tag ON /*_*/change_tag (ct_rc_id,ct_tag); -CREATE UNIQUE INDEX /*i*/change_tag_log_tag ON /*_*/change_tag (ct_log_id,ct_tag); -CREATE UNIQUE INDEX /*i*/change_tag_rev_tag ON /*_*/change_tag (ct_rev_id,ct_tag); -CREATE INDEX /*i*/change_tag_tag_id ON /*_*/change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id); -CREATE TABLE /*_*/tag_summary ( - ts_rc_id int NULL, - ts_log_id int NULL, - ts_rev_id int NULL, - ts_tags blob NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/tag_summary_rc_id ON /*_*/tag_summary (ts_rc_id); -CREATE UNIQUE INDEX /*i*/tag_summary_log_id ON /*_*/tag_summary (ts_log_id); -CREATE UNIQUE INDEX /*i*/tag_summary_rev_id ON /*_*/tag_summary (ts_rev_id); -CREATE TABLE /*_*/valid_tag ( - vt_tag varchar(255) NOT NULL PRIMARY KEY -) /*$wgDBTableOptions*/; -CREATE TABLE /*_*/l10n_cache ( - lc_lang varbinary(32) NOT NULL, - lc_key varchar(255) NOT NULL, - lc_value mediumblob NOT NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/lc_lang_key ON /*_*/l10n_cache (lc_lang, lc_key); diff --git a/tests/phpunit/data/db/sqlite/tables-1.17.sql b/tests/phpunit/data/db/sqlite/tables-1.17.sql deleted file mode 100644 index e02e3e14..00000000 --- a/tests/phpunit/data/db/sqlite/tables-1.17.sql +++ /dev/null @@ -1,511 +0,0 @@ --- This is a copy of MediaWiki 1.17 schema shared by MySQL and SQLite. --- It is used for updater testing. Comments are stripped to decrease --- file size, as we don't need to maintain it. - -CREATE TABLE /*_*/user ( - user_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - user_name varchar(255) binary NOT NULL default '', - user_real_name varchar(255) binary NOT NULL default '', - user_password tinyblob NOT NULL, - user_newpassword tinyblob NOT NULL, - user_newpass_time binary(14), - user_email tinytext NOT NULL, - user_options blob NOT NULL, - user_touched binary(14) NOT NULL default '', - user_token binary(32) NOT NULL default '', - user_email_authenticated binary(14), - user_email_token binary(32), - user_email_token_expires binary(14), - user_registration binary(14), - user_editcount int -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/user_name ON /*_*/user (user_name); -CREATE INDEX /*i*/user_email_token ON /*_*/user (user_email_token); -CREATE TABLE /*_*/user_groups ( - ug_user int unsigned NOT NULL default 0, - ug_group varbinary(16) NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ug_user_group ON /*_*/user_groups (ug_user,ug_group); -CREATE INDEX /*i*/ug_group ON /*_*/user_groups (ug_group); -CREATE TABLE /*_*/user_newtalk ( - user_id int NOT NULL default 0, - user_ip varbinary(40) NOT NULL default '', - user_last_timestamp binary(14) NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/un_user_id ON /*_*/user_newtalk (user_id); -CREATE INDEX /*i*/un_user_ip ON /*_*/user_newtalk (user_ip); -CREATE TABLE /*_*/user_properties ( - up_user int NOT NULL, - up_property varbinary(32) NOT NULL, - up_value blob -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/user_properties_user_property ON /*_*/user_properties (up_user,up_property); -CREATE INDEX /*i*/user_properties_property ON /*_*/user_properties (up_property); -CREATE TABLE /*_*/page ( - page_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - page_namespace int NOT NULL, - page_title varchar(255) binary NOT NULL, - page_restrictions tinyblob NOT NULL, - page_counter bigint unsigned NOT NULL default 0, - page_is_redirect tinyint unsigned NOT NULL default 0, - page_is_new tinyint unsigned NOT NULL default 0, - page_random real unsigned NOT NULL, - page_touched binary(14) NOT NULL default '', - page_latest int unsigned NOT NULL, - page_len int unsigned NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/name_title ON /*_*/page (page_namespace,page_title); -CREATE INDEX /*i*/page_random ON /*_*/page (page_random); -CREATE INDEX /*i*/page_len ON /*_*/page (page_len); -CREATE TABLE /*_*/revision ( - rev_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - rev_page int unsigned NOT NULL, - rev_text_id int unsigned NOT NULL, - rev_comment tinyblob NOT NULL, - rev_user int unsigned NOT NULL default 0, - rev_user_text varchar(255) binary NOT NULL default '', - rev_timestamp binary(14) NOT NULL default '', - rev_minor_edit tinyint unsigned NOT NULL default 0, - rev_deleted tinyint unsigned NOT NULL default 0, - rev_len int unsigned, - rev_parent_id int unsigned default NULL -) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=1024; -CREATE UNIQUE INDEX /*i*/rev_page_id ON /*_*/revision (rev_page, rev_id); -CREATE INDEX /*i*/rev_timestamp ON /*_*/revision (rev_timestamp); -CREATE INDEX /*i*/page_timestamp ON /*_*/revision (rev_page,rev_timestamp); -CREATE INDEX /*i*/user_timestamp ON /*_*/revision (rev_user,rev_timestamp); -CREATE INDEX /*i*/usertext_timestamp ON /*_*/revision (rev_user_text,rev_timestamp); -CREATE TABLE /*_*/text ( - old_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - old_text mediumblob NOT NULL, - old_flags tinyblob NOT NULL -) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=10240; -CREATE TABLE /*_*/archive ( - ar_namespace int NOT NULL default 0, - ar_title varchar(255) binary NOT NULL default '', - ar_text mediumblob NOT NULL, - ar_comment tinyblob NOT NULL, - ar_user int unsigned NOT NULL default 0, - ar_user_text varchar(255) binary NOT NULL, - ar_timestamp binary(14) NOT NULL default '', - ar_minor_edit tinyint NOT NULL default 0, - ar_flags tinyblob NOT NULL, - ar_rev_id int unsigned, - ar_text_id int unsigned, - ar_deleted tinyint unsigned NOT NULL default 0, - ar_len int unsigned, - ar_page_id int unsigned, - ar_parent_id int unsigned default NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp); -CREATE INDEX /*i*/ar_usertext_timestamp ON /*_*/archive (ar_user_text,ar_timestamp); -CREATE INDEX /*i*/ar_revid ON /*_*/archive (ar_rev_id); -CREATE TABLE /*_*/pagelinks ( - pl_from int unsigned NOT NULL default 0, - pl_namespace int NOT NULL default 0, - pl_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/pl_from ON /*_*/pagelinks (pl_from,pl_namespace,pl_title); -CREATE UNIQUE INDEX /*i*/pl_namespace ON /*_*/pagelinks (pl_namespace,pl_title,pl_from); -CREATE TABLE /*_*/templatelinks ( - tl_from int unsigned NOT NULL default 0, - tl_namespace int NOT NULL default 0, - tl_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/tl_from ON /*_*/templatelinks (tl_from,tl_namespace,tl_title); -CREATE UNIQUE INDEX /*i*/tl_namespace ON /*_*/templatelinks (tl_namespace,tl_title,tl_from); -CREATE TABLE /*_*/imagelinks ( - il_from int unsigned NOT NULL default 0, - il_to varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/il_from ON /*_*/imagelinks (il_from,il_to); -CREATE UNIQUE INDEX /*i*/il_to ON /*_*/imagelinks (il_to,il_from); -CREATE TABLE /*_*/categorylinks ( - cl_from int unsigned NOT NULL default 0, - cl_to varchar(255) binary NOT NULL default '', - cl_sortkey varbinary(230) NOT NULL default '', - cl_sortkey_prefix varchar(255) binary NOT NULL default '', - cl_timestamp timestamp NOT NULL, - cl_collation varbinary(32) NOT NULL default '', - cl_type ENUM('page', 'subcat', 'file') NOT NULL default 'page' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/cl_from ON /*_*/categorylinks (cl_from,cl_to); -CREATE INDEX /*i*/cl_sortkey ON /*_*/categorylinks (cl_to,cl_type,cl_sortkey,cl_from); -CREATE INDEX /*i*/cl_timestamp ON /*_*/categorylinks (cl_to,cl_timestamp); -CREATE INDEX /*i*/cl_collation ON /*_*/categorylinks (cl_collation); -CREATE TABLE /*_*/category ( - cat_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - cat_title varchar(255) binary NOT NULL, - cat_pages int signed NOT NULL default 0, - cat_subcats int signed NOT NULL default 0, - cat_files int signed NOT NULL default 0, - cat_hidden tinyint unsigned NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/cat_title ON /*_*/category (cat_title); -CREATE INDEX /*i*/cat_pages ON /*_*/category (cat_pages); -CREATE TABLE /*_*/externallinks ( - el_from int unsigned NOT NULL default 0, - el_to blob NOT NULL, - el_index blob NOT NULL -) /*$wgDBTableOptions*/; -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 /*_*/langlinks ( - ll_from int unsigned NOT NULL default 0, - ll_lang varbinary(20) NOT NULL default '', - ll_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ll_from ON /*_*/langlinks (ll_from, ll_lang); -CREATE INDEX /*i*/ll_lang ON /*_*/langlinks (ll_lang, ll_title); -CREATE TABLE /*_*/iwlinks ( - iwl_from int unsigned NOT NULL default 0, - iwl_prefix varbinary(20) NOT NULL default '', - iwl_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/iwl_from ON /*_*/iwlinks (iwl_from, iwl_prefix, iwl_title); -CREATE UNIQUE INDEX /*i*/iwl_prefix_title_from ON /*_*/iwlinks (iwl_prefix, iwl_title, iwl_from); -CREATE TABLE /*_*/site_stats ( - ss_row_id int unsigned NOT NULL, - ss_total_views bigint unsigned default 0, - ss_total_edits bigint unsigned default 0, - ss_good_articles bigint unsigned default 0, - ss_total_pages bigint default '-1', - ss_users bigint default '-1', - ss_active_users bigint default '-1', - ss_admins int default '-1', - ss_images int default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ss_row_id ON /*_*/site_stats (ss_row_id); -CREATE TABLE /*_*/hitcounter ( - hc_id int unsigned NOT NULL -) ENGINE=HEAP MAX_ROWS=25000; -CREATE TABLE /*_*/ipblocks ( - ipb_id int NOT NULL PRIMARY KEY AUTO_INCREMENT, - ipb_address tinyblob NOT NULL, - ipb_user int unsigned NOT NULL default 0, - ipb_by int unsigned NOT NULL default 0, - ipb_by_text varchar(255) binary NOT NULL default '', - ipb_reason tinyblob NOT NULL, - ipb_timestamp binary(14) NOT NULL default '', - ipb_auto bool NOT NULL default 0, - ipb_anon_only bool NOT NULL default 0, - ipb_create_account bool NOT NULL default 1, - ipb_enable_autoblock bool 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 bool NOT NULL default 0, - ipb_block_email bool NOT NULL default 0, - ipb_allow_usertalk bool NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ipb_address ON /*_*/ipblocks (ipb_address(255), ipb_user, ipb_auto, ipb_anon_only); -CREATE INDEX /*i*/ipb_user ON /*_*/ipblocks (ipb_user); -CREATE INDEX /*i*/ipb_range ON /*_*/ipblocks (ipb_range_start(8), ipb_range_end(8)); -CREATE INDEX /*i*/ipb_timestamp ON /*_*/ipblocks (ipb_timestamp); -CREATE INDEX /*i*/ipb_expiry ON /*_*/ipblocks (ipb_expiry); -CREATE TABLE /*_*/image ( - img_name varchar(255) binary NOT NULL default '' PRIMARY KEY, - img_size int unsigned NOT NULL default 0, - img_width int NOT NULL default 0, - img_height int NOT NULL default 0, - img_metadata mediumblob NOT NULL, - img_bits int 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 unsigned NOT NULL default 0, - img_user_text varchar(255) binary NOT NULL, - img_timestamp varbinary(14) NOT NULL default '', - img_sha1 varbinary(32) NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/img_usertext_timestamp ON /*_*/image (img_user_text,img_timestamp); -CREATE INDEX /*i*/img_size ON /*_*/image (img_size); -CREATE INDEX /*i*/img_timestamp ON /*_*/image (img_timestamp); -CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1); -CREATE TABLE /*_*/oldimage ( - oi_name varchar(255) binary NOT NULL default '', - oi_archive_name varchar(255) binary NOT NULL default '', - oi_size int unsigned NOT NULL default 0, - oi_width int NOT NULL default 0, - oi_height int NOT NULL default 0, - oi_bits int NOT NULL default 0, - oi_description tinyblob NOT NULL, - oi_user int unsigned NOT NULL default 0, - oi_user_text varchar(255) binary NOT NULL, - oi_timestamp binary(14) NOT NULL default '', - 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 unsigned NOT NULL default 0, - oi_sha1 varbinary(32) NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/oi_usertext_timestamp ON /*_*/oldimage (oi_user_text,oi_timestamp); -CREATE INDEX /*i*/oi_name_timestamp ON /*_*/oldimage (oi_name,oi_timestamp); -CREATE INDEX /*i*/oi_name_archive_name ON /*_*/oldimage (oi_name,oi_archive_name(14)); -CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1); -CREATE TABLE /*_*/filearchive ( - fa_id int NOT NULL PRIMARY KEY AUTO_INCREMENT, - fa_name varchar(255) binary NOT NULL default '', - fa_archive_name varchar(255) binary default '', - fa_storage_group varbinary(16), - fa_storage_key varbinary(64) default '', - fa_deleted_user int, - fa_deleted_timestamp binary(14) default '', - fa_deleted_reason text, - fa_size int unsigned default 0, - fa_width int default 0, - fa_height int default 0, - fa_metadata mediumblob, - fa_bits int 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 unsigned default 0, - fa_user_text varchar(255) binary, - fa_timestamp binary(14) default '', - fa_deleted tinyint unsigned NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/fa_name ON /*_*/filearchive (fa_name, fa_timestamp); -CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_storage_key); -CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp); -CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp); -CREATE TABLE /*_*/recentchanges ( - rc_id int NOT NULL PRIMARY KEY AUTO_INCREMENT, - rc_timestamp varbinary(14) NOT NULL default '', - rc_cur_time varbinary(14) NOT NULL default '', - rc_user int unsigned NOT NULL default 0, - rc_user_text varchar(255) binary NOT NULL, - rc_namespace int NOT NULL default 0, - rc_title varchar(255) binary NOT NULL default '', - rc_comment varchar(255) binary NOT NULL default '', - rc_minor tinyint unsigned NOT NULL default 0, - rc_bot tinyint unsigned NOT NULL default 0, - rc_new tinyint unsigned NOT NULL default 0, - rc_cur_id int unsigned NOT NULL default 0, - rc_this_oldid int unsigned NOT NULL default 0, - rc_last_oldid int unsigned NOT NULL default 0, - rc_type tinyint unsigned NOT NULL default 0, - rc_moved_to_ns tinyint unsigned NOT NULL default 0, - rc_moved_to_title varchar(255) binary NOT NULL default '', - rc_patrolled tinyint unsigned NOT NULL default 0, - rc_ip varbinary(40) NOT NULL default '', - rc_old_len int, - rc_new_len int, - rc_deleted tinyint unsigned NOT NULL default 0, - rc_logid int unsigned NOT NULL default 0, - rc_log_type varbinary(255) NULL default NULL, - rc_log_action varbinary(255) NULL default NULL, - rc_params blob NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/rc_timestamp ON /*_*/recentchanges (rc_timestamp); -CREATE INDEX /*i*/rc_namespace_title ON /*_*/recentchanges (rc_namespace, rc_title); -CREATE INDEX /*i*/rc_cur_id ON /*_*/recentchanges (rc_cur_id); -CREATE INDEX /*i*/new_name_timestamp ON /*_*/recentchanges (rc_new,rc_namespace,rc_timestamp); -CREATE INDEX /*i*/rc_ip ON /*_*/recentchanges (rc_ip); -CREATE INDEX /*i*/rc_ns_usertext ON /*_*/recentchanges (rc_namespace, rc_user_text); -CREATE INDEX /*i*/rc_user_text ON /*_*/recentchanges (rc_user_text, rc_timestamp); -CREATE TABLE /*_*/watchlist ( - wl_user int unsigned NOT NULL, - wl_namespace int NOT NULL default 0, - wl_title varchar(255) binary NOT NULL default '', - wl_notificationtimestamp varbinary(14) -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/wl_user ON /*_*/watchlist (wl_user, wl_namespace, wl_title); -CREATE INDEX /*i*/namespace_title ON /*_*/watchlist (wl_namespace, wl_title); -CREATE TABLE /*_*/math ( - math_inputhash varbinary(16) NOT NULL, - math_outputhash varbinary(16) NOT NULL, - math_html_conservativeness tinyint NOT NULL, - math_html text, - math_mathml text -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/math_inputhash ON /*_*/math (math_inputhash); -CREATE TABLE /*_*/searchindex ( - si_page int unsigned NOT NULL, - si_title varchar(255) NOT NULL default '', - si_text mediumtext NOT NULL -) ENGINE=MyISAM; -CREATE UNIQUE INDEX /*i*/si_page ON /*_*/searchindex (si_page); -CREATE FULLTEXT INDEX /*i*/si_title ON /*_*/searchindex (si_title); -CREATE FULLTEXT INDEX /*i*/si_text ON /*_*/searchindex (si_text); -CREATE TABLE /*_*/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 bool NOT NULL, - iw_trans tinyint NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/iw_prefix ON /*_*/interwiki (iw_prefix); -CREATE TABLE /*_*/querycache ( - qc_type varbinary(32) NOT NULL, - qc_value int unsigned NOT NULL default 0, - qc_namespace int NOT NULL default 0, - qc_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/qc_type ON /*_*/querycache (qc_type,qc_value); -CREATE TABLE /*_*/objectcache ( - keyname varbinary(255) NOT NULL default '' PRIMARY KEY, - value mediumblob, - exptime datetime -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/exptime ON /*_*/objectcache (exptime); -CREATE TABLE /*_*/transcache ( - tc_url varbinary(255) NOT NULL, - tc_contents text, - tc_time binary(14) NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/tc_url_idx ON /*_*/transcache (tc_url); -CREATE TABLE /*_*/logging ( - log_id int unsigned NOT NULL PRIMARY KEY 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 unsigned NOT NULL default 0, - log_user_text varchar(255) binary NOT NULL default '', - log_namespace int NOT NULL default 0, - log_title varchar(255) binary NOT NULL default '', - log_page int unsigned NULL, - log_comment varchar(255) NOT NULL default '', - log_params blob NOT NULL, - log_deleted tinyint unsigned NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/type_time ON /*_*/logging (log_type, log_timestamp); -CREATE INDEX /*i*/user_time ON /*_*/logging (log_user, log_timestamp); -CREATE INDEX /*i*/page_time ON /*_*/logging (log_namespace, log_title, log_timestamp); -CREATE INDEX /*i*/times ON /*_*/logging (log_timestamp); -CREATE INDEX /*i*/log_user_type_time ON /*_*/logging (log_user, log_type, log_timestamp); -CREATE INDEX /*i*/log_page_id_time ON /*_*/logging (log_page,log_timestamp); -CREATE TABLE /*_*/log_search ( - ls_field varbinary(32) NOT NULL, - ls_value varchar(255) NOT NULL, - ls_log_id int unsigned NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ls_field_val ON /*_*/log_search (ls_field,ls_value,ls_log_id); -CREATE INDEX /*i*/ls_log_id ON /*_*/log_search (ls_log_id); -CREATE TABLE /*_*/trackbacks ( - tb_id int PRIMARY KEY AUTO_INCREMENT, - tb_page int REFERENCES /*_*/page(page_id) ON DELETE CASCADE, - tb_title varchar(255) NOT NULL, - tb_url blob NOT NULL, - tb_ex text, - tb_name varchar(255) -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/tb_page ON /*_*/trackbacks (tb_page); -CREATE TABLE /*_*/job ( - job_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - job_cmd varbinary(60) NOT NULL default '', - job_namespace int NOT NULL, - job_title varchar(255) binary NOT NULL, - job_params blob NOT NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/job_cmd ON /*_*/job (job_cmd, job_namespace, job_title, job_params(128)); -CREATE TABLE /*_*/querycache_info ( - qci_type varbinary(32) NOT NULL default '', - qci_timestamp binary(14) NOT NULL default '19700101000000' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/qci_type ON /*_*/querycache_info (qci_type); -CREATE TABLE /*_*/redirect ( - rd_from int unsigned NOT NULL default 0 PRIMARY KEY, - rd_namespace int NOT NULL default 0, - rd_title varchar(255) binary NOT NULL default '', - rd_interwiki varchar(32) default NULL, - rd_fragment varchar(255) binary default NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/rd_ns_title ON /*_*/redirect (rd_namespace,rd_title,rd_from); -CREATE TABLE /*_*/querycachetwo ( - qcc_type varbinary(32) NOT NULL, - qcc_value int unsigned NOT NULL default 0, - qcc_namespace int NOT NULL default 0, - qcc_title varchar(255) binary NOT NULL default '', - qcc_namespacetwo int NOT NULL default 0, - qcc_titletwo varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/qcc_type ON /*_*/querycachetwo (qcc_type,qcc_value); -CREATE INDEX /*i*/qcc_title ON /*_*/querycachetwo (qcc_type,qcc_namespace,qcc_title); -CREATE INDEX /*i*/qcc_titletwo ON /*_*/querycachetwo (qcc_type,qcc_namespacetwo,qcc_titletwo); -CREATE TABLE /*_*/page_restrictions ( - pr_page int NOT NULL, - pr_type varbinary(60) NOT NULL, - pr_level varbinary(60) NOT NULL, - pr_cascade tinyint NOT NULL, - pr_user int NULL, - pr_expiry varbinary(14) NULL, - pr_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/pr_pagetype ON /*_*/page_restrictions (pr_page,pr_type); -CREATE INDEX /*i*/pr_typelevel ON /*_*/page_restrictions (pr_type,pr_level); -CREATE INDEX /*i*/pr_level ON /*_*/page_restrictions (pr_level); -CREATE INDEX /*i*/pr_cascade ON /*_*/page_restrictions (pr_cascade); -CREATE TABLE /*_*/protected_titles ( - pt_namespace int NOT NULL, - pt_title varchar(255) binary NOT NULL, - pt_user int 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 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/pt_namespace_title ON /*_*/protected_titles (pt_namespace,pt_title); -CREATE INDEX /*i*/pt_timestamp ON /*_*/protected_titles (pt_timestamp); -CREATE TABLE /*_*/page_props ( - pp_page int NOT NULL, - pp_propname varbinary(60) NOT NULL, - pp_value blob NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/pp_page_propname ON /*_*/page_props (pp_page,pp_propname); -CREATE TABLE /*_*/updatelog ( - ul_key varchar(255) NOT NULL PRIMARY KEY, - ul_value blob -) /*$wgDBTableOptions*/; -CREATE TABLE /*_*/change_tag ( - ct_rc_id int NULL, - ct_log_id int NULL, - ct_rev_id int NULL, - ct_tag varchar(255) NOT NULL, - ct_params blob NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/change_tag_rc_tag ON /*_*/change_tag (ct_rc_id,ct_tag); -CREATE UNIQUE INDEX /*i*/change_tag_log_tag ON /*_*/change_tag (ct_log_id,ct_tag); -CREATE UNIQUE INDEX /*i*/change_tag_rev_tag ON /*_*/change_tag (ct_rev_id,ct_tag); -CREATE INDEX /*i*/change_tag_tag_id ON /*_*/change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id); -CREATE TABLE /*_*/tag_summary ( - ts_rc_id int NULL, - ts_log_id int NULL, - ts_rev_id int NULL, - ts_tags blob NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/tag_summary_rc_id ON /*_*/tag_summary (ts_rc_id); -CREATE UNIQUE INDEX /*i*/tag_summary_log_id ON /*_*/tag_summary (ts_log_id); -CREATE UNIQUE INDEX /*i*/tag_summary_rev_id ON /*_*/tag_summary (ts_rev_id); -CREATE TABLE /*_*/valid_tag ( - vt_tag varchar(255) NOT NULL PRIMARY KEY -) /*$wgDBTableOptions*/; -CREATE TABLE /*_*/l10n_cache ( - lc_lang varbinary(32) NOT NULL, - lc_key varchar(255) NOT NULL, - lc_value mediumblob NOT NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/lc_lang_key ON /*_*/l10n_cache (lc_lang, lc_key); -CREATE TABLE /*_*/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 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/mr_resource_lang ON /*_*/msg_resource (mr_resource, mr_lang); -CREATE TABLE /*_*/msg_resource_links ( - mrl_resource varbinary(255) NOT NULL, - mrl_message varbinary(255) NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/mrl_message_resource ON /*_*/msg_resource_links (mrl_message, mrl_resource); -CREATE TABLE /*_*/module_deps ( - md_module varbinary(255) NOT NULL, - md_skin varbinary(32) NOT NULL, - md_deps mediumblob NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/md_module_skin ON /*_*/module_deps (md_module, md_skin); diff --git a/tests/phpunit/data/db/sqlite/tables-1.18.sql b/tests/phpunit/data/db/sqlite/tables-1.18.sql deleted file mode 100644 index 8bfc28e2..00000000 --- a/tests/phpunit/data/db/sqlite/tables-1.18.sql +++ /dev/null @@ -1,530 +0,0 @@ --- This is a copy of MediaWiki 1.18 schema shared by MySQL and SQLite. --- It is used for updater testing. Comments are stripped to decrease --- file size, as we don't need to maintain it. - -CREATE TABLE /*_*/user ( - user_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - user_name varchar(255) binary NOT NULL default '', - user_real_name varchar(255) binary NOT NULL default '', - user_password tinyblob NOT NULL, - user_newpassword tinyblob NOT NULL, - user_newpass_time binary(14), - user_email tinytext NOT NULL, - user_options blob NOT NULL, - user_touched binary(14) NOT NULL default '', - user_token binary(32) NOT NULL default '', - user_email_authenticated binary(14), - user_email_token binary(32), - user_email_token_expires binary(14), - user_registration binary(14), - user_editcount int -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/user_name ON /*_*/user (user_name); -CREATE INDEX /*i*/user_email_token ON /*_*/user (user_email_token); -CREATE INDEX /*i*/user_email ON /*_*/user (user_email(50)); -CREATE TABLE /*_*/user_groups ( - ug_user int unsigned NOT NULL default 0, - ug_group varbinary(16) NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ug_user_group ON /*_*/user_groups (ug_user,ug_group); -CREATE INDEX /*i*/ug_group ON /*_*/user_groups (ug_group); -CREATE TABLE /*_*/user_former_groups ( - ufg_user int unsigned NOT NULL default 0, - ufg_group varbinary(16) NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ufg_user_group ON /*_*/user_former_groups (ufg_user,ufg_group); -CREATE TABLE /*_*/user_newtalk ( - user_id int NOT NULL default 0, - user_ip varbinary(40) NOT NULL default '', - user_last_timestamp varbinary(14) NULL default NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/un_user_id ON /*_*/user_newtalk (user_id); -CREATE INDEX /*i*/un_user_ip ON /*_*/user_newtalk (user_ip); -CREATE TABLE /*_*/user_properties ( - up_user int NOT NULL, - up_property varbinary(255) NOT NULL, - up_value blob -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/user_properties_user_property ON /*_*/user_properties (up_user,up_property); -CREATE INDEX /*i*/user_properties_property ON /*_*/user_properties (up_property); -CREATE TABLE /*_*/page ( - page_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - page_namespace int NOT NULL, - page_title varchar(255) binary NOT NULL, - page_restrictions tinyblob NOT NULL, - page_counter bigint unsigned NOT NULL default 0, - page_is_redirect tinyint unsigned NOT NULL default 0, - page_is_new tinyint unsigned NOT NULL default 0, - page_random real unsigned NOT NULL, - page_touched binary(14) NOT NULL default '', - page_latest int unsigned NOT NULL, - page_len int unsigned NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/name_title ON /*_*/page (page_namespace,page_title); -CREATE INDEX /*i*/page_random ON /*_*/page (page_random); -CREATE INDEX /*i*/page_len ON /*_*/page (page_len); -CREATE TABLE /*_*/revision ( - rev_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - rev_page int unsigned NOT NULL, - rev_text_id int unsigned NOT NULL, - rev_comment tinyblob NOT NULL, - rev_user int unsigned NOT NULL default 0, - rev_user_text varchar(255) binary NOT NULL default '', - rev_timestamp binary(14) NOT NULL default '', - rev_minor_edit tinyint unsigned NOT NULL default 0, - rev_deleted tinyint unsigned NOT NULL default 0, - rev_len int unsigned, - rev_parent_id int unsigned default NULL -) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=1024; -CREATE UNIQUE INDEX /*i*/rev_page_id ON /*_*/revision (rev_page, rev_id); -CREATE INDEX /*i*/rev_timestamp ON /*_*/revision (rev_timestamp); -CREATE INDEX /*i*/page_timestamp ON /*_*/revision (rev_page,rev_timestamp); -CREATE INDEX /*i*/user_timestamp ON /*_*/revision (rev_user,rev_timestamp); -CREATE INDEX /*i*/usertext_timestamp ON /*_*/revision (rev_user_text,rev_timestamp); -CREATE TABLE /*_*/text ( - old_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - old_text mediumblob NOT NULL, - old_flags tinyblob NOT NULL -) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=10240; -CREATE TABLE /*_*/archive ( - ar_namespace int NOT NULL default 0, - ar_title varchar(255) binary NOT NULL default '', - ar_text mediumblob NOT NULL, - ar_comment tinyblob NOT NULL, - ar_user int unsigned NOT NULL default 0, - ar_user_text varchar(255) binary NOT NULL, - ar_timestamp binary(14) NOT NULL default '', - ar_minor_edit tinyint NOT NULL default 0, - ar_flags tinyblob NOT NULL, - ar_rev_id int unsigned, - ar_text_id int unsigned, - ar_deleted tinyint unsigned NOT NULL default 0, - ar_len int unsigned, - ar_page_id int unsigned, - ar_parent_id int unsigned default NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp); -CREATE INDEX /*i*/ar_usertext_timestamp ON /*_*/archive (ar_user_text,ar_timestamp); -CREATE INDEX /*i*/ar_revid ON /*_*/archive (ar_rev_id); -CREATE TABLE /*_*/pagelinks ( - pl_from int unsigned NOT NULL default 0, - pl_namespace int NOT NULL default 0, - pl_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/pl_from ON /*_*/pagelinks (pl_from,pl_namespace,pl_title); -CREATE UNIQUE INDEX /*i*/pl_namespace ON /*_*/pagelinks (pl_namespace,pl_title,pl_from); -CREATE TABLE /*_*/templatelinks ( - tl_from int unsigned NOT NULL default 0, - tl_namespace int NOT NULL default 0, - tl_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/tl_from ON /*_*/templatelinks (tl_from,tl_namespace,tl_title); -CREATE UNIQUE INDEX /*i*/tl_namespace ON /*_*/templatelinks (tl_namespace,tl_title,tl_from); -CREATE TABLE /*_*/imagelinks ( - il_from int unsigned NOT NULL default 0, - il_to varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/il_from ON /*_*/imagelinks (il_from,il_to); -CREATE UNIQUE INDEX /*i*/il_to ON /*_*/imagelinks (il_to,il_from); -CREATE TABLE /*_*/categorylinks ( - cl_from int unsigned NOT NULL default 0, - cl_to varchar(255) binary NOT NULL default '', - cl_sortkey varbinary(230) NOT NULL default '', - cl_sortkey_prefix varchar(255) binary NOT NULL default '', - cl_timestamp timestamp NOT NULL, - cl_collation varbinary(32) NOT NULL default '', - cl_type ENUM('page', 'subcat', 'file') NOT NULL default 'page' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/cl_from ON /*_*/categorylinks (cl_from,cl_to); -CREATE INDEX /*i*/cl_sortkey ON /*_*/categorylinks (cl_to,cl_type,cl_sortkey,cl_from); -CREATE INDEX /*i*/cl_timestamp ON /*_*/categorylinks (cl_to,cl_timestamp); -CREATE INDEX /*i*/cl_collation ON /*_*/categorylinks (cl_collation); -CREATE TABLE /*_*/category ( - cat_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - cat_title varchar(255) binary NOT NULL, - cat_pages int signed NOT NULL default 0, - cat_subcats int signed NOT NULL default 0, - cat_files int signed NOT NULL default 0, - cat_hidden tinyint unsigned NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/cat_title ON /*_*/category (cat_title); -CREATE INDEX /*i*/cat_pages ON /*_*/category (cat_pages); -CREATE TABLE /*_*/externallinks ( - el_from int unsigned NOT NULL default 0, - el_to blob NOT NULL, - el_index blob NOT NULL -) /*$wgDBTableOptions*/; -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 /*_*/langlinks ( - ll_from int unsigned NOT NULL default 0, - ll_lang varbinary(20) NOT NULL default '', - ll_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ll_from ON /*_*/langlinks (ll_from, ll_lang); -CREATE INDEX /*i*/ll_lang ON /*_*/langlinks (ll_lang, ll_title); -CREATE TABLE /*_*/iwlinks ( - iwl_from int unsigned NOT NULL default 0, - iwl_prefix varbinary(20) NOT NULL default '', - iwl_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/iwl_from ON /*_*/iwlinks (iwl_from, iwl_prefix, iwl_title); -CREATE UNIQUE INDEX /*i*/iwl_prefix_title_from ON /*_*/iwlinks (iwl_prefix, iwl_title, iwl_from); -CREATE TABLE /*_*/site_stats ( - ss_row_id int unsigned NOT NULL, - ss_total_views bigint unsigned default 0, - ss_total_edits bigint unsigned default 0, - ss_good_articles bigint unsigned default 0, - ss_total_pages bigint default '-1', - ss_users bigint default '-1', - ss_active_users bigint default '-1', - ss_admins int default '-1', - ss_images int default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ss_row_id ON /*_*/site_stats (ss_row_id); -CREATE TABLE /*_*/hitcounter ( - hc_id int unsigned NOT NULL -) ENGINE=HEAP MAX_ROWS=25000; -CREATE TABLE /*_*/ipblocks ( - ipb_id int NOT NULL PRIMARY KEY AUTO_INCREMENT, - ipb_address tinyblob NOT NULL, - ipb_user int unsigned NOT NULL default 0, - ipb_by int unsigned NOT NULL default 0, - ipb_by_text varchar(255) binary NOT NULL default '', - ipb_reason tinyblob NOT NULL, - ipb_timestamp binary(14) NOT NULL default '', - ipb_auto bool NOT NULL default 0, - ipb_anon_only bool NOT NULL default 0, - ipb_create_account bool NOT NULL default 1, - ipb_enable_autoblock bool 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 bool NOT NULL default 0, - ipb_block_email bool NOT NULL default 0, - ipb_allow_usertalk bool NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ipb_address ON /*_*/ipblocks (ipb_address(255), ipb_user, ipb_auto, ipb_anon_only); -CREATE INDEX /*i*/ipb_user ON /*_*/ipblocks (ipb_user); -CREATE INDEX /*i*/ipb_range ON /*_*/ipblocks (ipb_range_start(8), ipb_range_end(8)); -CREATE INDEX /*i*/ipb_timestamp ON /*_*/ipblocks (ipb_timestamp); -CREATE INDEX /*i*/ipb_expiry ON /*_*/ipblocks (ipb_expiry); -CREATE TABLE /*_*/image ( - img_name varchar(255) binary NOT NULL default '' PRIMARY KEY, - img_size int unsigned NOT NULL default 0, - img_width int NOT NULL default 0, - img_height int NOT NULL default 0, - img_metadata mediumblob NOT NULL, - img_bits int 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 unsigned NOT NULL default 0, - img_user_text varchar(255) binary NOT NULL, - img_timestamp varbinary(14) NOT NULL default '', - img_sha1 varbinary(32) NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/img_usertext_timestamp ON /*_*/image (img_user_text,img_timestamp); -CREATE INDEX /*i*/img_size ON /*_*/image (img_size); -CREATE INDEX /*i*/img_timestamp ON /*_*/image (img_timestamp); -CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1); -CREATE TABLE /*_*/oldimage ( - oi_name varchar(255) binary NOT NULL default '', - oi_archive_name varchar(255) binary NOT NULL default '', - oi_size int unsigned NOT NULL default 0, - oi_width int NOT NULL default 0, - oi_height int NOT NULL default 0, - oi_bits int NOT NULL default 0, - oi_description tinyblob NOT NULL, - oi_user int unsigned NOT NULL default 0, - oi_user_text varchar(255) binary NOT NULL, - oi_timestamp binary(14) NOT NULL default '', - 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 unsigned NOT NULL default 0, - oi_sha1 varbinary(32) NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/oi_usertext_timestamp ON /*_*/oldimage (oi_user_text,oi_timestamp); -CREATE INDEX /*i*/oi_name_timestamp ON /*_*/oldimage (oi_name,oi_timestamp); -CREATE INDEX /*i*/oi_name_archive_name ON /*_*/oldimage (oi_name,oi_archive_name(14)); -CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1); -CREATE TABLE /*_*/filearchive ( - fa_id int NOT NULL PRIMARY KEY AUTO_INCREMENT, - fa_name varchar(255) binary NOT NULL default '', - fa_archive_name varchar(255) binary default '', - fa_storage_group varbinary(16), - fa_storage_key varbinary(64) default '', - fa_deleted_user int, - fa_deleted_timestamp binary(14) default '', - fa_deleted_reason text, - fa_size int unsigned default 0, - fa_width int default 0, - fa_height int default 0, - fa_metadata mediumblob, - fa_bits int 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 unsigned default 0, - fa_user_text varchar(255) binary, - fa_timestamp binary(14) default '', - fa_deleted tinyint unsigned NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/fa_name ON /*_*/filearchive (fa_name, fa_timestamp); -CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_storage_key); -CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp); -CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp); -CREATE TABLE /*_*/uploadstash ( - us_id int unsigned NOT NULL PRIMARY KEY auto_increment, - us_user int unsigned NOT NULL, - us_key varchar(255) NOT NULL, - us_orig_path varchar(255) NOT NULL, - us_path varchar(255) NOT NULL, - us_source_type varchar(50), - us_timestamp varbinary(14) not null, - us_status varchar(50) not null, - us_size int unsigned NOT NULL, - us_sha1 varchar(31) NOT NULL, - us_mime varchar(255), - us_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL, - us_image_width int unsigned, - us_image_height int unsigned, - us_image_bits smallint unsigned -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/us_user ON /*_*/uploadstash (us_user); -CREATE UNIQUE INDEX /*i*/us_key ON /*_*/uploadstash (us_key); -CREATE INDEX /*i*/us_timestamp ON /*_*/uploadstash (us_timestamp); -CREATE TABLE /*_*/recentchanges ( - rc_id int NOT NULL PRIMARY KEY AUTO_INCREMENT, - rc_timestamp varbinary(14) NOT NULL default '', - rc_cur_time varbinary(14) NOT NULL default '', - rc_user int unsigned NOT NULL default 0, - rc_user_text varchar(255) binary NOT NULL, - rc_namespace int NOT NULL default 0, - rc_title varchar(255) binary NOT NULL default '', - rc_comment varchar(255) binary NOT NULL default '', - rc_minor tinyint unsigned NOT NULL default 0, - rc_bot tinyint unsigned NOT NULL default 0, - rc_new tinyint unsigned NOT NULL default 0, - rc_cur_id int unsigned NOT NULL default 0, - rc_this_oldid int unsigned NOT NULL default 0, - rc_last_oldid int unsigned NOT NULL default 0, - rc_type tinyint unsigned NOT NULL default 0, - rc_moved_to_ns tinyint unsigned NOT NULL default 0, - rc_moved_to_title varchar(255) binary NOT NULL default '', - rc_patrolled tinyint unsigned NOT NULL default 0, - rc_ip varbinary(40) NOT NULL default '', - rc_old_len int, - rc_new_len int, - rc_deleted tinyint unsigned NOT NULL default 0, - rc_logid int unsigned NOT NULL default 0, - rc_log_type varbinary(255) NULL default NULL, - rc_log_action varbinary(255) NULL default NULL, - rc_params blob NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/rc_timestamp ON /*_*/recentchanges (rc_timestamp); -CREATE INDEX /*i*/rc_namespace_title ON /*_*/recentchanges (rc_namespace, rc_title); -CREATE INDEX /*i*/rc_cur_id ON /*_*/recentchanges (rc_cur_id); -CREATE INDEX /*i*/new_name_timestamp ON /*_*/recentchanges (rc_new,rc_namespace,rc_timestamp); -CREATE INDEX /*i*/rc_ip ON /*_*/recentchanges (rc_ip); -CREATE INDEX /*i*/rc_ns_usertext ON /*_*/recentchanges (rc_namespace, rc_user_text); -CREATE INDEX /*i*/rc_user_text ON /*_*/recentchanges (rc_user_text, rc_timestamp); -CREATE TABLE /*_*/watchlist ( - wl_user int unsigned NOT NULL, - wl_namespace int NOT NULL default 0, - wl_title varchar(255) binary NOT NULL default '', - wl_notificationtimestamp varbinary(14) -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/wl_user ON /*_*/watchlist (wl_user, wl_namespace, wl_title); -CREATE INDEX /*i*/namespace_title ON /*_*/watchlist (wl_namespace, wl_title); -CREATE TABLE /*_*/searchindex ( - si_page int unsigned NOT NULL, - si_title varchar(255) NOT NULL default '', - si_text mediumtext NOT NULL -) ENGINE=MyISAM; -CREATE UNIQUE INDEX /*i*/si_page ON /*_*/searchindex (si_page); -CREATE FULLTEXT INDEX /*i*/si_title ON /*_*/searchindex (si_title); -CREATE FULLTEXT INDEX /*i*/si_text ON /*_*/searchindex (si_text); -CREATE TABLE /*_*/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 bool NOT NULL, - iw_trans tinyint NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/iw_prefix ON /*_*/interwiki (iw_prefix); -CREATE TABLE /*_*/querycache ( - qc_type varbinary(32) NOT NULL, - qc_value int unsigned NOT NULL default 0, - qc_namespace int NOT NULL default 0, - qc_title varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/qc_type ON /*_*/querycache (qc_type,qc_value); -CREATE TABLE /*_*/objectcache ( - keyname varbinary(255) NOT NULL default '' PRIMARY KEY, - value mediumblob, - exptime datetime -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/exptime ON /*_*/objectcache (exptime); -CREATE TABLE /*_*/transcache ( - tc_url varbinary(255) NOT NULL, - tc_contents text, - tc_time binary(14) NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/tc_url_idx ON /*_*/transcache (tc_url); -CREATE TABLE /*_*/logging ( - log_id int unsigned NOT NULL PRIMARY KEY 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 unsigned NOT NULL default 0, - log_user_text varchar(255) binary NOT NULL default '', - log_namespace int NOT NULL default 0, - log_title varchar(255) binary NOT NULL default '', - log_page int unsigned NULL, - log_comment varchar(255) NOT NULL default '', - log_params blob NOT NULL, - log_deleted tinyint unsigned NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/type_time ON /*_*/logging (log_type, log_timestamp); -CREATE INDEX /*i*/user_time ON /*_*/logging (log_user, log_timestamp); -CREATE INDEX /*i*/page_time ON /*_*/logging (log_namespace, log_title, log_timestamp); -CREATE INDEX /*i*/times ON /*_*/logging (log_timestamp); -CREATE INDEX /*i*/log_user_type_time ON /*_*/logging (log_user, log_type, log_timestamp); -CREATE INDEX /*i*/log_page_id_time ON /*_*/logging (log_page,log_timestamp); -CREATE TABLE /*_*/log_search ( - ls_field varbinary(32) NOT NULL, - ls_value varchar(255) NOT NULL, - ls_log_id int unsigned NOT NULL default 0 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/ls_field_val ON /*_*/log_search (ls_field,ls_value,ls_log_id); -CREATE INDEX /*i*/ls_log_id ON /*_*/log_search (ls_log_id); -CREATE TABLE /*_*/trackbacks ( - tb_id int PRIMARY KEY AUTO_INCREMENT, - tb_page int REFERENCES /*_*/page(page_id) ON DELETE CASCADE, - tb_title varchar(255) NOT NULL, - tb_url blob NOT NULL, - tb_ex text, - tb_name varchar(255) -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/tb_page ON /*_*/trackbacks (tb_page); -CREATE TABLE /*_*/job ( - job_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - job_cmd varbinary(60) NOT NULL default '', - job_namespace int NOT NULL, - job_title varchar(255) binary NOT NULL, - job_params blob NOT NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/job_cmd ON /*_*/job (job_cmd, job_namespace, job_title, job_params(128)); -CREATE TABLE /*_*/querycache_info ( - qci_type varbinary(32) NOT NULL default '', - qci_timestamp binary(14) NOT NULL default '19700101000000' -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/qci_type ON /*_*/querycache_info (qci_type); -CREATE TABLE /*_*/redirect ( - rd_from int unsigned NOT NULL default 0 PRIMARY KEY, - rd_namespace int NOT NULL default 0, - rd_title varchar(255) binary NOT NULL default '', - rd_interwiki varchar(32) default NULL, - rd_fragment varchar(255) binary default NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/rd_ns_title ON /*_*/redirect (rd_namespace,rd_title,rd_from); -CREATE TABLE /*_*/querycachetwo ( - qcc_type varbinary(32) NOT NULL, - qcc_value int unsigned NOT NULL default 0, - qcc_namespace int NOT NULL default 0, - qcc_title varchar(255) binary NOT NULL default '', - qcc_namespacetwo int NOT NULL default 0, - qcc_titletwo varchar(255) binary NOT NULL default '' -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/qcc_type ON /*_*/querycachetwo (qcc_type,qcc_value); -CREATE INDEX /*i*/qcc_title ON /*_*/querycachetwo (qcc_type,qcc_namespace,qcc_title); -CREATE INDEX /*i*/qcc_titletwo ON /*_*/querycachetwo (qcc_type,qcc_namespacetwo,qcc_titletwo); -CREATE TABLE /*_*/page_restrictions ( - pr_page int NOT NULL, - pr_type varbinary(60) NOT NULL, - pr_level varbinary(60) NOT NULL, - pr_cascade tinyint NOT NULL, - pr_user int NULL, - pr_expiry varbinary(14) NULL, - pr_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/pr_pagetype ON /*_*/page_restrictions (pr_page,pr_type); -CREATE INDEX /*i*/pr_typelevel ON /*_*/page_restrictions (pr_type,pr_level); -CREATE INDEX /*i*/pr_level ON /*_*/page_restrictions (pr_level); -CREATE INDEX /*i*/pr_cascade ON /*_*/page_restrictions (pr_cascade); -CREATE TABLE /*_*/protected_titles ( - pt_namespace int NOT NULL, - pt_title varchar(255) binary NOT NULL, - pt_user int 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 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/pt_namespace_title ON /*_*/protected_titles (pt_namespace,pt_title); -CREATE INDEX /*i*/pt_timestamp ON /*_*/protected_titles (pt_timestamp); -CREATE TABLE /*_*/page_props ( - pp_page int NOT NULL, - pp_propname varbinary(60) NOT NULL, - pp_value blob NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/pp_page_propname ON /*_*/page_props (pp_page,pp_propname); -CREATE TABLE /*_*/updatelog ( - ul_key varchar(255) NOT NULL PRIMARY KEY, - ul_value blob -) /*$wgDBTableOptions*/; -CREATE TABLE /*_*/change_tag ( - ct_rc_id int NULL, - ct_log_id int NULL, - ct_rev_id int NULL, - ct_tag varchar(255) NOT NULL, - ct_params blob NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/change_tag_rc_tag ON /*_*/change_tag (ct_rc_id,ct_tag); -CREATE UNIQUE INDEX /*i*/change_tag_log_tag ON /*_*/change_tag (ct_log_id,ct_tag); -CREATE UNIQUE INDEX /*i*/change_tag_rev_tag ON /*_*/change_tag (ct_rev_id,ct_tag); -CREATE INDEX /*i*/change_tag_tag_id ON /*_*/change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id); -CREATE TABLE /*_*/tag_summary ( - ts_rc_id int NULL, - ts_log_id int NULL, - ts_rev_id int NULL, - ts_tags blob NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/tag_summary_rc_id ON /*_*/tag_summary (ts_rc_id); -CREATE UNIQUE INDEX /*i*/tag_summary_log_id ON /*_*/tag_summary (ts_log_id); -CREATE UNIQUE INDEX /*i*/tag_summary_rev_id ON /*_*/tag_summary (ts_rev_id); -CREATE TABLE /*_*/valid_tag ( - vt_tag varchar(255) NOT NULL PRIMARY KEY -) /*$wgDBTableOptions*/; -CREATE TABLE /*_*/l10n_cache ( - lc_lang varbinary(32) NOT NULL, - lc_key varchar(255) NOT NULL, - lc_value mediumblob NOT NULL -) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/lc_lang_key ON /*_*/l10n_cache (lc_lang, lc_key); -CREATE TABLE /*_*/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 -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/mr_resource_lang ON /*_*/msg_resource (mr_resource, mr_lang); -CREATE TABLE /*_*/msg_resource_links ( - mrl_resource varbinary(255) NOT NULL, - mrl_message varbinary(255) NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/mrl_message_resource ON /*_*/msg_resource_links (mrl_message, mrl_resource); -CREATE TABLE /*_*/module_deps ( - md_module varbinary(255) NOT NULL, - md_skin varbinary(32) NOT NULL, - md_deps mediumblob NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/md_module_skin ON /*_*/module_deps (md_module, md_skin); - diff --git a/tests/phpunit/data/less/common/test.common.mixins.less b/tests/phpunit/data/less/common/test.common.mixins.less deleted file mode 100644 index 2fbe9b79..00000000 --- a/tests/phpunit/data/less/common/test.common.mixins.less +++ /dev/null @@ -1,5 +0,0 @@ -.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 deleted file mode 100644 index c7725a25..00000000 --- a/tests/phpunit/data/less/module/dependency.less +++ /dev/null @@ -1,3 +0,0 @@ -@import "test.common.mixins"; - -@unitTestColor: green; diff --git a/tests/phpunit/data/less/module/styles.css b/tests/phpunit/data/less/module/styles.css deleted file mode 100644 index b78780a9..00000000 --- a/tests/phpunit/data/less/module/styles.css +++ /dev/null @@ -1,6 +0,0 @@ -/* @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 deleted file mode 100644 index ecac8392..00000000 --- a/tests/phpunit/data/less/module/styles.less +++ /dev/null @@ -1,6 +0,0 @@ -@import "dependency"; - -/* @noflip */ -.unit-tests { - .test-mixin(@unitTestColor); -} diff --git a/tests/phpunit/data/media/1bit-png.png b/tests/phpunit/data/media/1bit-png.png Binary files differdeleted file mode 100644 index 254e403a..00000000 --- a/tests/phpunit/data/media/1bit-png.png +++ /dev/null diff --git a/tests/phpunit/data/media/80x60-2layers.xcf b/tests/phpunit/data/media/80x60-2layers.xcf Binary files differdeleted file mode 100644 index c51e980c..00000000 --- a/tests/phpunit/data/media/80x60-2layers.xcf +++ /dev/null diff --git a/tests/phpunit/data/media/80x60-Greyscale.xcf b/tests/phpunit/data/media/80x60-Greyscale.xcf Binary files differdeleted file mode 100644 index 84bf3e67..00000000 --- a/tests/phpunit/data/media/80x60-Greyscale.xcf +++ /dev/null diff --git a/tests/phpunit/data/media/80x60-RGB.xcf b/tests/phpunit/data/media/80x60-RGB.xcf Binary files differdeleted file mode 100644 index 1d58f16d..00000000 --- a/tests/phpunit/data/media/80x60-RGB.xcf +++ /dev/null diff --git a/tests/phpunit/data/media/Animated_PNG_example_bouncing_beach_ball.png b/tests/phpunit/data/media/Animated_PNG_example_bouncing_beach_ball.png Binary files differdeleted file mode 100644 index c2f45d90..00000000 --- a/tests/phpunit/data/media/Animated_PNG_example_bouncing_beach_ball.png +++ /dev/null diff --git a/tests/phpunit/data/media/Gtk-media-play-ltr.svg b/tests/phpunit/data/media/Gtk-media-play-ltr.svg deleted file mode 100644 index fc22338a..00000000 --- a/tests/phpunit/data/media/Gtk-media-play-ltr.svg +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [ - <!ATTLIST svg - xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink"> -]> -<!-- Created with Sodipodi ("http://www.sodipodi.com/") --> -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" version="1" x="0.00000000" y="0.00000000" width="60.0000000" height="60.0000000" viewBox="0 0 256 256" id="svg548"> - <defs id="defs572"/> - <g style="font-size:12;stroke:#000000;" id="Layer_1"> - <path d="M 256 256 L 0 256 L 0 0 L 256 0 L 256 256 z " style="fill:none;stroke:none;" id="path550"/> - </g> - <g style="font-size:12;stroke:#000000;" id="Layer_2"> - <path d="M 35.159 8.29 C 32.18 10.01 30.329 13.216 30.329 16.656 L 30.329 245.539 C 30.329 248.978 32.179 252.184 35.158 253.902 C 38.138 255.623 41.839 255.623 44.817 253.904 L 243.037 139.463 C 246.016 137.742 247.867 134.537 247.867 131.098 C 247.867 127.658 246.016 124.452 243.037 122.731 L 44.818 8.29 C 41.839 6.57 38.138 6.57 35.159 8.29 z " style="opacity:0.2;stroke:none;" id="path552"/> - <path d="M 27.314 2.29 C 24.335 4.01 22.484 7.216 22.484 10.656 L 22.484 239.538 C 22.484 242.977 24.335 246.184 27.313 247.903 C 30.293 249.623 33.994 249.623 36.973 247.905 L 235.193 133.464 C 238.172 131.742 240.023 128.536 240.023 125.098 C 240.023 121.658 238.172 118.452 235.193 116.732 L 36.975 2.29 C 33.996 0.57 30.294 0.57 27.314 2.29 z " style="fill:#003399;stroke:none;" id="path553"/> - <path d="M 29.247 5.636 C 27.454 6.672 26.349 8.585 26.349 10.656 L 26.349 239.538 C 26.349 241.608 27.453 243.521 29.247 244.558 C 31.04 245.592 33.249 245.592 35.042 244.558 L 233.261 130.117 C 235.054 129.081 236.159 127.169 236.159 125.098 C 236.159 123.027 235.054 121.114 233.261 120.078 L 35.042 5.636 C 33.25 4.601 31.041 4.601 29.247 5.636 z " style="fill:#003399;stroke:none;" id="path554"/> - <path d="M 32.145 10.656 L 230.364 125.097 L 32.145 239.538 L 32.145 10.656 z " style="fill:#3399ff;stroke:none;" id="path555"/> - <linearGradient x1="109.971703" y1="8.70849991" x2="109.971703" y2="107.238800" id="XMLID_1_" gradientUnits="userSpaceOnUse" spreadMethod="pad"> - <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0.00000000" id="stop557"/> - <stop style="stop-color:#3399ff;stop-opacity:1;" offset="1.00000000" id="stop558"/> - <a:midPointStop offset="0" style="stop-color:#FFFFFF" id="midPointStop559"/> - <a:midPointStop offset="0.5" style="stop-color:#FFFFFF" id="midPointStop560"/> - <a:midPointStop offset="1" style="stop-color:#3399FF" id="midPointStop561"/> - </linearGradient> - <path d="M 32.145 141.057 C 36.775 141.258 41.456 141.368 46.183 141.368 C 105.41 141.368 157.526 125.124 187.799 100.524 L 32.145 10.656 L 32.145 141.057 z " style="fill:url(#XMLID_1_);stroke:none;" id="path562"/> - <linearGradient x1="109.972198" y1="264.875000" x2="109.972198" y2="145.249298" id="XMLID_2_" gradientUnits="userSpaceOnUse" spreadMethod="pad"> - <stop style="stop-color:#ccffff;stop-opacity:1;" offset="0.00000000" id="stop564"/> - <stop style="stop-color:#3399ff;stop-opacity:1;" offset="1.00000000" id="stop565"/> - <a:midPointStop offset="0" style="stop-color:#CCFFFF" id="midPointStop566"/> - <a:midPointStop offset="0.5" style="stop-color:#CCFFFF" id="midPointStop567"/> - <a:midPointStop offset="1" style="stop-color:#3399FF" id="midPointStop568"/> - </linearGradient> - <path d="M 32.145 108.517 C 36.775 108.315 41.456 108.206 46.183 108.206 C 105.41 108.206 157.526 124.451 187.799 149.05 L 32.145 238.916 L 32.145 108.517 z " style="fill:url(#XMLID_2_);stroke:none;" id="path569"/> - <path d="M 37.145 19.316 C 36.526 19.673 36.145 20.334 36.145 21.048 L 36.145 162.69 C 36.145 163.768 36.999 198.629 38.077 198.667 C 39.154 198.703 40.41 48.03 48.066 40.375 C 55.722 32.72 212.492 122.951 213 122 C 213.507 121.049 186.703 104.509 185.77 103.97 L 39.145 19.316 C 38.526 18.959 37.764 18.959 37.145 19.316 z " style="opacity:0.5;fill:#ffffff;stroke:none;" id="path570"/> - </g> -</svg>
\ No newline at end of file diff --git a/tests/phpunit/data/media/Png-native-test.png b/tests/phpunit/data/media/Png-native-test.png Binary files differdeleted file mode 100644 index a0b81ca9..00000000 --- a/tests/phpunit/data/media/Png-native-test.png +++ /dev/null diff --git a/tests/phpunit/data/media/QA_icon.svg b/tests/phpunit/data/media/QA_icon.svg deleted file mode 100644 index 6b5d86e4..00000000 --- a/tests/phpunit/data/media/QA_icon.svg +++ /dev/null @@ -1,77 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> -<svg:svg xmlns:svg="http://www.w3.org/2000/svg" version="1.0" width="60" height="60" viewBox="0 0 128 128" id="svg548"> - <svg:defs id="defs601"> - <svg:linearGradient id="linearGradient2802"> - <svg:stop style="stop-color:#1d12aa;stop-opacity:1" offset="0" id="stop2804"/> - <svg:stop style="stop-color:#8b12aa;stop-opacity:0" offset="1" id="stop2806"/> - </svg:linearGradient> - <svg:linearGradient id="linearGradient2812"> - <svg:stop style="stop-color:#1d25aa;stop-opacity:1" offset="0" id="stop2814"/> - <svg:stop style="stop-color:#8b12aa;stop-opacity:0" offset="1" id="stop2816"/> - </svg:linearGradient> - <svg:marker refX="0" refY="0" orient="auto" style="overflow:visible" id="Arrow1Lstart"> - <svg:path d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z " transform="scale(0.8)" style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none" id="path2991"/> - </svg:marker> - <svg:linearGradient id="linearGradient4766"> - <svg:stop style="stop-color:#0447ff;stop-opacity:1" offset="0" id="stop4768"/> - <svg:stop style="stop-color:#000000;stop-opacity:0" offset="1" id="stop4770"/> - </svg:linearGradient> - <svg:linearGradient x1="55.4272" y1="102.1953" x2="55.4272" y2="-7.1773" id="XMLID_1_" gradientUnits="userSpaceOnUse" gradientTransform="translate(0, -0.496766)" spreadMethod="pad"> - <svg:stop style="stop-color:#7c74ff;stop-opacity:1" offset="0" id="stop556"/> - <svg:stop style="stop-color:#b3caff;stop-opacity:1" offset="0.41010001" id="stop557"/> - <svg:stop style="stop-color:#dfeaff;stop-opacity:1" offset="0.8258" id="stop558"/> - <svg:stop style="stop-color:#ffffff;stop-opacity:1" offset="1" id="stop559"/> - <midPointStop offset="0" style="stop-color:#7C74FF" id="midPointStop560"/> - <midPointStop offset="0.5" style="stop-color:#7C74FF" id="midPointStop561"/> - <midPointStop offset="0.4101" style="stop-color:#B3CAFF" id="midPointStop562"/> - <midPointStop offset="0.5" style="stop-color:#B3CAFF" id="midPointStop563"/> - <midPointStop offset="0.8258" style="stop-color:#DFEAFF" id="midPointStop564"/> - <midPointStop offset="0.5" style="stop-color:#DFEAFF" id="midPointStop565"/> - <midPointStop offset="1" style="stop-color:#FFFFFF" id="midPointStop566"/> - </svg:linearGradient> - <svg:linearGradient x1="54.7607" y1="7.2758999" x2="54.7607" y2="57.487301" id="XMLID_2_" gradientUnits="userSpaceOnUse" spreadMethod="pad"> - <svg:stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop569"/> - <svg:stop style="stop-color:#b3caff;stop-opacity:1" offset="1" id="stop570"/> - <midPointStop offset="0" style="stop-color:#FFFFFF" id="midPointStop571"/> - <midPointStop offset="0.5" style="stop-color:#FFFFFF" id="midPointStop572"/> - <midPointStop offset="1" style="stop-color:#B3CAFF" id="midPointStop573"/> - </svg:linearGradient> - <svg:linearGradient x1="83.637703" y1="119.3457" x2="83.637703" y2="42.033901" id="XMLID_3_" gradientUnits="userSpaceOnUse" spreadMethod="pad"> - <svg:stop style="stop-color:#006dff;stop-opacity:1" offset="0" id="stop577"/> - <svg:stop style="stop-color:#94caff;stop-opacity:1" offset="0.41010001" id="stop578"/> - <svg:stop style="stop-color:#dcf0ff;stop-opacity:1" offset="0.8258" id="stop579"/> - <svg:stop style="stop-color:#ffffff;stop-opacity:1" offset="1" id="stop580"/> - <midPointStop offset="0" style="stop-color:#006DFF" id="midPointStop581"/> - <midPointStop offset="0.5" style="stop-color:#006DFF" id="midPointStop582"/> - <midPointStop offset="0.4101" style="stop-color:#94CAFF" id="midPointStop583"/> - <midPointStop offset="0.5" style="stop-color:#94CAFF" id="midPointStop584"/> - <midPointStop offset="0.8258" style="stop-color:#DCF0FF" id="midPointStop585"/> - <midPointStop offset="0.5" style="stop-color:#DCF0FF" id="midPointStop586"/> - <midPointStop offset="1" style="stop-color:#FFFFFF" id="midPointStop587"/> - </svg:linearGradient> - <svg:linearGradient x1="265.11331" y1="52.250999" x2="265.11331" y2="87.743599" id="XMLID_4_" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1, 0, 0, 1, 349, 0)" spreadMethod="pad"> - <svg:stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop590"/> - <svg:stop style="stop-color:#94caff;stop-opacity:1" offset="1" id="stop591"/> - <midPointStop offset="0" style="stop-color:#FFFFFF" id="midPointStop592"/> - <midPointStop offset="0.5" style="stop-color:#FFFFFF" id="midPointStop593"/> - <midPointStop offset="1" style="stop-color:#94CAFF" id="midPointStop594"/> - </svg:linearGradient> - </svg:defs> - <svg:g style="font-size:12px;stroke:#000000" id="Layer_2"> - <svg:path d="M 128,128 L 0,128 L 0,0 L 128,0 L 128,128 z " style="fill:none;stroke:none" id="path550"/> - </svg:g> - <svg:g style="font-size:12px;stroke:#000000" id="Layer_1"/> - <svg:path d="M 9.041,92.189 C 9.041,92.189 21.955,85.393 30.11,67.382 L 52.198,76.897 C 52.198,76.897 46.422,92.189 9.041,92.189 z " style="font-size:12px;fill:#00008d;stroke:none" id="path553"/> - <svg:path d="M 1.905,49.712 C 1.905,70.733 25.867,87.773 55.427,87.773 C 84.987,87.773 108.949,70.733 108.949,49.712 C 108.949,28.692 84.987,11.651 55.427,11.651 C 25.867,11.651 1.905,28.692 1.905,49.712 z " style="font-size:12px;fill:#00008d;stroke:none" id="path554"/> - <svg:path d="M 55.427,13.193234 C 27.039,13.193234 3.943,29.352234 3.943,49.214234 C 3.943,61.333234 12.55,72.067234 25.703,78.598234 C 22.202,83.521234 18.6,87.075234 15.722,89.464234 C 27.71,88.800234 35.664,86.388234 40.883,83.762234 C 45.498,84.716234 50.377,85.236234 55.427,85.236234 C 83.815,85.236234 106.91,69.077234 106.91,49.215234 C 106.91,29.353234 83.815,13.193234 55.427,13.193234 z " style="font-size:12px;fill:url(#XMLID_1_);stroke:none" id="path567"/> - <svg:path d="M 12.999,35.282 C 30.044,44.81 49.474,47.149 69.356,41.962 C 73.46,40.821 77.627,39.436 81.656,38.096 C 86.51,36.482 91.504,34.846 96.524,33.573 C 88.559,23.302 72.888,16.748 55.428,16.748 C 37.091,16.749 20.396,24.128 12.999,35.282 z " style="font-size:12px;fill:url(#XMLID_2_);stroke:none" id="path574"/> - <svg:text x="32.487015" y="68.006958" style="font-size:48px;font-style:normal;font-weight:bold;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Microsoft Sans Serif" id="text2303" xml:space="preserve"><svg:tspan x="32.487015" y="68.006958" style="font-size:64px;font-style:normal;font-weight:bold;fill:#000000;fill-opacity:1;font-family:sans" id="tspan2305">?</svg:tspan></svg:text> - <svg:path d="M 42.401,82.248 C 42.401,98.96 60.9,112.557 83.638,112.557 C 86.794,112.557 90.053,112.231 93.329,111.651 C 98.255,113.817 104.317,115.142 111.437,115.538 L 126.095,116.35 L 114.798,106.972 C 114.067,106.367 113.056,105.441 111.922,104.237 C 120.165,98.531 124.875,90.66 124.875,82.25 C 124.875,65.538 106.376,51.942 83.637,51.942 C 60.9,51.94 42.401,65.536 42.401,82.248 z " style="font-size:12px;fill:#0032a4;stroke:none" id="path575"/> - <svg:path d="M 44.823,82.248 C 44.823,97.624 62.236,110.133 83.637,110.133 C 87.009,110.133 90.357,109.784 93.616,109.163 C 98.327,111.368 104.334,112.717 111.571,113.118 L 118.9,113.524 L 113.251,108.835 C 111.96,107.763 110.162,106.071 108.268,103.754 C 117.176,98.487 122.454,90.629 122.454,82.248 C 122.454,66.871 105.042,54.363 83.639,54.363 C 62.236,54.363 44.823,66.871 44.823,82.248 z " style="font-size:12px;fill:url(#XMLID_3_);stroke:none" id="path588"/> - <svg:path d="M 83.638,57.505 C 98.257,57.505 110.759,63.777 115.655,72.576 C 102.935,80.147 88.183,82.013 73.429,78.165 C 66.228,76.163 59.247,73.276 52.12,71.719 C 57.332,63.374 69.498,57.505 83.638,57.505 z " style="font-size:12px;fill:url(#XMLID_4_);stroke:none" id="path595"/> - <svg:g transform="matrix(1.38561, 0, 0, 1.38561, -32.2514, -30.5491)" id="g4248"> - <svg:path d="M 103.21356 24.205935 A 24.311146 23.627199 0 1 1 54.591267,24.205935 A 24.311146 23.627199 0 1 1 103.21356 24.205935 z" transform="matrix(0.148134, 0, 0, 0.152972, 71.9504, 64.0705)" style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:6.64218044;stroke-linecap:square;marker-start:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path3881"/> - <svg:path d="M 87.539971,77.627004 C 87.539971,78.31674 87.591107,91.916423 87.60756,94.355578 C 87.61771,95.860439 89.879004,95.050778 90.026509,95.980703 C 90.2785,97.569343 86.888685,97.025111 86.718511,97.01762 C 85.743882,96.974724 82.425764,97.036144 81.376943,97.036144 C 81.101002,97.036144 77.578516,97.69007 77.314172,96.309196 C 77.071189,95.039902 79.49446,95.29146 79.833236,94.380195 C 81.070282,91.052684 81.154686,84.029315 80.322646,79.891188 C 79.902772,77.802954 76.928763,78.363984 77.263297,76.859643 C 77.479369,75.888015 78.579837,75.778912 79.35102,75.513942 C 81.049574,74.930337 83.123826,75.068206 84.579101,74.012707 C 86.187481,72.846162 87.539971,75.631913 87.539971,77.627004 z " style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.99986994;stroke-linecap:square;marker-start:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" id="path4774"/> - </svg:g> -</svg:svg>
\ No newline at end of file diff --git a/tests/phpunit/data/media/README b/tests/phpunit/data/media/README deleted file mode 100644 index fe3bc682..00000000 --- a/tests/phpunit/data/media/README +++ /dev/null @@ -1,38 +0,0 @@ -This directory contains media files for use with the -tests in includes/media directory. - -Image credits: - -QA_icon.svg: -http://es.wikipedia.org/wiki/Archivo:QA_icon.svg -GNU Lesser General Public License -~~helix84 (16.4.2007), Philverney (6.12.2005) David Vignoni - -Gtk-media-play-ltr.svg -http://commons.wikimedia.org/wiki/File:Gtk-media-play-ltr.svg -GNU Lesser General Public License -http://ftp.gnome.org/pub/GNOME/sources/gnome-themes-extras/0.9/gnome-themes-extras-0.9.0.tar.gz -David Vignoni - -US_states_by_total_state_tax_revenue.svg -http://commons.wikimedia.org/wiki/File:US_states_by_total_state_tax_revenue.svg -CC-BY 3.0 -TastyCakes on English Wikipedia - -greyscale-na-png.png, rgb-png.png, Xmp-exif-multilingual_test.jpg -greyscale-png.png, 1bit-png.png, Png-native-test.png, rgb-na-png.png, -test.tiff, test.jpg, jpeg-comment-multiple.jpg, jpeg-comment-utf.jpg, -jpeg-comment-iso8859-1.jpg, jpeg-comment-binary.jpg, jpeg-xmp-psir.jpg, -jpeg-xmp-alt.jpg, animated.gif, exif-user-comment.jpg, animated-xmp.gif, -iptc-timetest-invalid.jpg, jpeg-iptc-bad-hash.jpg, iptc-timetest.jpg, -xmp.png, nonanimated.gif, exif-gps.jpg, jpeg-xmp-psir.xmp, jpeg-iptc-good-hash.jpg, -jpeg-padding-even.jpg, jpeg-padding-odd.jpg -Are all by Bawolff. I don't think they contain enough originality to -claim copyright, but on the off chance they do, feel free to use them -however you feel fit, without restriction. - -Animated_PNG_example_bouncing_beach_ball.png -http://commons.wikimedia.org/wiki/File:Animated_PNG_example_bouncing_beach_ball.png (originally http://www.treebuilder.de/default.asp?file=89031.xml ) -Public Domain -Holger Will - diff --git a/tests/phpunit/data/media/Toll_Texas_1.svg b/tests/phpunit/data/media/Toll_Texas_1.svg deleted file mode 100644 index 73004e3e..00000000 --- a/tests/phpunit/data/media/Toll_Texas_1.svg +++ /dev/null @@ -1,150 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) --> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ - <!ENTITY ns_svg "http://www.w3.org/2000/svg"> - <!ENTITY ns_xlink "http://www.w3.org/1999/xlink"> -]> -<svg version="1.1" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="385" height="385.0004883" - viewBox="0 0 385 385.0004883" overflow="visible" enable-background="new 0 0 385 385.0004883" xml:space="preserve"> -<g> - <g> - <g> - <path fill="#FFFFFF" d="M0.5,24.5c0-13.2548828,10.7451172-24,24-24h336c13.2548828,0,24,10.7451172,24,24v336.0004883 - c0,13.2548828-10.7451172,24-24,24h-336c-13.2548828,0-24-10.7451172-24-24V24.5L0.5,24.5z"/> - <path fill="#FFFFFF" d="M192.5,192.5004883"/> - </g> - <g> - <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="3.863693" d="M0.5,24.5 - c0-13.2548828,10.7451172-24,24-24h336c13.2548828,0,24,10.7451172,24,24v336.0004883c0,13.2548828-10.7451172,24-24,24h-336 - c-13.2548828,0-24-10.7451172-24-24V24.5L0.5,24.5z"/> - <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="3.863693" d=" - M192.5,192.5004883"/> - </g> - </g> - <g> - <path fill="#003882" d="M24.5,0.5h336c13.2548828,0,24,10.7451172,24,24v232.0004883H0.5V24.5 - C0.5,11.2451172,11.2451172,0.5,24.5,0.5z"/> - </g> - <g> - <path fill="#FFFFFF" d="M10.5,24.5c0-7.7319336,6.2680664-14,14-14h336c7.7324219,0,14,6.2680664,14,14v222.0004883h-364V24.5z"/> - </g> - <g> - <polygon fill-rule="evenodd" clip-rule="evenodd" fill="#003882" points="93.809082,348.2397461 91.6787109,347.8666992 - 89.5478516,347.7368164 85.2929688,347.7368164 83.1640625,347.8666992 78.9042969,348.6157227 76.7763672,349.1166992 - 72.7666016,350.3706055 70.7631836,351.246582 68.8837891,352.121582 67.0053711,353.1254883 65.1254883,354.253418 - 63.3740234,355.5063477 60.1210938,358.2602539 58.4926758,359.762207 57.1132813,361.2641602 55.7338867,362.8959961 - 54.3603516,364.6459961 21.2949219,301.3999023 21.168457,301.3999023 22.5478516,299.6469727 23.9248047,298.0200195 - 25.3022461,296.5180664 26.9296875,295.0141602 30.1875,292.2592773 31.9404297,291.0073242 33.8188477,289.8793945 - 35.6972656,288.8774414 37.5761719,288.0004883 39.5791016,287.1245117 43.5878906,285.8706055 45.7148438,285.3706055 - 49.9755859,284.6176758 52.1020508,284.4946289 56.3632813,284.4946289 58.4926758,284.6176758 60.6201172,284.9946289 - 60.6201172,284.8696289 "/> - </g> - <g> - <polygon fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" points="32.8154297,319.559082 45.0898438,312.4233398 - 42.2080078,298.5209961 52.7299805,308.0375977 65.1254883,300.9008789 59.2421875,313.9243164 69.8867188,323.4428711 - 55.7338867,321.9389648 49.8476563,334.965332 46.9677734,321.0629883 "/> - </g> - <g> - <polygon fill-rule="evenodd" clip-rule="evenodd" fill="#B01C2E" points="132.0053711,306.6606445 148.5385742,338.2211914 - 147.4101563,339.7241211 146.1577148,341.2270508 144.9052734,342.6020508 143.5302734,343.9848633 142.1494141,345.2358398 - 140.6484375,346.4868164 139.2705078,347.6157227 137.765625,348.6157227 136.1381836,349.6176758 134.6357422,350.621582 - 133.0083008,351.3696289 131.3798828,352.246582 129.625,352.8745117 128,353.5024414 126.2441406,354.0004883 - 124.4921875,354.5043945 122.737793,354.8774414 120.9853516,355.1293945 117.4785156,355.3793945 113.9707031,355.3793945 - 112.09375,355.2543945 110.3408203,355.003418 108.5854492,354.6274414 106.9589844,354.253418 103.4501953,353.2485352 - 101.8232422,352.6254883 100.0688477,351.871582 98.4428711,351.1235352 96.9389648,350.1176758 95.3095703,349.2426758 - 93.809082,348.2397461 93.809082,348.1147461 93.809082,348.2397461 77.1523438,316.4282227 77.2753906,316.4282227 - 77.2753906,316.5551758 78.78125,317.5581055 80.4057617,318.4350586 81.9116211,319.4360352 83.5395508,320.1860352 - 85.2929688,320.9399414 86.9208984,321.5649414 90.4257813,322.5668945 92.0551758,322.9418945 93.809082,323.3188477 - 95.5620117,323.5688477 97.4423828,323.6948242 100.9462891,323.6948242 102.6992188,323.5688477 104.4521484,323.4428711 - 106.2060547,323.1928711 107.9609375,322.8168945 111.4682617,321.8168945 113.0947266,321.1889648 114.8481445,320.5639648 - 116.4765625,319.6879883 118.1035156,318.9350586 119.6083984,317.934082 121.2363281,316.9301758 122.737793,315.9282227 - 124.1152344,314.8012695 125.6196289,313.5483398 126.9960938,312.2983398 128.3759766,310.9194336 129.625,309.5424805 - 130.8789063,308.0375977 132.0053711,306.5366211 132.1328125,306.5366211 "/> - </g> - <g> - - <polyline fill="none" stroke="#003882" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="3.863693" points=" - 60.7441406,285.1196289 63,286.4956055 65.2529297,287.7485352 67.5068359,288.8774414 69.8867188,289.8793945 - 72.3916016,290.6313477 74.8955078,291.3813477 77.4008789,291.7583008 80.0302734,292.1333008 82.5366211,292.2592773 - 85.1655273,292.2592773 87.6708984,292.0083008 90.3022461,291.6313477 92.8066406,291.1313477 95.3095703,290.3793945 - 97.6904297,289.5024414 100.0688477,288.5004883 102.3256836,287.2504883 104.578125,285.8706055 106.7070313,284.4946289 - 108.7124023,282.8637695 110.5888672,281.1108398 112.3427734,279.2329102 114.0986328,277.2290039 115.5976563,275.1010742 "/> - </g> - <g> - - <line fill="none" stroke="#003882" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="3.863693" x1="115.4746094" y1="275.1010742" x2="131.8793945" y2="306.2836914"/> - </g> - <g> - <polygon fill-rule="evenodd" clip-rule="evenodd" fill="#003882" points="215.1650391,349.1166992 213.1601563,348.2397461 - 211.2832031,347.237793 207.7773438,344.7329102 206.1503906,343.2319336 204.6435547,341.7270508 203.2685547,340.0991211 - 202.0166016,338.347168 200.8867188,336.5942383 199.8857422,334.590332 199.0097656,332.7114258 198.2578125,330.7075195 - 197.6328125,328.5776367 197.1289063,326.5756836 196.7548828,324.4458008 196.6318359,322.3168945 196.6318359,320.0629883 - 196.7548828,317.934082 197.0058594,315.8041992 197.3818359,313.6743164 198.6357422,309.6665039 199.5107422,307.6635742 - 200.5126953,305.7827148 201.6386719,303.9067383 202.890625,302.152832 204.2685547,300.3989258 205.6464844,298.8969727 - 207.2744141,297.3920898 208.9023438,296.0161133 210.6572266,294.887207 212.5361328,293.7602539 214.4130859,292.7602539 - 216.4179688,291.8833008 218.5449219,291.0073242 220.6767578,290.2543945 222.9306641,289.6274414 227.4384766,288.8774414 - 229.6933594,288.6254883 231.9482422,288.5004883 234.2011719,288.5004883 236.4541016,288.6254883 238.7119141,288.8774414 - 240.9638672,289.253418 243.21875,289.7543945 245.3476563,290.3793945 247.6025391,291.1313477 249.6054688,292.0083008 - 251.7363281,293.0083008 251.7363281,292.8852539 253.6132813,294.137207 255.4931641,295.5151367 257.2460938,297.0161133 - 258.8740234,298.6459961 260.5019531,300.3989258 261.8808594,302.277832 263.1328125,304.1577148 264.2578125,306.2836914 - 266.0117188,310.543457 266.6386719,312.7983398 267.390625,317.3051758 267.5136719,319.6879883 267.390625,321.9418945 - 267.265625,324.3188477 266.2626953,328.8286133 265.5117188,330.9575195 264.6347656,333.2114258 263.6318359,335.2163086 - 262.5058594,337.2192383 261.1298828,339.0981445 259.625,340.9770508 258.1240234,342.6020508 256.3701172,344.1079102 - 254.4902344,345.6098633 252.6142578,346.8618164 250.609375,347.9926758 248.4785156,348.9926758 246.3496094,349.8696289 - 244.2216797,350.621582 242.0927734,351.246582 239.8359375,351.7485352 237.5830078,352.121582 235.3291016,352.3754883 - 232.9501953,352.4985352 230.6933594,352.4985352 228.4414063,352.3754883 226.1865234,352.121582 223.9296875,351.7485352 - 221.6777344,351.246582 219.421875,350.746582 217.2949219,349.9946289 "/> - </g> - <g> - <polygon fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" points="219.9238281,303.6547852 221.9287109,301.5258789 - 224.4335938,299.8999023 227.1904297,298.8969727 230.1943359,298.2700195 233.0742188,298.3959961 235.9550781,299.0219727 - 238.7119141,300.2739258 241.0898438,301.9018555 243.0957031,304.1577148 244.5957031,306.5366211 245.9746094,308.9145508 - 246.9765625,311.4204102 247.8535156,314.0512695 248.4785156,316.8051758 248.8535156,319.559082 248.9804688,322.3168945 - 248.9804688,325.0727539 248.6035156,327.8256836 248.1035156,330.5805664 247.3496094,333.2114258 246.3496094,335.7172852 - 244.9726563,337.8442383 243.34375,339.6000977 241.3408203,341.1020508 239.2109375,342.355957 236.8330078,343.2319336 - 234.4511719,343.6049805 231.9482422,343.7319336 229.4414063,343.3579102 227.1904297,342.6020508 224.9326172,341.4770508 - 222.9306641,340.0991211 221.1757813,338.347168 219.6748047,336.3422852 218.5449219,334.2114258 217.7949219,331.8334961 - 217.0449219,329.7036133 216.0419922,325.4477539 215.7910156,323.1928711 215.6660156,320.9399414 215.6660156,318.684082 - 215.9169922,316.4282227 216.1669922,314.300293 216.6679688,312.0454102 217.2949219,309.918457 218.0458984,307.7895508 - 218.9208984,305.7827148 219.9238281,303.7817383 "/> - </g> - <g> - <polygon fill-rule="evenodd" clip-rule="evenodd" fill="#003882" points="150.4169922,290.0063477 196.3789063,289.7543945 - 192.7470703,304.4067383 192.6220703,304.5307617 192.1210938,303.7817383 191.4960938,303.1567383 190.8681641,302.5288086 - 190.1162109,302.027832 189.2421875,301.652832 188.4887695,301.2768555 187.6113281,301.0258789 186.7353516,300.7758789 - 179.9741211,300.7758789 179.8481445,345.1098633 179.8481445,345.2358398 180.0966797,346.1118164 180.3486328,347.1157227 - 180.7246094,347.9926758 181.1005859,348.7407227 181.6015625,349.6176758 182.8549805,351.1235352 183.6054688,351.7485352 - 158.5556641,351.7485352 158.5556641,351.871582 159.3095703,351.246582 160.0595703,350.4956055 160.6845703,349.7426758 - 161.1875,348.9926758 161.6879883,347.9926758 161.9384766,347.1157227 162.1894531,346.1118164 162.3144531,345.1098633 - 162.4375,300.9008789 156.5527344,300.9008789 155.1767578,301.0258789 153.9248047,301.2768555 152.671875,301.5258789 - 151.4204102,301.9018555 150.1660156,302.4008789 148.9135742,303.0297852 146.6601563,304.2797852 146.6601563,304.4067383 "/> - </g> - <g> - <polygon fill-rule="evenodd" clip-rule="evenodd" fill="#003882" points="275.7822266,344.3598633 276.03125,298.1450195 - 275.90625,297.769043 275.90625,297.894043 275.7822266,296.7661133 275.5302734,295.7670898 275.15625,294.6391602 - 274.7792969,293.637207 272.8984375,291.0073242 272.0234375,290.2543945 272.1484375,290.2543945 297.4492188,290.1313477 - 296.4453125,290.8803711 295.5683594,291.6313477 294.6904297,292.5083008 294.0673828,293.5102539 293.5644531,294.6391602 - 293.1904297,295.7670898 293.0644531,297.0161133 293.0644531,298.2700195 293.0644531,298.1450195 293.1904297,298.1450195 - 293.0644531,340.7260742 292.9394531,340.7260742 294.8183594,341.3540039 296.8222656,341.8540039 298.7011719,342.1040039 - 300.7050781,342.355957 302.7070313,342.4799805 304.5878906,342.355957 306.5917969,342.2299805 308.46875,341.8540039 - 311.4746094,340.7260742 312.4765625,340.2231445 313.3535156,339.7241211 314.3535156,339.2241211 316.109375,337.972168 - 311.8505859,351.621582 271.3984375,351.7485352 272.3994141,351.1235352 273.2753906,350.3706055 274.0292969,349.6176758 - 275.2802734,347.6157227 275.53125,346.4868164 275.7822266,345.4858398 275.90625,344.2348633 "/> - </g> - <g> - <polygon fill-rule="evenodd" clip-rule="evenodd" fill="#003882" points="327.5058594,344.3598633 327.7539063,298.1450195 - 327.6308594,297.769043 327.6308594,297.894043 327.5058594,296.7661133 327.2539063,295.7670898 326.8769531,294.6391602 - 326.5029297,293.637207 324.6259766,291.0073242 323.7480469,290.2543945 323.8740234,290.2543945 349.171875,290.1313477 - 348.1708984,290.8803711 347.2929688,291.6313477 346.4179688,292.5083008 345.7890625,293.5102539 345.2871094,294.6391602 - 344.9121094,295.7670898 344.7890625,297.0161133 344.7890625,298.2700195 344.7890625,298.1450195 344.9121094,298.1450195 - 344.7890625,340.7260742 344.6640625,340.7260742 346.5410156,341.3540039 348.5458984,341.8540039 350.4238281,342.1040039 - 352.4277344,342.355957 354.4316406,342.4799805 356.3105469,342.355957 358.3144531,342.2299805 360.1933594,341.8540039 - 361.1933594,341.4770508 363.1992188,340.7260742 364.2011719,340.2231445 365.078125,339.7241211 366.0820313,339.2241211 - 367.8320313,337.972168 363.5751953,351.621582 323.1220703,351.7485352 324.125,351.1235352 325.0019531,350.3706055 - 325.7519531,349.6176758 327.0058594,347.6157227 327.2539063,346.4868164 327.5058594,345.4858398 327.6308594,344.2348633 "/> - </g> -</g> -<path fill-rule="evenodd" clip-rule="evenodd" fill="#003882" d="M188.4228516,211.0395508V89.7011719h-23.2304688V66.4711914 - c7.4140625-0.3291016,13.8393555-2.3886719,19.2763672-6.1782227c5.4365234-3.7890625,9.3085938-8.7314453,11.6152344-14.8276367 - h23.7236328v165.5742188H188.4228516z"/> -</svg> diff --git a/tests/phpunit/data/media/US_states_by_total_state_tax_revenue.svg b/tests/phpunit/data/media/US_states_by_total_state_tax_revenue.svg deleted file mode 100644 index 9afea859..00000000 --- a/tests/phpunit/data/media/US_states_by_total_state_tax_revenue.svg +++ /dev/null @@ -1,248 +0,0 @@ -<ns0:svg height="592.78998" id="svg2275" version="1.0" width="958.69" ns1:docbase="C:\Users\Adam\Desktop" ns1:docname="Blank_US_Map_with_borders.svg" ns1:version="0.32" ns2:output_extension="org.inkscape.output.svg.inkscape" ns2:version="0.46" xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:ns2="http://www.inkscape.org/namespaces/inkscape"> - <ns0:metadata id="metadata2625"> - <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> - <ns4:Work rdf:about="" xmlns:ns4="http://creativecommons.org/ns#"> - <ns5:format xmlns:ns5="http://purl.org/dc/elements/1.1/">image/svg+xml</ns5:format> - <ns5:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" xmlns:ns5="http://purl.org/dc/elements/1.1/" /> - </ns4:Work> - </rdf:RDF> - </ns0:metadata> - <ns0:defs id="defs2623"> - <ns2:perspective id="perspective226" ns1:type="inkscape:persp3d" ns2:persp3d-origin="479.345 : 197.59666 : 1" ns2:vp_x="0 : 296.39499 : 1" ns2:vp_y="0 : 1000 : 0" ns2:vp_z="958.69 : 296.39499 : 1" /> - </ns0:defs> - <ns1:namedview bordercolor="#666666" borderopacity="1.0" gridtolerance="10.0" guidetolerance="10.0" id="base" objecttolerance="10.0" pagecolor="#ffffff" showgrid="false" ns2:current-layer="svg2275" ns2:cx="479.345" ns2:cy="299.1307" ns2:pageopacity="0.0" ns2:pageshadow="2" ns2:window-height="820" ns2:window-width="1440" ns2:window-x="-8" ns2:window-y="-8" ns2:zoom="0.99941554" /> - <ns0:path d="M 798.49579,591.98217 L 799.73403,593.07468 L 802.54072,590.88965 L 807.98899,586.51962 L 811.78627,582.48573 L 814.3453,575.59451 L 815.3359,573.82969 L 815.501,570.30004 L 814.75805,570.80427 L 813.76746,573.74564 L 812.28156,578.53588 L 808.97958,583.99844 L 804.52191,588.36847 L 801.05483,590.38542 L 798.49579,591.98217 z M 784.71002,597.19259 L 787.18651,596.52028 L 788.5073,596.26817 L 789.99319,593.83102 L 792.38713,592.15024 L 793.70792,592.65448 L 795.44146,592.99063 L 795.8542,594.08315 L 792.30458,595.34374 L 788.012,596.85644 L 785.61807,598.11703 L 784.71002,597.19259 z M 657.3254,482.07418 L 660.96585,481.47149 L 667.07449,479.28647 L 673.18314,478.78224 L 677.6408,478.10993 L 685.40042,479.95879 L 693.65535,483.99266 L 695.30633,485.50536 L 698.2781,486.6819 L 699.92909,488.69884 L 700.25929,491.55616 L 703.56126,490.21154 L 707.52362,490.21154 L 711.15578,488.1946 L 714.95305,484.49689 L 718.08992,484.66497 L 718.58522,483.48842 L 717.75972,482.47995 L 717.92482,480.46302 L 722.05228,479.62263 L 724.69386,479.62263 L 727.66563,481.13533 L 731.95819,482.64803 L 734.43467,486.51382 L 737.24134,487.52229 L 738.39703,491.05193 L 741.8641,492.73271 L 743.51508,495.42195 L 745.49627,496.09427 L 750.77942,497.43889 L 752.1002,500.63237 L 755.23708,504.49816 L 755.23708,514.41476 L 753.75119,519.28902 L 754.08139,522.14634 L 755.40217,527.18868 L 757.21826,531.39063 L 758.04375,530.8864 L 759.52964,526.18021 L 756.88806,525.17175 L 756.55786,524.49943 L 758.20885,523.82712 L 762.83161,524.83559 L 762.9967,526.51637 L 759.69473,532.23102 L 757.54845,534.75219 L 761.18062,538.61798 L 763.8222,541.81146 L 766.79397,547.35803 L 769.76574,551.3919 L 771.91202,556.60232 L 773.7281,556.93847 L 775.37909,554.75346 L 777.19517,555.93001 L 779.83675,560.13195 L 780.49714,563.82967 L 783.63401,568.36777 L 784.4595,567.02315 L 788.42187,567.3593 L 792.05403,569.7124 L 795.5211,575.09089 L 796.34659,578.62053 L 796.67679,581.64593 L 797.83248,582.6544 L 799.15327,583.15863 L 801.62975,582.15016 L 803.11563,580.46938 L 807.078,580.3013 L 810.21487,578.7886 L 813.02154,575.42704 L 812.52624,573.41011 L 812.19605,570.88894 L 812.85644,568.87201 L 812.52624,566.85507 L 815.00272,565.51045 L 815.33292,561.98081 L 814.67252,560.13195 L 814.17723,547.69419 L 812.85644,539.79453 L 808.23368,531.22255 L 804.60152,525.17175 L 801.95994,519.62517 L 798.98817,516.59977 L 796.0164,508.86819 L 796.84189,507.52356 L 797.99758,506.17894 L 796.34659,503.15354 L 792.21913,499.28775 L 787.26618,493.5731 L 783.46891,487.01806 L 778.02066,477.26954 L 774.21165,467.14054 L 771.56179,458.12552" id="FL_Gulf" style="fill:#cccccc;fill-opacity:0;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 772.07835,458.61245 L 774.21165,467.14054 L 778.02066,477.26954 L 783.46891,487.01806 L 787.26618,493.5731 L 792.21913,499.28775 L 796.34659,503.15354 L 797.99758,506.17894 L 796.84189,507.52356 L 796.0164,508.86819 L 798.98817,516.59977 L 801.95994,519.62517 L 804.60152,525.17175 L 808.23368,531.22255 L 812.85644,539.79453 L 814.17723,547.69419 L 814.67252,560.13195 L 815.33292,561.98081 L 815.00272,565.51045 L 812.52624,566.85507 L 812.85644,568.87201 L 812.19605,570.88894 L 812.52624,573.41011 L 813.02154,575.42704 L 810.21487,578.7886 L 807.078,580.3013 L 803.11563,580.46938 L 801.62975,582.15016 L 799.15327,583.15863 L 797.83248,582.6544 L 796.67679,581.64593 L 796.34659,578.62053 L 795.5211,575.09089 L 792.05403,569.7124 L 788.42187,567.3593 L 784.4595,567.02315 L 783.63401,568.36777 L 780.49714,563.82967 L 779.83675,560.13195 L 777.19517,555.93001 L 775.37909,554.75346 L 773.7281,556.93847 L 771.91202,556.60232 L 769.76574,551.3919 L 766.79397,547.35803 L 763.8222,541.81146 L 761.18062,538.61798 L 757.54845,534.75219 L 759.69473,532.23102 L 762.9967,526.51637 L 762.83161,524.83559 L 758.20885,523.82712 L 756.55786,524.49943 L 756.88806,525.17175 L 759.52964,526.18021 L 758.04375,530.8864 L 757.21826,531.39063 L 755.40217,527.18868 L 754.08139,522.14634 L 753.75119,519.28902 L 755.23708,514.41476 L 755.23708,504.49816 L 752.1002,500.63237 L 750.77942,497.43889 L 745.49627,496.09427 L 743.51508,495.42195 L 741.8641,492.73271 L 738.39703,491.05193 L 737.24134,487.52229 L 734.43467,486.51382 L 731.95819,482.64803 L 727.66563,481.13533 L 724.69386,479.62263 L 722.05228,479.62263 L 717.92482,480.46302 L 717.75972,482.47995 L 718.58522,483.48842 L 718.08992,484.66497 L 714.95305,484.49689 L 711.15578,488.1946 L 707.52362,490.21154 L 703.56126,490.21154 L 700.25929,491.55616 L 699.92909,488.69884 L 698.2781,486.6819 L 695.30633,485.50536 L 693.65535,483.99266 L 685.40042,479.95879 L 677.6408,478.10993 L 673.18314,478.78224 L 667.07449,479.28647 L 660.96585,481.47149 L 657.41261,482.10878 L 657.16963,473.73948 L 654.52806,471.72255 L 652.71197,469.87369 L 653.04217,466.6802 L 663.44338,465.33558 L 689.52898,462.31017 L 696.46313,461.63786 L 702.73688,461.46977 L 705.37846,465.50365 L 706.86434,467.01635 L 714.95419,467.18443 L 726.00404,466.51212 L 747.97393,465.1675 L 753.53546,464.46636 L 758.21005,464.49519 L 758.37515,467.52059 L 761.01673,468.36098 L 761.34692,463.82287 L 759.69594,459.11668 L 760.85163,457.4359 L 766.79518,458.27629 L 772.07835,458.61245 z M 784.71002,597.19259 L 787.18651,596.52028 L 788.5073,596.26817 L 789.99319,593.83102 L 792.38713,592.15024 L 793.70792,592.65448 L 795.44146,592.99063 L 795.8542,594.08315 L 792.30458,595.34374 L 788.012,596.85644 L 785.61807,598.11703 L 784.71002,597.19259 z M 798.49579,591.98217 L 799.73403,593.07468 L 802.54072,590.88965 L 807.98899,586.51962 L 811.78627,582.48573 L 814.3453,575.59451 L 815.3359,573.82969 L 815.501,570.30004 L 814.75805,570.80427 L 813.76746,573.74564 L 812.28156,578.53588 L 808.97958,583.99844 L 804.52191,588.36847 L 801.05483,590.38542 L 798.49579,591.98217 z " id="FL" style="fill:#501616" /> - <ns0:path d="M 777.85557,425.66962 L 776.04071,426.6776 L 773.39913,425.33297 L 772.73874,423.14795 L 771.41795,419.45024 L 769.10656,417.26521 L 766.46499,416.5929 L 764.814,411.55057 L 762.00732,405.33167 L 757.71476,403.31473 L 755.56847,401.29779 L 754.24768,398.60854 L 752.1014,396.5916 L 749.79002,395.24697 L 747.47863,392.22157 L 744.34176,389.86848 L 739.71899,388.01961 L 739.2237,386.50691 L 736.74722,383.48151 L 736.25192,381.9688 L 732.78485,376.5903 L 729.31778,376.75838 L 725.19031,374.2372 L 723.86952,372.89258 L 723.53932,371.04372 L 724.36481,369.02679 L 726.67619,368.01831 L 726.346,365.8333 L 732.61975,363.14405 L 741.86527,358.43786 L 749.29471,357.59747 L 766.13479,357.09323 L 768.44617,359.11017 L 770.09715,362.47174 L 774.55482,361.9675 L 787.43252,360.45479 L 790.4043,361.29519 L 803.282,369.19486 L 813.60504,377.63896 L 808.06859,383.31398 L 805.42701,389.70094 L 804.93171,396.25598 L 803.28073,397.09637 L 802.12504,399.95369 L 799.64856,400.62601 L 797.50228,404.32372 L 794.69561,407.18104 L 792.38423,410.71068 L 790.73325,411.55107 L 787.10108,415.08071 L 784.12931,415.24879 L 785.1199,418.61034 L 780.00185,424.32499 L 777.85557,425.66962 z " id="SC" style="fill:#e9afaf" /> - <ns0:path d="M 704.71806,368.52255 L 699.7651,369.36294 L 691.17997,370.53949 L 682.42974,371.46391 L 682.42974,373.73297 L 682.59484,375.91799 L 683.25523,379.44763 L 686.72231,387.68346 L 689.19879,397.93623 L 690.68467,404.3232 L 692.33566,409.36554 L 693.82155,416.5929 L 695.96784,423.14795 L 698.60941,426.6776 L 699.10471,430.20724 L 701.0859,431.04763 L 701.251,433.23265 L 699.4349,438.27499 L 698.93961,441.63656 L 698.77451,443.65349 L 700.4255,448.19161 L 700.7557,453.73818 L 699.9302,456.25936 L 700.5906,457.09975 L 702.07649,457.94014 L 702.73688,461.46977 L 705.37846,465.50365 L 706.86434,467.01635 L 714.95419,467.18443 L 726.00404,466.51212 L 747.97393,465.1675 L 753.53546,464.46636 L 758.21005,464.49519 L 758.37515,467.52059 L 761.01673,468.36098 L 761.34692,463.82287 L 759.69594,459.11668 L 760.85163,457.4359 L 766.79518,458.27629 L 771.87844,458.60669 L 771.08653,452.05785 L 773.39791,441.63702 L 774.88379,437.26699 L 774.3885,434.57775 L 778.51596,427.3504 L 777.90454,425.66937 L 776.04071,426.6776 L 773.39913,425.33297 L 772.73874,423.14795 L 771.41795,419.45024 L 769.10656,417.26521 L 766.46499,416.5929 L 764.814,411.55057 L 762.00732,405.33167 L 757.71476,403.31473 L 755.56847,401.29779 L 754.24768,398.60854 L 752.1014,396.5916 L 749.79002,395.24697 L 747.47863,392.22157 L 744.34176,389.86848 L 739.71899,388.01961 L 739.2237,386.50691 L 736.74722,383.48151 L 736.25192,381.9688 L 732.78485,376.5903 L 729.31778,376.75838 L 725.19031,374.2372 L 723.86952,372.89258 L 723.53932,371.04372 L 724.36481,369.02679 L 726.67619,368.01831 L 726.51109,365.64481 L 724.69501,366.16945 L 718.75146,367.17792 L 711.65221,368.01831 L 704.71806,368.52255 z " id="GA" style="fill:#d35f5f" /> - <ns0:path d="M 639.33795,481.63956 L 637.68799,465.83981 L 634.88131,446.34274 L 635.04641,431.71994 L 635.8719,399.44893 L 635.7068,382.13688 L 635.87539,375.46299 L 643.79664,375.07759 L 672.19362,372.38834 L 682.58068,371.46391 L 682.42974,373.73297 L 682.59484,375.91799 L 683.25523,379.44763 L 686.72231,387.68346 L 689.19879,397.93623 L 690.68467,404.3232 L 692.33566,409.36554 L 693.82155,416.5929 L 695.96784,423.14795 L 698.60941,426.6776 L 699.10471,430.20724 L 701.0859,431.04763 L 701.251,433.23265 L 699.4349,438.27499 L 698.93961,441.63656 L 698.77451,443.65349 L 700.4255,448.19161 L 700.7557,453.73818 L 699.9302,456.25936 L 700.5906,457.09975 L 702.07649,457.94014 L 702.90198,461.63786 L 696.46313,461.63786 L 689.52898,462.31017 L 663.44338,465.33558 L 653.04217,466.6802 L 652.71197,469.87369 L 654.52806,471.72255 L 657.16963,473.73948 L 657.76284,481.98993 L 651.05994,484.66497 L 648.25327,484.32881 L 651.05994,482.31188 L 651.05994,481.30341 L 647.92307,475.08453 L 645.61169,474.41221 L 644.12581,478.95032 L 642.80502,481.80764 L 642.14462,481.63956 L 639.33795,481.63956 z " id="AL" style="fill:#e9afaf" /> - <ns0:path d="M 850.23842,306.65958 L 851.98478,311.54471 L 855.61694,318.26782 L 858.09342,320.78899 L 858.75382,323.14208 L 856.27734,323.31016 L 857.10283,323.98247 L 856.77263,328.3525 L 854.13106,329.69712 L 853.47066,331.88214 L 852.14988,334.90754 L 848.35261,336.58832 L 845.87614,336.25216 L 844.39025,336.08408 L 842.73926,334.73946 L 843.06946,336.08408 L 843.06946,337.09255 L 845.05064,337.09255 L 845.87614,338.43717 L 843.89495,344.99221 L 848.18751,344.99221 L 848.84791,346.67299 L 851.15929,344.3199 L 852.48007,343.81567 L 850.49889,347.51338 L 847.36202,352.55572 L 846.04123,352.55572 L 844.88554,352.05149 L 842.07887,352.7238 L 836.79572,355.24497 L 830.19178,360.79154 L 826.72471,365.6658 L 824.74353,372.38892 L 824.24824,374.91008 L 819.46038,375.41432 L 813.43993,377.723 L 803.282,369.19486 L 790.4043,361.29519 L 787.43252,360.45479 L 774.55482,361.9675 L 770.09715,362.47174 L 768.44617,359.11017 L 766.13479,357.09323 L 749.29471,357.59747 L 741.86527,358.43786 L 732.61975,363.14405 L 726.346,365.8333 L 724.69501,366.16945 L 718.75146,367.17792 L 711.65221,368.01831 L 704.71806,368.52255 L 705.04826,363.4802 L 706.86434,361.9675 L 709.67103,361.29519 L 710.33142,357.42939 L 714.62399,354.57206 L 718.58636,353.05935 L 722.87893,349.36164 L 727.33659,347.17662 L 727.99698,343.98313 L 731.95935,339.94926 L 732.61975,339.78119 C 732.61975,339.78119 732.61975,340.95773 733.44524,340.95773 C 734.27073,340.95773 735.42643,341.29389 735.42643,341.29389 L 737.73781,337.59616 L 739.88409,336.92385 L 742.19547,337.26001 L 743.84646,333.56229 L 746.81824,330.87303 L 747.31353,328.68802 L 747.31353,324.57011 L 751.9363,325.32646 L 759.22415,323.98183 L 775.38031,321.96489 L 792.88078,319.27565 L 813.92151,315.35219 L 833.49506,311.37597 L 845.21707,308.35056 L 850.23842,306.65958 z M 854.21672,340.95692 L 856.85831,338.3517 L 860.07773,335.66244 L 861.64617,334.99013 L 861.81127,332.88915 L 861.15088,326.50217 L 859.66499,324.06503 L 859.00459,322.13213 L 859.74753,321.88001 L 862.55422,327.59468 L 862.96697,332.21684 L 862.80187,335.74649 L 859.33479,337.34323 L 856.44555,339.86441 L 855.28987,341.125 L 854.21672,340.95692 z " id="NC" style="fill:#c83737" /> - <ns0:path d="M 712.3126,329.69649 L 659.31592,334.90691 L 643.2212,336.75577 L 638.50172,337.28883 L 634.55111,337.26001 L 634.55111,341.29389 L 625.96598,341.79812 L 618.86673,342.47043 L 607.53473,342.52544 L 607.26436,348.59252 L 605.08072,355.11718 L 604.06449,358.25292 L 602.68706,362.80789 L 602.35687,365.49714 L 598.22939,367.85023 L 599.71528,371.54796 L 598.72469,376.08606 L 597.15628,377.85089 L 605.49374,377.76685 L 630.09345,375.74991 L 635.54175,375.58184 L 643.79664,375.07759 L 672.19362,372.38834 L 682.58068,371.54796 L 691.17997,370.53949 L 699.7651,369.36294 L 704.71806,368.52255 L 705.04826,363.4802 L 706.86434,361.9675 L 709.67103,361.29519 L 710.33142,357.42939 L 714.62399,354.57206 L 718.58636,353.05935 L 722.87893,349.36164 L 727.33659,347.17662 L 727.99698,343.98313 L 731.95935,339.94926 L 732.61975,339.78119 C 732.61975,339.78119 732.61975,340.95773 733.44524,340.95773 C 734.27073,340.95773 735.42643,341.29389 735.42643,341.29389 L 737.73781,337.59616 L 739.88409,336.92385 L 742.19547,337.26001 L 743.84646,333.56229 L 746.81824,330.87303 L 747.31353,328.68802 L 747.49366,324.59981 L 745.16725,324.65414 L 742.69078,326.67109 L 734.60093,326.83916 L 722.3505,328.8153 L 712.3126,329.69649 z " id="TN" style="fill:#de8787" /> - <ns0:path d="M 893.09433,183.30123 L 892.6011,178.92994 L 891.77561,174.39182 L 890.04208,168.25697 L 895.90308,166.66023 L 897.55407,167.83677 L 901.02115,172.37489 L 903.99187,176.99768 L 901.01902,178.59507 L 899.69824,178.42699 L 898.54255,180.27585 L 896.06607,182.29279 L 893.09433,183.30123 z " id="RI" style="fill:#f4d7d7" /> - <ns0:path d="M 893.58963,183.30123 L 892.6011,178.92994 L 891.77561,174.39182 L 890.12463,168.17293 L 884.84146,169.34947 L 862.55312,174.30778 L 863.21351,177.75339 L 864.6994,185.31692 L 864.6994,193.72083 L 863.54371,196.07393 L 865.41508,198.26677 L 870.47581,194.73055 L 874.10797,191.36899 L 876.08916,189.18398 L 876.91465,189.85629 L 879.72132,188.34359 L 885.00447,187.16705 L 893.58963,183.30123 z " id="CT" style="fill:#de8787" /> - <ns0:path d="M 919.55232,177.09192 L 921.77043,176.37882 L 922.23741,174.59609 L 923.28809,174.71493 L 924.33877,177.09192 L 923.0546,177.56732 L 919.08535,177.68617 L 919.55232,177.09192 z M 909.97943,177.92387 L 912.31427,175.19033 L 913.94868,175.19033 L 915.81656,176.73537 L 913.36497,177.80501 L 911.14686,178.87466 L 909.97943,177.92387 z M 874.44023,155.06282 L 892.27091,150.69278 L 894.5823,150.02047 L 896.72858,146.65891 L 900.54482,144.92957 L 903.4955,149.51759 L 901.01902,154.89608 L 900.68883,156.40879 L 902.67001,159.09803 L 903.8257,158.25764 L 905.64178,158.25764 L 907.95316,160.94689 L 911.91552,167.16577 L 915.54769,167.67001 L 917.85907,166.66154 L 919.67515,164.81268 L 918.84966,161.95536 L 916.70338,160.27458 L 915.21749,161.11497 L 914.2269,159.77034 L 914.7222,159.26611 L 916.86848,159.09803 L 918.68456,159.93842 L 920.66574,162.45959 L 921.65633,165.48499 L 921.98653,168.00616 L 917.69397,169.51886 L 913.73161,171.5358 L 909.76924,176.24198 L 907.78806,177.75468 L 907.78806,176.74621 L 910.26454,175.23351 L 910.75983,173.38466 L 909.93434,170.19118 L 906.96257,171.70388 L 906.13708,173.21658 L 906.63237,175.56967 L 903.82678,177.08172 L 901.02115,172.37489 L 897.55407,167.83677 L 895.90308,166.66023 L 890.04208,168.25697 L 884.84146,169.34947 L 862.55312,174.30778 L 861.56253,168.34101 L 862.22292,157.33189 L 867.50608,156.40745 L 874.44023,155.06282" id="MA" style="fill:#c83737" /> - <ns0:path d="M 943.28423,76.73985 L 945.26541,78.924863 L 947.57679,82.790656 L 947.57679,84.807591 L 945.43051,89.68185 L 943.44933,90.354162 L 939.98226,93.547643 L 935.02931,99.262292 C 935.02931,99.262292 934.36891,99.262292 933.70852,99.262292 C 933.04813,99.262292 932.71793,97.077279 932.71793,97.077279 L 930.90185,97.245357 L 929.91126,98.758058 L 927.43478,100.27076 L 926.44419,101.78346 L 928.09517,103.29616 L 927.59988,103.96847 L 927.10458,106.8258 L 925.1234,106.65772 L 925.1234,104.97694 L 924.7932,103.63232 L 923.30732,103.96847 L 921.49123,100.60692 L 919.34495,101.95154 L 920.66574,103.46424 L 920.99594,104.64079 L 920.17045,105.98541 L 920.50064,109.17889 L 920.66574,110.85967 L 919.01476,113.54892 L 916.04298,114.05315 L 915.71279,117.07855 L 910.26454,120.27203 L 908.94375,120.77627 L 907.29277,119.26356 L 904.15589,122.96128 L 905.14649,126.32284 L 903.6606,127.66746 L 903.4955,132.20556 L 901.88477,140.12915 L 899.37016,138.9273 L 898.87486,135.73381 L 894.91249,134.55727 L 894.5823,131.69993 L 887.15284,107.32858 L 882.28553,91.967581 L 884.77927,91.608771 L 886.32526,92.034941 L 886.32526,89.345695 L 887.15075,83.631045 L 889.79233,78.756786 L 891.27821,74.554837 L 889.29703,72.033669 L 889.29703,65.814786 L 890.12252,64.806318 L 890.94802,61.948993 L 890.78292,60.436292 L 890.61782,55.393954 L 892.4339,50.351617 L 895.40568,41.107331 L 897.55196,36.737305 L 898.87274,36.737305 L 900.19353,36.905383 L 900.19353,38.081928 L 901.51432,40.435019 L 904.32099,41.107331 L 905.14649,40.266941 L 905.14649,39.258474 L 909.27395,36.233071 L 911.09003,34.384214 L 912.57592,34.552292 L 918.68456,37.073461 L 920.66574,38.081928 L 929.91126,69.176344 L 936.0199,69.176344 L 936.84539,71.193279 L 937.01049,76.235617 L 939.98226,78.588708 L 940.80775,78.588708 L 940.97285,78.084474 L 940.47756,76.907928 L 943.28423,76.73985 z M 921.90732,108.08415 L 923.47577,106.48741 L 924.87911,107.57992 L 925.45696,110.1011 L 923.72342,111.02553 L 921.90732,108.08415 z M 928.75894,101.94929 L 930.57502,103.88219 C 930.57502,103.88219 931.89582,103.96623 931.89582,103.63007 C 931.89582,103.29391 932.14346,101.52909 932.14346,101.52909 L 933.05151,100.6887 L 932.22602,98.839833 L 930.16228,99.596189 L 928.75894,101.94929 z " id="ME" style="fill:#f4d7d7" /> - <ns0:path d="M 900.54588,144.88986 L 900.85393,143.29871 L 901.96733,139.87704 L 899.37016,138.9273 L 898.87486,135.73381 L 894.91249,134.55727 L 894.5823,131.69993 L 887.15284,107.32858 L 882.45357,92.208279 L 881.5374,92.203019 L 880.87701,93.883799 L 880.21662,93.379565 L 879.22603,92.371097 L 877.74014,94.388032 L 876.76354,100.09176 L 877.08182,105.98396 L 879.063,108.84129 L 879.063,113.04325 L 875.26572,117.2452 L 872.62415,118.42176 L 872.62415,119.5983 L 873.77984,121.44716 L 873.77984,130.35531 L 872.95434,139.93577 L 872.78925,144.97812 L 873.77984,146.32275 L 873.61474,151.02894 L 873.11944,152.8778 L 874.60533,154.97877 L 892.27091,150.69278 L 894.5823,150.02047 L 896.72858,146.65891 L 900.54588,144.88986 z " id="NH" style="fill:#f4d7d7" /> - <ns0:path d="M 862.38802,157.584 L 861.56253,151.70126 L 858.42565,140.27193 L 857.76525,139.93577 L 854.79347,138.59115 L 855.61896,135.56574 L 854.79347,133.38072 L 852.1519,128.67453 L 853.14249,124.64065 L 852.31699,119.26214 L 849.84051,112.53901 L 849.0178,107.42109 L 876.75058,99.933872 L 877.08182,105.98396 L 879.063,108.84129 L 879.063,113.04325 L 875.26572,117.2452 L 872.62415,118.42176 L 872.62415,119.5983 L 873.77984,121.44716 L 873.77984,130.35531 L 872.95434,139.93577 L 872.78925,144.97812 L 873.77984,146.32275 L 873.61474,151.02894 L 873.11944,152.8778 L 874.60533,154.97877 L 867.50608,156.40745 L 862.38802,157.584 z " id="VT" style="fill:#f4d7d7" /> - <ns0:path d="M 846.20833,194.22506 L 845.05264,193.21659 L 842.41105,193.04851 L 840.09968,191.03158 L 837.62319,185.485 L 834.55471,184.51732 L 832.17493,182.29151 L 813.18856,186.49346 L 769.27227,195.56969 L 760.19184,197.08239 L 759.43798,189.88537 L 762.17121,188.00743 L 763.492,186.83089 L 764.48259,185.15011 L 766.29867,183.97356 L 768.27985,182.12471 L 768.77515,180.44393 L 770.92143,177.5866 L 772.07712,176.57814 L 771.91202,175.56967 L 770.59123,172.37619 L 768.77515,172.20811 L 766.79397,165.82115 L 769.76574,163.97229 L 774.2234,162.45959 L 778.35086,161.11497 L 781.65283,160.61073 L 788.09167,160.44266 L 790.07285,161.78728 L 791.72384,161.95536 L 793.87012,160.61073 L 796.51169,159.43419 L 801.79484,158.92995 L 803.94112,157.0811 L 805.75721,153.71954 L 807.40819,151.7026 L 809.55447,151.7026 L 811.53565,150.52606 L 811.70075,148.17297 L 810.21487,145.98795 L 809.88467,144.47525 L 811.04036,142.29024 L 811.04036,140.77754 L 809.22428,140.77754 L 807.40819,139.93715 L 806.5827,138.7606 L 806.4176,136.07136 L 812.36115,130.35671 L 813.02154,129.51632 L 814.50743,126.49092 L 817.4792,121.78473 L 820.28587,117.91894 L 822.43215,115.39777 L 824.89861,113.49969 L 828.0455,112.20429 L 833.65885,110.85967 L 836.96082,111.02775 L 841.58358,109.51505 L 849.30966,107.36166 L 849.84051,112.53901 L 852.31699,119.26214 L 853.14249,124.64065 L 852.1519,128.67453 L 854.79347,133.38072 L 855.61896,135.56574 L 854.79347,138.59115 L 857.76525,139.93577 L 858.42565,140.27193 L 861.56253,151.70126 L 862.05782,157.07976 L 861.56253,168.34101 L 862.38802,174.05567 L 863.21351,177.75339 L 864.6994,185.31692 L 864.6994,193.72083 L 863.54371,196.07393 L 865.42216,198.14582 L 865.19266,199.77289 L 863.21147,201.62175 L 863.54167,202.96637 L 864.86246,202.63021 L 866.34835,201.28559 L 868.65972,198.59634 L 869.81541,197.92403 L 871.4664,198.59634 L 873.77778,198.76442 L 881.8676,194.73055 L 884.83937,191.87323 L 886.16016,190.36053 L 890.45272,192.0413 L 886.98565,195.73902 L 883.02329,198.76442 L 875.75896,204.31099 L 873.11738,205.31946 L 867.17384,207.3364 L 863.04638,208.51294 L 861.49899,207.95886 L 860.90212,204.47784 L 861.39742,201.62051 L 861.23232,199.4355 L 858.59075,198.25894 L 853.96798,197.25047 L 850.0056,196.07393 L 846.20833,194.22506 z " id="NY" style="fill:#280b0b" /> - <ns0:path d="M 846.20833,194.22506 L 844.06205,196.74624 L 844.06205,199.93973 L 842.08086,203.13321 L 841.91576,204.814 L 843.23656,206.15862 L 843.07146,208.6798 L 840.76007,209.85635 L 841.58556,212.71367 L 841.75066,213.89023 L 844.55734,214.22639 L 845.54794,216.91563 L 849.18011,219.43681 L 851.65659,221.11759 L 851.65659,221.95798 L 848.35462,225.15147 L 846.70362,227.50456 L 845.21774,230.3619 L 842.90636,231.70652 L 841.66812,232.46288 L 841.42046,233.72347 L 840.79828,236.43369 L 841.91377,238.76697 L 845.21574,241.79237 L 850.1687,244.14546 L 854.29616,244.81777 L 854.46126,246.33047 L 853.63576,247.33894 L 853.96596,250.19627 L 854.79145,250.19627 L 856.93773,247.6751 L 857.76322,242.63276 L 860.5699,238.43081 L 863.70677,231.70769 L 864.86246,225.99305 L 864.20207,224.8165 L 864.03697,215.06798 L 862.38598,211.53834 L 861.23029,212.37873 L 858.42362,212.71489 L 857.92832,212.21066 L 859.08401,211.20219 L 861.23029,209.18525 L 861.29469,208.048 L 860.90212,204.47784 L 861.39742,201.62051 L 861.23232,199.4355 L 858.59075,198.25894 L 853.96798,197.25047 L 850.0056,196.07393 L 846.20833,194.22506 z " id="NJ" style="fill:#a02c2c" /> - <ns0:path d="M 841.75066,232.37883 L 842.90636,231.70652 L 845.21774,230.3619 L 846.70362,227.50456 L 848.35462,225.15147 L 851.65659,221.95798 L 851.65659,221.11759 L 849.18011,219.43681 L 845.54794,216.91563 L 844.55734,214.22639 L 841.75066,213.89023 L 841.58556,212.71367 L 840.76007,209.85635 L 843.07146,208.6798 L 843.23656,206.15862 L 841.91576,204.814 L 842.08086,203.13321 L 844.06205,199.93973 L 844.06205,196.74624 L 846.45598,194.22507 L 845.05264,193.21659 L 842.41105,193.04851 L 840.09968,191.03158 L 837.62319,185.485 L 834.55471,184.51732 L 832.17493,182.29151 L 813.18856,186.49346 L 769.27227,195.56969 L 760.19184,197.08239 L 759.68563,189.71729 L 754.08139,195.57094 L 752.7606,196.07518 L 748.46894,199.20351 L 751.4416,219.10066 L 753.16482,230.27806 L 756.81257,250.30417 L 761.54207,249.5232 L 773.73965,247.96108 L 812.47286,239.9916 L 827.66544,237.0562 L 836.14231,235.36944 L 837.45809,234.05962 L 839.60438,232.37883 L 841.75066,232.37883 z " id="PA" style="fill:#782121" /> - <ns0:path d="M 840.59298,235.90964 L 841.42046,233.72347 L 841.66812,232.37883 L 839.60438,232.37883 L 837.45809,234.05962 L 835.9722,235.57232 L 837.45809,239.94236 L 839.76948,245.8251 L 841.91576,255.9098 L 843.56675,262.46486 L 848.68482,262.29678 L 854.95755,261.03674 L 852.64517,253.38975 L 851.65458,253.89398 L 848.02242,251.37281 L 846.20633,246.49855 L 844.22515,242.80084 L 841.91377,241.79237 L 839.76749,238.09466 L 840.59298,235.90964 z " id="DE" style="fill:#f4d7d7" /> - <ns0:path d="M 854.95655,260.95325 L 848.68482,262.29678 L 843.56675,262.46486 L 841.91576,255.9098 L 839.76948,245.8251 L 837.45809,239.94236 L 836.14231,235.36944 L 827.66544,237.0562 L 812.47286,239.9916 L 774.22495,247.84224 L 775.38031,253.05285 L 776.37091,258.93558 L 776.7011,258.59942 L 778.84739,256.07825 L 781.15877,252.88476 L 783.63525,252.71668 L 785.12115,251.20398 L 786.93723,248.51473 L 788.25802,249.18705 L 791.22979,248.85089 L 793.87137,246.66588 L 795.92094,245.15492 L 797.80542,244.65068 L 799.48473,245.82549 L 802.45651,247.33819 L 804.43769,249.18705 L 805.67593,250.78379 L 809.88595,252.5486 L 809.88595,255.57402 L 815.49931,256.91864 L 817.48049,258.26326 L 818.47108,256.24633 L 820.78247,257.92711 L 819.29657,261.28868 L 818.96637,264.146 L 817.15029,266.83525 L 817.15029,269.02027 L 817.81068,270.86913 L 822.98233,272.27864 L 827.38511,272.21447 L 830.52198,273.22294 L 832.66826,273.5591 L 833.65885,271.37408 L 832.17296,269.18907 L 832.17296,267.34021 L 829.69649,265.1552 L 827.55021,259.44055 L 828.87099,253.89398 L 828.70589,251.70897 L 827.38511,250.36434 C 827.38511,250.36434 828.87099,248.68356 828.87099,248.01125 C 828.87099,247.33894 829.36629,245.82624 829.36629,245.82624 L 831.34747,244.48162 L 833.32865,242.80084 L 833.82395,243.8093 L 832.33806,245.49008 L 831.01727,249.35588 L 831.34747,250.53242 L 833.16355,250.86858 L 833.65885,256.58323 L 831.51257,257.59169 L 831.84277,261.28941 L 832.33806,261.12133 L 833.49375,259.1044 L 835.14473,260.95325 L 833.49375,262.29788 L 833.16355,265.82751 L 835.80513,269.35715 L 839.76749,269.86138 L 841.41848,269.02099 L 844.72045,274.39949 L 846.53653,274.90372 L 846.53653,278.60143 L 844.22515,283.64377 L 843.72986,290.87112 L 845.21574,294.40076 L 846.70163,294.56884 L 848.68281,290.19881 L 849.5083,286.5011 L 849.6734,279.10567 L 852.81027,274.06333 L 854.95655,266.83598 L 854.95655,260.95325 z M 838.20212,271.12031 L 839.3578,273.72552 L 839.5229,275.57439 L 840.67859,277.50729 C 840.67859,277.50729 841.58664,276.58285 841.58664,276.2467 C 841.58664,275.91054 840.8437,273.05321 840.8437,273.05321 L 840.10075,270.61606 L 838.20212,271.12031 z " id="MD" style="fill:#d35f5f" /> - <ns0:path d="M 822.59725,272.21447 L 827.38511,272.21447 L 830.52198,273.22294 L 832.66826,273.5591 L 833.65885,271.37408 L 832.17296,269.18907 L 832.17296,267.34021 L 829.69649,265.1552 L 827.55021,259.44055 L 828.87099,253.89398 L 828.70589,251.70897 L 827.38511,250.36434 C 827.38511,250.36434 828.87099,248.68356 828.87099,248.01125 C 828.87099,247.33894 829.36629,245.82624 829.36629,245.82624 L 831.34747,244.48162 L 833.32865,242.80084 L 833.82395,243.8093 L 832.33806,245.49008 L 831.01727,249.35588 L 831.34747,250.53242 L 833.16355,250.86858 L 833.65885,256.58323 L 831.51257,257.59169 L 831.84277,261.28941 L 832.33806,261.12133 L 833.49375,259.1044 L 835.14473,260.95325 L 833.49375,262.29788 L 833.16355,265.82751 L 835.80513,269.35715 L 839.76749,269.86138 L 841.41848,269.02099 L 844.72045,274.39949 L 846.53653,274.90372 L 846.53653,278.60143 L 844.22515,283.64377 L 843.72986,290.87112 L 845.21574,294.40076 L 846.70163,294.56884 L 848.68281,290.19881 L 849.5083,286.5011 L 849.6734,279.10567 L 852.81027,274.06333 L 854.95655,266.83598 L 854.95655,260.95325 M 838.20212,271.12031 L 839.3578,273.72552 L 839.5229,275.57439 L 840.67859,277.50729 C 840.67859,277.50729 841.58664,276.58285 841.58664,276.2467 C 841.58664,275.91054 840.8437,273.05321 840.8437,273.05321 L 840.10075,270.61606 L 838.20212,271.12031 z " id="MD_Atlantic" style="fill:#0000ff;fill-opacity:0;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 774.24466,247.91204 L 775.38031,253.05285 L 776.37091,258.93558 L 776.7011,258.59942 L 778.84739,256.07825 L 781.15877,252.88476 L 783.63525,252.71668 L 785.12115,251.20398 L 786.93723,248.51473 L 788.25802,249.18705 L 791.22979,248.85089 L 793.87137,246.66588 L 795.92094,245.15492 L 797.80542,244.65068 L 799.48473,245.82549 L 802.45651,247.33819 L 804.43769,249.18705 L 805.84103,250.53167 L 804.7679,255.7421 L 798.98943,252.5486 L 794.36667,250.69975 L 794.20157,256.24633 L 793.70628,258.43134 L 792.05529,261.28868 L 791.39489,262.96946 L 788.25802,265.49063 L 787.76272,267.84373 L 784.29564,268.17988 L 783.96545,271.37336 L 782.80976,277.08802 L 780.16818,277.08802 L 778.84739,276.24763 L 777.1964,273.3903 L 775.38031,273.55838 L 775.05012,278.09649 L 772.90384,284.9877 L 767.78577,296.24894 L 768.61127,297.59356 L 768.44617,300.45089 L 766.29989,302.46782 L 764.814,302.13167 L 761.51202,304.65285 L 758.87045,303.64438 L 757.05436,308.51864 C 757.05436,308.51864 753.25709,309.35903 752.59669,309.52711 C 751.9363,309.69518 750.12022,308.18248 750.12022,308.18248 L 747.64373,310.53557 L 745.00215,311.2079 L 742.03037,310.36749 L 740.70958,309.02287 L 738.47074,305.8795 L 735.26132,303.81246 L 732.61975,300.95512 L 729.64798,297.08933 L 728.98758,294.73623 L 726.346,293.22353 L 725.5205,291.54275 L 725.27285,286.0802 L 727.50168,285.99616 L 729.48288,285.15577 L 729.64798,282.29845 L 731.29896,280.78574 L 731.46406,275.57532 L 732.45465,271.54144 L 733.77544,270.86913 L 735.09623,272.04567 L 735.59153,273.89453 L 737.40761,272.88606 L 737.90291,271.20529 L 736.74722,269.35643 L 736.74722,266.83525 L 737.73781,265.49063 L 740.04919,261.96099 L 741.36998,260.44829 L 743.51627,260.95252 L 745.82765,259.27173 L 748.96452,255.7421 L 751.27591,251.70821 L 751.6061,245.82549 L 752.1014,240.61506 L 752.1014,235.74079 L 750.94571,232.54731 L 751.9363,231.0346 L 753.24707,229.68997 L 756.81257,250.30417 L 761.54207,249.5232 L 774.24466,247.91204 z " id="WV" style="fill:#f4d7d7" /> - <ns0:path d="M 738.61165,306.09768 L 735.42643,309.35903 L 731.13386,313.05675 L 726.51109,318.60333 L 724.69501,320.45219 L 724.69501,322.6372 L 720.73264,324.82222 L 714.95419,328.35186 L 712.28688,329.81359 L 659.31592,334.90691 L 643.2212,336.75577 L 638.50172,337.28883 L 634.55111,337.26001 L 634.55111,341.29389 L 625.96598,341.79812 L 618.86673,342.47043 L 608.21432,342.68419 L 609.24067,341.39196 L 611.46709,339.55999 L 613.56845,338.3715 L 613.80194,335.04372 L 614.73588,333.14213 L 613.09488,330.50244 L 613.91377,328.51994 L 616.22516,326.67109 L 618.37144,325.99877 L 621.17811,327.3434 L 624.81029,328.68802 L 625.96598,328.35186 L 626.13108,325.99877 L 624.81029,323.47759 L 625.14049,321.1245 L 627.12167,319.6118 L 629.76325,318.93949 L 631.41424,318.26718 L 630.58875,316.41831 L 629.92835,314.40138 L 631.08404,313.56099 L 632.15718,310.11537 L 635.2115,308.35056 L 641.15506,307.34209 L 644.78724,306.83786 L 646.27312,308.85479 L 648.08921,309.69518 L 649.90529,306.33362 L 652.87707,304.82092 L 654.85825,306.5017 L 655.68375,307.67825 L 657.83004,307.17401 L 657.66493,303.64438 L 660.63671,301.96359 L 661.7924,301.1232 L 662.94809,302.80398 L 667.73595,302.80398 L 668.56145,300.61896 L 668.23125,298.26587 L 671.20302,294.56815 L 675.99089,290.53428 L 676.48618,285.82809 L 679.29287,285.49193 L 683.25523,283.64307 L 686.06192,281.62613 L 685.73171,279.60919 L 684.24582,278.09649 L 684.82367,275.82744 L 689.03369,275.57532 L 691.51017,274.73493 L 694.48195,276.41571 L 696.13293,280.95382 L 702.07649,281.28997 L 703.89257,283.13884 L 706.03885,283.30692 L 708.51534,281.79422 L 711.65221,282.29845 L 712.973,283.81115 L 715.77968,281.12189 L 717.59577,279.77727 L 719.24675,279.77727 L 719.90714,282.63461 L 721.72324,283.64307 L 725.3554,285.82809 L 725.5205,291.54275 L 726.346,293.22353 L 728.98758,294.73623 L 729.64798,297.08933 L 732.61975,300.95512 L 735.26132,303.81246 L 738.61165,306.09768 z " id="KY" style="fill:#e9afaf" /> - <ns0:path d="M 748.46982,198.97029 L 741.20371,203.30253 L 737.24134,205.65562 L 733.77427,209.52141 L 729.64681,213.55528 L 726.34484,214.39567 L 723.37307,214.8999 L 717.75972,217.58915 L 715.61344,217.75723 L 712.14638,214.56375 L 706.86322,215.23606 L 704.22165,213.72336 L 701.78994,212.3189 L 696.79333,213.05024 L 686.39211,214.73102 L 678.46737,215.99161 L 679.78816,231.20268 L 681.60425,245.48932 L 684.24582,269.86066 L 684.82367,275.82744 L 689.03369,275.57532 L 691.51017,274.73493 L 694.48195,276.41571 L 696.13293,280.95382 L 702.07649,281.28997 L 703.89257,283.13884 L 706.03885,283.30692 L 708.51534,281.79422 L 711.65221,282.29845 L 712.973,283.81115 L 715.77968,281.12189 L 717.59577,279.77727 L 719.24675,279.77727 L 719.90714,282.63461 L 721.72324,283.64307 L 725.27285,286.0802 L 727.50168,285.99616 L 729.48288,285.15577 L 729.64798,282.29845 L 731.29896,280.78574 L 731.46406,275.57532 L 732.45465,271.54144 L 733.77544,270.86913 L 735.09623,272.04567 L 735.59153,273.89453 L 737.40761,272.88606 L 737.90291,271.20529 L 736.74722,269.35643 L 736.74722,266.83525 L 737.73781,265.49063 L 740.04919,261.96099 L 741.36998,260.44829 L 743.51627,260.95252 L 745.82765,259.27173 L 748.96452,255.7421 L 751.27591,251.70821 L 751.6061,245.82549 L 752.1014,240.61506 L 752.1014,235.74079 L 750.94571,232.54731 L 751.9363,231.0346 L 753.33994,230.27806 L 751.4416,219.10066 L 748.46982,198.97029 z " id="OH" style="fill:#c83737" /> - <ns0:path d="M 594.42414,81.655837 L 596.29202,79.516552 L 598.51013,78.684606 L 603.99703,74.643722 L 606.33188,74.049474 L 606.79885,74.524879 L 601.54544,79.873103 L 598.1599,81.893534 L 596.05854,82.844333 L 594.42414,81.655837 z M 682.43117,115.05941 L 683.09156,117.66462 L 686.39354,117.8327 L 687.71434,116.57211 C 687.71434,116.57211 687.63178,115.05941 687.30159,114.89133 C 686.97139,114.72326 685.6506,112.95843 685.6506,112.95843 L 683.42177,113.21054 L 681.77077,113.37862 L 681.44058,114.55518 L 682.43117,115.05941 z M 713.13697,180.61201 L 709.835,172.04003 L 707.52362,162.62767 L 705.04714,159.26611 L 702.40557,157.41725 L 700.75458,158.5938 L 696.79222,160.44266 L 694.81104,165.65307 L 692.00436,169.51886 L 690.84867,170.19118 L 689.36279,169.51886 C 689.36279,169.51886 686.72121,168.00616 686.88631,167.33385 C 687.05141,166.66154 687.38161,162.12343 687.38161,162.12343 L 690.84867,160.77881 L 691.67417,157.24918 L 692.33456,154.55993 L 694.81104,152.87915 L 694.48084,142.45832 L 692.82985,140.10523 L 691.50907,139.26484 L 690.68357,137.07982 L 691.50907,136.23943 L 693.16005,136.57559 L 693.32515,134.89481 L 690.84867,132.54172 L 689.52789,129.85247 L 686.88631,129.85247 L 682.26355,128.33977 L 676.6502,124.81014 L 673.84353,124.81014 L 673.18314,125.48245 L 672.19255,124.97821 L 669.05568,122.62512 L 666.0839,124.47398 L 663.11213,126.82707 L 663.44233,130.52479 L 664.43292,130.86094 L 666.5792,131.36518 L 667.07449,132.20556 L 664.43292,133.04595 L 661.79134,133.38211 L 660.30546,135.23097 L 659.97526,137.41598 L 660.30546,139.09676 L 660.63565,144.81141 L 657.00349,146.99642 L 656.34309,146.82834 L 656.34309,142.45832 L 657.66388,139.93715 L 658.32427,137.41598 L 657.49878,136.57559 L 655.5176,137.41598 L 654.52701,141.78601 L 651.72034,142.96255 L 649.90425,144.97949 L 649.73915,145.98795 L 650.39955,146.82834 L 649.73915,149.51759 L 647.42778,150.02182 L 647.42778,151.19837 L 648.25327,153.71954 L 647.09758,160.1065 L 645.44659,164.30845 L 646.10699,169.18271 L 646.60228,170.35925 L 645.77679,172.88042 L 645.44659,173.72081 L 645.1164,176.57814 L 648.74856,182.79702 L 651.72034,189.52014 L 653.20622,194.56247 L 652.38073,199.43673 L 651.39014,205.65562 L 648.91366,211.03411 L 648.58347,213.89143 L 645.43483,217.12572 L 644.67586,217.92491 L 649.40999,217.75643 L 671.86343,215.40333 L 678.13717,214.73102 L 678.46737,215.99161 L 686.39211,214.73102 L 696.79333,213.05024 L 702.12014,212.57103 L 700.75458,211.37027 L 700.91968,209.85756 L 703.06596,205.99177 L 705.10906,204.18493 L 704.88204,198.9325 L 706.51299,197.27212 L 707.62681,196.91556 L 707.85382,193.21785 L 709.42225,190.0664 L 710.49539,190.69668 L 710.66049,191.36899 L 711.48598,191.53707 L 713.46716,190.5286 L 713.13697,180.61201 z M 578.8376,112.43927 L 580.72799,111.3639 L 583.53467,110.52351 L 587.16683,108.17042 L 587.16683,107.16195 L 587.82723,106.48964 L 593.93587,105.48118 L 596.41235,103.46424 L 600.87001,101.27923 L 601.03511,99.934604 L 603.01629,96.909201 L 604.83237,96.068811 L 606.15316,94.219954 L 608.46454,91.866863 L 612.9222,89.345695 L 617.71005,88.841461 L 618.86574,90.018006 L 618.53554,91.026474 L 614.73828,92.034941 L 613.25239,95.228422 L 610.94101,96.068811 L 610.44572,98.58998 L 607.96924,101.95154 L 607.63904,104.64079 L 608.46454,105.14502 L 609.45513,103.96847 L 613.08729,100.94307 L 614.40808,102.28769 L 616.71946,102.28769 L 620.02143,103.29616 L 621.50732,104.47271 L 622.9932,107.66619 L 625.79988,110.52351 L 629.76224,110.35543 L 631.24813,109.34697 L 632.89911,110.69159 L 634.5501,111.19582 L 635.87088,110.35543 L 637.02657,110.35543 L 638.67756,109.34697 L 642.80502,105.64925 L 646.27209,104.47271 L 653.04112,104.13655 L 657.66388,102.11962 L 660.30546,100.77499 L 661.79134,100.94307 L 661.79134,106.8258 L 662.28664,107.16195 L 665.25841,108.00234 L 667.23959,107.49811 L 673.51333,105.81733 L 674.66902,104.64079 L 676.15491,105.14502 L 676.15491,112.37237 L 679.45688,115.56585 L 680.77767,116.23816 L 682.09845,117.24663 L 680.77767,117.58279 L 679.95217,117.24663 L 676.15491,116.7424 L 674.00863,117.41471 L 671.69725,117.24663 L 668.39528,118.75933 L 666.5792,118.75933 L 660.63565,117.41471 L 655.3525,117.58279 L 653.37132,120.27203 L 646.27209,120.94434 L 643.79561,121.78473 L 642.63992,124.97821 L 641.31913,126.15476 L 640.82384,125.98668 L 639.33795,124.3059 L 634.71519,126.82707 L 634.0548,126.82707 L 632.89911,125.14629 L 632.07362,125.31437 L 630.09244,129.85247 L 629.10185,134.05442 L 625.27363,142.51293 L 623.6083,141.31962 L 622.20739,139.89342 L 620.57299,129.197 L 616.83724,128.00851 L 615.43633,125.63153 L 602.59467,122.77914 L 600.02634,121.59066 L 591.62089,119.21367 L 583.21544,118.02518 L 578.8376,112.43927 z " id="MI" style="fill:#c83737" /> - <ns0:path d="M 363.20447,145.98954 L 351.44763,144.98362 L 318.67723,141.55738 L 302.09981,139.41809 L 273.14771,135.13952 L 252.83454,132.04945 L 251.38528,143.66906 L 247.4644,168.89268 L 242.09425,200.50655 L 240.53069,211.44019 L 238.82546,223.80098 L 245.48808,224.7662 L 262.73518,227.14318 L 271.75391,228.36645 L 292.76047,230.93187 L 330.81813,235.21041 L 355.80134,237.34972 L 360.23755,191.23625 L 361.87193,164.85174 L 363.20447,145.98954 z " id="WY" style="fill:#f4d7d7" /> - <ns0:path d="M 365.51098,123.96764 L 366.33647,111.87386 L 368.64299,85.935913 L 370.0439,70.247815 L 371.33142,55.452236 L 338.69364,52.032396 L 308.81082,48.334682 L 278.92799,44.132734 L 245.9083,38.586162 L 227.08707,35.056526 L 193.6675,27.848581 L 189.09322,50.043547 L 192.59549,57.887585 L 191.19458,62.64155 L 193.06246,67.395514 L 196.33125,68.821708 L 200.067,79.518133 L 203.80276,83.321298 L 204.26973,84.509794 L 207.772,85.698291 L 208.23897,87.837565 L 201.00095,106.14034 L 201.00095,108.75502 L 203.56928,112.08279 L 204.50321,112.08279 L 209.40639,108.99272 L 210.10685,107.80422 L 211.74124,108.51732 L 211.50775,113.98438 L 214.30957,127.05779 L 217.34487,129.67247 L 218.2788,130.38556 L 220.14668,132.76254 L 219.67972,136.32802 L 220.38017,139.89349 L 221.5476,140.84429 L 223.88244,138.4673 L 226.68426,138.4673 L 229.95305,140.13119 L 232.52138,139.1804 L 236.7241,139.1804 L 240.45985,140.84429 L 243.26167,140.36889 L 243.72864,137.27881 L 246.76394,136.56572 L 248.16485,137.99191 L 248.63182,141.31968 L 251.26853,143.90677 L 252.83454,132.04945 L 273.14771,135.13952 L 302.09981,139.41809 L 318.67723,141.55738 L 351.44763,144.98362 L 363.16317,146.23449 L 364.89307,129.69427 L 365.51098,123.96764 z " id="MT" style="fill:#f4d7d7" /> - <ns0:path d="M 144.08485,180.96023 L 148.93381,161.76187 L 153.37002,143.34026 L 154.77093,138.94284 L 157.33926,132.76269 L 156.0551,130.38571 L 153.48676,130.50455 L 152.66957,129.43491 L 153.13654,128.24642 L 153.48676,125.0375 L 158.03971,119.33273 L 159.90759,118.85734 L 161.07501,117.66885 L 161.65873,114.34107 L 162.59266,113.62798 L 166.5619,107.56668 L 170.53114,103.05041 L 170.76463,99.128389 L 167.26235,96.394856 L 165.91982,91.819167 L 166.32842,81.776422 L 170.06418,64.662142 L 174.61712,43.031605 L 178.46962,29.00742 L 179.24775,25.053259 L 193.6675,27.848581 L 189.09322,50.043547 L 192.59549,57.887585 L 191.19458,62.64155 L 193.06246,67.395514 L 196.33125,68.821708 L 200.067,79.518133 L 203.80276,83.321298 L 204.26973,84.509794 L 207.772,85.698291 L 208.23897,87.837565 L 201.00095,106.14034 L 201.00095,108.75502 L 203.56928,112.08279 L 204.50321,112.08279 L 209.40639,108.99272 L 210.10685,107.80422 L 211.74124,108.51732 L 211.50775,113.98438 L 214.30957,127.05779 L 217.34487,129.67247 L 218.2788,130.38556 L 220.14668,132.76254 L 219.67972,136.32802 L 220.38017,139.89349 L 221.5476,140.84429 L 223.88244,138.4673 L 226.68426,138.4673 L 229.95305,140.13119 L 232.52138,139.1804 L 236.7241,139.1804 L 240.45985,140.84429 L 243.26167,140.36889 L 243.72864,137.27881 L 246.76394,136.56572 L 248.16485,137.99191 L 248.63182,141.31968 L 251.31689,143.45897 L 247.4644,168.89268 L 242.21095,200.38777 L 237.30774,199.55589 L 228.78555,198.12969 L 218.27875,196.22811 L 206.02081,194.08882 L 193.0624,191.65242 L 184.89044,189.57255 L 175.43432,187.67098 L 165.51122,185.65054 L 144.08485,180.96023 z " id="ID" style="fill:#f4d7d7" /> - <ns0:path d="M 95.99889,2.9536428 L 100.45655,4.4663441 L 110.36246,7.3236687 L 119.11268,9.3406038 L 139.58489,15.223331 L 163.02887,21.106058 L 179.49525,24.969183 L 178.46962,29.00742 L 174.61712,43.031605 L 170.06418,64.662142 L 166.32842,81.776422 L 166.13328,91.861195 L 151.85237,88.313121 L 136.44238,84.628799 L 120.68217,84.747642 L 120.21521,83.321459 L 114.61157,85.460744 L 110.05862,84.866496 L 107.60703,83.202605 L 106.32286,83.915707 L 101.53644,83.678 L 99.785303,82.251817 L 94.415149,80.112532 L 93.597952,80.231386 L 89.161743,78.686338 L 87.177124,80.587926 L 80.873036,80.231386 L 74.802439,75.952816 L 75.50289,75.12087 L 75.736374,67.039124 L 73.401527,62.998262 L 69.198802,62.404014 L 68.498351,59.789335 L 66.094359,59.304248 L 64.13488,57.747045 L 62.318797,58.755513 L 60.007419,55.73011 L 60.337616,52.704708 L 63.14429,52.368552 L 64.795274,48.166604 L 62.153699,46.990058 L 62.318797,43.124266 L 66.776456,42.451954 L 63.969782,39.59463 L 62.483896,32.199201 L 63.14429,29.173799 L 63.14429,20.93798 L 61.328206,17.576422 L 63.639585,7.8279025 L 65.785865,8.3321363 L 68.262342,11.357539 L 71.069016,14.046786 L 74.370985,16.063721 L 78.993743,18.248734 L 82.130616,18.921045 L 85.102388,20.433747 L 88.569459,21.442214 L 90.880838,21.274136 L 90.880838,18.752967 L 92.201625,17.576422 L 94.347905,16.231799 L 94.678102,17.408344 L 95.008299,19.257201 L 92.696921,19.761435 L 92.366724,21.946448 L 94.182807,23.459149 L 95.338496,25.980318 L 95.99889,27.997253 L 97.484776,27.829175 L 97.649875,26.484552 L 96.659284,25.139928 L 96.163989,21.77837 L 96.989481,19.929513 L 96.329087,18.416812 L 96.329087,16.063721 L 98.14517,12.366006 L 96.989481,9.6767597 L 94.513004,4.634422 L 94.843201,3.7940324 L 95.99889,2.9536428 z M 86.341086,9.169955 L 88.404826,9.001877 L 88.900121,10.430545 L 90.468562,8.7497548 L 92.862495,8.7497548 L 93.687987,10.3465 L 92.119546,12.111324 L 92.779951,12.951724 L 92.037002,15.052704 L 90.63366,15.472893 C 90.63366,15.472893 89.725613,15.556938 89.725613,15.220782 C 89.725613,14.884626 91.21151,12.531524 91.21151,12.531524 L 89.477971,11.943246 L 89.147774,13.455958 L 88.404826,14.12827 L 86.836382,11.775168 L 86.341086,9.169955 z " id="WA" style="fill:#d35f5f" /> - <ns0:path d="M 224.65378,521.59843 L 226.52879,518.16091 L 228.7163,517.84841 L 229.0288,518.62966 L 226.99754,521.59843 L 224.65378,521.59843 z M 234.49758,518.00466 L 240.43511,520.50467 L 242.46637,520.19217 L 244.02887,516.44215 L 243.40387,513.16089 L 239.34135,512.69214 L 235.43508,514.41089 L 234.49758,518.00466 z M 264.18522,527.69221 L 267.77898,533.00473 L 270.12274,532.69223 L 271.2165,532.22348 L 272.62275,533.47348 L 276.21652,533.31723 L 277.15403,531.91098 L 274.34151,530.19222 L 272.4665,526.59845 L 270.43524,523.16094 L 264.81022,525.97345 L 264.18522,527.69221 z M 283.71656,536.286 L 284.96656,534.41099 L 289.49783,535.34849 L 290.12284,534.87974 L 296.06036,535.50474 L 295.74786,536.75475 L 293.24785,538.161 L 289.02908,537.8485 L 283.71656,536.286 z M 288.87283,541.28602 L 290.74784,545.03604 L 293.7166,543.94228 L 294.0291,542.37977 L 292.4666,540.34851 L 288.87283,540.03601 L 288.87283,541.28602 z M 295.59161,540.19226 L 297.77912,537.37975 L 302.31039,539.72351 L 306.52916,540.81727 L 310.74793,543.47353 L 310.74793,545.34854 L 307.31042,547.0673 L 302.62289,548.0048 L 300.27913,546.59854 L 295.59161,540.19226 z M 311.68544,555.19233 L 313.24794,553.94233 L 316.52921,555.50484 L 323.87299,558.94235 L 327.15426,560.97361 L 328.71676,563.31737 L 330.59177,567.53614 L 334.49804,570.03615 L 334.18554,571.28616 L 330.43552,574.41117 L 326.373,575.81743 L 324.96675,575.19243 L 321.99798,576.91118 L 319.65422,580.0362 L 317.46671,582.84871 L 315.74795,582.69246 L 312.31044,580.19245 L 311.99794,575.81743 L 312.62294,573.47367 L 311.06043,568.00489 L 309.02917,566.28613 L 308.87292,563.78612 L 311.06043,562.84862 L 313.09169,559.87986 L 313.56044,558.94235 L 311.99794,557.22359 L 311.68544,555.19233 z " id="HI_Pacific" style="fill:none;fill-opacity:0.26666697;stroke:#80b0f0;stroke-width:1pt" /> - <ns0:path d="M 224.65378,521.59843 L 226.52879,518.16091 L 228.7163,517.84841 L 229.0288,518.62966 L 226.99754,521.59843 L 224.65378,521.59843 z M 234.49758,518.00466 L 240.43511,520.50467 L 242.46637,520.19217 L 244.02887,516.44215 L 243.40387,513.16089 L 239.34135,512.69214 L 235.43508,514.41089 L 234.49758,518.00466 z M 264.18522,527.69221 L 267.77898,533.00473 L 270.12274,532.69223 L 271.2165,532.22348 L 272.62275,533.47348 L 276.21652,533.31723 L 277.15403,531.91098 L 274.34151,530.19222 L 272.4665,526.59845 L 270.43524,523.16094 L 264.81022,525.97345 L 264.18522,527.69221 z M 283.71656,536.286 L 284.96656,534.41099 L 289.49783,535.34849 L 290.12284,534.87974 L 296.06036,535.50474 L 295.74786,536.75475 L 293.24785,538.161 L 289.02908,537.8485 L 283.71656,536.286 z M 288.87283,541.28602 L 290.74784,545.03604 L 293.7166,543.94228 L 294.0291,542.37977 L 292.4666,540.34851 L 288.87283,540.03601 L 288.87283,541.28602 z M 295.59161,540.19226 L 297.77912,537.37975 L 302.31039,539.72351 L 306.52916,540.81727 L 310.74793,543.47353 L 310.74793,545.34854 L 307.31042,547.0673 L 302.62289,548.0048 L 300.27913,546.59854 L 295.59161,540.19226 z M 311.68544,555.19233 L 313.24794,553.94233 L 316.52921,555.50484 L 323.87299,558.94235 L 327.15426,560.97361 L 328.71676,563.31737 L 330.59177,567.53614 L 334.49804,570.03615 L 334.18554,571.28616 L 330.43552,574.41117 L 326.373,575.81743 L 324.96675,575.19243 L 321.99798,576.91118 L 319.65422,580.0362 L 317.46671,582.84871 L 315.74795,582.69246 L 312.31044,580.19245 L 311.99794,575.81743 L 312.62294,573.47367 L 311.06043,568.00489 L 309.02917,566.28613 L 308.87292,563.78612 L 311.06043,562.84862 L 313.09169,559.87986 L 313.56044,558.94235 L 311.99794,557.22359 L 311.68544,555.19233 z " id="HI" style="fill:#e9afaf" /> - <ns0:path d="M 365.08234,342.9472 L 388.2557,344.07626 L 420.00963,345.26475 L 418.60872,369.98537 L 418.14175,388.52584 L 418.37523,390.18973 L 422.81144,393.9929 L 424.9128,395.18139 L 425.61327,394.94369 L 426.31372,392.80441 L 427.71463,394.70599 L 429.81599,394.70599 L 429.81599,393.2798 L 432.6178,394.70599 L 432.15084,398.74687 L 436.35356,398.98457 L 438.92189,400.17306 L 443.12462,400.88615 L 445.69295,402.78774 L 448.02779,400.64846 L 451.53007,401.36155 L 454.0984,404.92703 L 455.03233,404.92703 L 455.03233,407.30401 L 457.36718,408.0171 L 459.70203,405.64012 L 461.5699,406.35321 L 464.13823,406.35321 L 465.07218,408.9679 L 469.97536,410.86948 L 471.37627,410.15638 L 473.24415,405.87781 L 474.41156,405.87781 L 475.57899,408.0171 L 479.78172,408.73019 L 483.51747,410.15638 L 486.55277,411.10718 L 488.42065,410.15638 L 489.1211,407.54171 L 493.55731,407.54171 L 495.65868,408.49249 L 498.46049,406.35321 L 499.62792,406.35321 L 500.32837,408.0171 L 504.53109,408.0171 L 506.16549,405.87781 L 508.03337,406.35321 L 510.13473,408.9679 L 513.40351,410.86948 L 516.6723,411.82028 L 519.47412,413.12761 L 521.80896,415.14805 L 524.84426,413.72186 L 527.64608,414.91035 L 528.33194,426.45357 L 528.34653,436.5409 L 529.04699,446.28652 L 529.74745,450.3274 L 532.31578,454.60597 L 533.24971,459.83533 L 537.68592,465.54009 L 537.9194,468.86787 L 538.61987,469.58096 L 537.9194,478.3758 L 534.88411,483.60516 L 536.5185,485.74444 L 535.81804,488.35912 L 535.11759,495.96547 L 533.71668,499.29324 L 534.00598,503.01936 L 527.40119,504.83432 L 517.33018,509.5405 L 516.33959,511.55743 L 513.69802,513.57437 L 511.55174,515.08707 L 510.23095,515.92746 L 504.4525,521.47403 L 501.64583,523.65904 L 496.19758,527.0206 L 490.41913,529.54177 L 483.98029,533.07141 L 482.16421,534.58411 L 476.22066,538.28182 L 472.7536,538.95414 L 468.79123,544.66878 L 464.66377,545.00494 L 463.67318,547.02188 L 465.98456,549.03881 L 464.49867,554.75346 L 463.17788,559.45964 L 462.0222,563.49351 L 461.1967,568.19969 L 462.0222,570.72086 L 463.83828,577.94821 L 464.82887,584.33517 L 466.64495,587.1925 L 465.65436,588.7052 L 462.51749,590.72214 L 456.73904,586.68827 L 451.1257,585.51172 L 449.80491,586.01595 L 446.50294,585.34364 L 442.21038,582.15016 L 436.92723,580.97362 L 429.1676,577.44398 L 427.02132,573.41011 L 425.70053,566.68699 L 422.39856,564.67006 L 421.73817,562.31697 L 422.39856,561.64466 L 422.72876,558.11502 L 421.40797,557.44271 L 420.74758,556.43424 L 422.06837,551.89614 L 420.41738,549.54304 L 417.11541,548.19842 L 413.64834,543.66032 L 410.01618,536.76912 L 405.72362,534.07988 L 405.88872,532.06294 L 400.44047,519.28902 L 399.61497,514.91899 L 397.79889,512.90206 L 397.63379,511.38936 L 391.52515,505.84279 L 388.88357,502.6493 L 388.88357,501.47276 L 386.242,499.28775 L 379.30786,498.1112 L 371.71333,497.43889 L 368.57646,495.0858 L 363.9537,496.93466 L 360.32154,498.44736 L 358.01016,501.80891 L 357.01957,505.67471 L 352.56191,512.06167 L 350.08543,514.58284 L 347.44386,513.57437 L 345.62777,512.39782 L 343.64659,511.72551 L 339.68423,509.37242 L 339.68423,508.70011 L 337.86815,506.68317 L 332.585,504.49816 L 324.99047,496.43042 L 322.67909,491.55616 L 322.67909,483.15227 L 319.37712,476.42915 L 318.88182,473.57182 L 317.23084,472.56336 L 316.07515,470.37834 L 310.9571,468.19333 L 309.63631,466.51255 L 302.37198,458.27673 L 301.05119,454.91517 L 296.26332,452.56207 L 294.77744,448.02394 L 292.13584,444.99855 L 290.15467,444.49434 L 289.49163,439.63101 L 297.66367,440.34413 L 327.31615,443.19648 L 356.96871,444.86037 L 359.30356,420.13975 L 363.27277,362.37936 L 364.90719,342.88781 L 366.3081,342.91754 M 467.38967,586.18345 L 466.81183,578.788 L 464.00514,571.30851 L 463.42729,563.99709 L 464.99573,555.42509 L 468.38027,548.28176 L 471.92989,542.65112 L 475.14933,538.95339 L 475.80972,539.20552 L 470.9393,546.09673 L 466.48163,552.90391 L 464.41788,559.79513 L 464.08769,565.17365 L 464.99573,571.56063 L 467.63732,579.04012 L 468.13261,584.41863 L 468.29771,585.93134 L 467.38967,586.18345 z " id="TX" style="fill:#280b0b" /> - <ns0:path d="M 140.74058,399.1133 L 144.96457,398.27159 L 146.48222,396.01346 L 147.06593,393.16108 L 143.33019,392.56684 L 142.86321,391.73489 L 143.33019,389.95216 L 143.44692,383.89086 L 145.54828,383.17775 L 148.46685,380.32538 L 149.05056,375.21486 L 150.56821,371.4117 L 152.55282,369.39125 L 156.0551,367.60852 L 157.68948,366.18234 L 157.80623,363.80536 L 156.75555,363.21111 L 155.93835,362.14147 L 154.65419,356.08016 L 151.85237,350.96965 L 152.44317,347.57226 L 149.86775,344.19525 L 135.04148,320.54427 L 115.19528,290.35661 L 91.963567,255.17727 L 79.318752,235.85757 L 80.989783,229.03046 L 88.111072,202.05171 L 96.399776,169.3682 L 82.624178,165.56503 L 68.848582,161.99955 L 56.006928,157.72098 L 48.301935,155.58169 L 36.627704,152.49162 L 29.426941,149.98419 L 27.813217,154.89608 L 27.648119,162.62767 L 22.364968,174.89736 L 19.228097,177.5866 L 18.8979,178.76315 L 17.081817,179.60354 L 15.595931,183.97356 L 14.770438,187.33512 L 17.577112,191.70515 L 19.228097,196.07518 L 20.383786,199.77289 L 20.053589,206.49601 L 18.237506,209.68949 L 17.577112,215.74029 L 16.586521,219.60608 L 18.402605,223.63995 L 21.209279,228.34614 L 23.520657,233.38847 L 24.841445,237.59042 L 24.511248,240.95198 L 24.181051,241.45621 L 24.181051,243.64123 L 29.959497,250.19627 L 29.464202,252.71743 L 28.803808,255.07053 L 28.143414,257.08746 L 28.308513,265.65943 L 30.454793,269.52523 L 32.435974,272.21447 L 35.242648,272.71871 L 36.233239,275.57603 L 35.07755,279.27375 L 32.93127,280.95453 L 31.775581,280.95453 L 30.950088,284.9884 L 31.445384,288.0138 L 34.747353,292.5519 L 36.398338,298.09847 L 37.884224,302.97273 L 39.205012,306.16621 L 42.672079,312.21702 L 44.157966,314.90627 L 44.653261,317.93167 L 46.304246,318.94014 L 46.304246,321.4613 L 45.478753,323.47824 L 43.66267,330.87367 L 43.167375,332.8906 L 45.643852,335.74793 L 49.936412,336.25216 L 54.559169,338.10102 L 58.521532,340.28603 L 61.493305,340.28603 L 64.465077,343.47951 L 67.106653,348.52185 L 68.262342,350.87494 L 72.224705,353.05995 L 77.177659,353.90034 L 78.663546,356.08536 L 79.32394,359.44692 L 77.838053,360.11923 L 78.16825,361.12769 L 81.470222,361.96808 L 84.276896,362.13616 L 87.248668,367.01042 L 91.211035,371.38045 L 92.036527,373.73354 L 94.678102,378.10356 L 95.008299,381.46512 L 95.008299,391.21364 L 95.503595,393.0625 L 105.7397,394.5752 L 125.88171,397.43253 L 140.74058,399.1133 z M 50.26694,346.75563 L 51.587732,348.35237 L 51.422633,349.697 L 48.120652,349.61296 L 47.542806,348.35237 L 46.88241,346.83966 L 50.26694,346.75563 z M 52.248128,346.75563 L 53.48637,346.08332 L 57.118549,348.26833 L 60.255432,349.52892 L 59.347387,350.20124 L 54.724613,349.94912 L 53.073623,348.26833 L 52.248128,346.75563 z M 73.380807,367.34524 L 75.19689,369.78238 L 76.022393,370.79086 L 77.590834,371.37912 L 78.168673,369.86642 L 77.178082,368.01756 L 74.453952,365.91658 L 73.380807,366.08465 L 73.380807,367.34524 z M 71.89491,376.33744 L 73.711004,379.61497 L 74.949248,381.63192 L 73.463351,381.88403 L 72.142563,380.62344 C 72.142563,380.62344 71.399615,379.11074 71.399615,378.69054 C 71.399615,378.27035 71.399615,376.42148 71.399615,376.42148 L 71.89491,376.33744 z " id="CA" style="fill:#280b0b" /> - <ns0:path d="M 141.11208,399.22238 L 138.4292,401.4664 L 138.099,402.9791 L 138.5943,403.98756 L 157.91082,415.08071 L 170.2932,422.98037 L 185.31716,431.8885 L 202.4874,442.30933 L 215.03489,444.8305 L 242.33612,448.47703 L 244.42909,434.63935 L 248.26156,406.64864 L 255.37454,351.33455 L 259.72234,319.30647 L 233.45531,315.31482 L 205.67064,310.56085 L 171.53056,303.99238 L 168.54652,322.80241 L 168.07955,323.2778 L 166.32842,326.01134 L 163.76009,325.89248 L 162.47592,323.04011 L 159.67411,322.68356 L 158.74017,321.49507 L 157.80623,321.49507 L 156.87229,322.08932 L 154.88767,323.15896 L 154.77093,330.40875 L 154.53744,332.19149 L 153.95374,345.26489 L 152.43609,347.52302 L 151.85237,350.96965 L 154.65419,356.08016 L 155.93835,362.14147 L 156.75555,363.21111 L 157.80623,363.80536 L 157.68948,366.18234 L 156.0551,367.60852 L 152.55282,369.39125 L 150.56821,371.4117 L 149.05056,375.21486 L 148.46685,380.32538 L 145.54828,383.17775 L 143.44692,383.89086 L 143.33019,389.95216 L 142.86321,391.73489 L 143.33019,392.56684 L 147.06593,393.16108 L 146.48222,396.01346 L 144.96457,398.27159 L 141.11208,399.22238 z " id="AZ" style="fill:#de8787" /> - <ns0:path d="M 144.08485,180.96023 L 165.51122,185.65054 L 175.43432,187.67098 L 184.89044,189.57255 L 193.12078,191.77126 L 191.89498,197.53545 L 188.27597,215.71936 L 184.42347,236.99336 L 182.43886,246.26359 L 180.22075,260.40663 L 176.83522,277.63975 L 173.56644,293.44668 L 171.55619,304.36486 L 168.54652,322.80241 L 168.07955,323.2778 L 166.32842,326.01134 L 163.76009,325.89248 L 162.47592,323.04011 L 159.67411,322.68356 L 158.74017,321.49507 L 157.80623,321.49507 L 156.87229,322.08932 L 154.88767,323.15896 L 154.77093,330.40875 L 154.53744,332.19149 L 153.95374,345.26489 L 152.43963,347.54764 L 149.86775,344.19525 L 135.04148,320.54427 L 115.19528,290.35661 L 91.963567,255.17727 L 79.318752,235.85757 L 80.989783,229.03046 L 88.111072,202.05171 L 96.166292,169.45944 L 130.48854,177.92533 L 144.49761,181.0154" id="NV" style="fill:#e9afaf" /> - <ns0:path d="M 259.6056,319.59339 L 233.45531,315.31482 L 205.67064,310.56085 L 171.45228,304.13508 L 173.56644,293.44668 L 176.83522,277.63975 L 180.22075,260.40663 L 182.43886,246.26359 L 184.42347,236.99336 L 188.27597,215.71936 L 191.89498,197.53545 L 193.03322,191.74155 L 206.02081,194.08882 L 218.27875,196.22811 L 228.78555,198.12969 L 237.30774,199.55589 L 242.21095,200.38777 L 240.53069,211.44019 L 238.82546,223.80098 L 245.48808,224.7662 L 262.73518,227.14318 L 272.10412,228.36648 L 268.94498,251.37398 L 265.6762,274.66841 L 261.84373,303.76606 L 260.30605,315.31482 L 259.6056,319.59339 z " id="UT" style="fill:#e9afaf" /> - <ns0:path d="M 384.05299,331.95365 L 388.2557,263.49654 L 389.8901,240.2021 L 355.80134,237.34972 L 330.81813,235.21041 L 292.76047,230.93187 L 271.63008,228.31722 L 268.94498,251.37398 L 265.6762,274.66841 L 261.84373,303.76606 L 260.30605,315.31482 L 259.72234,319.35569 L 294.86179,323.63426 L 332.58567,328.23704 L 366.04543,330.52751 L 372.84567,331.2406 L 384.5199,331.83485" id="CO" style="fill:#e9afaf" /> - <ns0:path d="M 290.31977,444.66242 L 289.49163,439.63101 L 297.66367,440.34413 L 327.31615,443.19648 L 356.96871,444.86037 L 359.30356,420.13975 L 363.27277,362.37936 L 364.90719,342.88781 L 366.3081,342.91754 L 366.29351,330.73549 L 332.58567,328.23704 L 294.86179,323.63426 L 259.66398,319.35569 L 255.37454,351.33455 L 248.26156,406.64864 L 244.42909,434.63935 L 242.33612,448.47703 L 258.12559,450.54515 L 259.44637,440.12432 L 276.45152,442.81356 L 290.31977,444.66242 z " id="NM" style="fill:#e9afaf" /> - <ns0:path d="M 144.38087,180.54003 L 148.93381,161.76187 L 153.37002,143.34026 L 154.77093,138.94284 L 157.33926,132.76269 L 156.0551,130.38571 L 153.48676,130.50455 L 152.66957,129.43491 L 153.13654,128.24642 L 153.48676,125.0375 L 158.03971,119.33273 L 159.90759,118.85734 L 161.07501,117.66885 L 161.65873,114.34107 L 162.59266,113.62798 L 166.5619,107.56668 L 170.53114,103.05041 L 170.76463,99.128389 L 167.26235,96.394856 L 166.19165,92.03947 L 151.85237,88.313121 L 136.44238,84.628799 L 120.68217,84.747642 L 120.21521,83.321459 L 114.61157,85.460744 L 110.05862,84.866496 L 107.60703,83.202605 L 106.32286,83.915707 L 101.53644,83.678 L 99.785303,82.251817 L 94.415149,80.112532 L 93.597952,80.231386 L 89.161743,78.686338 L 87.177124,80.587926 L 80.873036,80.231386 L 74.802439,75.952816 L 75.50289,75.12087 L 75.736374,67.039124 L 73.401527,62.998262 L 69.198802,62.404014 L 68.498351,59.789335 L 66.094359,59.304248 L 60.172517,61.44476 L 57.861139,68.167876 L 54.559169,78.588708 L 51.2572,85.311824 L 46.139147,99.934604 L 39.535209,114.05315 L 31.280285,127.16323 L 29.299104,130.18863 L 28.473611,139.09676 L 27.152823,145.31564 L 29.426941,149.98419 L 36.627704,152.49162 L 48.301935,155.58169 L 56.006928,157.72098 L 68.848582,161.99955 L 82.624178,165.56503 L 96.399776,169.60589 M 144.08485,180.96023 L 96.166292,169.45944 L 130.48854,177.92533 L 144.49761,181.0154" id="OR" style="fill:#e9afaf" /> - <ns0:path d="M 482.58353,129.91009 L 481.88308,121.11525 L 480.0152,113.50891 L 478.14732,99.484714 L 477.68036,89.263683 L 475.81248,85.698205 L 474.17808,80.468846 L 474.17808,69.772421 L 474.87853,65.731548 L 472.88209,60.014242 L 442.87077,59.427825 L 423.88445,58.755513 L 396.8083,57.410889 L 371.33142,55.452236 L 370.0439,70.247815 L 368.64299,85.935913 L 366.33647,111.87386 L 365.67607,124.49947 L 423.04492,128.24621 L 482.58353,129.91009 z " id="ND" style="fill:#f4d7d7" /> - <ns0:path d="M 484.10703,208.42015 L 483.13305,206.29529 L 481.4161,203.35887 L 483.28398,198.8426 L 484.6849,192.90014 L 481.88308,190.76086 L 481.4161,187.90848 L 482.35005,185.29379 L 484.21793,185.29379 L 484.6849,178.16284 L 484.45141,146.54897 L 483.98444,143.4589 L 479.78172,139.89342 L 478.61429,137.99183 L 478.61429,136.32794 L 480.71565,134.66406 L 482.11657,133.23787 L 482.4668,129.91009 L 423.04492,128.24621 L 365.67608,124.20534 L 364.89307,129.69427 L 363.24575,146.19243 L 361.87193,164.85174 L 360.23755,191.5928 L 376.1145,192.66245 L 396.66115,193.85093 L 414.87297,195.03943 L 439.15538,196.22791 L 450.12916,195.75252 L 452.23052,198.1295 L 457.1337,201.21959 L 458.30112,202.17037 L 462.73733,200.74418 L 466.70658,200.26879 L 469.50839,200.03109 L 471.37627,201.45728 L 476.51293,203.12117 L 479.54822,204.78505 L 480.0152,206.44894 L 480.94914,208.58823 L 482.81702,208.58823 L 484.10703,208.42015 z " id="SD" style="fill:#f4d7d7" /> - <ns0:path d="M 496.12564,252.80011 L 497.52656,255.41479 L 497.29307,257.79177 L 499.8614,261.83265 L 503.13018,266.11122 L 496.82609,266.11122 L 451.76325,265.63581 L 410.43676,264.20963 L 388.13897,263.37769 L 389.8901,240.2021 L 355.80134,237.34972 L 360.23755,191.5928 L 376.1145,192.66245 L 396.66115,193.85093 L 414.87297,195.03943 L 439.15538,196.22791 L 450.12916,195.75252 L 452.23052,198.1295 L 457.1337,201.21959 L 458.30112,202.17037 L 462.73733,200.74418 L 466.70658,200.26879 L 469.50839,200.03109 L 471.37627,201.45728 L 476.51293,203.12117 L 479.54822,204.78505 L 480.0152,206.44894 L 480.94914,208.58823 L 482.81702,208.58823 L 484.45141,208.46938 L 485.61883,214.05529 L 488.42065,221.89933 L 489.35459,226.891 L 491.68943,230.69417 L 492.38988,236.16123 L 494.02428,240.4398 L 494.25776,247.33306 L 496.23653,253.05224" id="NE" style="fill:#f4d7d7" /> - <ns0:path d="M 580.12177,205.73586 L 580.18014,207.63744 L 582.51499,208.35053 L 583.44892,209.53902 L 583.91589,211.44061 L 587.88513,215.00608 L 588.58559,217.38307 L 587.88513,220.94855 L 586.01725,224.75171 L 585.3168,227.36639 L 582.98196,229.26798 L 581.11408,229.98108 L 575.74393,231.40726 L 575.04347,233.30885 L 574.34302,235.44814 L 575.04347,236.87433 L 576.91135,238.53822 L 576.67787,242.81678 L 574.80999,244.48067 L 574.10954,246.14456 L 574.10954,248.99694 L 572.24166,249.47233 L 570.60726,250.66083 L 570.37378,252.08702 L 570.60726,254.22631 L 568.85613,256.06846 L 565.4706,252.56242 L 564.30317,250.18543 L 556.3647,250.89852 L 546.32485,251.37392 L 520.40805,252.32472 L 506.63246,252.56242 L 497.05959,252.80011 L 495.9476,252.92617 L 494.25776,247.33306 L 494.02428,240.4398 L 492.38988,236.16123 L 491.68943,230.69417 L 489.35459,226.891 L 488.42065,221.89933 L 485.61883,214.05529 L 484.45141,208.46938 L 483.0505,206.21125 L 481.4161,203.35887 L 483.28398,198.8426 L 484.6849,192.90014 L 481.88308,190.76086 L 481.4161,187.90848 L 482.35005,185.29379 L 484.10119,185.29379 L 495.89216,185.29379 L 546.55834,184.5807 L 565.00364,183.86761 L 569.20636,183.74877 L 569.90681,187.19538 L 572.24166,188.85927 L 572.47514,190.28546 L 570.37378,193.85093 L 570.60726,197.17871 L 573.1756,201.21959 L 575.74393,202.40807 L 578.77923,202.88347 L 580.12177,205.73586 z " id="IA" style="fill:#e9afaf" /> - <ns0:path d="M 639.20393,481.84625 L 638.01716,483.15227 L 632.73401,483.15227 L 631.24813,482.31188 L 629.10185,481.97572 L 622.16771,483.99266 L 620.35163,483.15227 L 617.71005,487.52229 L 616.58406,488.3312 L 615.43633,485.74444 L 614.2689,481.70357 L 610.76664,478.3758 L 611.93406,470.53175 L 611.23361,469.58096 L 609.36573,469.81866 L 600.96028,470.53175 L 576.2109,471.24485 L 575.74393,469.58096 L 576.44438,461.26152 L 579.94666,454.84366 L 585.3168,445.33573 L 584.38287,443.19645 L 585.55029,443.19645 L 586.25075,439.86868 L 583.91589,437.96709 L 584.14938,436.0655 L 582.04802,431.31154 L 581.75616,425.75534 L 583.15706,422.99209 L 582.74847,418.47583 L 581.34756,415.38574 L 582.74847,413.95956 L 581.34756,411.82028 L 581.81454,409.91869 L 582.74847,403.50083 L 585.78377,400.64846 L 585.08332,398.50917 L 588.81908,393.0421 L 591.62089,392.09132 L 591.62089,389.47664 L 590.92044,388.05044 L 593.72225,382.58339 L 596.52407,381.39489 L 596.63379,377.84737 L 605.49374,377.76685 L 630.09345,375.74991 L 635.69855,375.51222 L 635.7068,382.13688 L 635.8719,399.44893 L 635.04641,431.71994 L 634.88131,446.34274 L 637.68799,465.83981 L 639.20393,481.84625 z " id="MS" style="fill:#e9afaf" /> - <ns0:path d="M 632.23973,310.19942 L 632.07463,306.16555 L 632.56993,301.45935 L 634.88131,298.43395 L 636.6974,294.40007 L 639.33898,290.03004 L 638.84368,283.97923 L 637.0276,281.12189 L 636.6974,277.76034 L 637.52289,272.04567 L 637.0276,264.81831 L 635.7068,248.17858 L 634.38601,232.21115 L 633.3949,220.02589 L 636.53128,220.95071 L 638.01716,221.95917 L 639.17285,221.62302 L 641.31913,219.60608 L 644.20888,217.92491 L 649.40999,217.75643 L 671.86343,215.40333 L 678.13717,214.73102 L 678.30227,215.90756 L 679.78816,231.20268 L 681.60425,245.48932 L 684.24582,269.86066 L 684.74112,275.7434 L 684.24582,278.09649 L 685.73171,279.60919 L 686.06192,281.62613 L 683.25523,283.64307 L 679.29287,285.49193 L 676.48618,285.82809 L 675.99089,290.53428 L 671.20302,294.56815 L 668.23125,298.26587 L 668.56145,300.61896 L 667.73595,302.80398 L 662.94809,302.80398 L 661.7924,301.1232 L 660.63671,301.96359 L 657.66493,303.64438 L 657.83004,307.17401 L 655.68375,307.67825 L 654.85825,306.5017 L 652.87707,304.82092 L 649.90529,306.33362 L 648.08921,309.69518 L 646.27312,308.85479 L 644.78724,306.83786 L 641.15506,307.34209 L 635.2115,308.35056 L 632.23973,310.19942 z " id="IN" style="fill:#de8787" /> - <ns0:path d="M 632.07463,310.03134 L 632.07463,306.16555 L 632.56993,301.45935 L 634.88131,298.43395 L 636.6974,294.40007 L 639.33898,290.03004 L 638.84368,283.97923 L 637.0276,281.12189 L 636.6974,277.76034 L 637.52289,272.04567 L 637.0276,264.81831 L 635.7068,248.17858 L 634.38601,232.21115 L 633.56001,220.10992 L 632.23872,219.26993 L 631.41322,216.58068 L 630.09244,212.71489 L 628.44145,210.86603 L 626.95557,208.17679 L 626.71703,202.46993 L 616.60376,203.83427 L 588.81909,205.617 L 579.94666,205.17133 L 580.18014,207.63744 L 582.51499,208.35053 L 583.44892,209.53902 L 583.91589,211.44061 L 587.88513,215.00608 L 588.58559,217.38307 L 587.88513,220.94855 L 586.01725,224.75171 L 585.3168,227.36639 L 582.98196,229.26798 L 581.11408,229.98108 L 575.74393,231.40726 L 575.04347,233.30885 L 574.34302,235.44814 L 575.04347,236.87433 L 576.91135,238.53822 L 576.67787,242.81678 L 574.80999,244.48067 L 574.10954,246.14456 L 574.10954,248.99694 L 572.24166,249.47233 L 570.60726,250.66083 L 570.37378,252.08702 L 570.60726,254.22631 L 568.85613,255.59306 L 567.80545,258.50488 L 568.27242,262.30804 L 570.60726,269.91439 L 578.07878,277.75843 L 583.68241,281.56161 L 583.44892,286.07787 L 584.38287,287.50407 L 590.92044,287.97946 L 593.72225,289.40566 L 593.0218,293.20882 L 590.68696,299.38898 L 589.98649,302.71676 L 592.32134,306.75762 L 598.85891,312.22469 L 603.52862,312.93778 L 605.62997,318.16715 L 607.73133,321.49492 L 606.7974,324.58499 L 608.43179,328.86356 L 610.29967,331.00285 L 613.32836,330.65102 L 613.91377,328.51994 L 616.22516,326.67109 L 618.37144,325.99877 L 621.17811,327.3434 L 624.81029,328.68802 L 625.96598,328.35186 L 626.13108,325.99877 L 624.81029,323.47759 L 625.14049,321.1245 L 627.12167,319.6118 L 629.76325,318.93949 L 631.41424,318.26718 L 630.58875,316.41831 L 629.92835,314.40138 L 631.08404,313.56099 L 632.07463,310.03134 z " id="IL" style="fill:#782121" /> - <ns0:path d="M 482.35005,129.91009 L 481.88308,121.11525 L 480.0152,113.50891 L 478.14732,99.484714 L 477.68036,89.263683 L 475.81248,85.698205 L 474.17808,80.468846 L 474.17808,69.772421 L 474.87853,65.731548 L 473.01887,60.063466 L 503.79211,60.100136 L 504.1223,51.528162 L 504.7827,51.360084 L 507.09408,51.864318 L 509.07526,52.704708 L 509.90075,58.419357 L 511.38664,64.806318 L 513.03762,66.487097 L 517.99058,66.487097 L 518.32077,67.999799 L 524.75961,68.335954 L 524.75961,70.520967 L 529.71257,70.520967 L 530.04276,69.176344 L 531.19845,67.999799 L 533.50983,67.327487 L 534.83062,68.335954 L 537.80239,68.335954 L 541.76476,71.025201 L 547.21301,73.54637 L 549.68948,74.050604 L 550.18478,73.042136 L 551.67066,72.537902 L 552.16596,75.563305 L 554.80753,76.907928 L 555.30283,76.403695 L 556.62362,76.571773 L 556.62362,78.756786 L 559.26519,79.765253 L 562.40206,79.765253 L 564.05305,78.924863 L 567.35502,75.563305 L 569.99659,75.059071 L 570.82209,76.907928 L 571.31738,78.252552 L 572.30797,78.252552 L 573.29856,77.412162 L 582.37898,77.076006 L 584.19506,80.269487 L 584.85546,80.269487 L 585.58425,79.142165 L 590.11857,78.756786 L 589.49346,81.126733 L 585.47097,83.036786 L 576.02857,87.25913 L 571.15228,89.345695 L 568.01541,92.034941 L 565.53894,95.732656 L 563.22756,99.766526 L 561.41147,100.60692 L 556.78872,105.81733 L 555.46793,105.98541 L 552.00086,109.17889 L 552.70347,109.74365 L 549.82713,112.55812 L 549.59365,115.4105 L 549.59365,124.20534 L 548.42622,125.86923 L 543.05607,129.91009 L 540.72123,136.09025 L 541.18819,136.32794 L 543.75652,138.46723 L 544.45698,141.79501 L 542.5891,145.12278 L 542.5891,149.16365 L 543.05607,156.0569 L 546.09137,159.14699 L 549.59365,159.14699 L 551.46153,162.47476 L 554.96379,162.95015 L 558.93303,168.89261 L 566.17105,173.17118 L 568.27242,176.02356 L 569.20636,183.86761 L 565.00364,183.86761 L 546.55834,184.5807 L 495.89216,185.29379 L 484.10119,185.29379 L 484.6849,178.16284 L 484.45141,146.54897 L 483.98444,143.4589 L 479.78172,139.89342 L 478.61429,137.99183 L 478.61429,136.32794 L 480.71565,134.66406 L 482.11657,133.23787 L 482.35005,129.91009 z " id="MN" style="fill:#d35f5f" /> - <ns0:path d="M 626.6436,202.64577 L 626.79047,198.26019 L 625.13948,193.55401 L 624.47909,187.16705 L 623.3234,184.64588 L 624.31399,181.4524 L 625.13948,178.42699 L 626.62537,175.73775 L 625.96497,172.20811 L 625.30458,168.5104 L 625.79988,166.66154 L 627.78106,164.14037 L 627.94616,161.28305 L 627.12066,159.93842 L 627.78106,157.24918 L 628.27635,153.88762 L 631.08303,148.00489 L 634.0548,140.94562 L 634.2199,138.59253 L 633.8897,137.58406 L 633.06421,138.08829 L 628.77165,144.64333 L 625.96497,148.84528 L 623.98379,150.69414 L 623.1583,153.04723 L 621.67241,153.88762 L 620.51673,155.90455 L 619.03084,155.5684 L 618.86574,153.71954 L 620.18653,151.19837 L 622.33281,146.32411 L 624.14889,144.64333 L 625.27363,142.26081 L 623.6083,141.31962 L 622.20739,139.89342 L 620.57299,129.197 L 616.83724,128.00851 L 615.43633,125.63153 L 602.59467,122.77914 L 600.02634,121.59066 L 591.62089,119.21367 L 583.21544,118.02518 L 578.9573,112.40581 L 578.41662,113.71699 L 577.26093,113.54892 L 576.60053,112.37237 L 573.79386,111.53198 L 572.63817,111.70006 L 570.82209,112.70853 L 569.8315,112.03621 L 570.49189,110.01928 L 572.47307,106.8258 L 573.62876,105.64925 L 571.64758,104.13655 L 569.5013,104.97694 L 566.52953,106.99388 L 558.935,110.35543 L 555.96322,111.02775 L 552.99145,110.52351 L 551.98885,109.6104 L 549.82713,112.55812 L 549.59365,115.4105 L 549.59365,124.20534 L 548.42622,125.86923 L 543.05607,129.91009 L 540.72123,136.09025 L 541.18819,136.32794 L 543.75652,138.46723 L 544.45698,141.79501 L 542.5891,145.12278 L 542.5891,149.16365 L 543.05607,156.0569 L 546.09137,159.14699 L 549.59365,159.14699 L 551.46153,162.47476 L 554.96379,162.95015 L 558.93303,168.89261 L 566.17105,173.17118 L 568.27242,176.02356 L 569.20636,183.74877 L 569.90681,187.19538 L 572.24166,188.85927 L 572.47514,190.28546 L 570.37378,193.85093 L 570.60726,197.17871 L 573.1756,201.21959 L 575.74393,202.40807 L 578.77923,202.88347 L 580.03422,205.49817 L 589.40281,205.49815 L 616.60376,203.83427 L 626.6436,202.64577 z " id="WI" style="fill:#de8787" /> - <ns0:path d="M 568.73938,255.89021 L 565.4706,252.56242 L 564.30317,250.18543 L 556.3647,250.89852 L 546.32485,251.37392 L 520.40805,252.32472 L 506.63246,252.56242 L 498.57727,252.68126 L 496.24239,252.80011 L 497.52656,255.41479 L 497.29307,257.79177 L 499.8614,261.83265 L 503.01343,266.11122 L 506.16549,268.96359 L 508.50034,269.20129 L 509.90124,270.15209 L 509.90124,273.24216 L 508.03337,274.90605 L 507.56639,277.28304 L 509.66775,280.84852 L 512.23609,283.93859 L 514.80442,285.84018 L 516.20533,297.96278 L 515.50487,334.68718 L 515.73836,339.55999 L 516.20533,346.69094 L 540.02077,346.21554 L 563.83621,345.50245 L 585.08332,344.55165 L 596.29058,344.07626 L 598.15846,347.16634 L 597.69149,349.54332 L 594.4227,352.3957 L 593.72225,355.48577 L 600.02634,355.96118 L 605.163,355.24808 L 607.26436,348.59252 L 607.11843,342.73921 L 610.06619,341.22388 L 611.46709,339.55999 L 613.56845,338.3715 L 613.80194,335.04372 L 614.73588,333.14213 L 613.33497,330.61659 L 610.29967,331.00285 L 608.43179,328.86356 L 606.7974,324.58499 L 607.73133,321.49492 L 605.62997,318.16715 L 603.52862,312.93778 L 598.85891,312.22469 L 592.32134,306.75762 L 589.98649,302.71676 L 590.68696,299.38898 L 593.0218,293.20882 L 593.72225,289.40566 L 590.92044,287.97946 L 584.38287,287.50407 L 583.44892,286.07787 L 583.68241,281.56161 L 578.07878,277.75843 L 570.60726,269.91439 L 568.27242,262.30804 L 567.80545,258.50488 L 568.73938,255.89021 z " id="MO" style="fill:#de8787" /> - <ns0:path d="M 604.99844,354.98628 L 600.02634,355.96118 L 593.72225,355.48577 L 594.4227,352.3957 L 597.69149,349.54332 L 598.15846,347.16634 L 596.29058,344.07626 L 585.08332,344.55165 L 563.83621,345.50245 L 540.02077,346.21554 L 516.20533,346.69094 L 517.83972,353.82189 L 517.83971,362.37904 L 519.24063,373.78867 L 519.47412,413.12761 L 521.80896,415.14805 L 524.84426,413.72186 L 527.64608,414.91035 L 528.31735,426.58728 L 550.99455,426.55757 L 570.60726,425.60677 L 581.63941,425.75534 L 583.15706,422.99209 L 582.74847,418.47583 L 581.34756,415.38574 L 582.74847,413.95956 L 581.34756,411.82028 L 581.81454,409.91869 L 582.74847,403.50083 L 585.78377,400.64846 L 585.08332,398.50917 L 588.81908,393.0421 L 591.62089,392.09132 L 591.62089,389.47664 L 590.92044,388.05044 L 593.72225,382.58339 L 596.52407,381.39489 L 596.22104,377.59524 L 598.72469,376.42223 L 599.71528,371.54796 L 598.22939,367.85023 L 602.35687,365.49714 L 602.68706,362.80789 L 604.06449,358.25292 L 604.99844,354.98628 z " id="AR" style="fill:#e9afaf" /> - <ns0:path d="M 383.76113,331.71594 L 372.84567,331.2406 L 366.27891,330.73549 L 366.54158,330.94347 L 365.98708,342.94722 L 388.2557,344.07626 L 420.00963,345.26475 L 418.60872,369.98537 L 418.14175,388.52584 L 418.37523,390.18973 L 422.81144,393.9929 L 424.9128,395.18139 L 425.61327,394.94369 L 426.31372,392.80441 L 427.71463,394.70599 L 429.81599,394.70599 L 429.81599,393.2798 L 432.6178,394.70599 L 432.15084,398.74687 L 436.35356,398.98457 L 438.92189,400.17306 L 443.12462,400.88615 L 445.69295,402.78774 L 448.02779,400.64846 L 451.53007,401.36155 L 454.0984,404.92703 L 455.03233,404.92703 L 455.03233,407.30401 L 457.36718,408.0171 L 459.70203,405.64012 L 461.5699,406.35321 L 464.13823,406.35321 L 465.07218,408.9679 L 469.97536,410.86948 L 471.37627,410.15638 L 473.24415,405.87781 L 474.41156,405.87781 L 475.57899,408.0171 L 479.78172,408.73019 L 483.51747,410.15638 L 486.55277,411.10718 L 488.42065,410.15638 L 489.1211,407.54171 L 493.55731,407.54171 L 495.65868,408.49249 L 498.46049,406.35321 L 499.62792,406.35321 L 500.32837,408.0171 L 504.53109,408.0171 L 506.16549,405.87781 L 508.03337,406.35321 L 510.13473,408.9679 L 513.40351,410.86948 L 516.6723,411.82028 L 519.47412,413.48417 L 519.24063,373.78867 L 517.83971,362.37904 L 517.83972,353.82189 L 516.20533,346.69094 L 515.73836,339.55999 L 515.50487,334.92488 L 501.9627,335.75681 L 454.56566,335.28143 L 408.56892,333.14212 L 383.76113,331.71594 z " id="OK" style="fill:#e9afaf" /> - <ns0:path d="M 515.50487,335.04372 L 501.9627,335.75681 L 454.56566,335.28143 L 408.56892,333.14212 L 383.90706,331.83479 L 388.13897,263.37769 L 410.43676,264.20963 L 451.76325,265.63581 L 496.82609,266.11122 L 503.01343,266.11122 L 506.16549,268.96359 L 508.50034,269.20129 L 509.90124,270.15209 L 509.90124,273.24216 L 508.03337,274.90605 L 507.56639,277.28304 L 509.66775,280.84852 L 512.23609,283.93859 L 514.80442,285.84018 L 516.20533,297.96278 L 515.50487,335.04372 z " id="KS" style="fill:#e9afaf" /> - <ns0:path d="M 616.71945,488.11058 L 615.43633,485.74444 L 614.2689,481.70357 L 610.76664,478.3758 L 611.93406,470.53175 L 611.23361,469.58096 L 609.36573,469.81866 L 600.96028,470.53175 L 576.2109,471.24485 L 575.74393,469.58096 L 576.44438,461.26152 L 579.94666,454.84366 L 585.3168,445.33573 L 584.38287,443.19645 L 585.55029,443.19645 L 586.25075,439.86868 L 583.91589,437.96709 L 584.14938,436.0655 L 582.04802,431.31154 L 581.69779,425.60677 L 570.60726,425.60677 L 550.99455,426.55757 L 528.31735,426.58728 L 528.34653,436.5409 L 529.04699,446.28652 L 529.74745,450.3274 L 532.31578,454.60597 L 533.24971,459.83533 L 537.68592,465.54009 L 537.9194,468.86787 L 538.61987,469.58096 L 537.9194,478.3758 L 534.88411,483.60516 L 536.5185,485.74444 L 535.81804,488.35912 L 535.11759,495.96547 L 533.71668,499.29324 L 533.84174,503.05325 L 538.62788,501.47276 L 546.88281,501.1366 L 557.44911,504.83432 L 564.05305,506.01086 L 567.85031,504.49816 L 571.15228,505.67471 L 574.45425,506.68317 L 575.27974,504.49816 L 571.97778,503.32162 L 569.3362,503.82585 L 566.52953,502.14507 C 566.52953,502.14507 566.69462,500.80045 567.35502,500.63237 C 568.01541,500.46429 570.49189,499.6239 570.49189,499.6239 L 572.30797,501.1366 L 574.12406,500.12814 L 577.42603,500.80045 L 578.91191,503.32162 L 579.24211,505.67471 L 583.86487,506.01086 L 585.68095,507.85972 L 584.85546,509.5405 L 583.53467,510.38089 L 585.18565,512.06167 L 593.77077,515.75938 L 597.40294,514.41476 L 598.39353,511.89359 L 601.03511,511.22128 L 602.85119,509.70858 L 604.17198,510.71704 L 604.99747,513.74245 L 602.68609,514.58284 L 603.34648,515.25515 L 606.81355,513.91053 L 609.12493,510.38089 L 609.95042,509.87666 L 607.80414,509.5405 L 608.62964,507.85972 L 608.46454,506.34702 L 610.61082,505.84279 L 611.76651,504.49816 L 612.4269,505.33855 C 612.4269,505.33855 612.2618,508.53203 613.08729,508.53203 C 613.91279,508.53203 617.37985,509.20434 617.37985,509.20434 L 621.50732,511.22128 L 622.49791,512.73398 L 625.46968,512.73398 L 626.62537,513.74245 L 628.93675,510.54897 L 628.93675,509.03627 L 627.61596,509.03627 L 624.14889,506.17894 L 618.20535,505.33855 L 614.90338,502.98546 L 616.05907,500.12814 L 618.37045,500.46429 L 618.53554,499.79198 L 616.71946,498.78351 L 616.71946,498.27928 L 620.02143,498.27928 L 621.83751,495.0858 L 620.51673,493.06886 L 620.18653,490.21154 L 618.70064,490.37962 L 616.71946,492.56463 L 616.05907,495.25388 L 612.9222,494.58156 L 611.93161,492.73271 L 613.74769,490.71577 L 615.81141,488.86693 L 616.71945,488.11058 z " id="LA" style="fill:#de8787" /> - <ns0:path d="M 817.62464,258.28441 L 818.55858,256.38283 L 820.84673,258.09426 L 819.7727,260.66139 L 818.09161,259.04505 L 817.62464,258.28441 z " id="path6656" style="fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <ns0:g id="g8180" style="fill:#cccccc"> - <ns0:path d="M 738.7284,305.32516 L 740.70958,309.02287 L 742.03037,310.36749 L 745.00215,311.2079 L 747.64373,310.53557 L 750.12022,308.18248 C 750.12022,308.18248 751.9363,309.69518 752.59669,309.52711 C 753.25709,309.35903 757.05436,308.51864 757.05436,308.51864 L 758.87045,303.64438 L 761.51202,304.65285 L 764.814,302.13167 L 766.29989,302.46782 L 768.44617,300.45089 L 768.61127,297.59356 L 767.78577,296.24894 L 772.90384,284.9877 L 775.05012,278.09649 L 775.38031,273.55838 L 777.1964,273.3903 L 778.84739,276.24763 L 780.16818,277.08802 L 782.80976,277.08802 L 783.96545,271.37336 L 784.29564,268.17988 L 787.76272,267.84373 L 788.25802,265.49063 L 791.39489,262.96946 L 792.05529,261.28868 L 793.70628,258.43134 L 794.20157,256.24633 L 794.36667,250.69975 L 798.98943,252.5486 L 804.7679,255.7421 L 805.59338,250.44764 L 809.88595,252.5486 L 809.88595,255.57402 L 815.49931,256.91864 L 817.48049,258.26326 L 818.47108,256.24633 L 820.78247,257.92711 L 819.29657,261.28868 L 818.96637,264.146 L 817.15029,266.83525 L 817.15029,269.02027 L 817.81068,270.86913 L 822.98233,272.27864 L 824.90863,273.89525 L 830.19178,274.23141 L 832.83336,276.5845 L 836.13533,277.25681 L 837.45611,278.60143 L 836.96082,283.30762 L 837.95141,284.31608 L 838.11651,286.66917 L 839.43729,288.85419 L 839.2722,290.70305 L 835.97023,289.5265 L 835.97023,290.53497 L 837.95141,292.21575 L 837.95141,293.39229 L 839.43729,294.56884 L 840.75808,296.24962 L 840.92318,298.60271 L 838.6118,300.11541 L 838.942,300.61964 L 841.58358,300.11541 L 844.88554,299.4431 L 846.04123,299.27502 L 850.20356,306.58097 L 845.21707,308.35056 L 833.49506,311.37597 L 813.92151,315.35219 L 792.88078,319.27565 L 775.38031,321.96489 L 759.22415,323.98183 L 751.9363,325.32646 L 747.32856,324.68385 L 745.16725,324.65414 L 742.69078,326.67109 L 734.60093,326.83916 L 722.3505,328.8153 L 712.13922,329.78475 L 714.95419,328.35186 L 720.73264,324.82222 L 724.69501,322.6372 L 724.69501,320.45219 L 726.51109,318.60333 L 731.13386,313.05675 L 735.42643,309.35903 L 738.7284,305.32516 z " id="VA" style="fill:#d35f5f" /> - <ns0:path d="M 845.69487,293.77543 L 844.35758,290.76684 L 844.75381,282.95122 L 847.26331,278.51396 L 847.13123,274.21116 L 853.07478,271.9253 L 852.41438,274.21116 L 849.24449,278.3795 L 848.92256,286.54808 L 848.17135,289.94326 L 846.33876,293.85948 L 845.69487,293.77543 z " id="path3106" style="fill:#d35f5f" ns1:nodetypes="cccccccccccc" /> - </ns0:g> - <ns0:path d="M 467.38967,586.18345 L 466.81183,578.788 L 464.00514,571.30851 L 463.42729,563.99709 L 464.99573,555.42509 L 468.38027,548.28176 L 471.92989,542.65112 L 475.14933,538.95339 L 475.80972,539.20552 L 470.9393,546.09673 L 466.48163,552.90391 L 464.41788,559.79513 L 464.08769,565.17365 L 464.99573,571.56063 L 467.63732,579.04012 L 468.13261,584.41863 L 468.29771,585.93134 L 467.38967,586.18345 z M 465.65436,588.7052 L 466.64495,587.1925 L 464.82887,584.33517 L 463.83828,577.94821 L 462.0222,570.72086 L 461.1967,568.19969 L 462.0222,563.49351 L 463.17788,559.45964 L 464.49867,554.75346 L 465.98456,549.03881 L 463.67318,547.02188 L 464.66377,545.00494 L 468.79123,544.66878 L 472.7536,538.95414 L 476.22066,538.28182 L 482.16421,534.58411 L 483.98029,533.07141 L 490.41913,529.54177 L 496.19758,527.0206 L 501.64583,523.65904 L 504.4525,521.47403 L 510.23095,515.92746 L 511.55174,515.08707 L 513.69802,513.57437 L 516.33959,511.55743 L 517.33018,509.5405 L 527.40119,504.83432 L 534.17024,502.98546" id="TX_Gulf" style="fill:none;fill-opacity:0.26666697;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 900.52373,145.31564 L 900.85393,143.29871 L 902.00961,139.60099" id="NH_Atlantic" style="fill:#0000ff;fill-opacity:0;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 919.55232,177.09192 L 921.77043,176.37882 L 922.23741,174.59609 L 923.28809,174.71493 L 924.33877,177.09192 L 923.0546,177.56732 L 919.08535,177.68617 L 919.55232,177.09192 z M 909.97943,177.92387 L 912.31427,175.19033 L 913.94868,175.19033 L 915.81656,176.73537 L 913.36497,177.80501 L 911.14686,178.87466 L 909.97943,177.92387 z M 903.66061,177.08236 L 906.63237,175.56967 L 906.13708,173.21658 L 906.96257,171.70388 L 909.93434,170.19118 L 910.75983,173.38466 L 910.26454,175.23351 L 907.78806,176.74621 L 907.78806,177.75468 L 909.76924,176.24198 L 913.73161,171.5358 L 917.69397,169.51886 L 921.98653,168.00616 L 921.65633,165.48499 L 920.66574,162.45959 L 918.68456,159.93842 L 916.86848,159.09803 L 914.7222,159.26611 L 914.2269,159.77034 L 915.21749,161.11497 L 916.70338,160.27458 L 918.84966,161.95536 L 919.67515,164.81268 L 917.85907,166.66154 L 915.54769,167.67001 L 911.91552,167.16577 L 907.95316,160.94689 L 905.64178,158.25764 L 903.8257,158.25764 L 902.67001,159.09803 L 900.68883,156.40879 L 901.01902,154.89608 L 903.4955,149.51759 L 900.35862,144.81139" id="MA_Atlantic" style="fill:#0000ff;fill-opacity:0;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 771.67854,458.60093 L 771.08653,452.05785 L 773.39791,441.63702 L 774.88379,437.26699 L 774.3885,434.57775 L 778.51596,427.3504 L 777.85557,425.66962" id="GA_Atlantic" style="fill:#6666e6;fill-opacity:0;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 777.85557,425.66962 L 780.00185,424.32499 L 785.1199,418.61034 L 784.12931,415.24879 L 787.10108,415.08071 L 790.73325,411.55107 L 792.38423,410.71068 L 794.69561,407.18104 L 797.50228,404.32372 L 799.64856,400.62601 L 802.12504,399.95369 L 803.28073,397.09637 L 804.93171,396.25598 L 805.42701,389.70094 L 808.06859,383.31398 L 813.51684,377.43125" id="SC_Atlantic" style="fill:#0000ff;fill-opacity:0;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 813.18663,377.59933 L 819.46038,375.41432 L 824.24824,374.91008 L 824.74353,372.38892 L 826.72471,365.6658 L 830.19178,360.79154 L 836.79572,355.24497 L 842.07887,352.7238 L 844.88554,352.05149 L 846.04123,352.55572 L 847.36202,352.55572 L 850.49889,347.51338 L 852.48007,343.81567 L 851.15929,344.3199 L 848.84791,346.67299 L 848.18751,344.99221 L 843.89495,344.99221 L 845.87614,338.43717 L 845.05064,337.09255 L 843.06946,337.09255 L 843.06946,336.08408 L 842.73926,334.73946 L 844.39025,336.08408 L 845.87614,336.25216 L 848.35261,336.58832 L 852.14988,334.90754 L 853.47066,331.88214 L 854.13106,329.69712 L 856.77263,328.3525 L 857.10283,323.98247 L 856.27734,323.31016 L 858.75382,323.14208 L 858.09342,320.78899 L 855.61694,318.26782 L 851.98478,311.54471 L 850.1687,306.50237 M 854.21672,340.95692 L 856.85831,338.3517 L 860.07773,335.66244 L 861.64617,334.99013 L 861.81127,332.88915 L 861.15088,326.50217 L 859.66499,324.06503 L 859.00459,322.13213 L 859.74753,321.88001 L 862.55422,327.59468 L 862.96697,332.21684 L 862.80187,335.74649 L 859.33479,337.34323 L 856.44555,339.86441 L 855.28987,341.125 L 854.21672,340.95692 z " id="NC_Atlantic" style="fill:#0000ff;fill-opacity:0;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 850.1687,306.50237 L 846.04123,299.27502 L 844.88554,299.4431 L 841.58358,300.11541 L 838.942,300.61964 L 838.6118,300.11541 L 840.92318,298.60271 L 840.75808,296.24962 L 839.43729,294.56884 L 837.95141,293.39229 L 837.95141,292.21575 L 835.97023,290.53497 L 835.97023,289.5265 L 839.2722,290.70305 L 839.43729,288.85419 L 838.11651,286.66917 L 837.95141,284.31608 L 836.96082,283.30762 L 837.45611,278.60143 L 836.13533,277.25681 L 832.83336,276.5845 L 830.19178,274.23141 L 824.90863,273.89525 L 822.59725,272.21447" id="VA_Atlantic" style="fill:#0000ff;fill-opacity:0;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 893.09433,183.30123 L 896.06607,182.29279 L 898.54255,180.27585 L 899.69824,178.42699 L 901.01902,178.59507 L 903.99082,176.91428" id="RI_Atlantic" style="fill:#0000ff;fill-opacity:0;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 865.2752,198.17615 L 870.47581,194.73055 L 874.10797,191.36899 L 876.08916,189.18398 L 876.91465,189.85629 L 879.72132,188.34359 L 885.00447,187.16705 L 893.58963,183.30123" id="CT_Atlantic" style="fill:#0000ff;fill-opacity:0;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 840.75808,236.41389 L 841.91377,238.76697 L 845.21574,241.79237 L 850.1687,244.14546 L 854.29616,244.81777 L 854.46126,246.33047 L 853.63576,247.33894 L 853.96596,250.19627 L 854.79145,250.19627 L 856.93773,247.6751 L 857.76322,242.63276 L 860.5699,238.43081 L 863.70677,231.70769 L 864.86246,225.99305 L 864.20207,224.8165 L 864.03697,215.06798 L 862.38598,211.53834 L 861.23029,212.37873 L 858.42362,212.71489 L 857.92832,212.21066 L 859.08401,211.20219 L 861.23029,209.18525 L 861.06519,207.84063" id="NJ_Atlantic" style="fill:#0000ff;fill-opacity:0;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 861.06519,207.84063 L 863.04638,208.51294 L 867.17384,207.3364 L 873.11738,205.31946 L 875.75896,204.31099 L 883.02329,198.76442 L 886.98565,195.73902 L 890.45272,192.0413 L 886.16016,190.36053 L 884.83937,191.87323 L 881.8676,194.73055 L 873.77778,198.76442 L 871.4664,198.59634 L 869.81541,197.92403 L 868.65972,198.59634 L 866.34835,201.28559 L 864.86246,202.63021 L 863.54167,202.96637 L 863.21147,201.62175 L 865.19266,199.77289 L 865.52285,197.75595" id="NY_Atlantic" style="fill:#0000ff;fill-opacity:0;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 854.95655,260.95325 L 852.64517,253.38975 L 851.65458,253.89398 L 848.02242,251.37281 L 846.20633,246.49855 L 844.22515,242.80084 L 841.91377,241.79237 L 839.76749,238.09466 L 840.59298,235.90964" id="DE_Atlantic" style="fill:#cccccc;fill-opacity:0.26666697;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 29.464207,149.85375 L 27.813223,154.89608 L 27.648124,162.62767 L 22.364973,174.89736 L 19.228102,177.5866 L 18.897905,178.76315 L 17.081822,179.60354 L 15.595936,183.97356 L 14.770444,187.33512 L 17.577118,191.70515 L 19.228102,196.07518 L 20.383791,199.77289 L 20.053595,206.49601 L 18.237511,209.68949 L 17.577118,215.74029 L 16.586527,219.60608 L 18.40261,223.63995 L 21.209284,228.34614 L 23.520662,233.38847 L 24.84145,237.59042 L 24.511253,240.95198 L 24.181056,241.45621 L 24.181056,243.64123 L 29.959503,250.19627 L 29.464207,252.71743 L 28.803813,255.07053 L 28.14342,257.08746 L 28.308518,265.65943 L 30.454798,269.52523 L 32.43598,272.21447 L 35.242654,272.71871 L 36.233244,275.57603 L 35.077555,279.27375 L 32.931275,280.95453 L 31.775586,280.95453 L 30.950093,284.9884 L 31.445389,288.0138 L 34.747358,292.5519 L 36.398343,298.09847 L 37.884229,302.97273 L 39.205017,306.16621 L 42.672085,312.21702 L 44.157971,314.90627 L 44.653266,317.93167 L 46.304251,318.94014 L 46.304251,321.4613 L 45.478759,323.47824 L 43.662676,330.87367 L 43.16738,332.8906 L 45.643857,335.74793 L 49.936417,336.25216 L 54.559175,338.10102 L 58.521538,340.28603 L 61.49331,340.28603 L 64.465083,343.47951 L 67.106658,348.52185 L 68.262347,350.87494 L 72.224711,353.05995 L 77.177665,353.90034 L 78.663551,356.08536 L 79.323945,359.44692 L 77.838059,360.11923 L 78.168256,361.12769 L 81.470225,361.96808 L 84.276899,362.13616 L 87.248671,367.01042 L 91.211035,371.38045 L 92.036527,373.73354 L 94.678102,378.10356 L 95.008299,381.46512 L 95.008299,391.21364 L 95.503595,393.0625 M 50.266945,346.75563 L 51.587737,348.35237 L 51.422639,349.697 L 48.120658,349.61296 L 47.542811,348.35237 L 46.882415,346.83966 L 50.266945,346.75563 z M 52.248133,346.75563 L 53.486376,346.08332 L 57.118555,348.26833 L 60.255437,349.52892 L 59.347393,350.20124 L 54.724619,349.94912 L 53.073629,348.26833 L 52.248133,346.75563 z M 73.380812,367.34524 L 75.196895,369.78238 L 76.022398,370.79086 L 77.590839,371.37912 L 78.168678,369.86642 L 77.178087,368.01756 L 74.453957,365.91658 L 73.380812,366.08465 L 73.380812,367.34524 z M 71.894915,376.33744 L 73.711009,379.61497 L 74.949253,381.63192 L 73.463356,381.88403 L 72.142568,380.62344 C 72.142568,380.62344 71.39962,379.11074 71.39962,378.69054 C 71.39962,378.27035 71.39962,376.42148 71.39962,376.42148 L 71.894915,376.33744 z " id="CA_Pacific" style="fill:none;fill-opacity:0.26666697;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 95.99889,2.9536428 L 94.843201,3.7940324 L 94.513004,4.634422 L 96.989481,9.6767597 L 98.14517,12.366006 L 96.329087,16.063721 L 96.329087,18.416812 L 96.989481,19.929513 L 96.163989,21.77837 L 96.659284,25.139928 L 97.649875,26.484552 L 97.484776,27.829175 L 95.99889,27.997253 L 95.338496,25.980318 L 94.182807,23.459149 L 92.366724,21.946448 L 92.696921,19.761435 L 95.008299,19.257201 L 94.678102,17.408344 L 94.347905,16.231799 L 92.201625,17.576422 L 90.880838,18.752967 L 90.880838,21.274136 L 88.569459,21.442214 L 85.102391,20.433747 L 82.130619,18.921045 L 78.993748,18.248734 L 74.370991,16.063721 L 71.069021,14.046786 L 68.262347,11.357539 L 65.78587,8.3321363 L 63.63959,7.8279025 L 61.328212,17.576422 L 63.144295,20.93798 L 63.144295,29.173799 L 62.483901,32.199201 L 63.969787,39.59463 L 66.776461,42.451954 L 62.318803,43.124266 L 62.153704,46.990058 L 64.79528,48.166604 L 63.144295,52.368552 L 60.337621,52.704708 L 60.007424,55.73011 L 62.318803,58.755513 L 64.134886,57.747045 L 66.446264,59.427825 M 86.341089,9.169955 L 88.404826,9.001877 L 88.900121,10.430545 L 90.468562,8.7497548 L 92.862495,8.7497548 L 93.687987,10.3465 L 92.119546,12.111324 L 92.779951,12.951724 L 92.037002,15.052704 L 90.63366,15.472893 C 90.63366,15.472893 89.725613,15.556938 89.725613,15.220782 C 89.725613,14.884626 91.21151,12.531524 91.21151,12.531524 L 89.477971,11.943246 L 89.147774,13.455958 L 88.404826,14.12827 L 86.836385,11.775168 L 86.341089,9.169955 z " id="WA_Pacific" style="fill:none;fill-opacity:0.26666697;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 66.446264,59.427825 L 60.172522,61.44476 L 57.861144,68.167876 L 54.559175,78.588708 L 51.257205,85.311824 L 46.139153,99.934604 L 39.535214,114.05315 L 31.28029,127.16323 L 29.299109,130.18863 L 28.473616,139.09676 L 27.152829,145.31564 L 29.464207,149.85375" id="OR_Pacific" style="fill:none;fill-opacity:0.26666697;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 639.33795,481.63956 L 642.14462,481.63956 L 642.80502,481.80764 L 644.12581,478.95032 L 645.61169,474.41221 L 647.92307,475.08453 L 651.05994,481.30341 L 651.05994,482.31188 L 648.25327,484.32881 L 651.05994,484.66497 L 658.02586,481.83647" id="AL_Gulf" style="fill:none;fill-opacity:0.26666697;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 616.38926,488.36268 L 617.71005,487.52229 L 620.35163,483.15227 L 622.16771,483.99266 L 629.10185,481.97572 L 631.24813,482.31188 L 632.73401,483.15227 L 638.01716,483.15227 L 639.33795,481.63956" id="MS_Gulf" style="fill:none;fill-opacity:0.26666697;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:path d="M 533.67494,503.06949 L 538.62788,501.47276 L 546.88281,501.1366 L 557.44911,504.83432 L 564.05305,506.01086 L 567.85031,504.49816 L 571.15228,505.67471 L 574.45425,506.68317 L 575.27974,504.49816 L 571.97778,503.32162 L 569.3362,503.82585 L 566.52953,502.14507 C 566.52953,502.14507 566.69462,500.80045 567.35502,500.63237 C 568.01541,500.46429 570.49189,499.6239 570.49189,499.6239 L 572.30797,501.1366 L 574.12406,500.12814 L 577.42603,500.80045 L 578.91191,503.32162 L 579.24211,505.67471 L 583.86487,506.01086 L 585.68095,507.85972 L 584.85546,509.5405 L 583.53467,510.38089 L 585.18565,512.06167 L 593.77077,515.75938 L 597.40294,514.41476 L 598.39353,511.89359 L 601.03511,511.22128 L 602.85119,509.70858 L 604.17198,510.71704 L 604.99747,513.74245 L 602.68609,514.58284 L 603.34648,515.25515 L 606.81355,513.91053 L 609.12493,510.38089 L 609.95042,509.87666 L 607.80414,509.5405 L 608.62964,507.85972 L 608.46454,506.34702 L 610.61082,505.84279 L 611.76651,504.49816 L 612.4269,505.33855 C 612.4269,505.33855 612.2618,508.53203 613.08729,508.53203 C 613.91279,508.53203 617.37985,509.20434 617.37985,509.20434 L 621.50732,511.22128 L 622.49791,512.73398 L 625.46968,512.73398 L 626.62537,513.74245 L 628.93675,510.54897 L 628.93675,509.03627 L 627.61596,509.03627 L 624.14889,506.17894 L 618.20535,505.33855 L 614.90338,502.98546 L 616.05907,500.12814 L 618.37045,500.46429 L 618.53554,499.79198 L 616.71946,498.78351 L 616.71946,498.27928 L 620.02143,498.27928 L 621.83751,495.0858 L 620.51673,493.06886 L 620.18653,490.21154 L 618.70064,490.37962 L 616.71946,492.56463 L 616.05907,495.25388 L 612.9222,494.58156 L 611.93161,492.73271 L 613.74769,490.71577 L 616.38926,488.36268 L 617.2973,487.77441" id="LA_Gulf" style="fill:none;fill-opacity:0.26666697;stroke:#80b0f0;stroke-width:1.06612186pt" /> - <ns0:g id="Great_Lakes_borders" style="fill:none;stroke:#80b0f0" transform="matrix(1.0566302,0,0,1.0756987,-45.325399,-166.80506)"> - <ns0:path d="M 652.1875,357.8125 L 649.84375,359.21875 L 647.8125,361.09375 L 646.71875,361.40625 L 645.3125,360.46875 L 642.18749,359.53125" id="IN_Great_Lakes" style="fill:none;stroke:#80b0f0;stroke-width:1pt" /> - <ns0:path d="M 712.53906,338.43751 L 712.8125,334.6875 L 714.29687,331.75782 L 715.50782,330.39062 M 717.85156,323.16407 L 714.6875,315 L 712.5,306.25 L 710.15625,303.125 L 707.65625,301.40625 L 706.09375,302.5 L 702.34375,304.21875 L 700.46875,309.0625 L 697.8125,312.65625 L 696.71875,313.28125 L 695.3125,312.65625 C 695.3125,312.65625 692.8125,311.25 692.96875,310.625 C 693.125,310 693.4375,305.78125 693.4375,305.78125 L 696.71875,304.53125 L 697.5,301.25 L 698.125,298.75 L 700.46875,297.1875 L 700.15625,287.5 L 698.59375,285.3125 L 697.34375,284.53125 L 696.5625,282.5 L 697.34375,281.71875 L 698.90625,282.03125 L 699.0625,280.46875 L 696.71875,278.28125 L 695.46875,275.78125 L 692.96875,275.78125 L 688.59375,274.375 L 683.28125,271.09375 L 680.625,271.09375 L 680,271.71875 L 679.0625,271.25 L 676.09375,269.0625 L 673.28125,270.78125 L 670.46875,272.96875 L 670.78125,276.40625 L 671.71875,276.71875 L 673.75,277.1875 L 674.21875,277.96875 L 671.71875,278.75 L 669.21875,279.0625 L 667.8125,280.78125 L 667.5,282.8125 L 667.8125,284.375 L 668.125,289.6875 L 664.6875,291.71875 L 664.0625,291.5625 L 664.0625,287.5 L 665.3125,285.15625 L 665.9375,282.8125 L 665.15625,282.03125 L 663.28125,282.8125 L 662.34375,286.875 L 659.6875,287.96875 L 657.96875,289.84375 L 657.8125,290.78125 L 658.4375,291.5625 L 657.8125,294.0625 L 655.625,294.53125 L 655.625,295.625 L 656.40625,297.96875 L 655.3125,303.90625 L 653.75,307.8125 L 654.375,312.34375 L 654.84375,313.4375 L 654.0625,315.78125 L 653.75,316.5625 L 653.4375,319.21875 L 656.875,325 L 659.6875,331.25 L 661.09375,335.9375 L 660.3125,340.46875 L 659.375,346.25 L 657.03125,351.25 L 656.71875,353.90625 L 654.84375,356.25 L 652.1875,357.8125 M 605.4621,230.97629 L 607.22987,228.98755 L 609.3291,228.21415 L 614.52193,224.45763 L 616.73164,223.9052 L 617.17359,224.34715 L 612.20173,229.31901 L 608.99764,231.19726 L 607.0089,232.08115 L 605.4621,230.97629 z M 634.68749,287.50003 L 638.28125,279.6875 L 639.21875,275.78125 L 641.09375,271.5625 L 641.875,271.40625 L 642.96875,272.96875 L 643.59375,272.96875 L 647.96875,270.625 L 649.375,272.1875 L 649.84375,272.34375 L 651.09375,271.25 L 652.1875,268.28125 L 654.53125,267.5 L 661.25,266.875 L 663.125,264.375 L 668.125,264.21875 L 673.75,265.46875 L 675.46875,265.46875 L 678.59375,264.0625 L 680.78125,264.21875 L 682.8125,263.59375 L 686.40625,264.0625 L 687.1875,264.375 L 688.4375,264.0625 L 687.1875,263.125 L 685.9375,262.5 L 682.8125,259.53125 L 682.8125,252.8125 L 681.40625,252.34375 L 680.3125,253.4375 L 674.375,255 L 672.5,255.46875 L 669.6875,254.6875 L 669.21875,254.375 L 669.21875,248.90625 L 667.8125,248.75 L 665.3125,250 L 660.9375,251.875 L 654.53125,252.1875 L 651.25,253.28125 L 647.34375,256.71875 L 645.78125,257.65625 L 644.6875,257.65625 L 643.4375,258.4375 L 641.875,257.96875 L 640.3125,256.71875 L 638.90625,257.65625 L 635.15625,257.8125 L 632.5,255.15625 L 631.09375,252.1875 L 629.6875,251.09375 L 626.5625,250.15625 L 624.375,250.15625 L 623.125,248.90625 L 619.6875,251.71875 L 618.75,252.8125 L 617.96875,252.34375 L 618.28125,249.84375 L 620.625,246.71875 L 621.09375,244.375 L 623.28125,243.59375 L 624.6875,240.625 L 628.28125,239.6875 L 628.59375,238.75 L 627.5,237.65625 L 622.96875,238.125 L 618.75,240.46875 L 616.5625,242.65625 L 615.3125,244.375 L 613.59375,245.15625 L 611.71875,247.96875 L 611.5625,249.21875 L 607.34375,251.25 L 605,253.125 L 599.21875,254.0625 L 598.59375,254.6875 L 598.59375,255.625 L 595.15625,257.8125 L 592.5,258.59375 L 590.9375,259.53125 M 688.75238,262.0292 L 689.37738,264.45108 L 692.50239,264.60733 L 693.7524,263.43545 C 693.7524,263.43545 693.67427,262.0292 693.36177,261.87295 C 693.04927,261.7167 691.79927,260.07607 691.79927,260.07607 L 689.68989,260.31044 L 688.12738,260.46669 L 687.81488,261.56045 L 688.75238,262.0292 z M 707.34375,352.8125 L 706.09375,351.5625 L 706.25,350.15625 L 708.28125,346.5625 L 710.42969,344.60937" id="MI_Great_Lakes" style="fill:none;stroke:#80b0f0;stroke-width:1pt" /> - <ns0:path d="M 762.03126,331.40624 L 756.5625,336.875 L 755.3125,337.34375 L 751.25001,340.46875" id="PA_Great_Lakes" style="fill:none;stroke:#80b0f0;stroke-width:1pt" /> - <ns0:path d="M 773.4375,318.28125 L 773.59375,319.21875 L 772.5,320.15625 L 770.46875,322.8125 L 770,324.375 L 768.125,326.09375 L 766.40625,327.1875 L 765.46875,328.75 L 764.21875,329.84375 L 761.56251,331.71874 M 823.75,260.46875 L 821.25,262.34375 L 819.21875,264.6875 L 816.5625,268.28125 L 813.75,272.65625 L 812.34375,275.46875 L 811.71875,276.25 L 806.09375,281.5625 L 806.25,284.0625 L 807.03125,285.15625 L 808.75,285.9375 L 810.46875,285.9375 L 810.46875,287.34375 L 809.375,289.375 L 809.6875,290.78125 L 811.09375,292.8125 L 810.9375,295 L 809.0625,296.09375 L 807.03125,296.09375 L 805.46875,297.96875 L 803.75,301.09375 L 801.71875,302.8125 L 796.71875,303.28125 L 794.21875,304.375 L 792.1875,305.625 L 790.625,305.46875 L 788.75,304.21875 L 782.65625,304.375 L 779.53125,304.84375 L 775.625,306.09375 L 771.40625,307.5 L 768.59375,309.21875" id="NY_Great_Lakes" style="fill:none;stroke:#80b0f0;stroke-width:1pt" /> - <ns0:path d="M 751.40626,340.46875 L 744.375,344.0625 L 740.625,346.25 L 737.34375,349.84375 L 733.4375,353.59375 L 730.3125,354.375 L 727.5,354.84375 L 722.1875,357.34375 L 720.15625,357.5 L 716.875,354.53125 L 711.875,355.15625 L 709.375,353.75 L 706.71874,352.34374" id="OH_Great_Lakes" style="fill:none;stroke:#80b0f0;stroke-width:1pt" /> - <ns0:path d="M 642.5,359.6875 L 641.25,358.90625 L 640.46875,356.40625 L 639.21875,352.8125 L 637.65625,351.09375 L 636.25,348.59375 L 636.09375,343.12504" id="IL_Great_Lakes" style="fill:none;stroke:#80b0f0;stroke-width:1pt" /> - <ns0:path d="M 590.9375,259.53125 L 590.3125,260.78125 L 589.21875,260.625 L 588.59375,259.53125 L 585.9375,258.75 L 584.84375,258.90625 L 583.125,259.84375 L 582.1875,259.21875 L 582.8125,257.34375 L 584.6875,254.375 L 585.78125,253.28125 L 583.90625,251.875 L 581.875,252.65625 L 579.0625,254.53125 L 571.875,257.65625 L 569.0625,258.28125 L 566.25,257.8125 L 565.46875,256.875 M 636.25,343.43744 L 636.09375,339.375 L 634.53125,335 L 633.90625,329.0625 L 632.8125,326.71875 L 633.75,323.75 L 634.53125,320.9375 L 635.9375,318.4375 L 635.3125,315.15625 L 634.6875,311.71875 L 635.15625,310 L 637.03125,307.65625 L 637.1875,305 L 636.40625,303.75 L 637.03125,301.25 L 637.5,298.125 L 640.15625,292.65625 L 642.96875,286.09375 L 643.125,283.90625 L 642.8125,282.96875 L 642.03125,283.4375 L 637.96875,289.53125 L 635.3125,293.4375 L 633.4375,295.15625 L 632.65625,297.34375 L 631.25,298.125 L 630.15625,300 L 628.75,299.6875 L 628.59375,297.96875 L 629.84375,295.625 L 631.875,291.09375 L 633.59375,289.53125 L 634.68749,287.03127" id="WI_Great_Lakes" style="fill:none;stroke:#80b0f0;stroke-width:1pt" /> - <ns0:path d="M 565.9375,257.34374 L 565.3125,256.5625 L 568.59375,253.59375 L 569.84375,253.4375 L 574.21875,248.59375 L 575.9375,247.8125 L 578.125,244.0625 L 580.46875,240.625 L 583.4375,238.125 L 587.5,236.40625 L 595,232.8125 L 597.8125,232.03125 C 597.8125,232.03125 600.78125,230.3125 601.09375,229.6875 C 601.40625,229.0625 601.71875,228.28125 601.71875,228.28125" id="MN_Great_Lakes" style="fill:none;stroke:#80b0f0;stroke-width:1pt" /> - </ns0:g> - <ns0:path d="M 152.15345,458.16063 L 151.84095,540.66102 L 153.40345,541.59852 L 156.37222,541.75477 L 157.77847,540.66102 L 160.27848,540.66102 L 160.43474,543.47353 L 167.15352,550.03606 L 167.62227,552.53607 L 170.90353,550.66106 L 171.52854,550.50481 L 171.84104,547.53605 L 173.24729,545.97354 L 174.34105,545.81729 L 176.21606,544.41103 L 179.18482,546.44229 L 179.80983,549.25481 L 181.68483,550.34856 L 182.77859,552.69232 L 186.52861,554.41108 L 189.80987,560.19236 L 192.46613,563.94237 L 194.65364,566.59864 L 196.0599,570.1924 L 200.90367,571.91116 L 205.9037,573.94242 L 206.8412,578.16119 L 207.30995,581.12995 L 206.37245,584.41122 L 204.65369,586.59873 L 203.09118,585.81748 L 201.68493,582.84871 L 199.02866,581.44246 L 197.30991,580.3487 L 196.52865,581.12995 L 197.93491,583.78622 L 198.09116,587.37998 L 196.9974,587.84873 L 195.1224,585.97373 L 193.09114,584.72372 L 193.55989,586.28623 L 194.80989,588.00499 L 194.02864,588.78624 C 194.02864,588.78624 193.24739,588.47374 192.77864,587.84873 C 192.30988,587.22373 190.74738,584.56747 190.74738,584.56747 L 189.80987,582.37996 C 189.80987,582.37996 189.49737,583.62997 188.87237,583.31746 C 188.24736,583.00496 187.62236,581.91121 187.62236,581.91121 L 189.34112,580.0362 L 187.93486,578.62994 L 187.93486,573.78617 L 187.15361,573.78617 L 186.37236,577.06743 L 185.2786,577.53619 L 184.3411,573.94242 L 183.71609,570.34865 L 182.93484,569.8799 L 183.24734,575.34868 L 183.24734,576.44243 L 181.84108,575.19243 L 178.40357,569.41115 L 176.37231,568.9424 L 175.74731,565.34863 L 174.1848,562.53612 L 172.62229,561.44236 L 172.62229,559.25485 L 174.65355,558.00485 L 174.1848,557.69235 L 171.68479,558.31735 L 168.40352,555.97359 L 165.90351,553.16107 L 161.21599,550.66106 L 157.30972,548.16105 L 158.55973,545.03604 L 158.55973,543.47353 L 156.84097,545.03604 L 154.02846,546.12979 L 150.43469,545.03604 L 144.96591,542.69228 L 139.65339,542.69228 L 139.02839,543.16103 L 132.77836,539.41101 L 130.7471,539.09851 L 128.09084,533.47348 L 124.65332,533.78598 L 121.2158,535.19224 L 121.68456,539.56726 L 122.77831,536.75475 L 123.71582,537.06725 L 122.30956,541.28602 L 125.43457,538.62976 L 126.05958,540.19226 L 122.30956,544.41103 L 121.05955,544.09853 L 120.5908,542.22352 L 119.3408,541.44227 L 118.09079,542.53603 L 115.43453,540.81727 L 112.46576,542.84853 L 110.74701,544.87979 L 107.46574,546.91105 L 102.93447,546.75479 L 102.46572,544.72354 L 106.05948,544.09853 L 106.05948,542.84853 L 103.87197,542.22352 L 104.80948,539.87976 L 106.99699,536.12975 L 106.99699,534.41099 L 107.15324,533.62973 L 111.37201,531.44222 L 112.30951,532.69223 L 114.96578,532.69223 L 113.71577,530.19222 L 110.122,529.87972 L 105.27823,532.53598 L 102.93447,535.81724 L 101.21571,538.31726 L 100.12196,540.50477 L 96.059441,541.91102 L 93.090671,544.41103 L 92.778171,545.97354 L 94.965681,546.91105 L 95.746941,548.9423 L 93.090671,552.06732 L 86.840651,556.12984 L 79.340608,560.19236 L 77.309348,561.28611 L 72.153076,562.37987 L 66.996796,564.56738 L 68.715556,565.81738 L 67.309296,567.22364 L 66.840546,568.31739 L 64.184286,567.37989 L 61.059276,567.53614 L 60.278016,569.72365 L 59.340516,569.72365 L 59.653016,567.37989 L 56.215496,568.6299 L 53.402986,569.5674 L 50.121721,568.31739 L 47.309208,570.1924 L 44.184194,570.1924 L 42.152934,571.44241 L 40.590427,572.22366 L 38.559168,571.91116 L 36.059156,570.81741 L 33.871646,571.44241 L 32.934142,572.37991 L 31.371634,571.28616 L 31.371634,569.41115 L 34.340398,568.16114 L 40.434176,568.78615 L 44.652946,567.22364 L 46.684205,565.19238 L 49.496718,564.56738 L 51.215476,563.78612 L 53.871739,563.94237 L 55.434246,565.19238 L 56.371746,564.87988 L 58.559256,562.22362 L 61.528026,561.28611 L 64.809286,560.66111 L 66.059296,560.34861 L 66.684296,560.81736 L 67.465556,560.81736 L 68.715556,557.22359 L 72.621826,555.81734 L 74.496836,552.22357 L 76.684348,547.84855 L 78.246858,546.44229 L 78.559358,543.94228 L 76.996848,545.19229 L 73.715576,545.81729 L 73.090576,543.47353 L 71.840576,543.16103 L 70.903066,544.09853 L 70.746816,546.91105 L 69.340556,546.75479 L 67.934306,541.12977 L 66.684296,542.37977 L 65.590546,541.91102 L 65.278046,540.03601 L 61.371776,540.19226 L 59.340516,541.28602 L 56.840506,540.97352 L 58.246756,539.56726 L 58.715506,537.06725 L 58.090506,535.19224 L 59.496766,534.25474 L 60.746766,534.09849 L 60.121766,532.37973 L 60.121766,528.16096 L 59.184266,527.22345 L 58.403006,528.62971 L 52.465482,528.62971 L 51.059226,527.3797 L 50.434223,523.62969 L 48.402963,520.19217 L 48.402963,519.25467 L 50.434223,518.47341 L 50.590473,516.44215 L 51.684228,515.3484 L 50.902975,514.87965 L 49.652969,515.3484 L 48.559214,512.69214 L 49.496718,507.84836 L 53.871739,504.72335 L 56.371746,503.16084 L 58.246756,499.56708 L 60.903026,498.31707 L 63.403036,499.41083 L 63.715536,501.75459 L 66.059296,501.44208 L 69.184306,499.09832 L 70.746816,499.72333 L 71.684316,500.34833 L 73.246826,500.34833 L 75.434338,499.09832 L 76.215598,494.87955 C 76.215598,494.87955 76.528098,492.06704 77.153098,491.59829 C 77.778098,491.12954 78.090598,490.66079 78.090598,490.66079 L 76.996848,488.78578 L 74.496836,489.56703 L 71.371816,490.34828 L 69.496806,489.87953 L 66.059296,488.16077 L 61.215526,488.00452 L 57.778006,484.41076 L 58.246756,480.66074 L 58.871766,478.31698 L 56.840506,476.59822 L 54.965494,473.00445 L 55.434246,472.2232 L 61.996776,471.75445 L 64.028036,471.75445 L 64.965536,472.69195 L 65.590546,472.69195 L 65.434296,471.12944 L 69.184306,470.50444 L 71.684316,470.81694 L 73.090576,471.9107 L 71.684316,473.94196 L 71.215566,475.34821 L 73.871836,476.91072 L 78.715608,478.62948 L 80.434368,477.69198 L 78.246858,473.47321 L 77.309348,470.34819 L 78.246858,469.56694 L 74.965588,467.69193 L 74.496836,466.59817 L 74.965588,465.03567 L 74.184336,461.28565 L 71.371816,456.75438 L 69.028056,452.69186 L 71.840576,450.81685 L 74.965588,450.81685 L 76.684348,451.44185 L 80.746868,451.2856 L 84.340631,447.84809 L 85.434391,444.87932 L 89.028161,442.53556 L 90.590661,443.47307 L 93.246921,442.84806 L 96.840691,440.8168 L 97.934451,440.66055 L 98.871951,441.44181 L 103.24697,441.28556 L 105.90323,438.31679 L 106.99699,438.31679 L 110.4345,440.66055 L 112.30951,442.69181 L 111.84076,443.78557 L 112.46576,444.87932 L 114.02827,443.31682 L 117.77829,443.62932 L 118.09079,447.22308 L 119.9658,448.62934 L 126.84083,449.25434 L 132.93461,453.31686 L 134.34086,452.37936 L 139.34089,454.87937 L 141.37215,454.25437 L 143.24716,453.47311 L 147.93468,455.34812 L 152.15345,458.16063 z M 40.902929,486.12951 L 42.934188,491.28579 L 42.777937,492.22329 L 39.965424,491.91079 L 38.246666,488.00452 L 36.527908,486.59827 L 34.184147,486.59827 L 34.027897,484.09825 L 35.746655,481.75449 L 36.84041,484.09825 L 38.246666,485.50451 L 40.902929,486.12951 z M 38.402917,518.47341 L 41.996684,519.25467 L 45.59045,520.19217 L 46.371704,521.12968 L 44.809197,524.72344 L 41.840433,524.56719 L 38.559168,521.12968 L 38.402917,518.47341 z M 18.402824,504.8796 L 19.49658,507.37961 L 20.590335,508.94212 L 19.49658,509.72337 L 17.46532,506.75461 L 17.46532,504.8796 L 18.402824,504.8796 z M 5.1215129,575.50493 L 8.4027779,573.31742 L 11.684043,572.37991 L 14.184055,572.69241 L 14.652807,574.25492 L 16.527816,574.72367 L 18.402824,572.84867 L 18.090323,571.28616 L 20.746585,570.66116 L 23.559098,573.16117 L 22.465343,574.87992 L 18.246574,575.97368 L 15.590311,575.50493 L 11.996545,574.41117 L 7.7777749,575.81743 L 6.2152679,576.12993 L 5.1215129,575.50493 z M 52.465482,571.12991 L 54.027989,573.00492 L 56.059246,571.44241 L 54.652992,570.1924 L 52.465482,571.12991 z M 55.277995,574.09867 L 56.371746,571.91116 L 58.403006,572.22366 L 57.621756,574.09867 L 55.277995,574.09867 z M 78.090598,572.22366 L 79.496858,573.94242 L 80.434368,572.84867 L 79.653108,570.97366 L 78.090598,572.22366 z M 86.528141,560.19236 L 87.621901,565.81738 L 90.434411,566.59864 L 95.278181,563.78612 L 99.496951,561.28611 L 97.934451,558.94235 L 98.403201,556.59859 L 96.371941,557.8486 L 93.559431,557.06734 L 95.121931,555.97359 L 96.996941,556.75484 L 100.74696,555.03608 L 101.21571,553.62983 L 98.871951,552.84857 L 99.653201,550.97356 L 96.996941,552.84857 L 92.465671,556.28609 L 87.778151,559.0986 L 86.528141,560.19236 z M 127.46583,540.97352 L 129.80959,539.56726 L 128.87209,537.8485 L 127.15333,538.78601 L 127.46583,540.97352 z " id="AK" style="fill:#f4d7d7" /> - <ns0:g id="g16325" style="stroke:#000000;stroke-opacity:1"> - <ns0:g id="g5778" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-opacity:1"> - <ns0:path d="M 816.92419,258.09425 C 817.71859,258.70718 818.14466,259.56702 819.77271,260.56631 L 819.77271,260.61385" id="path6654" style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:#000000;stroke-width:1.33265233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" ns1:nodetypes="ccc" /> - <ns0:g id="g4679" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-opacity:1"> - <ns0:g id="g3580" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-opacity:1"> - <ns0:g id="State_borders_old" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-opacity:1" transform="matrix(1.0566302,0,0,1.0756987,-45.325399,-166.80506)"> - <ns0:path d="M 389.29574,462.33445 L 395.75915,462.99736 L 406.8077,463.54979" id="CO_OK" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 389.79293,462.72114 L 389.2405,473.88019" id="NM_OK" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 389.90342,473.82495 L 388.24613,473.82494 L 386.69931,491.94483 L 382.94283,545.64053 L 380.73312,568.62152 L 352.66979,567.07472 L 324.60654,564.42309 L 316.87248,563.76016 L 317.5354,568.62152" id="NM_TX" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 299.63678,367.31684 L 319.96612,369.74752 L 355.98408,373.72497 L 379.62831,375.71374" id="WY_CO" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 379.62831,375.71374 L 411.89008,378.36539 L 410.34328,400.02056" id="NE_CO" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 410.34328,400.02056 L 406.36581,463.66023" id="CO_KS" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 379.62831,375.71374 L 383.82676,332.84535" id="WY_NE" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 383.82676,332.84535 L 385.37355,308.31756 L 386.63467,290.78272" id="WY_SD" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 386.7128,291.15996 L 388.23277,275.63418 L 388.81756,270.31054" id="MT_SD" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 388.81755,270.85742 L 389.59881,259.06782 L 391.78171,234.95517 L 393.10754,220.37107 L 394.43337,206.67087" id="MT_ND" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 389.13006,270.75248 L 443.26797,274.28802 L 499.6156,275.83481" id="ND_SD" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 490.55578,211.09029 L 492.32355,216.17262 L 491.66064,219.92913 L 491.66064,229.87283 L 493.20744,234.73419 L 494.97521,238.04876 L 495.41715,247.55052 L 497.18492,260.58781 L 498.95269,267.65888 L 499.39463,275.83481" id="ND_MN" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 499.39463,275.83481 L 499.17366,278.92841 L 497.84783,280.25424 L 495.85909,281.80103 L 495.85909,283.34783 L 496.96395,285.1156 L 500.94143,288.43017 L 501.38337,291.30279 L 501.60434,320.69194 L 501.1624,327.32107" id="SD_MN" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 501.1624,327.32107 L 499.39463,327.32107 L 498.51074,329.75176 L 498.95269,332.40341 L 501.60434,334.39215 L 500.27851,339.91643 L 498.51074,344.11488 L 500.05754,346.76653 L 501.60434,348.97624" id="SD_IA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 501.60434,348.97624 L 499.83657,348.97624 L 498.0688,348.97624 L 497.18492,346.9875 L 496.74297,345.4407 L 493.87035,343.89391 L 489.00899,342.34711 L 487.24122,341.02128 L 484.58957,341.24225 L 480.83306,341.68419 L 476.63461,343.01002 L 475.52975,342.12614 L 470.88936,339.25351 L 468.90062,337.0438 L 458.51498,337.48574 L 435.53399,336.38089 L 418.29824,335.27603 L 398.85279,334.17118 L 383.82676,333.50826" id="SD_NE" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 500.94143,327.32107 L 512.21095,327.32107 L 560.16167,326.65816 L 577.61839,325.99525 L 581.59587,325.99525" id="MN_IA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 581.59587,325.99525 L 580.71198,318.7032 L 578.72324,316.05155 L 571.87314,312.07407 L 568.11663,306.54979 L 564.80207,306.10785 L 563.0343,303.01426 L 559.71973,303.01426 L 556.84711,300.14163 L 556.40516,293.73347 L 556.40516,289.97696 L 558.17293,286.88337 L 557.51002,283.78977 L 555.07934,281.80103 L 554.6374,281.58006 L 556.84711,275.83481 L 561.92944,272.07831 L 563.0343,270.53151 L 563.0343,262.35558 L 563.25527,259.70393 L 566.01741,256.8313" id="MN_WI" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 590.71092,259.59344 L 594.85413,264.78626 L 602.80909,265.89112 L 610.76405,268.10083 L 613.19473,269.20568 L 625.34814,271.85734 L 626.67397,274.06705 L 630.2095,275.1719 L 631.7563,285.1156 L 633.08213,286.44143 L 634.62893,287.60152" id="WI_MI" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 581.59587,325.77428 L 582.25878,329.08884 L 584.46849,330.63564 L 584.68946,331.96147 L 582.70072,335.27603 L 582.92169,338.36963 L 585.35238,342.12614 L 587.78306,343.23099 L 590.65568,343.67293 L 591.92627,346.3246" id="IA_WI" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 591.76054,345.88265 L 601.04136,346.10361 L 626.453,344.55682 L 635.95475,343.45196" id="WI_IL" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 591.76054,345.71692 L 591.98151,348.09236 L 594.19122,348.75527 L 595.0751,349.86012 L 595.51704,351.62789 L 599.27355,354.94246 L 599.93647,357.15217 L 599.27355,360.46674 L 597.50578,364.00227 L 596.84287,366.43295 L 594.63316,368.20072 L 592.86539,368.86364 L 587.78306,370.18946 L 587.12014,371.95723 L 586.45723,373.94597 L 587.12014,375.2718 L 588.88791,376.8186 L 588.66694,380.79607 L 586.89917,382.34287 L 586.23626,383.88967 L 586.23626,386.54132 L 584.46849,386.98326 L 582.92169,388.08812 L 582.70072,389.41395 L 582.92169,391.40269 L 581.15393,393.05996" id="IA_IL" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 581.3749,393.17045 L 578.06033,389.85589 L 576.95547,387.64618 L 569.44246,388.30909 L 559.9407,388.75103 L 535.41291,389.63492 L 522.37562,389.85589 L 513.31581,390.07686 L 511.98998,390.07686" id="IA_MO" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 512.53686,390.31124 L 510.66415,384.99453 L 510.44318,378.58636 L 508.89638,374.60888 L 508.23347,369.52655 L 506.02376,365.99101 L 505.13988,361.35062 L 502.48822,354.05857 L 501.1624,348.75527" id="NE_IA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 410.12231,399.79959 L 431.33554,400.68347 L 470.44713,402.00929 L 513.09483,402.45124 L 519.06105,402.45124" id="NE_KS" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 519.06105,402.45124 L 515.96746,398.47376 L 513.53678,394.71725 L 513.75775,392.50754 L 512.43192,390.07686" id="NE_MO" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 518.84008,402.45124 L 521.93368,405.10289 L 524.14339,405.32386 L 525.46921,406.20775 L 525.46921,409.08037 L 523.70145,410.62717 L 523.2595,412.83688 L 525.24824,416.15145 L 527.67893,419.02407 L 530.10961,420.79184 L 531.43543,432.06136 L 530.77252,466.53285" id="KS_MO" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 530.77252,466.53285 L 517.95614,467.19576 L 473.09935,466.75383 L 429.56781,464.76507 L 406.08959,463.43925" id="KS_OK" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 388.4119,473.88015 L 410.34328,474.92975 L 440.39535,476.03461 L 439.06952,499.0156 L 438.62758,516.25134 L 438.84855,517.79814 L 443.047,521.33368 L 445.03574,522.43853 L 445.69866,522.21756 L 446.36157,520.22882 L 447.6874,521.99659 L 449.67614,521.99659 L 449.67614,520.67076 L 452.32779,521.99659 L 451.88585,525.7531 L 455.86333,525.97407 L 458.29401,527.07893 L 462.27149,527.74184 L 464.70217,529.50961 L 466.91188,527.52087 L 470.22645,528.18378 L 472.65713,531.49835 L 473.54101,531.49835 L 473.54101,533.70806 L 475.75072,534.37097 L 477.96043,532.16126 L 479.7282,532.82417 L 482.15888,532.82417 L 483.04277,535.25486 L 487.68316,537.02262 L 489.00899,536.35971 L 490.77676,532.38223 L 491.88161,532.38223 L 492.98647,534.37097 L 496.96395,535.03388 L 500.49948,536.35971 L 503.37211,537.2436 L 505.13988,536.35971 L 505.80279,533.92903 L 510.00124,533.92903 L 511.98998,534.81291 L 514.64163,532.82417 L 515.74649,532.82417 L 516.4094,534.37097 L 520.38688,534.37097 L 521.93368,532.38223 L 523.70145,532.82417 L 525.69019,535.25486 L 528.78378,537.02262 L 531.87738,537.90651 L 534.52903,539.45331" id="OK_TX" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 534.52903,539.45331 L 534.30806,502.55125 L 532.98222,491.94454 L 532.98223,483.98957 L 531.43543,477.36043" id="OK_AR" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 531.43543,477.36043 L 530.99349,470.7313 L 530.77252,465.86994" id="OK_MO" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 531.43543,477.36043 L 553.97448,476.91849 L 576.51353,476.25558 L 596.6219,475.37169 L 607.22851,474.92975 L 608.99628,477.80238 L 608.55434,480.01209 L 605.46074,482.66374 L 604.79783,485.53636 L 610.76405,485.97831 L 615.62541,485.31539" id="MO_AR" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 615.62541,485.31539 L 617.61415,479.1282 L 617.61415,473.38295" id="MO_TN" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 617.33793,473.99063 L 620.26581,472.2781 L 621.59163,470.7313 L 623.58037,469.62645 L 623.80134,466.53285 L 624.68523,464.76508 L 623.13842,462.27915" id="MO_KY" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 623.58037,462.55537 L 620.48678,462.77634 L 618.71901,460.7876 L 617.17221,456.81012 L 618.05609,453.9375 L 616.06735,450.84391 L 614.07862,445.98254 L 609.65919,445.31963 L 603.472,440.23729 L 601.26229,436.48079 L 601.92521,433.38719 L 604.13492,427.64194 L 604.79783,424.10641 L 602.14618,422.78058 L 595.95899,422.33864 L 595.0751,421.01281 L 595.29607,416.81436 L 589.99277,413.27882 L 582.92169,405.98678 L 580.71198,398.9157 L 580.27004,395.38017 L 581.3749,392.28657" id="MO_IL" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 534.52903,538.79039 L 536.73874,541.0001 L 539.61136,539.67428 L 542.26302,540.77913 L 542.92593,551.38574" id="TX_AR" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 542.92593,551.38574 L 542.92593,560.8875 L 543.58884,569.94731 L 544.25176,573.70382 L 546.68244,577.6813 L 547.56632,582.54267 L 551.76477,587.84597 L 551.98574,590.93957 L 552.64866,591.60248 L 551.98574,599.77841 L 549.11312,604.63977 L 550.65992,606.62851 L 549.997,609.05919 L 549.33409,616.13027 L 548.00826,619.22386 L 548.28448,622.70416" id="TX_LA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 542.87069,551.88293 L 564.36012,551.60672 L 582.92169,550.72283 L 593.30733,550.72283" id="AR_LA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 593.52831,550.72283 L 593.74928,556.02614 L 595.73802,560.44556 L 595.51704,562.21333 L 597.72676,563.9811 L 597.06384,567.07469 L 595.95899,567.07469 L 596.84287,569.06343 L 591.76054,577.90227 L 588.44597,583.86849 L 587.78306,591.60248 L 588.225,593.14928 L 611.64793,592.48636 L 619.60289,591.82345 L 621.37066,591.60248 L 622.03357,592.48636 L 620.92872,599.77841 L 624.24328,602.872 L 625.34814,606.62851 L 626.61872,609.00395" id="LA_MS" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 593.41781,550.99905 L 594.79888,548.29215 L 594.41219,544.0937 L 593.08636,541.22107 L 594.41219,539.89525 L 593.08636,537.90651 L 593.52831,536.13874 L 594.41219,530.17252 L 597.28481,527.52087 L 596.6219,525.53213 L 600.15744,520.44979 L 602.80909,519.56591 L 602.80909,517.13523 L 602.14618,515.8094 L 604.79783,510.72707 L 607.44948,509.62221 L 607.44948,506.08667" id="AR_MS" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 642.50096,359.68676 L 643.28221,370.93678 L 644.53221,385.78055 L 645.78222,401.24932 L 646.25097,407.96808 L 645.46972,413.28059 L 645.78222,416.40559 L 647.50097,419.06185 L 647.96972,424.68686 L 645.46972,428.74936 L 643.75096,432.49937 L 641.56346,435.31187 L 641.09471,439.68688 L 641.09471,443.28063" id="IL_IN" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 641.09471,443.28063 L 640.15721,446.56189 L 639.06346,447.34314 L 639.68846,449.21814 L 640.46971,450.9369 L 638.90721,451.5619 L 636.4072,452.1869 L 634.5322,453.59315 L 634.2197,455.78065 L 635.4697,458.12441 L 635.31345,460.31191 L 634.2197,460.62441 L 630.78219,459.37441 L 628.12594,458.12441 L 626.09469,458.74941 L 623.90718,460.46816 L 623.12593,462.34316" id="IL_KY" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 641.25096,443.43688 L 644.06346,441.71813 L 649.68847,440.78063 L 653.12598,440.31188 L 654.53223,442.18688 L 656.25098,442.96813 L 657.96973,439.84313 L 660.78224,438.43688 L 662.65724,439.99938 L 663.43849,441.09313 L 665.46975,440.62438 L 665.31349,437.34313 L 668.126,435.78062 L 669.21975,434.99937 L 670.3135,436.56187 L 674.84476,436.56187 L 675.62601,434.53062 L 675.31351,432.34312 L 678.12601,428.90561 L 682.65727,425.15561 L 683.12602,420.7806 L 685.78228,420.4681 L 689.53228,418.74935 L 692.18854,416.87434 L 691.87603,414.99934 L 690.46978,413.59309 L 690.93853,411.40559" id="IN_KY" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 690.93853,411.40559 L 690.46978,405.93683 L 687.96978,383.28054 L 686.25103,369.99927 L 684.84477,355.7805" id="IN_OH" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 684.84477,355.7805 L 684.68852,354.68675 L 678.75102,355.31175 L 657.50098,357.49926 L 652.96973,357.49926" id="IN_MI" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 615.46967,485.07202 L 614.58577,488.10878 L 613.28217,492.34321 L 612.96967,494.84321 L 609.06341,497.03071 L 610.46966,500.46822 L 609.53216,504.99948 L 606.87591,506.09323" id="AR_TN" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 607.65716,506.56198 L 615.93842,506.24948 L 639.21971,504.37448 L 642.96971,504.21823" id="TN_MS" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 644.51654,503.77628 L 644.53221,510.31198 L 644.68846,526.40576 L 643.90721,556.4058 L 643.75096,569.99957 L 646.40722,588.1246 L 647.9524,603.33611" id="MS_AL" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 642.65721,504.21823 L 652.18848,503.74947 L 679.06352,501.24947 L 689.03673,500.46822" id="TN_AL" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 199.86827,240.25868 L 200.31021,231.08839 L 203.84575,215.17847 L 208.15468,195.07011 L 211.8007,182.03283 L 212.5741,178.27632" id="WA_ID" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 105.11516,210.08273 L 107.72336,210.64857 L 108.38627,213.07925 L 112.36375,213.63168 L 114.57346,217.38818 L 114.35249,224.9012 L 113.68958,225.6746 L 119.43482,229.65208 L 125.40104,229.98353 L 127.27929,228.21576 L 131.47774,229.65208 L 132.25114,229.54159 L 137.33348,231.53033 L 138.99076,232.85615 L 143.52066,233.07713 L 144.736,232.41421 L 147.0562,233.96101 L 151.36513,234.51344 L 156.66844,232.5247 L 157.11038,233.85052 L 172.02592,233.74004 L 186.61001,237.16509 L 200.38279,240.66827" id="WA_OR" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 199.97875,240.59014 L 201.19409,244.6781 L 204.50866,247.21927 L 204.28769,250.86529 L 200.53118,255.06374 L 196.77467,260.6985 L 195.89079,261.36141 L 195.33836,264.45501 L 194.23351,265.55986 L 192.46574,266.0018 L 188.1568,271.30511 L 187.82535,274.28822 L 187.38341,275.39307 L 188.1568,276.38744 L 190.58749,276.27696 L 191.80283,278.48667 L 189.37215,284.23191 L 188.04632,288.31988 L 183.84787,305.44513 L 179.53894,322.90184" id="OR_ID" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 134.1294,312.29523 L 126.28493,342.89971 L 119.54531,367.97992 L 117.96384,374.32659 L 129.93095,392.28673 L 151.91756,424.99044 L 170.7001,453.05375 L 184.73175,475.04037 L 187.28633,478.33598" id="CA_NV" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 179.25879,323.29247 L 199.53681,327.65271 L 208.92808,329.53097 L 217.8774,331.29873 L 225.72187,333.17699" id="ID_NV" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 225.5009,333.28747 L 237.87528,335.49718 L 249.47626,337.48592 L 259.41995,339.25369 L 267.48539,340.57952 L 272.23627,341.24243" id="ID_UT" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 187.05195,478.02348 L 186.61001,481.33804 L 189.26166,486.08892 L 190.477,491.72368 L 191.2504,492.71805 L 192.24477,493.27048 L 192.13428,495.48019 L 190.58749,496.80601 L 187.27292,498.46329 L 185.39467,500.34155 L 183.95836,503.87708 L 183.40593,508.62796 L 180.64379,511.27961 L 178.65505,511.94253 L 178.54457,517.57729 L 178.10262,519.23457 L 178.54457,520.00797 L 182.0801,520.56039 L 181.52767,523.21205 L 180.09136,525.31127 L 176.44534,526.19515" id="CA_AZ" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 187.27292,478.24445 L 188.59875,476.03474 L 189.15117,463.88133 L 189.37215,462.22405 L 189.48263,455.48444 L 191.36088,454.49007 L 192.24477,453.93764 L 193.12865,453.93764 L 194.01254,455.04249 L 196.66419,455.37395 L 197.87953,458.0256 L 200.31021,458.13609 L 201.96749,455.59492 L 202.40943,455.15298 L 205.40595,437.74758" id="NV_AZ" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 205.28206,438.35918 L 207.16031,427.86306 L 210.2539,413.16849 L 213.45798,397.14809 L 215.55721,384.00032 L 217.43546,375.38245 L 221.08148,355.60554 L 224.50653,338.70126 L 225.61139,333.50844" id="NV_UT" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 70.710722,294.61753 L 77.560823,296.82724 L 88.609373,299.69986 L 95.901416,301.6886 L 108.05482,305.66608 L 121.09211,308.98065 L 134.1294,312.73715" id="OR_CA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 133.68746,312.68584 L 166.39117,320.47114 L 179.64943,323.34376" id="OR_NV" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 226.27435,180.81733 L 221.85493,201.58861 L 225.1695,208.88065 L 223.84367,213.30007 L 225.61144,217.71949 L 228.70504,219.04532 L 232.24057,228.98902 L 235.77611,232.52455 L 236.21805,233.62941 L 239.53262,234.73427 L 239.97456,236.723 L 233.12446,253.73778 L 233.12446,256.16846 L 235.55514,259.26205 L 236.43902,259.26205 L 241.07941,256.38943 L 241.74233,255.28457 L 243.28913,255.94749 L 243.06815,261.02982 L 245.71981,273.18323 L 248.59243,275.61391 L 249.47631,276.27682 L 251.24408,278.48653 L 250.80214,281.8011 L 251.46505,285.11566 L 252.56991,285.99955 L 254.77962,283.78984 L 257.43127,283.78984 L 260.52487,285.33664 L 262.95555,284.45275 L 266.93303,284.45275 L 270.46856,285.99955 L 273.12022,285.55761 L 273.56216,282.68498 L 276.43478,282.02207 L 277.76061,283.3479 L 278.20255,286.44149 L 280.63323,288.6512" id="ID_MT" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 280.76267,289.04183 L 282.18003,277.82362 L 301.40451,280.69624 L 328.80492,284.67372 L 344.49387,286.66246 L 375.50794,289.84759 L 386.47836,290.86091" id="MT_WY" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 280.8542,288.20926 L 277.0977,312.07413 L 272.01536,341.46328" id="ID_WY" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 272.01536,341.46328 L 270.5356,351.6275 L 268.92177,363.11844 L 275.2273,364.01574 L 291.55004,366.22545 L 300.53404,367.40842" id="UT_WY" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 300.29966,367.31689 L 297.42703,388.75109 L 294.33344,410.40625 L 290.70637,437.45625 L 289.2511,448.1923 L 288.58819,452.16978" id="UT_CO" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 205.06113,437.58569 L 237.54388,443.77288 L 263.83943,448.1923 L 288.80916,451.85728" id="UT_AZ" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 288.58819,451.94881 L 284.5839,481.67727 L 277.85214,533.09881 L 274.22507,559.11977 L 272.4573,571.93609" id="AZ_NM" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 288.80916,451.72784 L 321.95482,455.92629 L 357.65689,460.20517 L 389.35099,462.33445" id="CO_NM" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 685.15727,355.93675 L 692.50104,354.68675 L 702.3448,353.12425 L 707.42849,352.54501" id="MI_OH" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 691.09478,411.56184 L 695.00104,411.24934 L 697.34479,410.46809 L 700.1573,412.03059 L 701.7198,416.24934 L 707.34481,416.56184 L 709.06356,418.2806 L 711.09481,418.43685 L 713.43857,417.0306 L 716.40732,417.49935 L 717.65732,418.9056 L 720.31358,416.40559 L 722.03233,415.15559 L 723.59483,415.15559 L 724.21983,417.81185 L 725.93859,418.74935 L 729.37609,420.7806" id="OH_KY" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 729.37609,420.7806 L 729.53234,426.09311 L 730.31359,427.65561 L 732.8136,429.06186 L 733.4386,431.24937 L 736.2511,434.84312 L 738.7511,437.49938 L 741.92187,439.62379" id="KY_WV" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 742.03236,438.90563 L 738.90736,442.65563 L 734.84485,446.09314 L 730.46984,451.2494 L 728.75109,452.96815 L 728.75109,454.9994 L 725.00108,457.03065 L 719.53233,460.31191 L 716.70413,461.72601" id="KY_VA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 717.31181,461.61552 L 666.876,466.40567 L 651.64388,468.12442 L 647.17734,468.61997 L 643.43846,468.59317 L 643.43846,472.34318 L 635.31345,472.81193 L 628.59469,473.43693 L 618.12592,473.59318" id="KY_TN" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 665.15724,603.28087 L 664.84474,595.46836 L 662.34474,593.59336 L 660.62599,591.87461 L 660.93849,588.90585 L 670.78225,587.65585 L 695.46979,584.84335 L 702.0323,584.21835 L 708.12606,584.21835" id="AL_FL" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 708.12606,584.21835 L 707.34481,580.78084 L 705.93856,579.99959 L 705.31355,579.21834 L 706.09481,576.87458 L 705.78231,571.71833 L 704.2198,567.49957 L 704.37605,565.62457 L 704.8448,562.49956 L 706.56356,557.81206 L 706.40731,555.7808 L 704.5323,554.99955 L 704.06355,551.7183 L 701.56355,548.43704 L 699.5323,542.34328 L 698.12604,535.62452 L 696.56354,530.93702 L 695.15729,524.99951 L 692.81354,515.46824 L 689.53228,507.81198 L 688.90728,504.53073 L 688.75103,502.49947 L 688.75103,500.31197" id="AL_GA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 707.81356,583.90584 L 710.46981,587.8121 L 711.87606,589.21835 L 719.53233,589.3746 L 729.98996,588.7496 L 750.78237,587.4996 L 756.04583,586.8478 L 760.46989,586.8746 L 760.62614,589.6871 L 763.12614,590.46835 L 763.43864,586.2496 L 761.87614,581.87459 L 762.96989,580.31209 L 768.5949,581.09334 L 773.59491,581.40584" id="GA_FL" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 688.75103,500.46822 L 697.03229,499.53072 L 705.1573,498.43697 L 709.84481,497.65572" id="TN_GA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 709.84481,497.65572 L 716.40732,497.18696 L 723.12608,496.40571 L 728.75109,495.46821 L 730.46984,495.31196" id="NC_GA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 730.46984,495.31196 L 730.62609,497.18696 L 728.43859,498.12447 L 727.65734,499.99947 L 727.96984,501.71822 L 729.21984,502.96822 L 733.1261,505.31198 L 736.40735,505.15573 L 739.68861,510.15573 L 740.15736,511.56199 L 742.50111,514.37449 L 742.96986,515.78074 L 747.34487,517.4995 L 750.31362,519.687 L 752.50113,522.4995 L 754.68863,523.7495 L 756.71988,525.62451 L 757.96988,528.12451 L 760.00114,529.99951 L 764.06364,531.87452 L 766.7199,537.65578 L 768.2824,542.34328 L 770.7824,542.96828 L 772.96991,544.99954 L 774.21991,548.43704 L 774.84491,550.46829 L 777.34491,551.7183 L 779.37617,550.7808" id="GA_SC" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 730.15734,494.99946 L 736.2511,492.65571 L 745.00111,488.2807 L 752.03237,487.49945 L 767.9699,487.0307 L 770.1574,488.9057 L 771.7199,492.03071 L 775.93866,491.56196 L 788.12618,490.1557 L 790.93868,490.93696 L 803.1262,498.28072 L 812.97945,506.32368" id="NC_SC" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 709.84481,497.65572 L 710.15731,492.96821 L 711.87606,491.56196 L 714.53232,490.93696 L 715.15732,487.3432 L 719.21983,484.68695 L 722.96983,483.28069 L 727.03234,479.84319 L 731.25109,477.81194 L 731.87609,474.84318 L 735.6261,471.09318 L 736.2511,470.93693 C 736.2511,470.93693 736.2511,472.03068 737.03235,472.03068 C 737.8136,472.03068 738.90736,472.34318 738.90736,472.34318 L 741.09486,468.90567 L 743.12611,468.28067 L 745.31361,468.59317 L 746.87612,465.15567 L 749.68862,462.65566 L 750.15737,460.62441 L 750.31362,456.71815" id="TN_NC" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 717.03232,461.56191 L 726.53223,460.74273 L 738.1261,458.90566 L 745.78237,458.74941 L 748.12612,456.8744 L 750.34206,456.92964" id="VA_TN" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 750.00112,456.8744 L 754.53238,457.49941 L 761.42964,456.2494 L 776.71991,454.3744 L 793.28244,451.8744 L 813.19549,448.22704 L 831.71999,444.53064 L 842.81376,441.71813 L 847.56599,440.14615" id="VA_NC" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 741.65514,439.21813 L 743.90736,442.34313 L 745.15736,443.59313 L 747.96987,444.37439 L 750.46987,443.74938 L 752.81363,441.56188 C 752.81363,441.56188 754.53238,442.96813 755.15738,442.81188 C 755.78238,442.65563 759.37614,441.87438 759.37614,441.87438 L 761.09489,437.34313 L 763.59489,438.28063 L 766.7199,435.93687 L 768.12615,436.24937 L 770.1574,434.37437 L 770.31365,431.71812 L 769.5324,430.46812 L 774.37616,419.99935 L 776.40741,413.59309 L 776.71991,409.37433 L 778.43866,409.21808 L 780.00117,411.87434 L 781.25117,412.65559 L 783.75117,412.65559 L 784.84492,407.34308 L 785.15742,404.37433 L 788.43868,404.06183 L 788.90743,401.87432 L 791.87618,399.53057 L 792.50119,397.96807 L 794.06369,395.31181 L 794.53244,393.28056 L 794.68869,388.1243 L 799.06369,389.84305 L 804.53246,392.81181 L 805.46995,387.65555" id="WV_VA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 805.15745,388.1243 L 809.37621,389.84305 L 809.37621,392.65556 L 814.68872,393.90556 L 816.56372,395.15556 L 817.50122,393.28056 L 819.68873,394.84306 L 818.28247,397.96807 L 817.96997,400.62432 L 816.25122,403.12432 L 816.25122,405.15558 L 816.87622,406.87433 L 822.13512,408.2443" id="VA_MD" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 805.6262,388.28055 L 804.21995,386.71805 L 802.34495,384.9993 L 799.53245,383.59305 L 797.94314,382.50092 L 796.15966,382.96967 L 794.21994,384.3743 L 791.71993,386.40555 L 788.90743,386.71805 L 787.65743,386.09305 L 785.93868,388.59305 L 784.53242,389.9993 L 782.18867,390.15555 L 780.00117,393.12431 L 777.96991,395.46806 L 777.65741,395.78056 L 776.71991,390.31181 L 775.31366,385.3118" id="WV_MD" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 775.64512,385.53277 L 763.62333,387.03055 L 759.14731,387.75656 L 755.60717,368.59302" id="PA_WV" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 755.93863,368.59302 L 754.53238,369.84302 L 753.59488,371.24928 L 754.68863,374.21803 L 754.68863,378.74929 L 754.21988,383.59305 L 753.90738,389.0618 L 751.71987,392.81181 L 748.75112,396.09306 L 746.56362,397.65557 L 744.53236,397.18682 L 743.28236,398.59307 L 741.09486,401.87432 L 740.15736,403.12432 L 740.15736,405.46808 L 741.25111,407.18683 L 740.78236,408.74933 L 739.06361,409.68683 L 738.59485,407.96808 L 737.34485,406.87433 L 736.09485,407.49933 L 735.15735,411.24934 L 735.0011,416.09309 L 733.4386,417.49935 L 733.28235,420.1556 L 731.40734,420.93685 L 729.21984,421.24935" id="OH_WV" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 751.25169,340.03513 L 754.06419,358.74889 L 755.78295,369.68641" id="OH_PA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 761.7015,331.46032 L 762.34546,338.28009 L 770.93923,336.87384 L 812.50182,328.43632 L 830.47061,324.53006 L 832.72285,326.59924 L 835.62687,327.49882 L 837.97063,332.65508 L 840.15813,334.53008 L 842.65814,334.68633 L 843.90814,335.78009" id="NY_PA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 843.75189,335.62383 L 847.34565,337.34259 L 851.09566,338.43634 L 855.47067,339.37384 L 857.97067,340.4676 L 858.12692,342.49885 L 857.65817,345.15511 L 858.24689,348.66681" id="NY_NJ" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 844.06439,335.46758 L 841.72064,337.96759 L 841.72064,340.93635 L 839.84563,343.9051 L 839.68938,345.46761 L 840.93939,346.71761 L 840.78314,349.06137 L 838.59563,350.15512 L 839.37688,352.81137 L 839.53313,353.90513 L 842.18939,354.21763 L 843.12689,356.71763 L 846.5644,359.06139 L 848.90815,360.62389 L 848.90815,361.40514 L 845.78315,364.3739 L 844.22064,366.5614 L 842.81439,369.21766 L 840.62689,370.46766 L 839.53313,371.24891" id="PA_NJ" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 839.37688,371.09266 L 839.22063,372.34267 L 838.66983,374.88059" id="DE_NJ" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 839.53313,371.09266 L 837.50188,371.09266 L 835.47062,372.65517 L 834.06437,374.06142" id="NY_DE" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 834.06437,374.06142 L 835.47062,378.12393 L 837.65813,383.59269 L 839.68938,392.96771 L 841.25189,399.06148 L 846.09565,398.90523 L 852.03316,397.81147" id="MD_DE" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 834.38635,373.6842 L 826.20281,375.44087 L 811.82448,378.1697 L 774.68924,385.62395" id="PA_MD" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 862.06162,339.46537 L 860.15818,337.34259 L 861.25193,335.15508 L 861.25193,327.34257 L 859.84568,320.3113 L 859.06443,316.87379" id="NY_CT" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 859.06443,316.87379 L 858.28318,311.56128 L 858.75193,301.09251" id="NY_MA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 858.75193,301.09251 L 858.28318,296.0925 L 855.31442,285.46747 L 854.68942,285.15497 L 851.87691,283.90497 L 852.65816,281.09246 L 851.87691,279.06121 L 849.37691,274.6862 L 850.31441,270.93619 L 849.53316,265.93618 L 847.1894,259.68616 L 846.5644,254.8424" id="NY_VT" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 872.65821,247.81114 L 872.97071,253.5924 L 874.84571,256.24866 L 874.84571,260.15492 L 871.25195,264.06117 L 868.75195,265.15493 L 868.75195,266.24868 L 869.8457,267.96743 L 869.8457,276.2487 L 869.06445,285.15497 L 868.9082,289.84248 L 869.8457,291.09249 L 869.68945,295.46749 L 869.2207,297.18625 L 870.7832,299.06125" id="VT_NH" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 859.06443,301.56126 L 863.90819,300.46751 L 870.4707,299.2175" id="VT_MA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 870.4707,299.2175 L 887.34574,295.15499 L 889.53325,294.52999 L 891.5645,291.40499 L 895.50868,289.5947" id="NH_MA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 896.48246,285.35698 L 894.06451,284.21747 L 893.59575,281.24871 L 889.84575,280.15496 L 889.53325,277.4987 L 882.50198,254.8424 L 877.81447,240.46737" id="NH_ME" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 859.37693,317.34254 L 880.31447,312.49878 L 885.31449,311.40503" id="MA_CT" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 885.31449,311.40503 L 886.87699,317.18629 L 887.65824,321.40505 L 888.28324,325.46756" id="CT_RI" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - <ns0:path d="M 885.15824,311.56128 L 890.78325,309.99878 L 892.34575,311.09253 L 895.62701,315.31129 L 898.43952,319.6863" id="RI_MA" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1pt;stroke-opacity:1" /> - </ns0:g> - <ns0:g id="g3561" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-opacity:1"> - <ns0:path d="M 242.11104,448.52821 L 258.12559,450.54515 L 259.44637,440.12432 L 276.45152,442.81356 L 290.31977,444.66242" id="NM_Mexico" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2.66530466;stroke-dasharray:none;stroke-opacity:1" /> - <ns0:path d="M 289.98957,444.32625 L 292.13584,444.99855 L 294.77744,448.02394 L 296.26332,452.56207 L 301.05119,454.91517 L 302.37198,458.27673 L 309.63631,466.51255 L 310.9571,468.19333 L 316.07515,470.37834 L 317.23084,472.56336 L 318.88182,473.57182 L 319.37712,476.42915 L 322.67909,483.15227 L 322.67909,491.55616 L 324.99047,496.43042 L 332.585,504.49816 L 337.86815,506.68317 L 339.68423,508.70011 L 339.68423,509.37242 L 343.64659,511.72551 L 345.62777,512.39782 L 347.44386,513.57437 L 350.08543,514.58284 L 352.56191,512.06167 L 357.01957,505.67471 L 358.01016,501.80891 L 360.32154,498.44736 L 363.9537,496.93466 L 368.57646,495.0858 L 371.71333,497.43889 L 379.30786,498.1112 L 386.242,499.28775 L 388.88357,501.47276 L 388.88357,502.6493 L 391.52515,505.84279 L 397.63379,511.38936 L 397.79889,512.90206 L 399.61497,514.91899 L 400.44047,519.28902 L 405.88872,532.06294 L 405.72362,534.07988 L 410.01618,536.76912 L 413.64834,543.66032 L 417.11541,548.19842 L 420.41738,549.54304 L 422.06837,551.89614 L 420.74758,556.43424 L 421.40797,557.44271 L 422.72876,558.11502 L 422.39856,561.64466 L 421.73817,562.31697 L 422.39856,564.67006 L 425.70053,566.68699 L 427.02132,573.41011 L 429.1676,577.44398 L 436.92723,580.97362 L 442.21038,582.15016 L 446.50294,585.34364 L 449.80491,586.01595 L 451.1257,585.51172 L 456.73904,586.68827 L 462.51749,590.72214 L 465.65436,588.7052" id="TX_Mexico" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2.66530466;stroke-dasharray:none;stroke-opacity:1" /> - <ns0:path d="M 95.503595,393.0625 L 105.7397,394.5752 L 125.88171,397.43253 L 140.74058,399.1133" id="CA_Mexico" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2.66530466;stroke-dasharray:none;stroke-opacity:1" /> - <ns0:path d="M 140.74058,399.1133 L 138.4292,401.4664 L 138.099,402.9791 L 138.5943,403.98756 L 157.91082,415.08071 L 170.2932,422.98037 L 185.31716,431.8885 L 202.4874,442.30933 L 215.03489,444.8305 L 242.11104,448.52821" id="AZ_Mexico" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2.66530466;stroke-dasharray:none;stroke-opacity:1" /> - <ns0:g id="g3547" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-opacity:1"> - <ns0:path d="M 876.74955,100.10268 L 848.85548,107.51359" id="VT_Canada" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2.66530466;stroke-dasharray:none;stroke-opacity:1" /> - <ns0:path d="M 943.28423,76.73985 L 940.47756,76.907928 L 940.97285,78.084474 L 940.80775,78.588708 L 939.98226,78.588708 L 937.01049,76.235617 L 936.84539,71.193279 L 936.0199,69.176344 L 929.91126,69.176344 L 920.66574,38.081928 L 918.68456,37.073461 L 912.57592,34.552292 L 911.09003,34.384214 L 909.27395,36.233071 L 905.14649,39.258474 L 905.14649,40.266941 L 904.32099,41.107331 L 901.51432,40.435019 L 900.19353,38.081928 L 900.19353,36.905383 L 898.87274,36.737305 L 897.55196,36.737305 L 895.40568,41.107331 L 892.4339,50.351617 L 890.61782,55.393954 L 890.78292,60.436292 L 890.94802,61.948993 L 890.12252,64.806318 L 889.29703,65.814786 L 889.29703,72.033669 L 891.27821,74.554837 L 889.79233,78.756786 L 887.15075,83.631045 L 886.32526,89.345695 L 886.32526,92.034941 L 884.77927,91.608771 L 881.71077,91.733617" id="ME_Canada" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2.66530466;stroke-dasharray:none;stroke-opacity:1" /> - <ns0:path d="M 882.59051,91.36264 L 881.5374,92.203019 L 880.87701,93.883799 L 880.21662,93.379565 L 879.22603,92.371097 L 877.74014,94.388032 L 875.84148,100.77501" id="NH_Canada" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2.66530466;stroke-dasharray:none;stroke-opacity:1" /> - <ns0:g id="g3537" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-opacity:1"> - <ns0:path d="M 710.49539,188.67975 L 711.48598,189.52014 L 710.49539,190.69668 L 710.66049,191.36899 L 711.48598,191.53707 L 713.46716,190.5286 L 713.13697,180.61201 M 704.88204,204.47907 L 704.88204,198.9325 L 706.86322,196.91556 L 707.68872,196.57941" id="MI_Canada" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2.66530466;stroke-dasharray:none;stroke-opacity:1" /> - <ns0:path d="M 766.79397,165.82115 L 768.77515,172.20811 L 770.59123,172.37619 L 771.91202,175.56967 M 849.4392,107.39474 L 841.58358,109.51505 L 836.96082,111.02775 L 833.65885,110.85967 L 828.0455,112.20429 L 824.7235,113.61855" id="NY_Canada" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2.66530466;stroke-opacity:1" /> - <ns0:g id="g3530" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-opacity:1"> - <ns0:path d="M 179.70368,24.971818 L 163.02887,21.106058 L 139.58489,15.223331 L 119.11268,9.3406038 L 110.36246,7.3236687 L 100.45655,4.4663441 L 95.99889,2.9536428" id="WA_Canada" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2.66530466;stroke-dasharray:none;stroke-opacity:1" /> - <ns0:path d="M 193.57209,27.997253 L 179.20868,25.139971" id="ID_Canada" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2.66530466;stroke-dasharray:none;stroke-opacity:1" /> - <ns0:path d="M 371.21804,55.393954 L 338.69364,52.032396 L 308.81082,48.334682 L 278.92799,44.132734 L 245.9083,38.586162 L 227.08707,35.056526 L 193.57209,27.997253" id="MT_Canada" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2.66530466;stroke-dasharray:none;stroke-opacity:1" /> - <ns0:path d="M 472.75352,59.76398 L 442.87077,59.427825 L 423.88445,58.755513 L 396.8083,57.410889 L 371.21804,55.393954" id="ND_Canada" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2.66530466;stroke-dasharray:none;stroke-opacity:1" /> - <ns0:path d="M 590.4688,78.756786 L 585.35075,79.261019 L 584.85546,80.269487 L 584.19506,80.269487 L 582.37898,77.076006 L 573.29856,77.412162 L 572.30797,78.252552 L 571.31738,78.252552 L 570.82209,76.907928 L 569.99659,75.059071 L 567.35502,75.563305 L 564.05305,78.924863 L 562.40206,79.765253 L 559.26519,79.765253 L 556.62362,78.756786 L 556.62362,76.571773 L 555.30283,76.403695 L 554.80753,76.907928 L 552.16596,75.563305 L 551.67066,72.537902 L 550.18478,73.042136 L 549.68948,74.050604 L 547.21301,73.54637 L 541.76476,71.025201 L 537.80239,68.335954 L 534.83062,68.335954 L 533.50983,67.327487 L 531.19845,67.999799 L 530.04276,69.176344 L 529.71257,70.520967 L 524.75961,70.520967 L 524.75961,68.335954 L 518.32077,67.999799 L 517.99058,66.487097 L 513.03762,66.487097 L 511.38664,64.806318 L 509.90075,58.419357 L 509.07526,52.704708 L 507.09408,51.864318 L 504.7827,51.360084 L 504.1223,51.528162 L 503.79211,60.100136 L 472.09313,60.100136" id="MN_Canada" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2.66530466;stroke-dasharray:none;stroke-opacity:1" /> - </ns0:g> - </ns0:g> - </ns0:g> - </ns0:g> - </ns0:g> - <ns0:g id="g4675" style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-opacity:1"> - <ns0:path d="M 846.52085,274.72594 L 847.80814,273.69012 L 850.29359,272.77823 L 852.1404,272.10064 L 852.89317,271.82446 L 853.40684,271.87199" id="path3995" style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:#000000;stroke-width:1.33265233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" ns1:nodetypes="cccccc" /> - <ns0:path d="M 817.25107,257.90409 C 818.2317,258.85489 818.79206,259.61552 818.79206,259.61552 L 819.39913,260.85156 L 819.53922,260.70894" id="path5767" style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:#000000;stroke-width:0.41898587;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" ns1:nodetypes="cccc" /> - </ns0:g> - </ns0:g> - </ns0:g> - <ns0:path d="M 152.15345,458.16063 L 151.84095,540.66102 L 153.40345,541.59852 L 156.37222,541.75477 L 157.77847,540.66102 L 160.27848,540.66102 L 160.43474,543.47353 L 167.15352,550.03606 L 167.62227,552.53607 L 170.90353,550.66106 L 171.52854,550.50481 L 171.84104,547.53605 L 173.24729,545.97354 L 174.34105,545.81729 L 176.21606,544.41103 L 179.18482,546.44229 L 179.80983,549.25481 L 181.68483,550.34856 L 182.77859,552.69232 L 186.52861,554.41108 L 189.80987,560.19236 L 192.46613,563.94237 L 194.65364,566.59864 L 196.0599,570.1924 L 200.90367,571.91116 L 205.9037,573.94242 L 206.8412,578.16119 L 207.30995,581.12995 L 206.37245,584.41122 L 204.34118,587.14562" id="AK_Canada" style="fill:none;stroke:#000000;stroke-width:2.5;stroke-dasharray:none;stroke-opacity:1" /> - </ns0:g> - <ns0:path d="M 127.46583,540.97352 L 129.80959,539.56726 L 128.87209,537.8485 L 127.15333,538.78601 L 127.46583,540.97352 z M 86.528141,560.19236 L 87.621901,565.81738 L 90.434411,566.59864 L 95.278181,563.78612 L 99.496951,561.28611 L 97.934451,558.94235 L 98.403201,556.59859 L 96.371941,557.8486 L 93.559431,557.06734 L 95.121931,555.97359 L 96.996941,556.75484 L 100.74696,555.03608 L 101.21571,553.62983 L 98.871951,552.84857 L 99.653201,550.97356 L 96.996941,552.84857 L 92.465671,556.28609 L 87.778151,559.0986 L 86.528141,560.19236 z M 78.090601,572.22366 L 79.496861,573.94242 L 80.434371,572.84867 L 79.653111,570.97366 L 78.090601,572.22366 z M 55.278,574.09867 L 56.371751,571.91116 L 58.403011,572.22366 L 57.621761,574.09867 L 55.278,574.09867 z M 52.465487,571.12991 L 54.027994,573.00492 L 56.059251,571.44241 L 54.652997,570.1924 L 52.465487,571.12991 z M 5.1215179,575.50493 L 8.4027829,573.31742 L 11.684048,572.37991 L 14.18406,572.69241 L 14.652812,574.25492 L 16.527821,574.72367 L 18.402829,572.84867 L 18.090328,571.28616 L 20.74659,570.66116 L 23.559103,573.16117 L 22.465348,574.87992 L 18.246579,575.97368 L 15.590316,575.50493 L 11.99655,574.41117 L 7.7777799,575.81743 L 6.2152729,576.12993 L 5.1215179,575.50493 z M 18.402829,504.8796 L 19.496585,507.37961 L 20.59034,508.94212 L 19.496585,509.72337 L 17.465325,506.75461 L 17.465325,504.8796 L 18.402829,504.8796 z M 38.402922,518.47341 L 41.996689,519.25467 L 45.590455,520.19217 L 46.371709,521.12968 L 44.809202,524.72344 L 41.840438,524.56719 L 38.559173,521.12968 L 38.402922,518.47341 z M 40.902934,486.12951 L 42.934193,491.28579 L 42.777942,492.22329 L 39.965429,491.91079 L 38.246671,488.00452 L 36.527913,486.59827 L 34.184152,486.59827 L 34.027902,484.09825 L 35.74666,481.75449 L 36.840415,484.09825 L 38.246671,485.50451 L 40.902934,486.12951 z M 204.65369,586.59873 L 203.09118,585.81748 L 201.68493,582.84871 L 199.02866,581.44246 L 197.30991,580.3487 L 196.52865,581.12995 L 197.93491,583.78622 L 198.09116,587.37998 L 196.9974,587.84873 L 195.1224,585.97373 L 193.09114,584.72372 L 193.55989,586.28623 L 194.80989,588.00499 L 194.02864,588.78624 C 194.02864,588.78624 193.24739,588.47374 192.77864,587.84873 C 192.30988,587.22373 190.74738,584.56747 190.74738,584.56747 L 189.80987,582.37996 C 189.80987,582.37996 189.49737,583.62997 188.87237,583.31746 C 188.24736,583.00496 187.62236,581.91121 187.62236,581.91121 L 189.34112,580.0362 L 187.93486,578.62994 L 187.93486,573.78617 L 187.15361,573.78617 L 186.37236,577.06743 L 185.2786,577.53619 L 184.3411,573.94242 L 183.71609,570.34865 L 182.93484,569.8799 L 183.24734,575.34868 L 183.24734,576.44243 L 181.84108,575.19243 L 178.40357,569.41115 L 176.37231,568.9424 L 175.74731,565.34863 L 174.1848,562.53612 L 172.62229,561.44236 L 172.62229,559.25485 L 174.65355,558.00485 L 174.1848,557.69235 L 171.68479,558.31735 L 168.40352,555.97359 L 165.90351,553.16107 L 161.21599,550.66106 L 157.30972,548.16105 L 158.55973,545.03604 L 158.55973,543.47353 L 156.84097,545.03604 L 154.02846,546.12979 L 150.43469,545.03604 L 144.96591,542.69228 L 139.65339,542.69228 L 139.02839,543.16103 L 132.77836,539.41101 L 130.7471,539.09851 L 128.09084,533.47348 L 124.65332,533.78598 L 121.2158,535.19224 L 121.68456,539.56726 L 122.77831,536.75475 L 123.71582,537.06725 L 122.30956,541.28602 L 125.43457,538.62976 L 126.05958,540.19226 L 122.30956,544.41103 L 121.05955,544.09853 L 120.5908,542.22352 L 119.3408,541.44227 L 118.09079,542.53603 L 115.43453,540.81727 L 112.46576,542.84853 L 110.74701,544.87979 L 107.46574,546.91105 L 102.93447,546.75479 L 102.46572,544.72354 L 106.05948,544.09853 L 106.05948,542.84853 L 103.87197,542.22352 L 104.80948,539.87976 L 106.99699,536.12975 L 106.99699,534.41099 L 107.15324,533.62973 L 111.37201,531.44222 L 112.30951,532.69223 L 114.96578,532.69223 L 113.71577,530.19222 L 110.122,529.87972 L 105.27823,532.53598 L 102.93447,535.81724 L 101.21571,538.31726 L 100.12196,540.50477 L 96.059441,541.91102 L 93.090671,544.41103 L 92.778171,545.97354 L 94.965681,546.91105 L 95.746941,548.9423 L 93.090671,552.06732 L 86.840651,556.12984 L 79.340611,560.19236 L 77.309351,561.28611 L 72.153081,562.37987 L 66.996801,564.56738 L 68.715561,565.81738 L 67.309301,567.22364 L 66.840551,568.31739 L 64.184291,567.37989 L 61.059281,567.53614 L 60.278021,569.72365 L 59.340521,569.72365 L 59.653021,567.37989 L 56.215501,568.6299 L 53.402991,569.5674 L 50.121726,568.31739 L 47.309213,570.1924 L 44.184199,570.1924 L 42.152939,571.44241 L 40.590432,572.22366 L 38.559173,571.91116 L 36.059161,570.81741 L 33.871651,571.44241 L 32.934147,572.37991 L 31.371639,571.28616 L 31.371639,569.41115 L 34.340403,568.16114 L 40.434181,568.78615 L 44.652951,567.22364 L 46.68421,565.19238 L 49.496723,564.56738 L 51.215481,563.78612 L 53.871744,563.94237 L 55.434251,565.19238 L 56.371751,564.87988 L 58.559261,562.22362 L 61.528031,561.28611 L 64.809291,560.66111 L 66.059301,560.34861 L 66.684301,560.81736 L 67.465561,560.81736 L 68.715561,557.22359 L 72.621831,555.81734 L 74.496841,552.22357 L 76.684351,547.84855 L 78.246861,546.44229 L 78.559361,543.94228 L 76.996851,545.19229 L 73.715581,545.81729 L 73.090581,543.47353 L 71.840581,543.16103 L 70.903071,544.09853 L 70.746821,546.91105 L 69.340561,546.75479 L 67.934311,541.12977 L 66.684301,542.37977 L 65.590551,541.91102 L 65.278051,540.03601 L 61.371781,540.19226 L 59.340521,541.28602 L 56.840511,540.97352 L 58.246761,539.56726 L 58.715511,537.06725 L 58.090511,535.19224 L 59.496771,534.25474 L 60.746771,534.09849 L 60.121771,532.37973 L 60.121771,528.16096 L 59.184271,527.22345 L 58.403011,528.62971 L 52.465487,528.62971 L 51.059231,527.3797 L 50.434228,523.62969 L 48.402968,520.19217 L 48.402968,519.25467 L 50.434228,518.47341 L 50.590478,516.44215 L 51.684233,515.3484 L 50.90298,514.87965 L 49.652974,515.3484 L 48.559219,512.69214 L 49.496723,507.84836 L 53.871744,504.72335 L 56.371751,503.16084 L 58.246761,499.56708 L 60.903031,498.31707 L 63.403041,499.41083 L 63.715541,501.75459 L 66.059301,501.44208 L 69.184311,499.09832 L 70.746821,499.72333 L 71.684321,500.34833 L 73.246831,500.34833 L 75.434341,499.09832 L 76.215601,494.87955 C 76.215601,494.87955 76.528101,492.06704 77.153101,491.59829 C 77.778101,491.12954 78.090601,490.66079 78.090601,490.66079 L 76.996851,488.78578 L 74.496841,489.56703 L 71.371821,490.34828 L 69.496811,489.87953 L 66.059301,488.16077 L 61.215531,488.00452 L 57.778011,484.41076 L 58.246761,480.66074 L 58.871771,478.31698 L 56.840511,476.59822 L 54.965499,473.00445 L 55.434251,472.2232 L 61.996781,471.75445 L 64.028041,471.75445 L 64.965541,472.69195 L 65.590551,472.69195 L 65.434301,471.12944 L 69.184311,470.50444 L 71.684321,470.81694 L 73.090581,471.9107 L 71.684321,473.94196 L 71.215571,475.34821 L 73.871841,476.91072 L 78.715611,478.62948 L 80.434371,477.69198 L 78.246861,473.47321 L 77.309351,470.34819 L 78.246861,469.56694 L 74.965591,467.69193 L 74.496841,466.59817 L 74.965591,465.03567 L 74.184341,461.28565 L 71.371821,456.75438 L 69.028061,452.69186 L 71.840581,450.81685 L 74.965591,450.81685 L 76.684351,451.44185 L 80.746871,451.2856 L 84.340631,447.84809 L 85.434391,444.87932 L 89.028161,442.53556 L 90.590661,443.47307 L 93.246921,442.84806 L 96.840691,440.8168 L 97.934451,440.66055 L 98.871951,441.44181 L 103.24697,441.28556 L 105.90323,438.31679 L 106.99699,438.31679 L 110.4345,440.66055 L 112.30951,442.69181 L 111.84076,443.78557 L 112.46576,444.87932 L 114.02827,443.31682 L 117.77829,443.62932 L 118.09079,447.22308 L 119.9658,448.62934 L 126.84083,449.25434 L 132.93461,453.31686 L 134.34086,452.37936 L 139.34089,454.87937 L 141.37215,454.25437 L 143.24716,453.47311 L 147.93468,455.34812 L 152.15345,458.16063" id="AK_Pacific" style="fill:none;fill-opacity:0.26666697;stroke:#80b0f0;stroke-width:1pt" /> - <ns0:g id="Frames" transform="translate(-18.307669,-131.99439)"> - <ns0:path d="M 229.21212,631.12334 L 229.68087,688.43625 L 264.68114,723.74902 M 18.429285,562.99783 L 161.86786,563.31033 L 229.52462,631.59209 L 314.68151,631.74834 L 370.43191,685.18624 L 370.11941,723.43652" id="Inset_border" style="fill:none;fill-opacity:0.75;stroke:#000000;stroke-width:1.875;stroke-dasharray:none" ns1:nodetypes="ccccccccc" /> - <ns0:rect height="590.28674" id="Outer_border" style="fill:none;stroke:#000000;stroke-width:2.5;stroke-dasharray:none" width="955.48639" x="19.444839" y="133.89751" /> - </ns0:g> - <ns0:path d="M 822.91849,258.28198 A 4.1274123,3.62712 0 1 1 814.66366,258.28198 A 4.1274123,3.62712 0 1 1 822.91849,258.28198 z" id="DC" style="opacity:1;fill:#a02c2c;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" transform="matrix(0.9707988,0,0,1.0018987,24.345102,-0.4278704)" ns1:cx="818.79108" ns1:cy="258.28198" ns1:rx="4.1274123" ns1:ry="3.62712" ns1:type="arc" ns2:label="#DC" /> -</ns0:svg>
\ No newline at end of file diff --git a/tests/phpunit/data/media/Wikimedia-logo.svg b/tests/phpunit/data/media/Wikimedia-logo.svg deleted file mode 100644 index 1e17acbe..00000000 --- a/tests/phpunit/data/media/Wikimedia-logo.svg +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Wikimedia logo" viewBox="-599 -599 1198 1198" width="1024" height="1024"> -<defs> - <clipPath id="mask"> - <path d="M 47.5,-87.5 v 425 h -95 v -425 l -552,-552 v 1250 h 1199 v -1250 z"/> - </clipPath> -</defs> -<g clip-path="url(#mask)"> - <circle id="green parts" fill="#396" r="336.5"/> - <circle id="blue arc" fill="none" stroke="#069" r="480.25" stroke-width="135.5"/> -</g> -<circle fill="#900" cy="-379.5" r="184.5" id="red circle"/> -</svg>
\ No newline at end of file diff --git a/tests/phpunit/data/media/Xmp-exif-multilingual_test.jpg b/tests/phpunit/data/media/Xmp-exif-multilingual_test.jpg Binary files differdeleted file mode 100644 index f7b23025..00000000 --- a/tests/phpunit/data/media/Xmp-exif-multilingual_test.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/animated-xmp.gif b/tests/phpunit/data/media/animated-xmp.gif Binary files differdeleted file mode 100644 index fcba079d..00000000 --- a/tests/phpunit/data/media/animated-xmp.gif +++ /dev/null diff --git a/tests/phpunit/data/media/animated.gif b/tests/phpunit/data/media/animated.gif Binary files differdeleted file mode 100644 index a8f248b3..00000000 --- a/tests/phpunit/data/media/animated.gif +++ /dev/null diff --git a/tests/phpunit/data/media/broken_exif_date.jpg b/tests/phpunit/data/media/broken_exif_date.jpg Binary files differdeleted file mode 100644 index 82f62f57..00000000 --- a/tests/phpunit/data/media/broken_exif_date.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/exif-gps.jpg b/tests/phpunit/data/media/exif-gps.jpg Binary files differdeleted file mode 100644 index 40137340..00000000 --- a/tests/phpunit/data/media/exif-gps.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/exif-user-comment.jpg b/tests/phpunit/data/media/exif-user-comment.jpg Binary files differdeleted file mode 100644 index 9f23966a..00000000 --- a/tests/phpunit/data/media/exif-user-comment.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/greyscale-na-png.png b/tests/phpunit/data/media/greyscale-na-png.png Binary files differdeleted file mode 100644 index 4a4b7452..00000000 --- a/tests/phpunit/data/media/greyscale-na-png.png +++ /dev/null diff --git a/tests/phpunit/data/media/greyscale-png.png b/tests/phpunit/data/media/greyscale-png.png Binary files differdeleted file mode 100644 index 340a67b4..00000000 --- a/tests/phpunit/data/media/greyscale-png.png +++ /dev/null diff --git a/tests/phpunit/data/media/iptc-invalid-psir.jpg b/tests/phpunit/data/media/iptc-invalid-psir.jpg Binary files differdeleted file mode 100644 index 01b9acf3..00000000 --- a/tests/phpunit/data/media/iptc-invalid-psir.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/iptc-timetest-invalid.jpg b/tests/phpunit/data/media/iptc-timetest-invalid.jpg Binary files differdeleted file mode 100644 index b03e192a..00000000 --- a/tests/phpunit/data/media/iptc-timetest-invalid.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/iptc-timetest.jpg b/tests/phpunit/data/media/iptc-timetest.jpg Binary files differdeleted file mode 100644 index db9932ba..00000000 --- a/tests/phpunit/data/media/iptc-timetest.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/jpeg-comment-binary.jpg b/tests/phpunit/data/media/jpeg-comment-binary.jpg Binary files differdeleted file mode 100644 index b467fe43..00000000 --- a/tests/phpunit/data/media/jpeg-comment-binary.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/jpeg-comment-iso8859-1.jpg b/tests/phpunit/data/media/jpeg-comment-iso8859-1.jpg Binary files differdeleted file mode 100644 index d9ffbac1..00000000 --- a/tests/phpunit/data/media/jpeg-comment-iso8859-1.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/jpeg-comment-multiple.jpg b/tests/phpunit/data/media/jpeg-comment-multiple.jpg Binary files differdeleted file mode 100644 index 363c7385..00000000 --- a/tests/phpunit/data/media/jpeg-comment-multiple.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/jpeg-comment-utf.jpg b/tests/phpunit/data/media/jpeg-comment-utf.jpg Binary files differdeleted file mode 100644 index d6d35b4b..00000000 --- a/tests/phpunit/data/media/jpeg-comment-utf.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/jpeg-iptc-bad-hash.jpg b/tests/phpunit/data/media/jpeg-iptc-bad-hash.jpg Binary files differdeleted file mode 100644 index 6464c5b8..00000000 --- a/tests/phpunit/data/media/jpeg-iptc-bad-hash.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/jpeg-iptc-good-hash.jpg b/tests/phpunit/data/media/jpeg-iptc-good-hash.jpg Binary files differdeleted file mode 100644 index ef970854..00000000 --- a/tests/phpunit/data/media/jpeg-iptc-good-hash.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/jpeg-padding-even.jpg b/tests/phpunit/data/media/jpeg-padding-even.jpg Binary files differdeleted file mode 100644 index c83c66bd..00000000 --- a/tests/phpunit/data/media/jpeg-padding-even.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/jpeg-padding-odd.jpg b/tests/phpunit/data/media/jpeg-padding-odd.jpg Binary files differdeleted file mode 100644 index 25b93308..00000000 --- a/tests/phpunit/data/media/jpeg-padding-odd.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/jpeg-xmp-alt.jpg b/tests/phpunit/data/media/jpeg-xmp-alt.jpg Binary files differdeleted file mode 100644 index 0e2c3f63..00000000 --- a/tests/phpunit/data/media/jpeg-xmp-alt.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/jpeg-xmp-psir.jpg b/tests/phpunit/data/media/jpeg-xmp-psir.jpg Binary files differdeleted file mode 100644 index 4d19fcbe..00000000 --- a/tests/phpunit/data/media/jpeg-xmp-psir.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/jpeg-xmp-psir.xmp b/tests/phpunit/data/media/jpeg-xmp-psir.xmp deleted file mode 100644 index fee6ee18..00000000 --- a/tests/phpunit/data/media/jpeg-xmp-psir.xmp +++ /dev/null @@ -1,35 +0,0 @@ -<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?> -<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 7.30'> -<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'> - - <rdf:Description rdf:about='' - xmlns:dc='http://purl.org/dc/elements/1.1/'> - <dc:identifier>jpeg-xmp-psir.jpg</dc:identifier> - </rdf:Description> -</rdf:RDF> -</x:xmpmeta> - - - - - - - - - - - - - - - - - - - - - - - - -<?xpacket end='w'?>
\ No newline at end of file diff --git a/tests/phpunit/data/media/landscape-plain.jpg b/tests/phpunit/data/media/landscape-plain.jpg Binary files differdeleted file mode 100644 index cf296555..00000000 --- a/tests/phpunit/data/media/landscape-plain.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/nonanimated.gif b/tests/phpunit/data/media/nonanimated.gif Binary files differdeleted file mode 100644 index 9e52a7f0..00000000 --- a/tests/phpunit/data/media/nonanimated.gif +++ /dev/null diff --git a/tests/phpunit/data/media/portrait-rotated.jpg b/tests/phpunit/data/media/portrait-rotated.jpg Binary files differdeleted file mode 100644 index 445feaed..00000000 --- a/tests/phpunit/data/media/portrait-rotated.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/rgb-na-png.png b/tests/phpunit/data/media/rgb-na-png.png Binary files differdeleted file mode 100644 index 2f2a5ca0..00000000 --- a/tests/phpunit/data/media/rgb-na-png.png +++ /dev/null diff --git a/tests/phpunit/data/media/rgb-png.png b/tests/phpunit/data/media/rgb-png.png Binary files differdeleted file mode 100644 index 6f40cc92..00000000 --- a/tests/phpunit/data/media/rgb-png.png +++ /dev/null diff --git a/tests/phpunit/data/media/test.jpg b/tests/phpunit/data/media/test.jpg Binary files differdeleted file mode 100644 index cb084253..00000000 --- a/tests/phpunit/data/media/test.jpg +++ /dev/null diff --git a/tests/phpunit/data/media/test.tiff b/tests/phpunit/data/media/test.tiff Binary files differdeleted file mode 100644 index 6a36f760..00000000 --- a/tests/phpunit/data/media/test.tiff +++ /dev/null diff --git a/tests/phpunit/data/media/xmp.png b/tests/phpunit/data/media/xmp.png Binary files differdeleted file mode 100644 index 6b9f7a87..00000000 --- a/tests/phpunit/data/media/xmp.png +++ /dev/null diff --git a/tests/phpunit/data/xmp/1.result.php b/tests/phpunit/data/xmp/1.result.php deleted file mode 100644 index beead1bd..00000000 --- a/tests/phpunit/data/xmp/1.result.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php - -$result = array( 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => '9' - ) -); diff --git a/tests/phpunit/data/xmp/1.xmp b/tests/phpunit/data/xmp/1.xmp deleted file mode 100644 index 66e15427..00000000 --- a/tests/phpunit/data/xmp/1.xmp +++ /dev/null @@ -1,11 +0,0 @@ -<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core - 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10 "> -<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> -<rdf:Description - rdf:about="" - xmlns:exif="http://ns.adobe.com/exif/1.0/" - exif:DigitalZoomRatio="0/10"> -<exif:Flash rdf:parseType='Resource'> -<exif:Fired>True</exif:Fired> <exif:Return>0</exif:Return> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></exif:Flash> </rdf:Description> </rdf:RDF> </x:xmpmeta> - -<?xpacket end="w"?> diff --git a/tests/phpunit/data/xmp/2.result.php b/tests/phpunit/data/xmp/2.result.php deleted file mode 100644 index beead1bd..00000000 --- a/tests/phpunit/data/xmp/2.result.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php - -$result = array( 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => '9' - ) -); diff --git a/tests/phpunit/data/xmp/2.xmp b/tests/phpunit/data/xmp/2.xmp deleted file mode 100644 index 0fa6a894..00000000 --- a/tests/phpunit/data/xmp/2.xmp +++ /dev/null @@ -1,12 +0,0 @@ -<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core - 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10 "> -<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> -<rdf:Description - rdf:about="" - xmlns:exif="http://ns.adobe.com/exif/1.0/" - exif:DigitalZoomRatio="0/10"> -<exif:Flash> -<rdf:Description exif:Return="0"> -<exif:Fired>True</exif:Fired> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></rdf:Description></exif:Flash> </rdf:Description> </rdf:RDF> </x:xmpmeta> - -<?xpacket end="w"?> diff --git a/tests/phpunit/data/xmp/3-invalid.result.php b/tests/phpunit/data/xmp/3-invalid.result.php deleted file mode 100644 index 5741b2c9..00000000 --- a/tests/phpunit/data/xmp/3-invalid.result.php +++ /dev/null @@ -1,7 +0,0 @@ -<?php - -$result = array( 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - ) -); diff --git a/tests/phpunit/data/xmp/3-invalid.xmp b/tests/phpunit/data/xmp/3-invalid.xmp deleted file mode 100644 index 2425e254..00000000 --- a/tests/phpunit/data/xmp/3-invalid.xmp +++ /dev/null @@ -1,31 +0,0 @@ -<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core - 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10 "> -<!-- -This file has an invalid flash compoenent (one of the values are a qualifier) ---> -<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> -<rdf:Description - rdf:about="" - xmlns:exif="http://ns.adobe.com/exif/1.0/" -> -<exif:DigitalZoomRatio> - -<rdf:Description> -<rdf:value> -0/10 -</rdf:value> -<exif:foobarbaz>fred</exif:foobarbaz> - -</rdf:Description> - -</exif:DigitalZoomRatio> - -<exif:Flash> -<rdf:Description exif:Return="0"> -<exif:Mode><rdf:Description> -<rdf:value>1</rdf:value> -<exif:Fired>False</exif:Fired> <!-- qualifier. should be ignored--> -</rdf:Description> -</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></rdf:Description></exif:Flash> </rdf:Description> </rdf:RDF> </x:xmpmeta> - -<?xpacket end="w"?> diff --git a/tests/phpunit/data/xmp/3.result.php b/tests/phpunit/data/xmp/3.result.php deleted file mode 100644 index beead1bd..00000000 --- a/tests/phpunit/data/xmp/3.result.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php - -$result = array( 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => '9' - ) -); diff --git a/tests/phpunit/data/xmp/3.xmp b/tests/phpunit/data/xmp/3.xmp deleted file mode 100644 index 2cf19883..00000000 --- a/tests/phpunit/data/xmp/3.xmp +++ /dev/null @@ -1,29 +0,0 @@ -<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core - 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10 "> -<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> -<rdf:Description - rdf:about="" - xmlns:exif="http://ns.adobe.com/exif/1.0/" -> -<exif:DigitalZoomRatio> - -<rdf:Description> -<rdf:value> -0/10 -</rdf:value> -<exif:foobarbaz>fred</exif:foobarbaz> - -</rdf:Description> - -</exif:DigitalZoomRatio> - -<exif:Flash> -<rdf:Description exif:Return="0"> -<exif:Fired>True</exif:Fired> -<exif:Mode><rdf:Description> -<rdf:value>1</rdf:value> -<exif:Fired>False</exif:Fired> <!-- qualifier. should be ignored--> -</rdf:Description> -</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></rdf:Description></exif:Flash> </rdf:Description> </rdf:RDF> </x:xmpmeta> - -<?xpacket end="w"?> diff --git a/tests/phpunit/data/xmp/4.result.php b/tests/phpunit/data/xmp/4.result.php deleted file mode 100644 index 5741b2c9..00000000 --- a/tests/phpunit/data/xmp/4.result.php +++ /dev/null @@ -1,7 +0,0 @@ -<?php - -$result = array( 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - ) -); diff --git a/tests/phpunit/data/xmp/4.xmp b/tests/phpunit/data/xmp/4.xmp deleted file mode 100644 index 29eb614b..00000000 --- a/tests/phpunit/data/xmp/4.xmp +++ /dev/null @@ -1,22 +0,0 @@ -<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core - 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10 "> -<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> -<!-- Valid output is just the DigitalZoomRatio -as the flash is a qualifier ---> -<rdf:Description - rdf:about="" - xmlns:exif="http://ns.adobe.com/exif/1.0/"> - <exif:DigitalZoomRatio> -<rdf:Description> -<rdf:value> -0/10 -</rdf:value> -<exif:Flash rdf:parseType='Resource'> -<exif:Fired>True</exif:Fired> <exif:Return>0</exif:Return> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></exif:Flash> -</rdf:Description> -</exif:DigitalZoomRatio> -</rdf:Description> </rdf:RDF> </x:xmpmeta> - - -<?xpacket end="w"?> diff --git a/tests/phpunit/data/xmp/5.result.php b/tests/phpunit/data/xmp/5.result.php deleted file mode 100644 index 5741b2c9..00000000 --- a/tests/phpunit/data/xmp/5.result.php +++ /dev/null @@ -1,7 +0,0 @@ -<?php - -$result = array( 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - ) -); diff --git a/tests/phpunit/data/xmp/5.xmp b/tests/phpunit/data/xmp/5.xmp deleted file mode 100644 index 3cc61d68..00000000 --- a/tests/phpunit/data/xmp/5.xmp +++ /dev/null @@ -1,16 +0,0 @@ -<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core - 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10 "> -<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> -<rdf:Description - rdf:about="" - xmlns:exif="http://ns.adobe.com/exif/1.0/"> - <exif:DigitalZoomRatio> -<rdf:Description rdf:value="0/10"> -<exif:Flash rdf:parseType='Resource'> -<exif:Fired>True</exif:Fired> <exif:Return>0</exif:Return> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></exif:Flash> -</rdf:Description> -</exif:DigitalZoomRatio> -</rdf:Description> </rdf:RDF> </x:xmpmeta> - - -<?xpacket end="w"?> diff --git a/tests/phpunit/data/xmp/6.result.php b/tests/phpunit/data/xmp/6.result.php deleted file mode 100644 index beead1bd..00000000 --- a/tests/phpunit/data/xmp/6.result.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php - -$result = array( 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => '9' - ) -); diff --git a/tests/phpunit/data/xmp/6.xmp b/tests/phpunit/data/xmp/6.xmp deleted file mode 100644 index f435ab23..00000000 --- a/tests/phpunit/data/xmp/6.xmp +++ /dev/null @@ -1,18 +0,0 @@ -<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core - 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10 "> -<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> -<rdf:Description - rdf:about="" - xmlns:exif="http://ns.adobe.com/exif/1.0/"> -<exif:DigitalZoomRatio> -0/10 -</exif:DigitalZoomRatio> -</rdf:Description> -<rdf:Description - rdf:about="" - xmlns:exif="http://ns.adobe.com/exif/1.0/"> - -<exif:Flash rdf:parseType='Resource'> -<exif:Fired>True</exif:Fired> <exif:Return>0</exif:Return> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></exif:Flash> </rdf:Description> </rdf:RDF> </x:xmpmeta> - -<?xpacket end="w"?> diff --git a/tests/phpunit/data/xmp/7.result.php b/tests/phpunit/data/xmp/7.result.php deleted file mode 100644 index 115cdc92..00000000 --- a/tests/phpunit/data/xmp/7.result.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -$result = array( - 'xmp-exif' => - array( - 'CameraOwnerName' => 'Me!', - ), - 'xmp-general' => - array( - 'LicenseUrl' => 'http://creativecommons.com/cc-by-2.9', - 'ImageDescription' => - array( - 'x-default' => 'Test image for the cc: xmp: xmpRights: namespaces in xmp', - '_type' => 'lang', - ), - 'ObjectName' => - 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( - 0 => 'http://example.com/identifierurl', - 1 => 'urn:sha1:342524abcdef', - '_type' => 'ul', - ), - 'Label' => 'Test image', - 'DateTimeMetadata' => '2011:05:12', - 'DateTime' => '2007:03:04 06:34:10', - 'Nickname' => 'My little xmp test image', - 'Rating' => '5', - 'RightsCertificate' => 'http://example.com/rights-certificate/', - 'Copyrighted' => 'True', - 'CopyrightOwner' => - array( - 0 => 'Bawolff is copyright owner', - '_type' => 'ul', - ), - 'UsageTerms' => - array( - 'x-default' => 'do whatever you want', - 'en-gb' => 'Do whatever you want in british english', - '_type' => 'lang', - ), - 'WebStatement' => 'http://example.com/web_statement', - ), - 'xmp-deprecated' => - array( - 'Identifier' => 'http://example.com/identifierurl/wrong', - ), -); diff --git a/tests/phpunit/data/xmp/7.xmp b/tests/phpunit/data/xmp/7.xmp deleted file mode 100644 index e18e13d9..00000000 --- a/tests/phpunit/data/xmp/7.xmp +++ /dev/null @@ -1,67 +0,0 @@ -<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?> -<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 7.30'> -<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'> - - <rdf:Description rdf:about='' - xmlns:aux='http://ns.adobe.com/exif/1.0/aux/'> - <aux:OwnerName>Me!</aux:OwnerName> - </rdf:Description> - - <rdf:Description rdf:about='' - xmlns:cc='http://creativecommons.org/ns#'> - <cc:license>http://creativecommons.com/cc-by-2.9</cc:license> - </rdf:Description> - - <rdf:Description rdf:about='' - xmlns:dc='http://purl.org/dc/elements/1.1/'> - <dc:description> - <rdf:Alt> - <rdf:li xml:lang='x-default'>Test image for the cc: xmp: xmpRights: namespaces in xmp</rdf:li> - </rdf:Alt> - </dc:description> - <dc:identifier>http://example.com/identifierurl/wrong</dc:identifier> - <dc:title> - <rdf:Alt> - <rdf:li xml:lang='x-default'>xmp core/xmp rights/cc ns test</rdf:li> - </rdf:Alt> - </dc:title> - </rdf:Description> - - <rdf:Description rdf:about='' - xmlns:xmp='http://ns.adobe.com/xap/1.0/'> - <xmp:CreateDate>2005-04-03</xmp:CreateDate> - <xmp:CreatorTool>The one true editor: Vi (ok i used gimp)</xmp:CreatorTool> - <xmp:Identifier> - <rdf:Bag> - <rdf:li>http://example.com/identifierurl -</rdf:li> - <rdf:li>urn:sha1:342524abcdef</rdf:li> - </rdf:Bag> - </xmp:Identifier> - <xmp:Label>Test image</xmp:Label> - <xmp:MetadataDate>2011-05-12</xmp:MetadataDate> - <xmp:ModifyDate>2007-03-04T12:34:10-06:00</xmp:ModifyDate> - <xmp:Nickname>My little xmp test image</xmp:Nickname> - <xmp:Rating>7</xmp:Rating> - </rdf:Description> - - <rdf:Description rdf:about='' - xmlns:xmpRights='http://ns.adobe.com/xap/1.0/rights/'> - <xmpRights:Certificate>http://example.com/rights-certificate/</xmpRights:Certificate> - <xmpRights:Marked>True</xmpRights:Marked> - <xmpRights:Owner> - <rdf:Bag> - <rdf:li>Bawolff is copyright owner</rdf:li> - </rdf:Bag> - </xmpRights:Owner> - <xmpRights:UsageTerms> - <rdf:Alt> - <rdf:li xml:lang='x-default'>do whatever you want</rdf:li> - <rdf:li xml:lang='en-GB'>Do whatever you want in british english</rdf:li> - </rdf:Alt> - </xmpRights:UsageTerms> - <xmpRights:WebStatement>http://example.com/web_statement</xmpRights:WebStatement> - </rdf:Description> -</rdf:RDF> -</x:xmpmeta> -<?xpacket end='r'?> diff --git a/tests/phpunit/data/xmp/README b/tests/phpunit/data/xmp/README deleted file mode 100644 index bd949176..00000000 --- a/tests/phpunit/data/xmp/README +++ /dev/null @@ -1,3 +0,0 @@ -This directory contains a bunch of XMP files -as well as a bunch of php files containing what the -parsed version of the XMP looks like. diff --git a/tests/phpunit/data/xmp/bag-for-seq.result.php b/tests/phpunit/data/xmp/bag-for-seq.result.php deleted file mode 100644 index b5244f88..00000000 --- a/tests/phpunit/data/xmp/bag-for-seq.result.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php - -$result = array( - 'xmp-general' => array( - 'Artist' => array( - '_type' => 'ul', - 0 => 'The author', - ) - ) -); diff --git a/tests/phpunit/data/xmp/bag-for-seq.xmp b/tests/phpunit/data/xmp/bag-for-seq.xmp deleted file mode 100644 index c6ed5b7c..00000000 --- a/tests/phpunit/data/xmp/bag-for-seq.xmp +++ /dev/null @@ -1 +0,0 @@ -<?xpacket begin=""?> <x:xmpmeta xmlns:x="adobe:ns:meta/"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/"> <dc:creator> <rdf:Bag> <rdf:li>The author</rdf:li> </rdf:Bag> </dc:creator> </rdf:Description> </rdf:RDF> </x:xmpmeta> diff --git a/tests/phpunit/data/xmp/flash.result.php b/tests/phpunit/data/xmp/flash.result.php deleted file mode 100644 index 018c0ac1..00000000 --- a/tests/phpunit/data/xmp/flash.result.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php - -$result = array( 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => '127' - ) -); diff --git a/tests/phpunit/data/xmp/flash.xmp b/tests/phpunit/data/xmp/flash.xmp deleted file mode 100644 index b1373cc2..00000000 --- a/tests/phpunit/data/xmp/flash.xmp +++ /dev/null @@ -1,11 +0,0 @@ -<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core - 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10 "> -<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> -<rdf:Description - rdf:about="" - xmlns:exif="http://ns.adobe.com/exif/1.0/" - exif:DigitalZoomRatio="0/10"> -<exif:Flash rdf:parseType='Resource'> -<exif:Fired>True</exif:Fired> <exif:Return>3</exif:Return> <exif:Mode>3</exif:Mode> <exif:Function>True</exif:Function> <exif:RedEyeMode>True</exif:RedEyeMode></exif:Flash> </rdf:Description> </rdf:RDF> </x:xmpmeta> - -<?xpacket end="w"?> diff --git a/tests/phpunit/data/xmp/gps.result.php b/tests/phpunit/data/xmp/gps.result.php deleted file mode 100644 index 8ea9c68c..00000000 --- a/tests/phpunit/data/xmp/gps.result.php +++ /dev/null @@ -1,11 +0,0 @@ -<?php - -$result = array( 'xmp-exif' => - array( - 'GPSAltitude' => -3.14159265301, - 'GPSDOP' => '5/1', - 'GPSLatitude' => 88.51805555, - 'GPSLongitude' => -21.12356945, - 'GPSVersionID' => '2.2.0.0' - ) -); diff --git a/tests/phpunit/data/xmp/gps.xmp b/tests/phpunit/data/xmp/gps.xmp deleted file mode 100644 index e52d2c8a..00000000 --- a/tests/phpunit/data/xmp/gps.xmp +++ /dev/null @@ -1,17 +0,0 @@ -<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?> -<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 7.30'> -<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'> - - <rdf:Description rdf:about='' - xmlns:exif='http://ns.adobe.com/exif/1.0/'> - <exif:GPSAltitude>103993/33102</exif:GPSAltitude> - <exif:GPSAltitudeRef>1</exif:GPSAltitudeRef> - <exif:GPSDOP>5/1</exif:GPSDOP> - <exif:GPSLatitude>88,31.083333N</exif:GPSLatitude> - <exif:GPSLongitude>21,7.414167W</exif:GPSLongitude> - <exif:GPSVersionID>2.2.0.0</exif:GPSVersionID> - </rdf:Description> - -</rdf:RDF> -</x:xmpmeta> -<?xpacket end='w'?> diff --git a/tests/phpunit/data/xmp/invalid-child-not-struct.result.php b/tests/phpunit/data/xmp/invalid-child-not-struct.result.php deleted file mode 100644 index 5741b2c9..00000000 --- a/tests/phpunit/data/xmp/invalid-child-not-struct.result.php +++ /dev/null @@ -1,7 +0,0 @@ -<?php - -$result = array( 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - ) -); diff --git a/tests/phpunit/data/xmp/invalid-child-not-struct.xmp b/tests/phpunit/data/xmp/invalid-child-not-struct.xmp deleted file mode 100644 index 6aa0c10b..00000000 --- a/tests/phpunit/data/xmp/invalid-child-not-struct.xmp +++ /dev/null @@ -1,12 +0,0 @@ -<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core - 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10 "> -<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> -<rdf:Description - rdf:about="" - xmlns:exif="http://ns.adobe.com/exif/1.0/" - exif:DigitalZoomRatio="0/10"> -<exif:Fired>True</exif:Fired> <exif:Return>0</exif:Return> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode> - - </rdf:Description> </rdf:RDF> </x:xmpmeta> - -<?xpacket end="w"?> diff --git a/tests/phpunit/data/xmp/no-namespace.result.php b/tests/phpunit/data/xmp/no-namespace.result.php deleted file mode 100644 index 3ff69201..00000000 --- a/tests/phpunit/data/xmp/no-namespace.result.php +++ /dev/null @@ -1,7 +0,0 @@ -<?php - -$result = array( 'xmp-exif' => - array( - 'FNumber' => '28/10', - ) -); diff --git a/tests/phpunit/data/xmp/no-namespace.xmp b/tests/phpunit/data/xmp/no-namespace.xmp deleted file mode 100644 index 7d6cdb2f..00000000 --- a/tests/phpunit/data/xmp/no-namespace.xmp +++ /dev/null @@ -1,11 +0,0 @@ -<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> -<!-- Testing it handles random non-namespaced properties in files ok. - Some older photoshop's did not include the rdf: prefix on about. --> -<rdf:Description - about="" - rdf:about="" - xmlns:exif="http://ns.adobe.com/exif/1.0/" - exif:FNumber="28/10"> -</rdf:Description> -</rdf:RDF> -<?xpacket end="w"?> diff --git a/tests/phpunit/data/xmp/no-recognized-props.result.php b/tests/phpunit/data/xmp/no-recognized-props.result.php deleted file mode 100644 index b3ca9f5a..00000000 --- a/tests/phpunit/data/xmp/no-recognized-props.result.php +++ /dev/null @@ -1,2 +0,0 @@ -<?php -$result = array(); diff --git a/tests/phpunit/data/xmp/no-recognized-props.xmp b/tests/phpunit/data/xmp/no-recognized-props.xmp deleted file mode 100644 index 54e80901..00000000 --- a/tests/phpunit/data/xmp/no-recognized-props.xmp +++ /dev/null @@ -1,8 +0,0 @@ -<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> -<rdf:Description - rdf:about="" - xmlns:exif="http://ns.adobe.com/exif/1.0/not-exif-namespace" - exif:FNumber="2/10"> -</rdf:Description> -</rdf:RDF> -<?xpacket end="w"?> diff --git a/tests/phpunit/data/xmp/utf16BE.result.php b/tests/phpunit/data/xmp/utf16BE.result.php deleted file mode 100644 index ac7ea506..00000000 --- a/tests/phpunit/data/xmp/utf16BE.result.php +++ /dev/null @@ -1,12 +0,0 @@ -<?php - -$result = array( - 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - ), - 'xmp-general' => - array( - 'Label' => '' - ), -); diff --git a/tests/phpunit/data/xmp/utf16BE.xmp b/tests/phpunit/data/xmp/utf16BE.xmp Binary files differdeleted file mode 100644 index 0cf60d60..00000000 --- a/tests/phpunit/data/xmp/utf16BE.xmp +++ /dev/null diff --git a/tests/phpunit/data/xmp/utf16LE.result.php b/tests/phpunit/data/xmp/utf16LE.result.php deleted file mode 100644 index ac7ea506..00000000 --- a/tests/phpunit/data/xmp/utf16LE.result.php +++ /dev/null @@ -1,12 +0,0 @@ -<?php - -$result = array( - 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - ), - 'xmp-general' => - array( - 'Label' => '' - ), -); diff --git a/tests/phpunit/data/xmp/utf16LE.xmp b/tests/phpunit/data/xmp/utf16LE.xmp Binary files differdeleted file mode 100644 index 66d71f4c..00000000 --- a/tests/phpunit/data/xmp/utf16LE.xmp +++ /dev/null diff --git a/tests/phpunit/data/xmp/utf32BE.result.php b/tests/phpunit/data/xmp/utf32BE.result.php deleted file mode 100644 index ac7ea506..00000000 --- a/tests/phpunit/data/xmp/utf32BE.result.php +++ /dev/null @@ -1,12 +0,0 @@ -<?php - -$result = array( - 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - ), - 'xmp-general' => - array( - 'Label' => '' - ), -); diff --git a/tests/phpunit/data/xmp/utf32BE.xmp b/tests/phpunit/data/xmp/utf32BE.xmp Binary files differdeleted file mode 100644 index 06afdf92..00000000 --- a/tests/phpunit/data/xmp/utf32BE.xmp +++ /dev/null diff --git a/tests/phpunit/data/xmp/utf32LE.result.php b/tests/phpunit/data/xmp/utf32LE.result.php deleted file mode 100644 index ac7ea506..00000000 --- a/tests/phpunit/data/xmp/utf32LE.result.php +++ /dev/null @@ -1,12 +0,0 @@ -<?php - -$result = array( - 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - ), - 'xmp-general' => - array( - 'Label' => '' - ), -); diff --git a/tests/phpunit/data/xmp/utf32LE.xmp b/tests/phpunit/data/xmp/utf32LE.xmp Binary files differdeleted file mode 100644 index bf2097fe..00000000 --- a/tests/phpunit/data/xmp/utf32LE.xmp +++ /dev/null diff --git a/tests/phpunit/data/xmp/xmpExt.result.php b/tests/phpunit/data/xmp/xmpExt.result.php deleted file mode 100644 index beead1bd..00000000 --- a/tests/phpunit/data/xmp/xmpExt.result.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php - -$result = array( 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => '9' - ) -); diff --git a/tests/phpunit/data/xmp/xmpExt.xmp b/tests/phpunit/data/xmp/xmpExt.xmp deleted file mode 100644 index da0383f8..00000000 --- a/tests/phpunit/data/xmp/xmpExt.xmp +++ /dev/null @@ -1,13 +0,0 @@ -<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core - 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10 "> -<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> -<rdf:Description - rdf:about="" - xmlns:exif="http://ns.adobe.com/exif/1.0/" - xmlns:xmpNote="http://ns.adobe.com/xmp/note/" - exif:DigitalZoomRatio="0/10" - xmpNote:HasExtendedXMP="28C74E0AC2D796886759006FBE2E57B7"> -<exif:Flash rdf:parseType='Resource'> -<exif:Fired>True</exif:Fired> <exif:Return>0</exif:Return> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></exif:Flash> </rdf:Description> </rdf:RDF> </x:xmpmeta> - -<?xpacket end="w"?> diff --git a/tests/phpunit/data/xmp/xmpExt2.xmp b/tests/phpunit/data/xmp/xmpExt2.xmp deleted file mode 100644 index 060abb2c..00000000 --- a/tests/phpunit/data/xmp/xmpExt2.xmp +++ /dev/null @@ -1,8 +0,0 @@ -<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> -<rdf:Description - rdf:about="" - xmlns:exif="http://ns.adobe.com/exif/1.0/" - exif:FNumber="2/10"> -</rdf:Description> -</rdf:RDF> -<?xpacket end="w"?> diff --git a/tests/phpunit/data/zip/cd-gap.zip b/tests/phpunit/data/zip/cd-gap.zip Binary files differdeleted file mode 100644 index b5ae6ccd..00000000 --- a/tests/phpunit/data/zip/cd-gap.zip +++ /dev/null diff --git a/tests/phpunit/data/zip/cd-truncated.zip b/tests/phpunit/data/zip/cd-truncated.zip Binary files differdeleted file mode 100644 index 4d40d7d4..00000000 --- a/tests/phpunit/data/zip/cd-truncated.zip +++ /dev/null diff --git a/tests/phpunit/data/zip/class-trailing-null.zip b/tests/phpunit/data/zip/class-trailing-null.zip Binary files differdeleted file mode 100644 index 31dcf3d8..00000000 --- a/tests/phpunit/data/zip/class-trailing-null.zip +++ /dev/null diff --git a/tests/phpunit/data/zip/class-trailing-slash.zip b/tests/phpunit/data/zip/class-trailing-slash.zip Binary files differdeleted file mode 100644 index 9eb1f037..00000000 --- a/tests/phpunit/data/zip/class-trailing-slash.zip +++ /dev/null diff --git a/tests/phpunit/data/zip/class.zip b/tests/phpunit/data/zip/class.zip Binary files differdeleted file mode 100644 index 98a625b7..00000000 --- a/tests/phpunit/data/zip/class.zip +++ /dev/null diff --git a/tests/phpunit/data/zip/empty.zip b/tests/phpunit/data/zip/empty.zip Binary files differdeleted file mode 100644 index 15cb0ecb..00000000 --- a/tests/phpunit/data/zip/empty.zip +++ /dev/null diff --git a/tests/phpunit/data/zip/looks-like-zip64.zip b/tests/phpunit/data/zip/looks-like-zip64.zip Binary files differdeleted file mode 100644 index 7428cddd..00000000 --- a/tests/phpunit/data/zip/looks-like-zip64.zip +++ /dev/null diff --git a/tests/phpunit/data/zip/nosig.zip b/tests/phpunit/data/zip/nosig.zip Binary files differdeleted file mode 100644 index a22c73a4..00000000 --- a/tests/phpunit/data/zip/nosig.zip +++ /dev/null diff --git a/tests/phpunit/data/zip/split.zip b/tests/phpunit/data/zip/split.zip Binary files differdeleted file mode 100644 index 6984ae6d..00000000 --- a/tests/phpunit/data/zip/split.zip +++ /dev/null diff --git a/tests/phpunit/data/zip/trail.zip b/tests/phpunit/data/zip/trail.zip Binary files differdeleted file mode 100644 index 50bcea12..00000000 --- a/tests/phpunit/data/zip/trail.zip +++ /dev/null diff --git a/tests/phpunit/data/zip/wrong-cd-start-disk.zip b/tests/phpunit/data/zip/wrong-cd-start-disk.zip Binary files differdeleted file mode 100644 index 59b45938..00000000 --- a/tests/phpunit/data/zip/wrong-cd-start-disk.zip +++ /dev/null diff --git a/tests/phpunit/data/zip/wrong-central-entry-sig.zip b/tests/phpunit/data/zip/wrong-central-entry-sig.zip Binary files differdeleted file mode 100644 index 05329b43..00000000 --- a/tests/phpunit/data/zip/wrong-central-entry-sig.zip +++ /dev/null diff --git a/tests/phpunit/docs/ExportDemoTest.php b/tests/phpunit/docs/ExportDemoTest.php deleted file mode 100644 index b09487a6..00000000 --- a/tests/phpunit/docs/ExportDemoTest.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php -/** - * Test for the demo xml - * - * @group Dump - */ -class ExportDemoTest extends DumpTestCase { - - /** - * @group large - */ - function testExportDemo() { - $this->validateXmlFileAgainstXsd( "../../docs/export-demo.xml" ); - } - - /** - * Validates a xml file against the xsd. - * - * The validation is slow, because php has to read the xsd on each call. - * - * @param $fname string: name of file to validate - */ - protected function validateXmlFileAgainstXsd( $fname ) { - $version = WikiExporter::schemaVersion(); - - $dom = new DomDocument(); - $dom->load( $fname ); - - // Ensure, the demo is for the current version - $this->assertEquals( $dom->documentElement->getAttribute( 'version' ), $version, 'export-demo.xml should have the current version' ); - - try { - $this->assertTrue( $dom->schemaValidate( "../../docs/export-" . $version . ".xsd" ), - "schemaValidate has found an error" ); - } catch ( Exception $e ) { - $this->fail( "xml not valid against xsd: " . $e->getMessage() ); - } - } -} diff --git a/tests/phpunit/includes/ArticleTablesTest.php b/tests/phpunit/includes/ArticleTablesTest.php deleted file mode 100644 index 469d1d19..00000000 --- a/tests/phpunit/includes/ArticleTablesTest.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php - -/** - * @group Database - */ -class ArticleTablesTest extends MediaWikiLangTestCase { - - public function testbug14404() { - global $wgContLang, $wgLanguageCode, $wgLang; - - $title = Title::newFromText( 'Bug 14404' ); - $page = WikiPage::factory( $title ); - $user = new User(); - $user->mRights = array( 'createpage', 'edit', 'purge' ); - $wgLanguageCode = 'es'; - $wgContLang = Language::factory( 'es' ); - - $wgLang = Language::factory( 'fr' ); - $page->doEditContent( new WikitextContent( '{{:{{int:history}}}}' ), 'Test code for bug 14404', 0, false, $user ); - $templates1 = $title->getTemplateLinksFrom(); - - $wgLang = Language::factory( 'de' ); - $page = WikiPage::factory( $title ); // In order to force the rerendering of the same wikitext - - // We need an edit, a purge is not enough to regenerate the tables - $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 deleted file mode 100644 index b4d6dca6..00000000 --- a/tests/phpunit/includes/ArticleTest.php +++ /dev/null @@ -1,92 +0,0 @@ -<?php - -class ArticleTest extends MediaWikiTestCase { - - /** - * @var Title - */ - private $title; - /** - * @var Article - */ - private $article; - - /** creates a title object and its article object */ - protected function setUp() { - parent::setUp(); - $this->title = Title::makeTitle( NS_MAIN, 'SomePage' ); - $this->article = new Article( $this->title ); - } - - /** cleanup title object and its article object */ - protected function tearDown() { - parent::tearDown(); - $this->title = null; - $this->article = null; - } - - public function testImplementsGetMagic() { - $this->assertEquals( false, $this->article->mLatest, "Article __get magic" ); - } - - /** - * @depends testImplementsGetMagic - */ - public function testImplementsSetMagic() { - $this->article->mLatest = 2; - $this->assertEquals( 2, $this->article->mLatest, "Article __set magic" ); - } - - /** - * @depends testImplementsSetMagic - */ - public function testImplementsCallMagic() { - $this->article->mLatest = 33; - $this->article->mDataLoaded = true; - $this->assertEquals( 33, $this->article->getLatest(), "Article __call magic" ); - } - - public function testGetOrSetOnNewProperty() { - $this->article->ext_someNewProperty = 12; - $this->assertEquals( 12, $this->article->ext_someNewProperty, - "Article get/set magic on new field" ); - - $this->article->ext_someNewProperty = -8; - $this->assertEquals( -8, $this->article->ext_someNewProperty, - "Article get/set magic on update to new field" ); - } - - /** - * Checks for the existence of the backwards compatibility static functions (forwarders to WikiPage class) - */ - public function testStaticFunctions() { - $this->hideDeprecated( 'Article::getAutosummary' ); - $this->hideDeprecated( 'WikiPage::getAutosummary' ); - $this->hideDeprecated( 'CategoryPage::getAutosummary' ); // Inherited from Article - - $this->assertEquals( WikiPage::selectFields(), Article::selectFields(), - "Article static functions" ); - $this->assertEquals( true, is_callable( "Article::onArticleCreate" ), - "Article static functions" ); - $this->assertEquals( true, is_callable( "Article::onArticleDelete" ), - "Article static functions" ); - $this->assertEquals( true, is_callable( "ImagePage::onArticleEdit" ), - "Article static functions" ); - $this->assertTrue( is_string( CategoryPage::getAutosummary( '', '', 0 ) ), - "Article static functions" ); - } - - public function testWikiPageFactory() { - $title = Title::makeTitle( NS_FILE, 'Someimage.png' ); - $page = WikiPage::factory( $title ); - $this->assertEquals( 'WikiFilePage', get_class( $page ) ); - - $title = Title::makeTitle( NS_CATEGORY, 'SomeCategory' ); - $page = WikiPage::factory( $title ); - $this->assertEquals( 'WikiCategoryPage', get_class( $page ) ); - - $title = Title::makeTitle( NS_MAIN, 'SomePage' ); - $page = WikiPage::factory( $title ); - $this->assertEquals( 'WikiPage', get_class( $page ) ); - } -} diff --git a/tests/phpunit/includes/BlockTest.php b/tests/phpunit/includes/BlockTest.php deleted file mode 100644 index 21de0985..00000000 --- a/tests/phpunit/includes/BlockTest.php +++ /dev/null @@ -1,354 +0,0 @@ -<?php - -/** - * @group Database - * @group Blocking - */ -class BlockTest extends MediaWikiLangTestCase { - - private $block, $madeAt; - - /* variable used to save up the blockID we insert in this test suite */ - private $blockId; - - protected function setUp() { - parent::setUp(); - $this->setMwGlobals( array( - 'wgLanguageCode' => 'en', - 'wgContLang' => Language::factory( 'en' ) - ) ); - } - - function addDBData() { - - $user = User::newFromName( 'UTBlockee' ); - if ( $user->getID() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTBlockeePassword' ); - - $user->saveSettings(); - } - - // Delete the last round's block if it's still there - $oldBlock = Block::newFromTarget( 'UTBlockee' ); - if ( $oldBlock ) { - // An old block will prevent our new one from saving. - $oldBlock->delete(); - } - - $this->block = new Block( 'UTBlockee', $user->getID(), 0, - 'Parce que', 0, false, time() + 100500 - ); - $this->madeAt = wfTimestamp( TS_MW ); - - $this->block->insert(); - // save up ID for use in assertion. Since ID is an autoincrement, - // its value might change depending on the order the tests are run. - // ApiBlockTest insert its own blocks! - $newBlockId = $this->block->getId(); - if ( $newBlockId ) { - $this->blockId = $newBlockId; - } 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->select( 'ipblocks', '*' ); - print "Got " . $v->numRows() . " rows. Full dump follow:\n"; - foreach ( $v as $row ) { - print_r( $row ); - } - } - - 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 - */ - 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()" ); - } - - /** - * This is the method previously used to load block info in CheckUser etc - * passing an empty value (empty string, null, etc) as the ip parameter bypasses IP lookup checks. - * - * This stopped working with r84475 and friends: regression being fixed for bug 29116. - * - * @dataProvider provideBug29116Data - */ - public function testBug29116LoadWithEmptyIp( $vagueTarget ) { - $this->hideDeprecated( 'Block::load' ); - - $uid = User::idFromName( 'UTBlockee' ); - $this->assertTrue( ( $uid > 0 ), 'Must be able to look up the target user during tests' ); - - $block = new Block(); - $ok = $block->load( $vagueTarget, $uid ); - $this->assertTrue( $ok, "Block->load() with empty IP and user ID '$uid' should return a block" ); - - $this->assertTrue( $this->block->equals( $block ), "Block->load() returns the same block as the one that was made when given empty ip param " . var_export( $vagueTarget, true ) ); - } - - /** - * CheckUser since being changed to use Block::newFromTarget started failing - * because the new function didn't accept empty strings like Block::load() - * had. Regression bug 29116. - * - * @dataProvider provideBug29116Data - */ - 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 ) ); - } - - public static function provideBug29116Data() { - return array( - array( null ), - array( '' ), - array( false ) - ); - } - - public function testBlockedUserCanNotCreateAccount() { - $username = 'BlockedUserToCreateAccountWith'; - $u = User::newFromName( $username ); - $u->setPassword( 'NotRandomPass' ); - $u->addToDatabase(); - unset( $u ); - - // Sanity check - $this->assertNull( - Block::newFromTarget( $username ), - "$username should not be blocked" - ); - - // Reload user - $u = User::newFromName( $username ); - $this->assertFalse( - $u->isBlockedFromCreateAccount(), - "Our sandbox user should be able to create account before being blocked" - ); - - // Foreign perspective (blockee not on current wiki)... - $block = new Block( - /* $address */ $username, - /* $user */ 14146, - /* $by */ 0, - /* $reason */ 'crosswiki block...', - /* $timestamp */ wfTimestampNow(), - /* $auto */ false, - /* $expiry */ $this->db->getInfinity(), - /* anonOnly */ false, - /* $createAccount */ true, - /* $enableAutoblock */ true, - /* $hideName (ipb_deleted) */ true, - /* $blockEmail */ true, - /* $allowUsertalk */ false, - /* $byName */ 'MetaWikiUser' - ); - $block->insert(); - - // Reload block from DB - $userBlock = Block::newFromTarget( $username ); - $this->assertTrue( - (bool)$block->prevents( 'createaccount' ), - "Block object in DB should prevents 'createaccount'" - ); - - $this->assertInstanceOf( - 'Block', - $userBlock, - "'$username' block block object should be existent" - ); - - // Reload user - $u = User::newFromName( $username ); - $this->assertTrue( - (bool)$u->isBlockedFromCreateAccount(), - "Our sandbox user '$username' should NOT be able to create account" - ); - } - - public function testCrappyCrossWikiBlocks() { - // Delete the last round's block if it's still there - $oldBlock = Block::newFromTarget( 'UserOnForeignWiki' ); - if ( $oldBlock ) { - // An old block will prevent our new one from saving. - $oldBlock->delete(); - } - - // Foreign perspective (blockee not on current wiki)... - $block = new Block( - /* $address */ 'UserOnForeignWiki', - /* $user */ 14146, - /* $by */ 0, - /* $reason */ 'crosswiki block...', - /* $timestamp */ wfTimestampNow(), - /* $auto */ false, - /* $expiry */ $this->db->getInfinity(), - /* anonOnly */ false, - /* $createAccount */ true, - /* $enableAutoblock */ true, - /* $hideName (ipb_deleted) */ true, - /* $blockEmail */ true, - /* $allowUsertalk */ false, - /* $byName */ 'MetaWikiUser' - ); - - $res = $block->insert( $this->db ); - $this->assertTrue( (bool)$res['id'], 'Block succeeded' ); - - // Local perspective (blockee on current wiki)... - $user = User::newFromName( 'UserOnForeignWiki' ); - $user->addToDatabase(); - // Set user ID to match the test value - $this->db->update( 'user', array( 'user_id' => 14146 ), array( 'user_id' => $user->getId() ) ); - $user = null; // clear - - $block = Block::newFromID( $res['id'] ); - $this->assertEquals( 'UserOnForeignWiki', $block->getTarget()->getName(), 'Correct blockee name' ); - $this->assertEquals( '14146', $block->getTarget()->getId(), 'Correct blockee id' ); - $this->assertEquals( 'MetaWikiUser', $block->getBlocker(), 'Correct blocker name' ); - $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 deleted file mode 100644 index e3d9da7c..00000000 --- a/tests/phpunit/includes/CdbTest.php +++ /dev/null @@ -1,88 +0,0 @@ -<?php - -/** - * Test the CDB reader/writer - */ -class CdbTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - if ( !CdbReader::haveExtension() ) { - $this->markTestSkipped( 'Native CDB support is not available' ); - } - } - - /** - * @group medium - */ - public function testCdb() { - $dir = wfTempDir(); - if ( !is_writable( $dir ) ) { - $this->markTestSkipped( "Temp dir isn't writable" ); - } - - $phpcdbfile = $this->getNewTempFile(); - $dbacdbfile = $this->getNewTempFile(); - - $w1 = new CdbWriter_PHP( $phpcdbfile ); - $w2 = new CdbWriter_DBA( $dbacdbfile ); - - $data = array(); - for ( $i = 0; $i < 1000; $i++ ) { - $key = $this->randomString(); - $value = $this->randomString(); - $w1->set( $key, $value ); - $w2->set( $key, $value ); - - if ( !isset( $data[$key] ) ) { - $data[$key] = $value; - } - } - - $w1->close(); - $w2->close(); - - $this->assertEquals( - md5_file( $phpcdbfile ), - md5_file( $dbacdbfile ), - 'same hash' - ); - - $r1 = new CdbReader_PHP( $phpcdbfile ); - $r2 = new CdbReader_DBA( $dbacdbfile ); - - foreach ( $data as $key => $value ) { - if ( $key === '' ) { - // Known bug - continue; - } - $v1 = $r1->get( $key ); - $v2 = $r2->get( $key ); - - $v1 = $v1 === false ? '(not found)' : $v1; - $v2 = $v2 === false ? '(not found)' : $v2; - - # cdbAssert( 'Mismatch', $key, $v1, $v2 ); - $this->cdbAssert( "PHP error", $key, $v1, $value ); - $this->cdbAssert( "DBA error", $key, $v2, $value ); - } - } - - private function randomString() { - $len = mt_rand( 0, 10 ); - $s = ''; - for ( $j = 0; $j < $len; $j++ ) { - $s .= chr( mt_rand( 0, 255 ) ); - } - - return $s; - } - - private function cdbAssert( $msg, $key, $v1, $v2 ) { - $this->assertEquals( - $v2, - $v1, - $msg . ', k=' . bin2hex( $key ) - ); - } -} diff --git a/tests/phpunit/includes/CollationTest.php b/tests/phpunit/includes/CollationTest.php deleted file mode 100644 index 43bb3941..00000000 --- a/tests/phpunit/includes/CollationTest.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php -class CollationTest extends MediaWikiLangTestCase { - protected function setUp() { - parent::setUp(); - if ( !extension_loaded( 'intl' ) ) { - $this->markTestSkipped( 'These tests require intl extension' ); - } - } - - /** - * Test to make sure, that if you - * have "X" and "XY", the binary - * sortkey also has "X" being a - * prefix of "XY". Our collation - * code makes this assumption. - * - * @param $lang String Language code for collator - * @param $base String Base string - * @param $extended String String containing base as a prefix. - * - * @dataProvider prefixDataProvider - */ - public function testIsPrefix( $lang, $base, $extended ) { - $cp = Collator::create( $lang ); - $cp->setStrength( Collator::PRIMARY ); - $baseBin = $cp->getSortKey( $base ); - // Remove sortkey terminator - $baseBin = rtrim( $baseBin, "\0" ); - $extendedBin = $cp->getSortKey( $extended ); - $this->assertStringStartsWith( $baseBin, $extendedBin, "$base is not a prefix of $extended" ); - } - - function prefixDataProvider() { - return array( - array( 'en', 'A', 'AA' ), - array( 'en', 'A', 'AAA' ), - array( 'en', 'Д', 'ДЂ' ), - array( 'en', 'Д', 'ДA' ), - // 'Ʒ' should expand to 'Z ' (note space). - array( 'fi', 'Z', 'Ʒ' ), - // 'Þ' should expand to 'th' - array( 'sv', 't', 'Þ' ), - // Javanese is a limited use alphabet, so should have 3 bytes - // per character, so do some tests with it. - array( 'en', 'ꦲ', 'ꦲꦤ' ), - array( 'en', 'ꦲ', 'ꦲД' ), - array( 'en', 'A', 'Aꦲ' ), - ); - } - - /** - * Opposite of testIsPrefix - * - * @dataProvider notPrefixDataProvider - */ - public function testNotIsPrefix( $lang, $base, $extended ) { - $cp = Collator::create( $lang ); - $cp->setStrength( Collator::PRIMARY ); - $baseBin = $cp->getSortKey( $base ); - // Remove sortkey terminator - $baseBin = rtrim( $baseBin, "\0" ); - $extendedBin = $cp->getSortKey( $extended ); - $this->assertStringStartsNotWith( $baseBin, $extendedBin, "$base is a prefix of $extended" ); - } - - function notPrefixDataProvider() { - return array( - array( 'en', 'A', 'B' ), - array( 'en', 'AC', 'ABC' ), - array( 'en', 'Z', 'Ʒ' ), - array( 'en', 'A', 'ꦲ' ), - ); - } - - /** - * Test correct first letter is fetched. - * - * @param $collation String Collation name (aka uca-en) - * @param $string String String to get first letter of - * @param $firstLetter String Expected first letter. - * - * @dataProvider firstLetterProvider - */ - public function testGetFirstLetter( $collation, $string, $firstLetter ) { - $col = Collation::factory( $collation ); - $this->assertEquals( $firstLetter, $col->getFirstLetter( $string ) ); - } - - function firstLetterProvider() { - return array( - array( 'uppercase', 'Abc', 'A' ), - array( 'uppercase', 'abc', 'A' ), - array( 'identity', 'abc', 'a' ), - array( 'uca-en', 'abc', 'A' ), - array( 'uca-en', ' ', ' ' ), - array( 'uca-en', 'Êveryone', 'E' ), - array( 'uca-vi', 'Êveryone', 'Ê' ), - // Make sure thorn is not a first letter. - array( 'uca-sv', 'The', 'T' ), - array( 'uca-sv', 'Å', 'Å' ), - array( 'uca-hu', 'dzsdo', 'Dzs' ), - array( 'uca-hu', 'dzdso', 'Dz' ), - array( 'uca-hu', 'CSD', 'Cs' ), - array( 'uca-root', 'CSD', 'C' ), - array( 'uca-fi', 'Ǥ', 'G' ), - array( 'uca-fi', 'Ŧ', 'T' ), - array( 'uca-fi', 'Ʒ', 'Z' ), - array( 'uca-fi', 'Ŋ', 'N' ), - ); - } -} diff --git a/tests/phpunit/includes/DiffHistoryBlobTest.php b/tests/phpunit/includes/DiffHistoryBlobTest.php deleted file mode 100644 index a4d5b91a..00000000 --- a/tests/phpunit/includes/DiffHistoryBlobTest.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php - -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' ) ) { - $this->markTestSkipped( 'The hash extension is not available' ); - - return; - } - parent::setUp(); - } - - /** - * Test for DiffHistoryBlob::xdiffAdler32() - * @dataProvider provideXdiffAdler32 - */ - public function testXdiffAdler32( $input ) { - $xdiffHash = substr( xdiff_string_rabdiff( $input, '' ), 0, 4 ); - $dhb = new DiffHistoryBlob; - $myHash = $dhb->xdiffAdler32( $input ); - $this->assertSame( bin2hex( $xdiffHash ), bin2hex( $myHash ), - "Hash of " . addcslashes( $input, "\0..\37!@\@\177..\377" ) ); - } - - public static function provideXdiffAdler32() { - return array( - array( '', 'Empty string' ), - array( "\0", 'Null' ), - array( "\0\0\0", "Several nulls" ), - array( "Hello", "An ASCII string" ), - array( str_repeat( "x", 6000 ), "A string larger than xdiff's NMAX (5552)" ) - ); - } -} diff --git a/tests/phpunit/includes/EditPageTest.php b/tests/phpunit/includes/EditPageTest.php deleted file mode 100644 index 87272a4c..00000000 --- a/tests/phpunit/includes/EditPageTest.php +++ /dev/null @@ -1,491 +0,0 @@ -<?php - -/** - * @group Editing - * - * @group Database - * ^--- tell jenkins this test needs the database - * - * @group medium - * ^--- tell phpunit that these test cases may take longer than 2 seconds. - */ -class EditPageTest extends MediaWikiLangTestCase { - - /** - * @dataProvider provideExtractSectionTitle - */ - public function testExtractSectionTitle( $section, $title ) { - $extracted = EditPage::extractSectionTitle( $section ); - $this->assertEquals( $title, $extracted ); - } - - public static function provideExtractSectionTitle() { - return array( - array( - "== Test ==\n\nJust a test section.", - "Test" - ), - array( - "An initial section, no header.", - false - ), - array( - "An initial section with a fake heder (bug 32617)\n\n== Test == ??\nwtf", - false - ), - array( - "== Section ==\nfollowed by a fake == Non-section == ??\nnoooo", - "Section" - ), - array( - "== Section== \t\r\n followed by whitespace (bug 35051)", - 'Section', - ), - ); - } - - protected function forceRevisionDate( WikiPage $page, $timestamp ) { - $dbw = wfGetDB( DB_MASTER ); - - $dbw->update( 'revision', - array( 'rev_timestamp' => $dbw->timestamp( $timestamp ) ), - array( 'rev_id' => $page->getLatest() ) ); - - $page->clear(); - } - - /** - * User input text is passed to rtrim() by edit page. This is a simple - * wrapper around assertEquals() which calls rrtrim() to normalize the - * expected and actual texts. - */ - function assertEditedTextEquals( $expected, $actual, $msg = '' ) { - return $this->assertEquals( rtrim( $expected ), rtrim( $actual ), $msg ); - } - - /** - * Performs an edit and checks the result. - * - * @param String|Title $title The title of the page to edit - * @param String|null $baseText Some text to create the page with before attempting the edit. - * @param User|String|null $user The user to perform the edit as. - * @param array $edit An array of request parameters used to define the edit to perform. - * Some well known fields are: - * * wpTextbox1: the text to submit - * * wpSummary: the edit summary - * * wpEditToken: the edit token (will be inserted if not provided) - * * wpEdittime: timestamp of the edit's base revision (will be inserted if not provided) - * * wpStarttime: timestamp when the edit started (will be inserted if not provided) - * * wpSectionTitle: the section to edit - * * wpMinorEdit: mark as minor edit - * * wpWatchthis: whether to watch the page - * @param int|null $expectedCode The expected result code (EditPage::AS_XXX constants). - * Set to null to skip the check. Defaults to EditPage::AS_OK. - * @param String|null $expectedText The text expected to be on the page after the edit. - * Set to null to skip the check. - * @param String|null $message An optional message to show along with any error message. - * - * @return WikiPage The page that was just edited, useful for getting the edit's rev_id, etc. - */ - protected function assertEdit( $title, $baseText, $user = null, array $edit, - $expectedCode = EditPage::AS_OK, $expectedText = null, $message = null - ) { - if ( is_string( $title ) ) { - $ns = $this->getDefaultWikitextNS(); - $title = Title::newFromText( $title, $ns ); - } - - if ( is_string( $user ) ) { - $user = User::newFromName( $user ); - - if ( $user->getId() === 0 ) { - $user->addToDatabase(); - } - } - - $page = WikiPage::factory( $title ); - - if ( $baseText !== null ) { - $content = ContentHandler::makeContent( $baseText, $title ); - $page->doEditContent( $content, "base text for test" ); - $this->forceRevisionDate( $page, '20120101000000' ); - - //sanity check - $page->clear(); - $currentText = ContentHandler::getContentText( $page->getContent() ); - - # EditPage rtrim() the user input, so we alter our expected text - # to reflect that. - $this->assertEditedTextEquals( $baseText, $currentText ); - } - - if ( $user == null ) { - $user = $GLOBALS['wgUser']; - } else { - $this->setMwGlobals( 'wgUser', $user ); - } - - if ( !isset( $edit['wpEditToken'] ) ) { - $edit['wpEditToken'] = $user->getEditToken(); - } - - if ( !isset( $edit['wpEdittime'] ) ) { - $edit['wpEdittime'] = $page->exists() ? $page->getTimestamp() : ''; - } - - if ( !isset( $edit['wpStarttime'] ) ) { - $edit['wpStarttime'] = wfTimestampNow(); - } - - $req = new FauxRequest( $edit, true ); // session ?? - - $ep = new EditPage( new Article( $title ) ); - $ep->setContextTitle( $title ); - $ep->importFormData( $req ); - - $bot = isset( $edit['bot'] ) ? (bool)$edit['bot'] : false; - - // this is where the edit happens! - // Note: don't want to use EditPage::AttemptSave, because it messes with $wgOut - // and throws exceptions like PermissionsError - $status = $ep->internalAttemptSave( $result, $bot ); - - if ( $expectedCode !== null ) { - // check edit code - $this->assertEquals( $expectedCode, $status->value, - "Expected result code mismatch. $message" ); - } - - $page = WikiPage::factory( $title ); - - if ( $expectedText !== null ) { - // check resulting page text - $content = $page->getContent(); - $text = ContentHandler::getContentText( $content ); - - # EditPage rtrim() the user input, so we alter our expected text - # to reflect that. - $this->assertEditedTextEquals( $expectedText, $text, - "Expected article text mismatch. $message" ); - } - - return $page; - } - - public function testCreatePage() { - $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( - '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() { - $text = "one"; - $edit = array( - 'wpTextbox1' => $text, - 'wpSummary' => 'first update', - ); - - $page = $this->assertEdit( 'EditPageTest_testUpdatePage', "zero", null, $edit, - EditPage::AS_SUCCESS_UPDATE, $text, - "expected successfull update with given text" ); - - $this->forceRevisionDate( $page, '20120101000000' ); - - $text = "two"; - $edit = array( - 'wpTextbox1' => $text, - 'wpSummary' => 'second update', - ); - - $this->assertEdit( 'EditPageTest_testUpdatePage', null, null, $edit, - EditPage::AS_SUCCESS_UPDATE, $text, - "expected successfull update with given text" ); - } - - public static function provideSectionEdit() { - $text = 'Intro - -== one == -first section. - -== two == -second section. -'; - - $sectionOne = '== one == -hello -'; - - $newSection = '== new section == - -hello -'; - - $textWithNewSectionOne = preg_replace( - '/== one ==.*== two ==/ms', - "$sectionOne\n== two ==", $text - ); - - $textWithNewSectionAdded = "$text\n$newSection"; - - return array( - array( #0 - $text, - '', - 'hello', - 'replace all', - 'hello' - ), - - array( #1 - $text, - '1', - $sectionOne, - 'replace first section', - $textWithNewSectionOne, - ), - - array( #2 - $text, - 'new', - 'hello', - 'new section', - $textWithNewSectionAdded, - ), - ); - } - - /** - * @dataProvider provideSectionEdit - */ - public function testSectionEdit( $base, $section, $text, $summary, $expected ) { - $edit = array( - 'wpTextbox1' => $text, - 'wpSummary' => $summary, - 'wpSection' => $section, - ); - - $this->assertEdit( 'EditPageTest_testSectionEdit', $base, null, $edit, - EditPage::AS_SUCCESS_UPDATE, $expected, - "expected successfull update of section" ); - } - - public static function provideAutoMerge() { - $tests = array(); - - $tests[] = array( #0: plain conflict - "Elmo", # base edit user - "one\n\ntwo\n\nthree\n", - array( #adam's edit - 'wpStarttime' => 1, - 'wpTextbox1' => "ONE\n\ntwo\n\nthree\n", - ), - array( #berta's edit - 'wpStarttime' => 2, - 'wpTextbox1' => "(one)\n\ntwo\n\nthree\n", - ), - EditPage::AS_CONFLICT_DETECTED, # expected code - "ONE\n\ntwo\n\nthree\n", # expected text - 'expected edit conflict', # message - ); - - $tests[] = array( #1: successful merge - "Elmo", # base edit user - "one\n\ntwo\n\nthree\n", - array( #adam's edit - 'wpStarttime' => 1, - 'wpTextbox1' => "ONE\n\ntwo\n\nthree\n", - ), - array( #berta's edit - 'wpStarttime' => 2, - 'wpTextbox1' => "one\n\ntwo\n\nTHREE\n", - ), - EditPage::AS_SUCCESS_UPDATE, # expected code - "ONE\n\ntwo\n\nTHREE\n", # expected text - 'expected automatic merge', # message - ); - - $text = "Intro\n\n"; - $text .= "== first section ==\n\n"; - $text .= "one\n\ntwo\n\nthree\n\n"; - $text .= "== second section ==\n\n"; - $text .= "four\n\nfive\n\nsix\n\n"; - - // extract the first section. - $section = preg_replace( '/.*(== first section ==.*)== second section ==.*/sm', '$1', $text ); - - // generate expected text after merge - $expected = str_replace( 'one', 'ONE', str_replace( 'three', 'THREE', $text ) ); - - $tests[] = array( #2: merge in section - "Elmo", # base edit user - $text, - array( #adam's edit - 'wpStarttime' => 1, - 'wpTextbox1' => str_replace( 'one', 'ONE', $section ), - 'wpSection' => '1' - ), - array( #berta's edit - 'wpStarttime' => 2, - 'wpTextbox1' => str_replace( 'three', 'THREE', $section ), - 'wpSection' => '1' - ), - EditPage::AS_SUCCESS_UPDATE, # expected code - $expected, # expected text - 'expected automatic section merge', # message - ); - - // see whether it makes a difference who did the base edit - $testsWithAdam = array_map( function ( $test ) { - $test[0] = 'Adam'; // change base edit user - return $test; - }, $tests ); - - $testsWithBerta = array_map( function ( $test ) { - $test[0] = 'Berta'; // change base edit user - return $test; - }, $tests ); - - return array_merge( $tests, $testsWithAdam, $testsWithBerta ); - } - - /** - * @dataProvider provideAutoMerge - */ - public function testAutoMerge( $baseUser, $text, $adamsEdit, $bertasEdit, - $expectedCode, $expectedText, $message = null - ) { - $this->checkHasDiff3(); - - //create page - $ns = $this->getDefaultWikitextNS(); - $title = Title::newFromText( 'EditPageTest_testAutoMerge', $ns ); - $page = WikiPage::factory( $title ); - - if ( $page->exists() ) { - $page->doDeleteArticle( "clean slate for testing" ); - } - - $baseEdit = array( - 'wpTextbox1' => $text, - ); - - $page = $this->assertEdit( 'EditPageTest_testAutoMerge', null, - $baseUser, $baseEdit, null, null, __METHOD__ ); - - $this->forceRevisionDate( $page, '20120101000000' ); - - $edittime = $page->getTimestamp(); - - // start timestamps for conflict detection - if ( !isset( $adamsEdit['wpStarttime'] ) ) { - $adamsEdit['wpStarttime'] = 1; - } - - if ( !isset( $bertasEdit['wpStarttime'] ) ) { - $bertasEdit['wpStarttime'] = 2; - } - - $starttime = wfTimestampNow(); - $adamsTime = wfTimestamp( TS_MW, (int)wfTimestamp( TS_UNIX, $starttime ) + (int)$adamsEdit['wpStarttime'] ); - $bertasTime = wfTimestamp( TS_MW, (int)wfTimestamp( TS_UNIX, $starttime ) + (int)$bertasEdit['wpStarttime'] ); - - $adamsEdit['wpStarttime'] = $adamsTime; - $bertasEdit['wpStarttime'] = $bertasTime; - - $adamsEdit['wpSummary'] = 'Adam\'s edit'; - $bertasEdit['wpSummary'] = 'Bertas\'s edit'; - - $adamsEdit['wpEdittime'] = $edittime; - $bertasEdit['wpEdittime'] = $edittime; - - // first edit - $this->assertEdit( 'EditPageTest_testAutoMerge', null, 'Adam', $adamsEdit, - EditPage::AS_SUCCESS_UPDATE, null, "expected successfull update" ); - - // second edit - $this->assertEdit( 'EditPageTest_testAutoMerge', null, 'Berta', $bertasEdit, - $expectedCode, $expectedText, $message ); - } -} diff --git a/tests/phpunit/includes/ExternalStoreTest.php b/tests/phpunit/includes/ExternalStoreTest.php deleted file mode 100644 index fcffcbc2..00000000 --- a/tests/phpunit/includes/ExternalStoreTest.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php -/** - * External Store tests - */ - -class ExternalStoreTest extends MediaWikiTestCase { - - public function testExternalFetchFromURL() { - $this->setMwGlobals( 'wgExternalStores', false ); - - $this->assertFalse( - ExternalStore::fetchFromURL( 'FOO://cluster1/200' ), - 'Deny if wgExternalStores is not set to a non-empty array' - ); - - $this->setMwGlobals( 'wgExternalStores', array( 'FOO' ) ); - - $this->assertEquals( - ExternalStore::fetchFromURL( 'FOO://cluster1/200' ), - 'Hello', - 'Allow FOO://cluster1/200' - ); - $this->assertEquals( - ExternalStore::fetchFromURL( 'FOO://cluster1/300/0' ), - 'Hello', - 'Allow FOO://cluster1/300/0' - ); - # Assertions for r68900 - $this->assertFalse( - ExternalStore::fetchFromURL( 'ftp.example.org' ), - 'Deny domain ftp.example.org' - ); - $this->assertFalse( - ExternalStore::fetchFromURL( '/example.txt' ), - 'Deny path /example.txt' - ); - $this->assertFalse( - ExternalStore::fetchFromURL( 'http://' ), - 'Deny protocol http://' - ); - } -} - -class ExternalStoreFOO { - - protected $data = array( - 'cluster1' => array( - '200' => 'Hello', - '300' => array( - 'Hello', 'World', - ), - ), - ); - - /** - * Fetch data from given URL - * @param $url String: an url of the form FOO://cluster/id or FOO://cluster/id/itemid. - * @return mixed - */ - function fetchFromURL( $url ) { - // Based on ExternalStoreDB - $path = explode( '/', $url ); - $cluster = $path[2]; - $id = $path[3]; - if ( isset( $path[4] ) ) { - $itemID = $path[4]; - } else { - $itemID = false; - } - - if ( !isset( $this->data[$cluster][$id] ) ) { - return null; - } - - if ( $itemID !== false && is_array( $this->data[$cluster][$id] ) && isset( $this->data[$cluster][$id][$itemID] ) ) { - return $this->data[$cluster][$id][$itemID]; - } - - return $this->data[$cluster][$id]; - } -} diff --git a/tests/phpunit/includes/ExtraParserTest.php b/tests/phpunit/includes/ExtraParserTest.php deleted file mode 100644 index 6c67beb1..00000000 --- a/tests/phpunit/includes/ExtraParserTest.php +++ /dev/null @@ -1,157 +0,0 @@ -<?php - -/** - * Parser-related tests that don't suit for parserTests.txt - */ -class ExtraParserTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - $contLang = Language::factory( 'en' ); - $this->setMwGlobals( array( - 'wgShowDBErrorBacktrace' => true, - 'wgLanguageCode' => 'en', - 'wgContLang' => $contLang, - 'wgLang' => Language::factory( 'en' ), - 'wgMemc' => new EmptyBagOStuff, - 'wgAlwaysUseTidy' => false, - 'wgCleanSignatures' => true, - ) ); - - $this->options = ParserOptions::newFromUserAndLang( new User, $contLang ); - $this->options->setTemplateCallback( array( __CLASS__, 'statelessFetchTemplate' ) ); - $this->parser = new Parser; - - MagicWord::clearCache(); - } - - // Bug 8689 - Long numeric lines kill the parser - public function testBug8689() { - global $wgUser; - $longLine = '1.' . str_repeat( '1234567890', 100000 ) . "\n"; - - $t = Title::newFromText( 'Unit test' ); - $options = ParserOptions::newFromUser( $wgUser ); - $this->assertEquals( "<p>$longLine</p>", - $this->parser->parse( $longLine, $t, $options )->getText() ); - } - - /* Test the parser entry points */ - 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() ); - } - - public function testPreSaveTransform() { - global $wgUser; - $title = Title::newFromText( __FUNCTION__ ); - $outputText = $this->parser->preSaveTransform( "Test\r\n{{subst:Foo}}\n{{Bar}}", $title, $wgUser, $this->options ); - - $this->assertEquals( "Test\nContent of ''Template:Foo''\n{{Bar}}", $outputText ); - } - - public function testPreprocess() { - $title = Title::newFromText( __FUNCTION__ ); - $outputText = $this->parser->preprocess( "Test\n{{Foo}}\n{{Bar}}", $title, $this->options ); - - $this->assertEquals( "Test\nContent of ''Template:Foo''\nContent of ''Template:Bar''", $outputText ); - } - - /** - * cleanSig() makes all templates substs and removes tildes - */ - public function testCleanSig() { - $title = Title::newFromText( __FUNCTION__ ); - $outputText = $this->parser->cleanSig( "{{Foo}} ~~~~" ); - - $this->assertEquals( "{{SUBST:Foo}} ", $outputText ); - } - - /** - * cleanSig() should do nothing if disabled - */ - public function testCleanSigDisabled() { - $this->setMwGlobals( 'wgCleanSignatures', false ); - - $title = Title::newFromText( __FUNCTION__ ); - $outputText = $this->parser->cleanSig( "{{Foo}} ~~~~" ); - - $this->assertEquals( "{{Foo}} ~~~~", $outputText ); - } - - /** - * cleanSigInSig() just removes tildes - * @dataProvider provideStringsForCleanSigInSig - */ - public function testCleanSigInSig( $in, $out ) { - $this->assertEquals( Parser::cleanSigInSig( $in ), $out ); - } - - public static function provideStringsForCleanSigInSig() { - return array( - array( "{{Foo}} ~~~~", "{{Foo}} " ), - array( "~~~", "" ), - array( "~~~~~", "" ), - ); - } - - 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 ); - - $this->assertEquals( "=== Heading 2 ===\nSection 2", $outputText2 ); - $this->assertEquals( "== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2", $outputText1 ); - } - - 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 ); - } - - /** - * Templates and comments are not affected, but noinclude/onlyinclude is. - */ - public function testGetPreloadText() { - $title = Title::newFromText( __FUNCTION__ ); - $outputText = $this->parser->getPreloadText( "{{Foo}}<noinclude> censored</noinclude> information <!-- is very secret -->", $title, $this->options ); - - $this->assertEquals( "{{Foo}} information <!-- is very secret -->", $outputText ); - } - - static function statelessFetchTemplate( $title, $parser = false ) { - $text = "Content of ''" . $title->getFullText() . "''"; - $deps = array(); - - return array( - 'text' => $text, - 'finalTitle' => $title, - 'deps' => $deps ); - } - - /** - * @group Database - */ - public function testTrackingCategory() { - $title = Title::newFromText( __FUNCTION__ ); - $catName = wfMessage( 'broken-file-category' )->inContentLanguage()->text(); - $cat = Title::makeTitleSafe( NS_CATEGORY, $catName ); - $expected = array( $cat->getDBkey() ); - $parserOutput = $this->parser->parse( "[[file:nonexistent]]", $title, $this->options ); - $result = $parserOutput->getCategoryLinks(); - $this->assertEquals( $expected, $result ); - } - - /** - * @group Database - */ - public function testTrackingCategorySpecial() { - // Special pages shouldn't have tracking cats. - $title = SpecialPage::getTitleFor( 'Contributions' ); - $parserOutput = $this->parser->parse( "[[file:nonexistent]]", $title, $this->options ); - $result = $parserOutput->getCategoryLinks(); - $this->assertEmpty( $result ); - } -} diff --git a/tests/phpunit/includes/FallbackTest.php b/tests/phpunit/includes/FallbackTest.php deleted file mode 100644 index f408f471..00000000 --- a/tests/phpunit/includes/FallbackTest.php +++ /dev/null @@ -1,73 +0,0 @@ -<?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 deleted file mode 100644 index 9f3aa11d..00000000 --- a/tests/phpunit/includes/FauxRequestTest.php +++ /dev/null @@ -1,15 +0,0 @@ -<?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 deleted file mode 100644 index f9ba1b3b..00000000 --- a/tests/phpunit/includes/FauxResponseTest.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php -/** - * Tests for the FauxResponse class - * - * Copyright @ 2011 Alexandre Emsenhuber - * - * 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 - */ - -class FauxResponseTest extends MediaWikiTestCase { - var $response; - - protected function setUp() { - parent::setUp(); - $this->response = new FauxResponse; - } - - 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' ); - } - - public function testHeader() { - $this->assertEquals( null, $this->response->getheader( 'Location' ), 'Non-existing header' ); - - $this->response->header( 'Location: http://localhost/' ); - $this->assertEquals( 'http://localhost/', $this->response->getheader( 'Location' ), 'Set header' ); - - $this->response->header( 'Location: http://127.0.0.1/' ); - $this->assertEquals( 'http://127.0.0.1/', $this->response->getheader( 'Location' ), 'Same header' ); - - $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' ); - } - - public function testResponseCode() { - $this->response->header( 'HTTP/1.1 200' ); - $this->assertEquals( 200, $this->response->getStatusCode(), 'Header with no message' ); - - $this->response->header( 'HTTP/1.x 201' ); - $this->assertEquals( 201, $this->response->getStatusCode(), 'Header with no message and protocol 1.x' ); - - $this->response->header( 'HTTP/1.1 202 OK' ); - $this->assertEquals( 202, $this->response->getStatusCode(), 'Normal header' ); - - $this->response->header( 'HTTP/1.x 203 OK' ); - $this->assertEquals( 203, $this->response->getStatusCode(), 'Normal header with no message and protocol 1.x' ); - - $this->response->header( 'HTTP/1.x 204 OK', false, 205 ); - $this->assertEquals( 205, $this->response->getStatusCode(), 'Third parameter overrides the HTTP/... header' ); - - $this->response->header( 'Location: http://localhost/', false, 206 ); - $this->assertEquals( 206, $this->response->getStatusCode(), 'Third parameter with another header' ); - } -} diff --git a/tests/phpunit/includes/FormOptionsInitializationTest.php b/tests/phpunit/includes/FormOptionsInitializationTest.php deleted file mode 100644 index fb2304dc..00000000 --- a/tests/phpunit/includes/FormOptionsInitializationTest.php +++ /dev/null @@ -1,84 +0,0 @@ -<?php -/** - * This file host two test case classes for the MediaWiki FormOptions class: - * - FormOptionsInitializationTest : tests initialization of the class. - * - FormOptionsTest : tests methods an on instance - * - * The split let us take advantage of setting up a fixture for the methods - * tests. - */ - -/** - * Dummy class to makes FormOptions::$options public. - * Used by FormOptionsInitializationTest which need to verify the $options - * array is correctly set through the FormOptions::add() function. - */ -class FormOptionsExposed extends FormOptions { - public function getOptions() { - return $this->options; - } -} - -/** - * Test class for FormOptions initialization - * Ensure the FormOptions::add() does what we want it to do. - * - * Generated by PHPUnit on 2011-02-28 at 20:46:27. - * - * Copyright © 2011, Antoine Musso - * - * @author Antoine Musso - */ -class FormOptionsInitializationTest extends MediaWikiTestCase { - /** - * @var FormOptions - */ - protected $object; - - - /** - * A new fresh and empty FormOptions object to test initialization - * with. - */ - protected function setUp() { - parent::setUp(); - $this->object = new FormOptionsExposed(); - } - - public function testAddStringOption() { - $this->object->add( 'foo', 'string value' ); - $this->assertEquals( - array( - 'foo' => array( - 'default' => 'string value', - 'consumed' => false, - 'type' => FormOptions::STRING, - 'value' => null, - ) - ), - $this->object->getOptions() - ); - } - - public function testAddIntegers() { - $this->object->add( 'one', 1 ); - $this->object->add( 'negone', -1 ); - $this->assertEquals( - array( - 'negone' => array( - 'default' => -1, - 'value' => null, - 'consumed' => false, - 'type' => FormOptions::INT, - ), - 'one' => array( - 'default' => 1, - 'value' => null, - 'consumed' => false, - 'type' => FormOptions::INT, - ) - ), - $this->object->getOptions() - ); - } -} diff --git a/tests/phpunit/includes/FormOptionsTest.php b/tests/phpunit/includes/FormOptionsTest.php deleted file mode 100644 index 0a13cfec..00000000 --- a/tests/phpunit/includes/FormOptionsTest.php +++ /dev/null @@ -1,91 +0,0 @@ -<?php -/** - * This file host two test case classes for the MediaWiki FormOptions class: - * - FormOptionsInitializationTest : tests initialization of the class. - * - FormOptionsTest : tests methods an on instance - * - * The split let us take advantage of setting up a fixture for the methods - * tests. - */ - -/** - * Test class for FormOptions methods. - * Generated by PHPUnit on 2011-02-28 at 20:46:27. - * - * Copyright © 2011, Antoine Musso - * - * @author Antoine Musso - */ -class FormOptionsTest extends MediaWikiTestCase { - /** - * @var FormOptions - */ - protected $object; - - /** - * Instanciates a FormOptions object to play with. - * FormOptions::add() is tested by the class FormOptionsInitializationTest - * so we assume the function is well tested already an use it to create - * the fixture. - */ - protected function setUp() { - parent::setUp(); - $this->object = new FormOptions; - $this->object->add( 'string1', 'string one' ); - $this->object->add( 'string2', 'string two' ); - $this->object->add( 'integer', 0 ); - $this->object->add( 'intnull', 0, FormOptions::INTNULL ); - } - - /** Helpers for testGuessType() */ - /* @{ */ - private function assertGuessBoolean( $data ) { - $this->guess( FormOptions::BOOL, $data ); - } - private function assertGuessInt( $data ) { - $this->guess( FormOptions::INT, $data ); - } - private function assertGuessString( $data ) { - $this->guess( FormOptions::STRING, $data ); - } - - /** Generic helper */ - private function guess( $expected, $data ) { - $this->assertEquals( - $expected, - FormOptions::guessType( $data ) - ); - } - /* @} */ - - /** - * Reuse helpers above assertGuessBoolean assertGuessInt assertGuessString - */ - public function testGuessTypeDetection() { - $this->assertGuessBoolean( true ); - $this->assertGuessBoolean( false ); - - $this->assertGuessInt( 0 ); - $this->assertGuessInt( -5 ); - $this->assertGuessInt( 5 ); - $this->assertGuessInt( 0x0F ); - - $this->assertGuessString( 'true' ); - $this->assertGuessString( 'false' ); - $this->assertGuessString( '5' ); - $this->assertGuessString( '0' ); - } - - /** - * @expectedException MWException - */ - public function testGuessTypeOnArrayThrowException() { - $this->object->guessType( array( 'foo' ) ); - } - /** - * @expectedException MWException - */ - public function testGuessTypeOnNullThrowException() { - $this->object->guessType( null ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/GlobalTest.php b/tests/phpunit/includes/GlobalFunctions/GlobalTest.php deleted file mode 100644 index 6154df1d..00000000 --- a/tests/phpunit/includes/GlobalFunctions/GlobalTest.php +++ /dev/null @@ -1,652 +0,0 @@ -<?php - -class GlobalTest extends MediaWikiTestCase { - protected function setUp() { - parent::setUp(); - - $readOnlyFile = tempnam( wfTempDir(), "mwtest_readonly" ); - unlink( $readOnlyFile ); - - $this->setMwGlobals( array( - 'wgReadOnlyFile' => $readOnlyFile, - 'wgUrlProtocols' => array( - 'http://', - 'https://', - 'mailto:', - '//', - 'file://', # Non-default - ), - ) ); - } - - protected function tearDown() { - global $wgReadOnlyFile; - - if ( file_exists( $wgReadOnlyFile ) ) { - unlink( $wgReadOnlyFile ); - } - - parent::tearDown(); - } - - /** - * @dataProvider provideForWfArrayDiff2 - * @covers ::wfArrayDiff2 - */ - public function testWfArrayDiff2( $a, $b, $expected ) { - $this->assertEquals( - wfArrayDiff2( $a, $b ), $expected - ); - } - - // @todo Provide more tests - public static function provideForWfArrayDiff2() { - // $a $b $expected - return array( - array( - array( 'a', 'b' ), - array( 'a', 'b' ), - array(), - ), - array( - array( array( 'a' ), array( 'a', 'b', 'c' ) ), - array( array( 'a' ), array( 'a', 'b' ) ), - array( 1 => array( 'a', 'b', 'c' ) ), - ), - ); - } - - /** - * @covers ::wfRandom - */ - public function testRandom() { - # This could hypothetically fail, but it shouldn't ;) - $this->assertFalse( - wfRandom() == wfRandom() ); - } - - /** - * @covers ::wfUrlencode - */ - public function testUrlencode() { - $this->assertEquals( - "%E7%89%B9%E5%88%A5:Contributions/Foobar", - wfUrlencode( "\xE7\x89\xB9\xE5\x88\xA5:Contributions/Foobar" ) ); - } - - /** - * @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" ) ); - } - - /** - * @covers ::wfReadOnly - */ - public function testReadOnlyEmpty() { - global $wgReadOnly; - $wgReadOnly = null; - - $this->assertFalse( wfReadOnly() ); - $this->assertFalse( wfReadOnly() ); - } - - /** - * @covers ::wfReadOnly - */ - public function testReadOnlySet() { - global $wgReadOnly, $wgReadOnlyFile; - - $f = fopen( $wgReadOnlyFile, "wt" ); - fwrite( $f, 'Message' ); - fclose( $f ); - $wgReadOnly = null; # Check on $wgReadOnlyFile - - $this->assertTrue( wfReadOnly() ); - $this->assertTrue( wfReadOnly() ); # Check cached - - unlink( $wgReadOnlyFile ); - $wgReadOnly = null; # Clean cache - - $this->assertFalse( wfReadOnly() ); - $this->assertFalse( wfReadOnly() ); - } - - public static function provideArrayToCGI() { - return array( - array( array(), '' ), // empty - array( array( 'foo' => 'bar' ), 'foo=bar' ), // string test - array( array( 'foo' => '' ), 'foo=' ), // empty string test - array( array( 'foo' => 1 ), 'foo=1' ), // number test - array( array( 'foo' => true ), 'foo=1' ), // true test - array( array( 'foo' => false ), '' ), // false test - array( array( 'foo' => null ), '' ), // null test - array( array( 'foo' => 'A&B=5+6@!"\'' ), 'foo=A%26B%3D5%2B6%40%21%22%27' ), // urlencoding test - array( array( 'foo' => 'bar', 'baz' => 'is', 'asdf' => 'qwerty' ), 'foo=bar&baz=is&asdf=qwerty' ), // multi-item test - array( array( 'foo' => array( 'bar' => 'baz' ) ), 'foo%5Bbar%5D=baz' ), - array( array( 'foo' => array( 'bar' => 'baz', 'qwerty' => 'asdf' ) ), 'foo%5Bbar%5D=baz&foo%5Bqwerty%5D=asdf' ), - array( array( 'foo' => array( 'bar', 'baz' ) ), 'foo%5B0%5D=bar&foo%5B1%5D=baz' ), - array( array( 'foo' => array( 'bar' => array( 'bar' => 'baz' ) ) ), 'foo%5Bbar%5D%5Bbar%5D=baz' ), - ); - } - - /** - * @dataProvider provideArrayToCGI - * @covers ::wfArrayToCgi - */ - public function testArrayToCGI( $array, $result ) { - $this->assertEquals( $result, wfArrayToCgi( $array ) ); - } - - - /** - * @covers ::testWfArrayDiff2 - */ - public function testArrayToCGI2() { - $this->assertEquals( - "baz=bar&foo=bar", - wfArrayToCgi( - array( 'baz' => 'bar' ), - array( 'foo' => 'bar', 'baz' => 'overridden value' ) ) ); - } - - public static function provideCgiToArray() { - return array( - array( '', array() ), // empty - array( 'foo=bar', array( 'foo' => 'bar' ) ), // string - array( 'foo=', array( 'foo' => '' ) ), // empty string - array( 'foo', array( 'foo' => '' ) ), // missing = - array( 'foo=bar&qwerty=asdf', array( 'foo' => 'bar', 'qwerty' => 'asdf' ) ), // multiple value - array( 'foo=A%26B%3D5%2B6%40%21%22%27', array( 'foo' => 'A&B=5+6@!"\'' ) ), // urldecoding test - array( 'foo%5Bbar%5D=baz', array( 'foo' => array( 'bar' => 'baz' ) ) ), - array( 'foo%5Bbar%5D=baz&foo%5Bqwerty%5D=asdf', array( 'foo' => array( 'bar' => 'baz', 'qwerty' => 'asdf' ) ) ), - array( 'foo%5B0%5D=bar&foo%5B1%5D=baz', array( 'foo' => array( 0 => 'bar', 1 => 'baz' ) ) ), - array( 'foo%5Bbar%5D%5Bbar%5D=baz', array( 'foo' => array( 'bar' => array( 'bar' => 'baz' ) ) ) ), - ); - } - - /** - * @dataProvider provideCgiToArray - * @covers ::wfCgiToArray - */ - public function testCgiToArray( $cgi, $result ) { - $this->assertEquals( $result, wfCgiToArray( $cgi ) ); - } - - public static function provideCgiRoundTrip() { - return array( - array( '' ), - array( 'foo=bar' ), - array( 'foo=' ), - array( 'foo=bar&baz=biz' ), - array( 'foo=A%26B%3D5%2B6%40%21%22%27' ), - array( 'foo%5Bbar%5D=baz' ), - array( 'foo%5B0%5D=bar&foo%5B1%5D=baz' ), - array( 'foo%5Bbar%5D%5Bbar%5D=baz' ), - ); - } - - /** - * @dataProvider provideCgiRoundTrip - * @covers ::wfArrayToCgi - */ - public function testCgiRoundTrip( $cgi ) { - $this->assertEquals( $cgi, wfArrayToCgi( wfCgiToArray( $cgi ) ) ); - } - - /** - * @covers ::mimeTypeMatch - */ - public function testMimeTypeMatch() { - $this->assertEquals( - 'text/html', - mimeTypeMatch( 'text/html', - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.7, - 'text/plain' => 0.3 ) ) ); - $this->assertEquals( - 'text/*', - mimeTypeMatch( 'text/html', - array( 'image/*' => 1.0, - 'text/*' => 0.5 ) ) ); - $this->assertEquals( - '*/*', - mimeTypeMatch( 'text/html', - array( '*/*' => 1.0 ) ) ); - $this->assertNull( - mimeTypeMatch( 'text/html', - array( 'image/png' => 1.0, - 'image/svg+xml' => 0.5 ) ) ); - } - - /** - * @covers ::wfNegotiateType - */ - public function testNegotiateType() { - $this->assertEquals( - 'text/html', - wfNegotiateType( - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.7, - 'text/plain' => 0.5, - 'text/*' => 0.2 ), - array( 'text/html' => 1.0 ) ) ); - $this->assertEquals( - 'application/xhtml+xml', - wfNegotiateType( - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.7, - 'text/plain' => 0.5, - 'text/*' => 0.2 ), - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.5 ) ) ); - $this->assertEquals( - 'text/html', - wfNegotiateType( - array( 'text/html' => 1.0, - 'text/plain' => 0.5, - 'text/*' => 0.5, - 'application/xhtml+xml' => 0.2 ), - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.5 ) ) ); - $this->assertEquals( - 'text/html', - wfNegotiateType( - array( 'text/*' => 1.0, - 'image/*' => 0.7, - '*/*' => 0.3 ), - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.5 ) ) ); - $this->assertNull( - wfNegotiateType( - array( 'text/*' => 1.0 ), - array( 'application/xhtml+xml' => 1.0 ) ) ); - } - - /** - * @covers ::wfDebug - * @covers ::wfDebugMem - */ - public function testDebugFunctionTest() { - - global $wgDebugLogFile, $wgDebugTimestamps; - - $old_log_file = $wgDebugLogFile; - $wgDebugLogFile = tempnam( wfTempDir(), 'mw-' ); - # @todo FIXME: $wgDebugTimestamps should be tested - $old_wgDebugTimestamps = $wgDebugTimestamps; - $wgDebugTimestamps = false; - - wfDebug( "This is a normal string" ); - $this->assertEquals( "This is a normal string", file_get_contents( $wgDebugLogFile ) ); - unlink( $wgDebugLogFile ); - - wfDebug( "This is nöt an ASCII string" ); - $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 ); - - wfDebugMem(); - $this->assertGreaterThan( 5000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) ); - unlink( $wgDebugLogFile ); - - wfDebugMem( true ); - $this->assertGreaterThan( 5000000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) ); - unlink( $wgDebugLogFile ); - - $wgDebugLogFile = $old_log_file; - $wgDebugTimestamps = $old_wgDebugTimestamps; - } - - /** - * @covers ::wfClientAcceptsGzip - */ - public function testClientAcceptsGzipTest() { - - $settings = array( - 'gzip' => true, - 'bzip' => false, - '*' => false, - 'compress, gzip' => true, - 'gzip;q=1.0' => true, - 'foozip' => false, - 'foo*zip' => false, - 'gzip;q=abcde' => true, //is this REALLY valid? - 'gzip;q=12345678.9' => true, - ' gzip' => true, - ); - - if ( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) { - $old_server_setting = $_SERVER['HTTP_ACCEPT_ENCODING']; - } - - foreach ( $settings as $encoding => $expect ) { - $_SERVER['HTTP_ACCEPT_ENCODING'] = $encoding; - - $this->assertEquals( $expect, wfClientAcceptsGzip( true ), - "'$encoding' => " . wfBoolToStr( $expect ) ); - } - - if ( isset( $old_server_setting ) ) { - $_SERVER['HTTP_ACCEPT_ENCODING'] = $old_server_setting; - } - } - - /** - * @covers ::swap - */ - public function testSwapVarsTest() { - $var1 = 1; - $var2 = 2; - - $this->assertEquals( $var1, 1, 'var1 is set originally' ); - $this->assertEquals( $var2, 2, 'var1 is set originally' ); - - swap( $var1, $var2 ); - - $this->assertEquals( $var1, 2, 'var1 is swapped' ); - $this->assertEquals( $var2, 1, 'var2 is swapped' ); - } - - /** - * @covers ::wfPercent - */ - public function testWfPercentTest() { - - $pcts = array( - array( 6 / 7, '0.86%', 2, false ), - array( 3 / 3, '1%' ), - array( 22 / 7, '3.14286%', 5 ), - array( 3 / 6, '0.5%' ), - array( 1 / 3, '0%', 0 ), - array( 10 / 3, '0%', -1 ), - array( 3 / 4 / 5, '0.1%', 1 ), - array( 6 / 7 * 8, '6.8571428571%', 10 ), - ); - - foreach ( $pcts as $pct ) { - if ( !isset( $pct[2] ) ) { - $pct[2] = 2; - } - if ( !isset( $pct[3] ) ) { - $pct[3] = true; - } - - $this->assertEquals( wfPercent( $pct[0], $pct[2], $pct[3] ), $pct[1], $pct[1] ); - } - } - - /** - * test @see wfShorthandToInteger() - * @dataProvider provideShorthand - * @covers ::wfShorthandToInteger - */ - public function testWfShorthandToInteger( $shorthand, $expected ) { - $this->assertEquals( $expected, - wfShorthandToInteger( $shorthand ) - ); - } - - /** array( shorthand, expected integer ) */ - public static function provideShorthand() { - return array( - # Null, empty ... - array( '', -1 ), - array( ' ', -1 ), - array( null, -1 ), - - # Failures returns 0 :( - array( 'ABCDEFG', 0 ), - array( 'Ak', 0 ), - - # Int, strings with spaces - array( 1, 1 ), - array( ' 1 ', 1 ), - array( 1023, 1023 ), - array( ' 1023 ', 1023 ), - - # kilo, Mega, Giga - array( '1k', 1024 ), - array( '1K', 1024 ), - array( '1m', 1024 * 1024 ), - array( '1M', 1024 * 1024 ), - array( '1g', 1024 * 1024 * 1024 ), - array( '1G', 1024 * 1024 * 1024 ), - - # Negatives - array( -1, -1 ), - array( -500, -500 ), - array( '-500', -500 ), - array( '-1k', -1024 ), - - # Zeroes - array( '0', 0 ), - array( '0k', 0 ), - array( '0M', 0 ), - array( '0G', 0 ), - array( '-0', 0 ), - array( '-0k', 0 ), - array( '-0M', 0 ), - array( '-0G', 0 ), - ); - } - - /** - * @param String $old: Text as it was in the database - * @param String $mine: Text submitted while user was editing - * @param String $yours: Text submitted by the user - * @param Boolean $expectedMergeResult Whether the merge should be a success - * @param String $expectedText: Text after merge has been completed - * - * @dataProvider provideMerge() - * @group medium - * @covers ::wfMerge - */ - public function testMerge( $old, $mine, $yours, $expectedMergeResult, $expectedText ) { - $this->checkHasDiff3(); - - $mergedText = null; - $isMerged = wfMerge( $old, $mine, $yours, $mergedText ); - - $msg = 'Merge should be a '; - $msg .= $expectedMergeResult ? 'success' : 'failure'; - $this->assertEquals( $expectedMergeResult, $isMerged, $msg ); - - if ( $isMerged ) { - // Verify the merged text - $this->assertEquals( $expectedText, $mergedText, - 'is merged text as expected?' ); - } - } - - public static function provideMerge() { - $EXPECT_MERGE_SUCCESS = true; - $EXPECT_MERGE_FAILURE = false; - - return array( - // #0: clean merge - array( - // old: - "one one one\n" . // trimmed - "\n" . - "two two two", - - // mine: - "one one one ONE ONE\n" . - "\n" . - "two two two\n", // with tailing whitespace - - // yours: - "one one one\n" . - "\n" . - "two two TWO TWO", // trimmed - - // ok: - $EXPECT_MERGE_SUCCESS, - - // result: - "one one one ONE ONE\n" . - "\n" . - "two two TWO TWO\n", // note: will always end in a newline - ), - - // #1: conflict, fail - array( - // old: - "one one one", // trimmed - - // mine: - "one one one ONE ONE\n" . - "\n" . - "bla bla\n" . - "\n", // with tailing whitespace - - // yours: - "one one one\n" . - "\n" . - "two two", // trimmed - - $EXPECT_MERGE_FAILURE, - - // result: - null, - ), - ); - } - - /** - * @dataProvider provideMakeUrlIndexes() - * @covers ::wfMakeUrlIndexes - */ - public function testMakeUrlIndexes( $url, $expected ) { - $index = wfMakeUrlIndexes( $url ); - $this->assertEquals( $expected, $index, "wfMakeUrlIndexes(\"$url\")" ); - } - - public static function provideMakeUrlIndexes() { - return array( - array( - // just a regular :) - 'https://bugzilla.wikimedia.org/show_bug.cgi?id=28627', - array( 'https://org.wikimedia.bugzilla./show_bug.cgi?id=28627' ) - ), - array( - // mailtos are handled special - // is this really right though? that final . probably belongs earlier? - 'mailto:wiki@wikimedia.org', - array( 'mailto:org.wikimedia@wiki.' ) - ), - - // file URL cases per bug 28627... - array( - // three slashes: local filesystem path Unix-style - 'file:///whatever/you/like.txt', - array( 'file://./whatever/you/like.txt' ) - ), - array( - // three slashes: local filesystem path Windows-style - 'file:///c:/whatever/you/like.txt', - array( 'file://./c:/whatever/you/like.txt' ) - ), - array( - // two slashes: UNC filesystem path Windows-style - 'file://intranet/whatever/you/like.txt', - array( 'file://intranet./whatever/you/like.txt' ) - ), - // Multiple-slash cases that can sorta work on Mozilla - // if you hack it just right are kinda pathological, - // and unreliable cross-platform or on IE which means they're - // unlikely to appear on intranets. - // - // Those will survive the algorithm but with results that - // are less consistent. - - // protocol-relative URL cases per bug 29854... - array( - '//bugzilla.wikimedia.org/show_bug.cgi?id=28627', - array( - 'http://org.wikimedia.bugzilla./show_bug.cgi?id=28627', - 'https://org.wikimedia.bugzilla./show_bug.cgi?id=28627' - ) - ), - ); - } - - /** - * @dataProvider provideWfMatchesDomainList - * @covers ::wfMatchesDomainList - */ - public function testWfMatchesDomainList( $url, $domains, $expected, $description ) { - $actual = wfMatchesDomainList( $url, $domains ); - $this->assertEquals( $expected, $actual, $description ); - } - - public static function provideWfMatchesDomainList() { - $a = array(); - $protocols = array( 'HTTP' => 'http:', 'HTTPS' => 'https:', 'protocol-relative' => '' ); - foreach ( $protocols as $pDesc => $p ) { - $a = array_merge( $a, array( - array( "$p//www.example.com", array(), false, "No matches for empty domains array, $pDesc URL" ), - array( "$p//www.example.com", array( 'www.example.com' ), true, "Exact match in domains array, $pDesc URL" ), - array( "$p//www.example.com", array( 'example.com' ), true, "Match without subdomain in domains array, $pDesc URL" ), - 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" ), - 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 - */ - public function testWfShellMaintenanceCmd( $script, $parameters, $options, $expected, $description ) { - if ( wfIsWindows() ) { - // Approximation that's good enough for our purposes just now - $expected = str_replace( "'", '"', $expected ); - } - $actual = wfShellMaintenanceCmd( $script, $parameters, $options ); - $this->assertEquals( $expected, $actual, $description ); - } - - public static function provideWfShellMaintenanceCmdList() { - global $wgPhpCli; - - return array( - array( 'eval.php', array( '--help', '--test' ), array(), - "'$wgPhpCli' 'eval.php' '--help' '--test'", - "Called eval.php --help --test" ), - array( 'eval.php', array( '--help', '--test space' ), array( 'php' => 'php5' ), - "'php5' 'eval.php' '--help' '--test space'", - "Called eval.php --help --test with php option" ), - array( 'eval.php', array( '--help', '--test', 'X' ), array( 'wrapper' => 'MWScript.php' ), - "'$wgPhpCli' 'MWScript.php' 'eval.php' '--help' '--test' 'X'", - "Called eval.php --help --test with wrapper option" ), - array( 'eval.php', array( '--help', '--test', 'y' ), array( 'php' => 'php5', 'wrapper' => 'MWScript.php' ), - "'php5' 'MWScript.php' 'eval.php' '--help' '--test' 'y'", - "Called eval.php --help --test with wrapper and php option" ), - ); - } - /* @TODO many more! */ -} diff --git a/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php b/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php deleted file mode 100644 index cf891e7b..00000000 --- a/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php - -/** - * @group Database - */ -class GlobalWithDBTest extends MediaWikiTestCase { - /** - * @dataProvider provideWfIsBadImageList - * @covers ::wfIsBadImage - */ - public function testWfIsBadImage( $name, $title, $blacklist, $expected, $desc ) { - $this->assertEquals( $expected, wfIsBadImage( $name, $title, $blacklist ), $desc ); - } - - public static function provideWfIsBadImageList() { - $blacklist = '* [[File:Bad.jpg]] except [[Nasty page]]'; - - return array( - array( 'Bad.jpg', false, $blacklist, true, - 'Called on a bad image' ), - array( 'Bad.jpg', Title::makeTitle( NS_MAIN, 'A page' ), $blacklist, true, - 'Called on a bad image' ), - array( 'NotBad.jpg', false, $blacklist, false, - 'Called on a non-bad image' ), - array( 'Bad.jpg', Title::makeTitle( NS_MAIN, 'Nasty page' ), $blacklist, false, - 'Called on a bad image but is on a whitelisted page' ), - array( 'File:Bad.jpg', false, $blacklist, false, - 'Called on a bad image with File:' ), - ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/README b/tests/phpunit/includes/GlobalFunctions/README deleted file mode 100644 index 0042bdac..00000000 --- a/tests/phpunit/includes/GlobalFunctions/README +++ /dev/null @@ -1,2 +0,0 @@ -This directory hold tests for includes/GlobalFunctions.php file -which is a pile of functions. diff --git a/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php deleted file mode 100644 index 9bb74873..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php -/** - * @covers ::wfAssembleUrl - */ -class WfAssembleUrlTest extends MediaWikiTestCase { - /** - * @dataProvider provideURLParts - */ - public function testWfAssembleUrl( $parts, $output ) { - $partsDump = print_r( $parts, true ); - $this->assertEquals( - $output, - wfAssembleUrl( $parts ), - "Testing $partsDump assembles to $output" - ); - } - - /** - * Provider of URL parts for testing wfAssembleUrl() - * - * @return array - */ - public static function provideURLParts() { - $schemes = array( - '' => array(), - '//' => array( - 'delimiter' => '//', - ), - 'http://' => array( - 'scheme' => 'http', - 'delimiter' => '://', - ), - ); - - $hosts = array( - '' => array(), - 'example.com' => array( - 'host' => 'example.com', - ), - 'example.com:123' => array( - 'host' => 'example.com', - 'port' => 123, - ), - 'id@example.com' => array( - 'user' => 'id', - 'host' => 'example.com', - ), - 'id@example.com:123' => array( - 'user' => 'id', - 'host' => 'example.com', - 'port' => 123, - ), - 'id:key@example.com' => array( - 'user' => 'id', - 'pass' => 'key', - 'host' => 'example.com', - ), - 'id:key@example.com:123' => array( - 'user' => 'id', - 'pass' => 'key', - 'host' => 'example.com', - 'port' => 123, - ), - ); - - $cases = array(); - foreach ( $schemes as $scheme => $schemeParts ) { - foreach ( $hosts as $host => $hostParts ) { - foreach ( array( '', '/path' ) as $path ) { - foreach ( array( '', 'query' ) as $query ) { - foreach ( array( '', 'fragment' ) as $fragment ) { - $parts = array_merge( - $schemeParts, - $hostParts - ); - $url = $scheme . - $host . - $path; - - if ( $path ) { - $parts['path'] = $path; - } - if ( $query ) { - $parts['query'] = $query; - $url .= '?' . $query; - } - if ( $fragment ) { - $parts['fragment'] = $fragment; - $url .= '#' . $fragment; - } - - $cases[] = array( - $parts, - $url, - ); - } - } - } - } - } - - $complexURL = 'http://id:key@example.org:321' . - '/over/there?name=ferret&foo=bar#nose'; - $cases[] = array( - wfParseUrl( $complexURL ), - $complexURL, - ); - - return $cases; - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php b/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php deleted file mode 100644 index a01c0d49..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php +++ /dev/null @@ -1,120 +0,0 @@ -<?php -/** - * @covers ::wfBCP47 - */ -class WfBCP47Test extends MediaWikiTestCase { - /** - * test @see wfBCP47(). - * Please note the BCP explicitly state that language codes are case - * insensitive, there are some exceptions to the rule :) - * This test is used to verify our formatting against all lower and - * all upper cases language code. - * - * @see http://tools.ietf.org/html/bcp47 - * @dataProvider provideLanguageCodes() - */ - public function testBCP47( $code, $expected ) { - $code = strtolower( $code ); - $this->assertEquals( $expected, wfBCP47( $code ), - "Applying BCP47 standard to lower case '$code'" - ); - - $code = strtoupper( $code ); - $this->assertEquals( $expected, wfBCP47( $code ), - "Applying BCP47 standard to upper case '$code'" - ); - } - - /** - * Array format is ($code, $expected) - */ - public static function provideLanguageCodes() { - return array( - // Extracted from BCP47 (list not exhaustive) - # 2.1.1 - array( 'en-ca-x-ca', 'en-CA-x-ca' ), - array( 'sgn-be-fr', 'sgn-BE-FR' ), - array( 'az-latn-x-latn', 'az-Latn-x-latn' ), - # 2.2 - array( 'sr-Latn-RS', 'sr-Latn-RS' ), - array( 'az-arab-ir', 'az-Arab-IR' ), - - # 2.2.5 - array( 'sl-nedis', 'sl-nedis' ), - array( 'de-ch-1996', 'de-CH-1996' ), - - # 2.2.6 - array( - 'en-latn-gb-boont-r-extended-sequence-x-private', - 'en-Latn-GB-boont-r-extended-sequence-x-private' - ), - - // Examples from BCP47 Appendix A - # Simple language subtag: - array( 'DE', 'de' ), - array( 'fR', 'fr' ), - array( 'ja', 'ja' ), - - # Language subtag plus script subtag: - array( 'zh-hans', 'zh-Hans' ), - array( 'sr-cyrl', 'sr-Cyrl' ), - array( 'sr-latn', 'sr-Latn' ), - - # Extended language subtags and their primary language subtag - # counterparts: - array( 'zh-cmn-hans-cn', 'zh-cmn-Hans-CN' ), - array( 'cmn-hans-cn', 'cmn-Hans-CN' ), - array( 'zh-yue-hk', 'zh-yue-HK' ), - array( 'yue-hk', 'yue-HK' ), - - # Language-Script-Region: - array( 'zh-hans-cn', 'zh-Hans-CN' ), - array( 'sr-latn-RS', 'sr-Latn-RS' ), - - # Language-Variant: - array( 'sl-rozaj', 'sl-rozaj' ), - array( 'sl-rozaj-biske', 'sl-rozaj-biske' ), - array( 'sl-nedis', 'sl-nedis' ), - - # Language-Region-Variant: - array( 'de-ch-1901', 'de-CH-1901' ), - array( 'sl-it-nedis', 'sl-IT-nedis' ), - - # Language-Script-Region-Variant: - array( 'hy-latn-it-arevela', 'hy-Latn-IT-arevela' ), - - # Language-Region: - array( 'de-de', 'de-DE' ), - array( 'en-us', 'en-US' ), - array( 'es-419', 'es-419' ), - - # Private use subtags: - array( 'de-ch-x-phonebk', 'de-CH-x-phonebk' ), - array( 'az-arab-x-aze-derbend', 'az-Arab-x-aze-derbend' ), - /** - * Previous test does not reflect the BCP which states: - * az-Arab-x-AZE-derbend - * AZE being private, it should be lower case, hence the test above - * should probably be: - #array( 'az-arab-x-aze-derbend', 'az-Arab-x-AZE-derbend' ), - */ - - # Private use registry values: - array( 'x-whatever', 'x-whatever' ), - array( 'qaa-qaaa-qm-x-southern', 'qaa-Qaaa-QM-x-southern' ), - array( 'de-qaaa', 'de-Qaaa' ), - array( 'sr-latn-qm', 'sr-Latn-QM' ), - array( 'sr-qaaa-rs', 'sr-Qaaa-RS' ), - - # Tags that use extensions - array( 'en-us-u-islamcal', 'en-US-u-islamcal' ), - array( 'zh-cn-a-myext-x-private', 'zh-CN-a-myext-x-private' ), - array( 'en-a-myext-b-another', 'en-a-myext-b-another' ), - - # Invalid: - // de-419-DE - // a-DE - // ar-a-aaa-b-bbb-a-ccc - ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php b/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php deleted file mode 100644 index 7da804e6..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php +++ /dev/null @@ -1,182 +0,0 @@ -<?php -/** - * @covers ::wfBaseConvert - */ -class WfBaseConvertTest extends MediaWikiTestCase { - public static function provideSingleDigitConversions() { - return array( - // 2 3 5 8 10 16 36 - array( '0', '0', '0', '0', '0', '0', '0' ), - array( '1', '1', '1', '1', '1', '1', '1' ), - array( '10', '2', '2', '2', '2', '2', '2' ), - array( '11', '10', '3', '3', '3', '3', '3' ), - array( '100', '11', '4', '4', '4', '4', '4' ), - array( '101', '12', '10', '5', '5', '5', '5' ), - array( '110', '20', '11', '6', '6', '6', '6' ), - array( '111', '21', '12', '7', '7', '7', '7' ), - array( '1000', '22', '13', '10', '8', '8', '8' ), - array( '1001', '100', '14', '11', '9', '9', '9' ), - array( '1010', '101', '20', '12', '10', 'a', 'a' ), - array( '1011', '102', '21', '13', '11', 'b', 'b' ), - array( '1100', '110', '22', '14', '12', 'c', 'c' ), - array( '1101', '111', '23', '15', '13', 'd', 'd' ), - array( '1110', '112', '24', '16', '14', 'e', 'e' ), - array( '1111', '120', '30', '17', '15', 'f', 'f' ), - array( '10000', '121', '31', '20', '16', '10', 'g' ), - array( '10001', '122', '32', '21', '17', '11', 'h' ), - array( '10010', '200', '33', '22', '18', '12', 'i' ), - array( '10011', '201', '34', '23', '19', '13', 'j' ), - array( '10100', '202', '40', '24', '20', '14', 'k' ), - array( '10101', '210', '41', '25', '21', '15', 'l' ), - array( '10110', '211', '42', '26', '22', '16', 'm' ), - array( '10111', '212', '43', '27', '23', '17', 'n' ), - array( '11000', '220', '44', '30', '24', '18', 'o' ), - array( '11001', '221', '100', '31', '25', '19', 'p' ), - array( '11010', '222', '101', '32', '26', '1a', 'q' ), - array( '11011', '1000', '102', '33', '27', '1b', 'r' ), - array( '11100', '1001', '103', '34', '28', '1c', 's' ), - array( '11101', '1002', '104', '35', '29', '1d', 't' ), - array( '11110', '1010', '110', '36', '30', '1e', 'u' ), - array( '11111', '1011', '111', '37', '31', '1f', 'v' ), - array( '100000', '1012', '112', '40', '32', '20', 'w' ), - array( '100001', '1020', '113', '41', '33', '21', 'x' ), - array( '100010', '1021', '114', '42', '34', '22', 'y' ), - array( '100011', '1022', '120', '43', '35', '23', 'z' ) - ); - } - - /** - * @dataProvider provideSingleDigitConversions - */ - public function testDigitToBase2( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) { - $this->assertSame( $base2, wfBaseConvert( $base3, '3', '2' ) ); - $this->assertSame( $base2, wfBaseConvert( $base5, '5', '2' ) ); - $this->assertSame( $base2, wfBaseConvert( $base8, '8', '2' ) ); - $this->assertSame( $base2, wfBaseConvert( $base10, '10', '2' ) ); - $this->assertSame( $base2, wfBaseConvert( $base16, '16', '2' ) ); - $this->assertSame( $base2, wfBaseConvert( $base36, '36', '2' ) ); - } - - /** - * @dataProvider provideSingleDigitConversions - */ - public function testDigitToBase3( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) { - $this->assertSame( $base3, wfBaseConvert( $base2, '2', '3' ) ); - $this->assertSame( $base3, wfBaseConvert( $base5, '5', '3' ) ); - $this->assertSame( $base3, wfBaseConvert( $base8, '8', '3' ) ); - $this->assertSame( $base3, wfBaseConvert( $base10, '10', '3' ) ); - $this->assertSame( $base3, wfBaseConvert( $base16, '16', '3' ) ); - $this->assertSame( $base3, wfBaseConvert( $base36, '36', '3' ) ); - } - - /** - * @dataProvider provideSingleDigitConversions - */ - public function testDigitToBase5( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) { - $this->assertSame( $base5, wfBaseConvert( $base2, '2', '5' ) ); - $this->assertSame( $base5, wfBaseConvert( $base3, '3', '5' ) ); - $this->assertSame( $base5, wfBaseConvert( $base8, '8', '5' ) ); - $this->assertSame( $base5, wfBaseConvert( $base10, '10', '5' ) ); - $this->assertSame( $base5, wfBaseConvert( $base16, '16', '5' ) ); - $this->assertSame( $base5, wfBaseConvert( $base36, '36', '5' ) ); - } - - /** - * @dataProvider provideSingleDigitConversions - */ - public function testDigitToBase8( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) { - $this->assertSame( $base8, wfBaseConvert( $base2, '2', '8' ) ); - $this->assertSame( $base8, wfBaseConvert( $base3, '3', '8' ) ); - $this->assertSame( $base8, wfBaseConvert( $base5, '5', '8' ) ); - $this->assertSame( $base8, wfBaseConvert( $base10, '10', '8' ) ); - $this->assertSame( $base8, wfBaseConvert( $base16, '16', '8' ) ); - $this->assertSame( $base8, wfBaseConvert( $base36, '36', '8' ) ); - } - - /** - * @dataProvider provideSingleDigitConversions - */ - public function testDigitToBase10( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) { - $this->assertSame( $base10, wfBaseConvert( $base2, '2', '10' ) ); - $this->assertSame( $base10, wfBaseConvert( $base3, '3', '10' ) ); - $this->assertSame( $base10, wfBaseConvert( $base5, '5', '10' ) ); - $this->assertSame( $base10, wfBaseConvert( $base8, '8', '10' ) ); - $this->assertSame( $base10, wfBaseConvert( $base16, '16', '10' ) ); - $this->assertSame( $base10, wfBaseConvert( $base36, '36', '10' ) ); - } - - /** - * @dataProvider provideSingleDigitConversions - */ - public function testDigitToBase16( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) { - $this->assertSame( $base16, wfBaseConvert( $base2, '2', '16' ) ); - $this->assertSame( $base16, wfBaseConvert( $base3, '3', '16' ) ); - $this->assertSame( $base16, wfBaseConvert( $base5, '5', '16' ) ); - $this->assertSame( $base16, wfBaseConvert( $base8, '8', '16' ) ); - $this->assertSame( $base16, wfBaseConvert( $base10, '10', '16' ) ); - $this->assertSame( $base16, wfBaseConvert( $base36, '36', '16' ) ); - } - - /** - * @dataProvider provideSingleDigitConversions - */ - public function testDigitToBase36( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) { - $this->assertSame( $base36, wfBaseConvert( $base2, '2', '36' ) ); - $this->assertSame( $base36, wfBaseConvert( $base3, '3', '36' ) ); - $this->assertSame( $base36, wfBaseConvert( $base5, '5', '36' ) ); - $this->assertSame( $base36, wfBaseConvert( $base8, '8', '36' ) ); - $this->assertSame( $base36, wfBaseConvert( $base10, '10', '36' ) ); - $this->assertSame( $base36, wfBaseConvert( $base16, '16', '36' ) ); - } - - public function testLargeNumber() { - $this->assertSame( '1100110001111010000000101110100', wfBaseConvert( 'sd89ys', 36, 2 ) ); - $this->assertSame( '11102112120221201101', wfBaseConvert( 'sd89ys', 36, 3 ) ); - $this->assertSame( '12003102232400', wfBaseConvert( 'sd89ys', 36, 5 ) ); - $this->assertSame( '14617200564', wfBaseConvert( 'sd89ys', 36, 8 ) ); - $this->assertSame( '1715274100', wfBaseConvert( 'sd89ys', 36, 10 ) ); - $this->assertSame( '663d0174', wfBaseConvert( 'sd89ys', 36, 16 ) ); - } - - public static function provideNumbers() { - $x = array(); - $chars = '0123456789abcdefghijklmnopqrstuvwxyz'; - for ( $i = 0; $i < 50; $i++ ) { - $base = mt_rand( 2, 36 ); - $len = mt_rand( 10, 100 ); - - $str = ''; - for ( $j = 0; $j < $len; $j++ ) { - $str .= $chars[mt_rand( 0, $base - 1 )]; - } - - $x[] = array( $base, $str ); - } - - return $x; - } - - /** - * @dataProvider provideNumbers - */ - public function testIdentity( $base, $number ) { - $this->assertSame( $number, wfBaseConvert( $number, $base, $base, strlen( $number ) ) ); - } - - public function testInvalid() { - $this->assertFalse( wfBaseConvert( '101', 1, 15 ) ); - $this->assertFalse( wfBaseConvert( '101', 15, 1 ) ); - $this->assertFalse( wfBaseConvert( '101', 37, 15 ) ); - $this->assertFalse( wfBaseConvert( '101', 15, 37 ) ); - $this->assertFalse( wfBaseConvert( 'abcde', 10, 11 ) ); - $this->assertFalse( wfBaseConvert( '12930', 2, 10 ) ); - $this->assertFalse( wfBaseConvert( '101', 'abc', 15 ) ); - $this->assertFalse( wfBaseConvert( '101', 15, 'abc' ) ); - } - - public function testPadding() { - $number = "10101010101"; - $this->assertSame( strlen( $number ) + 5, strlen( wfBaseConvert( $number, 2, 2, strlen( $number ) + 5 ) ) ); - $this->assertSame( strlen( $number ), strlen( wfBaseConvert( $number, 2, 2, strlen( $number ) - 5 ) ) ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php b/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php deleted file mode 100644 index 8c548040..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php -/** - * @covers ::wfBaseName - */ -class WfBaseNameTest extends MediaWikiTestCase { - /** - * @dataProvider providePaths - */ - public function testBaseName( $fullpath, $basename ) { - $this->assertEquals( $basename, wfBaseName( $fullpath ), - "wfBaseName('$fullpath') => '$basename'" ); - } - - public static function providePaths() { - return array( - array( '', '' ), - array( '/', '' ), - array( '\\', '' ), - array( '//', '' ), - array( '\\\\', '' ), - array( 'a', 'a' ), - array( 'aaaa', 'aaaa' ), - array( '/a', 'a' ), - array( '\\a', 'a' ), - array( '/aaaa', 'aaaa' ), - array( '\\aaaa', 'aaaa' ), - array( '/aaaa/', 'aaaa' ), - array( '\\aaaa\\', 'aaaa' ), - array( '\\aaaa\\', 'aaaa' ), - array( '/mnt/upload3/wikipedia/en/thumb/8/8b/Zork_Grand_Inquisitor_box_cover.jpg/93px-Zork_Grand_Inquisitor_box_cover.jpg', - '93px-Zork_Grand_Inquisitor_box_cover.jpg' ), - array( 'C:\\Progra~1\\Wikime~1\\Wikipe~1\\VIEWER.EXE', 'VIEWER.EXE' ), - array( 'Östergötland_coat_of_arms.png', 'Östergötland_coat_of_arms.png' ), - ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php deleted file mode 100644 index 41230a1e..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php -/** - * @covers ::wfExpandUrl - */ -class WfExpandUrlTest extends MediaWikiTestCase { - /** - * @dataProvider provideExpandableUrls - */ - public function testWfExpandUrl( $fullUrl, $shortUrl, $defaultProto, $server, $canServer, $httpsMode, $message ) { - // Fake $wgServer and $wgCanonicalServer - $this->setMwGlobals( array( - 'wgServer' => $server, - 'wgCanonicalServer' => $canServer, - ) ); - - // Fake $_SERVER['HTTPS'] if needed - if ( $httpsMode ) { - $_SERVER['HTTPS'] = 'on'; - } else { - unset( $_SERVER['HTTPS'] ); - } - - $this->assertEquals( $fullUrl, wfExpandUrl( $shortUrl, $defaultProto ), $message ); - } - - /** - * Provider of URL examples for testing wfExpandUrl() - * - * @return array - */ - public static function provideExpandableUrls() { - $modes = array( 'http', 'https' ); - $servers = array( - 'http' => 'http://example.com', - 'https' => 'https://example.com', - 'protocol-relative' => '//example.com' - ); - $defaultProtos = array( - 'http' => PROTO_HTTP, - 'https' => PROTO_HTTPS, - 'protocol-relative' => PROTO_RELATIVE, - 'current' => PROTO_CURRENT, - 'canonical' => PROTO_CANONICAL - ); - - $retval = array(); - foreach ( $modes as $mode ) { - $httpsMode = $mode == 'https'; - foreach ( $servers as $serverDesc => $server ) { - foreach ( $modes as $canServerMode ) { - $canServer = "$canServerMode://example2.com"; - foreach ( $defaultProtos as $protoDesc => $defaultProto ) { - $retval[] = array( - 'http://example.com', 'http://example.com', - $defaultProto, $server, $canServer, $httpsMode, - "Testing fully qualified http URLs (no need to expand) ' . - '(defaultProto: $protoDesc , wgServer: $server, wgCanonicalServer: $canServer, current request protocol: $mode )" - ); - $retval[] = array( - 'https://example.com', 'https://example.com', - $defaultProto, $server, $canServer, $httpsMode, - "Testing fully qualified https URLs (no need to expand) ' . - '(defaultProto: $protoDesc , wgServer: $server, wgCanonicalServer: $canServer, current request protocol: $mode )" - ); - # Would be nice to support this, see fixme on wfExpandUrl() - $retval[] = array( - "wiki/FooBar", 'wiki/FooBar', - $defaultProto, $server, $canServer, $httpsMode, - "Test non-expandable relative URLs ' . - '(defaultProto: $protoDesc , wgServer: $server, wgCanonicalServer: $canServer, current request protocol: $mode )" - ); - - // Determine expected protocol - if ( $protoDesc == 'protocol-relative' ) { - $p = ''; - } elseif ( $protoDesc == 'current' ) { - $p = "$mode:"; - } elseif ( $protoDesc == 'canonical' ) { - $p = "$canServerMode:"; - } else { - $p = $protoDesc . ':'; - } - // Determine expected server name - if ( $protoDesc == 'canonical' ) { - $srv = $canServer; - } elseif ( $serverDesc == 'protocol-relative' ) { - $srv = $p . $server; - } else { - $srv = $server; - } - - $retval[] = array( - "$p//wikipedia.org", '//wikipedia.org', - $defaultProto, $server, $canServer, $httpsMode, - "Test protocol-relative URL ' . - '(defaultProto: $protoDesc, wgServer: $server, wgCanonicalServer: $canServer, current request protocol: $mode )" - ); - $retval[] = array( - "$srv/wiki/FooBar", '/wiki/FooBar', - $defaultProto, $server, $canServer, $httpsMode, - "Testing expanding URL beginning with / ' . - '(defaultProto: $protoDesc , wgServer: $server, wgCanonicalServer: $canServer, current request protocol: $mode )" - ); - } - } - } - } - - return $retval; - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php b/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php deleted file mode 100644 index 62296245..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php - -/** - * @covers ::wfGetCaller - */ -class WfGetCallerTest extends MediaWikiTestCase { - - public function testZero() { - $this->assertEquals( __METHOD__, wfGetCaller( 1 ) ); - } - - function callerOne() { - return wfGetCaller(); - } - - public function testOne() { - $this->assertEquals( 'WfGetCallerTest::testOne', self::callerOne() ); - } - - function intermediateFunction( $level = 2, $n = 0 ) { - if ( $n > 0 ) { - return self::intermediateFunction( $level, $n - 1 ); - } - - return wfGetCaller( $level ); - } - - public function testTwo() { - $this->assertEquals( 'WfGetCallerTest::testTwo', self::intermediateFunction() ); - } - - 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++ ) { - $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 deleted file mode 100644 index 5032dc11..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php +++ /dev/null @@ -1,146 +0,0 @@ -<?php -/** - * Copyright © 2013 Alexandre Emsenhuber - * - * 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 - */ - -/** - * @covers ::wfParseUrl - */ -class WfParseUrlTest extends MediaWikiTestCase { - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( 'wgUrlProtocols', array( - '//', 'http://', 'file://', 'mailto:', - ) ); - } - - /** - * @dataProvider provideURLs - */ - public function testWfParseUrl( $url, $parts ) { - $partsDump = var_export( $parts, true ); - $this->assertEquals( - $parts, - wfParseUrl( $url ), - "Testing $url parses to $partsDump" - ); - } - - /** - * Provider of URLs for testing wfParseUrl() - * - * @return array - */ - public static function provideURLs() { - return array( - array( - '//example.org', - array( - 'scheme' => '', - 'delimiter' => '//', - 'host' => 'example.org', - ) - ), - array( - 'http://example.org', - array( - 'scheme' => 'http', - 'delimiter' => '://', - 'host' => 'example.org', - ) - ), - array( - 'http://id:key@example.org:123/path?foo=bar#baz', - array( - 'scheme' => 'http', - 'delimiter' => '://', - 'user' => 'id', - 'pass' => 'key', - 'host' => 'example.org', - 'port' => 123, - 'path' => '/path', - 'query' => 'foo=bar', - 'fragment' => 'baz', - ) - ), - array( - 'file://example.org/etc/php.ini', - array( - 'scheme' => 'file', - 'delimiter' => '://', - 'host' => 'example.org', - 'path' => '/etc/php.ini', - ) - ), - array( - 'file:///etc/php.ini', - array( - 'scheme' => 'file', - 'delimiter' => '://', - 'host' => '', - 'path' => '/etc/php.ini', - ) - ), - array( - 'file:///c:/', - array( - 'scheme' => 'file', - 'delimiter' => '://', - 'host' => '', - 'path' => '/c:/', - ) - ), - array( - 'mailto:id@example.org', - array( - 'scheme' => 'mailto', - 'delimiter' => ':', - 'host' => 'id@example.org', - 'path' => '', - ) - ), - array( - 'mailto:id@example.org?subject=Foo', - array( - 'scheme' => 'mailto', - 'delimiter' => ':', - 'host' => 'id@example.org', - 'path' => '', - 'query' => 'subject=Foo', - ) - ), - array( - 'mailto:?subject=Foo', - array( - 'scheme' => 'mailto', - 'delimiter' => ':', - 'host' => '', - 'path' => '', - 'query' => 'subject=Foo', - ) - ), - array( - 'invalid://test/', - false - ), - ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php b/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php deleted file mode 100644 index 238a2c9c..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php +++ /dev/null @@ -1,91 +0,0 @@ -<?php -/** - *@covers ::wfRemoveDotSegments - */ -class WfRemoveDotSegmentsTest extends MediaWikiTestCase { - /** - * @dataProvider providePaths - */ - public function testWfRemoveDotSegments( $inputPath, $outputPath ) { - $this->assertEquals( - $outputPath, - wfRemoveDotSegments( $inputPath ), - "Testing $inputPath expands to $outputPath" - ); - } - - /** - * Provider of URL paths for testing wfRemoveDotSegments() - * - * @return array - */ - public static function providePaths() { - return array( - array( '/a/b/c/./../../g', '/a/g' ), - array( 'mid/content=5/../6', 'mid/6' ), - array( '/a//../b', '/a/b' ), - array( '/.../a', '/.../a' ), - array( '.../a', '.../a' ), - array( '', '' ), - array( '/', '/' ), - array( '//', '//' ), - array( '.', '' ), - array( '..', '' ), - array( '...', '...' ), - array( '/.', '/' ), - array( '/..', '/' ), - array( './', '' ), - array( '../', '' ), - array( './a', 'a' ), - array( '../a', 'a' ), - array( '../../a', 'a' ), - array( '.././a', 'a' ), - array( './../a', 'a' ), - array( '././a', 'a' ), - array( '../../', '' ), - array( '.././', '' ), - array( './../', '' ), - array( '././', '' ), - array( '../..', '' ), - array( '../.', '' ), - array( './..', '' ), - array( './.', '' ), - array( '/../../a', '/a' ), - array( '/.././a', '/a' ), - array( '/./../a', '/a' ), - array( '/././a', '/a' ), - array( '/../../', '/' ), - array( '/.././', '/' ), - array( '/./../', '/' ), - array( '/././', '/' ), - array( '/../..', '/' ), - array( '/../.', '/' ), - array( '/./..', '/' ), - array( '/./.', '/' ), - array( 'b/../../a', '/a' ), - array( 'b/.././a', '/a' ), - array( 'b/./../a', '/a' ), - array( 'b/././a', 'b/a' ), - array( 'b/../../', '/' ), - array( 'b/.././', '/' ), - array( 'b/./../', '/' ), - array( 'b/././', 'b/' ), - array( 'b/../..', '/' ), - array( 'b/../.', '/' ), - array( 'b/./..', '/' ), - array( 'b/./.', 'b/' ), - array( '/b/../../a', '/a' ), - array( '/b/.././a', '/a' ), - array( '/b/./../a', '/a' ), - array( '/b/././a', '/b/a' ), - array( '/b/../../', '/' ), - array( '/b/.././', '/' ), - array( '/b/./../', '/' ), - array( '/b/././', '/b/' ), - array( '/b/../..', '/' ), - array( '/b/../.', '/' ), - array( '/b/./..', '/' ), - array( '/b/./.', '/b/' ), - ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php b/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php deleted file mode 100644 index aadec87f..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php - -/** - * @covers ::wfShorthandToInteger - */ -class WfShorthandToIntegerTest extends MediaWikiTestCase { - /** - * @dataProvider provideABunchOfShorthands - */ - public function testWfShorthandToInteger( $input, $output, $description ) { - $this->assertEquals( - wfShorthandToInteger( $input ), - $output, - $description - ); - } - - public static function provideABunchOfShorthands() { - return array( - array( '', -1, 'Empty string' ), - array( ' ', -1, 'String of spaces' ), - array( '1G', 1024 * 1024 * 1024, 'One gig uppercased' ), - array( '1g', 1024 * 1024 * 1024, 'One gig lowercased' ), - array( '1M', 1024 * 1024, 'One meg uppercased' ), - array( '1m', 1024 * 1024, 'One meg lowercased' ), - array( '1K', 1024, 'One kb uppercased' ), - array( '1k', 1024, 'One kb lowercased' ), - ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php b/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php deleted file mode 100644 index 5998f186..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php +++ /dev/null @@ -1,134 +0,0 @@ -<?php -/* - * @covers ::wfTimestamp - */ -class WfTimestampTest extends MediaWikiTestCase { - /** - * @dataProvider provideNormalTimestamps - */ - public function testNormalTimestamps( $input, $format, $output, $desc ) { - $this->assertEquals( $output, wfTimestamp( $format, $input ), $desc ); - } - - 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' ), - array( -30281104, TS_MW, '19690115123456', 'Negative TS_UNIX to TS_MW' ), - array( $t, TS_UNIX, 979562096, 'TS_UNIX to TS_UNIX' ), - array( $t, TS_DB, '2001-01-15 12:34:56', 'TS_UNIX to TS_DB' ), - - array( $t, TS_ISO_8601_BASIC, '20010115T123456Z', 'TS_ISO_8601_BASIC to TS_DB' ), - - // TS_MW - array( '20010115123456', TS_MW, '20010115123456', 'TS_MW to TS_MW' ), - array( '20010115123456', TS_UNIX, 979562096, 'TS_MW to TS_UNIX' ), - array( '20010115123456', TS_DB, '2001-01-15 12:34:56', 'TS_MW to TS_DB' ), - array( '20010115123456', TS_ISO_8601_BASIC, '20010115T123456Z', 'TS_MW to TS_ISO_8601_BASIC' ), - - // TS_DB - array( '2001-01-15 12:34:56', TS_MW, '20010115123456', 'TS_DB to TS_MW' ), - array( '2001-01-15 12:34:56', TS_UNIX, 979562096, 'TS_DB to TS_UNIX' ), - array( '2001-01-15 12:34:56', TS_DB, '2001-01-15 12:34:56', 'TS_DB to TS_DB' ), - array( '2001-01-15 12:34:56', TS_ISO_8601_BASIC, '20010115T123456Z', 'TS_DB to TS_ISO_8601_BASIC' ), - - # rfc2822 section 3.3 - array( '20010115123456', TS_RFC2822, 'Mon, 15 Jan 2001 12:34:56 GMT', 'TS_MW to TS_RFC2822' ), - array( 'Mon, 15 Jan 2001 12:34:56 GMT', TS_MW, '20010115123456', 'TS_RFC2822 to TS_MW' ), - array( ' Mon, 15 Jan 2001 12:34:56 GMT', TS_MW, '20010115123456', 'TS_RFC2822 with leading space to TS_MW' ), - array( '15 Jan 2001 12:34:56 GMT', TS_MW, '20010115123456', 'TS_RFC2822 without optional day-of-week to TS_MW' ), - - # FWS = ([*WSP CRLF] 1*WSP) / obs-FWS ; Folding white space - # obs-FWS = 1*WSP *(CRLF 1*WSP) ; Section 4.2 - array( 'Mon, 15 Jan 2001 12:34:56 GMT', TS_MW, '20010115123456', 'TS_RFC2822 to TS_MW' ), - - # WSP = SP / HTAB ; rfc2234 - array( "Mon, 15 Jan\x092001 12:34:56 GMT", TS_MW, '20010115123456', 'TS_RFC2822 with HTAB to TS_MW' ), - array( "Mon, 15 Jan\x09 \x09 2001 12:34:56 GMT", TS_MW, '20010115123456', 'TS_RFC2822 with HTAB and SP to TS_MW' ), - array( 'Sun, 6 Nov 94 08:49:37 GMT', TS_MW, '19941106084937', 'TS_RFC2822 with obsolete year to TS_MW' ), - ); - } - - /** - * This test checks wfTimestamp() with values outside. - * It needs PHP 64 bits or PHP > 5.1. - * See r74778 and bug 25451 - * @dataProvider provideOldTimestamps - */ - public function testOldTimestamps( $input, $format, $output, $desc ) { - $this->assertEquals( $output, wfTimestamp( $format, $input ), $desc ); - } - - 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' ), - array( '19011213204552', TS_UNIX, '-2147483648', 'Earliest 32 bit unix time' ), - array( '20380119031407', TS_UNIX, '2147483647', 'Latest 32 bit unix time' ), - array( '19011213204552', TS_RFC2822, 'Fri, 13 Dec 1901 20:45:52 GMT', 'Earliest 32 bit time' ), - array( '19011213204551', TS_RFC2822, 'Fri, 13 Dec 1901 20:45:51 GMT', 'Earliest 32 bit time - 1' ), - array( '20380119031408', TS_RFC2822, 'Tue, 19 Jan 2038 03:14:08 GMT', 'Latest 32 bit time + 1' ), - array( '19011212000000', TS_MW, '19011212000000', 'Convert to itself r74778#c10645' ), - array( '19011213204551', TS_UNIX, '-2147483649', 'Earliest 32 bit unix time - 1' ), - array( '20380119031408', TS_UNIX, '2147483648', 'Latest 32 bit unix time + 1' ), - array( '-2147483649', TS_MW, '19011213204551', '1901 negative unix time to MediaWiki' ), - array( '-5331871504', TS_MW, '18010115123456', '1801 negative unix time to MediaWiki' ), - array( '0117-08-09 12:34:56', TS_RFC2822, 'Tue, 09 Aug 0117 12:34:56 GMT', 'Death of Roman Emperor [[Trajan]]' ), - - /* @todo FIXME: 00 to 101 years are taken as being in [1970-2069] */ - array( '-58979923200', TS_RFC2822, 'Sun, 01 Jan 0101 00:00:00 GMT', '1/1/101' ), - array( '-62135596800', TS_RFC2822, 'Mon, 01 Jan 0001 00:00:00 GMT', 'Year 1' ), - - /* It is not clear if we should generate a year 0 or not - * We are completely off RFC2822 requirement of year being - * 1900 or later. - */ - array( '-62142076800', TS_RFC2822, 'Wed, 18 Oct 0000 00:00:00 GMT', 'ISO 8601:2004 [[year 0]], also called [[1 BC]]' ), - ); - } - - /** - * The Resource Loader uses wfTimestamp() to convert timestamps - * from If-Modified-Since header. Thus it must be able to parse all - * rfc2616 date formats - * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1 - * @dataProvider provideHttpDates - */ - public function testHttpDate( $input, $output, $desc ) { - $this->assertEquals( $output, wfTimestamp( TS_MW, $input ), $desc ); - } - - 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' ), - array( 'Sun Nov 6 08:49:37 1994', '19941106084937', "ANSI C's asctime() format" ), - // See http://www.squid-cache.org/mail-archive/squid-users/200307/0122.html and r77171 - array( 'Mon, 22 Nov 2010 14:12:42 GMT; length=52626', '20101122141242', 'Netscape extension to HTTP/1.0' ), - ); - } - - /** - * 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 - */ - public function testTimestampParameter() { - $now = wfTimestamp( TS_UNIX ); - // 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 ); - $this->assertNotEquals( false, $zero ); - $this->assertLessThan( 5, $zero - $now ); - - $empty = wfTimestamp( TS_UNIX, '' ); - $this->assertNotEquals( false, $empty ); - $this->assertLessThan( 5, $empty - $now ); - - $null = wfTimestamp( TS_UNIX, null ); - $this->assertNotEquals( false, $null ); - $this->assertLessThan( 5, $null - $now ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php b/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php deleted file mode 100644 index ce6c82c5..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php -/** - * The function only need a string parameter and might react to IIS7.0 - * @covers ::wfUrlencode - */ -class WfUrlencodeTest extends MediaWikiTestCase { - #### TESTS ############################################################## - - /** - * @dataProvider provideURLS - */ - public function testEncodingUrlWith( $input, $expected ) { - $this->verifyEncodingFor( 'Apache', $input, $expected ); - } - - /** - * @dataProvider provideURLS - */ - public function testEncodingUrlWithMicrosoftIis7( $input, $expected ) { - $this->verifyEncodingFor( 'Microsoft-IIS/7', $input, $expected ); - } - - #### HELPERS ############################################################# - - /** - * Internal helper that actually run the test. - * Called by the public methods testEncodingUrlWith...() - * - */ - private function verifyEncodingFor( $server, $input, $expectations ) { - $expected = $this->extractExpect( $server, $expectations ); - - // save up global - $old = isset( $_SERVER['SERVER_SOFTWARE'] ) - ? $_SERVER['SERVER_SOFTWARE'] - : null; - $_SERVER['SERVER_SOFTWARE'] = $server; - wfUrlencode( null ); - - // do the requested test - $this->assertEquals( - $expected, - wfUrlencode( $input ), - "Encoding '$input' for server '$server' should be '$expected'" - ); - - // restore global - if ( $old === null ) { - unset( $_SERVER['SERVER_SOFTWARE'] ); - } else { - $_SERVER['SERVER_SOFTWARE'] = $old; - } - wfUrlencode( null ); - } - - /** - * Interprets the provider array. Return expected value depending - * the HTTP server name. - */ - private function extractExpect( $server, $expectations ) { - if ( is_string( $expectations ) ) { - return $expectations; - } elseif ( is_array( $expectations ) ) { - if ( !array_key_exists( $server, $expectations ) ) { - throw new MWException( __METHOD__ . " expectation does not have any value for server name $server. Check the provider array.\n" ); - } else { - return $expectations[$server]; - } - } else { - throw new MWException( __METHOD__ . " given invalid expectation for '$server'. Should be a string or an array( <http server name> => <string> ).\n" ); - } - } - - #### PROVIDERS ########################################################### - - /** - * Format is either: - * array( 'input', 'expected' ); - * Or: - * array( 'input', - * array( 'Apache', 'expected' ), - * array( 'Microsoft-IIS/7', 'expected' ), - * ), - * If you want to add other HTTP server name, you will have to add a new - * testing method much like the testEncodingUrlWith() method above. - */ - public static function provideURLS() { - return array( - ### RFC 1738 chars - // + is not safe - array( '+', '%2B' ), - // & and = not safe in queries - array( '&', '%26' ), - array( '=', '%3D' ), - - array( ':', array( - 'Apache' => ':', - 'Microsoft-IIS/7' => '%3A', - ) ), - - // remaining chars do not need encoding - array( - ';@$-_.!*', - ';@$-_.!*', - ), - - ### Other tests - // slash remain unchanged. %2F seems to break things - array( '/', '/' ), - - // Other 'funnies' chars - array( '[]', '%5B%5D' ), - array( '<>', '%3C%3E' ), - - // Apostrophe is encoded - array( '\'', '%27' ), - ); - } -} diff --git a/tests/phpunit/includes/HTMLCheckMatrixTest.php b/tests/phpunit/includes/HTMLCheckMatrixTest.php deleted file mode 100644 index 5bbafd37..00000000 --- a/tests/phpunit/includes/HTMLCheckMatrixTest.php +++ /dev/null @@ -1,102 +0,0 @@ -<?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 deleted file mode 100644 index 65f13696..00000000 --- a/tests/phpunit/includes/HashRingTest.php +++ /dev/null @@ -1,53 +0,0 @@ -<?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 deleted file mode 100644 index 81dd4870..00000000 --- a/tests/phpunit/includes/HooksTest.php +++ /dev/null @@ -1,158 +0,0 @@ -<?php - -class HooksTest extends MediaWikiTestCase { - - function setUp() { - global $wgHooks; - parent::setUp(); - Hooks::clear( 'MediaWikiHooksTest001' ); - unset( $wgHooks['MediaWikiHooksTest001'] ); - } - - public static function provideHooks() { - $i = new NothingClass(); - - 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' ) - ); - } - - /** - * @dataProvider provideHooks - */ - public function testOldStyleHooks( $msg, array $hook, $expectedFoo, $expectedBar ) { - global $wgHooks; - $foo = $bar = 'original'; - - $wgHooks['MediaWikiHooksTest001'][] = $hook; - wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertSame( $expectedFoo, $foo, $msg ); - $this->assertSame( $expectedBar, $bar, $msg ); - } - - /** - * @dataProvider provideHooks - */ - public function testNewStyleHooks( $msg, $hook, $expectedFoo, $expectedBar ) { - $foo = $bar = 'original'; - - Hooks::register( 'MediaWikiHooksTest001', $hook ); - Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertSame( $expectedFoo, $foo, $msg ); - $this->assertSame( $expectedBar, $bar, $msg ); - } - - public function testNewStyleHookInteraction() { - global $wgHooks; - - $a = new NothingClass(); - $b = new NothingClass(); - - $wgHooks['MediaWikiHooksTest001'][] = $a; - $this->assertTrue( Hooks::isRegistered( 'MediaWikiHooksTest001' ), 'Hook registered via $wgHooks should be noticed by Hooks::isRegistered' ); - - Hooks::register( 'MediaWikiHooksTest001', $b ); - $this->assertEquals( 2, count( Hooks::getHandlers( 'MediaWikiHooksTest001' ) ), 'Hooks::getHandlers() should return hooks registered via wgHooks as well as Hooks::register' ); - - $foo = 'quux'; - $bar = 'qaax'; - - 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' ); - } - - /** - * @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 = 'changed-static'; - - return true; - } - - public function someNonStatic( &$foo, &$bar ) { - $this->calls++; - $foo = 'changed-nonstatic'; - $bar = 'changed-nonstatic'; - - return true; - } - - public function onMediaWikiHooksTest001( &$foo, &$bar ) { - $this->calls++; - $foo = 'changed-onevent'; - - return true; - } - - public function someNonStaticWithData( $data, &$foo, &$bar ) { - $this->calls++; - $foo = $data; - - return true; - } -} diff --git a/tests/phpunit/includes/HtmlFormatterTest.php b/tests/phpunit/includes/HtmlFormatterTest.php deleted file mode 100644 index a37df74f..00000000 --- a/tests/phpunit/includes/HtmlFormatterTest.php +++ /dev/null @@ -1,81 +0,0 @@ -<?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 deleted file mode 100644 index 1c62d032..00000000 --- a/tests/phpunit/includes/HtmlTest.php +++ /dev/null @@ -1,631 +0,0 @@ -<?php -/** tests for includes/Html.php */ - -class HtmlTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - $langCode = 'en'; - $langObj = Language::factory( $langCode ); - - // Hardcode namespaces during test runs, - // so that html output based on existing namespaces - // can be properly evaluated. - $langObj->setNamespaces( array( - -2 => 'Media', - -1 => 'Special', - 0 => '', - 1 => 'Talk', - 2 => 'User', - 3 => 'User_talk', - 4 => 'MyWiki', - 5 => 'MyWiki_Talk', - 6 => 'File', - 7 => 'File_talk', - 8 => 'MediaWiki', - 9 => 'MediaWiki_talk', - 10 => 'Template', - 11 => 'Template_talk', - 14 => 'Category', - 15 => 'Category_talk', - 100 => 'Custom', - 101 => 'Custom_talk', - ) ); - - $this->setMwGlobals( array( - 'wgLanguageCode' => $langCode, - 'wgContLang' => $langObj, - 'wgLang' => $langObj, - 'wgWellFormedXml' => false, - ) ); - } - - public function testElementBasics() { - $this->assertEquals( - '<img>', - Html::element( 'img', null, '' ), - 'No close tag for short-tag elements' - ); - - $this->assertEquals( - '<element></element>', - Html::element( 'element', null, null ), - 'Close tag for empty element (null, null)' - ); - - $this->assertEquals( - '<element></element>', - Html::element( 'element', array(), '' ), - 'Close tag for empty element (array, string)' - ); - - $this->setMwGlobals( 'wgWellFormedXml', true ); - - $this->assertEquals( - '<img />', - Html::element( 'img', null, '' ), - 'Self-closing tag for short-tag elements (wgWellFormedXml = true)' - ); - } - - 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 ######## - $this->assertEmpty( - Html::expandAttributes( array( 'foo' => null ) ), - 'skip keys with null value' - ); - $this->assertEmpty( - Html::expandAttributes( array( 'foo' => false ) ), - 'skip keys with false value' - ); - $this->assertNotEmpty( - Html::expandAttributes( array( 'foo' => '' ) ), - 'keep keys with an empty string' - ); - } - - public function testExpandAttributesForBooleans() { - $this->assertEquals( - '', - Html::expandAttributes( array( 'selected' => false ) ), - 'Boolean attributes do not generates output when value is false' - ); - $this->assertEquals( - '', - Html::expandAttributes( array( 'selected' => null ) ), - 'Boolean attributes do not generates output when value is null' - ); - - $this->assertEquals( - ' selected', - Html::expandAttributes( array( 'selected' => true ) ), - 'Boolean attributes have no value when value is true' - ); - $this->assertEquals( - ' selected', - Html::expandAttributes( array( 'selected' ) ), - 'Boolean attributes have no value when value is true (passed as numerical array)' - ); - - $this->setMwGlobals( 'wgWellFormedXml', true ); - - $this->assertEquals( - ' selected=""', - Html::expandAttributes( array( 'selected' => true ) ), - 'Boolean attributes have empty string value when value is true (wgWellFormedXml)' - ); - } - - /** - * Test for Html::expandAttributes() - * Please note it output a string prefixed with a space! - */ - public function testExpandAttributesVariousExpansions() { - ### NOT EMPTY #### - $this->assertEquals( - ' empty_string=""', - Html::expandAttributes( array( 'empty_string' => '' ) ), - 'Empty string is always quoted' - ); - $this->assertEquals( - ' key=value', - Html::expandAttributes( array( 'key' => 'value' ) ), - 'Simple string value needs no quotes' - ); - $this->assertEquals( - ' one=1', - Html::expandAttributes( array( 'one' => 1 ) ), - 'Number 1 value needs no quotes' - ); - $this->assertEquals( - ' zero=0', - Html::expandAttributes( array( 'zero' => 0 ) ), - 'Number 0 value needs no quotes' - ); - - $this->setMwGlobals( 'wgWellFormedXml', true ); - - $this->assertEquals( - ' empty_string=""', - Html::expandAttributes( array( 'empty_string' => '' ) ), - 'Attribute values are always quoted (wgWellFormedXml): Empty string' - ); - $this->assertEquals( - ' key="value"', - Html::expandAttributes( array( 'key' => 'value' ) ), - 'Attribute values are always quoted (wgWellFormedXml): Simple string' - ); - $this->assertEquals( - ' one="1"', - Html::expandAttributes( array( 'one' => 1 ) ), - 'Attribute values are always quoted (wgWellFormedXml): Number 1' - ); - $this->assertEquals( - ' zero="0"', - Html::expandAttributes( array( 'zero' => 0 ) ), - 'Attribute values are always quoted (wgWellFormedXml): Number 0' - ); - } - - /** - * Html::expandAttributes has special features for HTML - * attributes that use space separated lists and also - * allows arrays to be used as values. - */ - public function testExpandAttributesListValueAttributes() { - ### STRING VALUES - $this->assertEquals( - ' class="redundant spaces here"', - Html::expandAttributes( array( 'class' => ' redundant spaces here ' ) ), - 'Normalization should strip redundant spaces' - ); - $this->assertEquals( - ' class="foo bar"', - Html::expandAttributes( array( 'class' => 'foo bar foo bar bar' ) ), - 'Normalization should remove duplicates in string-lists' - ); - ### "EMPTY" ARRAY VALUES - $this->assertEquals( - ' class=""', - Html::expandAttributes( array( 'class' => array() ) ), - 'Value with an empty array' - ); - $this->assertEquals( - ' class=""', - Html::expandAttributes( array( 'class' => array( null, '', ' ', ' ' ) ) ), - 'Array with null, empty string and spaces' - ); - ### NON-EMPTY ARRAY VALUES - $this->assertEquals( - ' class="foo bar"', - Html::expandAttributes( array( 'class' => array( - 'foo', - 'bar', - 'foo', - 'bar', - 'bar', - ) ) ), - 'Normalization should remove duplicates in the array' - ); - $this->assertEquals( - ' class="foo bar"', - Html::expandAttributes( array( 'class' => array( - 'foo bar', - 'bar foo', - 'foo', - 'bar bar', - ) ) ), - 'Normalization should remove duplicates in string-lists in the array' - ); - } - - /** - * Test feature added by r96188, let pass attributes values as - * a PHP array. Restricted to class,rel, accesskey. - */ - public function testExpandAttributesSpaceSeparatedAttributesWithBoolean() { - $this->assertEquals( - ' class="booltrue one"', - Html::expandAttributes( array( 'class' => array( - 'booltrue' => true, - 'one' => 1, - - # Method use isset() internally, make sure we do discard - # attributes values which have been assigned well known values - 'emptystring' => '', - 'boolfalse' => false, - 'zero' => 0, - 'null' => null, - ) ) ) - ); - } - - /** - * How do we handle duplicate keys in HTML attributes expansion? - * We could pass a "class" the values: 'GREEN' and array( 'GREEN' => false ) - * The later will take precedence. - * - * Feature added by r96188 - */ - public function testValueIsAuthoritativeInSpaceSeparatedAttributesArrays() { - $this->assertEquals( - ' class=""', - Html::expandAttributes( array( 'class' => array( - 'GREEN', - 'GREEN' => false, - 'GREEN', - ) ) ) - ); - } - - public function testNamespaceSelector() { - $this->assertEquals( - '<select id=namespace name=namespace>' . "\n" . - '<option value=0>(Main)</option>' . "\n" . - '<option value=1>Talk</option>' . "\n" . - '<option value=2>User</option>' . "\n" . - '<option value=3>User talk</option>' . "\n" . - '<option value=4>MyWiki</option>' . "\n" . - '<option value=5>MyWiki Talk</option>' . "\n" . - '<option value=6>File</option>' . "\n" . - '<option value=7>File talk</option>' . "\n" . - '<option value=8>MediaWiki</option>' . "\n" . - '<option value=9>MediaWiki talk</option>' . "\n" . - '<option value=10>Template</option>' . "\n" . - '<option value=11>Template talk</option>' . "\n" . - '<option value=14>Category</option>' . "\n" . - '<option value=15>Category talk</option>' . "\n" . - '<option value=100>Custom</option>' . "\n" . - '<option value=101>Custom talk</option>' . "\n" . - '</select>', - Html::namespaceSelector(), - 'Basic namespace selector without custom options' - ); - - $this->assertEquals( - '<label for=mw-test-namespace>Select a namespace:</label> ' . - '<select id=mw-test-namespace name=wpNamespace>' . "\n" . - '<option value=all>all</option>' . "\n" . - '<option value=0>(Main)</option>' . "\n" . - '<option value=1>Talk</option>' . "\n" . - '<option value=2 selected>User</option>' . "\n" . - '<option value=3>User talk</option>' . "\n" . - '<option value=4>MyWiki</option>' . "\n" . - '<option value=5>MyWiki Talk</option>' . "\n" . - '<option value=6>File</option>' . "\n" . - '<option value=7>File talk</option>' . "\n" . - '<option value=8>MediaWiki</option>' . "\n" . - '<option value=9>MediaWiki talk</option>' . "\n" . - '<option value=10>Template</option>' . "\n" . - '<option value=11>Template talk</option>' . "\n" . - '<option value=14>Category</option>' . "\n" . - '<option value=15>Category talk</option>' . "\n" . - '<option value=100>Custom</option>' . "\n" . - '<option value=101>Custom talk</option>' . "\n" . - '</select>', - Html::namespaceSelector( - array( 'selected' => '2', 'all' => 'all', 'label' => 'Select a namespace:' ), - array( 'name' => 'wpNamespace', 'id' => 'mw-test-namespace' ) - ), - 'Basic namespace selector with custom values' - ); - - $this->assertEquals( - '<label for=namespace>Select a namespace:</label> ' . - '<select id=namespace name=namespace>' . "\n" . - '<option value=0>(Main)</option>' . "\n" . - '<option value=1>Talk</option>' . "\n" . - '<option value=2>User</option>' . "\n" . - '<option value=3>User talk</option>' . "\n" . - '<option value=4>MyWiki</option>' . "\n" . - '<option value=5>MyWiki Talk</option>' . "\n" . - '<option value=6>File</option>' . "\n" . - '<option value=7>File talk</option>' . "\n" . - '<option value=8>MediaWiki</option>' . "\n" . - '<option value=9>MediaWiki talk</option>' . "\n" . - '<option value=10>Template</option>' . "\n" . - '<option value=11>Template talk</option>' . "\n" . - '<option value=14>Category</option>' . "\n" . - '<option value=15>Category talk</option>' . "\n" . - '<option value=100>Custom</option>' . "\n" . - '<option value=101>Custom talk</option>' . "\n" . - '</select>', - Html::namespaceSelector( - array( 'label' => 'Select a namespace:' ) - ), - 'Basic namespace selector with a custom label but no id attribtue for the <select>' - ); - } - - public function testCanFilterOutNamespaces() { - $this->assertEquals( - '<select id=namespace name=namespace>' . "\n" . - '<option value=2>User</option>' . "\n" . - '<option value=4>MyWiki</option>' . "\n" . - '<option value=5>MyWiki Talk</option>' . "\n" . - '<option value=6>File</option>' . "\n" . - '<option value=7>File talk</option>' . "\n" . - '<option value=8>MediaWiki</option>' . "\n" . - '<option value=9>MediaWiki talk</option>' . "\n" . - '<option value=10>Template</option>' . "\n" . - '<option value=11>Template talk</option>' . "\n" . - '<option value=14>Category</option>' . "\n" . - '<option value=15>Category talk</option>' . "\n" . - '</select>', - Html::namespaceSelector( - array( 'exclude' => array( 0, 1, 3, 100, 101 ) ) - ), - 'Namespace selector namespace filtering.' - ); - } - - public function testCanDisableANamespaces() { - $this->assertEquals( - '<select id=namespace name=namespace>' . "\n" . - '<option disabled value=0>(Main)</option>' . "\n" . - '<option disabled value=1>Talk</option>' . "\n" . - '<option disabled value=2>User</option>' . "\n" . - '<option disabled value=3>User talk</option>' . "\n" . - '<option disabled value=4>MyWiki</option>' . "\n" . - '<option value=5>MyWiki Talk</option>' . "\n" . - '<option value=6>File</option>' . "\n" . - '<option value=7>File talk</option>' . "\n" . - '<option value=8>MediaWiki</option>' . "\n" . - '<option value=9>MediaWiki talk</option>' . "\n" . - '<option value=10>Template</option>' . "\n" . - '<option value=11>Template talk</option>' . "\n" . - '<option value=14>Category</option>' . "\n" . - '<option value=15>Category talk</option>' . "\n" . - '<option value=100>Custom</option>' . "\n" . - '<option value=101>Custom talk</option>' . "\n" . - '</select>', - Html::namespaceSelector( array( - 'disable' => array( 0, 1, 2, 3, 4 ) - ) ), - 'Namespace selector namespace disabling' - ); - } - - /** - * @dataProvider provideHtml5InputTypes - */ - public function testHtmlElementAcceptsNewHtml5TypesInHtml5Mode( $HTML5InputType ) { - $this->assertEquals( - '<input type=' . $HTML5InputType . '>', - Html::element( 'input', array( 'type' => $HTML5InputType ) ), - 'In HTML5, HTML::element() should accept type="' . $HTML5InputType . '"' - ); - } - - /** - * List of input element types values introduced by HTML5 - * Full list at http://www.w3.org/TR/html-markup/input.html - */ - public static function provideHtml5InputTypes() { - $types = array( - 'datetime', - 'datetime-local', - 'date', - 'month', - 'time', - 'week', - 'number', - 'range', - 'email', - 'url', - 'search', - 'tel', - 'color', - ); - $cases = array(); - foreach ( $types as $type ) { - $cases[] = array( $type ); - } - - return $cases; - } - - /** - * Test out Html::element drops or enforces default value - * @covers Html::dropDefaults - * @dataProvider provideElementsWithAttributesHavingDefaultValues - */ - public function testDropDefaults( $expected, $element, $attribs, $message = '' ) { - $this->assertEquals( $expected, Html::element( $element, $attribs ), $message ); - } - - public static function provideElementsWithAttributesHavingDefaultValues() { - # Use cases in a concise format: - # <expected>, <element name>, <array of attributes> [, <message>] - # Will be mapped to Html::element() - $cases = array(); - - ### Generic cases, match $attribDefault static array - $cases[] = array( '<area>', - 'area', array( 'shape' => 'rect' ) - ); - - $cases[] = array( '<button type=submit></button>', - 'button', array( 'formaction' => 'GET' ) - ); - $cases[] = array( '<button type=submit></button>', - 'button', array( 'formenctype' => 'application/x-www-form-urlencoded' ) - ); - - $cases[] = array( '<canvas></canvas>', - 'canvas', array( 'height' => '150' ) - ); - $cases[] = array( '<canvas></canvas>', - 'canvas', array( 'width' => '300' ) - ); - # Also check with numeric values - $cases[] = array( '<canvas></canvas>', - 'canvas', array( 'height' => 150 ) - ); - $cases[] = array( '<canvas></canvas>', - 'canvas', array( 'width' => 300 ) - ); - - $cases[] = array( '<command>', - 'command', array( 'type' => 'command' ) - ); - - $cases[] = array( '<form></form>', - 'form', array( 'action' => 'GET' ) - ); - $cases[] = array( '<form></form>', - 'form', array( 'autocomplete' => 'on' ) - ); - $cases[] = array( '<form></form>', - 'form', array( 'enctype' => 'application/x-www-form-urlencoded' ) - ); - - $cases[] = array( '<input>', - 'input', array( 'formaction' => 'GET' ) - ); - $cases[] = array( '<input>', - 'input', array( 'type' => 'text' ) - ); - - $cases[] = array( '<keygen>', - 'keygen', array( 'keytype' => 'rsa' ) - ); - - $cases[] = array( '<link>', - 'link', array( 'media' => 'all' ) - ); - - $cases[] = array( '<menu></menu>', - 'menu', array( 'type' => 'list' ) - ); - - $cases[] = array( '<script></script>', - 'script', array( 'type' => 'text/javascript' ) - ); - - $cases[] = array( '<style></style>', - 'style', array( 'media' => 'all' ) - ); - $cases[] = array( '<style></style>', - 'style', array( 'type' => 'text/css' ) - ); - - $cases[] = array( '<textarea></textarea>', - 'textarea', array( 'wrap' => 'soft' ) - ); - - ### SPECIFIC CASES - - # <link type="text/css"> - $cases[] = array( '<link>', - 'link', array( 'type' => 'text/css' ) - ); - - # <input> specific handling - $cases[] = array( '<input type=checkbox>', - 'input', array( 'type' => 'checkbox', 'value' => 'on' ), - 'Default value "on" is stripped of checkboxes', - ); - $cases[] = array( '<input type=radio>', - 'input', array( 'type' => 'radio', 'value' => 'on' ), - 'Default value "on" is stripped of radio buttons', - ); - $cases[] = array( '<input type=submit value=Submit>', - 'input', array( 'type' => 'submit', 'value' => 'Submit' ), - 'Default value "Submit" is kept on submit buttons (for possible l10n issues)', - ); - $cases[] = array( '<input type=color>', - 'input', array( 'type' => 'color', 'value' => '' ), - ); - $cases[] = array( '<input type=range>', - 'input', array( 'type' => 'range', 'value' => '' ), - ); - - # <button> specific handling - # see remarks on http://msdn.microsoft.com/en-us/library/ie/ms535211%28v=vs.85%29.aspx - $cases[] = array( '<button type=submit></button>', - 'button', array( 'type' => 'submit' ), - 'According to standard the default type is "submit". Depending on compatibility mode IE might use "button", instead.', - ); - - # <select> specifc handling - $cases[] = array( '<select multiple></select>', - 'select', array( 'size' => '4', 'multiple' => true ), - ); - # .. with numeric value - $cases[] = array( '<select multiple></select>', - 'select', array( 'size' => 4, 'multiple' => true ), - ); - $cases[] = array( '<select></select>', - 'select', array( 'size' => '1', 'multiple' => false ), - ); - # .. with numeric value - $cases[] = array( '<select></select>', - 'select', array( 'size' => 1, 'multiple' => false ), - ); - - # Passing an array as value - $cases[] = array( '<a class="css-class-one css-class-two"></a>', - 'a', array( 'class' => array( 'css-class-one', 'css-class-two' ) ), - "dropDefaults accepts values given as an array" - ); - - # FIXME: doDropDefault should remove defaults given in an array - # Expected should be '<a></a>' - $cases[] = array( '<a class=""></a>', - 'a', array( 'class' => array( '', '' ) ), - "dropDefaults accepts values given as an array" - ); - - # Craft the Html elements - $ret = array(); - foreach ( $cases as $case ) { - $ret[] = array( - $case[0], - $case[1], $case[2], - isset( $case[3] ) ? $case[3] : '' - ); - } - - return $ret; - } - - public function testFormValidationBlacklist() { - $this->assertEmpty( - Html::expandAttributes( array( 'min' => 1, 'max' => 100, 'pattern' => 'abc', 'required' => true, 'step' => 2 ) ), - 'Blacklist form validation attributes.' - ); - $this->assertEquals( - ' step=any', - Html::expandAttributes( array( 'min' => 1, 'max' => 100, 'pattern' => 'abc', 'required' => true, 'step' => 'any' ) ), - 'Allow special case "step=any".' - ); - } -} diff --git a/tests/phpunit/includes/HttpTest.php b/tests/phpunit/includes/HttpTest.php deleted file mode 100644 index 11d8ed60..00000000 --- a/tests/phpunit/includes/HttpTest.php +++ /dev/null @@ -1,216 +0,0 @@ -<?php -/** - * @group Broken - */ -class HttpTest extends MediaWikiTestCase { - /** - * @dataProvider cookieDomains - * @covers Cookie::validateCookieDomain - */ - public function testValidateCookieDomain( $expected, $domain, $origin = null ) { - if ( $origin ) { - $ok = Cookie::validateCookieDomain( $domain, $origin ); - $msg = "$domain against origin $origin"; - } else { - $ok = Cookie::validateCookieDomain( $domain ); - $msg = "$domain"; - } - $this->assertEquals( $expected, $ok, $msg ); - } - - public static function cookieDomains() { - return array( - array( false, "org" ), - array( false, ".org" ), - array( true, "wikipedia.org" ), - array( true, ".wikipedia.org" ), - array( false, "co.uk" ), - array( false, ".co.uk" ), - array( false, "gov.uk" ), - array( false, ".gov.uk" ), - array( true, "supermarket.uk" ), - array( false, "uk" ), - array( false, ".uk" ), - array( false, "127.0.0." ), - array( false, "127." ), - array( false, "127.0.0.1." ), - array( true, "127.0.0.1" ), - array( false, "333.0.0.1" ), - array( true, "example.com" ), - array( false, "example.com." ), - array( true, ".example.com" ), - - array( true, ".example.com", "www.example.com" ), - array( false, "example.com", "www.example.com" ), - array( true, "127.0.0.1", "127.0.0.1" ), - array( false, "127.0.0.1", "localhost" ), - ); - } - - /** - * Test Http::isValidURI() - * @bug 27854 : Http::isValidURI is too lax - * @dataProvider provideURI - * @covers Http::isValidURI - */ - public function testIsValidUri( $expect, $URI, $message = '' ) { - $this->assertEquals( - $expect, - (bool)Http::isValidURI( $URI ), - $message - ); - } - - /** - * Feeds URI to test a long regular expression in Http::isValidURI - */ - public static function provideURI() { - /** Format: 'boolean expectation', 'URI to test', 'Optional message' */ - return array( - array( false, '¿non sens before!! http://a', 'Allow anything before URI' ), - - # (http|https) - only two schemes allowed - array( true, 'http://www.example.org/' ), - array( true, 'https://www.example.org/' ), - array( true, 'http://www.example.org', 'URI without directory' ), - array( true, 'http://a', 'Short name' ), - array( true, 'http://étoile', 'Allow UTF-8 in hostname' ), # 'étoile' is french for 'star' - array( false, '\\host\directory', 'CIFS share' ), - array( false, 'gopher://host/dir', 'Reject gopher scheme' ), - array( false, 'telnet://host', 'Reject telnet scheme' ), - - # :\/\/ - double slashes - array( false, 'http//example.org', 'Reject missing colon in protocol' ), - array( false, 'http:/example.org', 'Reject missing slash in protocol' ), - array( false, 'http:example.org', 'Must have two slashes' ), - # Following fail since hostname can be made of anything - array( false, 'http:///example.org', 'Must have exactly two slashes, not three' ), - - # (\w+:{0,1}\w*@)? - optional user:pass - array( true, 'http://user@host', 'Username provided' ), - array( true, 'http://user:@host', 'Username provided, no password' ), - array( true, 'http://user:pass@host', 'Username and password provided' ), - - # (\S+) - host part is made of anything not whitespaces - array( false, 'http://!"èèè¿¿¿~~\'', 'hostname is made of any non whitespace' ), - array( false, 'http://exam:ple.org/', 'hostname can not use colons!' ), - - # (:[0-9]+)? - port number - array( true, 'http://example.org:80/' ), - array( true, 'https://example.org:80/' ), - array( true, 'http://example.org:443/' ), - array( true, 'https://example.org:443/' ), - - # Part after the hostname is / or / with something else - array( true, 'http://example/#' ), - array( true, 'http://example/!' ), - array( true, 'http://example/:' ), - array( true, 'http://example/.' ), - array( true, 'http://example/?' ), - array( true, 'http://example/+' ), - array( true, 'http://example/=' ), - array( true, 'http://example/&' ), - array( true, 'http://example/%' ), - array( true, 'http://example/@' ), - array( true, 'http://example/-' ), - array( true, 'http://example//' ), - array( true, 'http://example/&' ), - - # Fragment - array( true, 'http://exam#ple.org', ), # This one is valid, really! - array( true, 'http://example.org:80#anchor' ), - array( true, 'http://example.org/?id#anchor' ), - array( true, 'http://example.org/?#anchor' ), - - array( false, 'http://a ¿non !!sens after', 'Allow anything after URI' ), - ); - } - - /** - * Warning: - * - * These tests are for code that makes use of an artifact of how CURL - * handles header reporting on redirect pages, and will need to be - * rewritten when bug 29232 is taken care of (high-level handling of - * HTTP redirects). - */ - public function testRelativeRedirections() { - $h = MWHttpRequestTester::factory( 'http://oldsite/file.ext' ); - - # Forge a Location header - $h->setRespHeaders( 'location', array( - 'http://newsite/file.ext', - '/newfile.ext', - ) - ); - # Verify we correctly fix the Location - $this->assertEquals( - 'http://newsite/newfile.ext', - $h->getFinalUrl(), - "Relative file path Location: interpreted as full URL" - ); - - $h->setRespHeaders( 'location', array( - 'https://oldsite/file.ext' - ) - ); - $this->assertEquals( - 'https://oldsite/file.ext', - $h->getFinalUrl(), - "Location to the HTTPS version of the site" - ); - - $h->setRespHeaders( 'location', array( - '/anotherfile.ext', - 'http://anotherfile/hoster.ext', - 'https://anotherfile/hoster.ext' - ) - ); - $this->assertEquals( - 'https://anotherfile/hoster.ext', - $h->getFinalUrl( "Relative file path Location: should keep the latest host and scheme!" ) - ); - } -} - -/** - * Class to let us overwrite MWHttpRequest respHeaders variable - */ -class MWHttpRequestTester extends MWHttpRequest { - - // function derived from the MWHttpRequest factory function but - // returns appropriate tester class here - public static function factory( $url, $options = null ) { - if ( !Http::$httpEngine ) { - Http::$httpEngine = function_exists( 'curl_init' ) ? 'curl' : 'php'; - } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) { - throw new MWException( __METHOD__ . ': curl (http://php.net/curl) is not installed, but' . - 'Http::$httpEngine is set to "curl"' ); - } - - switch ( Http::$httpEngine ) { - case 'curl': - return new CurlHttpRequestTester( $url, $options ); - case 'php': - if ( !wfIniGetBool( 'allow_url_fopen' ) ) { - 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: - } - } -} - -class CurlHttpRequestTester extends CurlHttpRequest { - function setRespHeaders( $name, $value ) { - $this->respHeaders[$name] = $value; - } -} - -class PhpHttpRequestTester extends PhpHttpRequest { - function setRespHeaders( $name, $value ) { - $this->respHeaders[$name] = $value; - } -} diff --git a/tests/phpunit/includes/IPTest.php b/tests/phpunit/includes/IPTest.php deleted file mode 100644 index c074eea6..00000000 --- a/tests/phpunit/includes/IPTest.php +++ /dev/null @@ -1,595 +0,0 @@ -<?php -/** - * 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 { - /** - * not sure it should be tested with boolean false. hashar 20100924 - * @covers IP::isIPAddress - */ - public function testisIPAddress() { - $this->assertFalse( IP::isIPAddress( false ), 'Boolean false is not an IP' ); - $this->assertFalse( IP::isIPAddress( true ), 'Boolean true is not an IP' ); - $this->assertFalse( IP::isIPAddress( "" ), 'Empty string is not an IP' ); - $this->assertFalse( IP::isIPAddress( 'abc' ), 'Garbage IP string' ); - $this->assertFalse( IP::isIPAddress( ':' ), 'Single ":" is not an IP' ); - $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::1' ), 'IPv6 with a double :: occurrence' ); - $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::' ), 'IPv6 with a double :: occurrence, last at end' ); - $this->assertFalse( IP::isIPAddress( '::2001:0DB8::5:1' ), 'IPv6 with a double :: occurrence, firt at beginning' ); - $this->assertFalse( IP::isIPAddress( '124.24.52' ), 'IPv4 not enough quads' ); - $this->assertFalse( IP::isIPAddress( '24.324.52.13' ), 'IPv4 out of range' ); - $this->assertFalse( IP::isIPAddress( '.24.52.13' ), 'IPv4 starts with period' ); - $this->assertFalse( IP::isIPAddress( 'fc:100:300' ), 'IPv6 with only 3 words' ); - - $this->assertTrue( IP::isIPAddress( '::' ), 'RFC 4291 IPv6 Unspecified Address' ); - $this->assertTrue( IP::isIPAddress( '::1' ), 'RFC 4291 IPv6 Loopback Address' ); - $this->assertTrue( IP::isIPAddress( '74.24.52.13/20', 'IPv4 range' ) ); - $this->assertTrue( IP::isIPAddress( 'fc:100:a:d:1:e:ac:0/24' ), 'IPv6 range' ); - $this->assertTrue( IP::isIPAddress( 'fc::100:a:d:1:e:ac/96' ), 'IPv6 range with "::"' ); - - $validIPs = array( 'fc:100::', 'fc:100:a:d:1:e:ac::', 'fc::100', '::fc:100:a:d:1:e:ac', - '::fc', 'fc::100:a:d:1:e:ac', 'fc:100:a:d:1:e:ac:0', '124.24.52.13', '1.24.52.13' ); - foreach ( $validIPs as $ip ) { - $this->assertTrue( IP::isIPAddress( $ip ), "$ip is a valid IP address" ); - } - } - - /** - * @covers IP::isIPv6 - */ - public function testisIPv6() { - $this->assertFalse( IP::isIPv6( ':fc:100::' ), 'IPv6 starting with lone ":"' ); - $this->assertFalse( IP::isIPv6( 'fc:100:::' ), 'IPv6 ending with a ":::"' ); - $this->assertFalse( IP::isIPv6( 'fc:300' ), 'IPv6 with only 2 words' ); - $this->assertFalse( IP::isIPv6( 'fc:100:300' ), 'IPv6 with only 3 words' ); - - $this->assertTrue( IP::isIPv6( 'fc:100::' ) ); - $this->assertTrue( IP::isIPv6( 'fc:100:a::' ) ); - $this->assertTrue( IP::isIPv6( 'fc:100:a:d::' ) ); - $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1::' ) ); - $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e::' ) ); - $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e:ac::' ) ); - - $this->assertFalse( IP::isIPv6( 'fc:100:a:d:1:e:ac:0::' ), 'IPv6 with 8 words ending with "::"' ); - $this->assertFalse( IP::isIPv6( 'fc:100:a:d:1:e:ac:0:1::' ), 'IPv6 with 9 words ending with "::"' ); - - $this->assertFalse( IP::isIPv6( ':::' ) ); - $this->assertFalse( IP::isIPv6( '::0:' ), 'IPv6 ending in a lone ":"' ); - - $this->assertTrue( IP::isIPv6( '::' ), 'IPv6 zero address' ); - $this->assertTrue( IP::isIPv6( '::0' ) ); - $this->assertTrue( IP::isIPv6( '::fc' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100:a' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100:a:d' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1:e' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1:e:ac' ) ); - - $this->assertFalse( IP::isIPv6( '::fc:100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' ); - $this->assertFalse( IP::isIPv6( '::fc:100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' ); - - $this->assertFalse( IP::isIPv6( ':fc::100' ), 'IPv6 starting with lone ":"' ); - $this->assertFalse( IP::isIPv6( 'fc::100:' ), 'IPv6 ending with lone ":"' ); - $this->assertFalse( IP::isIPv6( 'fc:::100' ), 'IPv6 with ":::" in the middle' ); - - $this->assertTrue( IP::isIPv6( 'fc::100' ), 'IPv6 with "::" and 2 words' ); - $this->assertTrue( IP::isIPv6( 'fc::100:a' ), 'IPv6 with "::" and 3 words' ); - $this->assertTrue( IP::isIPv6( 'fc::100:a:d', 'IPv6 with "::" and 4 words' ) ); - $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' ); - $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1:e' ), 'IPv6 with "::" and 6 words' ); - $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' ); - $this->assertTrue( IP::isIPv6( '2001::df' ), 'IPv6 with "::" and 2 words' ); - $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df' ), 'IPv6 with "::" and 5 words' ); - $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df:2' ), 'IPv6 with "::" and 6 words' ); - - $this->assertFalse( IP::isIPv6( 'fc::100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' ); - $this->assertFalse( IP::isIPv6( 'fc::100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' ); - - $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e:ac:0' ) ); - } - - /** - * @covers IP::isIPv4 - */ - public function testisIPv4() { - $this->assertFalse( IP::isIPv4( false ), 'Boolean false is not an IP' ); - $this->assertFalse( IP::isIPv4( true ), 'Boolean true is not an IP' ); - $this->assertFalse( IP::isIPv4( "" ), 'Empty string is not an IP' ); - $this->assertFalse( IP::isIPv4( 'abc' ) ); - $this->assertFalse( IP::isIPv4( ':' ) ); - $this->assertFalse( IP::isIPv4( '124.24.52' ), 'IPv4 not enough quads' ); - $this->assertFalse( IP::isIPv4( '24.324.52.13' ), 'IPv4 out of range' ); - $this->assertFalse( IP::isIPv4( '.24.52.13' ), 'IPv4 starts with period' ); - - $this->assertTrue( IP::isIPv4( '124.24.52.13' ) ); - $this->assertTrue( IP::isIPv4( '1.24.52.13' ) ); - $this->assertTrue( IP::isIPv4( '74.24.52.13/20', 'IPv4 range' ) ); - } - - /** - * @covers IP::isValid - */ - public function testValidIPs() { - foreach ( range( 0, 255 ) as $i ) { - $a = sprintf( "%03d", $i ); - $b = sprintf( "%02d", $i ); - $c = sprintf( "%01d", $i ); - foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { - $ip = "$f.$f.$f.$f"; - $this->assertTrue( IP::isValid( $ip ), "$ip is a valid IPv4 address" ); - } - } - foreach ( range( 0x0, 0xFFFF, 0xF ) as $i ) { - $a = sprintf( "%04x", $i ); - $b = sprintf( "%03x", $i ); - $c = sprintf( "%02x", $i ); - foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { - $ip = "$f:$f:$f:$f:$f:$f:$f:$f"; - $this->assertTrue( IP::isValid( $ip ), "$ip is a valid IPv6 address" ); - } - } - // test with some abbreviations - $this->assertFalse( IP::isValid( ':fc:100::' ), 'IPv6 starting with lone ":"' ); - $this->assertFalse( IP::isValid( 'fc:100:::' ), 'IPv6 ending with a ":::"' ); - $this->assertFalse( IP::isValid( 'fc:300' ), 'IPv6 with only 2 words' ); - $this->assertFalse( IP::isValid( 'fc:100:300' ), 'IPv6 with only 3 words' ); - - $this->assertTrue( IP::isValid( 'fc:100::' ) ); - $this->assertTrue( IP::isValid( 'fc:100:a:d:1:e::' ) ); - $this->assertTrue( IP::isValid( 'fc:100:a:d:1:e:ac::' ) ); - - $this->assertTrue( IP::isValid( 'fc::100' ), 'IPv6 with "::" and 2 words' ); - $this->assertTrue( IP::isValid( 'fc::100:a' ), 'IPv6 with "::" and 3 words' ); - $this->assertTrue( IP::isValid( '2001::df' ), 'IPv6 with "::" and 2 words' ); - $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df' ), 'IPv6 with "::" and 5 words' ); - $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df:2' ), 'IPv6 with "::" and 6 words' ); - $this->assertTrue( IP::isValid( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' ); - $this->assertTrue( IP::isValid( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' ); - - $this->assertFalse( IP::isValid( 'fc:100:a:d:1:e:ac:0::' ), 'IPv6 with 8 words ending with "::"' ); - $this->assertFalse( IP::isValid( 'fc:100:a:d:1:e:ac:0:1::' ), 'IPv6 with 9 words ending with "::"' ); - } - - /** - * @covers IP::isValid - */ - public function testInvalidIPs() { - // Out of range... - foreach ( range( 256, 999 ) as $i ) { - $a = sprintf( "%03d", $i ); - $b = sprintf( "%02d", $i ); - $c = sprintf( "%01d", $i ); - foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { - $ip = "$f.$f.$f.$f"; - $this->assertFalse( IP::isValid( $ip ), "$ip is not a valid IPv4 address" ); - } - } - foreach ( range( 'g', 'z' ) as $i ) { - $a = sprintf( "%04s", $i ); - $b = sprintf( "%03s", $i ); - $c = sprintf( "%02s", $i ); - foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { - $ip = "$f:$f:$f:$f:$f:$f:$f:$f"; - $this->assertFalse( IP::isValid( $ip ), "$ip is not a valid IPv6 address" ); - } - } - // Have CIDR - $ipCIDRs = array( - '212.35.31.121/32', - '212.35.31.121/18', - '212.35.31.121/24', - '::ff:d:321:5/96', - 'ff::d3:321:5/116', - 'c:ff:12:1:ea:d:321:5/120', - ); - foreach ( $ipCIDRs as $i ) { - $this->assertFalse( IP::isValid( $i ), - "$i is an invalid IP address because it is a block" ); - } - // Incomplete/garbage - $invalid = array( - 'www.xn--var-xla.net', - '216.17.184.G', - '216.17.184.1.', - '216.17.184', - '216.17.184.', - '256.17.184.1' - ); - foreach ( $invalid as $i ) { - $this->assertFalse( IP::isValid( $i ), "$i is an invalid IP address" ); - } - } - - /** - * @covers IP::isValidBlock - */ - public function testValidBlocks() { - $valid = array( - '116.17.184.5/32', - '0.17.184.5/30', - '16.17.184.1/24', - '30.242.52.14/1', - '10.232.52.13/8', - '30.242.52.14/0', - '::e:f:2001/96', - '::c:f:2001/128', - '::10:f:2001/70', - '::fe:f:2001/1', - '::6d:f:2001/8', - '::fe:f:2001/0', - ); - foreach ( $valid as $i ) { - $this->assertTrue( IP::isValidBlock( $i ), "$i is a valid IP block" ); - } - } - - /** - * @covers IP::isValidBlock - */ - public function testInvalidBlocks() { - $invalid = array( - '116.17.184.5/33', - '0.17.184.5/130', - '16.17.184.1/-1', - '10.232.52.13/*', - '7.232.52.13/ab', - '11.232.52.13/', - '::e:f:2001/129', - '::c:f:2001/228', - '::10:f:2001/-1', - '::6d:f:2001/*', - '::86:f:2001/ab', - '::23:f:2001/', - ); - foreach ( $invalid as $i ) { - $this->assertFalse( IP::isValidBlock( $i ), "$i is not a valid IP block" ); - } - } - - /** - * Improve IP::sanitizeIP() code coverage - * @todo Most probably incomplete - */ - public function testSanitizeIP() { - $this->assertNull( IP::sanitizeIP( '' ) ); - $this->assertNull( IP::sanitizeIP( ' ' ) ); - } - - /** - * @covers IP::toUnsigned - * @dataProvider provideToUnsigned - */ - 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' ) - ); - } - - /** - * @covers IP::isPublic - */ - public function testPrivateIPs() { - $private = array( 'fc00::3', 'fc00::ff', '::1', '10.0.0.1', '172.16.0.1', '192.168.0.1' ); - foreach ( $private as $p ) { - $this->assertFalse( IP::isPublic( $p ), "$p is not a public IP address" ); - } - $public = array( '2001:5c0:1000:a::133', 'fc::3', '00FC::' ); - foreach ( $public as $p ) { - $this->assertTrue( IP::isPublic( $p ), "$p is a public IP address" ); - } - } - - // Private wrapper used to test CIDR Parsing. - private function assertFalseCIDR( $CIDR, $msg = '' ) { - $ff = array( false, false ); - $this->assertEquals( $ff, IP::parseCIDR( $CIDR ), $msg ); - } - - // Private wrapper to test network shifting using only dot notation - private function assertNet( $expected, $CIDR ) { - $parse = IP::parseCIDR( $CIDR ); - $this->assertEquals( $expected, long2ip( $parse[0] ), "network shifting $CIDR" ); - } - - /** - * @covers IP::hexToQuad - */ - public function testHexToQuad() { - $this->assertEquals( '0.0.0.1', IP::hexToQuad( '00000001' ) ); - $this->assertEquals( '255.0.0.0', IP::hexToQuad( 'FF000000' ) ); - $this->assertEquals( '255.255.255.255', IP::hexToQuad( 'FFFFFFFF' ) ); - $this->assertEquals( '10.188.222.255', IP::hexToQuad( '0ABCDEFF' ) ); - // hex not left-padded... - $this->assertEquals( '0.0.0.0', IP::hexToQuad( '0' ) ); - $this->assertEquals( '0.0.0.1', IP::hexToQuad( '1' ) ); - $this->assertEquals( '0.0.0.255', IP::hexToQuad( 'FF' ) ); - $this->assertEquals( '0.0.255.0', IP::hexToQuad( 'FF00' ) ); - } - - /** - * @covers IP::hexToOctet - */ - public function testHexToOctet() { - $this->assertEquals( '0:0:0:0:0:0:0:1', - IP::hexToOctet( '00000000000000000000000000000001' ) ); - $this->assertEquals( '0:0:0:0:0:0:FF:3', - IP::hexToOctet( '00000000000000000000000000FF0003' ) ); - $this->assertEquals( '0:0:0:0:0:0:FF00:6', - IP::hexToOctet( '000000000000000000000000FF000006' ) ); - $this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF', - IP::hexToOctet( '000000000000000000000000FCCFFAFF' ) ); - $this->assertEquals( 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF', - IP::hexToOctet( 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' ) ); - // hex not left-padded... - $this->assertEquals( '0:0:0:0:0:0:0:0', IP::hexToOctet( '0' ) ); - $this->assertEquals( '0:0:0:0:0:0:0:1', IP::hexToOctet( '1' ) ); - $this->assertEquals( '0:0:0:0:0:0:0:FF', IP::hexToOctet( 'FF' ) ); - $this->assertEquals( '0:0:0:0:0:0:0:FFD0', IP::hexToOctet( 'FFD0' ) ); - $this->assertEquals( '0:0:0:0:0:0:FA00:0', IP::hexToOctet( 'FA000000' ) ); - $this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF', IP::hexToOctet( 'FCCFFAFF' ) ); - } - - /** - * IP::parseCIDR() returns an array containing a signed IP address - * representing the network mask and the bit mask. - * @covers IP::parseCIDR - */ - public function testCIDRParsing() { - $this->assertFalseCIDR( '192.0.2.0', "missing mask" ); - $this->assertFalseCIDR( '192.0.2.0/', "missing bitmask" ); - - // Verify if statement - $this->assertFalseCIDR( '256.0.0.0/32', "invalid net" ); - $this->assertFalseCIDR( '192.0.2.0/AA', "mask not numeric" ); - $this->assertFalseCIDR( '192.0.2.0/-1', "mask < 0" ); - $this->assertFalseCIDR( '192.0.2.0/33', "mask > 32" ); - - // Check internal logic - # 0 mask always result in array(0,0) - $this->assertEquals( array( 0, 0 ), IP::parseCIDR( '192.0.0.2/0' ) ); - $this->assertEquals( array( 0, 0 ), IP::parseCIDR( '0.0.0.0/0' ) ); - $this->assertEquals( array( 0, 0 ), IP::parseCIDR( '255.255.255.255/0' ) ); - - // @todo FIXME: Add more tests. - - # This part test network shifting - $this->assertNet( '192.0.0.0', '192.0.0.2/24' ); - $this->assertNet( '192.168.5.0', '192.168.5.13/24' ); - $this->assertNet( '10.0.0.160', '10.0.0.161/28' ); - $this->assertNet( '10.0.0.0', '10.0.0.3/28' ); - $this->assertNet( '10.0.0.0', '10.0.0.3/30' ); - $this->assertNet( '10.0.0.4', '10.0.0.4/30' ); - $this->assertNet( '172.17.32.0', '172.17.35.48/21' ); - $this->assertNet( '10.128.0.0', '10.135.0.0/9' ); - $this->assertNet( '134.0.0.0', '134.0.5.1/8' ); - } - - /** - * @covers IP::canonicalize - */ - public function testIPCanonicalizeOnValidIp() { - $this->assertEquals( '192.0.2.152', IP::canonicalize( '192.0.2.152' ), - 'Canonicalization of a valid IP returns it unchanged' ); - } - - /** - * @covers IP::canonicalize - */ - public function testIPCanonicalizeMappedAddress() { - $this->assertEquals( - '192.0.2.152', - IP::canonicalize( '::ffff:192.0.2.152' ) - ); - $this->assertEquals( - '192.0.2.152', - IP::canonicalize( '::192.0.2.152' ) - ); - } - - /** - * Issues there are most probably from IP::toHex() or IP::parseRange() - * @covers IP::isInRange - * @dataProvider provideIPsAndRanges - */ - public function testIPIsInRange( $expected, $addr, $range, $message = '' ) { - $this->assertEquals( - $expected, - IP::isInRange( $addr, $range ), - $message - ); - } - - /** Provider for testIPIsInRange() */ - public static function provideIPsAndRanges() { - # Format: (expected boolean, address, range, optional message) - return array( - # IPv4 - array( true, '192.0.2.0', '192.0.2.0/24', 'Network address' ), - array( true, '192.0.2.77', '192.0.2.0/24', 'Simple address' ), - array( true, '192.0.2.255', '192.0.2.0/24', 'Broadcast address' ), - - array( false, '0.0.0.0', '192.0.2.0/24' ), - array( false, '255.255.255', '192.0.2.0/24' ), - - # IPv6 - array( false, '::1', '2001:DB8::/32' ), - array( false, '::', '2001:DB8::/32' ), - array( false, 'FE80::1', '2001:DB8::/32' ), - - array( true, '2001:DB8::', '2001:DB8::/32' ), - array( true, '2001:0DB8::', '2001:DB8::/32' ), - array( true, '2001:DB8::1', '2001:DB8::/32' ), - array( true, '2001:0DB8::1', '2001:DB8::/32' ), - array( true, '2001:0DB8:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF', - '2001:DB8::/32' ), - - array( false, '2001:0DB8:F::', '2001:DB8::/96' ), - ); - } - - /** - * Test for IP::splitHostAndPort(). - * @dataProvider provideSplitHostAndPort - */ - public function testSplitHostAndPort( $expected, $input, $description ) { - $this->assertEquals( $expected, IP::splitHostAndPort( $input ), $description ); - } - - /** - * Provider for IP::splitHostAndPort() - */ - public static function provideSplitHostAndPort() { - return array( - array( false, '[', 'Unclosed square bracket' ), - array( false, '[::', 'Unclosed square bracket 2' ), - array( array( '::', false ), '::', 'Bare IPv6 0' ), - array( array( '::1', false ), '::1', 'Bare IPv6 1' ), - array( array( '::', false ), '[::]', 'Bracketed IPv6 0' ), - array( array( '::1', false ), '[::1]', 'Bracketed IPv6 1' ), - array( array( '::1', 80 ), '[::1]:80', 'Bracketed IPv6 with port' ), - array( false, '::x', 'Double colon but no IPv6' ), - array( array( 'x', 80 ), 'x:80', 'Hostname and port' ), - array( false, 'x:x', 'Hostname and invalid port' ), - array( array( 'x', false ), 'x', 'Plain hostname' ) - ); - } - - /** - * Test for IP::combineHostAndPort() - * @dataProvider provideCombineHostAndPort - */ - public function testCombineHostAndPort( $expected, $input, $description ) { - list( $host, $port, $defaultPort ) = $input; - $this->assertEquals( - $expected, - IP::combineHostAndPort( $host, $port, $defaultPort ), - $description ); - } - - /** - * Provider for IP::combineHostAndPort() - */ - public static function provideCombineHostAndPort() { - return array( - array( '[::1]', array( '::1', 2, 2 ), 'IPv6 default port' ), - array( '[::1]:2', array( '::1', 2, 3 ), 'IPv6 non-default port' ), - array( 'x', array( 'x', 2, 2 ), 'Normal default port' ), - array( 'x:2', array( 'x', 2, 3 ), 'Normal non-default port' ), - ); - } - - /** - * Test for IP::sanitizeRange() - * @dataProvider provideIPCIDRs - */ - public function testSanitizeRange( $input, $expected, $description ) { - $this->assertEquals( $expected, IP::sanitizeRange( $input ), $description ); - } - - /** - * Provider for IP::testSanitizeRange() - */ - public static function provideIPCIDRs() { - return array( - array( '35.56.31.252/16', '35.56.0.0/16', 'IPv4 range' ), - array( '135.16.21.252/24', '135.16.21.0/24', 'IPv4 range' ), - array( '5.36.71.252/32', '5.36.71.252/32', 'IPv4 silly range' ), - array( '5.36.71.252', '5.36.71.252', 'IPv4 non-range' ), - array( '0:1:2:3:4:c5:f6:7/96', '0:1:2:3:4:C5:0:0/96', 'IPv6 range' ), - array( '0:1:2:3:4:5:6:7/120', '0:1:2:3:4:5:6:0/120', 'IPv6 range' ), - array( '0:e1:2:3:4:5:e6:7/128', '0:E1:2:3:4:5:E6:7/128', 'IPv6 silly range' ), - array( '0:c1:A2:3:4:5:c6:7', '0:C1:A2:3:4:5:C6:7', 'IPv6 non range' ), - ); - } - - /** - * Test for IP::prettifyIP() - * @dataProvider provideIPsToPrettify - */ - public function testPrettifyIP( $ip, $prettified ) { - $this->assertEquals( $prettified, IP::prettifyIP( $ip ), "Prettify of $ip" ); - } - - /** - * Provider for IP::testPrettifyIP() - */ - public static function provideIPsToPrettify() { - return array( - array( '0:0:0:0:0:0:0:0', '::' ), - array( '0:0:0::0:0:0', '::' ), - array( '0:0:0:1:0:0:0:0', '0:0:0:1::' ), - array( '0:0::f', '::f' ), - array( '0::0:0:0:33:fef:b', '::33:fef:b' ), - array( '3f:535:0:0:0:0:e:fbb', '3f:535::e:fbb' ), - array( '0:0:fef:0:0:0:e:fbb', '0:0:fef::e:fbb' ), - array( 'abbc:2004::0:0:0:0', 'abbc:2004::' ), - array( 'cebc:2004:f:0:0:0:0:0', 'cebc:2004:f::' ), - array( '0:0:0:0:0:0:0:0/16', '::/16' ), - array( '0:0:0::0:0:0/64', '::/64' ), - array( '0:0::f/52', '::f/52' ), - array( '::0:0:33:fef:b/52', '::33:fef:b/52' ), - array( '3f:535:0:0:0:0:e:fbb/48', '3f:535::e:fbb/48' ), - array( '0:0:fef:0:0:0:e:fbb/96', '0:0:fef::e:fbb/96' ), - array( 'abbc:2004:0:0::0:0/40', 'abbc:2004::/40' ), - array( 'aebc:2004:f:0:0:0:0:0/80', 'aebc:2004:f::/80' ), - ); - } -} diff --git a/tests/phpunit/includes/LanguageConverterTest.php b/tests/phpunit/includes/LanguageConverterTest.php deleted file mode 100644 index 7c2134b9..00000000 --- a/tests/phpunit/includes/LanguageConverterTest.php +++ /dev/null @@ -1,148 +0,0 @@ -<?php - -class LanguageConverterTest extends MediaWikiLangTestCase { - protected $lang = null; - protected $lc = null; - - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgContLang' => Language::factory( 'tg' ), - 'wgLanguageCode' => 'tg', - 'wgDefaultLanguageVariant' => false, - 'wgMemc' => new EmptyBagOStuff, - 'wgRequest' => new FauxRequest( array() ), - 'wgUser' => new User, - ) ); - - $this->lang = new LanguageToTest(); - $this->lc = new TestConverter( - $this->lang, 'tg', - array( 'tg', 'tg-latn' ) - ); - } - - protected function tearDown() { - unset( $this->lc ); - unset( $this->lang ); - - parent::tearDown(); - } - - public function testGetPreferredVariantDefaults() { - $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); - } - - public function testGetPreferredVariantHeaders() { - global $wgRequest; - $wgRequest->setHeader( 'Accept-Language', 'tg-latn' ); - - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); - } - - public function testGetPreferredVariantHeaderWeight() { - global $wgRequest; - $wgRequest->setHeader( 'Accept-Language', 'tg;q=1' ); - - $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); - } - - public function testGetPreferredVariantHeaderWeight2() { - global $wgRequest; - $wgRequest->setHeader( 'Accept-Language', 'tg-latn;q=1' ); - - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); - } - - public function testGetPreferredVariantHeaderMulti() { - global $wgRequest; - $wgRequest->setHeader( 'Accept-Language', 'en, tg-latn;q=1' ); - - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); - } - - public function testGetPreferredVariantUserOption() { - global $wgUser; - - $wgUser = new User; - $wgUser->load(); // from 'defaults' - $wgUser->mId = 1; - $wgUser->mDataLoaded = true; - $wgUser->mOptionsLoaded = true; - $wgUser->setOption( 'variant', 'tg-latn' ); - - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); - } - - 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' ); - $wgRequest->setVal( 'variant', 'tg' ); - $wgUser = User::newFromId( "admin" ); - $wgUser->setId( 1 ); - $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' ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); - } - - - public function testGetPreferredVariantDefaultLanguageVariant() { - global $wgDefaultLanguageVariant; - - $wgDefaultLanguageVariant = 'tg-latn'; - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); - } - - public function testGetPreferredVariantDefaultLanguageVsUrlVariant() { - global $wgDefaultLanguageVariant, $wgRequest, $wgContLang; - - $wgContLang = Language::factory( 'tg-latn' ); - $wgDefaultLanguageVariant = 'tg'; - $wgRequest->setVal( 'variant', null ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); - } -} - -/** - * Test converter (from Tajiki to latin orthography) - */ -class TestConverter extends LanguageConverter { - private $table = array( - 'б' => 'b', - 'в' => 'v', - 'г' => 'g', - ); - - function loadDefaultTables() { - $this->mTables = array( - 'tg-latn' => new ReplacementArray( $this->table ), - 'tg' => new ReplacementArray() - ); - } -} - -class LanguageToTest extends Language { - function __construct() { - parent::__construct(); - $variants = array( 'tg', 'tg-latn' ); - $this->mConverter = new TestConverter( $this, 'tg', $variants ); - } -} diff --git a/tests/phpunit/includes/LicensesTest.php b/tests/phpunit/includes/LicensesTest.php deleted file mode 100644 index 478a2ffc..00000000 --- a/tests/phpunit/includes/LicensesTest.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php - -class LicensesTest extends MediaWikiTestCase { - - public function testLicenses() { - $str = " -* Free licenses: -** GFDL|Debian disagrees -"; - - $lc = new Licenses( array( - 'fieldname' => 'FooField', - 'type' => 'select', - 'section' => 'description', - 'id' => 'wpLicense', - 'label' => 'A label text', # Note can't test label-message because $wgOut is not defined - 'name' => 'AnotherName', - 'licenses' => $str, - ) ); - $this->assertThat( $lc, $this->isInstanceOf( 'Licenses' ) ); - } -} diff --git a/tests/phpunit/includes/LinkerTest.php b/tests/phpunit/includes/LinkerTest.php deleted file mode 100644 index b605f08f..00000000 --- a/tests/phpunit/includes/LinkerTest.php +++ /dev/null @@ -1,71 +0,0 @@ -<?php - -class LinkerTest extends MediaWikiLangTestCase { - - /** - * @dataProvider provideCasesForUserLink - * @covers Linker::userLink - */ - public function testUserLink( $expected, $userId, $userName, $altUserName = false, $msg = '' ) { - $this->setMwGlobals( array( - 'wgArticlePath' => '/wiki/$1', - 'wgWellFormedXml' => true, - ) ); - - $this->assertEquals( $expected, - Linker::userLink( $userId, $userName, $altUserName, $msg ) - ); - } - - public static function provideCasesForUserLink() { - # Format: - # - expected - # - userid - # - username - # - optional altUserName - # - optional message - return array( - - ### ANONYMOUS USER ######################################## - array( - '<a href="/wiki/Special:Contributions/JohnDoe" title="Special:Contributions/JohnDoe" class="mw-userlink">JohnDoe</a>', - 0, 'JohnDoe', false, - ), - array( - '<a href="/wiki/Special:Contributions/::1" title="Special:Contributions/::1" class="mw-userlink">::1</a>', - 0, '::1', false, - 'Anonymous with pretty IPv6' - ), - array( - '<a href="/wiki/Special:Contributions/0:0:0:0:0:0:0:1" title="Special:Contributions/0:0:0:0:0:0:0:1" class="mw-userlink">::1</a>', - 0, '0:0:0:0:0:0:0:1', false, - 'Anonymous with almost pretty IPv6' - ), - array( - '<a href="/wiki/Special:Contributions/0000:0000:0000:0000:0000:0000:0000:0001" title="Special:Contributions/0000:0000:0000:0000:0000:0000:0000:0001" class="mw-userlink">::1</a>', - 0, '0000:0000:0000:0000:0000:0000:0000:0001', false, - 'Anonymous with full IPv6' - ), - array( - '<a href="/wiki/Special:Contributions/::1" title="Special:Contributions/::1" class="mw-userlink">AlternativeUsername</a>', - 0, '::1', 'AlternativeUsername', - 'Anonymous with pretty IPv6 and an alternative username' - ), - - # IPV4 - array( - '<a href="/wiki/Special:Contributions/127.0.0.1" title="Special:Contributions/127.0.0.1" class="mw-userlink">127.0.0.1</a>', - 0, '127.0.0.1', false, - 'Anonymous with IPv4' - ), - array( - '<a href="/wiki/Special:Contributions/127.0.0.1" title="Special:Contributions/127.0.0.1" class="mw-userlink">AlternativeUsername</a>', - 0, '127.0.0.1', 'AlternativeUsername', - 'Anonymous with IPv4 and an alternative username' - ), - - ### Regular user ########################################## - # TODO! - ); - } -} diff --git a/tests/phpunit/includes/LinksUpdateTest.php b/tests/phpunit/includes/LinksUpdateTest.php deleted file mode 100644 index 5ade250e..00000000 --- a/tests/phpunit/includes/LinksUpdateTest.php +++ /dev/null @@ -1,175 +0,0 @@ -<?php - -/** - * - * @group Database - * ^--- make sure temporary tables are used. - */ -class LinksUpdateTest extends MediaWikiTestCase { - - function __construct( $name = null, array $data = array(), $dataName = '' ) { - parent::__construct( $name, $data, $dataName ); - - $this->tablesUsed = array_merge( $this->tablesUsed, - array( - 'interwiki', - 'page_props', - 'pagelinks', - 'categorylinks', - 'langlinks', - 'externallinks', - 'imagelinks', - 'templatelinks', - 'iwlinks' - ) - ); - } - - protected function setUp() { - parent::setUp(); - $dbw = wfGetDB( DB_MASTER ); - $dbw->replace( - 'interwiki', - array( 'iw_prefix' ), - array( - 'iw_prefix' => 'linksupdatetest', - 'iw_url' => 'http://testing.com/wiki/$1', - 'iw_api' => 'http://testing.com/w/api.php', - 'iw_local' => 0, - 'iw_trans' => 0, - 'iw_wikiid' => 'linksupdatetest', - ) - ); - } - - protected function makeTitleAndParserOutput( $name, $id ) { - $t = Title::newFromText( $name ); - $t->mArticleID = $id; # XXX: this is fugly - - $po = new ParserOutput(); - $po->setTitleText( $t->getPrefixedText() ); - - return array( $t, $po ); - } - - public function testUpdate_pagelinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addLink( Title::newFromText( "Foo" ) ); - $po->addLink( Title::newFromText( "Special:Foo" ) ); // special namespace should be ignored - $po->addLink( Title::newFromText( "linksupdatetest:Foo" ) ); // interwiki link should be ignored - $po->addLink( Title::newFromText( "#Foo" ) ); // hash link should be ignored - - $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" ) ); - - $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() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addExternalLink( "http://testing.com/wiki/Foo" ); - - $this->assertLinksUpdate( $t, $po, 'externallinks', 'el_to, el_index', 'el_from = 111', array( - array( 'http://testing.com/wiki/Foo', 'http://com.testing./wiki/Foo' ), - ) ); - } - - public function testUpdate_categorylinks() { - $this->setMwGlobals( 'wgCategoryCollation', 'uppercase' ); - - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addCategory( "Foo", "FOO" ); - - $this->assertLinksUpdate( $t, $po, 'categorylinks', 'cl_to, cl_sortkey', 'cl_from = 111', array( - array( 'Foo', "FOO\nTESTING" ), - ) ); - } - - public function testUpdate_iwlinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $target = Title::makeTitleSafe( NS_MAIN, "Foo", '', 'linksupdatetest' ); - $po->addInterwikiLink( $target ); - - $this->assertLinksUpdate( $t, $po, 'iwlinks', 'iwl_prefix, iwl_title', 'iwl_from = 111', array( - array( 'linksupdatetest', 'Foo' ), - ) ); - } - - public function testUpdate_templatelinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addTemplate( Title::newFromText( "Template:Foo" ), 23, 42 ); - - $this->assertLinksUpdate( $t, $po, 'templatelinks', 'tl_namespace, tl_title', 'tl_from = 111', array( - array( NS_TEMPLATE, 'Foo' ), - ) ); - } - - public function testUpdate_imagelinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addImage( "Foo.png" ); - - $this->assertLinksUpdate( $t, $po, 'imagelinks', 'il_to', 'il_from = 111', array( - array( 'Foo.png' ), - ) ); - } - - public function testUpdate_langlinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addLanguageLink( Title::newFromText( "en:Foo" )->getFullText() ); - - $this->assertLinksUpdate( $t, $po, 'langlinks', 'll_lang, ll_title', 'll_from = 111', array( - array( 'En', 'Foo' ), - ) ); - } - - public function testUpdate_page_props() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->setProperty( "foo", "bar" ); - - $this->assertLinksUpdate( $t, $po, 'page_props', 'pp_propname, pp_value', 'pp_page = 111', array( - array( 'foo', 'bar' ), - ) ); - } - - // @todo test recursive, too! - - protected function assertLinksUpdate( Title $title, ParserOutput $parserOutput, $table, $fields, $condition, array $expectedRows ) { - $update = new LinksUpdate( $title, $parserOutput ); - - //NOTE: make sure LinksUpdate does not generate warnings when called inside a transaction. - $update->beginTransaction(); - $update->doUpdate(); - $update->commitTransaction(); - - $this->assertSelect( $table, $fields, $condition, $expectedRows ); - return $update; - } -} diff --git a/tests/phpunit/includes/LocalFileTest.php b/tests/phpunit/includes/LocalFileTest.php deleted file mode 100644 index 2501c783..00000000 --- a/tests/phpunit/includes/LocalFileTest.php +++ /dev/null @@ -1,107 +0,0 @@ -<?php - -/** - * These tests should work regardless of $wgCapitalLinks - * @group Database - */ - -class LocalFileTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( 'wgCapitalLinks', true ); - - $info = array( - 'name' => 'test', - 'directory' => '/testdir', - 'url' => '/testurl', - 'hashLevels' => 2, - 'transformVia404' => false, - 'backend' => new FSFileBackend( array( - 'name' => 'local-backend', - 'lockManager' => 'fsLockManager', - 'containerPaths' => array( - 'cont1' => "/testdir/local-backend/tempimages/cont1", - 'cont2' => "/testdir/local-backend/tempimages/cont2" - ) - ) ) - ); - $this->repo_hl0 = new LocalRepo( array( 'hashLevels' => 0 ) + $info ); - $this->repo_hl2 = new LocalRepo( array( 'hashLevels' => 2 ) + $info ); - $this->repo_lc = new LocalRepo( array( 'initialCapital' => false ) + $info ); - $this->file_hl0 = $this->repo_hl0->newFile( 'test!' ); - $this->file_hl2 = $this->repo_hl2->newFile( 'test!' ); - $this->file_lc = $this->repo_lc->newFile( 'test!' ); - } - - 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() ); - } - - 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() ); - } - - 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() ); - } - - 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( '!' ) ); - } - - 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' ) ); - } - - 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( '!' ) ); - } - - 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' ) ); - } - - 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( '!' ) ); - } - - 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( '!' ) ); - } - - public function testGetUrl() { - $this->assertEquals( '/testurl/Test%21', $this->file_hl0->getUrl() ); - $this->assertEquals( '/testurl/a/a2/Test%21', $this->file_hl2->getUrl() ); - } - - 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/LocalisationCacheTest.php b/tests/phpunit/includes/LocalisationCacheTest.php deleted file mode 100644 index b34847aa..00000000 --- a/tests/phpunit/includes/LocalisationCacheTest.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php - -class LocalisationCacheTest extends MediaWikiTestCase { - public function testPuralRulesFallback() { - $cache = Language::getLocalisationCache(); - - $this->assertEquals( - $cache->getItem( 'ar', 'pluralRules' ), - $cache->getItem( 'arz', 'pluralRules' ), - 'arz plural rules (undefined) fallback to ar (defined)' - ); - - $this->assertEquals( - $cache->getItem( 'ar', 'compiledPluralRules' ), - $cache->getItem( 'arz', 'compiledPluralRules' ), - 'arz compiled plural rules (undefined) fallback to ar (defined)' - ); - - $this->assertNotEquals( - $cache->getItem( 'ksh', 'pluralRules' ), - $cache->getItem( 'de', 'pluralRules' ), - 'ksh plural rules (defined) dont fallback to de (defined)' - ); - - $this->assertNotEquals( - $cache->getItem( 'ksh', 'compiledPluralRules' ), - $cache->getItem( 'de', 'compiledPluralRules' ), - 'ksh compiled plural rules (defined) dont fallback to de (defined)' - ); - } -} diff --git a/tests/phpunit/includes/MWExceptionHandlerTest.php b/tests/phpunit/includes/MWExceptionHandlerTest.php deleted file mode 100644 index 987dfa83..00000000 --- a/tests/phpunit/includes/MWExceptionHandlerTest.php +++ /dev/null @@ -1,73 +0,0 @@ -<?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 deleted file mode 100644 index d86f2c9b..00000000 --- a/tests/phpunit/includes/MWFunctionTest.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php - -class MWFunctionTest extends MediaWikiTestCase { - public function testNewObjFunction() { - $arg1 = 'Foo'; - $arg2 = 'Bar'; - $arg3 = array( 'Baz' ); - $arg4 = new ExampleObject; - - $args = array( $arg1, $arg2, $arg3, $arg4 ); - - $newObject = new MWBlankClass( $arg1, $arg2, $arg3, $arg4 ); - $this->assertEquals( - MWFunction::newObj( 'MWBlankClass', $args )->args, - $newObject->args - ); - } -} - -class MWBlankClass { - - public $args = array(); - - function __construct( $arg1, $arg2, $arg3, $arg4 ) { - $this->args = array( $arg1, $arg2, $arg3, $arg4 ); - } -} - -class ExampleObject { -} diff --git a/tests/phpunit/includes/MWNamespaceTest.php b/tests/phpunit/includes/MWNamespaceTest.php deleted file mode 100644 index 10e9db61..00000000 --- a/tests/phpunit/includes/MWNamespaceTest.php +++ /dev/null @@ -1,571 +0,0 @@ -<?php -/** - * @author Antoine Musso - * @copyright Copyright © 2011, Antoine Musso - * @file - */ - -/** - * Test class for MWNamespace. - * Generated by PHPUnit on 2011-02-20 at 21:01:55. - * - */ -class MWNamespaceTest extends MediaWikiTestCase { - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgContentNamespaces' => array( NS_MAIN ), - 'wgNamespacesWithSubpages' => array( - NS_TALK => true, - NS_USER => true, - NS_USER_TALK => true, - ), - 'wgCapitalLinks' => true, - 'wgCapitalLinkOverrides' => array(), - 'wgNonincludableNamespaces' => array(), - ) ); - } - -#### START OF TESTS ######################################################### - - /** - * @todo Write more texts, handle $wgAllowImageMoving setting - */ - public function testIsMovable() { - $this->assertFalse( MWNamespace::isMovable( NS_CATEGORY ) ); - # @todo FIXME: Write more tests!! - } - - /** - * Please make sure to change testIsTalk() if you change the assertions below - */ - public function testIsSubject() { - // Special namespaces - $this->assertIsSubject( NS_MEDIA ); - $this->assertIsSubject( NS_SPECIAL ); - - // Subject pages - $this->assertIsSubject( NS_MAIN ); - $this->assertIsSubject( NS_USER ); - $this->assertIsSubject( 100 ); # user defined - - // Talk pages - $this->assertIsNotSubject( NS_TALK ); - $this->assertIsNotSubject( NS_USER_TALK ); - $this->assertIsNotSubject( 101 ); # user defined - } - - /** - * Reverse of testIsSubject(). - * Please update testIsSubject() if you change assertions below - */ - public function testIsTalk() { - // Special namespaces - $this->assertIsNotTalk( NS_MEDIA ); - $this->assertIsNotTalk( NS_SPECIAL ); - - // Subject pages - $this->assertIsNotTalk( NS_MAIN ); - $this->assertIsNotTalk( NS_USER ); - $this->assertIsNotTalk( 100 ); # user defined - - // Talk pages - $this->assertIsTalk( NS_TALK ); - $this->assertIsTalk( NS_USER_TALK ); - $this->assertIsTalk( 101 ); # user defined - } - - /** - */ - public function testGetSubject() { - // Special namespaces are their own subjects - $this->assertEquals( NS_MEDIA, MWNamespace::getSubject( NS_MEDIA ) ); - $this->assertEquals( NS_SPECIAL, MWNamespace::getSubject( NS_SPECIAL ) ); - - $this->assertEquals( NS_MAIN, MWNamespace::getSubject( NS_TALK ) ); - $this->assertEquals( NS_USER, MWNamespace::getSubject( NS_USER_TALK ) ); - } - - /** - * Regular getTalk() calls - * Namespaces without a talk page (NS_MEDIA, NS_SPECIAL) are tested in - * the function testGetTalkExceptions() - */ - public function testGetTalk() { - $this->assertEquals( NS_TALK, MWNamespace::getTalk( NS_MAIN ) ); - $this->assertEquals( NS_TALK, MWNamespace::getTalk( NS_TALK ) ); - $this->assertEquals( NS_USER_TALK, MWNamespace::getTalk( NS_USER ) ); - $this->assertEquals( NS_USER_TALK, MWNamespace::getTalk( NS_USER_TALK ) ); - } - - /** - * Exceptions with getTalk() - * NS_MEDIA does not have talk pages. MediaWiki raise an exception for them. - * @expectedException MWException - */ - public function testGetTalkExceptionsForNsMedia() { - $this->assertNull( MWNamespace::getTalk( NS_MEDIA ) ); - } - - /** - * Exceptions with getTalk() - * NS_SPECIAL does not have talk pages. MediaWiki raise an exception for them. - * @expectedException MWException - */ - public function testGetTalkExceptionsForNsSpecial() { - $this->assertNull( MWNamespace::getTalk( NS_SPECIAL ) ); - } - - /** - * Regular getAssociated() calls - * Namespaces without an associated page (NS_MEDIA, NS_SPECIAL) are tested in - * the function testGetAssociatedExceptions() - */ - public function testGetAssociated() { - $this->assertEquals( NS_TALK, MWNamespace::getAssociated( NS_MAIN ) ); - $this->assertEquals( NS_MAIN, MWNamespace::getAssociated( NS_TALK ) ); - } - - ### Exceptions with getAssociated() - ### NS_MEDIA and NS_SPECIAL do not have talk pages. MediaWiki raises - ### an exception for them. - /** - * @expectedException MWException - */ - public function testGetAssociatedExceptionsForNsMedia() { - $this->assertNull( MWNamespace::getAssociated( NS_MEDIA ) ); - } - - /** - * @expectedException MWException - */ - public function testGetAssociatedExceptionsForNsSpecial() { - $this->assertNull( MWNamespace::getAssociated( NS_SPECIAL ) ); - } - - /** - * @todo Implement testExists(). - */ - /* - public function testExists() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.' - ); - } - */ - - /** - * Test MWNamespace::equals - * Note if we add a namespace registration system with keys like 'MAIN' - * we should add tests here for equivilance on things like 'MAIN' == 0 - * and 'MAIN' == NS_MAIN. - */ - public function testEquals() { - $this->assertTrue( MWNamespace::equals( NS_MAIN, NS_MAIN ) ); - $this->assertTrue( MWNamespace::equals( NS_MAIN, 0 ) ); // In case we make NS_MAIN 'MAIN' - $this->assertTrue( MWNamespace::equals( NS_USER, NS_USER ) ); - $this->assertTrue( MWNamespace::equals( NS_USER, 2 ) ); - $this->assertTrue( MWNamespace::equals( NS_USER_TALK, NS_USER_TALK ) ); - $this->assertTrue( MWNamespace::equals( NS_SPECIAL, NS_SPECIAL ) ); - $this->assertFalse( MWNamespace::equals( NS_MAIN, NS_TALK ) ); - $this->assertFalse( MWNamespace::equals( NS_USER, NS_USER_TALK ) ); - $this->assertFalse( MWNamespace::equals( NS_PROJECT, NS_TEMPLATE ) ); - } - - /** - * Test MWNamespace::subjectEquals - */ - public function testSubjectEquals() { - $this->assertSameSubject( NS_MAIN, NS_MAIN ); - $this->assertSameSubject( NS_MAIN, 0 ); // In case we make NS_MAIN 'MAIN' - $this->assertSameSubject( NS_USER, NS_USER ); - $this->assertSameSubject( NS_USER, 2 ); - $this->assertSameSubject( NS_USER_TALK, NS_USER_TALK ); - $this->assertSameSubject( NS_SPECIAL, NS_SPECIAL ); - $this->assertSameSubject( NS_MAIN, NS_TALK ); - $this->assertSameSubject( NS_USER, NS_USER_TALK ); - - $this->assertDifferentSubject( NS_PROJECT, NS_TEMPLATE ); - $this->assertDifferentSubject( NS_SPECIAL, NS_MAIN ); - } - - public function testSpecialAndMediaAreDifferentSubjects() { - $this->assertDifferentSubject( - NS_MEDIA, NS_SPECIAL, - "NS_MEDIA and NS_SPECIAL are different subject namespaces" - ); - $this->assertDifferentSubject( - NS_SPECIAL, NS_MEDIA, - "NS_SPECIAL and NS_MEDIA are different subject namespaces" - ); - } - - /** - * @todo Implement testGetCanonicalNamespaces(). - */ - /* - public function testGetCanonicalNamespaces() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.' - ); - } - */ - /** - * @todo Implement testGetCanonicalName(). - */ - /* - public function testGetCanonicalName() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.' - ); - } - */ - /** - * @todo Implement testGetCanonicalIndex(). - */ - /* - public function testGetCanonicalIndex() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.' - ); - } - */ - - /** - * @todo Implement testGetValidNamespaces(). - */ - /* - public function testGetValidNamespaces() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.' - ); - } - */ - - /** - */ - public function testCanTalk() { - $this->assertCanNotTalk( NS_MEDIA ); - $this->assertCanNotTalk( NS_SPECIAL ); - - $this->assertCanTalk( NS_MAIN ); - $this->assertCanTalk( NS_TALK ); - $this->assertCanTalk( NS_USER ); - $this->assertCanTalk( NS_USER_TALK ); - - // User defined namespaces - $this->assertCanTalk( 100 ); - $this->assertCanTalk( 101 ); - } - - /** - */ - public function testIsContent() { - // NS_MAIN is a content namespace per DefaultSettings.php - // and per function definition. - - $this->assertIsContent( NS_MAIN ); - - // Other namespaces which are not expected to be content - - $this->assertIsNotContent( NS_MEDIA ); - $this->assertIsNotContent( NS_SPECIAL ); - $this->assertIsNotContent( NS_TALK ); - $this->assertIsNotContent( NS_USER ); - $this->assertIsNotContent( NS_CATEGORY ); - $this->assertIsNotContent( 100 ); - } - - /** - * Similar to testIsContent() but alters the $wgContentNamespaces - * global variable. - */ - public function testIsContentAdvanced() { - global $wgContentNamespaces; - - // Test that user defined namespace #252 is not content - $this->assertIsNotContent( 252 ); - - // Bless namespace # 252 as a content namespace - $wgContentNamespaces[] = 252; - - $this->assertIsContent( 252 ); - - // Makes sure NS_MAIN was not impacted - $this->assertIsContent( NS_MAIN ); - } - - public function testIsWatchable() { - // Specials namespaces are not watchable - $this->assertIsNotWatchable( NS_MEDIA ); - $this->assertIsNotWatchable( NS_SPECIAL ); - - // Core defined namespaces are watchables - $this->assertIsWatchable( NS_MAIN ); - $this->assertIsWatchable( NS_TALK ); - - // Additional, user defined namespaces are watchables - $this->assertIsWatchable( 100 ); - $this->assertIsWatchable( 101 ); - } - - public function testHasSubpages() { - global $wgNamespacesWithSubpages; - - // Special namespaces: - $this->assertHasNotSubpages( NS_MEDIA ); - $this->assertHasNotSubpages( NS_SPECIAL ); - - // Namespaces without subpages - $this->assertHasNotSubpages( NS_MAIN ); - - $wgNamespacesWithSubpages[NS_MAIN] = true; - $this->assertHasSubpages( NS_MAIN ); - - $wgNamespacesWithSubpages[NS_MAIN] = false; - $this->assertHasNotSubpages( NS_MAIN ); - - // Some namespaces with subpages - $this->assertHasSubpages( NS_TALK ); - $this->assertHasSubpages( NS_USER ); - $this->assertHasSubpages( NS_USER_TALK ); - } - - /** - */ - public function testGetContentNamespaces() { - global $wgContentNamespaces; - - $this->assertEquals( - array( NS_MAIN ), - MWNamespace::getContentNamespaces(), - '$wgContentNamespaces is an array with only NS_MAIN by default' - ); - - # test !is_array( $wgcontentNamespaces ) - $wgContentNamespaces = ''; - $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); - - $wgContentNamespaces = false; - $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); - - $wgContentNamespaces = null; - $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); - - $wgContentNamespaces = 5; - $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); - - # test $wgContentNamespaces === array() - $wgContentNamespaces = array(); - $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(), - 'NS_MAIN is forced in $wgContentNamespaces even if unwanted' - ); - - # test other cases, return $wgcontentNamespaces as is - $wgContentNamespaces = array( NS_MAIN ); - $this->assertEquals( - array( NS_MAIN ), - MWNamespace::getContentNamespaces() - ); - - $wgContentNamespaces = array( NS_MAIN, NS_USER, NS_CATEGORY ); - $this->assertEquals( - array( NS_MAIN, NS_USER, NS_CATEGORY ), - MWNamespace::getContentNamespaces() - ); - } - - /** - */ - public function testGetSubjectNamespaces() { - $subjectsNS = MWNamespace::getSubjectNamespaces(); - $this->assertContains( NS_MAIN, $subjectsNS, - "Talk namespaces should have NS_MAIN" ); - $this->assertNotContains( NS_TALK, $subjectsNS, - "Talk namespaces should have NS_TALK" ); - - $this->assertNotContains( NS_MEDIA, $subjectsNS, - "Talk namespaces should not have NS_MEDIA" ); - $this->assertNotContains( NS_SPECIAL, $subjectsNS, - "Talk namespaces should not have NS_SPECIAL" ); - } - - /** - */ - public function testGetTalkNamespaces() { - $talkNS = MWNamespace::getTalkNamespaces(); - $this->assertContains( NS_TALK, $talkNS, - "Subject namespaces should have NS_TALK" ); - $this->assertNotContains( NS_MAIN, $talkNS, - "Subject namespaces should not have NS_MAIN" ); - - $this->assertNotContains( NS_MEDIA, $talkNS, - "Subject namespaces should not have NS_MEDIA" ); - $this->assertNotContains( NS_SPECIAL, $talkNS, - "Subject namespaces should not have NS_SPECIAL" ); - } - - /** - * Some namespaces are always capitalized per code definition - * in MWNamespace::$alwaysCapitalizedNamespaces - */ - public function testIsCapitalizedHardcodedAssertions() { - // NS_MEDIA and NS_FILE are treated the same - $this->assertEquals( - MWNamespace::isCapitalized( NS_MEDIA ), - MWNamespace::isCapitalized( NS_FILE ), - 'NS_MEDIA and NS_FILE have same capitalization rendering' - ); - - // Boths are capitalized by default - $this->assertIsCapitalized( NS_MEDIA ); - $this->assertIsCapitalized( NS_FILE ); - - // Always capitalized namespaces - // @see MWNamespace::$alwaysCapitalizedNamespaces - $this->assertIsCapitalized( NS_SPECIAL ); - $this->assertIsCapitalized( NS_USER ); - $this->assertIsCapitalized( NS_MEDIAWIKI ); - } - - /** - * Follows up for testIsCapitalizedHardcodedAssertions() but alter the - * global $wgCapitalLink setting to have extended coverage. - * - * MWNamespace::isCapitalized() rely on two global settings: - * $wgCapitalLinkOverrides = array(); by default - * $wgCapitalLinks = true; by default - * This function test $wgCapitalLinks - * - * Global setting correctness is tested against the NS_PROJECT and - * NS_PROJECT_TALK namespaces since they are not hardcoded nor specials - */ - public function testIsCapitalizedWithWgCapitalLinks() { - global $wgCapitalLinks; - - $this->assertIsCapitalized( NS_PROJECT ); - $this->assertIsCapitalized( NS_PROJECT_TALK ); - - $wgCapitalLinks = false; - - // hardcoded namespaces (see above function) are still capitalized: - $this->assertIsCapitalized( NS_SPECIAL ); - $this->assertIsCapitalized( NS_USER ); - $this->assertIsCapitalized( NS_MEDIAWIKI ); - - // setting is correctly applied - $this->assertIsNotCapitalized( NS_PROJECT ); - $this->assertIsNotCapitalized( NS_PROJECT_TALK ); - } - - /** - * Counter part for MWNamespace::testIsCapitalizedWithWgCapitalLinks() now - * testing the $wgCapitalLinkOverrides global. - * - * @todo split groups of assertions in autonomous testing functions - */ - public function testIsCapitalizedWithWgCapitalLinkOverrides() { - global $wgCapitalLinkOverrides; - - // Test default settings - $this->assertIsCapitalized( NS_PROJECT ); - $this->assertIsCapitalized( NS_PROJECT_TALK ); - - // hardcoded namespaces (see above function) are capitalized: - $this->assertIsCapitalized( NS_SPECIAL ); - $this->assertIsCapitalized( NS_USER ); - $this->assertIsCapitalized( NS_MEDIAWIKI ); - - // Hardcoded namespaces remains capitalized - $wgCapitalLinkOverrides[NS_SPECIAL] = false; - $wgCapitalLinkOverrides[NS_USER] = false; - $wgCapitalLinkOverrides[NS_MEDIAWIKI] = false; - - $this->assertIsCapitalized( NS_SPECIAL ); - $this->assertIsCapitalized( NS_USER ); - $this->assertIsCapitalized( NS_MEDIAWIKI ); - - $wgCapitalLinkOverrides[NS_PROJECT] = false; - $this->assertIsNotCapitalized( NS_PROJECT ); - - $wgCapitalLinkOverrides[NS_PROJECT] = true; - $this->assertIsCapitalized( NS_PROJECT ); - - unset( $wgCapitalLinkOverrides[NS_PROJECT] ); - $this->assertIsCapitalized( NS_PROJECT ); - } - - public function testHasGenderDistinction() { - // Namespaces with gender distinctions - $this->assertTrue( MWNamespace::hasGenderDistinction( NS_USER ) ); - $this->assertTrue( MWNamespace::hasGenderDistinction( NS_USER_TALK ) ); - - // Other ones, "genderless" - $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MEDIA ) ); - $this->assertFalse( MWNamespace::hasGenderDistinction( NS_SPECIAL ) ); - $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MAIN ) ); - $this->assertFalse( MWNamespace::hasGenderDistinction( NS_TALK ) ); - } - - public function testIsNonincludable() { - global $wgNonincludableNamespaces; - - $wgNonincludableNamespaces = array( NS_USER ); - - $this->assertTrue( MWNamespace::isNonincludable( NS_USER ) ); - $this->assertFalse( MWNamespace::isNonincludable( NS_TEMPLATE ) ); - } - - ####### HELPERS ########################################################### - function __call( $method, $args ) { - // Call the real method if it exists - if ( method_exists( $this, $method ) ) { - return $this->$method( $args ); - } - - if ( preg_match( '/^assert(Has|Is|Can)(Not|)(Subject|Talk|Watchable|Content|Subpages|Capitalized)$/', $method, $m ) ) { - # Interprets arguments: - $ns = $args[0]; - $msg = isset( $args[1] ) ? $args[1] : " dummy message"; - - # Forge the namespace constant name: - if ( $ns === 0 ) { - $ns_name = "NS_MAIN"; - } else { - $ns_name = "NS_" . strtoupper( MWNamespace::getCanonicalName( $ns ) ); - } - # ... and the MWNamespace method name - $nsMethod = strtolower( $m[1] ) . $m[3]; - - $expect = ( $m[2] === '' ); - $expect_name = $expect ? 'TRUE' : 'FALSE'; - - return $this->assertEquals( $expect, - MWNamespace::$nsMethod( $ns, $msg ), - "MWNamespace::$nsMethod( $ns_name ) should returns $expect_name" - ); - } - - throw new Exception( __METHOD__ . " could not find a method named $method\n" ); - } - - function assertSameSubject( $ns1, $ns2, $msg = '' ) { - $this->assertTrue( MWNamespace::subjectEquals( $ns1, $ns2, $msg ) ); - } - - function assertDifferentSubject( $ns1, $ns2, $msg = '' ) { - $this->assertFalse( MWNamespace::subjectEquals( $ns1, $ns2, $msg ) ); - } -} diff --git a/tests/phpunit/includes/MessageTest.php b/tests/phpunit/includes/MessageTest.php deleted file mode 100644 index 1e18f975..00000000 --- a/tests/phpunit/includes/MessageTest.php +++ /dev/null @@ -1,130 +0,0 @@ -<?php - -class MessageTest extends MediaWikiLangTestCase { - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgLang' => Language::factory( 'en' ), - 'wgForceUIMsgAsContentMsg' => array(), - ) ); - } - - public function testExists() { - $this->assertTrue( wfMessage( 'mainpage' )->exists() ); - $this->assertTrue( wfMessage( 'mainpage' )->params( array() )->exists() ); - $this->assertTrue( wfMessage( 'mainpage' )->rawParams( 'foo', 123 )->exists() ); - $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->exists() ); - $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->params( array() )->exists() ); - $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->rawParams( 'foo', 123 )->exists() ); - } - - public function testKey() { - $this->assertInstanceOf( 'Message', wfMessage( 'mainpage' ) ); - $this->assertInstanceOf( 'Message', wfMessage( 'i-dont-exist-evar' ) ); - $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->text() ); - $this->assertEquals( '<i-dont-exist-evar>', wfMessage( 'i-dont-exist-evar' )->text() ); - $this->assertEquals( '<i-dont-exist-evar>', wfMessage( 'i-dont-exist-evar' )->plain() ); - $this->assertEquals( '<i-dont-exist-evar>', wfMessage( 'i-dont-exist-evar' )->escaped() ); - } - - 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() ); - } - - 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() ); - } - - 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() ); - } - - 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' ); - } - - /** - * 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' ); - } - - public function testInContentLanguageEnabled() { - $this->setMwGlobals( array( - 'wgLang' => Language::factory( 'fr' ), - 'wgForceUIMsgAsContentMsg' => array( 'mainpage' ), - ) ); - - $this->assertEquals( 'Accueil', wfMessage( 'mainpage' )->inContentLanguage()->plain(), 'ForceUIMsg enabled' ); - } - - /** - * @expectedException MWException - */ - public function testInLanguageThrows() { - wfMessage( 'foo' )->inLanguage( 123 ); - } -} diff --git a/tests/phpunit/includes/OutputPageTest.php b/tests/phpunit/includes/OutputPageTest.php deleted file mode 100644 index 56bb0fce..00000000 --- a/tests/phpunit/includes/OutputPageTest.php +++ /dev/null @@ -1,133 +0,0 @@ -<?php - -/** - * - * @author Matthew Flaschen - * - * @group Output - * - */ -class OutputPageTest extends MediaWikiTestCase { - const SCREEN_MEDIA_QUERY = 'screen and (min-width: 982px)'; - const SCREEN_ONLY_MEDIA_QUERY = 'only screen and (min-width: 982px)'; - - /** - * Tests a particular case of transformCssMedia, using the given input, globals, - * expected return, and message - * - * Asserts that $expectedReturn is returned. - * - * 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['media'] - passed into the method under the same name - * options['expectedReturn'] - expected return value - * options['message'] - PHPUnit message for assertion - * - * @param array $args key-value array of arguments as shown above - */ - protected function assertTransformCssMediaCase( $args ) { - $queryData = array(); - if ( isset( $args['printableQuery'] ) ) { - $queryData['printable'] = $args['printableQuery']; - } - - if ( isset( $args['handheldQuery'] ) ) { - $queryData['handheld'] = $args['handheldQuery']; - } - - $fauxRequest = new FauxRequest( $queryData, false ); - $this->setMWGlobals( array( - 'wgRequest' => $fauxRequest, - ) ); - - $actualReturn = OutputPage::transformCssMedia( $args['media'] ); - $this->assertSame( $args['expectedReturn'], $actualReturn, $args['message'] ); - } - - /** - * Tests print requests - */ - public function testPrintRequests() { - $this->assertTransformCssMediaCase( array( - 'printableQuery' => '1', - 'media' => 'screen', - 'expectedReturn' => null, - 'message' => 'On printable request, screen returns null' - ) ); - - $this->assertTransformCssMediaCase( array( - 'printableQuery' => '1', - 'media' => self::SCREEN_MEDIA_QUERY, - 'expectedReturn' => null, - 'message' => 'On printable request, screen media query returns null' - ) ); - - $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->assertTransformCssMediaCase( array( - 'printableQuery' => '1', - 'media' => 'print', - 'expectedReturn' => '', - 'message' => 'On printable request, media print returns empty string' - ) ); - } - - /** - * Tests screen requests, without either query parameter set - */ - public function testScreenRequests() { - $this->assertTransformCssMediaCase( array( - 'media' => 'screen', - 'expectedReturn' => 'screen', - '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->assertTransformCssMediaCase( array( - 'media' => self::SCREEN_MEDIA_QUERY, - 'expectedReturn' => self::SCREEN_MEDIA_QUERY, - 'message' => 'On screen request, screen media query is preserved.' - ) ); - - $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->assertTransformCssMediaCase( array( - 'media' => 'print', - 'expectedReturn' => 'print', - 'message' => 'On screen request, print media type is preserved' - ) ); - } - - /** - * Tests handheld behavior - */ - public function testHandheld() { - $this->assertTransformCssMediaCase( array( - 'handheldQuery' => '1', - 'media' => 'handheld', - 'expectedReturn' => '', - 'message' => 'On request with handheld querystring and media is handheld, returns empty string' - ) ); - - $this->assertTransformCssMediaCase( array( - 'handheldQuery' => '1', - 'media' => 'screen', - 'expectedReturn' => null, - 'message' => 'On request with handheld querystring and media is screen, returns null' - ) ); - } -} diff --git a/tests/phpunit/includes/PathRouterTest.php b/tests/phpunit/includes/PathRouterTest.php deleted file mode 100644 index adfb215a..00000000 --- a/tests/phpunit/includes/PathRouterTest.php +++ /dev/null @@ -1,263 +0,0 @@ -<?php -/** - * 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; - $router->add( "/wiki/$1" ); - $this->basicRouter = $router; - } - - /** - * Test basic path parsing - */ - public function testBasic() { - $matches = $this->basicRouter->parse( "/wiki/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - } - - /** - * Test loose path auto-$1 - */ - public function testLoose() { - $router = new PathRouter; - $router->add( "/" ); # Should be the same as "/$1" - $matches = $router->parse( "/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - - $router = new PathRouter; - $router->add( "/wiki" ); # Should be the same as /wiki/$1 - $matches = $router->parse( "/wiki/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - - $router = new PathRouter; - $router->add( "/wiki/" ); # Should be the same as /wiki/$1 - $matches = $router->parse( "/wiki/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - } - - /** - * Test to ensure that path is based on specifity, not order - */ - public function testOrder() { - $router = new PathRouter; - $router->add( "/$1" ); - $router->add( "/a/$1" ); - $router->add( "/b/$1" ); - $matches = $router->parse( "/a/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - - $router = new PathRouter; - $router->add( "/b/$1" ); - $router->add( "/a/$1" ); - $router->add( "/$1" ); - $matches = $router->parse( "/a/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - } - - /** - * Test the handling of key based arrays with a url parameter - */ - public function testKeyParameter() { - $router = new PathRouter; - $router->add( array( 'edit' => "/edit/$1" ), array( 'action' => '$key' ) ); - $matches = $router->parse( "/edit/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo", 'action' => 'edit' ) ); - } - - /** - * Test the handling of $2 inside paths - */ - public function testAdditionalParameter() { - // Basic $2 - $router = new PathRouter; - $router->add( '/$2/$1', array( 'test' => '$2' ) ); - $matches = $router->parse( "/asdf/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo", 'test' => 'asdf' ) ); - } - - /** - * Test additional restricted value parameter - */ - public function testRestrictedValue() { - $router = new PathRouter; - $router->add( '/$2/$1', - array( 'test' => '$2' ), - array( '$2' => array( 'a', 'b' ) ) - ); - $router->add( '/$2/$1', - array( 'test2' => '$2' ), - array( '$2' => 'c' ) - ); - $router->add( '/$1' ); - - $matches = $router->parse( "/asdf/Foo" ); - $this->assertEquals( $matches, array( 'title' => "asdf/Foo" ) ); - - $matches = $router->parse( "/a/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo", 'test' => 'a' ) ); - - $matches = $router->parse( "/c/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo", 'test2' => 'c' ) ); - } - - public function callbackForTest( &$matches, $data ) { - $matches['x'] = $data['$1']; - $matches['foo'] = $data['foo']; - } - - public function testCallback() { - $router = new PathRouter; - $router->add( "/$1", - array( 'a' => 'b', 'data:foo' => 'bar' ), - array( 'callback' => array( $this, 'callbackForTest' ) ) - ); - $matches = $router->parse( '/Foo' ); - $this->assertEquals( $matches, array( - 'title' => "Foo", - 'x' => 'Foo', - 'a' => 'b', - 'foo' => 'bar' - ) ); - } - - /** - * Test to ensure that matches are not made if a parameter expects nonexistent input - */ - public function testFail() { - $router = new PathRouter; - $router->add( "/wiki/$1", array( 'title' => "$1$2" ) ); - $matches = $router->parse( "/wiki/A" ); - $this->assertEquals( array(), $matches ); - } - - /** - * Test to ensure weight of paths is handled correctly - */ - public function testWeight() { - $router = new PathRouter; - $router->addStrict( "/Bar", array( 'ping' => 'pong' ) ); - $router->add( "/asdf-$1", array( 'title' => 'qwerty-$1' ) ); - $router->add( "/$1" ); - $router->add( "/qwerty-$1", array( 'title' => 'asdf-$1' ) ); - $router->addStrict( "/Baz", array( 'marco' => 'polo' ) ); - $router->add( "/a/$1" ); - $router->add( "/asdf/$1" ); - $router->add( "/$2/$1", array( 'unrestricted' => '$2' ) ); - $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 - ) { - $this->assertEquals( $router->parse( $path ), $result ); - } - } - - /** - * Make sure the router handles titles like Special:Recentchanges correctly - */ - public function testSpecial() { - $matches = $this->basicRouter->parse( "/wiki/Special:Recentchanges" ); - $this->assertEquals( $matches, array( 'title' => "Special:Recentchanges" ) ); - } - - /** - * Make sure the router decodes urlencoding properly - */ - public function testUrlencoding() { - $matches = $this->basicRouter->parse( "/wiki/Title_With%20Space" ); - $this->assertEquals( $matches, array( 'title' => "Title_With Space" ) ); - } - - public static function provideRegexpChars() { - return array( - array( "$" ), - array( "$1" ), - array( "\\" ), - array( "\\$1" ), - ); - } - - /** - * Make sure the router doesn't break on special characters like $ used in regexp replacements - * @dataProvider provideRegexpChars - */ - public function testRegexpChars( $char ) { - $matches = $this->basicRouter->parse( "/wiki/$char" ); - $this->assertEquals( $matches, array( 'title' => "$char" ) ); - } - - /** - * Make sure the router handles characters like +&() properly - */ - public function testCharacters() { - $matches = $this->basicRouter->parse( "/wiki/Plus+And&Dollar\\Stuff();[]{}*" ); - $this->assertEquals( $matches, array( 'title' => "Plus+And&Dollar\\Stuff();[]{}*" ) ); - } - - /** - * Make sure the router handles unicode characters correctly - * @depends testSpecial - * @depends testUrlencoding - * @depends testCharacters - */ - public function testUnicode() { - $matches = $this->basicRouter->parse( "/wiki/Spécial:Modifications_récentes" ); - $this->assertEquals( $matches, array( 'title' => "Spécial:Modifications_récentes" ) ); - - $matches = $this->basicRouter->parse( "/wiki/Sp%C3%A9cial:Modifications_r%C3%A9centes" ); - $this->assertEquals( $matches, array( 'title' => "Spécial:Modifications_récentes" ) ); - } - - /** - * Ensure the router doesn't choke on long paths. - */ - public function testLength() { - $matches = $this->basicRouter->parse( "/wiki/Lorem_ipsum_dolor_sit_amet,_consectetur_adipisicing_elit,_sed_do_eiusmod_tempor_incididunt_ut_labore_et_dolore_magna_aliqua._Ut_enim_ad_minim_veniam,_quis_nostrud_exercitation_ullamco_laboris_nisi_ut_aliquip_ex_ea_commodo_consequat._Duis_aute_irure_dolor_in_reprehenderit_in_voluptate_velit_esse_cillum_dolore_eu_fugiat_nulla_pariatur._Excepteur_sint_occaecat_cupidatat_non_proident,_sunt_in_culpa_qui_officia_deserunt_mollit_anim_id_est_laborum." ); - $this->assertEquals( $matches, array( 'title' => "Lorem_ipsum_dolor_sit_amet,_consectetur_adipisicing_elit,_sed_do_eiusmod_tempor_incididunt_ut_labore_et_dolore_magna_aliqua._Ut_enim_ad_minim_veniam,_quis_nostrud_exercitation_ullamco_laboris_nisi_ut_aliquip_ex_ea_commodo_consequat._Duis_aute_irure_dolor_in_reprehenderit_in_voluptate_velit_esse_cillum_dolore_eu_fugiat_nulla_pariatur._Excepteur_sint_occaecat_cupidatat_non_proident,_sunt_in_culpa_qui_officia_deserunt_mollit_anim_id_est_laborum." ) ); - } - - - /** - * Ensure that the php passed site of parameter values are not urldecoded - */ - public function testPatternUrlencoding() { - $router = new PathRouter; - $router->add( "/wiki/$1", array( 'title' => '%20:$1' ) ); - $matches = $router->parse( "/wiki/Foo" ); - $this->assertEquals( $matches, array( 'title' => '%20:Foo' ) ); - } - - /** - * Ensure that raw parameter values do not have any variable replacements or urldecoding - */ - public function testRawParamValue() { - $router = new PathRouter; - $router->add( "/wiki/$1", array( 'title' => array( 'value' => 'bar%20$1' ) ) ); - $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 deleted file mode 100644 index 3dec2da0..00000000 --- a/tests/phpunit/includes/PreferencesTest.php +++ /dev/null @@ -1,91 +0,0 @@ -<?php - -/** - * @group Database - */ -class PreferencesTest extends MediaWikiTestCase { - /** - * @var User[] - */ - private $prefUsers; - /** - * @var RequestContext - */ - private $context; - - public function __construct() { - parent::__construct(); - - $this->prefUsers['noemail'] = new User; - - $this->prefUsers['notauth'] = new User; - $this->prefUsers['notauth'] - ->setEmail( 'noauth@example.org' ); - - $this->prefUsers['auth'] = new User; - $this->prefUsers['auth'] - ->setEmail( 'noauth@example.org' ); - $this->prefUsers['auth'] - ->setEmailAuthenticationTimestamp( 1330946623 ); - - $this->context = new RequestContext; - $this->context->setTitle( Title::newFromText( 'PreferencesTest' ) ); - } - - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgEnableEmail' => true, - 'wgEmailAuthentication' => true, - ) ); - } - - /** - * Placeholder to verify bug 34302 - * @covers Preferences::profilePreferences - */ - public function testEmailFieldsWhenUserHasNoEmail() { - $prefs = $this->prefsFor( 'noemail' ); - $this->assertArrayHasKey( 'cssclass', - $prefs['emailaddress'] - ); - $this->assertEquals( 'mw-email-none', $prefs['emailaddress']['cssclass'] ); - } - - /** - * Placeholder to verify bug 34302 - * @covers Preferences::profilePreferences - */ - public function testEmailFieldsWhenUserEmailNotAuthenticated() { - $prefs = $this->prefsFor( 'notauth' ); - $this->assertArrayHasKey( 'cssclass', - $prefs['emailaddress'] - ); - $this->assertEquals( 'mw-email-not-authenticated', $prefs['emailaddress']['cssclass'] ); - } - - /** - * Placeholder to verify bug 34302 - * @covers Preferences::profilePreferences - */ - public function testEmailFieldsWhenUserEmailIsAuthenticated() { - $prefs = $this->prefsFor( 'auth' ); - $this->assertArrayHasKey( 'cssclass', - $prefs['emailaddress'] - ); - $this->assertEquals( 'mw-email-authenticated', $prefs['emailaddress']['cssclass'] ); - } - - /** Helper */ - protected function prefsFor( $user_key ) { - $preferences = array(); - Preferences::profilePreferences( - $this->prefUsers[$user_key] - , $this->context - , $preferences - ); - - return $preferences; - } -} diff --git a/tests/phpunit/includes/RecentChangeTest.php b/tests/phpunit/includes/RecentChangeTest.php deleted file mode 100644 index cfa3e777..00000000 --- a/tests/phpunit/includes/RecentChangeTest.php +++ /dev/null @@ -1,280 +0,0 @@ -<?php -/** - * @group Database - */ -class RecentChangeTest extends MediaWikiTestCase { - protected $title; - protected $target; - protected $user; - protected $user_comment; - protected $context; - - public function __construct() { - parent::__construct(); - - $this->title = Title::newFromText( 'SomeTitle' ); - $this->target = Title::newFromText( 'TestTarget' ); - $this->user = User::newFromName( 'UserName' ); - - $this->user_comment = '<User comment about action>'; - $this->context = RequestContext::newExtraneousContext( $this->title ); - } - - /** - * The testIrcMsgForAction* tests are supposed to cover the hacky - * LogFormatter::getIRCActionText / bug 34508 - * - * Third parties bots listen to those messages. They are clever enough - * to fetch the i18n messages from the wiki and then analyze the IRC feed - * to reverse engineer the $1, $2 messages. - * One thing bots can not detect is when MediaWiki change the meaning of - * a message like what happened when we deployed 1.19. $1 became the user - * performing the action which broke basically all bots around. - * - * Should cover the following log actions (which are most commonly used by bots): - * - block/block - * - block/unblock - * - delete/delete - * - delete/restore - * - newusers/create - * - newusers/create2 - * - newusers/autocreate - * - move/move - * - move/move_redir - * - protect/protect - * - protect/modifyprotect - * - protect/unprotect - * - upload/upload - * - * As well as the following Auto Edit Summaries: - * - blank - * - replace - * - rollback - * - undo - */ - - /** - * @covers LogFormatter::getIRCActionText - */ - public function testIrcMsgForLogTypeBlock() { - $sep = $this->context->msg( 'colon-separator' )->text(); - - # block/block - $this->assertIRCComment( - $this->context->msg( 'blocklogentry', 'SomeTitle' )->plain() . $sep . $this->user_comment, - 'block', 'block', - array(), - $this->user_comment - ); - # block/unblock - $this->assertIRCComment( - $this->context->msg( 'unblocklogentry', 'SomeTitle' )->plain() . $sep . $this->user_comment, - 'block', 'unblock', - array(), - $this->user_comment - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - public function testIrcMsgForLogTypeDelete() { - $sep = $this->context->msg( 'colon-separator' )->text(); - - # delete/delete - $this->assertIRCComment( - $this->context->msg( 'deletedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment, - 'delete', 'delete', - array(), - $this->user_comment - ); - - # delete/restore - $this->assertIRCComment( - $this->context->msg( 'undeletedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment, - 'delete', 'restore', - array(), - $this->user_comment - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - public function testIrcMsgForLogTypeNewusers() { - $this->assertIRCComment( - 'New user account', - 'newusers', 'newusers', - array() - ); - $this->assertIRCComment( - 'New user account', - 'newusers', 'create', - array() - ); - $this->assertIRCComment( - 'created new account SomeTitle', - 'newusers', 'create2', - array() - ); - $this->assertIRCComment( - 'Account created automatically', - 'newusers', 'autocreate', - array() - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - public function testIrcMsgForLogTypeMove() { - $move_params = array( - '4::target' => $this->target->getPrefixedText(), - '5::noredir' => 0, - ); - $sep = $this->context->msg( 'colon-separator' )->text(); - - # move/move - $this->assertIRCComment( - $this->context->msg( '1movedto2', 'SomeTitle', 'TestTarget' )->plain() . $sep . $this->user_comment, - 'move', 'move', - $move_params, - $this->user_comment - ); - - # move/move_redir - $this->assertIRCComment( - $this->context->msg( '1movedto2_redir', 'SomeTitle', 'TestTarget' )->plain() . $sep . $this->user_comment, - 'move', 'move_redir', - $move_params, - $this->user_comment - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - public function testIrcMsgForLogTypePatrol() { - # patrol/patrol - $this->assertIRCComment( - $this->context->msg( 'patrol-log-line', 'revision 777', '[[SomeTitle]]', '' )->plain(), - 'patrol', 'patrol', - array( - '4::curid' => '777', - '5::previd' => '666', - '6::auto' => 0, - ) - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - public function testIrcMsgForLogTypeProtect() { - $protectParams = array( - '[edit=sysop] (indefinite) [move=sysop] (indefinite)' - ); - $sep = $this->context->msg( 'colon-separator' )->text(); - - # protect/protect - $this->assertIRCComment( - $this->context->msg( 'protectedarticle', 'SomeTitle ' . $protectParams[0] )->plain() . $sep . $this->user_comment, - 'protect', 'protect', - $protectParams, - $this->user_comment - ); - - # protect/unprotect - $this->assertIRCComment( - $this->context->msg( 'unprotectedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment, - 'protect', 'unprotect', - array(), - $this->user_comment - ); - - # protect/modify - $this->assertIRCComment( - $this->context->msg( 'modifiedarticleprotection', 'SomeTitle ' . $protectParams[0] )->plain() . $sep . $this->user_comment, - 'protect', 'modify', - $protectParams, - $this->user_comment - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - public function testIrcMsgForLogTypeUpload() { - $sep = $this->context->msg( 'colon-separator' )->text(); - - # upload/upload - $this->assertIRCComment( - $this->context->msg( 'uploadedimage', 'SomeTitle' )->plain() . $sep . $this->user_comment, - 'upload', 'upload', - array(), - $this->user_comment - ); - - # upload/overwrite - $this->assertIRCComment( - $this->context->msg( 'overwroteimage', 'SomeTitle' )->plain() . $sep . $this->user_comment, - 'upload', 'overwrite', - array(), - $this->user_comment - ); - } - - /** - * @todo Emulate these edits somehow and extract - * raw edit summary from RecentChange object - * -- - */ - /* - public function testIrcMsgForBlankingAES() { - // $this->context->msg( 'autosumm-blank', .. ); - } - - public function testIrcMsgForReplaceAES() { - // $this->context->msg( 'autosumm-replace', .. ); - } - - public function testIrcMsgForRollbackAES() { - // $this->context->msg( 'revertpage', .. ); - } - - public function testIrcMsgForUndoAES() { - // $this->context->msg( 'undo-summary', .. ); - } - */ - - /** - * @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 :-) - */ - protected function assertIRCComment( $expected, $type, $action, $params, $comment = null, $msg = '' ) { - - $logEntry = new ManualLogEntry( $type, $action ); - $logEntry->setPerformer( $this->user ); - $logEntry->setTarget( $this->title ); - if ( $comment !== null ) { - $logEntry->setComment( $comment ); - } - $logEntry->setParameters( $params ); - - $formatter = LogFormatter::newFromEntry( $logEntry ); - $formatter->setContext( $this->context ); - - // Apply the same transformation as done in IRCColourfulRCFeedFormatter::getLine for rc_comment - $ircRcComment = IRCColourfulRCFeedFormatter::cleanupForIRC( $formatter->getIRCActionComment() ); - - $this->assertEquals( - $expected, - $ircRcComment, - $msg - ); - } -} diff --git a/tests/phpunit/includes/RequestContextTest.php b/tests/phpunit/includes/RequestContextTest.php deleted file mode 100644 index 1776b5d5..00000000 --- a/tests/phpunit/includes/RequestContextTest.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php - -/** - * @group Database - */ -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(); - - $curTitle = Title::newFromText( "A" ); - $context->setTitle( $curTitle ); - $this->assertTrue( $curTitle->equals( $context->getWikiPage()->getTitle() ), - "When a title is first set WikiPage should be created on-demand for that title." ); - - $curTitle = Title::newFromText( "B" ); - $context->setWikiPage( WikiPage::factory( $curTitle ) ); - $this->assertTrue( $curTitle->equals( $context->getTitle() ), - "Title must be updated when a new WikiPage is provided." ); - - $curTitle = Title::newFromText( "C" ); - $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(); - - $oInfo = $context->exportSession(); - $this->assertEquals( '127.0.0.1', $oInfo['ip'], "Correct initial IP address." ); - $this->assertEquals( 0, $oInfo['userId'], "Correct initial user ID." ); - - $user = User::newFromName( 'UnitTestContextUser' ); - $user->addToDatabase(); - - $sinfo = array( - 'sessionId' => 'd612ee607c87e749ef14da4983a702cd', - 'userId' => $user->getId(), - 'ip' => '192.0.2.0', - 'headers' => array( 'USER-AGENT' => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0' ) - ); - $sc = RequestContext::importScopedSession( $sinfo ); // load new context - - $info = $context->exportSession(); - $this->assertEquals( $sinfo['ip'], $info['ip'], "Correct IP address." ); - $this->assertEquals( $sinfo['headers'], $info['headers'], "Correct headers." ); - $this->assertEquals( $sinfo['sessionId'], $info['sessionId'], "Correct session ID." ); - $this->assertEquals( $sinfo['userId'], $info['userId'], "Correct user ID." ); - $this->assertEquals( $sinfo['ip'], $context->getRequest()->getIP(), "Correct context IP address." ); - $this->assertEquals( $sinfo['headers'], $context->getRequest()->getAllHeaders(), "Correct context headers." ); - $this->assertEquals( $sinfo['sessionId'], session_id(), "Correct context session ID." ); - $this->assertEquals( true, $context->getUser()->isLoggedIn(), "Correct context user." ); - $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 - - $info = $context->exportSession(); - $this->assertEquals( $oInfo['ip'], $info['ip'], "Correct initial IP address." ); - $this->assertEquals( $oInfo['headers'], $info['headers'], "Correct initial headers." ); - $this->assertEquals( $oInfo['sessionId'], $info['sessionId'], "Correct initial session ID." ); - $this->assertEquals( $oInfo['userId'], $info['userId'], "Correct initial user ID." ); - } -} diff --git a/tests/phpunit/includes/ResourceLoaderTest.php b/tests/phpunit/includes/ResourceLoaderTest.php deleted file mode 100644 index ca8b2b6e..00000000 --- a/tests/phpunit/includes/ResourceLoaderTest.php +++ /dev/null @@ -1,149 +0,0 @@ -<?php - -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 */ - - /** - * ResourceLoaderRegisterModules hook - */ - public static function resourceLoaderRegisterModules( &$resourceLoader ) { - self::$resourceLoaderRegisterModulesHook = true; - - return true; - } - - /* Provider Methods */ - public static function provideValidModules() { - return array( - array( 'TEST.validModule1', new ResourceLoaderTestModule() ), - ); - } - - public static function provideResourceLoaderContext() { - $resourceLoader = new ResourceLoader(); - $request = new FauxRequest(); - return array( - array( new ResourceLoaderContext( $resourceLoader, $request ) ), - ); - } - - /* Test Methods */ - - /** - * Ensures that the ResourceLoaderRegisterModules hook is called when a new ResourceLoader object is constructed - * @covers ResourceLoader::__construct - */ - public function testCreatingNewResourceLoaderCallsRegistrationHook() { - self::$resourceLoaderRegisterModulesHook = false; - $resourceLoader = new ResourceLoader(); - $this->assertTrue( self::$resourceLoaderRegisterModulesHook ); - - return $resourceLoader; - } - - /** - * @dataProvider provideValidModules - * @depends testCreatingNewResourceLoaderCallsRegistrationHook - * @covers ResourceLoader::register - * @covers ResourceLoader::getModule - */ - public function testRegisteredValidModulesAreAccessible( - $name, ResourceLoaderModule $module, ResourceLoader $resourceLoader - ) { - $resourceLoader->register( $name, $module ); - $this->assertEquals( $module, $resourceLoader->getModule( $name ) ); - } - - /** - * @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 ); - } - - /** - * @dataProvider providePackedModules - * @covers ResourceLoaderContext::expandModuleNames - */ - public function testexpandModuleNames( $desc, $modules, $packed ) { - $this->assertEquals( $modules, ResourceLoaderContext::expandModuleNames( $packed ), $desc ); - } - - public static function providePackedModules() { - return array( - array( - 'Example from makePackedModulesString doc comment', - array( 'foo.bar', 'foo.baz', 'bar.baz', 'bar.quux' ), - 'foo.bar,baz|bar.baz,quux', - ), - array( - 'Example from expandModuleNames doc comment', - array( 'jquery.foo', 'jquery.bar', 'jquery.ui.baz', 'jquery.ui.quux' ), - 'jquery.foo,bar|jquery.ui.baz,quux', - ), - array( - '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 { -} - -/* Hooks */ -global $wgHooks; -$wgHooks['ResourceLoaderRegisterModules'][] = 'ResourceLoaderTest::resourceLoaderRegisterModules'; diff --git a/tests/phpunit/includes/RevisionStorageTest.php b/tests/phpunit/includes/RevisionStorageTest.php deleted file mode 100644 index e17c7b0f..00000000 --- a/tests/phpunit/includes/RevisionStorageTest.php +++ /dev/null @@ -1,546 +0,0 @@ -<?php - -/** - * Test class for Revision storage. - * - * @group ContentHandler - * @group Database - * ^--- important, causes temporary tables to be used instead of the real database - * - * @group medium - * ^--- important, causes tests not to fail with timeout - */ -class RevisionStorageTest extends MediaWikiTestCase { - - /** - * @var WikiPage $the_page - */ - var $the_page; - - function __construct( $name = null, array $data = array(), $dataName = '' ) { - parent::__construct( $name, $data, $dataName ); - - $this->tablesUsed = array_merge( $this->tablesUsed, - array( 'page', - 'revision', - 'text', - - 'recentchanges', - 'logging', - - 'page_props', - 'pagelinks', - 'categorylinks', - 'langlinks', - 'externallinks', - 'imagelinks', - 'templatelinks', - 'iwlinks' ) ); - } - - protected function setUp() { - global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang; - - parent::setUp(); - - $wgExtraNamespaces[12312] = 'Dummy'; - $wgExtraNamespaces[12313] = 'Dummy_talk'; - - $wgNamespaceContentModels[12312] = 'DUMMY'; - $wgContentHandlers['DUMMY'] = 'DummyContentHandlerForTesting'; - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - if ( !$this->the_page ) { - $this->the_page = $this->createPage( 'RevisionStorageTest_the_page', "just a dummy page", CONTENT_MODEL_WIKITEXT ); - } - } - - public function tearDown() { - global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang; - - parent::tearDown(); - - unset( $wgExtraNamespaces[12312] ); - unset( $wgExtraNamespaces[12313] ); - - unset( $wgNamespaceContentModels[12312] ); - unset( $wgContentHandlers['DUMMY'] ); - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - } - - protected function makeRevision( $props = null ) { - if ( $props === null ) { - $props = array(); - } - - if ( !isset( $props['content'] ) && !isset( $props['text'] ) ) { - $props['text'] = 'Lorem Ipsum'; - } - - if ( !isset( $props['comment'] ) ) { - $props['comment'] = 'just a test'; - } - - if ( !isset( $props['page'] ) ) { - $props['page'] = $this->the_page->getId(); - } - - $rev = new Revision( $props ); - - $dbw = wfgetDB( DB_MASTER ); - $rev->insertOn( $dbw ); - - return $rev; - } - - protected function createPage( $page, $text, $model = null ) { - if ( is_string( $page ) ) { - if ( !preg_match( '/:/', $page ) && - ( $model === null || $model === CONTENT_MODEL_WIKITEXT ) - ) { - $ns = $this->getDefaultWikitextNS(); - $page = MWNamespace::getCanonicalName( $ns ) . ':' . $page; - } - - $page = Title::newFromText( $page ); - } - - if ( $page instanceof Title ) { - $page = new WikiPage( $page ); - } - - if ( $page->exists() ) { - $page->doDeleteArticle( "done" ); - } - - $content = ContentHandler::makeContent( $text, $page->getTitle(), $model ); - $page->doEditContent( $content, "testing", EDIT_NEW ); - - return $page; - } - - protected function assertRevEquals( Revision $orig, Revision $rev = null ) { - $this->assertNotNull( $rev, 'missing revision' ); - - $this->assertEquals( $orig->getId(), $rev->getId() ); - $this->assertEquals( $orig->getPage(), $rev->getPage() ); - $this->assertEquals( $orig->getTimestamp(), $rev->getTimestamp() ); - $this->assertEquals( $orig->getUser(), $rev->getUser() ); - $this->assertEquals( $orig->getContentModel(), $rev->getContentModel() ); - $this->assertEquals( $orig->getContentFormat(), $rev->getContentFormat() ); - $this->assertEquals( $orig->getSha1(), $rev->getSha1() ); - } - - /** - * @covers Revision::__construct - */ - public function testConstructFromRow() { - $orig = $this->makeRevision(); - - $dbr = wfgetDB( DB_SLAVE ); - $res = $dbr->select( 'revision', '*', array( 'rev_id' => $orig->getId() ) ); - $this->assertTrue( is_object( $res ), 'query failed' ); - - $row = $res->fetchObject(); - $res->free(); - - $rev = new Revision( $row ); - - $this->assertRevEquals( $orig, $rev ); - } - - /** - * @covers Revision::newFromRow - */ - public function testNewFromRow() { - $orig = $this->makeRevision(); - - $dbr = wfgetDB( DB_SLAVE ); - $res = $dbr->select( 'revision', '*', array( 'rev_id' => $orig->getId() ) ); - $this->assertTrue( is_object( $res ), 'query failed' ); - - $row = $res->fetchObject(); - $res->free(); - - $rev = Revision::newFromRow( $row ); - - $this->assertRevEquals( $orig, $rev ); - } - - - /** - * @covers Revision::newFromArchiveRow - */ - public function testNewFromArchiveRow() { - $page = $this->createPage( 'RevisionStorageTest_testNewFromArchiveRow', 'Lorem Ipsum', CONTENT_MODEL_WIKITEXT ); - $orig = $page->getRevision(); - $page->doDeleteArticle( 'test Revision::newFromArchiveRow' ); - - $dbr = wfgetDB( DB_SLAVE ); - $res = $dbr->select( 'archive', '*', array( 'ar_rev_id' => $orig->getId() ) ); - $this->assertTrue( is_object( $res ), 'query failed' ); - - $row = $res->fetchObject(); - $res->free(); - - $rev = Revision::newFromArchiveRow( $row ); - - $this->assertRevEquals( $orig, $rev ); - } - - /** - * @covers Revision::newFromId - */ - public function testNewFromId() { - $orig = $this->makeRevision(); - - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertRevEquals( $orig, $rev ); - } - - /** - * @covers Revision::fetchRevision - */ - public function testFetchRevision() { - $page = $this->createPage( 'RevisionStorageTest_testFetchRevision', 'one', CONTENT_MODEL_WIKITEXT ); - $id1 = $page->getRevision()->getId(); - - $page->doEditContent( new WikitextContent( 'two' ), 'second rev' ); - $id2 = $page->getRevision()->getId(); - - $res = Revision::fetchRevision( $page->getTitle() ); - - #note: order is unspecified - $rows = array(); - while ( ( $row = $res->fetchObject() ) ) { - $rows[$row->rev_id] = $row; - } - - $row = $res->fetchObject(); - $this->assertEquals( 1, count( $rows ), 'expected exactly one revision' ); - $this->assertArrayHasKey( $id2, $rows, 'missing revision with id ' . $id2 ); - } - - /** - * @covers Revision::selectFields - */ - public function testSelectFields() { - global $wgContentHandlerUseDB; - - $fields = Revision::selectFields(); - - $this->assertTrue( in_array( 'rev_id', $fields ), 'missing rev_id in list of fields' ); - $this->assertTrue( in_array( 'rev_page', $fields ), 'missing rev_page in list of fields' ); - $this->assertTrue( in_array( 'rev_timestamp', $fields ), 'missing rev_timestamp in list of fields' ); - $this->assertTrue( in_array( 'rev_user', $fields ), 'missing rev_user in list of fields' ); - - if ( $wgContentHandlerUseDB ) { - $this->assertTrue( in_array( 'rev_content_model', $fields ), - 'missing rev_content_model in list of fields' ); - $this->assertTrue( in_array( 'rev_content_format', $fields ), - 'missing rev_content_format in list of fields' ); - } - } - - /** - * @covers Revision::getPage - */ - public function testGetPage() { - $page = $this->the_page; - - $orig = $this->makeRevision( array( 'page' => $page->getId() ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( $page->getId(), $rev->getPage() ); - } - - /** - * @covers Revision::getText - */ - public function testGetText() { - $this->hideDeprecated( 'Revision::getText' ); - - $orig = $this->makeRevision( array( 'text' => 'hello hello.' ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( 'hello hello.', $rev->getText() ); - } - - /** - * @covers Revision::getContent - */ - public function testGetContent_failure() { - $rev = new Revision( array( - 'page' => $this->the_page->getId(), - 'content_model' => $this->the_page->getContentModel(), - 'text_id' => 123456789, // not in the test DB - ) ); - - $this->assertNull( $rev->getContent(), - "getContent() should return null if the revision's text blob could not be loaded." ); - - //NOTE: check this twice, once for lazy initialization, and once with the cached value. - $this->assertNull( $rev->getContent(), - "getContent() should return null if the revision's text blob could not be loaded." ); - } - - /** - * @covers Revision::getContent - */ - public function testGetContent() { - $orig = $this->makeRevision( array( 'text' => 'hello hello.' ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( 'hello hello.', $rev->getContent()->getNativeData() ); - } - - /** - * @covers Revision::revText - */ - public function testRevText() { - $this->hideDeprecated( 'Revision::revText' ); - $orig = $this->makeRevision( array( 'text' => 'hello hello rev.' ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( 'hello hello rev.', $rev->revText() ); - } - - /** - * @covers Revision::getRawText - */ - public function testGetRawText() { - $this->hideDeprecated( 'Revision::getRawText' ); - - $orig = $this->makeRevision( array( 'text' => 'hello hello raw.' ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( 'hello hello raw.', $rev->getRawText() ); - } - - /** - * @covers Revision::getContentModel - */ - public function testGetContentModel() { - global $wgContentHandlerUseDB; - - if ( !$wgContentHandlerUseDB ) { - $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' ); - } - - $orig = $this->makeRevision( array( 'text' => 'hello hello.', - 'content_model' => CONTENT_MODEL_JAVASCRIPT ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() ); - } - - /** - * @covers Revision::getContentFormat - */ - public function testGetContentFormat() { - global $wgContentHandlerUseDB; - - if ( !$wgContentHandlerUseDB ) { - $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' ); - } - - $orig = $this->makeRevision( array( - 'text' => 'hello hello.', - 'content_model' => CONTENT_MODEL_JAVASCRIPT, - 'content_format' => CONTENT_FORMAT_JAVASCRIPT - ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( CONTENT_FORMAT_JAVASCRIPT, $rev->getContentFormat() ); - } - - /** - * @covers Revision::isCurrent - */ - public function testIsCurrent() { - $page = $this->createPage( 'RevisionStorageTest_testIsCurrent', 'Lorem Ipsum', CONTENT_MODEL_WIKITEXT ); - $rev1 = $page->getRevision(); - - # @todo find out if this should be true - # $this->assertTrue( $rev1->isCurrent() ); - - $rev1x = Revision::newFromId( $rev1->getId() ); - $this->assertTrue( $rev1x->isCurrent() ); - - $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ), 'second rev' ); - $rev2 = $page->getRevision(); - - # @todo find out if this should be true - # $this->assertTrue( $rev2->isCurrent() ); - - $rev1x = Revision::newFromId( $rev1->getId() ); - $this->assertFalse( $rev1x->isCurrent() ); - - $rev2x = Revision::newFromId( $rev2->getId() ); - $this->assertTrue( $rev2x->isCurrent() ); - } - - /** - * @covers Revision::getPrevious - */ - public function testGetPrevious() { - $page = $this->createPage( 'RevisionStorageTest_testGetPrevious', 'Lorem Ipsum testGetPrevious', CONTENT_MODEL_WIKITEXT ); - $rev1 = $page->getRevision(); - - $this->assertNull( $rev1->getPrevious() ); - - $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ), - 'second rev testGetPrevious' ); - $rev2 = $page->getRevision(); - - $this->assertNotNull( $rev2->getPrevious() ); - $this->assertEquals( $rev1->getId(), $rev2->getPrevious()->getId() ); - } - - /** - * @covers Revision::getNext - */ - public function testGetNext() { - $page = $this->createPage( 'RevisionStorageTest_testGetNext', 'Lorem Ipsum testGetNext', CONTENT_MODEL_WIKITEXT ); - $rev1 = $page->getRevision(); - - $this->assertNull( $rev1->getNext() ); - - $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ), - 'second rev testGetNext' ); - $rev2 = $page->getRevision(); - - $this->assertNotNull( $rev1->getNext() ); - $this->assertEquals( $rev2->getId(), $rev1->getNext()->getId() ); - } - - /** - * @covers Revision::newNullRevision - */ - public function testNewNullRevision() { - $page = $this->createPage( 'RevisionStorageTest_testNewNullRevision', 'some testing text', CONTENT_MODEL_WIKITEXT ); - $orig = $page->getRevision(); - - $dbw = wfGetDB( DB_MASTER ); - $rev = Revision::newNullRevision( $dbw, $page->getId(), 'a null revision', false ); - - $this->assertNotEquals( $orig->getId(), $rev->getId(), - 'new null revision shold have a different id from the original revision' ); - $this->assertEquals( $orig->getTextId(), $rev->getTextId(), - 'new null revision shold have the same text id as the original revision' ); - $this->assertEquals( 'some testing text', $rev->getContent()->getNativeData() ); - } - - public static function provideUserWasLastToEdit() { - return array( - array( #0 - 3, true, # actually the last edit - ), - array( #1 - 2, true, # not the current edit, but still by this user - ), - array( #2 - 1, false, # edit by another user - ), - array( #3 - 0, false, # first edit, by this user, but another user edited in the mean time - ), - ); - } - - /** - * @dataProvider provideUserWasLastToEdit - */ - public function testUserWasLastToEdit( $sinceIdx, $expectedLast ) { - $userA = User::newFromName( "RevisionStorageTest_userA" ); - $userB = User::newFromName( "RevisionStorageTest_userB" ); - - if ( $userA->getId() === 0 ) { - $userA = User::createNew( $userA->getName() ); - } - - if ( $userB->getId() === 0 ) { - $userB = User::createNew( $userB->getName() ); - } - - $ns = $this->getDefaultWikitextNS(); - - $dbw = wfGetDB( DB_MASTER ); - $revisions = array(); - - // create revisions ----------------------------- - $page = WikiPage::factory( Title::newFromText( - 'RevisionStorageTest_testUserWasLastToEdit', $ns ) ); - - # zero - $revisions[0] = new Revision( array( - 'page' => $page->getId(), - 'title' => $page->getTitle(), // we need the title to determine the page's default content model - 'timestamp' => '20120101000000', - 'user' => $userA->getId(), - 'text' => 'zero', - 'content_model' => CONTENT_MODEL_WIKITEXT, - 'summary' => 'edit zero' - ) ); - $revisions[0]->insertOn( $dbw ); - - # one - $revisions[1] = new Revision( array( - 'page' => $page->getId(), - 'title' => $page->getTitle(), // still need the title, because $page->getId() is 0 (there's no entry in the page table) - 'timestamp' => '20120101000100', - 'user' => $userA->getId(), - 'text' => 'one', - 'content_model' => CONTENT_MODEL_WIKITEXT, - 'summary' => 'edit one' - ) ); - $revisions[1]->insertOn( $dbw ); - - # two - $revisions[2] = new Revision( array( - 'page' => $page->getId(), - 'title' => $page->getTitle(), - 'timestamp' => '20120101000200', - 'user' => $userB->getId(), - 'text' => 'two', - 'content_model' => CONTENT_MODEL_WIKITEXT, - 'summary' => 'edit two' - ) ); - $revisions[2]->insertOn( $dbw ); - - # three - $revisions[3] = new Revision( array( - 'page' => $page->getId(), - 'title' => $page->getTitle(), - 'timestamp' => '20120101000300', - 'user' => $userA->getId(), - 'text' => 'three', - 'content_model' => CONTENT_MODEL_WIKITEXT, - 'summary' => 'edit three' - ) ); - $revisions[3]->insertOn( $dbw ); - - # four - $revisions[4] = new Revision( array( - 'page' => $page->getId(), - 'title' => $page->getTitle(), - 'timestamp' => '20120101000200', - 'user' => $userA->getId(), - 'text' => 'zero', - 'content_model' => CONTENT_MODEL_WIKITEXT, - 'summary' => 'edit four' - ) ); - $revisions[4]->insertOn( $dbw ); - - // test it --------------------------------- - $since = $revisions[$sinceIdx]->getTimestamp(); - - $wasLast = Revision::userWasLastToEdit( $dbw, $page->getId(), $userA->getId(), $since ); - - $this->assertEquals( $expectedLast, $wasLast ); - } -} diff --git a/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php b/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php deleted file mode 100644 index 4e83e355..00000000 --- a/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php - -/** - * @group ContentHandler - * @group Database - * ^--- important, causes temporary tables to be used instead of the real database - */ -class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest { - - protected function setUp() { - $this->setMwGlobals( 'wgContentHandlerUseDB', false ); - - $dbw = wfGetDB( DB_MASTER ); - - $page_table = $dbw->tableName( 'page' ); - $revision_table = $dbw->tableName( 'revision' ); - $archive_table = $dbw->tableName( 'archive' ); - - if ( $dbw->fieldExists( $page_table, 'page_content_model' ) ) { - $dbw->query( "alter table $page_table drop column page_content_model" ); - $dbw->query( "alter table $revision_table drop column rev_content_model" ); - $dbw->query( "alter table $revision_table drop column rev_content_format" ); - $dbw->query( "alter table $archive_table drop column ar_content_model" ); - $dbw->query( "alter table $archive_table drop column ar_content_format" ); - } - - parent::setUp(); - } - - /** - * @covers Revision::selectFields - */ - public function testSelectFields() { - $fields = Revision::selectFields(); - - $this->assertTrue( in_array( 'rev_id', $fields ), 'missing rev_id in list of fields' ); - $this->assertTrue( in_array( 'rev_page', $fields ), 'missing rev_page in list of fields' ); - $this->assertTrue( in_array( 'rev_timestamp', $fields ), 'missing rev_timestamp in list of fields' ); - $this->assertTrue( in_array( 'rev_user', $fields ), 'missing rev_user in list of fields' ); - - $this->assertFalse( in_array( 'rev_content_model', $fields ), 'missing rev_content_model in list of fields' ); - $this->assertFalse( in_array( 'rev_content_format', $fields ), 'missing rev_content_format in list of fields' ); - } - - /** - * @covers Revision::getContentModel - */ - public function testGetContentModel() { - try { - $this->makeRevision( array( 'text' => 'hello hello.', - 'content_model' => CONTENT_MODEL_JAVASCRIPT ) ); - - $this->fail( "Creating JavaScript content on a wikitext page should fail with " - . "\$wgContentHandlerUseDB disabled" ); - } catch ( MWException $ex ) { - $this->assertTrue( true ); // ok - } - } - - - /** - * @covers Revision::getContentFormat - */ - public function testGetContentFormat() { - try { - // @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. - - $this->makeRevision( array( 'text' => 'hello hello.', - 'content_model' => CONTENT_MODEL_JAVASCRIPT, - 'content_format' => 'text/javascript' ) ); - - $this->fail( "Creating JavaScript content on a wikitext page should fail with " - . "\$wgContentHandlerUseDB disabled" ); - } catch ( MWException $ex ) { - $this->assertTrue( true ); // ok - } - } -} diff --git a/tests/phpunit/includes/RevisionTest.php b/tests/phpunit/includes/RevisionTest.php deleted file mode 100644 index b5819ff6..00000000 --- a/tests/phpunit/includes/RevisionTest.php +++ /dev/null @@ -1,481 +0,0 @@ -<?php - -/** - * @group ContentHandler - */ -class RevisionTest extends MediaWikiTestCase { - protected function setUp() { - global $wgContLang; - - parent::setUp(); - - $this->setMwGlobals( array( - 'wgContLang' => Language::factory( 'en' ), - 'wgLanguageCode' => 'en', - 'wgLegacyEncoding' => false, - 'wgCompressRevisions' => false, - - 'wgContentHandlerTextFallback' => 'ignore', - ) ); - - $this->mergeMwGlobalArrayValue( - 'wgExtraNamespaces', - array( - 12312 => 'Dummy', - 12313 => 'Dummy_talk', - ) - ); - - $this->mergeMwGlobalArrayValue( - 'wgNamespaceContentModels', - array( - 12312 => 'testing', - ) - ); - - $this->mergeMwGlobalArrayValue( - 'wgContentHandlers', - array( - 'testing' => 'DummyContentHandlerForTesting', - 'RevisionTestModifyableContent' => 'RevisionTestModifyableContentHandler', - ) - ); - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - } - - function tearDown() { - global $wgContLang; - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - - parent::tearDown(); - } - - /** - * @covers Revision::getRevisionText - */ - public function testGetRevisionText() { - $row = new stdClass; - $row->old_flags = ''; - $row->old_text = 'This is a bunch of revision text.'; - $this->assertEquals( - 'This is a bunch of revision text.', - Revision::getRevisionText( $row ) ); - } - - /** - * @covers Revision::getRevisionText - */ - public function testGetRevisionTextGzip() { - $this->checkPHPExtension( 'zlib' ); - - $row = new stdClass; - $row->old_flags = 'gzip'; - $row->old_text = gzdeflate( 'This is a bunch of revision text.' ); - $this->assertEquals( - 'This is a bunch of revision text.', - Revision::getRevisionText( $row ) ); - } - - /** - * @covers Revision::getRevisionText - */ - public function testGetRevisionTextUtf8Native() { - $row = new stdClass; - $row->old_flags = 'utf-8'; - $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; - $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; - $this->assertEquals( - "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ) ); - } - - /** - * @covers Revision::getRevisionText - */ - public function testGetRevisionTextUtf8Legacy() { - $row = new stdClass; - $row->old_flags = ''; - $row->old_text = "Wiki est l'\xe9cole superieur !"; - $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; - $this->assertEquals( - "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ) ); - } - - /** - * @covers Revision::getRevisionText - */ - public function testGetRevisionTextUtf8NativeGzip() { - $this->checkPHPExtension( 'zlib' ); - - $row = new stdClass; - $row->old_flags = 'gzip,utf-8'; - $row->old_text = gzdeflate( "Wiki est l'\xc3\xa9cole superieur !" ); - $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; - $this->assertEquals( - "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ) ); - } - - /** - * @covers Revision::getRevisionText - */ - public function testGetRevisionTextUtf8LegacyGzip() { - $this->checkPHPExtension( 'zlib' ); - - $row = new stdClass; - $row->old_flags = 'gzip'; - $row->old_text = gzdeflate( "Wiki est l'\xe9cole superieur !" ); - $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; - $this->assertEquals( - "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ) ); - } - - /** - * @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 ); - $this->assertTrue( false !== strpos( $row->old_flags, 'utf-8' ), - "Flags should contain 'utf-8'" ); - $this->assertFalse( false !== strpos( $row->old_flags, 'gzip' ), - "Flags should not contain 'gzip'" ); - $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", - $row->old_text, "Direct check" ); - $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ), "getRevisionText" ); - } - - /** - * @covers Revision::compressRevisionText - */ - public function testCompressRevisionTextUtf8Gzip() { - $this->checkPHPExtension( 'zlib' ); - $this->setMwGlobals( 'wgCompressRevisions', true ); - - $row = new stdClass; - $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; - $row->old_flags = Revision::compressRevisionText( $row->old_text ); - $this->assertTrue( false !== strpos( $row->old_flags, 'utf-8' ), - "Flags should contain 'utf-8'" ); - $this->assertTrue( false !== strpos( $row->old_flags, 'gzip' ), - "Flags should contain 'gzip'" ); - $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", - gzinflate( $row->old_text ), "Direct check" ); - $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ), "getRevisionText" ); - } - - # ================================================================================================================= - - /** - * @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 ) { - if ( is_string( $title ) ) { - $title = Title::newFromText( $title ); - } - - $content = ContentHandler::makeContent( $text, $title, $model, $format ); - - $rev = new Revision( - array( - 'id' => 42, - 'page' => 23, - 'title' => $title, - - 'content' => $content, - 'length' => $content->getSize(), - 'comment' => "testing", - 'minor_edit' => false, - - 'content_format' => $format, - ) - ); - - return $rev; - } - - function dataGetContentModel() { - //NOTE: we expect the help namespace to always contain wikitext - return array( - array( 'hello world', 'Help:Hello', null, null, CONTENT_MODEL_WIKITEXT ), - array( 'hello world', 'User:hello/there.css', null, null, CONTENT_MODEL_CSS ), - array( serialize( 'hello world' ), 'Dummy:Hello', null, null, "testing" ), - ); - } - - /** - * @group Database - * @dataProvider dataGetContentModel - * @covers Revision::getContentModel - */ - public function testGetContentModel( $text, $title, $model, $format, $expectedModel ) { - $rev = $this->newTestRevision( $text, $title, $model, $format ); - - $this->assertEquals( $expectedModel, $rev->getContentModel() ); - } - - function dataGetContentFormat() { - //NOTE: we expect the help namespace to always contain wikitext - return array( - array( 'hello world', 'Help:Hello', null, null, CONTENT_FORMAT_WIKITEXT ), - array( 'hello world', 'Help:Hello', CONTENT_MODEL_CSS, null, CONTENT_FORMAT_CSS ), - array( 'hello world', 'User:hello/there.css', null, null, CONTENT_FORMAT_CSS ), - array( serialize( 'hello world' ), 'Dummy:Hello', null, null, "testing" ), - ); - } - - /** - * @group Database - * @dataProvider dataGetContentFormat - * @covers Revision::getContentFormat - */ - public function testGetContentFormat( $text, $title, $model, $format, $expectedFormat ) { - $rev = $this->newTestRevision( $text, $title, $model, $format ); - - $this->assertEquals( $expectedFormat, $rev->getContentFormat() ); - } - - function dataGetContentHandler() { - //NOTE: we expect the help namespace to always contain wikitext - return array( - array( 'hello world', 'Help:Hello', null, null, 'WikitextContentHandler' ), - array( 'hello world', 'User:hello/there.css', null, null, 'CssContentHandler' ), - array( serialize( 'hello world' ), 'Dummy:Hello', null, null, 'DummyContentHandlerForTesting' ), - ); - } - - /** - * @group Database - * @dataProvider dataGetContentHandler - * @covers Revision::getContentHandler - */ - public function testGetContentHandler( $text, $title, $model, $format, $expectedClass ) { - $rev = $this->newTestRevision( $text, $title, $model, $format ); - - $this->assertEquals( $expectedClass, get_class( $rev->getContentHandler() ) ); - } - - function dataGetContent() { - //NOTE: we expect the help namespace to always contain wikitext - return array( - array( 'hello world', 'Help:Hello', null, null, Revision::FOR_PUBLIC, 'hello world' ), - array( serialize( 'hello world' ), 'Hello', "testing", null, Revision::FOR_PUBLIC, serialize( 'hello world' ) ), - array( serialize( 'hello world' ), 'Dummy:Hello', null, null, Revision::FOR_PUBLIC, serialize( 'hello world' ) ), - ); - } - - /** - * @group Database - * @dataProvider dataGetContent - * @covers Revision::getContent - */ - public function testGetContent( $text, $title, $model, $format, $audience, $expectedSerialization ) { - $rev = $this->newTestRevision( $text, $title, $model, $format ); - $content = $rev->getContent( $audience ); - - $this->assertEquals( $expectedSerialization, is_null( $content ) ? null : $content->serialize( $format ) ); - } - - function dataGetText() { - //NOTE: we expect the help namespace to always contain wikitext - return array( - array( 'hello world', 'Help:Hello', null, null, Revision::FOR_PUBLIC, 'hello world' ), - array( serialize( 'hello world' ), 'Hello', "testing", null, Revision::FOR_PUBLIC, null ), - array( serialize( 'hello world' ), 'Dummy:Hello', null, null, Revision::FOR_PUBLIC, null ), - ); - } - - /** - * @group Database - * @dataProvider dataGetText - * @covers Revision::getText - */ - public function testGetText( $text, $title, $model, $format, $audience, $expectedText ) { - $this->hideDeprecated( 'Revision::getText' ); - - $rev = $this->newTestRevision( $text, $title, $model, $format ); - - $this->assertEquals( $expectedText, $rev->getText( $audience ) ); - } - - /** - * @group Database - * @dataProvider dataGetText - * @covers Revision::getRawText - */ - public function testGetRawText( $text, $title, $model, $format, $audience, $expectedText ) { - $this->hideDeprecated( 'Revision::getRawText' ); - - $rev = $this->newTestRevision( $text, $title, $model, $format ); - - $this->assertEquals( $expectedText, $rev->getRawText( $audience ) ); - } - - - public function dataGetSize() { - return array( - array( "hello world.", CONTENT_MODEL_WIKITEXT, 12 ), - array( serialize( "hello world." ), "testing", 12 ), - ); - } - - /** - * @covers Revision::getSize - * @group Database - * @dataProvider dataGetSize - */ - public function testGetSize( $text, $model, $expected_size ) { - $rev = $this->newTestRevision( $text, 'RevisionTest_testGetSize', $model ); - $this->assertEquals( $expected_size, $rev->getSize() ); - } - - public function dataGetSha1() { - return array( - array( "hello world.", CONTENT_MODEL_WIKITEXT, Revision::base36Sha1( "hello world." ) ), - array( serialize( "hello world." ), "testing", Revision::base36Sha1( serialize( "hello world." ) ) ), - ); - } - - /** - * @covers Revision::getSha1 - * @group Database - * @dataProvider dataGetSha1 - */ - public function testGetSha1( $text, $model, $expected_hash ) { - $rev = $this->newTestRevision( $text, 'RevisionTest_testGetSha1', $model ); - $this->assertEquals( $expected_hash, $rev->getSha1() ); - } - - /** - * @covers Revision::__construct - */ - public function testConstructWithText() { - $this->hideDeprecated( "Revision::getText" ); - - $rev = new Revision( array( - 'text' => 'hello world.', - 'content_model' => CONTENT_MODEL_JAVASCRIPT - ) ); - - $this->assertNotNull( $rev->getText(), 'no content text' ); - $this->assertNotNull( $rev->getContent(), 'no content object available' ); - $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContent()->getModel() ); - $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() ); - } - - /** - * @covers Revision::__construct - */ - public function testConstructWithContent() { - $this->hideDeprecated( "Revision::getText" ); - - $title = Title::newFromText( 'RevisionTest_testConstructWithContent' ); - - $rev = new Revision( array( - 'content' => ContentHandler::makeContent( 'hello world.', $title, CONTENT_MODEL_JAVASCRIPT ), - ) ); - - $this->assertNotNull( $rev->getText(), 'no content text' ); - $this->assertNotNull( $rev->getContent(), 'no content object available' ); - $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContent()->getModel() ); - $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() ); - } - - /** - * Tests whether $rev->getContent() returns a clone when needed. - * - * @group Database - * @covers Revision::getContent - */ - public function testGetContentClone() { - $content = new RevisionTestModifyableContent( "foo" ); - - $rev = new Revision( - array( - 'id' => 42, - 'page' => 23, - 'title' => Title::newFromText( "testGetContentClone_dummy" ), - - 'content' => $content, - 'length' => $content->getSize(), - 'comment' => "testing", - 'minor_edit' => false, - ) - ); - - $content = $rev->getContent( Revision::RAW ); - $content->setText( "bar" ); - - $content2 = $rev->getContent( Revision::RAW ); - $this->assertNotSame( $content, $content2, "expected a clone" ); // content is mutable, expect clone - $this->assertEquals( "foo", $content2->getText() ); // clone should contain the original text - - $content2->setText( "bla bla" ); - $this->assertEquals( "bar", $content->getText() ); // clones should be independent - } - - - /** - * Tests whether $rev->getContent() returns the same object repeatedly if appropriate. - * - * @group Database - * @covers Revision::getContent - */ - public function testGetContentUncloned() { - $rev = $this->newTestRevision( "hello", "testGetContentUncloned_dummy", CONTENT_MODEL_WIKITEXT ); - $content = $rev->getContent( Revision::RAW ); - $content2 = $rev->getContent( Revision::RAW ); - - // for immutable content like wikitext, this should be the same object - $this->assertSame( $content, $content2 ); - } -} - -class RevisionTestModifyableContent extends TextContent { - public function __construct( $text ) { - parent::__construct( $text, "RevisionTestModifyableContent" ); - } - - public function copy() { - return new RevisionTestModifyableContent( $this->mText ); - } - - public function getText() { - return $this->mText; - } - - public function setText( $text ) { - $this->mText = $text; - } -} - -class RevisionTestModifyableContentHandler extends TextContentHandler { - - public function __construct() { - parent::__construct( "RevisionTestModifyableContent", array( CONTENT_FORMAT_TEXT ) ); - } - - public function unserializeContent( $text, $format = null ) { - $this->checkFormat( $format ); - - return new RevisionTestModifyableContent( $text ); - } - - public function makeEmptyContent() { - return new RevisionTestModifyableContent( '' ); - } -} diff --git a/tests/phpunit/includes/SampleTest.php b/tests/phpunit/includes/SampleTest.php deleted file mode 100644 index 8516a4ce..00000000 --- a/tests/phpunit/includes/SampleTest.php +++ /dev/null @@ -1,105 +0,0 @@ -<?php - -class TestSample extends MediaWikiLangTestCase { - - /** - * Anything that needs to happen before your tests should go here. - */ - protected function setUp() { - // Be sure to do call the parent setup and teardown functions. - // This makes sure that all the various cleanup and restorations - // happen as they should (including the restoration for setMwGlobals). - parent::setUp(); - - // This sets the globals and will restore them automatically - // after each test. - $this->setMwGlobals( array( - 'wgContLang' => Language::factory( 'en' ), - 'wgLanguageCode' => 'en', - ) ); - } - - /** - * Anything cleanup you need to do should go here. - */ - protected function tearDown() { - parent::tearDown(); - } - - /** - * Name tests so that PHPUnit can turn them into sentences when - * they run. While MediaWiki isn't strictly an Agile Programming - * project, you are encouraged to use the naming described under - * "Agile Documentation" at - * http://www.phpunit.de/manual/3.4/en/other-uses-for-tests.html - */ - public function testTitleObjectStringConversion() { - $title = Title::newFromText( "text" ); - $this->assertInstanceOf( 'Title', $title, "Title creation" ); - $this->assertEquals( "Text", $title, "Automatic string conversion" ); - - $title = Title::newFromText( "text", NS_MEDIA ); - $this->assertEquals( "Media:Text", $title, "Title creation with namespace" ); - } - - /** - * If you want to run a the same test with a variety of data. use a data provider. - * see: http://www.phpunit.de/manual/3.4/en/writing-tests-for-phpunit.html - * - * Note: Data providers are always called statically and outside setUp/tearDown! - */ - public static function provideTitles() { - return array( - array( 'Text', NS_MEDIA, 'Media:Text' ), - array( 'Text', null, 'Text' ), - array( 'text', null, 'Text' ), - array( 'Text', NS_USER, 'User:Text' ), - array( 'Photo.jpg', NS_FILE, 'File:Photo.jpg' ) - ); - } - - /** - * @dataProvider provideTitles - * See http://www.phpunit.de/manual/3.4/en/appendixes.annotations.html#appendixes.annotations.dataProvider - */ - public function testCreateBasicListOfTitles( $titleName, $ns, $text ) { - $title = Title::newFromText( $titleName, $ns ); - $this->assertEquals( $text, "$title", "see if '$titleName' matches '$text'" ); - } - - public function testSetUpMainPageTitleForNextTest() { - $title = Title::newMainPage(); - $this->assertEquals( "Main Page", "$title", "Test initial creation of a title" ); - - return $title; - } - - /** - * Instead of putting a bunch of tests in a single test method, - * you should put only one or two tests in each test method. This - * way, the test method names can remain descriptive. - * - * If you want to make tests depend on data created in another - * method, you can create dependencies feed whatever you return - * from the dependant method (e.g. testInitialCreation in this - * example) as arguments to the next method (e.g. $title in - * testTitleDepends is whatever testInitialCreatiion returned.) - */ - - /** - * @depends testSetUpMainPageTitleForNextTest - * See http://www.phpunit.de/manual/3.4/en/appendixes.annotations.html#appendixes.annotations.depends - */ - public function testCheckMainPageTitleIsConsideredLocal( $title ) { - $this->assertTrue( $title->isLocal() ); - } - - /** - * @expectedException MWException object - * See http://www.phpunit.de/manual/3.4/en/appendixes.annotations.html#appendixes.annotations.expectedException - */ - 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 deleted file mode 100644 index 81246d33..00000000 --- a/tests/phpunit/includes/SanitizerTest.php +++ /dev/null @@ -1,302 +0,0 @@ -<?php - -/** - * @todo Tests covering decodeCharReferences can be refactored into a single - * method and dataprovider. - */ -class SanitizerTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - AutoLoader::loadClass( 'Sanitizer' ); - } - - /** - * @covers Sanitizer::decodeCharReferences - */ - public function testDecodeNamedEntities() { - $this->assertEquals( - "\xc3\xa9cole", - Sanitizer::decodeCharReferences( 'école' ), - 'decode named entities' - ); - } - - /** - * @covers Sanitizer::decodeCharReferences - */ - public function testDecodeNumericEntities() { - $this->assertEquals( - "\xc4\x88io bonas dans l'\xc3\xa9cole!", - Sanitizer::decodeCharReferences( "Ĉio bonas dans l'école!" ), - 'decode numeric entities' - ); - } - - /** - * @covers Sanitizer::decodeCharReferences - */ - public function testDecodeMixedEntities() { - $this->assertEquals( - "\xc4\x88io bonas dans l'\xc3\xa9cole!", - Sanitizer::decodeCharReferences( "Ĉio bonas dans l'école!" ), - 'decode mixed numeric/named entities' - ); - } - - /** - * @covers Sanitizer::decodeCharReferences - */ - public function testDecodeMixedComplexEntities() { - $this->assertEquals( - "\xc4\x88io bonas dans l'\xc3\xa9cole! (mais pas Ĉio dans l'école)", - Sanitizer::decodeCharReferences( - "Ĉio bonas dans l'école! (mais pas &#x108;io dans l'&eacute;cole)" - ), - 'decode mixed complex entities' - ); - } - - /** - * @covers Sanitizer::decodeCharReferences - */ - public function testInvalidAmpersand() { - $this->assertEquals( - 'a & b', - Sanitizer::decodeCharReferences( 'a & b' ), - 'Invalid ampersand' - ); - } - - /** - * @covers Sanitizer::decodeCharReferences - */ - public function testInvalidEntities() { - $this->assertEquals( - '&foo;', - Sanitizer::decodeCharReferences( '&foo;' ), - 'Invalid named entity' - ); - } - - /** - * @covers Sanitizer::decodeCharReferences - */ - public function testInvalidNumberedEntities() { - $this->assertEquals( UTF8_REPLACEMENT, Sanitizer::decodeCharReferences( "�" ), 'Invalid numbered entity' ); - } - - /** - * @covers Sanitizer::removeHTMLtags - * @dataProvider provideHtml5Tags - * - * @param String $tag Name of an HTML5 element (ie: 'video') - * @param Boolean $escaped Wheter sanitizer let the tag in or escape it (ie: '<video>') - */ - public function testRemovehtmltagsOnHtml5Tags( $tag, $escaped ) { - $this->setMwGlobals( array( - 'wgUseTidy' => false - ) ); - - if ( $escaped ) { - $this->assertEquals( "<$tag>", - Sanitizer::removeHTMLtags( "<$tag>" ) - ); - } else { - $this->assertEquals( "<$tag></$tag>\n", - Sanitizer::removeHTMLtags( "<$tag>" ) - ); - } - } - - /** - * Provide HTML5 tags - */ - public static function provideHtml5Tags() { - $ESCAPED = true; # We want tag to be escaped - $VERBATIM = false; # We want to keep the tag - return array( - array( 'data', $VERBATIM ), - array( 'mark', $VERBATIM ), - array( 'time', $VERBATIM ), - array( 'video', $ESCAPED ), - ); - } - - 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 - */ - public function testDecodeTagAttributes( $expected, $attributes, $message = '' ) { - $this->assertEquals( $expected, - Sanitizer::decodeTagAttributes( $attributes ), - $message - ); - } - - public static function provideTagAttributesToDecode() { - return array( - array( array( 'foo' => 'bar' ), 'foo=bar', 'Unquoted attribute' ), - array( array( 'foo' => 'bar' ), ' foo = bar ', 'Spaced attribute' ), - array( array( 'foo' => 'bar' ), 'foo="bar"', 'Double-quoted attribute' ), - array( array( 'foo' => 'bar' ), 'foo=\'bar\'', 'Single-quoted attribute' ), - array( array( 'foo' => 'bar', 'baz' => 'foo' ), 'foo=\'bar\' baz="foo"', 'Several attributes' ), - array( array( 'foo' => 'bar', 'baz' => 'foo' ), 'foo=\'bar\' baz="foo"', 'Several attributes' ), - array( array( 'foo' => 'bar', 'baz' => 'foo' ), 'foo=\'bar\' baz="foo"', 'Several attributes' ), - array( array( ':foo' => 'bar' ), ':foo=\'bar\'', 'Leading :' ), - array( array( '_foo' => 'bar' ), '_foo=\'bar\'', 'Leading _' ), - array( array( 'foo' => 'bar' ), 'Foo=\'bar\'', 'Leading capital' ), - array( array( 'foo' => 'BAR' ), 'FOO=BAR', 'Attribute keys are normalized to lowercase' ), - - # Invalid beginning - array( array(), '-foo=bar', 'Leading - is forbidden' ), - array( array(), '.foo=bar', 'Leading . is forbidden' ), - array( array( 'foo-bar' => 'bar' ), 'foo-bar=bar', 'A - is allowed inside the attribute' ), - array( array( 'foo-' => 'bar' ), 'foo-=bar', 'A - is allowed inside the attribute' ), - array( array( 'foo.bar' => 'baz' ), 'foo.bar=baz', 'A . is allowed inside the attribute' ), - 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' ), - array( array(), 'foo$=baz', 'Symbols are not allowed' ), - array( array(), 'foo@=baz', 'Symbols are not allowed' ), - array( array(), 'foo~=baz', 'Symbols are not allowed' ), - array( array( 'foo' => '1[#^`*%w/(' ), 'foo=1[#^`*%w/(', 'All kind of characters are allowed as values' ), - array( array( 'foo' => '1[#^`*%\'w/(' ), 'foo="1[#^`*%\'w/("', 'Double quotes are allowed if quoted by single quotes' ), - array( array( 'foo' => '1[#^`*%"w/(' ), 'foo=\'1[#^`*%"w/(\'', 'Single quotes are allowed if quoted by double quotes' ), - array( array( 'foo' => '&"' ), 'foo=&"', 'Special chars can be provided as entities' ), - array( array( 'foo' => '&foobar;' ), 'foo=&foobar;', 'Entity-like items are accepted' ), - ); - } - - /** - * @dataProvider provideDeprecatedAttributes - * @covers Sanitizer::fixTagAttributes - */ - public function testDeprecatedAttributesUnaltered( $inputAttr, $inputEl, $message = '' ) { - $this->assertEquals( " $inputAttr", - Sanitizer::fixTagAttributes( $inputAttr, $inputEl ), - $message - ); - } - - public static function provideDeprecatedAttributes() { - /** array( <attribute>, <element>, [message] ) */ - return array( - array( 'clear="left"', 'br' ), - array( 'clear="all"', 'br' ), - array( 'width="100"', 'td' ), - array( 'nowrap="true"', 'td' ), - array( 'nowrap=""', 'td' ), - array( 'align="right"', 'td' ), - array( 'align="center"', 'table' ), - array( 'align="left"', 'tr' ), - array( 'align="center"', 'div' ), - array( 'align="left"', 'h1' ), - array( 'align="left"', 'span' ), - ); - } - - /** - * @dataProvider provideCssCommentsFixtures - * @covers Sanitizer::checkCss - */ - public function testCssCommentsChecking( $expected, $css, $message = '' ) { - $this->assertEquals( $expected, - Sanitizer::checkCss( $css ), - $message - ); - } - - public static function provideCssCommentsFixtures() { - /** array( <expected>, <css>, [message] ) */ - return array( - // Valid comments spanning entire input - array( '/**/', '/**/' ), - array( '/* comment */', '/* comment */' ), - // Weird stuff - array( ' ', '/****/' ), - 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' ), - array( '', "\\2f\\2a unifinished comment'", - 'Remove anything after a backslash-escaped comment-start token' ), - array( '/* insecure input */', 'filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'asdf.png\',sizingMethod=\'scale\');' ), - array( '/* insecure input */', '-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'asdf.png\',sizingMethod=\'scale\')";' ), - array( '/* insecure input */', 'width: expression(1+1);' ), - array( '/* insecure input */', 'background-image: image(asdf.png);' ), - array( '/* insecure input */', 'background-image: -webkit-image(asdf.png);' ), - array( '/* insecure input */', 'background-image: -moz-image(asdf.png);' ), - array( '/* insecure input */', 'background-image: image-set("asdf.png" 1x, "asdf.png" 2x);' ), - array( '/* insecure input */', 'background-image: -webkit-image-set("asdf.png" 1x, "asdf.png" 2x);' ), - array( '/* insecure input */', 'background-image: -moz-image-set("asdf.png" 1x, "asdf.png" 2x);' ), - ); - } - - /** - * Test for support or lack of support for specific attributes in the attribute whitelist. - */ - public static function provideAttributeSupport() { - /** array( <attributes>, <expected>, <message> ) */ - return array( - array( 'div', ' role="presentation"', ' role="presentation"', 'Support for WAI-ARIA\'s role="presentation".' ), - array( 'div', ' role="main"', '', "Other WAI-ARIA roles are currently not supported." ), - ); - } - - /** - * @dataProvider provideAttributeSupport - * @covers Sanitizer::fixTagAttributes - */ - 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 deleted file mode 100644 index f13e8382..00000000 --- a/tests/phpunit/includes/SanitizerValidateEmailTest.php +++ /dev/null @@ -1,103 +0,0 @@ -<?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 = '' ) { - if ( $msg == '' ) { - $msg = "Testing $addr"; - } - - $this->assertEquals( - $expected, - Sanitizer::validateEmail( $addr ), - $msg - ); - } - - private function valid( $addr, $msg = '' ) { - $this->checkEmail( $addr, true, $msg ); - } - - private function invalid( $addr, $msg = '' ) { - $this->checkEmail( $addr, false, $msg ); - } - - public function testEmailWellKnownUserAtHostDotTldAreValid() { - $this->valid( 'user@example.com' ); - $this->valid( 'user@example.museum' ); - } - - public function testEmailWithUpperCaseCharactersAreValid() { - $this->valid( 'USER@example.com' ); - $this->valid( 'user@EXAMPLE.COM' ); - $this->valid( 'user@Example.com' ); - $this->valid( 'USER@eXAMPLE.com' ); - } - - public function testEmailWithAPlusInUserName() { - $this->valid( 'user+sub@example.com' ); - $this->valid( 'user+@example.com' ); - } - - public function testEmailDoesNotNeedATopLevelDomain() { - $this->valid( "user@localhost" ); - $this->valid( "FooBar@localdomain" ); - $this->valid( "nobody@mycompany" ); - } - - public function testEmailWithWhiteSpacesBeforeOrAfterAreInvalids() { - $this->invalid( " user@host.com" ); - $this->invalid( "user@host.com " ); - $this->invalid( "\tuser@host.com" ); - $this->invalid( "user@host.com\t" ); - } - - 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 - */ - public function testEmailWithCommasAreInvalids() { - $this->invalid( "user,foo@example.org" ); - $this->invalid( "userfoo@ex,ample.org" ); - } - - public function testEmailWithHyphens() { - $this->valid( "user-foo@example.org" ); - $this->valid( "userfoo@ex-ample.org" ); - } - - public function testEmailDomainCanNotBeginWithDot() { - $this->invalid( "user@." ); - $this->invalid( "user@.localdomain" ); - $this->invalid( "user@localdomain." ); - $this->valid( "user.@localdomain" ); - $this->valid( ".@localdomain" ); - $this->invalid( ".@a............" ); - } - - public function testEmailWithFunnyCharacters() { - $this->valid( "\$user!ex{this}@123.com" ); - } - - public function testEmailTopLevelDomainCanBeNumerical() { - $this->valid( "user@example.1234" ); - } - - public function testEmailWithoutAtSignIsInvalid() { - $this->invalid( 'useràexample.com' ); - } - - public function testEmailWithOneCharacterDomainIsValid() { - $this->valid( 'user@a' ); - } -} diff --git a/tests/phpunit/includes/SiteConfigurationTest.php b/tests/phpunit/includes/SiteConfigurationTest.php deleted file mode 100644 index 053d8a7d..00000000 --- a/tests/phpunit/includes/SiteConfigurationTest.php +++ /dev/null @@ -1,335 +0,0 @@ -<?php - -function getSiteParams( $conf, $wiki ) { - $site = null; - $lang = null; - foreach ( $conf->suffixes as $suffix ) { - if ( substr( $wiki, -strlen( $suffix ) ) == $suffix ) { - $site = $suffix; - $lang = substr( $wiki, 0, -strlen( $suffix ) ); - break; - } - } - - return array( - 'suffix' => $site, - 'lang' => $lang, - 'params' => array( - 'lang' => $lang, - 'site' => $site, - 'wiki' => $wiki, - ), - 'tags' => array( 'tag' ), - ); -} - -class SiteConfigurationTest extends MediaWikiTestCase { - - /** - * @var SiteConfiguration - */ - protected $mConf; - - protected function setUp() { - parent::setUp(); - - $this->mConf = new SiteConfiguration; - - $this->mConf->suffixes = array( 'wikipedia' => 'wiki' ); - $this->mConf->wikis = array( 'enwiki', 'dewiki', 'frwiki' ); - $this->mConf->settings = array( - 'simple' => array( - 'wiki' => 'wiki', - 'tag' => 'tag', - 'enwiki' => 'enwiki', - 'dewiki' => 'dewiki', - 'frwiki' => 'frwiki', - ), - - 'fallback' => array( - 'default' => 'default', - 'wiki' => 'wiki', - 'tag' => 'tag', - ), - - 'params' => array( - 'default' => '$lang $site $wiki', - ), - - '+global' => array( - 'wiki' => array( - 'wiki' => 'wiki', - ), - 'tag' => array( - 'tag' => 'tag', - ), - 'enwiki' => array( - 'enwiki' => 'enwiki', - ), - 'dewiki' => array( - 'dewiki' => 'dewiki', - ), - 'frwiki' => array( - 'frwiki' => 'frwiki', - ), - ), - - 'merge' => array( - '+wiki' => array( - 'wiki' => 'wiki', - ), - '+tag' => array( - 'tag' => 'tag', - ), - 'default' => array( - 'default' => 'default', - ), - '+enwiki' => array( - 'enwiki' => 'enwiki', - ), - '+dewiki' => array( - 'dewiki' => 'dewiki', - ), - '+frwiki' => array( - 'frwiki' => 'frwiki', - ), - ), - ); - - $GLOBALS['global'] = array( 'global' => 'global' ); - } - - /** - * @covers SiteConfiguration::siteFromDB - */ - public function testSiteFromDb() { - $this->assertEquals( - array( 'wikipedia', 'en' ), - $this->mConf->siteFromDB( 'enwiki' ), - 'siteFromDB()' - ); - $this->assertEquals( - array( 'wikipedia', '' ), - $this->mConf->siteFromDB( 'wiki' ), - 'siteFromDB() on a suffix' - ); - $this->assertEquals( - array( null, null ), - $this->mConf->siteFromDB( 'wikien' ), - 'siteFromDB() on a non-existing wiki' - ); - - $this->mConf->suffixes = array( 'wiki', '' ); - $this->assertEquals( - array( '', 'wikien' ), - $this->mConf->siteFromDB( 'wikien' ), - 'siteFromDB() on a non-existing wiki (2)' - ); - } - - /** - * @covers SiteConfiguration::getLocalDatabases - */ - public function testGetLocalDatabases() { - $this->assertEquals( - array( 'enwiki', 'dewiki', 'frwiki' ), - $this->mConf->getLocalDatabases(), - 'getLocalDatabases()' - ); - } - - /** - * @covers SiteConfiguration::get - */ - public function testGetConfVariables() { - $this->assertEquals( - 'enwiki', - $this->mConf->get( 'simple', 'enwiki', 'wiki' ), - 'get(): simple setting on an existing wiki' - ); - $this->assertEquals( - 'dewiki', - $this->mConf->get( 'simple', 'dewiki', 'wiki' ), - 'get(): simple setting on an existing wiki (2)' - ); - $this->assertEquals( - 'frwiki', - $this->mConf->get( 'simple', 'frwiki', 'wiki' ), - 'get(): simple setting on an existing wiki (3)' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'simple', 'wiki', 'wiki' ), - 'get(): simple setting on an suffix' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'simple', 'eswiki', 'wiki' ), - 'get(): simple setting on an non-existing wiki' - ); - - $this->assertEquals( - 'wiki', - $this->mConf->get( 'fallback', 'enwiki', 'wiki' ), - 'get(): fallback setting on an existing wiki' - ); - $this->assertEquals( - 'tag', - $this->mConf->get( 'fallback', 'dewiki', 'wiki', array(), array( 'tag' ) ), - 'get(): fallback setting on an existing wiki (with wiki tag)' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'fallback', 'wiki', 'wiki' ), - 'get(): fallback setting on an suffix' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'fallback', 'wiki', 'wiki', array(), array( 'tag' ) ), - 'get(): fallback setting on an suffix (with wiki tag)' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'fallback', 'eswiki', 'wiki' ), - 'get(): fallback setting on an non-existing wiki' - ); - $this->assertEquals( - 'tag', - $this->mConf->get( 'fallback', 'eswiki', 'wiki', array(), array( 'tag' ) ), - 'get(): fallback setting on an non-existing wiki (with wiki tag)' - ); - - $common = array( 'wiki' => 'wiki', 'default' => 'default' ); - $commonTag = array( 'tag' => 'tag', 'wiki' => 'wiki', 'default' => 'default' ); - $this->assertEquals( - array( 'enwiki' => 'enwiki' ) + $common, - $this->mConf->get( 'merge', 'enwiki', 'wiki' ), - 'get(): merging setting on an existing wiki' - ); - $this->assertEquals( - array( 'enwiki' => 'enwiki' ) + $commonTag, - $this->mConf->get( 'merge', 'enwiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an existing wiki (with tag)' - ); - $this->assertEquals( - array( 'dewiki' => 'dewiki' ) + $common, - $this->mConf->get( 'merge', 'dewiki', 'wiki' ), - 'get(): merging setting on an existing wiki (2)' - ); - $this->assertEquals( - array( 'dewiki' => 'dewiki' ) + $commonTag, - $this->mConf->get( 'merge', 'dewiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an existing wiki (2) (with tag)' - ); - $this->assertEquals( - array( 'frwiki' => 'frwiki' ) + $common, - $this->mConf->get( 'merge', 'frwiki', 'wiki' ), - 'get(): merging setting on an existing wiki (3)' - ); - $this->assertEquals( - array( 'frwiki' => 'frwiki' ) + $commonTag, - $this->mConf->get( 'merge', 'frwiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an existing wiki (3) (with tag)' - ); - $this->assertEquals( - array( 'wiki' => 'wiki' ) + $common, - $this->mConf->get( 'merge', 'wiki', 'wiki' ), - 'get(): merging setting on an suffix' - ); - $this->assertEquals( - array( 'wiki' => 'wiki' ) + $commonTag, - $this->mConf->get( 'merge', 'wiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an suffix (with tag)' - ); - $this->assertEquals( - $common, - $this->mConf->get( 'merge', 'eswiki', 'wiki' ), - 'get(): merging setting on an non-existing wiki' - ); - $this->assertEquals( - $commonTag, - $this->mConf->get( 'merge', 'eswiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an non-existing wiki (with tag)' - ); - } - - /** - * @covers SiteConfiguration::siteFromDB - */ - public function testSiteFromDbWithCallback() { - $this->mConf->siteParamsCallback = 'getSiteParams'; - - $this->assertEquals( - array( 'wiki', 'en' ), - $this->mConf->siteFromDB( 'enwiki' ), - 'siteFromDB() with callback' - ); - $this->assertEquals( - array( 'wiki', '' ), - $this->mConf->siteFromDB( 'wiki' ), - 'siteFromDB() with callback on a suffix' - ); - $this->assertEquals( - array( null, null ), - $this->mConf->siteFromDB( 'wikien' ), - 'siteFromDB() with callback on a non-existing wiki' - ); - } - - /** - * @covers SiteConfiguration::get - */ - public function testParameterReplacement() { - $this->mConf->siteParamsCallback = 'getSiteParams'; - - $this->assertEquals( - 'en wiki enwiki', - $this->mConf->get( 'params', 'enwiki', 'wiki' ), - 'get(): parameter replacement on an existing wiki' - ); - $this->assertEquals( - 'de wiki dewiki', - $this->mConf->get( 'params', 'dewiki', 'wiki' ), - 'get(): parameter replacement on an existing wiki (2)' - ); - $this->assertEquals( - 'fr wiki frwiki', - $this->mConf->get( 'params', 'frwiki', 'wiki' ), - 'get(): parameter replacement on an existing wiki (3)' - ); - $this->assertEquals( - ' wiki wiki', - $this->mConf->get( 'params', 'wiki', 'wiki' ), - 'get(): parameter replacement on an suffix' - ); - $this->assertEquals( - 'es wiki eswiki', - $this->mConf->get( 'params', 'eswiki', 'wiki' ), - 'get(): parameter replacement on an non-existing wiki' - ); - } - - /** - * @covers SiteConfiguration::getAll - */ - public function testGetAllGlobals() { - $this->mConf->siteParamsCallback = 'getSiteParams'; - - $getall = array( - 'simple' => 'enwiki', - 'fallback' => 'tag', - 'params' => 'en wiki enwiki', - 'global' => array( 'enwiki' => 'enwiki' ) + $GLOBALS['global'], - 'merge' => array( 'enwiki' => 'enwiki', 'tag' => 'tag', 'wiki' => 'wiki', 'default' => 'default' ), - ); - $this->assertEquals( $getall, $this->mConf->getAll( 'enwiki' ), 'getAll()' ); - - $this->mConf->extractAllGlobals( 'enwiki', 'wiki' ); - - $this->assertEquals( $getall['simple'], $GLOBALS['simple'], 'extractAllGlobals(): simple setting' ); - $this->assertEquals( $getall['fallback'], $GLOBALS['fallback'], 'extractAllGlobals(): fallback setting' ); - $this->assertEquals( $getall['params'], $GLOBALS['params'], 'extractAllGlobals(): parameter replacement' ); - $this->assertEquals( $getall['global'], $GLOBALS['global'], 'extractAllGlobals(): merging with global' ); - $this->assertEquals( $getall['merge'], $GLOBALS['merge'], 'extractAllGlobals(): merging setting' ); - } -} diff --git a/tests/phpunit/includes/StringUtilsTest.php b/tests/phpunit/includes/StringUtilsTest.php deleted file mode 100644 index 89759e5c..00000000 --- a/tests/phpunit/includes/StringUtilsTest.php +++ /dev/null @@ -1,147 +0,0 @@ -<?php - -class StringUtilsTest extends MediaWikiTestCase { - - /** - * This tests StringUtils::isUtf8 whenever we have the mbstring extension - * loaded. - * - * @covers StringUtils::isUtf8 - * @dataProvider provideStringsForIsUtf8Check - */ - public function testIsUtf8WithMbstring( $expected, $string ) { - if ( !function_exists( 'mb_check_encoding' ) ) { - $this->markTestSkipped( 'Test requires the mbstring PHP extension' ); - } - $this->assertEquals( $expected, - StringUtils::isUtf8( $string ), - 'Testing string "' . $this->escaped( $string ) . '" with mb_check_encoding' - ); - } - - /** - * 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 - */ - public function testIsUtf8WithPhpFallbackImplementation( $expected, $string ) { - $this->assertEquals( $expected, - StringUtils::isUtf8( $string, /** disable mbstring: */true ), - 'Testing string "' . $this->escaped( $string ) . '" with pure PHP implementation' - ); - } - - /** - * Print high range characters as an hexadecimal - */ - function escaped( $string ) { - $escaped = ''; - $length = strlen( $string ); - for ( $i = 0; $i < $length; $i++ ) { - $char = $string[$i]; - $val = ord( $char ); - if ( $val > 127 ) { - $escaped .= '\x' . dechex( $val ); - } else { - $escaped .= $char; - } - } - - return $escaped; - } - - /** - * See also "UTF-8 decoder capability and stress test" by - * Markus Kuhn: - * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt - */ - public static function provideStringsForIsUtf8Check() { - // Expected return values for StringUtils::isUtf8() - $PASS = true; - $FAIL = false; - - return array( - '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 deleted file mode 100644 index fb63a564..00000000 --- a/tests/phpunit/includes/TemplateCategoriesTest.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php - -/** - * @group Database - */ -require __DIR__ . "/../../../maintenance/runJobs.php"; - -class TemplateCategoriesTest extends MediaWikiLangTestCase { - - /** - * @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' ); - - $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' ) ); - - $template->doEditContent( - new WikitextContent( '[[Category:Solved bugs]]' ), - 'Add a category through a template', - 0, - false, - $user - ); - - // Run the job queue - JobQueueGroup::destroySingletons(); - $jobs = new RunJobs; - $jobs->loadParamsAndArgs( null, array( 'quiet' => true ), null ); - $jobs->execute(); - - $this->assertEquals( - array( 'Category:Solved_bugs' => $title->getPrefixedText() ) - , $title->getParentCategories() - ); - } -} diff --git a/tests/phpunit/includes/TestUser.php b/tests/phpunit/includes/TestUser.php deleted file mode 100644 index 23e65031..00000000 --- a/tests/phpunit/includes/TestUser.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php - -/** - * 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; - public $email; - public $groups; - public $user; - - public function __construct( $username, $realname = 'Real Name', $email = 'sample@example.com', $groups = array() ) { - $this->username = $username; - $this->realname = $realname; - $this->email = $email; - $this->groups = $groups; - - // don't allow user to hardcode or select passwords -- people sometimes run tests - // on live wikis. Sometimes we create sysop users in these tests. A sysop user with - // a known password would be a Bad Thing. - $this->password = User::randomPassword(); - - $this->user = User::newFromName( $this->username ); - $this->user->load(); - - // In an ideal world we'd have a new wiki (or mock data store) for every single test. - // But for now, we just need to create or update the user with the desired properties. - // we particularly need the new password, since we just generated it randomly. - // In core MediaWiki, there is no functionality to delete users, so this is the best we can do. - if ( !$this->user->getID() ) { - // create the user - $this->user = User::createNew( - $this->username, array( - "email" => $this->email, - "real_name" => $this->realname - ) - ); - if ( !$this->user ) { - throw new Exception( "error creating user" ); - } - } - - // update the user to use the new random password and other details - $this->user->setPassword( $this->password ); - $this->user->setEmail( $this->email ); - $this->user->setRealName( $this->realname ); - // remove all groups, replace with any groups specified - foreach ( $this->user->getGroups() as $group ) { - $this->user->removeGroup( $group ); - } - if ( count( $this->groups ) ) { - foreach ( $this->groups as $group ) { - $this->user->addGroup( $group ); - } - } - $this->user->saveSettings(); - } -} diff --git a/tests/phpunit/includes/TimeAdjustTest.php b/tests/phpunit/includes/TimeAdjustTest.php deleted file mode 100644 index 0b368c25..00000000 --- a/tests/phpunit/includes/TimeAdjustTest.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php - -class TimeAdjustTest extends MediaWikiLangTestCase { - protected function setUp() { - parent::setUp(); - - $this->iniSet( 'precision', 15 ); - } - - /** - * 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 ); - - $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 ), - array( 20061231235959, 60, 20070101005959 ), - array( 20061231235959, 90, 20070101012959 ), - array( 20061231235959, 120, 20070101015959 ), - array( 20061231235959, 540, 20070101085959 ), - array( 20061231235959, -5, 20061231235459 ), - array( 20061231235959, -30, 20061231232959 ), - array( 20061231235959, -60, 20061231225959 ), - ); - } -} diff --git a/tests/phpunit/includes/TimestampTest.php b/tests/phpunit/includes/TimestampTest.php deleted file mode 100644 index 53388392..00000000 --- a/tests/phpunit/includes/TimestampTest.php +++ /dev/null @@ -1,304 +0,0 @@ -<?php - -/** - * Tests timestamp parsing and output. - */ -class TimestampTest extends MediaWikiLangTestCase { - - protected function setUp() { - parent::setUp(); - - RequestContext::getMain()->setLanguage( Language::factory( 'en' ) ); - } - - /** - * Test parsing of valid timestamps and outputing to MW format. - * @dataProvider provideValidTimestamps - * @covers MWTimestamp::getTimestamp - */ - public function testValidParse( $format, $original, $expected ) { - $timestamp = new MWTimestamp( $original ); - $this->assertEquals( $expected, $timestamp->getTimestamp( TS_MW ) ); - } - - /** - * Test outputting valid timestamps to different formats. - * @dataProvider provideValidTimestamps - * @covers MWTimestamp::getTimestamp - */ - public function testValidOutput( $format, $expected, $original ) { - $timestamp = new MWTimestamp( $original ); - $this->assertEquals( $expected, (string)$timestamp->getTimestamp( $format ) ); - } - - /** - * Test an invalid timestamp. - * @expectedException TimestampException - * @covers MWTimestamp - */ - public function testInvalidParse() { - new MWTimestamp( "This is not a timestamp." ); - } - - /** - * Test requesting an invalid output format. - * @expectedException TimestampException - * @covers MWTimestamp::getTimestamp - */ - public function testInvalidOutput() { - $timestamp = new MWTimestamp( '1343761268' ); - $timestamp->getTimestamp( 98 ); - } - - /** - * Returns a list of valid timestamps in the format: - * array( type, timestamp_of_type, timestamp_in_MW ) - */ - public static function provideValidTimestamps() { - return array( - // Various formats - array( TS_UNIX, '1343761268', '20120731190108' ), - array( TS_MW, '20120731190108', '20120731190108' ), - array( TS_DB, '2012-07-31 19:01:08', '20120731190108' ), - array( TS_ISO_8601, '2012-07-31T19:01:08Z', '20120731190108' ), - array( TS_ISO_8601_BASIC, '20120731T190108Z', '20120731190108' ), - array( TS_EXIF, '2012:07:31 19:01:08', '20120731190108' ), - array( TS_RFC2822, 'Tue, 31 Jul 2012 19:01:08 GMT', '20120731190108' ), - array( TS_ORACLE, '31-07-2012 19:01:08.000000', '20120731190108' ), - array( TS_POSTGRES, '2012-07-31 19:01:08 GMT', '20120731190108' ), - // Some extremes and weird values - array( TS_ISO_8601, '9999-12-31T23:59:59Z', '99991231235959' ), - 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 deleted file mode 100644 index 3079d73a..00000000 --- a/tests/phpunit/includes/TitleMethodsTest.php +++ /dev/null @@ -1,300 +0,0 @@ -<?php - -/** - * @group ContentHandler - * @group Database - * - * @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() { - global $wgContLang; - - parent::setUp(); - - $this->mergeMwGlobalArrayValue( - 'wgExtraNamespaces', - array( - 12302 => 'TEST-JS', - 12303 => 'TEST-JS_TALK', - ) - ); - - $this->mergeMwGlobalArrayValue( - 'wgNamespaceContentModels', - array( - 12302 => CONTENT_MODEL_JAVASCRIPT, - ) - ); - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - } - - public function tearDown() { - global $wgContLang; - - parent::tearDown(); - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - } - - public static function provideEquals() { - return array( - array( 'Main Page', 'Main Page', true ), - array( 'Main Page', 'Not The Main Page', false ), - array( 'Main Page', 'Project:Main Page', false ), - array( 'File:Example.png', 'Image:Example.png', true ), - array( 'Special:Version', 'Special:Version', true ), - array( 'Special:Version', 'Special:Recentchanges', false ), - array( 'Special:Version', 'Main Page', false ), - ); - } - - /** - * @dataProvider provideEquals - * @covers Title::equals - */ - public function testEquals( $titleA, $titleB, $expectedBool ) { - $titleA = Title::newFromText( $titleA ); - $titleB = Title::newFromText( $titleB ); - - $this->assertEquals( $expectedBool, $titleA->equals( $titleB ) ); - $this->assertEquals( $expectedBool, $titleB->equals( $titleA ) ); - } - - public static function provideInNamespace() { - return array( - array( 'Main Page', NS_MAIN, true ), - array( 'Main Page', NS_TALK, false ), - array( 'Main Page', NS_USER, false ), - array( 'User:Foo', NS_USER, true ), - array( 'User:Foo', NS_USER_TALK, false ), - array( 'User:Foo', NS_TEMPLATE, false ), - array( 'User_talk:Foo', NS_USER_TALK, true ), - array( 'User_talk:Foo', NS_USER, false ), - ); - } - - /** - * @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 ) ); - $this->assertTrue( $mainpage->inNamespaces( array( NS_MAIN, NS_USER ) ) ); - $this->assertTrue( $mainpage->inNamespaces( array( NS_USER, NS_MAIN ) ) ); - $this->assertFalse( $mainpage->inNamespaces( array( NS_PROJECT, NS_TEMPLATE ) ) ); - } - - public static function provideHasSubjectNamespace() { - return array( - array( 'Main Page', NS_MAIN, true ), - array( 'Main Page', NS_TALK, true ), - array( 'Main Page', NS_USER, false ), - array( 'User:Foo', NS_USER, true ), - array( 'User:Foo', NS_USER_TALK, true ), - array( 'User:Foo', NS_TEMPLATE, false ), - array( 'User_talk:Foo', NS_USER_TALK, true ), - array( 'User_talk:Foo', NS_USER, true ), - ); - } - - /** - * @dataProvider provideHasSubjectNamespace - * @covers Title::hasSubjectNamespace - */ - public function testHasSubjectNamespace( $title, $ns, $expectedBool ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->hasSubjectNamespace( $ns ) ); - } - - public function dataGetContentModel() { - return array( - array( 'Help:Foo', CONTENT_MODEL_WIKITEXT ), - array( 'Help:Foo.js', CONTENT_MODEL_WIKITEXT ), - array( 'Help:Foo/bar.js', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo.js', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo/bar.js', CONTENT_MODEL_JAVASCRIPT ), - array( 'User:Foo/bar.css', CONTENT_MODEL_CSS ), - array( 'User talk:Foo/bar.css', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo/bar.js.xxx', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo/bar.xxx', CONTENT_MODEL_WIKITEXT ), - array( 'MediaWiki:Foo.js', CONTENT_MODEL_JAVASCRIPT ), - array( 'MediaWiki:Foo.css', CONTENT_MODEL_CSS ), - array( 'MediaWiki:Foo/bar.css', CONTENT_MODEL_CSS ), - array( 'MediaWiki:Foo.JS', CONTENT_MODEL_WIKITEXT ), - array( 'MediaWiki:Foo.CSS', CONTENT_MODEL_WIKITEXT ), - array( 'MediaWiki:Foo.css.xxx', CONTENT_MODEL_WIKITEXT ), - array( 'TEST-JS:Foo', CONTENT_MODEL_JAVASCRIPT ), - array( 'TEST-JS:Foo.js', CONTENT_MODEL_JAVASCRIPT ), - array( 'TEST-JS:Foo/bar.js', CONTENT_MODEL_JAVASCRIPT ), - array( 'TEST-JS_TALK:Foo.js', CONTENT_MODEL_WIKITEXT ), - ); - } - - /** - * @dataProvider dataGetContentModel - * @covers Title::getContentModel - */ - public function testGetContentModel( $title, $expectedModelId ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedModelId, $title->getContentModel() ); - } - - /** - * @dataProvider dataGetContentModel - * @covers Title::hasContentModel - */ - public function testHasContentModel( $title, $expectedModelId ) { - $title = Title::newFromText( $title ); - $this->assertTrue( $title->hasContentModel( $expectedModelId ) ); - } - - public static function provideIsCssOrJsPage() { - return array( - array( 'Help:Foo', false ), - array( 'Help:Foo.js', false ), - array( 'Help:Foo/bar.js', false ), - array( 'User:Foo', false ), - array( 'User:Foo.js', false ), - array( 'User:Foo/bar.js', false ), - array( 'User:Foo/bar.css', false ), - array( 'User talk:Foo/bar.css', false ), - array( 'User:Foo/bar.js.xxx', false ), - array( 'User:Foo/bar.xxx', false ), - array( 'MediaWiki:Foo.js', true ), - array( 'MediaWiki:Foo.css', true ), - array( 'MediaWiki:Foo.JS', false ), - array( 'MediaWiki:Foo.CSS', false ), - array( 'MediaWiki:Foo.css.xxx', false ), - array( 'TEST-JS:Foo', false ), - array( 'TEST-JS:Foo.js', false ), - ); - } - - /** - * @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 ), - array( 'Help:Foo.js', false ), - array( 'Help:Foo/bar.js', false ), - array( 'User:Foo', false ), - array( 'User:Foo.js', false ), - array( 'User:Foo/bar.js', true ), - array( 'User:Foo/bar.css', true ), - array( 'User talk:Foo/bar.css', false ), - array( 'User:Foo/bar.js.xxx', false ), - array( 'User:Foo/bar.xxx', false ), - array( 'MediaWiki:Foo.js', false ), - array( 'User:Foo/bar.JS', false ), - array( 'User:Foo/bar.CSS', false ), - array( 'TEST-JS:Foo', false ), - array( 'TEST-JS:Foo.js', false ), - ); - } - - /** - * @dataProvider provideIsCssJsSubpage - * @covers Title::isCssJsSubpage - */ - public function testIsCssJsSubpage( $title, $expectedBool ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->isCssJsSubpage() ); - } - - public static function provideIsCssSubpage() { - return array( - array( 'Help:Foo', false ), - array( 'Help:Foo.css', false ), - array( 'User:Foo', false ), - array( 'User:Foo.js', false ), - array( 'User:Foo.css', false ), - array( 'User:Foo/bar.js', false ), - array( 'User:Foo/bar.css', true ), - ); - } - - /** - * @dataProvider provideIsCssSubpage - * @covers Title::isCssSubpage - */ - public function testIsCssSubpage( $title, $expectedBool ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->isCssSubpage() ); - } - - public static function provideIsJsSubpage() { - return array( - array( 'Help:Foo', false ), - array( 'Help:Foo.css', false ), - array( 'User:Foo', false ), - array( 'User:Foo.js', false ), - array( 'User:Foo.css', false ), - array( 'User:Foo/bar.js', true ), - array( 'User:Foo/bar.css', false ), - ); - } - - /** - * @dataProvider provideIsJsSubpage - * @covers Title::isJsSubpage - */ - public function testIsJsSubpage( $title, $expectedBool ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->isJsSubpage() ); - } - - public static function provideIsWikitextPage() { - return array( - array( 'Help:Foo', true ), - array( 'Help:Foo.js', true ), - array( 'Help:Foo/bar.js', true ), - array( 'User:Foo', true ), - array( 'User:Foo.js', true ), - array( 'User:Foo/bar.js', false ), - array( 'User:Foo/bar.css', false ), - array( 'User talk:Foo/bar.css', true ), - array( 'User:Foo/bar.js.xxx', true ), - array( 'User:Foo/bar.xxx', true ), - array( 'MediaWiki:Foo.js', false ), - array( 'MediaWiki:Foo.css', false ), - array( 'MediaWiki:Foo/bar.css', false ), - array( 'User:Foo/bar.JS', true ), - array( 'User:Foo/bar.CSS', true ), - array( 'TEST-JS:Foo', false ), - array( 'TEST-JS:Foo.js', false ), - array( 'TEST-JS_TALK:Foo.js', true ), - ); - } - - /** - * @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 deleted file mode 100644 index f15c1772..00000000 --- a/tests/phpunit/includes/TitlePermissionTest.php +++ /dev/null @@ -1,742 +0,0 @@ -<?php - -/** - * @group Database - * @todo covers tags - */ -class TitlePermissionTest extends MediaWikiLangTestCase { - - /** - * @var string - */ - protected $userName, $altUserName; - - /** - * @var Title - */ - protected $title; - - /** - * @var User - */ - protected $user, $anonUser, $userUser, $altUser; - - protected function setUp() { - parent::setUp(); - - $langObj = Language::factory( 'en' ); - $localZone = 'UTC'; - $localOffset = date( 'Z' ) / 60; - - $this->setMwGlobals( array( - 'wgMemc' => new EmptyBagOStuff, - 'wgContLang' => $langObj, - 'wgLanguageCode' => 'en', - 'wgLang' => $langObj, - 'wgLocaltimezone' => $localZone, - 'wgLocalTZoffset' => $localOffset, - 'wgNamespaceProtection' => array( - NS_MEDIAWIKI => 'editinterface', - ), - ) ); - - $this->userName = 'Useruser'; - $this->altUserName = 'Altuseruser'; - date_default_timezone_set( $localZone ); - - $this->title = Title::makeTitle( NS_MAIN, "Main Page" ); - if ( !isset( $this->userUser ) || !( $this->userUser instanceOf User ) ) { - $this->userUser = User::newFromName( $this->userName ); - - if ( !$this->userUser->getID() ) { - $this->userUser = User::createNew( $this->userName, array( - "email" => "test@example.com", - "real_name" => "Test User" ) ); - $this->userUser->load(); - } - - $this->altUser = User::newFromName( $this->altUserName ); - if ( !$this->altUser->getID() ) { - $this->altUser = User::createNew( $this->altUserName, array( - "email" => "alttest@example.com", - "real_name" => "Test User Alt" ) ); - $this->altUser->load(); - } - - $this->anonUser = User::newFromId( 0 ); - - $this->user = $this->userUser; - } - } - - protected function setUserPerm( $perm ) { - // Setting member variables is evil!!! - - if ( is_array( $perm ) ) { - $this->user->mRights = $perm; - } else { - $this->user->mRights = array( $perm ); - } - } - - protected function setTitle( $ns, $title = "Main_Page" ) { - $this->title = Title::makeTitle( $ns, $title ); - } - - protected function setUser( $userName = null ) { - if ( $userName === 'anon' ) { - $this->user = $this->anonUser; - } elseif ( $userName === null || $userName === $this->userName ) { - $this->user = $this->userUser; - } else { - $this->user = $this->altUser; - } - } - - /** - * @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 ); - - $this->setUser( 'anon' ); - $this->setTitle( NS_TALK ); - $this->setUserPerm( "createtalk" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setTitle( NS_TALK ); - $this->setUserPerm( "createpage" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( "nocreatetext" ) ), $res ); - - $this->setTitle( NS_TALK ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreatetext' ) ), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createpage" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createtalk" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreatetext' ) ), $res ); - - $this->setUser( $this->userName ); - $this->setTitle( NS_TALK ); - $this->setUserPerm( "createtalk" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setTitle( NS_TALK ); - $this->setUserPerm( "createpage" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); - - $this->setTitle( NS_TALK ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createpage" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createtalk" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); - - $this->setUser( 'anon' ); - $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'cant-move-user-page' ), array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'cant-move-user-page' ), array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setUser( $this->userName ); - $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenotallowedfile' ), array( 'movenotallowed' ) ), $res ); - - $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "movefile" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenotallowed' ) ), $res ); - - $this->setUser( 'anon' ); - $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenotallowedfile' ), array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "movefile" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setUser( $this->userName ); - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ) ) ); - - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ), array( 'movenotallowed' ) ) ); - - $this->setUser( 'anon' ); - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ) ) ); - - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ), array( 'movenotallowed' ) ), - array( array( 'movenotallowedfile' ), array( 'movenologintext' ) ) ); - - if ( $this->isWikitextNS( NS_MAIN ) ) { - //NOTE: some content models don't allow moving - // @todo find a Wikitext namespace for testing - - $this->setTitle( NS_MAIN ); - $this->setUser( 'anon' ); - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', array() ); - - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ), - array( array( 'movenologintext' ) ) ); - - $this->setUser( $this->userName ); - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ) ); - - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', array() ); - - $this->setUser( 'anon' ); - $this->setUserPerm( 'move' ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setUserPerm( '' ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array( array( 'movenotallowed' ) ), $res ); - } - - $this->setTitle( NS_USER ); - $this->setUser( $this->userName ); - $this->setUserPerm( array( "move", "move-rootuserpages" ) ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setUserPerm( "move" ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array( array( 'cant-move-to-user-page' ) ), $res ); - - $this->setUser( 'anon' ); - $this->setUserPerm( array( "move", "move-rootuserpages" ) ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setTitle( NS_USER, "User/subpage" ); - $this->setUserPerm( array( "move", "move-rootuserpages" ) ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setUserPerm( "move" ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setUser( 'anon' ); - $check = array( 'edit' => array( array( array( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ) ), - array( array( 'badaccess-group0' ) ), - array(), true ), - 'protect' => array( array( array( 'badaccess-groups', "[[$prefix:Administrators|Administrators]]", 1 ), array( 'protect-cantedit' ) ), - array( array( 'badaccess-group0' ), array( 'protect-cantedit' ) ), - array( array( 'protect-cantedit' ) ), false ), - '' => array( array(), array(), array(), true ) ); - - foreach ( array( "edit", "protect", "" ) as $action ) { - $this->setUserPerm( null ); - $this->assertEquals( $check[$action][0], - $this->title->getUserPermissionsErrors( $action, $this->user, true ) ); - - global $wgGroupPermissions; - $old = $wgGroupPermissions; - $wgGroupPermissions = array(); - - $this->assertEquals( $check[$action][1], - $this->title->getUserPermissionsErrors( $action, $this->user, true ) ); - $wgGroupPermissions = $old; - - $this->setUserPerm( $action ); - $this->assertEquals( $check[$action][2], - $this->title->getUserPermissionsErrors( $action, $this->user, true ) ); - - $this->setUserPerm( $action ); - $this->assertEquals( $check[$action][3], - $this->title->userCan( $action, $this->user, true ) ); - $this->assertEquals( $check[$action][3], - $this->title->quickUserCan( $action, $this->user ) ); - # count( User::getGroupsWithPermissions( $action ) ) < 1 - } - } - - protected function runGroupPermissions( $action, $result, $result2 = null ) { - global $wgGroupPermissions; - - if ( $result2 === null ) { - $result2 = $result; - } - - $wgGroupPermissions['autoconfirmed']['move'] = false; - $wgGroupPermissions['user']['move'] = false; - $res = $this->title->getUserPermissionsErrors( $action, $this->user ); - $this->assertEquals( $result, $res ); - - $wgGroupPermissions['autoconfirmed']['move'] = true; - $wgGroupPermissions['user']['move'] = false; - $res = $this->title->getUserPermissionsErrors( $action, $this->user ); - $this->assertEquals( $result2, $res ); - - $wgGroupPermissions['autoconfirmed']['move'] = true; - $wgGroupPermissions['user']['move'] = true; - $res = $this->title->getUserPermissionsErrors( $action, $this->user ); - $this->assertEquals( $result2, $res ); - - $wgGroupPermissions['autoconfirmed']['move'] = false; - $wgGroupPermissions['user']['move'] = true; - $res = $this->title->getUserPermissionsErrors( $action, $this->user ); - $this->assertEquals( $result2, $res ); - } - - /** - * @todo This test method should be split up into separate test methods and - * data providers - */ - public function testSpecialsAndNSPermissions() { - global $wgNamespaceProtection; - $this->setUser( $this->userName ); - - $this->setTitle( NS_SPECIAL ); - - $this->assertEquals( array( array( 'badaccess-group0' ), array( 'ns-specialprotected' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( 'bogus' ); - $this->assertEquals( array(), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( '' ); - $this->assertEquals( array( array( 'badaccess-group0' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $wgNamespaceProtection[NS_USER] = array( 'bogus' ); - - $this->setTitle( NS_USER ); - $this->setUserPerm( '' ); - $this->assertEquals( array( array( 'badaccess-group0' ), array( 'namespaceprotected', 'User' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $this->setTitle( NS_MEDIAWIKI ); - $this->setUserPerm( 'bogus' ); - $this->assertEquals( array( array( 'protectedinterface' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $this->setTitle( NS_MEDIAWIKI ); - $this->setUserPerm( 'bogus' ); - $this->assertEquals( array( array( 'protectedinterface' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $wgNamespaceProtection = null; - - $this->setUserPerm( 'bogus' ); - $this->assertEquals( array(), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - $this->assertEquals( true, - $this->title->userCan( 'bogus', $this->user ) ); - - $this->setUserPerm( '' ); - $this->assertEquals( array( array( 'badaccess-group0' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - $this->assertEquals( false, - $this->title->userCan( 'bogus', $this->user ) ); - } - - /** - * @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( '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' ) ) - ); - - $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' ) ) - ); - } - - protected function runCSSandJSPermissions( $result0, $result1, $result2, $result3, $result4 ) { - $this->setUserPerm( '' ); - $this->assertEquals( $result0, - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - - $this->setUserPerm( 'editmyusercss' ); - $this->assertEquals( $result1, - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - - $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', - $this->user ) ); - - $this->setUserPerm( array( 'edituserjs', 'editusercss' ) ); - $this->assertEquals( array( array( 'badaccess-group0' ) ), - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - } - - /** - * @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 ); - - $this->setTitle( NS_MAIN ); - $this->title->mRestrictionsLoaded = true; - $this->setUserPerm( "edit" ); - $this->title->mRestrictions = array( "bogus" => array( 'bogus', "sysop", "protect", "" ) ); - - $this->assertEquals( array(), - $this->title->getUserPermissionsErrors( 'edit', - $this->user ) ); - - $this->assertEquals( true, - $this->title->quickUserCan( 'edit', $this->user ) ); - $this->title->mRestrictions = array( "edit" => array( 'bogus', "sysop", "protect", "" ), - "bogus" => array( 'bogus', "sysop", "protect", "" ) ); - - $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( "" ); - $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( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ), - array( 'protectedpagetext', 'bogus' ), - 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' ) ), - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - $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, - $this->title->quickUserCan( 'edit', $this->user ) ); - $this->assertEquals( array( array( 'badaccess-group0' ), - array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - $this->title->getUserPermissionsErrors( 'edit', - $this->user ) ); - } - - public function testCascadingSourcesRestrictions() { - $this->setTitle( NS_MAIN, "test page" ); - $this->setUserPerm( array( "edit", "bogus" ) ); - - $this->title->mCascadeSources = array( Title::makeTitle( NS_MAIN, "Bogus" ), Title::makeTitle( NS_MAIN, "UnBogus" ) ); - $this->title->mCascadingRestrictions = array( "bogus" => array( 'bogus', "sysop", "protect", "" ) ); - - $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 ) ); - - $this->assertEquals( true, - $this->title->userCan( 'edit', $this->user ) ); - $this->assertEquals( array(), - $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); - } - - /** - * @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'] = ''; - $this->title->mTitleProtection['pt_user'] = $this->user->getID(); - $this->title->mTitleProtection['pt_expiry'] = wfGetDB( DB_SLAVE )->getInfinity(); - $this->title->mTitleProtection['pt_reason'] = 'test'; - $this->title->mCascadeRestriction = false; - - $this->assertEquals( array( array( 'titleprotected', 'Useruser', 'test' ) ), - $this->title->getUserPermissionsErrors( 'create', $this->user ) ); - $this->assertEquals( false, - $this->title->userCan( 'create', $this->user ) ); - - $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 ) ); - $this->assertEquals( false, - $this->title->userCan( 'create', $this->user ) ); - - $this->setTitle( NS_MEDIA, "test page" ); - $this->setUserPerm( array( "move" ) ); - $this->assertEquals( false, - $this->title->userCan( 'move', $this->user ) ); - $this->assertEquals( array( array( 'immobile-source-namespace', 'Media' ) ), - $this->title->getUserPermissionsErrors( 'move', $this->user ) ); - - $this->setTitle( NS_HELP, "test page" ); - $this->assertEquals( array(), - $this->title->getUserPermissionsErrors( 'move', $this->user ) ); - $this->assertEquals( true, - $this->title->userCan( 'move', $this->user ) ); - - $this->title->mInterwiki = "no"; - $this->assertEquals( array( array( 'immobile-source-page' ) ), - $this->title->getUserPermissionsErrors( 'move', $this->user ) ); - $this->assertEquals( false, - $this->title->userCan( 'move', $this->user ) ); - - $this->setTitle( NS_MEDIA, "test page" ); - $this->assertEquals( false, - $this->title->userCan( 'move-target', $this->user ) ); - $this->assertEquals( array( array( 'immobile-target-namespace', 'Media' ) ), - $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); - - $this->setTitle( NS_HELP, "test page" ); - $this->assertEquals( array(), - $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); - $this->assertEquals( true, - $this->title->userCan( 'move-target', $this->user ) ); - - $this->title->mInterwiki = "no"; - $this->assertEquals( array( array( 'immobile-target-page' ) ), - $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); - $this->assertEquals( false, - $this->title->userCan( 'move-target', $this->user ) ); - } - - public function testUserBlock() { - global $wgEmailConfirmToEdit, $wgEmailAuthentication; - $wgEmailConfirmToEdit = true; - $wgEmailAuthentication = true; - - $this->setUserPerm( array( "createpage", "move" ) ); - $this->setTitle( NS_HELP, "test page" ); - - # $short - $this->assertEquals( array( array( 'confirmedittext' ) ), - $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); - $wgEmailConfirmToEdit = false; - $this->assertEquals( true, $this->title->userCan( 'move-target', $this->user ) ); - - # $wgEmailConfirmToEdit && !$user->isEmailConfirmed() && $action != 'createaccount' - $this->assertEquals( array(), - $this->title->getUserPermissionsErrors( 'move-target', - $this->user ) ); - - global $wgLang; - $prev = time(); - $now = time() + 120; - $this->user->mBlockedby = $this->user->getId(); - $this->user->mBlock = new Block( '127.0.8.1', 0, $this->user->getId(), - 'no reason given', $prev + 3600, 1, 0 ); - $this->user->mBlock->mTimestamp = 0; - $this->assertEquals( array( array( 'autoblockedtext', - '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1', - 'Useruser', null, 'infinite', '127.0.8.1', - $wgLang->timeanddate( wfTimestamp( TS_MW, $prev ), true ) ) ), - $this->title->getUserPermissionsErrors( 'move-target', - $this->user ) ); - - $this->assertEquals( false, $this->title->userCan( 'move-target', $this->user ) ); - // quickUserCan should ignore user blocks - $this->assertEquals( true, $this->title->quickUserCan( 'move-target', $this->user ) ); - - global $wgLocalTZoffset; - $wgLocalTZoffset = -60; - $this->user->mBlockedby = $this->user->getName(); - $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 deleted file mode 100644 index 6bfe5453..00000000 --- a/tests/phpunit/includes/TitleTest.php +++ /dev/null @@ -1,485 +0,0 @@ -<?php - -/** - * @group Database - * ^--- needed for language cache stuff - */ -class TitleTest extends MediaWikiTestCase { - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgLanguageCode' => 'en', - 'wgContLang' => Language::factory( 'en' ), - // User language - 'wgLang' => Language::factory( 'en' ), - 'wgAllowUserJs' => false, - 'wgDefaultLanguageVariant' => false, - ) ); - } - - /** - * @covers Title::legalChars - */ - public function testLegalChars() { - $titlechars = Title::legalChars(); - - foreach ( range( 1, 255 ) as $num ) { - $chr = chr( $num ); - if ( strpos( "#[]{}<>|", $chr ) !== false || preg_match( "/[\\x00-\\x1f\\x7f]/", $chr ) ) { - $this->assertFalse( (bool)preg_match( "/[$titlechars]/", $chr ), "chr($num) = $chr is not a valid titlechar" ); - } else { - $this->assertTrue( (bool)preg_match( "/[$titlechars]/", $chr ), "chr($num) = $chr is a valid titlechar" ); - } - } - } - - /** - * 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 - */ - public function testBug31100FixSpecialName( $text, $expectedParam ) { - $title = Title::newFromText( $text ); - $fixed = $title->fixSpecialName(); - $stuff = explode( '/', $fixed->getDBkey(), 2 ); - if ( count( $stuff ) == 2 ) { - $par = $stuff[1]; - } else { - $par = null; - } - $this->assertEquals( $expectedParam, $par, "Bug 31100 regression check: Title->fixSpecialName() should preserve parameter" ); - } - - public static function provideBug31100() { - return array( - array( 'Special:Version', null ), - array( 'Special:Version/', '' ), - array( 'Special:Version/param', 'param' ), - ); - } - - /** - * Auth-less test of Title::isValidMoveOperation - * - * @group Database - * @param string $source - * @param string $target - * @param array|string|bool $expected Required error - * @dataProvider provideTestIsValidMoveOperation - * @covers Title::isValidMoveOperation - */ - public function testIsValidMoveOperation( $source, $target, $expected ) { - $title = Title::newFromText( $source ); - $nt = Title::newFromText( $target ); - $errors = $title->isValidMoveOperation( $nt, false ); - if ( $expected === true ) { - $this->assertTrue( $errors ); - } else { - $errors = $this->flattenErrorsArray( $errors ); - foreach ( (array)$expected as $error ) { - $this->assertContains( $error, $errors ); - } - } - } - - /** - * Provides test parameter values for testIsValidMoveOperation() - */ - public function dataTestIsValidMoveOperation() { - return array( - array( 'Test', 'Test', 'selfmove' ), - array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' ) - ); - } - - /** - * Auth-less test of Title::userCan - * - * @param array $whitelistRegexp - * @param string $source - * @param string $action - * @param array|string|bool $expected Required error - * - * @covers Title::checkReadPermissions - * @dataProvider dataWgWhitelistReadRegexp - */ - 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 - // type requisite. - if ( is_string( $whitelistRegexp ) ) { - $whitelistRegexp = array( $whitelistRegexp ); - } - - $title = Title::newFromDBkey( $source ); - - global $wgGroupPermissions; - $oldPermissions = $wgGroupPermissions; - // Disallow all so we can ensure our regex works - $wgGroupPermissions = array(); - $wgGroupPermissions['*']['read'] = false; - - global $wgWhitelistRead; - $oldWhitelist = $wgWhitelistRead; - // Undo any LocalSettings explicite whitelists so they won't cause a - // failing test to succeed. Set it to some random non sense just - // to make sure we properly test Title::checkReadPermissions() - $wgWhitelistRead = array( 'some random non sense title' ); - - global $wgWhitelistReadRegexp; - $oldWhitelistRegexp = $wgWhitelistReadRegexp; - $wgWhitelistReadRegexp = $whitelistRegexp; - - // Just use $wgUser which in test is a user object for '127.0.0.1' - global $wgUser; - // Invalidate user rights cache to take in account $wgGroupPermissions - // change above. - $wgUser->clearInstanceCache(); - $errors = $title->userCan( $action, $wgUser ); - - // Restore globals - $wgGroupPermissions = $oldPermissions; - $wgWhitelistRead = $oldWhitelist; - $wgWhitelistReadRegexp = $oldWhitelistRegexp; - - if ( is_bool( $expected ) ) { - # Forge the assertion message depending on the assertion expectation - $allowableness = $expected - ? " should be allowed" - : " should NOT be allowed"; - $this->assertEquals( $expected, $errors, "User action '$action' on [[$source]] $allowableness." ); - } else { - $errors = $this->flattenErrorsArray( $errors ); - foreach ( (array)$expected as $error ) { - $this->assertContains( $error, $errors ); - } - } - } - - /** - * Provides test parameter values for testWgWhitelistReadRegexp() - */ - public function dataWgWhitelistReadRegexp() { - $ALLOWED = true; - $DISALLOWED = false; - - return array( - // Everything, if this doesn't work, we're really in trouble - array( '/.*/', 'Main_Page', 'read', $ALLOWED ), - array( '/.*/', 'Main_Page', 'edit', $DISALLOWED ), - - // We validate against the title name, not the db key - array( '/^Main_Page$/', 'Main_Page', 'read', $DISALLOWED ), - // Main page - array( '/^Main/', 'Main_Page', 'read', $ALLOWED ), - array( '/^Main.*/', 'Main_Page', 'read', $ALLOWED ), - // With spaces - array( '/Mic\sCheck/', 'Mic Check', 'read', $ALLOWED ), - // Unicode multibyte - // ...without unicode modifier - array( '/Unicode Test . Yes/', 'Unicode Test Ñ Yes', 'read', $DISALLOWED ), - // ...with unicode modifier - array( '/Unicode Test . Yes/u', 'Unicode Test Ñ Yes', 'read', $ALLOWED ), - // Case insensitive - array( '/MiC ChEcK/', 'mic check', 'read', $DISALLOWED ), - array( '/MiC ChEcK/i', 'mic check', 'read', $ALLOWED ), - - // From DefaultSettings.php: - array( "@^UsEr.*@i", 'User is banned', 'read', $ALLOWED ), - array( "@^UsEr.*@i", 'User:John Doe', 'read', $ALLOWED ), - - // With namespaces: - array( '/^Special:NewPages$/', 'Special:NewPages', 'read', $ALLOWED ), - array( null, 'Special:Newpages', 'read', $DISALLOWED ), - - ); - } - - public function flattenErrorsArray( $errors ) { - $result = array(); - foreach ( $errors as $error ) { - $result[] = $error[0]; - } - - return $result; - } - - public static function provideTestIsValidMoveOperation() { - return array( - array( 'Test', 'Test', 'selfmove' ), - array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' ) - ); - } - - /** - * @dataProvider provideGetPageViewLanguage - * @covers Title::getPageViewLanguage - */ - public function testGetPageViewLanguage( $expected, $titleText, $contLang, $lang, $variant, $msg = '' ) { - global $wgLanguageCode, $wgContLang, $wgLang, $wgDefaultLanguageVariant, $wgAllowUserJs; - - // Setup environnement for this test - $wgLanguageCode = $contLang; - $wgContLang = Language::factory( $contLang ); - $wgLang = Language::factory( $lang ); - $wgDefaultLanguageVariant = $variant; - $wgAllowUserJs = true; - - $title = Title::newFromText( $titleText ); - $this->assertInstanceOf( 'Title', $title, - "Test must be passed a valid title text, you gave '$titleText'" - ); - $this->assertEquals( $expected, - $title->getPageViewLanguage()->getCode(), - $msg - ); - } - - public static function provideGetPageViewLanguage() { - # Format: - # - expected - # - Title name - # - wgContLang (expected in most case) - # - wgLang (on some specific pages) - # - wgDefaultLanguageVariant - # - Optional message - return array( - array( 'fr', 'Help:I_need_somebody', 'fr', 'fr', false ), - array( 'es', 'Help:I_need_somebody', 'es', 'zh-tw', false ), - array( 'zh', 'Help:I_need_somebody', 'zh', 'zh-tw', false ), - - array( 'es', 'Help:I_need_somebody', 'es', 'zh-tw', 'zh-cn' ), - array( 'es', 'MediaWiki:About', 'es', 'zh-tw', 'zh-cn' ), - array( 'es', 'MediaWiki:About/', 'es', 'zh-tw', 'zh-cn' ), - array( 'de', 'MediaWiki:About/de', 'es', 'zh-tw', 'zh-cn' ), - array( 'en', 'MediaWiki:Common.js', 'es', 'zh-tw', 'zh-cn' ), - array( 'en', 'MediaWiki:Common.css', 'es', 'zh-tw', 'zh-cn' ), - array( 'en', 'User:JohnDoe/Common.js', 'es', 'zh-tw', 'zh-cn' ), - array( 'en', 'User:JohnDoe/Monobook.css', 'es', 'zh-tw', 'zh-cn' ), - - array( 'zh-cn', 'Help:I_need_somebody', 'zh', 'zh-tw', 'zh-cn' ), - array( 'zh', 'MediaWiki:About', 'zh', 'zh-tw', 'zh-cn' ), - array( 'zh', 'MediaWiki:About/', 'zh', 'zh-tw', 'zh-cn' ), - array( 'de', 'MediaWiki:About/de', 'zh', 'zh-tw', 'zh-cn' ), - array( 'zh-cn', 'MediaWiki:About/zh-cn', 'zh', 'zh-tw', 'zh-cn' ), - array( 'zh-tw', 'MediaWiki:About/zh-tw', 'zh', 'zh-tw', 'zh-cn' ), - array( 'en', 'MediaWiki:Common.js', 'zh', 'zh-tw', 'zh-cn' ), - array( 'en', 'MediaWiki:Common.css', 'zh', 'zh-tw', 'zh-cn' ), - array( 'en', 'User:JohnDoe/Common.js', 'zh', 'zh-tw', 'zh-cn' ), - array( 'en', 'User:JohnDoe/Monobook.css', 'zh', 'zh-tw', 'zh-cn' ), - - array( 'zh-tw', 'Special:NewPages', 'es', 'zh-tw', 'zh-cn' ), - array( 'zh-tw', 'Special:NewPages', 'zh', 'zh-tw', 'zh-cn' ), - - ); - } - - /** - * @dataProvider provideBaseTitleCases - * @covers Title::getBaseText - */ - public function testGetBaseText( $title, $expected, $msg = '' ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expected, - $title->getBaseText(), - $msg - ); - } - - public static function provideBaseTitleCases() { - return array( - # Title, expected base, optional message - array( 'User:John_Doe/subOne/subTwo', 'John Doe/subOne' ), - array( 'User:Foo/Bar/Baz', 'Foo/Bar' ), - ); - } - - /** - * @dataProvider provideRootTitleCases - * @covers Title::getRootText - */ - public function testGetRootText( $title, $expected, $msg = '' ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expected, - $title->getRootText(), - $msg - ); - } - - public static function provideRootTitleCases() { - return array( - # Title, expected base, optional message - array( 'User:John_Doe/subOne/subTwo', 'John Doe' ), - array( 'User:Foo/Bar/Baz', 'Foo' ), - ); - } - - /** - * @todo Handle $wgNamespacesWithSubpages cases - * @dataProvider provideSubpageTitleCases - * @covers Title::getSubpageText - */ - public function testGetSubpageText( $title, $expected, $msg = '' ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expected, - $title->getSubpageText(), - $msg - ); - } - - public static function provideSubpageTitleCases() { - return array( - # Title, expected base, optional message - array( 'User:John_Doe/subOne/subTwo', 'subTwo' ), - array( 'User:John_Doe/subOne', 'subOne' ), - ); - } -} diff --git a/tests/phpunit/includes/UIDGeneratorTest.php b/tests/phpunit/includes/UIDGeneratorTest.php deleted file mode 100644 index 8f78ae51..00000000 --- a/tests/phpunit/includes/UIDGeneratorTest.php +++ /dev/null @@ -1,98 +0,0 @@ -<?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 ) ); - $this->assertEquals( true, ctype_digit( $id ), "UID made of digit characters" ); - $this->assertLessThanOrEqual( $digitlen, strlen( $id ), - "UID has the right number of digits" ); - $this->assertLessThanOrEqual( $bits, strlen( wfBaseConvert( $id, 10, 2 ) ), - "UID has the right number of bits" ); - - $ids = array(); - for ( $i = 0; $i < 300; $i++ ) { - $ids[] = call_user_func( array( 'UIDGenerator', $method ) ); - } - - $lastId = array_shift( $ids ); - if ( $hostbits ) { - $lastHost = substr( wfBaseConvert( $lastId, 10, 2, $bits ), -$hostbits ); - } - - $this->assertArrayEquals( array_unique( $ids ), $ids, "All generated IDs are unique." ); - - foreach ( $ids as $id ) { - $id_bin = wfBaseConvert( $id, 10, 2 ); - $lastId_bin = wfBaseConvert( $lastId, 10, 2 ); - - $this->assertGreaterThanOrEqual( - substr( $id_bin, 0, $tbits ), - substr( $lastId_bin, 0, $tbits ), - "New ID timestamp ($id_bin) >= prior one ($lastId_bin)." ); - - if ( $hostbits ) { - $this->assertEquals( - substr( $id_bin, 0, -$hostbits ), - substr( $lastId_bin, 0, -$hostbits ), - "Host ID of ($id_bin) is same as prior one ($lastId_bin)." ); - } - - $lastId = $id; - } - } - - /** - * 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( - array( 'newTimestampedUID128', 39, 128, 46, 48 ), - array( 'newTimestampedUID128', 39, 128, 46, 48 ), - array( 'newTimestampedUID88', 27, 88, 46, 32 ), - ); - } - - /** - * @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 deleted file mode 100644 index 278edfaa..00000000 --- a/tests/phpunit/includes/UserMailerTest.php +++ /dev/null @@ -1,14 +0,0 @@ -<?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 deleted file mode 100644 index ff33e825..00000000 --- a/tests/phpunit/includes/UserTest.php +++ /dev/null @@ -1,237 +0,0 @@ -<?php - -define( 'NS_UNITTEST', 5600 ); -define( 'NS_UNITTEST_TALK', 5601 ); - -/** - * @group Database - */ -class UserTest extends MediaWikiTestCase { - /** - * @var User - */ - protected $user; - - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgGroupPermissions' => array(), - 'wgRevokePermissions' => array(), - ) ); - - $this->setUpPermissionGlobals(); - - $this->user = new User; - $this->user->addGroup( 'unittesters' ); - } - - private function setUpPermissionGlobals() { - global $wgGroupPermissions, $wgRevokePermissions; - - # Data for regular $wgGroupPermissions test - $wgGroupPermissions['unittesters'] = array( - 'test' => true, - 'runtest' => true, - 'writetest' => false, - 'nukeworld' => false, - ); - $wgGroupPermissions['testwriters'] = array( - 'test' => true, - 'writetest' => true, - 'modifytest' => true, - ); - - # Data for regular $wgRevokePermissions test - $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 ); - $this->assertNotContains( 'writetest', $rights ); - $this->assertNotContains( 'modifytest', $rights ); - $this->assertNotContains( 'nukeworld', $rights ); - - $rights = User::getGroupPermissions( array( 'unittesters', 'testwriters' ) ); - $this->assertContains( 'runtest', $rights ); - $this->assertContains( 'writetest', $rights ); - $this->assertContains( 'modifytest', $rights ); - $this->assertNotContains( 'nukeworld', $rights ); - } - - /** - * @covers User::getGroupPermissions - */ - public function testRevokePermissions() { - $rights = User::getGroupPermissions( array( 'unittesters', 'formertesters' ) ); - $this->assertNotContains( 'runtest', $rights ); - $this->assertNotContains( 'writetest', $rights ); - $this->assertNotContains( 'modifytest', $rights ); - $this->assertNotContains( 'nukeworld', $rights ); - } - - /** - * @covers User::getRights - */ - public function testUserPermissions() { - $rights = $this->user->getRights(); - $this->assertContains( 'runtest', $rights ); - $this->assertNotContains( 'writetest', $rights ); - $this->assertNotContains( 'modifytest', $rights ); - $this->assertNotContains( 'nukeworld', $rights ); - } - - /** - * @dataProvider provideGetGroupsWithPermission - * @covers User::getGroupsWithPermission - */ - public function testGetGroupsWithPermission( $expected, $right ) { - $result = User::getGroupsWithPermission( $right ); - sort( $result ); - sort( $expected ); - - $this->assertEquals( $expected, $result, "Groups with permission $right" ); - } - - public static function provideGetGroupsWithPermission() { - return array( - array( - array( 'unittesters', 'testwriters' ), - 'test' - ), - array( - array( 'unittesters' ), - 'runtest' - ), - array( - array( 'testwriters' ), - 'writetest' - ), - array( - array( 'testwriters' ), - 'modifytest' - ), - ); - } - - /** - * @dataProvider provideUserNames - * @covers User::isValidUserName - */ - public function testIsValidUserName( $username, $result, $message ) { - $this->assertEquals( $this->user->isValidUserName( $username ), $result, $message ); - } - - public static function provideUserNames() { - return array( - array( '', false, 'Empty string' ), - array( ' ', false, 'Blank space' ), - array( 'abcd', false, 'Starts with small letter' ), - array( 'Ab/cd', false, 'Contains slash' ), - array( 'Ab cd', true, 'Whitespace' ), - array( '192.168.1.1', false, 'IP' ), - array( 'User:Abcd', false, 'Reserved Namespace' ), - array( '12abcd232', true, 'Starts with Numbers' ), - array( '?abcd', true, 'Start with ? mark' ), - array( '#abcd', false, 'Start with #' ), - array( 'Abcdകഖഗഘ', true, ' Mixed scripts' ), - array( 'ജോസ്തോമസ്', false, 'ZWNJ- Format control character' ), - array( 'Ab cd', false, ' Ideographic space' ), - ); - } - - /** - * Test, if for all rights a right- message exist, - * which is used on Special:ListGroupRights as help text - * Extensions and core - */ - public function testAllRightsWithMessage() { - //Getting all user rights, for core: User::$mCoreRights, for extensions: $wgAvailableRights - $allRights = User::getAllRights(); - $allMessageKeys = Language::getMessageKeysFor( 'en' ); - - $rightsWithMessage = array(); - foreach ( $allMessageKeys as $message ) { - // === 0: must be at beginning of string (position 0) - if ( strpos( $message, 'right-' ) === 0 ) { - $rightsWithMessage[] = substr( $message, strlen( 'right-' ) ); - } - } - - sort( $allRights ); - sort( $rightsWithMessage ); - - $this->assertEquals( - $allRights, - $rightsWithMessage, - 'Each user rights (core/extensions) has a corresponding right- message.' - ); - } - - /** - * Test User::editCount - * @group medium - * @covers User::getEditCount - */ - public function testEditCount() { - $user = User::newFromName( 'UnitTestUser' ); - $user->loadDefaults(); - $user->addToDatabase(); - - // let the user have a few (3) edits - $page = WikiPage::factory( Title::newFromText( 'Help:UserTest_EditCount' ) ); - for ( $i = 0; $i < 3; $i++ ) { - $page->doEdit( (string)$i, 'test', 0, false, $user ); - } - - $user->clearInstanceCache(); - $this->assertEquals( 3, $user->getEditCount(), 'After three edits, the user edit count should be 3' ); - - // increase the edit count and clear the cache - $user->incEditCount(); - - $user->clearInstanceCache(); - $this->assertEquals( 4, $user->getEditCount(), 'After increasing the edit count manually, the user edit count should be 4' ); - } - - /** - * Test changing user options. - * @covers User::setOption - * @covers User::getOption - */ - public function testOptions() { - $user = User::newFromName( 'UnitTestUser' ); - $user->addToDatabase(); - - $user->setOption( 'someoption', 'test' ); - $user->setOption( 'cols', 200 ); - $user->saveSettings(); - - $user = User::newFromName( 'UnitTestUser' ); - $this->assertEquals( 'test', $user->getOption( 'someoption' ) ); - $this->assertEquals( 200, $user->getOption( 'cols' ) ); - } - - /** - * Bug 37963 - * Make sure defaults are loaded when setOption is called. - * @covers User::loadOptions - */ - public function testAnonOptions() { - global $wgDefaultUserOptions; - $this->user->setOption( 'someoption', 'test' ); - $this->assertEquals( $wgDefaultUserOptions['cols'], $this->user->getOption( 'cols' ) ); - $this->assertEquals( 'test', $this->user->getOption( 'someoption' ) ); - } -} diff --git a/tests/phpunit/includes/WebRequestTest.php b/tests/phpunit/includes/WebRequestTest.php deleted file mode 100644 index f8ed14b6..00000000 --- a/tests/phpunit/includes/WebRequestTest.php +++ /dev/null @@ -1,310 +0,0 @@ -<?php - -/** - * @group WebRequest - */ -class WebRequestTest extends MediaWikiTestCase { - protected $oldServer; - - protected function setUp() { - parent::setUp(); - - $this->oldServer = $_SERVER; - } - - protected function tearDown() { - $_SERVER = $this->oldServer; - - parent::tearDown(); - } - - /** - * @dataProvider provideDetectServer - * @covers WebRequest::detectServer - */ - public function testDetectServer( $expected, $input, $description ) { - $_SERVER = $input; - $result = WebRequest::detectServer(); - $this->assertEquals( $expected, $result, $description ); - } - - public static function provideDetectServer() { - return array( - array( - 'http://x', - array( - 'HTTP_HOST' => 'x' - ), - 'Host header' - ), - array( - 'https://x', - array( - 'HTTP_HOST' => 'x', - 'HTTPS' => 'on', - ), - 'Host header with secure' - ), - array( - 'http://x', - array( - 'HTTP_HOST' => 'x', - 'SERVER_PORT' => 80, - ), - 'Default SERVER_PORT', - ), - array( - 'http://x', - array( - 'HTTP_HOST' => 'x', - 'HTTPS' => 'off', - ), - 'Secure off' - ), - array( - 'http://y', - array( - 'SERVER_NAME' => 'y', - ), - 'Server name' - ), - array( - 'http://x', - array( - 'HTTP_HOST' => 'x', - 'SERVER_NAME' => 'y', - ), - 'Host server name precedence' - ), - array( - 'http://[::1]:81', - array( - 'HTTP_HOST' => '[::1]', - 'SERVER_NAME' => '::1', - 'SERVER_PORT' => '81', - ), - 'Apache bug 26005' - ), - array( - 'http://localhost', - array( - 'SERVER_NAME' => '[2001' - ), - 'Kind of like lighttpd per commit message in MW r83847', - ), - array( - 'http://[2a01:e35:2eb4:1::2]:777', - array( - 'SERVER_NAME' => '[2a01:e35:2eb4:1::2]:777' - ), - 'Possible lighttpd environment per bug 14977 comment 13', - ), - ); - } - - /** - * @dataProvider provideGetIP - * @covers WebRequest::getIP - */ - public function testGetIP( $expected, $input, $squid, $xffList, $private, $description ) { - $_SERVER = $input; - $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 ); - } - - public static function provideGetIP() { - return array( - array( - '127.0.0.1', - array( - 'REMOTE_ADDR' => '127.0.0.1' - ), - array(), - array(), - false, - 'Simple IPv4' - ), - array( - '::1', - array( - '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' - ), - array( - '12.0.0.1', - array( - 'REMOTE_ADDR' => '12.0.0.1', - 'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2' - ), - array(), - array(), - false, - 'With X-Forwaded-For and disallowed server' - ), - 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( '12.0.0.1' ), - array(), - false, - 'With multiple X-Forwaded-For and only one allowed server' - ), - 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(), - false, - 'With X-Forwaded-For and private IP (from cache proxy)' - ), - 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', '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 - */ - public function testGetIpLackOfRemoteAddrThrowAnException() { - $request = new WebRequest(); - # Next call throw an exception about lacking an IP - $request->getIP(); - } - - public static function provideLanguageData() { - return array( - array( '', array(), 'Empty Accept-Language header' ), - array( 'en', array( 'en' => 1 ), 'One language' ), - array( 'en, ar', array( 'en' => 1, 'ar' => 1 ), 'Two languages listed in appearance order.' ), - array( 'zh-cn,zh-tw', array( 'zh-cn' => 1, 'zh-tw' => 1 ), 'Two equally prefered languages, listed in appearance order per rfc3282. Checks c9119' ), - array( 'es, en; q=0.5', array( 'es' => 1, 'en' => '0.5' ), 'Spanish as first language and English and second' ), - array( 'en; q=0.5, es', array( 'es' => 1, 'en' => '0.5' ), 'Less prefered language first' ), - array( 'fr, en; q=0.5, es', array( 'fr' => 1, 'es' => 1, 'en' => '0.5' ), 'Three languages' ), - array( 'en; q=0.5, es', array( 'es' => 1, 'en' => '0.5' ), 'Two languages' ), - array( 'en, zh;q=0', array( 'en' => 1 ), "It's Chinese to me" ), - array( 'es; q=1, pt;q=0.7, it; q=0.6, de; q=0.1, ru;q=0', array( 'es' => '1', 'pt' => '0.7', 'it' => '0.6', 'de' => '0.1' ), 'Preference for romance languages' ), - array( 'en-gb, en-us; q=1', array( 'en-gb' => 1, 'en-us' => '1' ), 'Two equally prefered English variants' ), - ); - } - - /** - * @dataProvider provideLanguageData - * @covers WebRequest::getAcceptLang - */ - 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 deleted file mode 100644 index e0d786b9..00000000 --- a/tests/phpunit/includes/WikiPageTest.php +++ /dev/null @@ -1,1074 +0,0 @@ -<?php - -/** - * @group ContentHandler - * @group Database - * ^--- important, causes temporary tables to be used instead of the real database - * @group medium - **/ -class WikiPageTest extends MediaWikiLangTestCase { - - protected $pages_to_delete; - - function __construct( $name = null, array $data = array(), $dataName = '' ) { - parent::__construct( $name, $data, $dataName ); - - $this->tablesUsed = array_merge( - $this->tablesUsed, - array( 'page', - 'revision', - 'text', - - 'recentchanges', - 'logging', - - 'page_props', - 'pagelinks', - 'categorylinks', - 'langlinks', - 'externallinks', - 'imagelinks', - 'templatelinks', - 'iwlinks' ) ); - } - - protected function setUp() { - parent::setUp(); - $this->pages_to_delete = array(); - - LinkCache::singleton()->clear(); # avoid cached redirect status, etc - } - - protected function tearDown() { - foreach ( $this->pages_to_delete as $p ) { - /* @var $p WikiPage */ - - try { - if ( $p->exists() ) { - $p->doDeleteArticle( "testing done." ); - } - } catch ( MWException $ex ) { - // fail silently - } - } - parent::tearDown(); - } - - /** - * @param Title $title - * @param String $model - * @return WikiPage - */ - protected function newPage( $title, $model = null ) { - if ( is_string( $title ) ) { - $ns = $this->getDefaultWikitextNS(); - $title = Title::newFromText( $title, $ns ); - } - - $p = new WikiPage( $title ); - - $this->pages_to_delete[] = $p; - - return $p; - } - - /** - * @param String|Title|WikiPage $page - * @param String $text - * @param int $model - * - * @return WikiPage - */ - protected function createPage( $page, $text, $model = null ) { - if ( is_string( $page ) || $page instanceof Title ) { - $page = $this->newPage( $page, $model ); - } - - $content = ContentHandler::makeContent( $text, $page->getTitle(), $model ); - $page->doEditContent( $content, "testing", EDIT_NEW ); - - return $page; - } - - /** - * @covers WikiPage::doEditContent - */ - public function testDoEditContent() { - $page = $this->newPage( "WikiPageTest_testDoEditContent" ); - $title = $page->getTitle(); - - $content = ContentHandler::makeContent( "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam " - . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.", - $title, CONTENT_MODEL_WIKITEXT ); - - $page->doEditContent( $content, "[[testing]] 1" ); - - $this->assertTrue( $title->getArticleID() > 0, "Title object should have new page id" ); - $this->assertTrue( $page->getId() > 0, "WikiPage should have new page id" ); - $this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" ); - $this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" ); - - $id = $page->getId(); - - # ------------------------ - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) ); - $n = $res->numRows(); - $res->free(); - - $this->assertEquals( 1, $n, 'pagelinks should contain one link from the page' ); - - # ------------------------ - $page = new WikiPage( $title ); - - $retrieved = $page->getContent(); - $this->assertTrue( $content->equals( $retrieved ), 'retrieved content doesn\'t equal original' ); - - # ------------------------ - $content = ContentHandler::makeContent( "At vero eos et accusam et justo duo [[dolores]] et ea rebum. " - . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.", - $title, CONTENT_MODEL_WIKITEXT ); - - $page->doEditContent( $content, "testing 2" ); - - # ------------------------ - $page = new WikiPage( $title ); - - $retrieved = $page->getContent(); - $this->assertTrue( $content->equals( $retrieved ), 'retrieved content doesn\'t equal original' ); - - # ------------------------ - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) ); - $n = $res->numRows(); - $res->free(); - - $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" ); - $this->hideDeprecated( "Revision::getText" ); - - //NOTE: assume help namespace will default to wikitext - $title = Title::newFromText( "Help:WikiPageTest_testDoEdit" ); - - $page = $this->newPage( $title ); - - $text = "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam " - . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat."; - - $page->doEdit( $text, "[[testing]] 1" ); - - $this->assertTrue( $title->getArticleID() > 0, "Title object should have new page id" ); - $this->assertTrue( $page->getId() > 0, "WikiPage should have new page id" ); - $this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" ); - $this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" ); - - $id = $page->getId(); - - # ------------------------ - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) ); - $n = $res->numRows(); - $res->free(); - - $this->assertEquals( 1, $n, 'pagelinks should contain one link from the page' ); - - # ------------------------ - $page = new WikiPage( $title ); - - $retrieved = $page->getText(); - $this->assertEquals( $text, $retrieved, 'retrieved text doesn\'t equal original' ); - - # ------------------------ - $text = "At vero eos et accusam et justo duo [[dolores]] et ea rebum. " - . "Stet clita kasd [[gubergren]], no sea takimata sanctus est."; - - $page->doEdit( $text, "testing 2" ); - - # ------------------------ - $page = new WikiPage( $title ); - - $retrieved = $page->getText(); - $this->assertEquals( $text, $retrieved, 'retrieved text doesn\'t equal original' ); - - # ------------------------ - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) ); - $n = $res->numRows(); - $res->free(); - - $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' ); - } - - /** - * @covers WikiPage::doQuickEdit - */ - public function testDoQuickEdit() { - global $wgUser; - - $this->hideDeprecated( "WikiPage::doQuickEdit" ); - - //NOTE: assume help namespace will default to wikitext - $page = $this->createPage( "Help:WikiPageTest_testDoQuickEdit", "original text" ); - - $text = "quick text"; - $page->doQuickEdit( $text, $wgUser, "testing q" ); - - # --------------------- - $page = new WikiPage( $page->getTitle() ); - $this->assertEquals( $text, $page->getText() ); - } - - /** - * @covers WikiPage::doQuickEditContent - */ - public function testDoQuickEditContent() { - global $wgUser; - - $page = $this->createPage( "WikiPageTest_testDoQuickEditContent", "original text", CONTENT_MODEL_WIKITEXT ); - - $content = ContentHandler::makeContent( "quick text", $page->getTitle(), CONTENT_MODEL_WIKITEXT ); - $page->doQuickEditContent( $content, $wgUser, "testing q" ); - - # --------------------- - $page = new WikiPage( $page->getTitle() ); - $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(); - - $page->doDeleteArticle( "testing deletion" ); - - $this->assertFalse( $page->getTitle()->getArticleID() > 0, "Title object should now have page id 0" ); - $this->assertFalse( $page->getId() > 0, "WikiPage should now have page id 0" ); - $this->assertFalse( $page->exists(), "WikiPage::exists should return false after page was deleted" ); - $this->assertNull( $page->getContent(), "WikiPage::getContent should return null after page was deleted" ); - $this->assertFalse( $page->getText(), "WikiPage::getText should return false after page was deleted" ); - - $t = Title::newFromText( $page->getTitle()->getPrefixedText() ); - $this->assertFalse( $t->exists(), "Title::exists should return false after page was deleted" ); - - # ------------------------ - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) ); - $n = $res->numRows(); - $res->free(); - - $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(); - - $page->doDeleteUpdates( $id ); - - # ------------------------ - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) ); - $n = $res->numRows(); - $res->free(); - - $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' ); - } - - /** - * @covers WikiPage::getRevision - */ - public function testGetRevision() { - $page = $this->newPage( "WikiPageTest_testGetRevision" ); - - $rev = $page->getRevision(); - $this->assertNull( $rev ); - - # ----------------- - $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT ); - - $rev = $page->getRevision(); - - $this->assertEquals( $page->getLatest(), $rev->getId() ); - $this->assertEquals( "some text", $rev->getContent()->getNativeData() ); - } - - /** - * @covers WikiPage::getContent - */ - public function testGetContent() { - $page = $this->newPage( "WikiPageTest_testGetContent" ); - - $content = $page->getContent(); - $this->assertNull( $content ); - - # ----------------- - $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT ); - - $content = $page->getContent(); - $this->assertEquals( "some text", $content->getNativeData() ); - } - - /** - * @covers WikiPage::getText - */ - public function testGetText() { - $this->hideDeprecated( "WikiPage::getText" ); - - $page = $this->newPage( "WikiPageTest_testGetText" ); - - $text = $page->getText(); - $this->assertFalse( $text ); - - # ----------------- - $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT ); - - $text = $page->getText(); - $this->assertEquals( "some text", $text ); - } - - /** - * @covers WikiPage::getRawText - */ - public function testGetRawText() { - $this->hideDeprecated( "WikiPage::getRawText" ); - - $page = $this->newPage( "WikiPageTest_testGetRawText" ); - - $text = $page->getRawText(); - $this->assertFalse( $text ); - - # ----------------- - $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT ); - - $text = $page->getRawText(); - $this->assertEquals( "some text", $text ); - } - - /** - * @covers WikiPage::getContentModel - */ - public function testGetContentModel() { - global $wgContentHandlerUseDB; - - if ( !$wgContentHandlerUseDB ) { - $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' ); - } - - $page = $this->createPage( "WikiPageTest_testGetContentModel", "some text", CONTENT_MODEL_JAVASCRIPT ); - - $page = new WikiPage( $page->getTitle() ); - $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $page->getContentModel() ); - } - - /** - * @covers WikiPage::getContentHandler - */ - public function testGetContentHandler() { - global $wgContentHandlerUseDB; - - if ( !$wgContentHandlerUseDB ) { - $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' ); - } - - $page = $this->createPage( "WikiPageTest_testGetContentHandler", "some text", CONTENT_MODEL_JAVASCRIPT ); - - $page = new WikiPage( $page->getTitle() ); - $this->assertEquals( 'JavaScriptContentHandler', get_class( $page->getContentHandler() ) ); - } - - /** - * @covers WikiPage::exists - */ - public function testExists() { - $page = $this->newPage( "WikiPageTest_testExists" ); - $this->assertFalse( $page->exists() ); - - # ----------------- - $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT ); - $this->assertTrue( $page->exists() ); - - $page = new WikiPage( $page->getTitle() ); - $this->assertTrue( $page->exists() ); - - # ----------------- - $page->doDeleteArticle( "done testing" ); - $this->assertFalse( $page->exists() ); - - $page = new WikiPage( $page->getTitle() ); - $this->assertFalse( $page->exists() ); - } - - public static function provideHasViewableContent() { - return array( - array( 'WikiPageTest_testHasViewableContent', false, true ), - array( 'Special:WikiPageTest_testHasViewableContent', false ), - array( 'MediaWiki:WikiPageTest_testHasViewableContent', false ), - array( 'Special:Userlogin', true ), - array( 'MediaWiki:help', true ), - ); - } - - /** - * @dataProvider provideHasViewableContent - * @covers WikiPage::hasViewableContent - */ - public function testHasViewableContent( $title, $viewable, $create = false ) { - $page = $this->newPage( $title ); - $this->assertEquals( $viewable, $page->hasViewableContent() ); - - if ( $create ) { - $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT ); - $this->assertTrue( $page->hasViewableContent() ); - - $page = new WikiPage( $page->getTitle() ); - $this->assertTrue( $page->hasViewableContent() ); - } - } - - public static function provideGetRedirectTarget() { - return array( - array( 'WikiPageTest_testGetRedirectTarget_1', CONTENT_MODEL_WIKITEXT, "hello world", null ), - array( 'WikiPageTest_testGetRedirectTarget_2', CONTENT_MODEL_WIKITEXT, "#REDIRECT [[hello world]]", "Hello world" ), - ); - } - - /** - * @dataProvider provideGetRedirectTarget - * @covers WikiPage::getRedirectTarget - */ - public function testGetRedirectTarget( $title, $model, $text, $target ) { - $page = $this->createPage( $title, $text, $model ); - - # sanity check, because this test seems to fail for no reason for some people. - $c = $page->getContent(); - $this->assertEquals( 'WikitextContent', get_class( $c ) ); - - # now, test the actual redirect - $t = $page->getRedirectTarget(); - $this->assertEquals( $target, is_null( $t ) ? null : $t->getPrefixedText() ); - } - - /** - * @dataProvider provideGetRedirectTarget - * @covers WikiPage::isRedirect - */ - public function testIsRedirect( $title, $model, $text, $target ) { - $page = $this->createPage( $title, $text, $model ); - $this->assertEquals( !is_null( $target ), $page->isRedirect() ); - } - - public static function provideIsCountable() { - return array( - - // any - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - '', - 'any', - true - ), - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - 'Foo', - 'any', - true - ), - - // comma - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - 'Foo', - 'comma', - false - ), - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - 'Foo, bar', - 'comma', - true - ), - - // link - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - 'Foo', - 'link', - false - ), - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - 'Foo [[bar]]', - 'link', - true - ), - - // redirects - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - '#REDIRECT [[bar]]', - 'any', - false - ), - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - '#REDIRECT [[bar]]', - 'comma', - false - ), - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - '#REDIRECT [[bar]]', - 'link', - false - ), - - // not a content namespace - array( 'Talk:WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - 'Foo', - 'any', - false - ), - array( 'Talk:WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - 'Foo, bar', - 'comma', - false - ), - array( 'Talk:WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - 'Foo [[bar]]', - 'link', - false - ), - - // not a content namespace, different model - array( 'MediaWiki:WikiPageTest_testIsCountable.js', - null, - 'Foo', - 'any', - false - ), - array( 'MediaWiki:WikiPageTest_testIsCountable.js', - null, - 'Foo, bar', - 'comma', - false - ), - array( 'MediaWiki:WikiPageTest_testIsCountable.js', - null, - 'Foo [[bar]]', - 'link', - false - ), - ); - } - - - /** - * @dataProvider provideIsCountable - * @covers WikiPage::isCountable - */ - public function testIsCountable( $title, $model, $text, $mode, $expected ) { - global $wgContentHandlerUseDB; - - $this->setMwGlobals( 'wgArticleCountMethod', $mode ); - - $title = Title::newFromText( $title ); - - if ( !$wgContentHandlerUseDB && $model && ContentHandler::getDefaultModelFor( $title ) != $model ) { - $this->markTestSkipped( "Can not use non-default content model $model for " - . $title->getPrefixedDBkey() . " with \$wgContentHandlerUseDB disabled." ); - } - - $page = $this->createPage( $title, $text, $model ); - $hasLinks = wfGetDB( DB_SLAVE )->selectField( 'pagelinks', 1, - array( 'pl_from' => $page->getId() ), __METHOD__ ); - - $editInfo = $page->prepareContentForEdit( $page->getContent() ); - - $v = $page->isCountable(); - $w = $page->isCountable( $editInfo ); - - $this->assertEquals( $expected, $v, "isCountable( null ) returned unexpected value " . var_export( $v, true ) - . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" ); - - $this->assertEquals( $expected, $w, "isCountable( \$editInfo ) returned unexpected value " . var_export( $v, true ) - . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" ); - } - - public static function provideGetParserOutput() { - return array( - array( CONTENT_MODEL_WIKITEXT, "hello ''world''\n", "<p>hello <i>world</i></p>" ), - // @todo more...? - ); - } - - /** - * @dataProvider provideGetParserOutput - * @covers WikiPage::getParserOutput - */ - public function testGetParserOutput( $model, $text, $expectedHtml ) { - $page = $this->createPage( 'WikiPageTest_testGetParserOutput', $text, $model ); - - $opt = $page->makeParserOptions( 'canonical' ); - $po = $page->getParserOutput( $opt ); - $text = $po->getText(); - - $text = trim( preg_replace( '/<!--.*?-->/sm', '', $text ) ); # strip injected comments - $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++; - - $page = new WikiPage( new Title( "WikiPageTest_testGetParserOutput_nonexisting_$count" ) ); - - $opt = new ParserOptions(); - $po = $page->getParserOutput( $opt ); - - $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 - - $this->assertFalse( $po, "getParserOutput() shall return false for non-existing revisions." ); - } - - static $sections = - - "Intro - -== stuff == -hello world - -== test == -just a test - -== foo == -more stuff -"; - - - public function dataReplaceSection() { - //NOTE: assume the Help namespace to contain wikitext - return array( - array( 'Help:WikiPageTest_testReplaceSection', - CONTENT_MODEL_WIKITEXT, - WikiPageTest::$sections, - "0", - "No more", - null, - trim( preg_replace( '/^Intro/sm', 'No more', WikiPageTest::$sections ) ) - ), - array( 'Help:WikiPageTest_testReplaceSection', - CONTENT_MODEL_WIKITEXT, - WikiPageTest::$sections, - "", - "No more", - null, - "No more" - ), - array( 'Help:WikiPageTest_testReplaceSection', - CONTENT_MODEL_WIKITEXT, - WikiPageTest::$sections, - "2", - "== TEST ==\nmore fun", - null, - trim( preg_replace( '/^== test ==.*== foo ==/sm', - "== TEST ==\nmore fun\n\n== foo ==", - WikiPageTest::$sections ) ) - ), - array( 'Help:WikiPageTest_testReplaceSection', - CONTENT_MODEL_WIKITEXT, - WikiPageTest::$sections, - "8", - "No more", - null, - trim( WikiPageTest::$sections ) - ), - array( 'Help:WikiPageTest_testReplaceSection', - CONTENT_MODEL_WIKITEXT, - WikiPageTest::$sections, - "new", - "No more", - "New", - trim( WikiPageTest::$sections ) . "\n\n== New ==\n\nNo more" - ), - ); - } - - /** - * @dataProvider dataReplaceSection - * @covers WikiPage::replaceSection - */ - public function testReplaceSection( $title, $model, $text, $section, $with, $sectionTitle, $expected ) { - $this->hideDeprecated( "WikiPage::replaceSection" ); - - $page = $this->createPage( $title, $text, $model ); - $text = $page->replaceSection( $section, $with, $sectionTitle ); - $text = trim( $text ); - - $this->assertEquals( $expected, $text ); - } - - /** - * @dataProvider dataReplaceSection - * @covers WikiPage::replaceSectionContent - */ - public function testReplaceSectionContent( $title, $model, $text, $section, $with, $sectionTitle, $expected ) { - $page = $this->createPage( $title, $text, $model ); - - $content = ContentHandler::makeContent( $with, $page->getTitle(), $page->getContentModel() ); - $c = $page->replaceSectionContent( $section, $content, $sectionTitle ); - - $this->assertEquals( $expected, is_null( $c ) ? null : trim( $c->getNativeData() ) ); - } - - /* @todo FIXME: fix this! - public function testGetUndoText() { - $this->checkHasDiff3(); - - $text = "one"; - $page = $this->createPage( "WikiPageTest_testGetUndoText", $text ); - $rev1 = $page->getRevision(); - - $text .= "\n\ntwo"; - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section two"); - $rev2 = $page->getRevision(); - - $text .= "\n\nthree"; - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section three"); - $rev3 = $page->getRevision(); - - $text .= "\n\nfour"; - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section four"); - $rev4 = $page->getRevision(); - - $text .= "\n\nfive"; - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section five"); - $rev5 = $page->getRevision(); - - $text .= "\n\nsix"; - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section six"); - $rev6 = $page->getRevision(); - - $undo6 = $page->getUndoText( $rev6 ); - if ( $undo6 === false ) $this->fail( "getUndoText failed for rev6" ); - $this->assertEquals( "one\n\ntwo\n\nthree\n\nfour\n\nfive", $undo6 ); - - $undo3 = $page->getUndoText( $rev4, $rev2 ); - if ( $undo3 === false ) $this->fail( "getUndoText failed for rev4..rev2" ); - $this->assertEquals( "one\n\ntwo\n\nfive", $undo3 ); - - $undo2 = $page->getUndoText( $rev2 ); - if ( $undo2 === false ) $this->fail( "getUndoText failed for rev2" ); - $this->assertEquals( "one\n\nfive", $undo2 ); - } - */ - - /** - * @todo FIXME: this is a better rollback test than the one below, but it keeps failing in jenkins for some reason. - */ - public function broken_testDoRollback() { - $admin = new User(); - $admin->setName( "Admin" ); - - $text = "one"; - $page = $this->newPage( "WikiPageTest_testDoRollback" ); - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), - "section one", EDIT_NEW, false, $admin ); - - $user1 = new User(); - $user1->setName( "127.0.1.11" ); - $text .= "\n\ntwo"; - $page = new WikiPage( $page->getTitle() ); - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), - "adding section two", 0, false, $user1 ); - - $user2 = new User(); - $user2->setName( "127.0.2.13" ); - $text .= "\n\nthree"; - $page = new WikiPage( $page->getTitle() ); - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), - "adding section three", 0, false, $user2 ); - - # we are having issues with doRollback spuriously failing. apparently the last revision somehow goes missing - # or not committed under some circumstances. so, make sure the last revision has the right user name. - $dbr = wfGetDB( DB_SLAVE ); - $this->assertEquals( 3, Revision::countByPageId( $dbr, $page->getId() ) ); - - $page = new WikiPage( $page->getTitle() ); - $rev3 = $page->getRevision(); - $this->assertEquals( '127.0.2.13', $rev3->getUserText() ); - - $rev2 = $rev3->getPrevious(); - $this->assertEquals( '127.0.1.11', $rev2->getUserText() ); - - $rev1 = $rev2->getPrevious(); - $this->assertEquals( 'Admin', $rev1->getUserText() ); - - # now, try the actual rollback - $admin->addGroup( "sysop" ); #XXX: make the test user a sysop... - $token = $admin->getEditToken( array( $page->getTitle()->getPrefixedText(), $user2->getName() ), null ); - $errors = $page->doRollback( $user2->getName(), "testing revert", $token, false, $details, $admin ); - - if ( $errors ) { - $this->fail( "Rollback failed:\n" . print_r( $errors, true ) . ";\n" . print_r( $details, true ) ); - } - - $page = new WikiPage( $page->getTitle() ); - $this->assertEquals( $rev2->getSha1(), $page->getRevision()->getSha1(), - "rollback did not revert to the correct revision" ); - $this->assertEquals( "one\n\ntwo", $page->getContent()->getNativeData() ); - } - - /** - * @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(); - $admin->setName( "Admin" ); - - $text = "one"; - $page = $this->newPage( "WikiPageTest_testDoRollback" ); - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ), - "section one", EDIT_NEW, false, $admin ); - $rev1 = $page->getRevision(); - - $user1 = new User(); - $user1->setName( "127.0.1.11" ); - $text .= "\n\ntwo"; - $page = new WikiPage( $page->getTitle() ); - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ), - "adding section two", 0, false, $user1 ); - - # now, try the rollback - $admin->addGroup( "sysop" ); #XXX: make the test user a sysop... - $token = $admin->getEditToken( array( $page->getTitle()->getPrefixedText(), $user1->getName() ), null ); - $errors = $page->doRollback( $user1->getName(), "testing revert", $token, false, $details, $admin ); - - if ( $errors ) { - $this->fail( "Rollback failed:\n" . print_r( $errors, true ) . ";\n" . print_r( $details, true ) ); - } - - $page = new WikiPage( $page->getTitle() ); - $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(), - "rollback did not revert to the correct revision" ); - $this->assertEquals( "one", $page->getContent()->getNativeData() ); - } - - public static function provideGetAutosummary() { - return array( - array( - 'Hello there, world!', - '#REDIRECT [[Foo]]', - 0, - '/^Redirected page .*Foo/' - ), - - array( - null, - 'Hello world!', - EDIT_NEW, - '/^Created page .*Hello/' - ), - - array( - 'Hello there, world!', - '', - 0, - '/^Blanked/' - ), - - array( - 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut - labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et - ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.', - 'Hello world!', - 0, - '/^Replaced .*Hello/' - ), - - array( - 'foo', - 'bar', - 0, - '/^$/' - ), - ); - } - - /** - * @dataProvider provideGetAutoSummary - * @covers WikiPage::getAutosummary - */ - public function testGetAutosummary( $old, $new, $flags, $expected ) { - $this->hideDeprecated( "WikiPage::getAutosummary" ); - - $page = $this->newPage( "WikiPageTest_testGetAutosummary" ); - - $summary = $page->getAutosummary( $old, $new, $flags ); - - $this->assertTrue( (bool)preg_match( $expected, $summary ), - "Autosummary didn't match expected pattern $expected: $summary" ); - } - - public static function provideGetAutoDeleteReason() { - return array( - array( - array(), - false, - false - ), - - array( - array( - array( "first edit", null ), - ), - "/first edit.*only contributor/", - false - ), - - array( - array( - array( "first edit", null ), - array( "second edit", null ), - ), - "/second edit.*only contributor/", - true - ), - - array( - array( - array( "first edit", "127.0.2.22" ), - array( "second edit", "127.0.3.33" ), - ), - "/second edit/", - true - ), - - array( - array( - array( "first edit: " - . "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam " - . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. " - . "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea " - . "takimata sanctus est Lorem ipsum dolor sit amet.'", null ), - ), - '/first edit:.*\.\.\."/', - false - ), - - array( - array( - array( "first edit", "127.0.2.22" ), - array( "", "127.0.3.33" ), - ), - "/before blanking.*first edit/", - true - ), - - ); - } - - /** - * @dataProvider provideGetAutoDeleteReason - * @covers WikiPage::getAutoDeleteReason - */ - public function testGetAutoDeleteReason( $edits, $expectedResult, $expectedHistory ) { - global $wgUser; - - //NOTE: assume Help namespace to contain wikitext - $page = $this->newPage( "Help:WikiPageTest_testGetAutoDeleteReason" ); - - $c = 1; - - foreach ( $edits as $edit ) { - $user = new User(); - - if ( !empty( $edit[1] ) ) { - $user->setName( $edit[1] ); - } else { - $user = $wgUser; - } - - $content = ContentHandler::makeContent( $edit[0], $page->getTitle(), $page->getContentModel() ); - - $page->doEditContent( $content, "test edit $c", $c < 2 ? EDIT_NEW : 0, false, $user ); - - $c += 1; - } - - $reason = $page->getAutoDeleteReason( $hasHistory ); - - if ( is_bool( $expectedResult ) || is_null( $expectedResult ) ) { - $this->assertEquals( $expectedResult, $reason ); - } else { - $this->assertTrue( (bool)preg_match( $expectedResult, $reason ), - "Autosummary didn't match expected pattern $expectedResult: $reason" ); - } - - $this->assertEquals( $expectedHistory, $hasHistory, - "expected \$hasHistory to be " . var_export( $expectedHistory, true ) ); - - $page->doDeleteArticle( "done" ); - } - - public static function providePreSaveTransform() { - return array( - array( 'hello this is ~~~', - "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]", - ), - array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>', - 'hello \'\'this\'\' is <nowiki>~~~</nowiki>', - ), - ); - } - - /** - * @dataProvider providePreSaveTransform - * @covers WikiPage::preSaveTransform - */ - public function testPreSaveTransform( $text, $expected ) { - $this->hideDeprecated( 'WikiPage::preSaveTransform' ); - $user = new User(); - $user->setName( "127.0.0.1" ); - - //NOTE: assume Help namespace to contain wikitext - $page = $this->newPage( "Help:WikiPageTest_testPreloadTransform" ); - $text = $page->preSaveTransform( $text, $user ); - - $this->assertEquals( $expected, $text ); - } -} diff --git a/tests/phpunit/includes/WikiPageTest_ContentHandlerUseDB.php b/tests/phpunit/includes/WikiPageTest_ContentHandlerUseDB.php deleted file mode 100644 index 2a723e85..00000000 --- a/tests/phpunit/includes/WikiPageTest_ContentHandlerUseDB.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php - -/** - * @group ContentHandler - * @group Database - * ^--- important, causes temporary tables to be used instead of the real database - */ -class WikiPageTest_ContentHandlerUseDB extends WikiPageTest { - - protected function setUp() { - parent::setUp(); - $this->setMwGlobals( 'wgContentHandlerUseDB', false ); - - $dbw = wfGetDB( DB_MASTER ); - - $page_table = $dbw->tableName( 'page' ); - $revision_table = $dbw->tableName( 'revision' ); - $archive_table = $dbw->tableName( 'archive' ); - - if ( $dbw->fieldExists( $page_table, 'page_content_model' ) ) { - $dbw->query( "alter table $page_table drop column page_content_model" ); - $dbw->query( "alter table $revision_table drop column rev_content_model" ); - $dbw->query( "alter table $revision_table drop column rev_content_format" ); - $dbw->query( "alter table $archive_table drop column ar_content_model" ); - $dbw->query( "alter table $archive_table drop column ar_content_format" ); - } - } - - /** - * @covers WikiPage::getContentModel - */ - public function testGetContentModel() { - $page = $this->createPage( "WikiPageTest_testGetContentModel", "some text", CONTENT_MODEL_JAVASCRIPT ); - - $page = new WikiPage( $page->getTitle() ); - - // NOTE: since the content model is not recorded in the database, - // we expect to get the default, namely CONTENT_MODEL_WIKITEXT - $this->assertEquals( CONTENT_MODEL_WIKITEXT, $page->getContentModel() ); - } - - /** - * @covers WikiPage::getContentHandler - */ - public function testGetContentHandler() { - $page = $this->createPage( "WikiPageTest_testGetContentHandler", "some text", CONTENT_MODEL_JAVASCRIPT ); - - // NOTE: since the content model is not recorded in the database, - // we expect to get the default, namely CONTENT_MODEL_WIKITEXT - $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 deleted file mode 100644 index 161468e2..00000000 --- a/tests/phpunit/includes/XmlJsTest.php +++ /dev/null @@ -1,24 +0,0 @@ -<?php - -/** - * @group Xml - */ -class XmlJs extends MediaWikiTestCase { - - /** - * @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 deleted file mode 100644 index 56d28b54..00000000 --- a/tests/phpunit/includes/XmlSelectTest.php +++ /dev/null @@ -1,173 +0,0 @@ -<?php - -/** - * @group Xml - */ -class XmlSelectTest extends MediaWikiTestCase { - - /** - * @var XmlSelect - */ - protected $select; - - protected function setUp() { - parent::setUp(); - $this->setMwGlobals( array( - 'wgWellFormedXml' => true, - ) ); - $this->select = new XmlSelect(); - } - - protected function tearDown() { - parent::tearDown(); - $this->select = null; - } - - /** - * @covers XmlSelect::__construct - */ - public function testConstructWithoutParameters() { - $this->assertEquals( '<select></select>', $this->select->getHTML() ); - } - - /** - * 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 ); - $this->assertEquals( $expected, $this->select->getHTML() ); - } - - /** - * Provide parameters for testConstructParameters() which use three - * parameters: - * - $name (default: false) - * - $id (default: false) - * - $default (default: false) - * Provides a fourth parameters representing the expected HTML output - */ - public static function provideConstructionParameters() { - return array( - /** - * Values are set following a 3-bit Gray code where two successive - * values differ by only one value. - * See http://en.wikipedia.org/wiki/Gray_code - */ - # $name $id $default - array( false, false, false, '<select></select>' ), - array( false, false, 'foo', '<select></select>' ), - array( false, 'id', 'foo', '<select id="id"></select>' ), - array( false, 'id', false, '<select id="id"></select>' ), - array( 'name', 'id', false, '<select name="name" id="id"></select>' ), - array( 'name', 'id', 'foo', '<select name="name" id="id"></select>' ), - array( 'name', false, 'foo', '<select name="name"></select>' ), - array( 'name', false, false, '<select name="name"></select>' ), - ); - } - - /** - * @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() ); - } - - /** - * @covers XmlSelect::setDefault - */ - public function testSetDefault() { - $this->select->setDefault( 'bar1' ); - $this->select->addOption( 'foo1' ); - $this->select->addOption( 'bar1' ); - $this->select->addOption( 'foo2' ); - $this->assertEquals( - '<select><option value="foo1">foo1</option>' . "\n" . - '<option value="bar1" selected="">bar1</option>' . "\n" . - '<option value="foo2">foo2</option></select>', $this->select->getHTML() ); - } - - /** - * 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' ); - $this->select->addOption( 'bar1' ); - $this->select->addOption( 'foo2' ); - $this->select->setDefault( 'bar1' ); # setting default after adding options - $this->assertEquals( - '<select><option value="foo1">foo1</option>' . "\n" . - '<option value="bar1" selected="">bar1</option>' . "\n" . - '<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 ); - $this->select->setAttribute( 'string', 'euro €' ); - $this->select->setAttribute( 1911, 'razor' ); - - # verify we can retrieve them - $this->assertEquals( - $this->select->getAttribute( 'dummy' ), - 0x777 - ); - $this->assertEquals( - $this->select->getAttribute( 'string' ), - 'euro €' - ); - $this->assertEquals( - $this->select->getAttribute( 1911 ), - 'razor' - ); - - # inexistant keys should give us 'null' - $this->assertEquals( - $this->select->getAttribute( 'I DO NOT EXIT' ), - null - ); - - # verify string / integer - $this->assertEquals( - $this->select->getAttribute( '1911' ), - 'razor' - ); - $this->assertEquals( - $this->select->getAttribute( 'dummy' ), - 0x777 - ); - } -} diff --git a/tests/phpunit/includes/XmlTest.php b/tests/phpunit/includes/XmlTest.php deleted file mode 100644 index 8205029f..00000000 --- a/tests/phpunit/includes/XmlTest.php +++ /dev/null @@ -1,402 +0,0 @@ -<?php - -/** - * @group Xml - */ -class XmlTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - $langObj = Language::factory( 'en' ); - $langObj->setNamespaces( array( - -2 => 'Media', - -1 => 'Special', - 0 => '', - 1 => 'Talk', - 2 => 'User', - 3 => 'User_talk', - 4 => 'MyWiki', - 5 => 'MyWiki_Talk', - 6 => 'File', - 7 => 'File_talk', - 8 => 'MediaWiki', - 9 => 'MediaWiki_talk', - 10 => 'Template', - 11 => 'Template_talk', - 100 => 'Custom', - 101 => 'Custom_talk', - ) ); - - $this->setMwGlobals( array( - 'wgLang' => $langObj, - 'wgWellFormedXml' => true, - ) ); - } - - /** - * @covers Xml::expandAttributes - */ - public function testExpandAttributes() { - $this->assertNull( Xml::expandAttributes( null ), - 'Converting a null list of attributes' - ); - $this->assertEquals( '', Xml::expandAttributes( array() ), - 'Converting an empty list of attributes' - ); - } - - /** - * @covers Xml::expandAttributes - */ - public function testExpandAttributesException() { - $this->setExpectedException( 'MWException' ); - Xml::expandAttributes( 'string' ); - } - - /** - * @covers Xml::element - */ - public function testElementOpen() { - $this->assertEquals( - '<element>', - Xml::element( 'element', null, null ), - 'Opening element with no attributes' - ); - } - - /** - * @covers Xml::element - */ - public function testElementEmpty() { - $this->assertEquals( - '<element />', - Xml::element( 'element', null, '' ), - 'Terminated empty element' - ); - } - - /** - * @covers Xml::input - */ - public function testElementInputCanHaveAValueOfZero() { - $this->assertEquals( - '<input name="name" value="0" />', - Xml::input( 'name', false, 0 ), - 'Input with a value of 0 (bug 23797)' - ); - } - - /** - * @covers Xml::element - */ - public function testElementEscaping() { - $this->assertEquals( - '<element>hello <there> you & you</element>', - Xml::element( 'element', null, 'hello <there> you & you' ), - 'Element with no attributes and content that needs escaping' - ); - } - - /** - * @covers Xml::escapeTagsOnly - */ - public function testEscapeTagsOnly() { - $this->assertEquals( '"><', Xml::escapeTagsOnly( '"><' ), - 'replace " > and < with their HTML entitites' - ); - } - - /** - * @covers Xml::element - */ - public function testElementAttributes() { - $this->assertEquals( - '<element key="value" <>="<>">', - Xml::element( 'element', array( 'key' => 'value', '<>' => '<>' ), null ), - 'Element attributes, keys are not escaped' - ); - } - - /** - * @covers Xml::openElement - */ - public function testOpenElement() { - $this->assertEquals( - '<element k="v">', - Xml::openElement( 'element', array( 'k' => 'v' ) ), - 'openElement() shortcut' - ); - } - - /** - * @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; - - $curMonth = intval( gmdate( 'n' ) ); - $prevMonth = $curMonth - 1; - if ( $prevMonth == 0 ) { - $prevMonth = 12; - } - $nextMonth = $curMonth + 1; - if ( $nextMonth == 13 ) { - $nextMonth = 1; - } - - $this->assertEquals( - '<label for="year">From year (and earlier):</label> <input id="year" maxlength="4" size="7" type="number" value="2011" name="year" /> <label for="month">From month (and earlier):</label> <select id="month" name="month" class="mw-month-selector"><option value="-1">all</option>' . "\n" . - '<option value="1">January</option>' . "\n" . - '<option value="2" selected="">February</option>' . "\n" . - '<option value="3">March</option>' . "\n" . - '<option value="4">April</option>' . "\n" . - '<option value="5">May</option>' . "\n" . - '<option value="6">June</option>' . "\n" . - '<option value="7">July</option>' . "\n" . - '<option value="8">August</option>' . "\n" . - '<option value="9">September</option>' . "\n" . - '<option value="10">October</option>' . "\n" . - '<option value="11">November</option>' . "\n" . - '<option value="12">December</option></select>', - Xml::dateMenu( 2011, 02 ), - "Date menu for february 2011" - ); - $this->assertEquals( - '<label for="year">From year (and earlier):</label> <input id="year" maxlength="4" size="7" type="number" value="2011" name="year" /> <label for="month">From month (and earlier):</label> <select id="month" name="month" class="mw-month-selector"><option value="-1">all</option>' . "\n" . - '<option value="1">January</option>' . "\n" . - '<option value="2">February</option>' . "\n" . - '<option value="3">March</option>' . "\n" . - '<option value="4">April</option>' . "\n" . - '<option value="5">May</option>' . "\n" . - '<option value="6">June</option>' . "\n" . - '<option value="7">July</option>' . "\n" . - '<option value="8">August</option>' . "\n" . - '<option value="9">September</option>' . "\n" . - '<option value="10">October</option>' . "\n" . - '<option value="11">November</option>' . "\n" . - '<option value="12">December</option></select>', - Xml::dateMenu( 2011, -1 ), - "Date menu with negative month for 'All'" - ); - $this->assertEquals( - Xml::dateMenu( $curYear, $curMonth ), - Xml::dateMenu( '', $curMonth ), - "Date menu year is the current one when not specified" - ); - - $wantedYear = $nextMonth == 1 ? $curYear : $prevYear; - $this->assertEquals( - Xml::dateMenu( $wantedYear, $nextMonth ), - Xml::dateMenu( '', $nextMonth ), - "Date menu next month is 11 months ago" - ); - - $this->assertEquals( - '<label for="year">From year (and earlier):</label> <input id="year" maxlength="4" size="7" type="number" name="year" /> <label for="month">From month (and earlier):</label> <select id="month" name="month" class="mw-month-selector"><option value="-1">all</option>' . "\n" . - '<option value="1">January</option>' . "\n" . - '<option value="2">February</option>' . "\n" . - '<option value="3">March</option>' . "\n" . - '<option value="4">April</option>' . "\n" . - '<option value="5">May</option>' . "\n" . - '<option value="6">June</option>' . "\n" . - '<option value="7">July</option>' . "\n" . - '<option value="8">August</option>' . "\n" . - '<option value="9">September</option>' . "\n" . - '<option value="10">October</option>' . "\n" . - '<option value="11">November</option>' . "\n" . - '<option value="12">December</option></select>', - Xml::dateMenu( '', '' ), - "Date menu with neither year or month" - ); - } - - /** - * @covers Xml::textarea - */ - public function testTextareaNoContent() { - $this->assertEquals( - '<textarea name="name" id="name" cols="40" rows="5"></textarea>', - Xml::textarea( 'name', '' ), - 'textarea() with not content' - ); - } - - /** - * @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 ), - 'textarea() with custom attribs' - ); - } - - /** - * @covers Xml::label - */ - public function testLabelCreation() { - $this->assertEquals( - '<label for="id">name</label>', - Xml::label( 'name', 'id' ), - 'label() with no attribs' - ); - } - - /** - * @covers Xml::label - */ - public function testLabelAttributeCanOnlyBeClassOrTitle() { - $this->assertEquals( - '<label for="id">name</label>', - Xml::label( 'name', 'id', array( 'generated' => true ) ), - 'label() can not be given a generated attribute' - ); - $this->assertEquals( - '<label for="id" class="nice">name</label>', - Xml::label( 'name', 'id', array( 'class' => 'nice' ) ), - 'label() can get a class attribute' - ); - $this->assertEquals( - '<label for="id" title="nice tooltip">name</label>', - Xml::label( 'name', 'id', array( 'title' => 'nice tooltip' ) ), - 'label() can get a title attribute' - ); - $this->assertEquals( - '<label for="id" class="nice" title="nice tooltip">name</label>', - Xml::label( 'name', 'id', array( - 'generated' => true, - 'class' => 'nice', - 'title' => 'nice tooltip', - 'anotherattr' => 'value', - ) - ), - 'label() skip all attributes but "class" and "title"' - ); - } - - /** - * @covers Xml::languageSelector - */ - public function testLanguageSelector() { - $select = Xml::languageSelector( 'en', true, null, - array( 'id' => 'testlang' ), wfMessage( 'yourlanguage' ) ); - $this->assertEquals( - '<label for="testlang">Language:</label>', - $select[0] - ); - } - - /** - * @covers Xml::escapeJsString - */ - public function testEscapeJsStringSpecialChars() { - $this->assertEquals( - '\\\\\r\n', - Xml::escapeJsString( "\\\r\n" ), - 'escapeJsString() with special characters' - ); - } - - /** - * @covers Xml::encodeJsVar - */ - public function testEncodeJsVarBoolean() { - $this->assertEquals( - 'true', - Xml::encodeJsVar( true ), - 'encodeJsVar() with boolean' - ); - } - - /** - * @covers Xml::encodeJsVar - */ - public function testEncodeJsVarNull() { - $this->assertEquals( - 'null', - Xml::encodeJsVar( null ), - 'encodeJsVar() with null' - ); - } - - /** - * @covers Xml::encodeJsVar - */ - public function testEncodeJsVarArray() { - $this->assertEquals( - '["a",1]', - Xml::encodeJsVar( array( 'a', 1 ) ), - 'encodeJsVar() with array' - ); - $this->assertEquals( - '{"a":"a","b":1}', - Xml::encodeJsVar( array( 'a' => 'a', 'b' => 1 ) ), - 'encodeJsVar() with associative array' - ); - } - - /** - * @covers Xml::encodeJsVar - */ - public function testEncodeJsVarObject() { - $this->assertEquals( - '{"a":"a","b":1}', - Xml::encodeJsVar( (object)array( 'a' => 'a', 'b' => 1 ) ), - 'encodeJsVar() with object' - ); - } - - /** - * @covers Xml::encodeJsVar - */ - public function testEncodeJsVarInt() { - $this->assertEquals( - '123456', - Xml::encodeJsVar( 123456 ), - 'encodeJsVar() with int' - ); - } - - /** - * @covers Xml::encodeJsVar - */ - public function testEncodeJsVarFloat() { - $this->assertEquals( - '1.23456', - Xml::encodeJsVar( 1.23456 ), - 'encodeJsVar() with float' - ); - } - - /** - * @covers Xml::encodeJsVar - */ - public function testEncodeJsVarIntString() { - $this->assertEquals( - '"123456"', - Xml::encodeJsVar( '123456' ), - 'encodeJsVar() with int-like string' - ); - } - - /** - * @covers Xml::encodeJsVar - */ - public function testEncodeJsVarFloatString() { - $this->assertEquals( - '"1.23456"', - Xml::encodeJsVar( '1.23456' ), - 'encodeJsVar() with float-like string' - ); - } -} diff --git a/tests/phpunit/includes/XmlTypeCheckTest.php b/tests/phpunit/includes/XmlTypeCheckTest.php deleted file mode 100644 index 8d6f1ed7..00000000 --- a/tests/phpunit/includes/XmlTypeCheckTest.php +++ /dev/null @@ -1,30 +0,0 @@ -<?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 deleted file mode 100644 index 2627a417..00000000 --- a/tests/phpunit/includes/ZipDirectoryReaderTest.php +++ /dev/null @@ -1,85 +0,0 @@ -<?php - -/** - * @covers ZipDirectoryReader - * NOTE: this test is more like an integration test than a unit test - */ -class ZipDirectoryReaderTest extends MediaWikiTestCase { - protected $zipDir; - protected $entries; - - protected function setUp() { - parent::setUp(); - $this->zipDir = __DIR__ . '/../data/zip'; - } - - function zipCallback( $entry ) { - $this->entries[] = $entry; - } - - function readZipAssertError( $file, $error, $assertMessage ) { - $this->entries = array(); - $status = ZipDirectoryReader::read( "{$this->zipDir}/$file", array( $this, 'zipCallback' ) ); - $this->assertTrue( $status->hasMessage( $error ), $assertMessage ); - } - - function readZipAssertSuccess( $file, $assertMessage ) { - $this->entries = array(); - $status = ZipDirectoryReader::read( "{$this->zipDir}/$file", array( $this, 'zipCallback' ) ); - $this->assertTrue( $status->isOK(), $assertMessage ); - } - - public function testEmpty() { - $this->readZipAssertSuccess( 'empty.zip', 'Empty zip' ); - } - - public function testMultiDisk0() { - $this->readZipAssertError( 'split.zip', 'zip-unsupported', - 'Split zip error' ); - } - - public function testNoSignature() { - $this->readZipAssertError( 'nosig.zip', 'zip-wrong-format', - 'No signature should give "wrong format" error' ); - } - - public function testSimple() { - $this->readZipAssertSuccess( 'class.zip', 'Simple ZIP' ); - $this->assertEquals( $this->entries, array( array( - 'name' => 'Class.class', - 'mtime' => '20010115000000', - 'size' => 1, - ) ) ); - } - - public function testBadCentralEntrySignature() { - $this->readZipAssertError( 'wrong-central-entry-sig.zip', 'zip-bad', - 'Bad central entry error' ); - } - - public function testTrailingBytes() { - $this->readZipAssertError( 'trail.zip', 'zip-bad', - 'Trailing bytes error' ); - } - - public function testWrongCDStart() { - $this->readZipAssertError( 'wrong-cd-start-disk.zip', 'zip-unsupported', - 'Wrong CD start disk error' ); - } - - - public function testCentralDirectoryGap() { - $this->readZipAssertError( 'cd-gap.zip', 'zip-bad', - 'CD gap error' ); - } - - public function testCentralDirectoryTruncated() { - $this->readZipAssertError( 'cd-truncated.zip', 'zip-bad', - 'CD truncated error (should hit unpack() overrun)' ); - } - - 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 deleted file mode 100644 index 68f80ac9..00000000 --- a/tests/phpunit/includes/api/ApiAccountCreationTest.php +++ /dev/null @@ -1,159 +0,0 @@ -<?php - -/** - * @group Database - * @group API - * @group medium - */ -class ApiCreateAccountTest extends ApiTestCase { - function setUp() { - parent::setUp(); - LoginForm::setCreateaccountToken(); - $this->setMwGlobals( array( 'wgEnableEmail' => true ) ); - } - - /** - * Test the account creation API with a valid request. Also - * make sure the new account can log in and is valid. - * - * This test does multiple API requests so it might end up being - * a bit slow. Raise the default timeout. - * @group medium - */ - public function testValid() { - global $wgServer; - - if ( !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' ); - } - - $password = User::randomPassword(); - - $ret = $this->doApiRequest( array( - 'action' => 'createaccount', - 'name' => 'Apitestnew', - 'password' => $password, - 'email' => 'test@domain.test', - 'realname' => 'Test Name' - ) ); - - $result = $ret[0]; - $this->assertNotInternalType( 'bool', $result ); - $this->assertNotInternalType( 'null', $result['createaccount'] ); - - // Should first ask for token. - $a = $result['createaccount']; - $this->assertEquals( 'needtoken', $a['result'] ); - $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] - ); - - $result = $ret[0]; - $this->assertNotInternalType( 'bool', $result ); - $this->assertEquals( 'success', $result['createaccount']['result'] ); - - // Try logging in with the new user. - $ret = $this->doApiRequest( array( - 'action' => 'login', - 'lgname' => 'Apitestnew', - 'lgpassword' => $password, - ) ); - - $result = $ret[0]; - $this->assertNotInternalType( 'bool', $result ); - $this->assertNotInternalType( 'null', $result['login'] ); - - $a = $result['login']['result']; - $this->assertEquals( 'NeedToken', $a ); - $token = $result['login']['token']; - - $ret = $this->doApiRequest( - array( - 'action' => 'login', - 'lgtoken' => $token, - 'lgname' => 'Apitestnew', - 'lgpassword' => $password, - ), - $ret[2] - ); - - $result = $ret[0]; - - $this->assertNotInternalType( 'bool', $result ); - $a = $result['login']['result']; - - $this->assertEquals( 'Success', $a ); - - // log out to destroy the session - $ret = $this->doApiRequest( - array( - 'action' => 'logout', - ), - $ret[2] - ); - $this->assertEquals( array(), $ret[0] ); - } - - /** - * Make sure requests with no names are invalid. - * @expectedException UsageException - */ - public function testNoName() { - $this->doApiRequest( array( - 'action' => 'createaccount', - 'token' => LoginForm::getCreateaccountToken(), - 'password' => 'password', - ) ); - } - - /** - * Make sure requests with no password are invalid. - * @expectedException UsageException - */ - public function testNoPassword() { - $this->doApiRequest( array( - 'action' => 'createaccount', - 'name' => 'testName', - 'token' => LoginForm::getCreateaccountToken(), - ) ); - } - - /** - * Make sure requests with existing users are invalid. - * @expectedException UsageException - */ - public function testExistingUser() { - $this->doApiRequest( array( - 'action' => 'createaccount', - 'name' => 'Apitestsysop', - 'token' => LoginForm::getCreateaccountToken(), - 'password' => 'password', - 'email' => 'test@domain.test', - ) ); - } - - /** - * Make sure requests with invalid emails are invalid. - * @expectedException UsageException - */ - public function testInvalidEmail() { - $this->doApiRequest( array( - 'action' => 'createaccount', - 'name' => 'Test User', - 'token' => LoginForm::getCreateaccountToken(), - 'password' => 'password', - 'email' => 'invalid', - ) ); - } -} diff --git a/tests/phpunit/includes/api/ApiBlockTest.php b/tests/phpunit/includes/api/ApiBlockTest.php deleted file mode 100644 index 8afb748a..00000000 --- a/tests/phpunit/includes/api/ApiBlockTest.php +++ /dev/null @@ -1,95 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - */ -class ApiBlockTest extends ApiTestCase { - protected function setUp() { - parent::setUp(); - $this->doLogin(); - } - - function getTokens() { - return $this->getTokenList( self::$users['sysop'] ); - } - - function addDBData() { - $user = User::newFromName( 'UTApiBlockee' ); - - if ( $user->getId() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTApiBlockeePassword' ); - - $user->saveSettings(); - } - } - - /** - * This test has probably always been broken and use an invalid token - * Bug tracking brokenness is https://bugzilla.wikimedia.org/35646 - * - * Root cause is https://gerrit.wikimedia.org/r/3434 - * Which made the Block/Unblock API to actually verify the token - * previously always considered valid (bug 34212). - */ - public function testMakeNormalBlock() { - $tokens = $this->getTokens(); - - $user = User::newFromName( 'UTApiBlockee' ); - - if ( !$user->getId() ) { - $this->markTestIncomplete( "The user UTApiBlockee does not exist" ); - } - - if ( !array_key_exists( 'blocktoken', $tokens ) ) { - $this->markTestIncomplete( "No block token found" ); - } - - $this->doApiRequest( array( - 'action' => 'block', - 'user' => 'UTApiBlockee', - 'reason' => 'Some reason', - 'token' => $tokens['blocktoken'] ), null, false, self::$users['sysop']->user ); - - $block = Block::newFromTarget( 'UTApiBlockee' ); - - $this->assertTrue( !is_null( $block ), 'Block is valid' ); - - $this->assertEquals( 'UTApiBlockee', (string)$block->getTarget() ); - $this->assertEquals( 'Some reason', $block->mReason ); - $this->assertEquals( 'infinity', $block->mExpiry ); - } - - /** - * Attempting to block without a token should give a UsageException with - * error message: - * "The token parameter must be set" - * - * @dataProvider provideBlockUnblockAction - * @expectedException UsageException - */ - public function testBlockingActionWithNoToken( $action ) { - $this->doApiRequest( - array( - 'action' => $action, - 'user' => 'UTApiBlockee', - 'reason' => 'Some reason', - ), - null, - false, - self::$users['sysop']->user - ); - } - - /** - * Just provide the 'block' and 'unblock' action to test both API calls - */ - 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 deleted file mode 100644 index 0c49b12b..00000000 --- a/tests/phpunit/includes/api/ApiEditPageTest.php +++ /dev/null @@ -1,417 +0,0 @@ -<?php - -/** - * Tests for MediaWiki api.php?action=edit. - * - * @author Daniel Kinzler - * - * @group API - * @group Database - * @group medium - */ -class ApiEditPageTest extends ApiTestCase { - - public function setUp() { - global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang; - - parent::setUp(); - - $wgExtraNamespaces[12312] = 'Dummy'; - $wgExtraNamespaces[12313] = 'Dummy_talk'; - - $wgNamespaceContentModels[12312] = "testing"; - $wgContentHandlers["testing"] = 'DummyContentHandlerForTesting'; - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - - $this->doLogin(); - } - - public function tearDown() { - global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang; - - unset( $wgExtraNamespaces[12312] ); - unset( $wgExtraNamespaces[12313] ); - - unset( $wgNamespaceContentModels[12312] ); - unset( $wgContentHandlers["testing"] ); - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - - parent::tearDown(); - } - - public function testEdit() { - $name = 'Help:ApiEditPageTest_testEdit'; // assume Help namespace to default to wikitext - - // -- test new page -------------------------------------------- - $apiResult = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => 'some text', - ) ); - $apiResult = $apiResult[0]; - - // Validate API result data - $this->assertArrayHasKey( 'edit', $apiResult ); - $this->assertArrayHasKey( 'result', $apiResult['edit'] ); - $this->assertEquals( 'Success', $apiResult['edit']['result'] ); - - $this->assertArrayHasKey( 'new', $apiResult['edit'] ); - $this->assertArrayNotHasKey( 'nochange', $apiResult['edit'] ); - - $this->assertArrayHasKey( 'pageid', $apiResult['edit'] ); - - // -- test existing page, no change ---------------------------- - $data = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => 'some text', - ) ); - - $this->assertEquals( 'Success', $data[0]['edit']['result'] ); - - $this->assertArrayNotHasKey( 'new', $data[0]['edit'] ); - $this->assertArrayHasKey( 'nochange', $data[0]['edit'] ); - - // -- test existing page, with change -------------------------- - $data = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => 'different text' - ) ); - - $this->assertEquals( 'Success', $data[0]['edit']['result'] ); - - $this->assertArrayNotHasKey( 'new', $data[0]['edit'] ); - $this->assertArrayNotHasKey( 'nochange', $data[0]['edit'] ); - - $this->assertArrayHasKey( 'oldrevid', $data[0]['edit'] ); - $this->assertArrayHasKey( 'newrevid', $data[0]['edit'] ); - $this->assertNotEquals( - $data[0]['edit']['newrevid'], - $data[0]['edit']['oldrevid'], - "revision id should change after edit" - ); - } - - public function testNonTextEdit() { - $name = 'Dummy:ApiEditPageTest_testNonTextEdit'; - $data = serialize( 'some bla bla text' ); - - // -- test new page -------------------------------------------- - $apiResult = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => $data, ) ); - $apiResult = $apiResult[0]; - - // Validate API result data - $this->assertArrayHasKey( 'edit', $apiResult ); - $this->assertArrayHasKey( 'result', $apiResult['edit'] ); - $this->assertEquals( 'Success', $apiResult['edit']['result'] ); - - $this->assertArrayHasKey( 'new', $apiResult['edit'] ); - $this->assertArrayNotHasKey( 'nochange', $apiResult['edit'] ); - - $this->assertArrayHasKey( 'pageid', $apiResult['edit'] ); - - // validate resulting revision - $page = WikiPage::factory( Title::newFromText( $name ) ); - $this->assertEquals( "testing", $page->getContentModel() ); - $this->assertEquals( $data, $page->getContent()->serialize() ); - } - - public static function provideEditAppend() { - return array( - array( #0: append - 'foo', 'append', 'bar', "foobar" - ), - array( #1: prepend - 'foo', 'prepend', 'bar', "barfoo" - ), - array( #2: append to empty page - '', 'append', 'foo', "foo" - ), - array( #3: prepend to empty page - '', 'prepend', 'foo', "foo" - ), - array( #4: append to non-existing page - null, 'append', 'foo', "foo" - ), - array( #5: prepend to non-existing page - null, 'prepend', 'foo', "foo" - ), - ); - } - - /** - * @dataProvider provideEditAppend - */ - public function testEditAppend( $text, $op, $append, $expected ) { - static $count = 0; - $count++; - - // assume NS_HELP defaults to wikitext - $name = "Help:ApiEditPageTest_testEditAppend_$count"; - - // -- create page (or not) ----------------------------------------- - if ( $text !== null ) { - if ( $text === '' ) { - // can't create an empty page, so create it with some content - $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => '(dummy)', ) ); - } - - list( $re ) = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => $text, ) ); - - $this->assertEquals( 'Success', $re['edit']['result'] ); // sanity - } - - // -- try append/prepend -------------------------------------------- - list( $re ) = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - $op . 'text' => $append, ) ); - - $this->assertEquals( 'Success', $re['edit']['result'] ); - - // -- validate ----------------------------------------------------- - $page = new WikiPage( Title::newFromText( $name ) ); - $content = $page->getContent(); - $this->assertNotNull( $content, 'Page should have been created' ); - - $text = $content->getNativeData(); - - $this->assertEquals( $expected, $text ); - } - - /** - * 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' ); - } - } - - /** - * 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" ); - } - - public function testEditConflict() { - static $count = 0; - $count++; - - // assume NS_HELP defaults to wikitext - $name = "Help:ApiEditPageTest_testEditConflict_$count"; - $title = Title::newFromText( $name ); - - $page = WikiPage::factory( $title ); - - // base edit - $page->doEditContent( new WikitextContent( "Foo" ), - "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); - $this->forceRevisionDate( $page, '20120101000000' ); - $baseTime = $page->getRevision()->getTimestamp(); - - // conflicting edit - $page->doEditContent( new WikitextContent( "Foo bar" ), - "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); - $this->forceRevisionDate( $page, '20120101020202' ); - - // try to save edit, expect conflict - try { - $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => 'nix bar!', - 'basetimestamp' => $baseTime, - ), null, self::$users['sysop']->user ); - - $this->fail( 'edit conflict expected' ); - } catch ( UsageException $ex ) { - $this->assertEquals( 'editconflict', $ex->getCodeString() ); - } - } - - public function testEditConflict_redirect() { - static $count = 0; - $count++; - - // assume NS_HELP defaults to wikitext - $name = "Help:ApiEditPageTest_testEditConflict_redirect_$count"; - $title = Title::newFromText( $name ); - $page = WikiPage::factory( $title ); - - $rname = "Help:ApiEditPageTest_testEditConflict_redirect_r$count"; - $rtitle = Title::newFromText( $rname ); - $rpage = WikiPage::factory( $rtitle ); - - // base edit for content - $page->doEditContent( new WikitextContent( "Foo" ), - "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); - $this->forceRevisionDate( $page, '20120101000000' ); - $baseTime = $page->getRevision()->getTimestamp(); - - // base edit for redirect - $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ), - "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); - $this->forceRevisionDate( $rpage, '20120101000000' ); - - // conflicting edit to redirect - $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]\n\n[[Category:Test]]" ), - "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); - $this->forceRevisionDate( $rpage, '20120101020202' ); - - // try to save edit; should work, because we follow the redirect - list( $re, , ) = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $rname, - 'text' => 'nix bar!', - 'basetimestamp' => $baseTime, - 'redirect' => true, - ), null, self::$users['sysop']->user ); - - $this->assertEquals( 'Success', $re['edit']['result'], - "no edit conflict expected when following redirect" ); - - // try again, without following the redirect. Should fail. - try { - $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $rname, - 'text' => 'nix bar!', - 'basetimestamp' => $baseTime, - ), null, self::$users['sysop']->user ); - - $this->fail( 'edit conflict expected' ); - } catch ( UsageException $ex ) { - $this->assertEquals( 'editconflict', $ex->getCodeString() ); - } - } - - 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' erroneously - * caused an edit conflict to be detected. - */ - - // assume NS_HELP defaults to wikitext - $name = "Help:ApiEditPageTest_testEditConflict_redirect_bug41990_$count"; - $title = Title::newFromText( $name ); - $page = WikiPage::factory( $title ); - - $rname = "Help:ApiEditPageTest_testEditConflict_redirect_bug41990_r$count"; - $rtitle = Title::newFromText( $rname ); - $rpage = WikiPage::factory( $rtitle ); - - // base edit for content - $page->doEditContent( new WikitextContent( "Foo" ), - "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); - $this->forceRevisionDate( $page, '20120101000000' ); - - // base edit for redirect - $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ), - "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); - $this->forceRevisionDate( $rpage, '20120101000000' ); - $baseTime = $rpage->getRevision()->getTimestamp(); - - // new edit to content - $page->doEditContent( new WikitextContent( "Foo bar" ), - "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); - $this->forceRevisionDate( $rpage, '20120101020202' ); - - // try to save edit; should work, following the redirect. - list( $re, , ) = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $rname, - 'text' => 'nix bar!', - 'redirect' => true, - ), null, self::$users['sysop']->user ); - - $this->assertEquals( 'Success', $re['edit']['result'], - "no edit conflict expected here" ); - } - - protected function forceRevisionDate( WikiPage $page, $timestamp ) { - $dbw = wfGetDB( DB_MASTER ); - - $dbw->update( 'revision', - array( 'rev_timestamp' => $dbw->timestamp( $timestamp ) ), - array( 'rev_id' => $page->getLatest() ) ); - - $page->clear(); - } -} diff --git a/tests/phpunit/includes/api/ApiOptionsTest.php b/tests/phpunit/includes/api/ApiOptionsTest.php deleted file mode 100644 index ad1e73ab..00000000 --- a/tests/phpunit/includes/api/ApiOptionsTest.php +++ /dev/null @@ -1,420 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - */ -class ApiOptionsTest extends MediaWikiLangTestCase { - - private $mTested, $mUserMock, $mContext, $mSession; - - private $mOldGetPreferencesHooks = false; - - private static $Success = array( 'options' => 'success' ); - - protected function setUp() { - parent::setUp(); - - $this->mUserMock = $this->getMockBuilder( 'User' ) - ->disableOriginalConstructor() - ->getMock(); - - // 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() ) - ->method( 'getOptionKinds' )->will( $this->returnCallback( array( $this, 'getOptionKinds' ) ) ); - - // Create a new context - $this->mContext = new DerivativeContext( new RequestContext() ); - $this->mContext->getContext()->setTitle( Title::newFromText( 'Test' ) ); - $this->mContext->setUser( $this->mUserMock ); - - $main = new ApiMain( $this->mContext ); - - // Empty session - $this->mSession = array(); - - $this->mTested = new ApiOptions( $main, 'options' ); - - global $wgHooks; - if ( !isset( $wgHooks['GetPreferences'] ) ) { - $wgHooks['GetPreferences'] = array(); - } - $this->mOldGetPreferencesHooks = $wgHooks['GetPreferences']; - $wgHooks['GetPreferences'][] = array( $this, 'hookGetPreferences' ); - } - - protected function tearDown() { - global $wgHooks; - - if ( $this->mOldGetPreferencesHooks !== false ) { - $wgHooks['GetPreferences'] = $this->mOldGetPreferencesHooks; - $this->mOldGetPreferencesHooks = false; - } - - parent::tearDown(); - } - - public function hookGetPreferences( $user, &$preferences ) { - $preferences = array(); - - foreach ( array( 'name', 'willBeNull', 'willBeEmpty', 'willBeHappy' ) as $k ) { - $preferences[$k] = array( - 'type' => 'text', - 'section' => 'test', - 'label' => ' ', - ); - } - - $preferences['testmultiselect'] = array( - 'type' => 'multiselect', - 'options' => array( - 'Test' => array( - '<span dir="auto">Some HTML here for option 1</span>' => 'opt1', - '<span dir="auto">Some HTML here for option 2</span>' => 'opt2', - '<span dir="auto">Some HTML here for option 3</span>' => 'opt3', - '<span dir="auto">Some HTML here for option 4</span>' => 'opt4', - ), - ), - 'section' => 'test', - 'label' => ' ', - 'prefix' => 'testmultiselect-', - 'default' => array(), - ); - - return true; - } - - public function getOptionKinds( IContextSource $context, $options = null ) { - // Match with above. - $kinds = array( - 'name' => 'registered', - 'willBeNull' => 'registered', - 'willBeEmpty' => 'registered', - 'willBeHappy' => 'registered', - 'testmultiselect-opt1' => 'registered-multiselect', - 'testmultiselect-opt2' => 'registered-multiselect', - 'testmultiselect-opt3' => 'registered-multiselect', - 'testmultiselect-opt4' => 'registered-multiselect', - ); - - if ( $options === null ) { - return $kinds; - } - - $mapping = array(); - foreach ( $options as $key => $value ) { - if ( isset( $kinds[$key] ) ) { - $mapping[$key] = $kinds[$key]; - } elseif ( substr( $key, 0, 7 ) === 'userjs-' ) { - $mapping[$key] = 'userjs'; - } else { - $mapping[$key] = 'unused'; - } - } - - return $mapping; - } - - private function getSampleRequest( $custom = array() ) { - $request = array( - 'token' => '123ABC', - 'change' => null, - '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(); - } - - /** - * @expectedException UsageException - */ - public function testNoToken() { - $request = $this->getSampleRequest( array( 'token' => null ) ); - - $this->executeQuery( $request ); - } - - public function testAnon() { - $this->mUserMock->expects( $this->once() ) - ->method( 'isAnon' ) - ->will( $this->returnValue( true ) ); - - try { - $request = $this->getSampleRequest(); - - $this->executeQuery( $request ); - } catch ( UsageException $e ) { - $this->assertEquals( 'notloggedin', $e->getCodeString() ); - $this->assertEquals( 'Anonymous users cannot change preferences', $e->getMessage() ); - - return; - } - $this->fail( "UsageException was not thrown" ); - } - - public function testNoOptionname() { - try { - $request = $this->getSampleRequest( array( 'optionvalue' => '1' ) ); - - $this->executeQuery( $request ); - } 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" ); - } - - public function testNoChanges() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->never() ) - ->method( 'setOption' ); - - $this->mUserMock->expects( $this->never() ) - ->method( 'saveSettings' ); - - try { - $request = $this->getSampleRequest(); - - $this->executeQuery( $request ); - } catch ( UsageException $e ) { - $this->assertEquals( 'nochanges', $e->getCodeString() ); - $this->assertEquals( 'No changes were requested', $e->getMessage() ); - - return; - } - $this->fail( "UsageException was not thrown" ); - } - - public function testReset() { - $this->mUserMock->expects( $this->once() ) - ->method( 'resetOptions' ) - ->with( $this->equalTo( array( 'all' ) ) ); - - $this->mUserMock->expects( $this->never() ) - ->method( 'setOption' ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( 'reset' => '' ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testResetKinds() { - $this->mUserMock->expects( $this->once() ) - ->method( 'resetOptions' ) - ->with( $this->equalTo( array( 'registered' ) ) ); - - $this->mUserMock->expects( $this->never() ) - ->method( 'setOption' ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( 'reset' => '', 'resetkinds' => 'registered' ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testOptionWithValue() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'name' ), $this->equalTo( 'value' ) ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( 'optionname' => 'name', 'optionvalue' => 'value' ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testOptionResetValue() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'name' ), $this->identicalTo( null ) ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( 'optionname' => 'name' ) ); - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testChange() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->at( 2 ) ) - ->method( 'getOptions' ); - - $this->mUserMock->expects( $this->at( 4 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'willBeNull' ), $this->identicalTo( null ) ); - - $this->mUserMock->expects( $this->at( 5 ) ) - ->method( 'getOptions' ); - - $this->mUserMock->expects( $this->at( 6 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'willBeEmpty' ), $this->equalTo( '' ) ); - - $this->mUserMock->expects( $this->at( 7 ) ) - ->method( 'getOptions' ); - - $this->mUserMock->expects( $this->at( 8 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'willBeHappy' ), $this->equalTo( 'Happy' ) ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( 'change' => 'willBeNull|willBeEmpty=|willBeHappy=Happy' ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testResetChangeOption() { - $this->mUserMock->expects( $this->once() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->at( 4 ) ) - ->method( 'getOptions' ); - - $this->mUserMock->expects( $this->at( 5 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'willBeHappy' ), $this->equalTo( 'Happy' ) ); - - $this->mUserMock->expects( $this->at( 6 ) ) - ->method( 'getOptions' ); - - $this->mUserMock->expects( $this->at( 7 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'name' ), $this->equalTo( 'value' ) ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $args = array( - 'reset' => '', - 'change' => 'willBeHappy=Happy', - 'optionname' => 'name', - 'optionvalue' => 'value' - ); - - $response = $this->executeQuery( $this->getSampleRequest( $args ) ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testMultiSelect() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->at( 3 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'testmultiselect-opt1' ), $this->identicalTo( true ) ); - - $this->mUserMock->expects( $this->at( 4 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'testmultiselect-opt2' ), $this->identicalTo( null ) ); - - $this->mUserMock->expects( $this->at( 5 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'testmultiselect-opt3' ), $this->identicalTo( false ) ); - - $this->mUserMock->expects( $this->at( 6 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'testmultiselect-opt4' ), $this->identicalTo( false ) ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( - 'change' => 'testmultiselect-opt1=1|testmultiselect-opt2|testmultiselect-opt3=|testmultiselect-opt4=0' - ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testUnknownOption() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->never() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( - 'change' => 'unknownOption=1' - ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( array( - 'options' => 'success', - 'warnings' => array( - 'options' => array( - '*' => "Validation error for 'unknownOption': not a valid preference" - ) - ) - ), $response ); - } - - public function testUserjsOption() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->at( 3 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'userjs-option' ), $this->equalTo( '1' ) ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( - 'change' => 'userjs-option=1' - ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } -} diff --git a/tests/phpunit/includes/api/ApiParseTest.php b/tests/phpunit/includes/api/ApiParseTest.php deleted file mode 100644 index 2d714e65..00000000 --- a/tests/phpunit/includes/api/ApiParseTest.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - */ -class ApiParseTest extends ApiTestCase { - - protected function setUp() { - parent::setUp(); - $this->doLogin(); - } - - public function testParseNonexistentPage() { - $somePage = mt_rand(); - - try { - $this->doApiRequest( array( - 'action' => 'parse', - 'page' => $somePage ) ); - - $this->fail( "API did not return an error when parsing a nonexistent page" ); - } catch ( UsageException $ex ) { - $this->assertEquals( 'missingtitle', $ex->getCodeString(), - "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 deleted file mode 100644 index 28b5ff4d..00000000 --- a/tests/phpunit/includes/api/ApiPurgeTest.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - */ -class ApiPurgeTest extends ApiTestCase { - - protected function setUp() { - parent::setUp(); - $this->doLogin(); - } - - /** - * @group Broken - */ - public function testPurgeMainPage() { - if ( !Title::newFromText( 'UTPage' )->exists() ) { - $this->markTestIncomplete( "The article [[UTPage]] does not exist" ); - } - - $somePage = mt_rand(); - - $data = $this->doApiRequest( array( - 'action' => 'purge', - 'titles' => 'UTPage|' . $somePage . '|%5D' ) ); - - $this->assertArrayHasKey( 'purge', $data[0], - "Must receive a 'purge' result from API" ); - - $this->assertEquals( 3, count( $data[0]['purge'] ), - "Purge request for three articles should give back three results received: " . var_export( $data[0]['purge'], true ) ); - - $pages = array( 'UTPage' => 'purged', $somePage => 'missing', '%5D' => 'invalid' ); - foreach ( $data[0]['purge'] as $v ) { - $this->assertArrayHasKey( $pages[$v['title']], $v ); - } - } -} diff --git a/tests/phpunit/includes/api/ApiTest.php b/tests/phpunit/includes/api/ApiTest.php deleted file mode 100644 index 472f8c4a..00000000 --- a/tests/phpunit/includes/api/ApiTest.php +++ /dev/null @@ -1,259 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - */ -class ApiTest extends ApiTestCase { - - public function testRequireOnlyOneParameterDefault() { - $mock = new MockApi(); - - $this->assertEquals( - null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt", - "enablechunks" => false ), "filename", "enablechunks" ) ); - } - - /** - * @expectedException UsageException - */ - public function testRequireOnlyOneParameterZero() { - $mock = new MockApi(); - - $this->assertEquals( - null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt", - "enablechunks" => 0 ), "filename", "enablechunks" ) ); - } - - /** - * @expectedException UsageException - */ - public function testRequireOnlyOneParameterTrue() { - $mock = new MockApi(); - - $this->assertEquals( - null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt", - "enablechunks" => true ), "filename", "enablechunks" ) ); - } - - /** - * Test that the API will accept a FauxRequest and execute. The help action - * (default) throws a UsageException. Just validate we're getting proper XML - * - * @expectedException UsageException - */ - public function testApi() { - $api = new ApiMain( - new FauxRequest( array( 'action' => 'help', 'format' => 'xml' ) ) - ); - $api->execute(); - $api->getPrinter()->setBufferResult( true ); - $api->printResult( false ); - $resp = $api->getPrinter()->getBuffer(); - - libxml_use_internal_errors( true ); - $sxe = simplexml_load_string( $resp ); - $this->assertNotInternalType( "bool", $sxe ); - $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); - } - - /** - * Test result of attempted login with an empty username - */ - public function testApiLoginNoName() { - $data = $this->doApiRequest( array( 'action' => 'login', - 'lgname' => '', 'lgpassword' => self::$users['sysop']->password, - ) ); - $this->assertEquals( 'NoName', $data[0]['login']['result'] ); - } - - public function testApiLoginBadPass() { - global $wgServer; - - $user = self::$users['sysop']; - $user->user->logOut(); - - if ( !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' ); - } - $ret = $this->doApiRequest( array( - "action" => "login", - "lgname" => $user->username, - "lgpassword" => "bad", - ) ); - - $result = $ret[0]; - - $this->assertNotInternalType( "bool", $result ); - $a = $result["login"]["result"]; - $this->assertEquals( "NeedToken", $a ); - - $token = $result["login"]["token"]; - - $ret = $this->doApiRequest( - array( - "action" => "login", - "lgtoken" => $token, - "lgname" => $user->username, - "lgpassword" => "badnowayinhell", - ), - $ret[2] - ); - - $result = $ret[0]; - - $this->assertNotInternalType( "bool", $result ); - $a = $result["login"]["result"]; - - $this->assertEquals( "WrongPass", $a ); - } - - public function testApiLoginGoodPass() { - global $wgServer; - - if ( !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' ); - } - - $user = self::$users['sysop']; - $user->user->logOut(); - - $ret = $this->doApiRequest( array( - "action" => "login", - "lgname" => $user->username, - "lgpassword" => $user->password, - ) - ); - - $result = $ret[0]; - $this->assertNotInternalType( "bool", $result ); - $this->assertNotInternalType( "null", $result["login"] ); - - $a = $result["login"]["result"]; - $this->assertEquals( "NeedToken", $a ); - $token = $result["login"]["token"]; - - $ret = $this->doApiRequest( - array( - "action" => "login", - "lgtoken" => $token, - "lgname" => $user->username, - "lgpassword" => $user->password, - ), - $ret[2] - ); - - $result = $ret[0]; - - $this->assertNotInternalType( "bool", $result ); - $a = $result["login"]["result"]; - - $this->assertEquals( "Success", $a ); - } - - /** - * @group Broken - */ - public function testApiGotCookie() { - $this->markTestIncomplete( "The server can't do external HTTP requests, and the internal one won't give cookies" ); - - global $wgServer, $wgScriptPath; - - if ( !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' ); - } - $user = self::$users['sysop']; - - $req = MWHttpRequest::factory( self::$apiUrl . "?action=login&format=xml", - array( "method" => "POST", - "postData" => array( - "lgname" => $user->username, - "lgpassword" => $user->password - ) - ) - ); - $req->execute(); - - libxml_use_internal_errors( true ); - $sxe = simplexml_load_string( $req->getContent() ); - $this->assertNotInternalType( "bool", $sxe ); - $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); - $this->assertNotInternalType( "null", $sxe->login[0] ); - - $a = $sxe->login[0]->attributes()->result[0]; - $this->assertEquals( ' result="NeedToken"', $a->asXML() ); - $token = (string)$sxe->login[0]->attributes()->token; - - $req->setData( array( - "lgtoken" => $token, - "lgname" => $user->username, - "lgpassword" => $user->password ) ); - $req->execute(); - - $cj = $req->getCookieJar(); - $serverName = parse_url( $wgServer, PHP_URL_HOST ); - $this->assertNotEquals( false, $serverName ); - $serializedCookie = $cj->serializeToHttpRequest( $wgScriptPath, $serverName ); - $this->assertNotEquals( '', $serializedCookie ); - $this->assertRegexp( '/_session=[^;]*; .*UserID=[0-9]*; .*UserName=' . $user->userName . '; .*Token=/', $serializedCookie ); - - return $cj; - } - - public function testRunLogin() { - $sysopUser = self::$users['sysop']; - $data = $this->doApiRequest( array( - 'action' => 'login', - 'lgname' => $sysopUser->username, - 'lgpassword' => $sysopUser->password ) ); - - $this->assertArrayHasKey( "login", $data[0] ); - $this->assertArrayHasKey( "result", $data[0]['login'] ); - $this->assertEquals( "NeedToken", $data[0]['login']['result'] ); - $token = $data[0]['login']['token']; - - $data = $this->doApiRequest( array( - 'action' => 'login', - "lgtoken" => $token, - "lgname" => $sysopUser->username, - "lgpassword" => $sysopUser->password ), $data[2] ); - - $this->assertArrayHasKey( "login", $data[0] ); - $this->assertArrayHasKey( "result", $data[0]['login'] ); - $this->assertEquals( "Success", $data[0]['login']['result'] ); - $this->assertArrayHasKey( 'lgtoken', $data[0]['login'] ); - - return $data; - } - - public function testGettingToken() { - foreach ( self::$users as $user ) { - $this->runTokenTest( $user ); - } - } - - function runTokenTest( $user ) { - $tokens = $this->getTokenList( $user ); - - $rights = $user->user->getRights(); - - $this->assertArrayHasKey( 'edittoken', $tokens ); - $this->assertArrayHasKey( 'movetoken', $tokens ); - - if ( isset( $rights['delete'] ) ) { - $this->assertArrayHasKey( 'deletetoken', $tokens ); - } - - if ( isset( $rights['block'] ) ) { - $this->assertArrayHasKey( 'blocktoken', $tokens ); - $this->assertArrayHasKey( 'unblocktoken', $tokens ); - } - - if ( isset( $rights['protect'] ) ) { - $this->assertArrayHasKey( 'protecttoken', $tokens ); - } - - return $tokens; - } -} diff --git a/tests/phpunit/includes/api/ApiTestCase.php b/tests/phpunit/includes/api/ApiTestCase.php deleted file mode 100644 index 94ef9c68..00000000 --- a/tests/phpunit/includes/api/ApiTestCase.php +++ /dev/null @@ -1,253 +0,0 @@ -<?php - -abstract class ApiTestCase extends MediaWikiLangTestCase { - protected static $apiUrl; - - /** - * @var ApiTestContext - */ - protected $apiContext; - - protected function setUp() { - global $wgServer; - - parent::setUp(); - self::$apiUrl = $wgServer . wfScript( 'api' ); - - ApiQueryInfo::resetTokenCache(); // tokens are invalid because we cleared the session - - self::$users = array( - 'sysop' => new TestUser( - 'Apitestsysop', - 'Api Test Sysop', - 'api_test_sysop@example.com', - array( 'sysop' ) - ), - 'uploader' => new TestUser( - 'Apitestuser', - 'Api Test User', - 'api_test_user@example.com', - array() - ) - ); - - $this->setMwGlobals( array( - 'wgMemc' => new EmptyBagOStuff(), - 'wgAuth' => new StubObject( 'wgAuth', 'AuthPlugin' ), - 'wgRequest' => new FauxRequest( array() ), - 'wgUser' => self::$users['sysop']->user, - ) ); - - $this->apiContext = new ApiTestContext(); - } - - /** - * Edits or creates a page/revision - * @param $pageName string page title - * @param $text string content of the page - * @param $summary string optional summary string for the revision - * @param $defaultNs int optional namespace id - * @return array as returned by WikiPage::doEditContent() - */ - 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 ); - } - - /** - * Does the API request and returns the result. - * - * The returned value is an array containing - * - the result data (array) - * - the request (WebRequest) - * - the session data of the request (array) - * - if $appendModule is true, the Api module $module - * - * @param array $params - * @param array|null $session - * @param bool $appendModule - * @param User|null $user - * - * @return array - */ - protected function doApiRequest( array $params, array $session = null, $appendModule = false, User $user = null ) { - global $wgRequest, $wgUser; - - if ( is_null( $session ) ) { - // re-use existing global session by default - $session = $wgRequest->getSessionArray(); - } - - // set up global environment - if ( $user ) { - $wgUser = $user; - } - - $wgRequest = new FauxRequest( $params, true, $session ); - RequestContext::getMain()->setRequest( $wgRequest ); - - // set up local environment - $context = $this->apiContext->newTestContext( $wgRequest, $wgUser ); - - $module = new ApiMain( $context, true ); - - // run it! - $module->execute(); - - // construct result - $results = array( - $module->getResultData(), - $context->getRequest(), - $context->getRequest()->getSessionArray() - ); - - if ( $appendModule ) { - $results[] = $module; - } - - return $results; - } - - /** - * Add an edit token to the API request - * This is cheating a bit -- we grab a token in the correct format and then add it to the pseudo-session and to the - * request, without actually requesting a "real" edit token - * @param $params Array: key-value API params - * @param $session Array|null: session array - * @param $user User|null A User object for the context - * @return result of the API call - * @throws Exception in case wsToken is not set in the session - */ - protected function doApiRequestWithToken( array $params, array $session = null, User $user = null ) { - global $wgRequest; - - if ( $session === null ) { - $session = $wgRequest->getSessionArray(); - } - - if ( $session['wsToken'] ) { - // add edit token to fake session - $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( $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[ $user ]->username, - 'lgpassword' => self::$users[ $user ]->password ) ); - - $token = $data[0]['login']['token']; - - $data = $this->doApiRequest( - array( - 'action' => 'login', - 'lgtoken' => $token, - 'lgname' => self::$users[ $user ]->username, - 'lgpassword' => self::$users[ $user ]->password, - ), - $data[2] - ); - - return $data; - } - - protected function getTokenList( $user, $session = null ) { - $data = $this->doApiRequest( array( - '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() { - $groups = PHPUnit_Util_Test::getGroups( get_class( $this ) ); - $constraint = PHPUnit_Framework_Assert::logicalOr( - $this->contains( 'medium' ), - $this->contains( 'large' ) - ); - $this->assertThat( $groups, $constraint, - 'ApiTestCase::setUp can be slow, tests must be "medium" or "large"' - ); - } -} - -class UserWrapper { - public $userName; - public $password; - public $user; - - public function __construct( $userName, $password, $group = '' ) { - $this->userName = $userName; - $this->password = $password; - - $this->user = User::newFromName( $this->userName ); - if ( !$this->user->getID() ) { - $this->user = User::createNew( $this->userName, array( - "email" => "test@example.com", - "real_name" => "Test User" ) ); - } - $this->user->setPassword( $this->password ); - - if ( $group !== '' ) { - $this->user->addGroup( $group ); - } - $this->user->saveSettings(); - } -} - -class MockApi extends ApiBase { - public function execute() { - } - - public function getVersion() { - } - - public function __construct() { - } - - public function getAllowedParams() { - return array( - 'filename' => null, - 'enablechunks' => false, - 'sessionkey' => null, - ); - } -} - -class ApiTestContext extends RequestContext { - - /** - * Returns a DerivativeContext with the request variables in place - * - * @param $request WebRequest request object including parameters and session - * @param $user User or null - * @return DerivativeContext - */ - public function newTestContext( WebRequest $request, User $user = null ) { - $context = new DerivativeContext( $this ); - $context->setRequest( $request ); - if ( $user !== null ) { - $context->setUser( $user ); - } - - return $context; - } -} diff --git a/tests/phpunit/includes/api/ApiTestCaseUpload.php b/tests/phpunit/includes/api/ApiTestCaseUpload.php deleted file mode 100644 index 7e18b6ed..00000000 --- a/tests/phpunit/includes/api/ApiTestCaseUpload.php +++ /dev/null @@ -1,149 +0,0 @@ -<?php - -/** - * * Abstract class to support upload tests - */ - -abstract class ApiTestCaseUpload extends ApiTestCase { - /** - * Fixture -- run before every test - */ - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgEnableUploads' => true, - 'wgEnableAPI' => true, - ) ); - - wfSetupSession(); - - $this->clearFakeUploads(); - } - - protected function tearDown() { - $this->clearTempUpload(); - - parent::tearDown(); - } - - /** - * Helper function -- remove files and associated articles by Title - * @param $title Title: title to be removed - */ - public function deleteFileByTitle( $title ) { - if ( $title->exists() ) { - $file = wfFindFile( $title, array( 'ignoreRedirect' => true ) ); - $noOldArchive = ""; // yes this really needs to be set this way - $comment = "removing for test"; - $restrictDeletedVersions = false; - $status = FileDeleteForm::doDelete( $title, $file, $noOldArchive, $comment, $restrictDeletedVersions ); - if ( !$status->isGood() ) { - return false; - } - $page = WikiPage::factory( $title ); - $page->doDeleteArticle( "removing for test" ); - - // see if it now doesn't exist; reload - $title = Title::newFromText( $title->getText(), NS_FILE ); - } - - return !( $title && $title instanceof Title && $title->exists() ); - } - - /** - * Helper function -- remove files and associated articles with a particular filename - * @param $fileName String: filename to be removed - */ - public function deleteFileByFileName( $fileName ) { - return $this->deleteFileByTitle( Title::newFromText( $fileName, NS_FILE ) ); - } - - /** - * Helper function -- given a file on the filesystem, find matching content in the db (and associated articles) and remove them. - * @param $filePath String: path to file on the filesystem - */ - public function deleteFileByContent( $filePath ) { - $hash = FSFile::getSha1Base36FromPath( $filePath ); - $dupes = RepoGroup::singleton()->findBySha1( $hash ); - $success = true; - foreach ( $dupes as $dupe ) { - $success &= $this->deleteFileByTitle( $dupe->getTitle() ); - } - - return $success; - } - - /** - * Fake an upload by dumping the file into temp space, and adding info to $_FILES. - * (This is what PHP would normally do). - * @param $fieldName String: name this would have in the upload form - * @param $fileName String: name to title this - * @param $type String: mime type - * @param $filePath String: path where to find file contents - */ - function fakeUploadFile( $fieldName, $fileName, $type, $filePath ) { - $tmpName = tempnam( wfTempDir(), "" ); - if ( !file_exists( $filePath ) ) { - throw new Exception( "$filePath doesn't exist!" ); - } - - if ( !copy( $filePath, $tmpName ) ) { - throw new Exception( "couldn't copy $filePath to $tmpName" ); - } - - clearstatcache(); - $size = filesize( $tmpName ); - if ( $size === false ) { - throw new Exception( "couldn't stat $tmpName" ); - } - - $_FILES[$fieldName] = array( - 'name' => $fileName, - 'type' => $type, - 'tmp_name' => $tmpName, - 'size' => $size, - 'error' => null - ); - - return true; - } - - function fakeUploadChunk( $fieldName, $fileName, $type, & $chunkData ) { - $tmpName = tempnam( wfTempDir(), "" ); - // copy the chunk data to temp location: - if ( !file_put_contents( $tmpName, $chunkData ) ) { - throw new Exception( "couldn't copy chunk data to $tmpName" ); - } - - clearstatcache(); - $size = filesize( $tmpName ); - if ( $size === false ) { - throw new Exception( "couldn't stat $tmpName" ); - } - - $_FILES[$fieldName] = array( - 'name' => $fileName, - 'type' => $type, - 'tmp_name' => $tmpName, - 'size' => $size, - 'error' => null - ); - } - - function clearTempUpload() { - if ( isset( $_FILES['file']['tmp_name'] ) ) { - $tmp = $_FILES['file']['tmp_name']; - if ( file_exists( $tmp ) ) { - unlink( $tmp ); - } - } - } - - /** - * Remove traces of previous fake uploads - */ - function clearFakeUploads() { - $_FILES = array(); - } -} diff --git a/tests/phpunit/includes/api/ApiUploadTest.php b/tests/phpunit/includes/api/ApiUploadTest.php deleted file mode 100644 index 1540af55..00000000 --- a/tests/phpunit/includes/api/ApiUploadTest.php +++ /dev/null @@ -1,561 +0,0 @@ -<?php - -/** - * @group API - * @group Database - */ - -/** - * n.b. Ensure that you can write to the images/ directory as the - * user that will run tests. - */ - -// Note for reviewers: this intentionally duplicates functionality already in "ApiSetup" and so on. -// This framework works better IMO and has less strangeness (such as test cases inheriting from "ApiSetup"...) -// (and in the case of the other Upload tests, this flat out just actually works... ) - -// TODO: port the other Upload tests, and other API tests to this framework - -require_once 'ApiTestCaseUpload.php'; - -/** - * @group Database - * @group Broken - * Broken test, reports false errors from time to time. - * See https://bugzilla.wikimedia.org/26169 - * - * This is pretty sucky... needs to be prettified. - */ -class ApiUploadTest extends ApiTestCaseUpload { - /** - * Testing login - * XXX this is a funny way of getting session context - */ - public function testLogin() { - $user = self::$users['uploader']; - - $params = array( - 'action' => 'login', - 'lgname' => $user->username, - 'lgpassword' => $user->password - ); - list( $result, , $session ) = $this->doApiRequest( $params ); - $this->assertArrayHasKey( "login", $result ); - $this->assertArrayHasKey( "result", $result['login'] ); - $this->assertEquals( "NeedToken", $result['login']['result'] ); - $token = $result['login']['token']; - - $params = array( - 'action' => 'login', - 'lgtoken' => $token, - 'lgname' => $user->username, - 'lgpassword' => $user->password - ); - list( $result, , $session ) = $this->doApiRequest( $params, $session ); - $this->assertArrayHasKey( "login", $result ); - $this->assertArrayHasKey( "result", $result['login'] ); - $this->assertEquals( "Success", $result['login']['result'] ); - $this->assertArrayHasKey( 'lgtoken', $result['login'] ); - - $this->assertNotEmpty( $session, 'API Login must return a session' ); - - return $session; - } - - /** - * @depends testLogin - */ - public function testUploadRequiresToken( $session ) { - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload' - ) ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "The token parameter must be set", $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - } - - /** - * @depends testLogin - */ - public function testUploadMissingParams( $session ) { - $exception = false; - try { - $this->doApiRequestWithToken( array( - 'action' => 'upload', - ), $session, self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "One of the parameters filekey, file, url, statuskey is required", - $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - } - - - /** - * @depends testLogin - */ - public function testUpload( $session ) { - $extension = 'png'; - $mimeType = 'image/png'; - - try { - $randomImageGenerator = new RandomImageGenerator(); - $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() ); - } catch ( Exception $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - - $filePath = $filePaths[0]; - $fileSize = filesize( $filePath ); - $fileName = basename( $filePath ); - - $this->deleteFileByFileName( $fileName ); - $this->deleteFileByContent( $filePath ); - - if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $params = array( - 'action' => 'upload', - 'filename' => $fileName, - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName", - ); - - $exception = false; - try { - list( $result, , ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertEquals( $fileSize, (int)$result['upload']['imageinfo']['size'] ); - $this->assertEquals( $mimeType, $result['upload']['imageinfo']['mime'] ); - $this->assertFalse( $exception ); - - // clean up - $this->deleteFileByFilename( $fileName ); - unlink( $filePath ); - } - - - /** - * @depends testLogin - */ - public function testUploadZeroLength( $session ) { - $mimeType = 'image/png'; - - $filePath = tempnam( wfTempDir(), "" ); - $fileName = "apiTestUploadZeroLength.png"; - - $this->deleteFileByFileName( $fileName ); - - if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $params = array( - 'action' => 'upload', - 'filename' => $fileName, - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName", - ); - - $exception = false; - try { - $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $this->assertContains( 'The file you submitted was empty', $e->getMessage() ); - $exception = true; - } - $this->assertTrue( $exception ); - - // clean up - $this->deleteFileByFilename( $fileName ); - unlink( $filePath ); - } - - - /** - * @depends testLogin - */ - public function testUploadSameFileName( $session ) { - $extension = 'png'; - $mimeType = 'image/png'; - - try { - $randomImageGenerator = new RandomImageGenerator(); - $filePaths = $randomImageGenerator->writeImages( 2, $extension, wfTempDir() ); - } catch ( Exception $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - - // we'll reuse this filename - $fileName = basename( $filePaths[0] ); - - // clear any other files with the same name - $this->deleteFileByFileName( $fileName ); - - // we reuse these params - $params = array( - 'action' => 'upload', - 'filename' => $fileName, - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName", - ); - - // first upload .... should succeed - - if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePaths[0] ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $exception = false; - try { - list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertFalse( $exception ); - - // second upload with the same name (but different content) - - if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePaths[1] ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $exception = false; - try { - list( $result, , ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); // FIXME: leaks a temporary file - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Warning', $result['upload']['result'] ); - $this->assertTrue( isset( $result['upload']['warnings'] ) ); - $this->assertTrue( isset( $result['upload']['warnings']['exists'] ) ); - $this->assertFalse( $exception ); - - // clean up - $this->deleteFileByFilename( $fileName ); - unlink( $filePaths[0] ); - unlink( $filePaths[1] ); - } - - - /** - * @depends testLogin - */ - public function testUploadSameContent( $session ) { - $extension = 'png'; - $mimeType = 'image/png'; - - try { - $randomImageGenerator = new RandomImageGenerator(); - $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() ); - } catch ( Exception $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - - $fileNames[0] = basename( $filePaths[0] ); - $fileNames[1] = "SameContentAs" . $fileNames[0]; - - // clear any other files with the same name or content - $this->deleteFileByContent( $filePaths[0] ); - $this->deleteFileByFileName( $fileNames[0] ); - $this->deleteFileByFileName( $fileNames[1] ); - - // first upload .... should succeed - - $params = array( - 'action' => 'upload', - 'filename' => $fileNames[0], - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for " . $fileNames[0], - ); - - if ( !$this->fakeUploadFile( 'file', $fileNames[0], $mimeType, $filePaths[0] ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $exception = false; - try { - list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $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] ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $params = array( - 'action' => 'upload', - 'filename' => $fileNames[1], - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for " . $fileNames[1], - ); - - $exception = false; - try { - list( $result ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); // FIXME: leaks a temporary file - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Warning', $result['upload']['result'] ); - $this->assertTrue( isset( $result['upload']['warnings'] ) ); - $this->assertTrue( isset( $result['upload']['warnings']['duplicate'] ) ); - $this->assertFalse( $exception ); - - // clean up - $this->deleteFileByFilename( $fileNames[0] ); - $this->deleteFileByFilename( $fileNames[1] ); - unlink( $filePaths[0] ); - } - - /** - * @depends testLogin - */ - public function testUploadStash( $session ) { - $this->setMwGlobals( array( - 'wgUser' => self::$users['uploader']->user, // @todo FIXME: still used somewhere - ) ); - - $extension = 'png'; - $mimeType = 'image/png'; - - try { - $randomImageGenerator = new RandomImageGenerator(); - $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() ); - } catch ( Exception $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - - $filePath = $filePaths[0]; - $fileSize = filesize( $filePath ); - $fileName = basename( $filePath ); - - $this->deleteFileByFileName( $fileName ); - $this->deleteFileByContent( $filePath ); - - if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $params = array( - 'action' => 'upload', - 'stash' => 1, - 'filename' => $fileName, - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName", - ); - - $exception = false; - try { - list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); // FIXME: leaks a temporary file - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertFalse( $exception ); - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Success', $result['upload']['result'] ); - $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'] ); - $filekey = $result['upload']['filekey']; - - // it should be visible from Special:UploadStash - // XXX ...but how to test this, with a fake WebRequest with the session? - - // now we should try to release the file from stash - $params = array( - 'action' => 'upload', - 'filekey' => $filekey, - 'filename' => $fileName, - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName, altered", - ); - - $this->clearFakeUploads(); - $exception = false; - try { - list( $result ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertFalse( $exception, "No UsageException exception." ); - - // clean up - $this->deleteFileByFilename( $fileName ); - unlink( $filePath ); - } - - /** - * @depends testLogin - */ - public function testUploadChunks( $session ) { - $this->setMwGlobals( array( - 'wgUser' => self::$users['uploader']->user, // @todo FIXME: still used somewhere - ) ); - - $chunkSize = 1048576; - // Download a large image file - // ( using RandomImageGenerator for large files is not stable ) - $mimeType = 'image/jpeg'; - $url = 'http://upload.wikimedia.org/wikipedia/commons/e/ed/Oberaargletscher_from_Oberaar%2C_2010_07.JPG'; - $filePath = wfTempDir() . '/Oberaargletscher_from_Oberaar.jpg'; - try { - // Only download if the file is not avaliable in the temp location: - if ( !is_file( $filePath ) ) { - copy( $url, $filePath ); - } - } catch ( Exception $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - - $fileSize = filesize( $filePath ); - $fileName = basename( $filePath ); - - $this->deleteFileByFileName( $fileName ); - $this->deleteFileByContent( $filePath ); - - // Base upload params: - $params = array( - 'action' => 'upload', - 'stash' => 1, - 'filename' => $fileName, - 'filesize' => $fileSize, - 'offset' => 0, - ); - - // Upload chunks - $chunkSessionKey = false; - $resultOffset = 0; - // Open the file: - $handle = @fopen( $filePath, "r" ); - if ( $handle === false ) { - $this->markTestIncomplete( "could not open file: $filePath" ); - } - while ( !feof( $handle ) ) { - // Get the current chunk - $chunkData = @fread( $handle, $chunkSize ); - - // Upload the current chunk into the $_FILE object: - $this->fakeUploadChunk( 'chunk', 'blob', $mimeType, $chunkData ); - - // Check for chunkSessionKey - if ( !$chunkSessionKey ) { - // Upload fist chunk ( and get the session key ) - try { - 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: - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertTrue( isset( $result['upload']['filekey'] ) ); - // If we don't get a session key mark test incomplete. - if ( !isset( $result['upload']['filekey'] ) ) { - $this->markTestIncomplete( "no filekey provided" ); - } - $chunkSessionKey = $result['upload']['filekey']; - $this->assertEquals( 'Continue', $result['upload']['result'] ); - // First chunk should have chunkSize == offset - $this->assertEquals( $chunkSize, $result['upload']['offset'] ); - $resultOffset = $result['upload']['offset']; - continue; - } - // Filekey set to chunk session - $params['filekey'] = $chunkSessionKey; - // Update the offset ( always add chunkSize for subquent chunks should be in-sync with $result['upload']['offset'] ) - $params['offset'] += $chunkSize; - // Make sure param offset is insync with resultOffset: - $this->assertEquals( $resultOffset, $params['offset'] ); - // Upload current chunk - try { - 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: - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertTrue( isset( $result['upload']['filekey'] ) ); - - // Check if we were on the last chunk: - if ( $params['offset'] + $chunkSize >= $fileSize ) { - $this->assertEquals( 'Success', $result['upload']['result'] ); - break; - } else { - $this->assertEquals( 'Continue', $result['upload']['result'] ); - // update $resultOffset - $resultOffset = $result['upload']['offset']; - } - } - fclose( $handle ); - - // Check that we got a valid file result: - wfDebug( __METHOD__ . " hohoh filesize {$fileSize} info {$result['upload']['imageinfo']['size']}\n\n" ); - $this->assertEquals( $fileSize, $result['upload']['imageinfo']['size'] ); - $this->assertEquals( $mimeType, $result['upload']['imageinfo']['mime'] ); - $this->assertTrue( isset( $result['upload']['filekey'] ) ); - $filekey = $result['upload']['filekey']; - - // Now we should try to release the file from stash - $params = array( - 'action' => 'upload', - 'filekey' => $filekey, - 'filename' => $fileName, - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName, altered", - ); - $this->clearFakeUploads(); - $exception = false; - try { - list( $result ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertFalse( $exception ); - - // clean up - $this->deleteFileByFilename( $fileName ); - // 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 deleted file mode 100644 index 028ea9ff..00000000 --- a/tests/phpunit/includes/api/ApiWatchTest.php +++ /dev/null @@ -1,148 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - * @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() { - return $this->getTokenList( self::$users['sysop'] ); - } - - /** - */ - public function testWatchEdit() { - $tokens = $this->getTokens(); - - $data = $this->doApiRequest( array( - 'action' => 'edit', - 'title' => 'Help:UTPage', // Help namespace is hopefully wikitext - 'text' => 'new text', - 'token' => $tokens['edittoken'], - 'watchlist' => 'watch' ) ); - $this->assertArrayHasKey( 'edit', $data[0] ); - $this->assertArrayHasKey( 'result', $data[0]['edit'] ); - $this->assertEquals( 'Success', $data[0]['edit']['result'] ); - - return $data; - } - - /** - * @depends testWatchEdit - */ - public function testWatchClear() { - $tokens = $this->getTokens(); - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'list' => 'watchlist' ) ); - - if ( isset( $data[0]['query']['watchlist'] ) ) { - $wl = $data[0]['query']['watchlist']; - - foreach ( $wl as $page ) { - $data = $this->doApiRequest( array( - 'action' => 'watch', - 'title' => $page['title'], - 'unwatch' => true, - 'token' => $tokens['watchtoken'] ) ); - } - } - $data = $this->doApiRequest( array( - 'action' => 'query', - 'list' => 'watchlist' ), $data ); - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'watchlist', $data[0]['query'] ); - $this->assertEquals( 0, count( $data[0]['query']['watchlist'] ) ); - - return $data; - } - - /** - */ - public function testWatchProtect() { - $tokens = $this->getTokens(); - - $data = $this->doApiRequest( array( - 'action' => 'protect', - 'token' => $tokens['protecttoken'], - 'title' => 'Help:UTPage', - 'protections' => 'edit=sysop', - 'watchlist' => 'unwatch' ) ); - - $this->assertArrayHasKey( 'protect', $data[0] ); - $this->assertArrayHasKey( 'protections', $data[0]['protect'] ); - $this->assertEquals( 1, count( $data[0]['protect']['protections'] ) ); - $this->assertArrayHasKey( 'edit', $data[0]['protect']['protections'][0] ); - } - - /** - */ - public function testGetRollbackToken() { - $this->getTokens(); - - if ( !Title::newFromText( 'Help:UTPage' )->exists() ) { - $this->markTestSkipped( "The article [[Help:UTPage]] does not exist" ); //TODO: just create it? - } - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'prop' => 'revisions', - 'titles' => 'Help:UTPage', - 'rvtoken' => 'rollback' ) ); - - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'pages', $data[0]['query'] ); - $keys = array_keys( $data[0]['query']['pages'] ); - $key = array_pop( $keys ); - - if ( isset( $data[0]['query']['pages'][$key]['missing'] ) ) { - $this->markTestSkipped( "Target page (Help:UTPage) doesn't exist" ); - } - - $this->assertArrayHasKey( 'pageid', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 'revisions', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 0, $data[0]['query']['pages'][$key]['revisions'] ); - $this->assertArrayHasKey( 'rollbacktoken', $data[0]['query']['pages'][$key]['revisions'][0] ); - - return $data; - } - - /** - * @group Broken - * Broken because there is currently no revision info in the $pageinfo - * - * @depends testGetRollbackToken - */ - public function testWatchRollback( $data ) { - $keys = array_keys( $data[0]['query']['pages'] ); - $key = array_pop( $keys ); - $pageinfo = $data[0]['query']['pages'][$key]; - $revinfo = $pageinfo['revisions'][0]; - - try { - $data = $this->doApiRequest( array( - 'action' => 'rollback', - 'title' => 'Help:UTPage', - 'user' => $revinfo['user'], - 'token' => $pageinfo['rollbacktoken'], - 'watchlist' => 'watch' ) ); - - $this->assertArrayHasKey( 'rollback', $data[0] ); - $this->assertArrayHasKey( 'title', $data[0]['rollback'] ); - } catch ( UsageException $ue ) { - if ( $ue->getCodeString() == 'onlyauthor' ) { - $this->markTestIncomplete( "Only one author to 'Help:UTPage', cannot test rollback" ); - } else { - $this->fail( "Received error '" . $ue->getCodeString() . "'" ); - } - } - } -} diff --git a/tests/phpunit/includes/api/PrefixUniquenessTest.php b/tests/phpunit/includes/api/PrefixUniquenessTest.php deleted file mode 100644 index d9be85e3..00000000 --- a/tests/phpunit/includes/api/PrefixUniquenessTest.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php - -/** - * Checks that all API query modules, core and extensions, have unique prefixes. - * - * @group API - */ -class PrefixUniquenessTest extends MediaWikiTestCase { - public function testPrefixes() { - $main = new ApiMain( new FauxRequest() ); - $query = new ApiQuery( $main, 'foo', 'bar' ); - $modules = $query->getModuleManager()->getNamesWithClasses(); - $prefixes = array(); - - foreach ( $modules as $name => $class ) { - $module = new $class( $main, $name ); - $prefix = $module->getModulePrefix(); - if ( isset( $prefixes[$prefix] ) ) { - $this->fail( "Module prefix '{$prefix}' is shared between {$class} and {$prefixes[$prefix]}" ); - } - $prefixes[$module->getModulePrefix()] = $class; - } - $this->assertTrue( true ); // dummy call to make this test non-incomplete - } -} diff --git a/tests/phpunit/includes/api/RandomImageGenerator.php b/tests/phpunit/includes/api/RandomImageGenerator.php deleted file mode 100644 index 59756b21..00000000 --- a/tests/phpunit/includes/api/RandomImageGenerator.php +++ /dev/null @@ -1,468 +0,0 @@ -<?php - -/** - * RandomImageGenerator -- does what it says on the tin. - * Requires Imagick, the ImageMagick library for PHP, or the command line equivalent (usually 'convert'). - * - * Because MediaWiki tests the uniqueness of media upload content, and filenames, it is sometimes useful to generate - * files that are guaranteed (or at least very likely) to be unique in both those ways. - * This generates a number of filenames with random names and random content (colored triangles) - * - * It is also useful to have fresh content because our tests currently run in a "destructive" mode, and don't create a fresh new wiki for each - * test run. - * Consequently, if we just had a few static files we kept re-uploading, we'd get lots of warnings about matching content or filenames, - * and even if we deleted those files, we'd get warnings about archived files. - * - * This can also be used with a cronjob to generate random files all the time -- I use it to have a constant, never ending supply when I'm - * testing interactively. - * - * @file - * @author Neil Kandalgaonkar <neilk@wikimedia.org> - */ - -/** - * RandomImageGenerator: does what it says on the tin. - * Can fetch a random image, or also write a number of them to disk with random filenames. - */ -class RandomImageGenerator { - - private $dictionaryFile; - private $minWidth = 400; - private $maxWidth = 800; - private $minHeight = 400; - private $maxHeight = 800; - private $shapesToDraw = 5; - - /** - * 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) - */ - private static $orientations = array( - array( - '0thRow' => 'top', - '0thCol' => 'left', - 'exifCode' => 1, - 'counterRotation' => array( array( 1, 0 ), array( 0, 1 ) ) - ), - array( - '0thRow' => 'bottom', - '0thCol' => 'right', - 'exifCode' => 3, - 'counterRotation' => array( array( -1, 0 ), array( 0, -1 ) ) - ), - array( - '0thRow' => 'right', - '0thCol' => 'top', - 'exifCode' => 6, - 'counterRotation' => array( array( 0, 1 ), array( 1, 0 ) ) - ), - array( - '0thRow' => 'left', - '0thCol' => 'bottom', - 'exifCode' => 8, - 'counterRotation' => array( array( 0, -1 ), array( -1, 0 ) ) - ) - ); - - - public function __construct( $options = array() ) { - foreach ( array( 'dictionaryFile', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight', 'shapesToDraw' ) as $property ) { - if ( isset( $options[$property] ) ) { - $this->$property = $options[$property]; - } - } - - // find the dictionary file, to generate random names - if ( !isset( $this->dictionaryFile ) ) { - foreach ( - array( - '/usr/share/dict/words', - '/usr/dict/words', - __DIR__ . '/words.txt' - ) as $dictionaryFile - ) { - if ( is_file( $dictionaryFile ) and is_readable( $dictionaryFile ) ) { - $this->dictionaryFile = $dictionaryFile; - break; - } - } - } - if ( !isset( $this->dictionaryFile ) ) { - throw new Exception( "RandomImageGenerator: dictionary file not found or not specified properly" ); - } - } - - /** - * Writes random images with random filenames to disk in the directory you specify, or current working directory - * - * @param $number Integer: number of filenames to write - * @param $format String: optional, must be understood by ImageMagick, such as 'jpg' or 'gif' - * @param $dir String: directory, optional (will default to current working directory) - * @return Array: filenames we just wrote - */ - function writeImages( $number, $format = 'jpg', $dir = null ) { - $filenames = $this->getRandomFilenames( $number, $format, $dir ); - $imageWriteMethod = $this->getImageWriteMethod( $format ); - foreach ( $filenames as $filename ) { - $this->{$imageWriteMethod}( $this->getImageSpec(), $format, $filename ); - } - - return $filenames; - } - - - /** - * Figure out how we write images. This is a factor of both format and the local system - * @param $format (a typical extension like 'svg', 'jpg', etc.) - */ - function getImageWriteMethod( $format ) { - global $wgUseImageMagick, $wgImageMagickConvertCommand; - if ( $format === 'svg' ) { - return 'writeSvg'; - } else { - // figure out how to write images - global $wgExiv2Command; - if ( class_exists( 'Imagick' ) && $wgExiv2Command && is_executable( $wgExiv2Command ) ) { - return 'writeImageWithApi'; - } elseif ( $wgUseImageMagick && $wgImageMagickConvertCommand && is_executable( $wgImageMagickConvertCommand ) ) { - return 'writeImageWithCommandLine'; - } - } - throw new Exception( "RandomImageGenerator: could not find a suitable method to write images in '$format' format" ); - } - - /** - * Return a number of randomly-generated filenames - * Each filename uses two words randomly drawn from the dictionary, like elephantine_spatula.jpg - * - * @param $number Integer: of filenames to generate - * @param $extension String: optional, defaults to 'jpg' - * @param $dir String: optional, defaults to current working directory - * @return Array: of filenames - */ - private function getRandomFilenames( $number, $extension = 'jpg', $dir = null ) { - if ( is_null( $dir ) ) { - $dir = getcwd(); - } - $filenames = array(); - foreach ( $this->getRandomWordPairs( $number ) as $pair ) { - $basename = $pair[0] . '_' . $pair[1]; - if ( !is_null( $extension ) ) { - $basename .= '.' . $extension; - } - $basename = preg_replace( '/\s+/', '', $basename ); - $filenames[] = "$dir/$basename"; - } - - return $filenames; - } - - - /** - * Generate data representing an image of random size (within limits), - * consisting of randomly colored and sized upward pointing triangles against a random background color - * (This data is used in the writeImage* methods). - * @return {Mixed} - */ - public function getImageSpec() { - $spec = array(); - - $spec['width'] = mt_rand( $this->minWidth, $this->maxWidth ); - $spec['height'] = mt_rand( $this->minHeight, $this->maxHeight ); - $spec['fill'] = $this->getRandomColor(); - - $diagonalLength = sqrt( pow( $spec['width'], 2 ) + pow( $spec['height'], 2 ) ); - - $draws = array(); - for ( $i = 0; $i <= $this->shapesToDraw; $i++ ) { - $radius = mt_rand( 0, $diagonalLength / 4 ); - if ( $radius == 0 ) { - continue; - } - $originX = mt_rand( -1 * $radius, $spec['width'] + $radius ); - $originY = mt_rand( -1 * $radius, $spec['height'] + $radius ); - $angle = mt_rand( 0, ( 3.141592 / 2 ) * $radius ) / $radius; - $legDeltaX = round( $radius * sin( $angle ) ); - $legDeltaY = round( $radius * cos( $angle ) ); - - $draw = array(); - $draw['fill'] = $this->getRandomColor(); - $draw['shape'] = array( - array( 'x' => $originX, 'y' => $originY - $radius ), - array( 'x' => $originX + $legDeltaX, 'y' => $originY + $legDeltaY ), - array( 'x' => $originX - $legDeltaX, 'y' => $originY + $legDeltaY ), - array( 'x' => $originX, 'y' => $originY - $radius ) - ); - $draws[] = $draw; - } - - $spec['draws'] = $draws; - - return $spec; - } - - /** - * Given array( array('x' => 10, 'y' => 20), array( 'x' => 30, y=> 5 ) ) - * returns "10,20 30,5" - * Useful for SVG and imagemagick command line arguments - * @param $shape: Array of arrays, each array containing x & y keys mapped to numeric values - * @return string - */ - static function shapePointsToString( $shape ) { - $points = array(); - foreach ( $shape as $point ) { - $points[] = $point['x'] . ',' . $point['y']; - } - - return join( " ", $points ); - } - - /** - * Based on image specification, write a very simple SVG file to disk. - * Ignores the background spec because transparency is cool. :) - * @param $spec: spec describing background and shapes to draw - * @param $format: file format to write (which is obviously always svg here) - * @param $filename: filename to write to - */ - public function writeSvg( $spec, $format, $filename ) { - $svg = new SimpleXmlElement( '<svg/>' ); - $svg->addAttribute( 'xmlns', 'http://www.w3.org/2000/svg' ); - $svg->addAttribute( 'version', '1.1' ); - $svg->addAttribute( 'width', $spec['width'] ); - $svg->addAttribute( 'height', $spec['height'] ); - $g = $svg->addChild( 'g' ); - foreach ( $spec['draws'] as $drawSpec ) { - $shape = $g->addChild( 'polygon' ); - $shape->addAttribute( 'fill', $drawSpec['fill'] ); - $shape->addAttribute( 'points', self::shapePointsToString( $drawSpec['shape'] ) ); - } - - if ( !$fh = fopen( $filename, 'w' ) ) { - throw new Exception( "couldn't open $filename for writing" ); - } - fwrite( $fh, $svg->asXML() ); - if ( !fclose( $fh ) ) { - throw new Exception( "couldn't close $filename" ); - } - } - - /** - * Based on an image specification, write such an image to disk, using Imagick PHP extension - * @param $spec: spec describing background and circles to draw - * @param $format: file format to write - * @param $filename: filename to write to - */ - public function writeImageWithApi( $spec, $format, $filename ) { - // this is a hack because I can't get setImageOrientation() to work. See below. - global $wgExiv2Command; - - $image = new Imagick(); - /** - * If the format is 'jpg', will also add a random orientation -- the image will be drawn rotated with triangle points - * facing in some direction (0, 90, 180 or 270 degrees) and a countering rotation should turn the triangle points upward again - */ - $orientation = self::$orientations[0]; // default is normal orientation - if ( $format == 'jpg' ) { - $orientation = self::$orientations[array_rand( self::$orientations )]; - $spec = self::rotateImageSpec( $spec, $orientation['counterRotation'] ); - } - - $image->newImage( $spec['width'], $spec['height'], new ImagickPixel( $spec['fill'] ) ); - - foreach ( $spec['draws'] as $drawSpec ) { - $draw = new ImagickDraw(); - $draw->setFillColor( $drawSpec['fill'] ); - $draw->polygon( $drawSpec['shape'] ); - $image->drawImage( $draw ); - } - - $image->setImageFormat( $format ); - - // this doesn't work, even though it's documented to do so... - // $image->setImageOrientation( $orientation['exifCode'] ); - - $image->writeImage( $filename ); - - // because the above setImageOrientation call doesn't work... nor can I get an external imagemagick binary to do this either... - // hacking this for now (only works if you have exiv2 installed, a program to read and manipulate exif) - if ( $wgExiv2Command ) { - $cmd = wfEscapeShellArg( $wgExiv2Command ) - . " -M " - . wfEscapeShellArg( "set Exif.Image.Orientation " . $orientation['exifCode'] ) - . " " - . wfEscapeShellArg( $filename ); - - $retval = 0; - $err = wfShellExec( $cmd, $retval ); - if ( $retval !== 0 ) { - print "Error with $cmd: $retval, $err\n"; - } - } - } - - /** - * Given an image specification, produce rotated version - * 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 - */ - private static function rotateImageSpec( &$spec, $matrix ) { - $tSpec = array(); - $dims = self::matrixMultiply2x2( $matrix, $spec['width'], $spec['height'] ); - $correctionX = 0; - $correctionY = 0; - if ( $dims['x'] < 0 ) { - $correctionX = abs( $dims['x'] ); - } - if ( $dims['y'] < 0 ) { - $correctionY = abs( $dims['y'] ); - } - $tSpec['width'] = abs( $dims['x'] ); - $tSpec['height'] = abs( $dims['y'] ); - $tSpec['fill'] = $spec['fill']; - $tSpec['draws'] = array(); - foreach ( $spec['draws'] as $draw ) { - $tDraw = array( - 'fill' => $draw['fill'], - 'shape' => array() - ); - foreach ( $draw['shape'] as $point ) { - $tPoint = self::matrixMultiply2x2( $matrix, $point['x'], $point['y'] ); - $tPoint['x'] += $correctionX; - $tPoint['y'] += $correctionY; - $tDraw['shape'][] = $tPoint; - } - $tSpec['draws'][] = $tDraw; - } - - return $tSpec; - } - - /** - * Given a matrix and a pair of images, return new position - * @param $matrix: 2x2 rotation matrix - * @param $x: x-coordinate number - * @param $y: y-coordinate number - * @return Array transformed with properties x, y - */ - private static function matrixMultiply2x2( $matrix, $x, $y ) { - return array( - 'x' => $x * $matrix[0][0] + $y * $matrix[0][1], - 'y' => $x * $matrix[1][0] + $y * $matrix[1][1] - ); - } - - - /** - * Based on an image specification, write such an image to disk, using the command line ImageMagick program ('convert'). - * - * Sample command line: - * $ convert -size 100x60 xc:rgb(90,87,45) \ - * -draw 'fill rgb(12,34,56) polygon 41,39 44,57 50,57 41,39' \ - * -draw 'fill rgb(99,123,231) circle 59,39 56,57' \ - * -draw 'fill rgb(240,12,32) circle 50,21 50,3' filename.png - * - * @param $spec: spec describing background and shapes to draw - * @param $format: file format to write (unused by this method but kept so it has the same signature as writeImageWithApi) - * @param $filename: filename to write to - */ - public function writeImageWithCommandLine( $spec, $format, $filename ) { - global $wgImageMagickConvertCommand; - $args = array(); - $args[] = "-size " . wfEscapeShellArg( $spec['width'] . 'x' . $spec['height'] ); - $args[] = wfEscapeShellArg( "xc:" . $spec['fill'] ); - foreach ( $spec['draws'] as $draw ) { - $fill = $draw['fill']; - $polygon = self::shapePointsToString( $draw['shape'] ); - $drawCommand = "fill $fill polygon $polygon"; - $args[] = '-draw ' . wfEscapeShellArg( $drawCommand ); - } - $args[] = wfEscapeShellArg( $filename ); - - $command = wfEscapeShellArg( $wgImageMagickConvertCommand ) . " " . implode( " ", $args ); - $retval = null; - wfShellExec( $command, $retval ); - - return ( $retval === 0 ); - } - - /** - * Generate a string of random colors for ImageMagick or SVG, like "rgb(12, 37, 98)" - * - * @return {String} - */ - public function getRandomColor() { - $components = array(); - for ( $i = 0; $i <= 2; $i++ ) { - $components[] = mt_rand( 0, 255 ); - } - - return 'rgb(' . join( ', ', $components ) . ')'; - } - - /** - * Get an array of random pairs of random words, like array( array( 'foo', 'bar' ), array( 'quux', 'baz' ) ); - * - * @param $number Integer: number of pairs - * @return Array: of two-element arrays - */ - private function getRandomWordPairs( $number ) { - $lines = $this->getRandomLines( $number * 2 ); - // construct pairs of words - $pairs = array(); - $count = count( $lines ); - for ( $i = 0; $i < $count; $i += 2 ) { - $pairs[] = array( $lines[$i], $lines[$i + 1] ); - } - - return $pairs; - } - - /** - * Return N random lines from a file - * - * Will throw exception if the file could not be read or if it had fewer lines than requested. - * - * @param $number_desired Integer: number of lines desired - * @return Array: of exactly n elements, drawn randomly from lines the file - */ - private function getRandomLines( $number_desired ) { - $filepath = $this->dictionaryFile; - - // initialize array of lines - $lines = array(); - for ( $i = 0; $i < $number_desired; $i++ ) { - $lines[] = null; - } - - /* - * This algorithm obtains N random lines from a file in one single pass. It does this by replacing elements of - * a fixed-size array of lines, less and less frequently as it reads the file. - */ - $fh = fopen( $filepath, "r" ); - if ( !$fh ) { - throw new Exception( "couldn't open $filepath" ); - } - $line_number = 0; - $max_index = $number_desired - 1; - while ( !feof( $fh ) ) { - $line = fgets( $fh ); - if ( $line !== false ) { - $line_number++; - $line = trim( $line ); - if ( mt_rand( 0, $line_number ) <= $max_index ) { - $lines[mt_rand( 0, $max_index )] = $line; - } - } - } - fclose( $fh ); - if ( $line_number < $number_desired ) { - throw new Exception( "not enough lines in $filepath" ); - } - - return $lines; - } -} diff --git a/tests/phpunit/includes/api/format/ApiFormatPhpTest.php b/tests/phpunit/includes/api/format/ApiFormatPhpTest.php deleted file mode 100644 index a0bbb2dc..00000000 --- a/tests/phpunit/includes/api/format/ApiFormatPhpTest.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - */ -class ApiFormatPhpTest extends ApiFormatTestBase { - - 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/format/ApiFormatTestBase.php b/tests/phpunit/includes/api/format/ApiFormatTestBase.php deleted file mode 100644 index 153f2cf4..00000000 --- a/tests/phpunit/includes/api/format/ApiFormatTestBase.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php - -abstract class ApiFormatTestBase extends ApiTestCase { - protected function apiRequest( $format, $params, $data = null ) { - $data = parent::doApiRequest( $params, $data, true ); - - $module = $data[3]; - - $printer = $module->createPrinterByName( $format ); - $printer->setUnescapeAmps( false ); - - $printer->initPrinter( false ); - - ob_start(); - $printer->execute(); - $out = ob_get_clean(); - - $printer->closePrinter(); - - return $out; - } -} diff --git a/tests/phpunit/includes/api/generateRandomImages.php b/tests/phpunit/includes/api/generateRandomImages.php deleted file mode 100644 index 87f5c4c0..00000000 --- a/tests/phpunit/includes/api/generateRandomImages.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -/** - * Bootstrapping for test image file generation - * - * @file - */ - -// Start up MediaWiki in command-line mode -require_once __DIR__ . "/../../../../maintenance/Maintenance.php"; -require __DIR__ . "/RandomImageGenerator.php"; - -class GenerateRandomImages extends Maintenance { - - public function getDbType() { - return Maintenance::DB_NONE; - } - - public function execute() { - - $getOptSpec = array( - 'dictionaryFile::', - 'minWidth::', - 'maxWidth::', - 'minHeight::', - 'maxHeight::', - 'shapesToDraw::', - 'shape::', - - 'number::', - 'format::' - ); - $options = getopt( null, $getOptSpec ); - - $format = isset( $options['format'] ) ? $options['format'] : 'jpg'; - unset( $options['format'] ); - - $number = isset( $options['number'] ) ? intval( $options['number'] ) : 10; - unset( $options['number'] ); - - $randomImageGenerator = new RandomImageGenerator( $options ); - $randomImageGenerator->writeImages( $number, $format ); - } -} - -$maintClass = 'GenerateRandomImages'; -require RUN_MAINTENANCE_IF_MAIN; diff --git a/tests/phpunit/includes/api/query/ApiQueryBasicTest.php b/tests/phpunit/includes/api/query/ApiQueryBasicTest.php deleted file mode 100644 index 1a2aa832..00000000 --- a/tests/phpunit/includes/api/query/ApiQueryBasicTest.php +++ /dev/null @@ -1,395 +0,0 @@ -<?php -/** - * - * - * Created on Feb 6, 2013 - * - * Copyright © 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - */ - -require_once 'ApiQueryTestBase.php'; - -/** These tests validate basic functionality of the api query module - * - * @group API - * @group Database - * @group medium - */ -class ApiQueryBasicTest extends ApiQueryTestBase { - /** - * Create a set of pages. These must not change, otherwise the tests might give wrong results. - * @see MediaWikiTestCase::addDBData() - */ - function addDBData() { - try { - if ( Title::newFromText( 'AQBT-All' )->exists() ) { - return; - } - - // Ordering is important, as it will be returned in the same order as stored in the index - $this->editPage( 'AQBT-All', '[[Category:AQBT-Cat]] [[AQBT-Links]] {{AQBT-T}}' ); - $this->editPage( 'AQBT-Categories', '[[Category:AQBT-Cat]]' ); - $this->editPage( 'AQBT-Links', '[[AQBT-All]] [[AQBT-Categories]] [[AQBT-Templates]]' ); - $this->editPage( 'AQBT-Templates', '{{AQBT-T}}' ); - $this->editPage( 'AQBT-T', 'Content', '', NS_TEMPLATE ); - - // Refresh due to the bug with listing transclusions as links if they don't exist - $this->editPage( 'AQBT-All', '[[Category:AQBT-Cat]] [[AQBT-Links]] {{AQBT-T}}' ); - $this->editPage( 'AQBT-Templates', '{{AQBT-T}}' ); - } catch ( Exception $e ) { - $this->exceptionFromAddDBData = $e; - } - } - - private static $links = array( - array( 'prop' => 'links', 'titles' => 'AQBT-All' ), - array( 'pages' => array( - '1' => array( - 'pageid' => 1, - 'ns' => 0, - 'title' => 'AQBT-All', - 'links' => array( - array( 'ns' => 0, 'title' => 'AQBT-Links' ), - ) - ) - ) ) - ); - - private static $templates = array( - array( 'prop' => 'templates', 'titles' => 'AQBT-All' ), - array( 'pages' => array( - '1' => array( - 'pageid' => 1, - 'ns' => 0, - 'title' => 'AQBT-All', - 'templates' => array( - array( 'ns' => 10, 'title' => 'Template:AQBT-T' ), - ) - ) - ) ) - ); - - private static $categories = array( - array( 'prop' => 'categories', 'titles' => 'AQBT-All' ), - array( 'pages' => array( - '1' => array( - 'pageid' => 1, - 'ns' => 0, - 'title' => 'AQBT-All', - 'categories' => array( - array( 'ns' => 14, 'title' => 'Category:AQBT-Cat' ), - ) - ) - ) ) - ); - - private static $allpages = array( - array( 'list' => 'allpages', 'apprefix' => 'AQBT-' ), - array( 'allpages' => array( - array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ), - 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-' ), - array( 'alllinks' => array( - array( 'ns' => 0, 'title' => 'AQBT-All' ), - 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-' ), - array( 'pages' => array( - '1' => array( - 'pageid' => 1, - 'ns' => 0, - 'title' => 'AQBT-All' ), - '2' => array( - 'pageid' => 2, - 'ns' => 0, - 'title' => 'AQBT-Categories' ), - '3' => array( - 'pageid' => 3, - 'ns' => 0, - 'title' => 'AQBT-Links' ), - '4' => array( - 'pageid' => 4, - 'ns' => 0, - 'title' => 'AQBT-Templates' ), - ) ) - ); - - private static $generatorLinks = array( - array( 'generator' => 'links', 'titles' => 'AQBT-Links' ), - array( 'pages' => array( - '1' => array( - 'pageid' => 1, - 'ns' => 0, - 'title' => 'AQBT-All' ), - '2' => array( - 'pageid' => 2, - 'ns' => 0, - 'title' => 'AQBT-Categories' ), - '4' => array( - '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' ), - array( 'pages' => array( - '1' => array( 'templates' => array( - array( 'ns' => 10, 'title' => 'Template:AQBT-T' ) ) ), - '4' => array( 'templates' => array( - array( 'ns' => 10, 'title' => 'Template:AQBT-T' ) ) ), - ) ) - ); - - /** - * Test basic props - */ - public function testProps() { - $this->check( self::$links ); - $this->check( self::$templates ); - $this->check( self::$categories ); - } - - /** - * Test basic lists - */ - public function testLists() { - $this->check( self::$allpages ); - $this->check( self::$alllinks ); - $this->check( self::$alltransclusions ); - // This test is temporarily disabled until a sqlite bug is fixed - // $this->check( self::$allcategories ); - $this->check( self::$backlinks ); - $this->check( self::$embeddedin ); - $this->check( self::$categorymembers ); - } - - /** - * Test basic lists - */ - public function testAllTogether() { - - // All props together - $this->check( $this->merge( - self::$links, - self::$templates, - self::$categories - ) ); - - // All lists together - $this->check( $this->merge( - self::$allpages, - self::$alllinks, - self::$alltransclusions, - // This test is temporarily disabled until a sqlite bug is fixed - // self::$allcategories, - self::$backlinks, - self::$embeddedin, - self::$categorymembers - ) ); - - // All props+lists together - $this->check( $this->merge( - self::$links, - self::$templates, - self::$categories, - self::$allpages, - self::$alllinks, - self::$alltransclusions, - // This test is temporarily disabled until a sqlite bug is fixed - // self::$allcategories, - self::$backlinks, - self::$embeddedin, - self::$categorymembers - ) ); - } - - /** - * Test basic lists - */ - public function testGenerator() { - // generator=allpages - $this->check( self::$generatorAllpages ); - // generator=allpages & list=allpages - $this->check( $this->merge( - self::$generatorAllpages, - self::$allpages ) ); - // generator=links - $this->check( self::$generatorLinks ); - // generator=links & prop=links - $this->check( $this->merge( - self::$generatorLinks, - self::$generatorLinksPropLinks ) ); - // generator=links & prop=templates - $this->check( $this->merge( - self::$generatorLinks, - self::$generatorLinksPropTemplates ) ); - // generator=links & prop=links|templates - $this->check( $this->merge( - self::$generatorLinks, - self::$generatorLinksPropLinks, - self::$generatorLinksPropTemplates ) ); - // generator=links & prop=links|templates & list=allpages|... - $this->check( $this->merge( - self::$generatorLinks, - self::$generatorLinksPropLinks, - self::$generatorLinksPropTemplates, - self::$allpages, - self::$alllinks, - self::$alltransclusions, - // This test is temporarily disabled until a sqlite bug is fixed - // self::$allcategories, - self::$backlinks, - self::$embeddedin, - self::$categorymembers ) ); - } - - /** - * 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 ) { - foreach ( $item as $k => $v ) { - if ( array_key_exists( $k, $all ) ) { - if ( is_array( $all[$k] ) ) { - $this->mergeExpected( $all[$k], $v ); - } else { - $this->assertEquals( $all[$k], $v ); - } - } else { - $all[$k] = $v; - } - } - } - - /** - * Recursively compare arrays, ignoring mismatches in numeric key and pageids. - * @param $expected array expected values - * @param $result array returned values - */ - private function assertQueryResults( $expected, $result ) { - reset( $expected ); - reset( $result ); - while ( true ) { - $e = each( $expected ); - $r = each( $result ); - // If either of the arrays is shorter, abort. If both are done, success. - $this->assertEquals( (bool)$e, (bool)$r ); - if ( !$e ) { - break; // done - } - // continue only if keys are identical or both keys are numeric - $this->assertTrue( $e['key'] === $r['key'] || ( is_numeric( $e['key'] ) && is_numeric( $r['key'] ) ) ); - // don't compare pageids - if ( $e['key'] !== 'pageid' ) { - // If values are arrays, compare recursively, otherwise compare with === - if ( is_array( $e['value'] ) && is_array( $r['value'] ) ) { - $this->assertQueryResults( $e['value'], $r['value'] ); - } else { - $this->assertEquals( $e['value'], $r['value'] ); - } - } - } - } -} diff --git a/tests/phpunit/includes/api/query/ApiQueryContinue2Test.php b/tests/phpunit/includes/api/query/ApiQueryContinue2Test.php deleted file mode 100644 index 4d5ddbae..00000000 --- a/tests/phpunit/includes/api/query/ApiQueryContinue2Test.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php -/** - * Copyright © 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.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 3 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 - */ - -require_once 'ApiQueryContinueTestBase.php'; - -/** - * @group API - * @group Database - * @group medium - */ -class ApiQueryContinue2Test extends ApiQueryContinueTestBase { - /** - * Create a set of pages. These must not change, otherwise the tests might give wrong results. - * @see MediaWikiTestCase::addDBData() - */ - function addDBData() { - try { - $this->editPage( 'AQCT73462-A', '**AQCT73462-A** [[AQCT73462-B]] [[AQCT73462-C]]' ); - $this->editPage( 'AQCT73462-B', '[[AQCT73462-A]] **AQCT73462-B** [[AQCT73462-C]]' ); - $this->editPage( 'AQCT73462-C', '[[AQCT73462-A]] [[AQCT73462-B]] **AQCT73462-C**' ); - $this->editPage( 'AQCT73462-A', '**AQCT73462-A** [[AQCT73462-B]] [[AQCT73462-C]]' ); - $this->editPage( 'AQCT73462-B', '[[AQCT73462-A]] **AQCT73462-B** [[AQCT73462-C]]' ); - $this->editPage( 'AQCT73462-C', '[[AQCT73462-A]] [[AQCT73462-B]] **AQCT73462-C**' ); - } catch ( Exception $e ) { - $this->exceptionFromAddDBData = $e; - } - } - - /** - * @medium - */ - public function testA() { - $this->mVerbose = false; - $mk = function ( $g, $p, $gDir ) { - return array( - 'generator' => 'allpages', - 'gapprefix' => 'AQCT73462-', - 'prop' => 'links', - 'gaplimit' => "$g", - 'pllimit' => "$p", - 'gapdir' => $gDir ? "ascending" : "descending", - ); - }; - // 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' ); - } -} diff --git a/tests/phpunit/includes/api/query/ApiQueryContinueTest.php b/tests/phpunit/includes/api/query/ApiQueryContinueTest.php deleted file mode 100644 index f494e9ca..00000000 --- a/tests/phpunit/includes/api/query/ApiQueryContinueTest.php +++ /dev/null @@ -1,313 +0,0 @@ -<?php -/** - * Copyright © 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -require_once 'ApiQueryContinueTestBase.php'; - -/** - * These tests validate the new continue functionality of the api query module by - * doing multiple requests with varying parameters, merging the results, and checking - * that the result matches the full data received in one no-limits call. - * - * @group API - * @group Database - * @group medium - */ -class ApiQueryContinueTest extends ApiQueryContinueTestBase { - /** - * Create a set of pages. These must not change, otherwise the tests might give wrong results. - * @see MediaWikiTestCase::addDBData() - */ - function addDBData() { - try { - $this->editPage( 'Template:AQCT-T1', '**Template:AQCT-T1**' ); - $this->editPage( 'Template:AQCT-T2', '**Template:AQCT-T2**' ); - $this->editPage( 'Template:AQCT-T3', '**Template:AQCT-T3**' ); - $this->editPage( 'Template:AQCT-T4', '**Template:AQCT-T4**' ); - $this->editPage( 'Template:AQCT-T5', '**Template:AQCT-T5**' ); - - $this->editPage( 'AQCT-1', '**AQCT-1** {{AQCT-T2}} {{AQCT-T3}} {{AQCT-T4}} {{AQCT-T5}}' ); - $this->editPage( 'AQCT-2', '[[AQCT-1]] **AQCT-2** {{AQCT-T3}} {{AQCT-T4}} {{AQCT-T5}}' ); - $this->editPage( 'AQCT-3', '[[AQCT-1]] [[AQCT-2]] **AQCT-3** {{AQCT-T4}} {{AQCT-T5}}' ); - $this->editPage( 'AQCT-4', '[[AQCT-1]] [[AQCT-2]] [[AQCT-3]] **AQCT-4** {{AQCT-T5}}' ); - $this->editPage( 'AQCT-5', '[[AQCT-1]] [[AQCT-2]] [[AQCT-3]] [[AQCT-4]] **AQCT-5**' ); - } catch ( Exception $e ) { - $this->exceptionFromAddDBData = $e; - } - } - - /** - * Test smart continue - list=allpages - * @medium - */ - public function test1List() { - $this->mVerbose = false; - $mk = function ( $l ) { - return array( - 'list' => 'allpages', - 'apprefix' => 'AQCT-', - 'aplimit' => "$l", - ); - }; - $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' ); - } - - /** - * Test smart continue - list=allpages|alltransclusions - * @medium - */ - public function test2Lists() { - $this->mVerbose = false; - $mk = function ( $l1, $l2 ) { - return array( - 'list' => 'allpages|alltransclusions', - 'apprefix' => 'AQCT-', - 'atprefix' => 'AQCT-', - 'atunique' => '', - 'aplimit' => "$l1", - 'atlimit' => "$l2", - ); - }; - // 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' ); - } - - /** - * Test smart continue - generator=allpages, prop=links - * @medium - */ - public function testGen1Prop() { - $this->mVerbose = false; - $mk = function ( $g, $p ) { - return array( - 'generator' => 'allpages', - 'gapprefix' => 'AQCT-', - 'gaplimit' => "$g", - 'prop' => 'links', - 'pllimit' => "$p", - ); - }; - // 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' ); - } - - /** - * Test smart continue - generator=allpages, prop=links|templates - * @medium - */ - public function testGen2Prop() { - $this->mVerbose = false; - $mk = function ( $g, $p1, $p2 ) { - return array( - 'generator' => 'allpages', - 'gapprefix' => 'AQCT-', - 'gaplimit' => "$g", - 'prop' => 'links|templates', - 'pllimit' => "$p1", - 'tllimit' => "$p2", - ); - }; - // 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' ); - } - - /** - * Test smart continue - generator=allpages, prop=links, list=alltransclusions - * @medium - */ - public function testGen1Prop1List() { - $this->mVerbose = false; - $mk = function ( $g, $p, $l ) { - return array( - 'generator' => 'allpages', - 'gapprefix' => 'AQCT-', - 'gaplimit' => "$g", - 'prop' => 'links', - 'pllimit' => "$p", - 'list' => 'alltransclusions', - 'atprefix' => 'AQCT-', - 'atunique' => '', - 'atlimit' => "$l", - ); - }; - // 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' ); - } - - /** - * Test smart continue - generator=allpages, prop=links|templates, - * list=alllinks|alltransclusions, meta=siteinfo - * @medium - */ - public function testGen2Prop2List1Meta() { - $this->mVerbose = false; - $mk = function ( $g, $p1, $p2, $l1, $l2 ) { - return array( - 'generator' => 'allpages', - 'gapprefix' => 'AQCT-', - 'gaplimit' => "$g", - 'prop' => 'links|templates', - 'pllimit' => "$p1", - 'tllimit' => "$p2", - 'list' => 'alllinks|alltransclusions', - 'alprefix' => 'AQCT-', - 'alunique' => '', - 'allimit' => "$l1", - 'atprefix' => 'AQCT-', - 'atunique' => '', - 'atlimit' => "$l2", - 'meta' => 'siteinfo', - 'siprop' => 'namespaces', - ); - }; - // 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' ); - } - - /** - * Test smart continue - generator=templates, prop=templates - * @medium - */ - public function testSameGenAndProp() { - $this->mVerbose = false; - $mk = function ( $g, $gDir, $p, $pDir ) { - return array( - 'titles' => 'AQCT-1', - 'generator' => 'templates', - 'gtllimit' => "$g", - 'gtldir' => $gDir ? 'ascending' : 'descending', - 'prop' => 'templates', - 'tllimit' => "$p", - 'tldir' => $pDir ? 'ascending' : 'descending', - ); - }; - // generator + 1 prop - $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, 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, 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' ); - } - - /** - * Test smart continue - generator=allpages, list=allpages - * @medium - */ - public function testSameGenList() { - $this->mVerbose = false; - $mk = function ( $g, $gDir, $l, $pDir ) { - return array( - 'generator' => 'allpages', - 'gapprefix' => 'AQCT-', - 'gaplimit' => "$g", - 'gapdir' => $gDir ? 'ascending' : 'descending', - 'list' => 'allpages', - 'apprefix' => 'AQCT-', - 'aplimit' => "$l", - 'apdir' => $pDir ? 'ascending' : 'descending', - ); - }; - // generator + 1 list - $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' ); - } -} diff --git a/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php b/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php deleted file mode 100644 index fbb1e640..00000000 --- a/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php +++ /dev/null @@ -1,209 +0,0 @@ -<?php -/** - * - * - * Created on Jan 1, 2013 - * - * Copyright © 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - */ - -require_once 'ApiQueryTestBase.php'; - -abstract class ApiQueryContinueTestBase extends ApiQueryTestBase { - - /** - * Enable to print in-depth debugging info during the test run - */ - protected $mVerbose = false; - - /** - * Run query() and compare against expected values - */ - protected function checkC( $expected, $params, $expectedCount, $id, $continue = true ) { - $result = $this->query( $params, $expectedCount, $id, $continue ); - $this->assertResult( $expected, $result, $id ); - } - - /** - * Run query in a loop until no more values are available - * @param array $params api parameters - * @param int $expectedCount max number of iterations - * @param string $id unit test id - * @param boolean $useContinue true to use smart continue - * @return mixed: merged results data array - * @throws Exception - */ - protected function query( $params, $expectedCount, $id, $useContinue = true ) { - if ( isset( $params['action'] ) ) { - $this->assertEquals( 'query', $params['action'], 'Invalid query action' ); - } else { - $params['action'] = 'query'; - } - if ( $useContinue && !isset( $params['continue'] ) ) { - $params['continue'] = ''; - } - $count = 0; - $result = array(); - $continue = array(); - do { - $request = array_merge( $params, $continue ); - 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"; - } - try { - $data = $this->doApiRequest( $request ); - } catch ( Exception $e ) { - throw new Exception( "$id on $count", 0, $e ); - } - $data = $data[0]; - if ( isset( $data['warnings'] ) ) { - $warnings = json_encode( $data['warnings'] ); - $this->fail( "$id Warnings on #$count in $reqStr\n$warnings" ); - } - $this->assertArrayHasKey( 'query', $data, "$id no 'query' on #$count in $reqStr" ); - if ( isset( $data['continue'] ) ) { - $continue = $data['continue']; - unset( $data['continue'] ); - } else { - $continue = array(); - } - if ( $this->mVerbose ) { - $this->printResult( $data ); - } - $this->mergeResult( $result, $data ); - $count++; - if ( empty( $continue ) ) { - // $this->assertEquals( $expectedCount, $count, "$id finished early" ); - 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 ); - } - - private function printResult( $data ) { - $q = $data['query']; - $print = array(); - if ( isset( $q['pages'] ) ) { - foreach ( $q['pages'] as $p ) { - $m = $p['title']; - if ( isset( $p['links'] ) ) { - $m .= '/[' . implode( ',', array_map( - function ( $v ) { - return $v['title']; - }, - $p['links'] ) ) . ']'; - } - if ( isset( $p['categories'] ) ) { - $m .= '/(' . implode( ',', array_map( - function ( $v ) { - return str_replace( 'Category:', '', $v['title'] ); - }, - $p['categories'] ) ) . ')'; - } - $print[] = $m; - } - } - 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"; - } - - private static function GetItems( $q, $moduleName, $name, &$print ) { - if ( isset( $q[$moduleName] ) ) { - $print[] = "*$name/[" . implode( ',', - array_map( function ( $v ) { - return $v['title']; - }, - $q[$moduleName] ) ) . ']'; - } - } - - /** - * Recursively merge the new result returned from the query to the previous results. - * @param mixed $results - * @param mixed $newResult - * @param bool $numericIds If true, treat keys as ids to be merged instead of appending - */ - protected function mergeResult( &$results, $newResult, $numericIds = false ) { - $this->assertEquals( is_array( $results ), is_array( $newResult ), 'Type of result and data do not match' ); - if ( !is_array( $results ) ) { - $this->assertEquals( $results, $newResult, 'Repeated result must be the same as before' ); - } else { - $sort = null; - 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 ) { - return strcmp( $a['title'], $b['title'] ); - }; - } else { - $sort = false; - } - } - $keyExists = array_key_exists( $key, $results ); - if ( is_numeric( $key ) ) { - if ( $numericIds ) { - if ( !$keyExists ) { - $results[$key] = $value; - } else { - $this->mergeResult( $results[$key], $value ); - } - } else { - $results[] = $value; - } - } elseif ( !$keyExists ) { - $results[$key] = $value; - } else { - $this->mergeResult( $results[$key], $value, $key === 'pages' ); - } - } - if ( $numericIds ) { - ksort( $results, SORT_NUMERIC ); - } elseif ( $sort !== null && $sort !== false ) { - uasort( $results, $sort ); - } - } - } -} diff --git a/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php b/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php deleted file mode 100644 index 1bca2256..00000000 --- a/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - */ -class ApiQueryRevisionsTest extends ApiTestCase { - - /** - * @group medium - */ - public function testContentComesWithContentModelAndFormat() { - $pageName = 'Help:' . __METHOD__; - $title = Title::newFromText( $pageName ); - $page = WikiPage::factory( $title ); - $page->doEdit( 'Some text', 'inserting content' ); - - $apiResult = $this->doApiRequest( array( - 'action' => 'query', - 'prop' => 'revisions', - 'titles' => $pageName, - 'rvprop' => 'content', - ) ); - $this->assertArrayHasKey( 'query', $apiResult[0] ); - $this->assertArrayHasKey( 'pages', $apiResult[0]['query'] ); - foreach ( $apiResult[0]['query']['pages'] as $page ) { - $this->assertArrayHasKey( 'revisions', $page ); - foreach ( $page['revisions'] as $revision ) { - $this->assertArrayHasKey( 'contentformat', $revision, - 'contentformat should be included when asking content so client knows how to interpret it' - ); - $this->assertArrayHasKey( 'contentmodel', $revision, - 'contentmodel should be included when asking content so client knows how to interpret it' - ); - } - } - } -} diff --git a/tests/phpunit/includes/api/query/ApiQueryTest.php b/tests/phpunit/includes/api/query/ApiQueryTest.php deleted file mode 100644 index f5645555..00000000 --- a/tests/phpunit/includes/api/query/ApiQueryTest.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - */ -class ApiQueryTest extends ApiTestCase { - - protected function setUp() { - parent::setUp(); - $this->doLogin(); - } - - public function testTitlesGetNormalized() { - - global $wgMetaNamespace; - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'titles' => 'Project:articleA|article_B' ) ); - - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'normalized', $data[0]['query'] ); - - // Forge a normalized title - $to = Title::newFromText( $wgMetaNamespace . ':ArticleA' ); - - $this->assertEquals( - array( - 'from' => 'Project:articleA', - 'to' => $to->getPrefixedText(), - ), - $data[0]['query']['normalized'][0] - ); - - $this->assertEquals( - array( - 'from' => 'article_B', - 'to' => 'Article B' - ), - $data[0]['query']['normalized'][1] - ); - } - - public function testTitlesAreRejectedIfInvalid() { - $title = false; - while ( !$title || Title::newFromText( $title )->exists() ) { - $title = md5( mt_rand( 0, 10000 ) + rand( 0, 999000 ) ); - } - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'titles' => $title . '|Talk:' ) ); - - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'pages', $data[0]['query'] ); - $this->assertEquals( 2, count( $data[0]['query']['pages'] ) ); - - $this->assertArrayHasKey( -2, $data[0]['query']['pages'] ); - $this->assertArrayHasKey( -1, $data[0]['query']['pages'] ); - - $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 deleted file mode 100644 index 8ee8ea96..00000000 --- a/tests/phpunit/includes/api/query/ApiQueryTestBase.php +++ /dev/null @@ -1,150 +0,0 @@ -<?php -/** - * - * - * Created on Feb 10, 2013 - * - * Copyright © 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.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 3 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 - */ - -/** This class has some common functionality for testing query module - */ -abstract class ApiQueryTestBase extends ApiTestCase { - - const PARAM_ASSERT = <<<STR -Each parameter must be an array of two elements, -first - an array of params to the API call, -and the second array - expected results as returned by the API -STR; - - /** - * Merges all requests parameter + expected values into one - * @param ... list of arrays, each of which contains exactly two - * @return array - */ - protected function merge( /*...*/ ) { - $request = array(); - $expected = array(); - 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 ); - } - - /** - * Check that the parameter is a valid two element array, - * with the first element being API request and the second - expected result - */ - private function validateRequestExpectedPair( $v ) { - $this->assertType( 'array', $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; - } - - /** - * Recursively merges the expected values in the $item into the $all - */ - private function mergeExpected( &$all, $item ) { - foreach ( $item as $k => $v ) { - if ( array_key_exists( $k, $all ) ) { - if ( is_array( $all[$k] ) ) { - $this->mergeExpected( $all[$k], $v ); - } else { - $this->assertEquals( $all[$k], $v ); - } - } else { - $all[$k] = $v; - } - } - } - - /** - * Checks that the request's result matches the expected results. - * @param $values array is a two element array( request, expected_results ) - * @throws Exception - */ - protected function check( $values ) { - list( $req, $exp ) = $this->validateRequestExpectedPair( $values ); - if ( !array_key_exists( 'action', $req ) ) { - $req['action'] = 'query'; - } - foreach ( $req as &$val ) { - if ( is_array( $val ) ) { - $val = implode( '|', array_unique( $val ) ); - } - } - $result = $this->doApiRequest( $req ); - $this->assertResult( array( 'query' => $exp ), $result[0], $req ); - } - - protected function assertResult( $exp, $result, $message = '' ) { - try { - $this->assertResultRecursive( $exp, $result ); - } catch ( Exception $e ) { - if ( is_array( $message ) ) { - $message = http_build_query( $message ); - } - print "\nRequest: $message\n"; - print "\nExpected:\n"; - print_r( $exp ); - print "\nResult:\n"; - print_r( $result ); - throw $e; // rethrow it - } - } - - /** - * Recursively compare arrays, ignoring mismatches in numeric key and pageids. - * @param $expected array expected values - * @param $result array returned values - */ - private function assertResultRecursive( $expected, $result ) { - reset( $expected ); - reset( $result ); - while ( true ) { - $e = each( $expected ); - $r = each( $result ); - // If either of the arrays is shorter, abort. If both are done, success. - $this->assertEquals( (bool)$e, (bool)$r ); - if ( !$e ) { - break; // done - } - // continue only if keys are identical or both keys are numeric - $this->assertTrue( $e['key'] === $r['key'] || ( is_numeric( $e['key'] ) && is_numeric( $r['key'] ) ) ); - // don't compare pageids - if ( $e['key'] !== 'pageid' ) { - // If values are arrays, compare recursively, otherwise compare with === - if ( is_array( $e['value'] ) && is_array( $r['value'] ) ) { - $this->assertResultRecursive( $e['value'], $r['value'] ); - } else { - $this->assertEquals( $e['value'], $r['value'] ); - } - } - } - } -} diff --git a/tests/phpunit/includes/api/words.txt b/tests/phpunit/includes/api/words.txt deleted file mode 100644 index 7ce23ee3..00000000 --- a/tests/phpunit/includes/api/words.txt +++ /dev/null @@ -1,1000 +0,0 @@ -Andaquian -Anoplanthus -Araquaju -Astrophyton -Avarish -Batonga -Bdellidae -Betoyan -Bismarck -Britishness -Carmen -Chatillon -Clement -Coryphaena -Croton -Cyrillianism -Dagomba -Decimus -Dichorisandra -Duculinae -Empusa -Escallonia -Fathometer -Fon -Fundulinae -Gadswoons -Gederathite -Gemini -Gerbera -Gregarinida -Gyracanthus -Halopsychidae -Hasidim -Hemerobius -Ichthyosauridae -Iscariot -Jeames -Jesuitry -Jovian -Judaization -Katie -Ladin -Langhian -Lapithaean -Lisette -Macrochira -Malaxis -Malvastrum -Maranhao -Marxian -Maurist -Metrosideros -Micky -Microsporon -Odacidae -Ophiuchid -Osmorhiza -Paguma -Palesman -Papayaceae -Pastinaca -Philoxenian -Pleurostigma -Rarotongan -Rhodoraceae -Rong -Saho -Sanyakoan -Sardanapalian -Sauropoda -Sedentaria -Shambu -Shukulumbwe -Solonian -Spaniardization -Spirochaetaceae -Stomatopoda -Stratiotes -Taiwanhemp -Titanically -Venetianed -Victrola -Yuman -abatis -abaton -abjoint -acanthoma -acari -acceptance -actinography -acuteness -addiment -adelite -adelomorphic -adelphogamy -adipocele -aelurophobia -affined -aflaunt -agathokakological -aischrolatreia -alarmedly -alebench -aleurone -allelotropic -allerion -alloplastic -allowable -alternacy -alternariose -altricial -ambitionist -amendment -amiableness -amicableness -ammo -amortizable -anchorate -anemometrically -angelocracy -angelological -anodal -anomalure -antedate -antiagglutinin -antirationalist -antiscorbutic -antisplasher -antithesize -antiunionist -antoecian -apolegamic -appropriation -archididascalian -archival -arteriophlebotomy -articulable -asseveration -assignation -atelo -atrienses -atrophy -atterminement -atypic -automower -aveloz -awrist -azteca -bairnteam -balsamweed -bannerman -beardy -becry -beek -beggarwise -bescab -bestness -bethel -bewildering -bibliophilism -bitterblain -blakeberyed -boccarella -bocedization -boobyalla -bourbon -bowbent -bowerbird -brachygnathous -brail -branchiferous -brelaw -brew -brideweed -bridgeable -brombenzamide -buddler -burbankian -burr -buskin -cacochymical -calefactory -caliper -canaliculus -candidature -canellaceous -canniness -canning -cantilene -carbonatation -carthamic -caseum -caudated -causationist -ceruleite -chalder -chalta -charmel -chekan -chillness -chirogymnast -chirpling -chlorinous -cholanthrene -chondroblast -chromatography -chromophilous -chronical -cicatrice -cinchonine -city -clubbing -coastal -coaxially -coercible -coeternity -coff -coinventor -collyba -combinator -complanation -comprehensibility -conchuela -congenital -context -contranatural -corallum -cordately -cornupete -corolliferous -coroneted -corticosterone -coseat -cottage -crocetin -crossleted -crottels -curvedness -cycadeous -cyclism -cylindrically -cynanche -cyrtoceratitic -cystospasm -danceress -dancette -dawny -daydreamy -debar -decarburization -decorousness -decrepitness -delirious -deozonizer -dermatosis -desma -deutencephalic -diacetate -diarthrodial -diathermy -dicolic -dimastigate -dimidiation -dipetto -disavowable -disintrench -disman -dismay -disorder -disoxygenation -dithionous -dogman -dragonfly -dramatical -drawspan -drubbly -drunk -duskly -ecderonic -ectocuniform -ectocyst -ehrwaldite -electrocute -elemicin -embracing -emotionality -enactment -enamor -enclave -endameba -endochylous -endocrinologist -endolymph -endothecal -entasia -epigeous -episcopicide -epitrichial -erminee -erraticalness -eruptivity -erythrocytoschisis -esperance -estuous -eucrystalline -eugeny -evacuant -everbloomer -evocation -exarchateship -exasperate -excorticate -excrementary -exile -expandedly -exponency -expressionist -expulsion -extemporary -extollation -extortive -extrabulbar -extraprostatic -facticide -fairer -fakery -fasibitikite -fatiscent -fearless -febrifuge -ferie -fibrousness -fingered -fisheye -flagpole -flagrantness -fleche -fluidism -folliculin -footbreadth -forceps -forecontrive -forthbring -foveated -fuchsin -fungicidal -funori -gamelang -gametically -garvanzo -gasoliner -gastrophile -germproof -gerontism -gigantical -glaciology -godmotherhood -gooseherd -gordunite -gove -gracilis -greathead -grieveship -guidable -gyromancy -gyrostat -habitus -hailweed -handhole -hangalai -haznadar -heliced -hemihypertrophy -hemimorphic -hemistrumectomy -heptavalent -heptite -herbalist -herpetology -hesperid -hexacarbon -hieromnemon -hobbyless -holodactylic -homoeoarchy -hopperings -hospitable -houseboat -huh -huntedly -hydroponics -hydrosomal -hyperdactylia -hyperperistalsis -hypogeocarpous -ideogram -idiopathical -illegitimate -imambarah -impotently -improvise -impuberal -inaccurately -incarnant -inchoation -incliner -incredulous -indiscriminateness -indulgenced -inebriation -inexpressiveness -infibulate -inflectedness -iniome -ink -inquietly -insaturable -insinuative -instiller -institutive -insultproof -interactionist -intercensal -interpenetrable -intertranspicuous -intrinsicality -inwards -iridiocyte -iridoparalysis -irreportable -isoprene -isosmotic -izard -jacuaru -jaculative -jerkined -joe -joyous -julienne -justicehood -kali -kalidium -katha -kathal -keelage -keratomycosis -khaki -khedival -kinkily -knife -kolo -kraken -kwarta -labba -labber -laboress -lacunar -latch -lauric -lawter -lectotype -leeches -legible -lepidosteoid -leucobasalt -leverer -libellate -limnimeter -lithography -lithotypic -locomotor -logarithmetically -logistician -lyncine -lysogenesis -machan -macromyelon -maharana -mandibulate -manganapatite -marchpane -mas -masochistic -mastaba -matching -meditatively -megalopolitan -melaniline -mentum -mercaptides -mestome -metasomatism -meterless -micronuclear -micropetalous -microreaction -microsporophore -mileway -milliarium -millisecond -misbind -miscollocation -misreader -modernicide -modification -modulant -monkfish -monoamino -monocarbide -monographical -morphinomaniac -mullein -munge -mutilate -mycophagist -myelosarcoma -myospasm -myriadly -nagaika -naphthionate -natant -naviculaeform -nayward -neallotype -necrophilia -nectared -neigher -neogamous -neurodynia -neurorthopteran -nidation -nieceship -nitrobacteria -nitrosification -nogheaded -nonassertive -noneuphonious -nonextant -nonincrease -nonintermittent -nonmetallic -nonprehensile -nonremunerative -nonsocial -nonvesting -noontime -noreaster -nounal -nub -nucleoplasm -nullisome -numero -numerous -oblongatal -observe -obtusilingual -obvert -occipitoatlantal -oceanside -ochlophobist -odontiasis -opalescence -opticon -oraculousness -orarium -organically -orthopedically -ostosis -overadvance -overbuilt -overdiscouragement -overdoer -overhardy -overjocular -overmagnify -overofficered -overpotent -overprizer -overrunner -overshrink -oversimply -oversplash -ovology -oxskin -oxychloride -oxygenant -ozokerite -pactional -palaeoanthropography -palaeographical -palaeopsychology -palliasse -palpebral -pandaric -pantelegraph -papicolist -papulate -parakinetic -parasitism -parochialic -parochialize -passionlike -patch -paucidentate -pawnbrokeress -pecite -pecky -pedipulation -pellitory -perfilograph -periblast -perigemmal -periost -periplus -perishable -periwig -permansive -persistingly -persymmetrical -phantom -phasmatrope -philocaly -philogyny -philosophister -philotherianism -phorology -phototrophic -phrator -phratral -phthisipneumony -physogastry -phytologic -phytoptid -pianograph -picqueter -piculet -pigeoner -pimaric -pinesap -pist -planometer -platano -playful -plea -pleuropneumonic -plowwoman -plump -pluviographical -pneumocele -podophthalmate -polyad -polythalamian -poppyhead -portamento -portmanteau -portraitlike -possible -potassamide -powderer -praepubis -preanesthetic -prebarbaric -predealer -predomination -prefactory -preirrigational -prelector -presbytership -presecure -preservable -prespecialist -preventionism -prewound -princely -priorship -proannexationist -proanthropos -probeable -probouleutic -profitless -proplasma -prosectorial -protecting -protochemistry -protosulphate -pseudoataxia -psilology -psychoneurotic -pterygial -publicist -purgation -purplishness -putatively -pyracene -pyrenomycete -pyromancy -pyrophone -quadroon -quailhead -qualifier -quaternal -rabblelike -rambunctious -rapidness -ratably -rationalism -razor -reannoy -recultivation -regulable -reimplant -reimposition -reimprison -reinjure -reinspiration -reintroduce -remantle -reprehensibility -reptant -require -resteal -restful -returnability -revisableness -rewash -rewhirl -reyield -rhizotomy -rhodamine -rigwiddie -rimester -ripper -rippet -rockish -rockwards -rollicky -roosters -rooted -rosal -rozum -saccharated -sagamore -sagy -salesmanship -salivous -sallet -salta -saprostomous -satiation -sauropsid -sawarra -sawback -scabish -scabrate -scampavia -scientificophilosophical -scirrosity -scoliometer -scolopendrelloid -secantly -seignioral -semibull -semic -seminarianism -semiped -semiprivate -semispherical -semispontaneous -seneschal -septendecimal -serotherapist -servation -sesquisulphuret -severish -sextipartite -sextubercular -shipyard -shuckpen -siderosis -silex -sillyhow -silverbelly -silverbelly -simulacrum -sisham -sixte -skeiner -skiapod -slopped -slubby -smalts -sockmaker -solute -somethingness -somnify -southwester -spathilla -spectrochemical -sphagnology -spinales -spiriting -spirling -spirochetemia -spreadboard -spurflower -squawdom -squeezing -staircase -staker -stamphead -statolith -stekan -stellulate -stinker -stomodaea -streamingly -strikingness -strouthocamelian -stuprum -subacutely -subboreal -subcontractor -subendorsement -subprofitable -subserviate -subsneer -subungual -sucuruju -sugan -sulphocarbolate -summerwood -superficialist -superinference -superregenerative -supplicate -suspendible -synchronizer -syntectic -tachyglossate -tailless -taintment -takingly -taletelling -tarpon -tasteful -taxeater -taxy -teache -teachless -teg -tegmen -teletyper -temperable -ten -tenent -teskere -testes -thallogen -thapsia -thewness -thickety -thiobacteria -thorniness -throwing -thyroprivic -tinnitus -tocalote -tolerationist -tonalamatl -torvous -totality -tottering -toug -tracheopathia -tragedical -translucent -trifoveolate -trilaurin -trophoplasmatic -trunkless -turbanless -turnpiker -twangle -twitterboned -ultraornate -umbilication -unabatingly -unabjured -unadequateness -unaffectedness -unarriving -unassorted -unattacked -unbenumbed -unboasted -unburning -uncensorious -uncongested -uncontemnedly -uncontemporary -uncrook -uncrystallizability -uncurb -uncustomariness -underbillow -undercanopy -underestimation -underhanging -underpetticoated -underpropped -undersole -understocking -underworld -undevout -undisappointing -undistinctive -unfiscal -unfluted -unfreckled -ungentilize -unglobe -unhelped -unhomogeneously -unifoliate -uninflammable -uninterrogated -unisonal -unkindled -unlikeableness -unlisty -unlocked -unmoving -unmultipliable -unnestled -unnoticed -unobservable -unobviated -unoffensively -unofficerlike -unpoetic -unpractically -unquestionableness -unrehearsed -unrevised -unrhetorical -unsadden -unsaluting -unscriptural -unseeking -unshowed -unsolicitous -unsprouted -unsubjective -unsubsidized -unsymbolic -untenant -unterrified -untranquil -untraversed -untrusty -untying -unwillful -unwinding -upspring -uptwist -urachovesical -uropygial -vagabondism -varicoid -varletess -vasal -ventrocaudal -verisimilitude -vermigerous -vibrometer -viminal -virus -vocationalism -voguey -vulnerability -waggle -wamblingly -warmus -waxer -waying -wedgeable -wellmaker -whomever -wigged -witchlike -wokas -woodrowel -woodsman -woolding -xanthelasmic -xiphosternum -yachtman -yachtsmanlike -yelp -zoophytal
\ No newline at end of file diff --git a/tests/phpunit/includes/cache/GenderCacheTest.php b/tests/phpunit/includes/cache/GenderCacheTest.php deleted file mode 100644 index ce2db5d7..00000000 --- a/tests/phpunit/includes/cache/GenderCacheTest.php +++ /dev/null @@ -1,104 +0,0 @@ -<?php - -/** - * @group Database - * @group Cache - */ -class GenderCacheTest extends MediaWikiLangTestCase { - - protected function setUp() { - global $wgDefaultUserOptions; - parent::setUp(); - //ensure the correct default gender - $wgDefaultUserOptions['gender'] = 'unknown'; - } - - function addDBData() { - $user = User::newFromName( 'UTMale' ); - if ( $user->getID() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTMalePassword' ); - } - //ensure the right gender - $user->setOption( 'gender', 'male' ); - $user->saveSettings(); - - $user = User::newFromName( 'UTFemale' ); - if ( $user->getID() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTFemalePassword' ); - } - //ensure the right gender - $user->setOption( 'gender', 'female' ); - $user->saveSettings(); - - $user = User::newFromName( 'UTDefaultGender' ); - if ( $user->getID() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTDefaultGenderPassword' ); - } - //ensure the default gender - $user->setOption( 'gender', null ); - $user->saveSettings(); - } - - /** - * test usernames - * - * @dataProvider provideUserGenders - * @covers GenderCache::getGenderOf - */ - public function testUserName( $username, $expectedGender ) { - $genderCache = GenderCache::singleton(); - $gender = $genderCache->getGenderOf( $username ); - $this->assertEquals( $gender, $expectedGender, "GenderCache normal" ); - } - - /** - * genderCache should work with user objects, too - * - * @dataProvider provideUserGenders - * @covers GenderCache::getGenderOf - */ - public function testUserObjects( $username, $expectedGender ) { - $genderCache = GenderCache::singleton(); - $user = User::newFromName( $username ); - $gender = $genderCache->getGenderOf( $user ); - $this->assertEquals( $gender, $expectedGender, "GenderCache normal" ); - } - - public static function provideUserGenders() { - return array( - array( 'UTMale', 'male' ), - array( 'UTFemale', 'female' ), - array( 'UTDefaultGender', 'unknown' ), - array( 'UTNotExist', 'unknown' ), - //some not valid user - array( '127.0.0.1', 'unknown' ), - array( 'user@test', 'unknown' ), - ); - } - - /** - * test strip of subpages to avoid unnecessary queries - * against the never existing username - * - * @dataProvider provideStripSubpages - * @covers GenderCache::getGenderOf - */ - public function testStripSubpages( $pageWithSubpage, $expectedGender ) { - $genderCache = GenderCache::singleton(); - $gender = $genderCache->getGenderOf( $pageWithSubpage ); - $this->assertEquals( $gender, $expectedGender, "GenderCache must strip of subpages" ); - } - - public static function provideStripSubpages() { - return array( - array( 'UTMale/subpage', 'male' ), - array( 'UTFemale/subpage', 'female' ), - array( 'UTDefaultGender/subpage', 'unknown' ), - array( 'UTNotExist/subpage', 'unknown' ), - array( '127.0.0.1/subpage', 'unknown' ), - ); - } -} diff --git a/tests/phpunit/includes/cache/MessageCacheTest.php b/tests/phpunit/includes/cache/MessageCacheTest.php deleted file mode 100644 index 803acf73..00000000 --- a/tests/phpunit/includes/cache/MessageCacheTest.php +++ /dev/null @@ -1,128 +0,0 @@ -<?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 deleted file mode 100644 index d3793d83..00000000 --- a/tests/phpunit/includes/cache/ProcessCacheLRUTest.php +++ /dev/null @@ -1,237 +0,0 @@ -<?php - -/** - * Test for ProcessCacheLRU class. - * - * Note that it uses the ProcessCacheLRUTestable class which extends some - * properties and methods visibility. That class is defined at the end of the - * file containing this class. - * - * @group Cache - */ -class ProcessCacheLRUTest extends MediaWikiTestCase { - - /** - * Helper to verify emptiness of a cache object. - * Compare against an array so we get the cache content difference. - */ - function assertCacheEmpty( $cache, $msg = 'Cache should be empty' ) { - $this->assertAttributeEquals( array(), 'cache', $cache, $msg ); - } - - /** - * Helper to fill a cache object passed by reference - */ - function fillCache( &$cache, $numEntries ) { - // Fill cache with three values - for ( $i = 1; $i <= $numEntries; $i++ ) { - $cache->set( "cache-key-$i", "prop-$i", "value-$i" ); - } - } - - /** - * Generates an array of what would be expected in cache for a given cache - * size and a number of entries filled in sequentially - */ - function getExpectedCache( $cacheMaxEntries, $entryToFill ) { - $expected = array(); - - if ( $entryToFill === 0 ) { - # The cache is empty! - return array(); - } elseif ( $entryToFill <= $cacheMaxEntries ) { - # Cache is not fully filled - $firstKey = 1; - } else { - # Cache overflowed - $firstKey = 1 + $entryToFill - $cacheMaxEntries; - } - - $lastKey = $entryToFill; - - for ( $i = $firstKey; $i <= $lastKey; $i++ ) { - $expected["cache-key-$i"] = array( "prop-$i" => "value-$i" ); - } - - return $expected; - } - - /** - * Highlight diff between assertEquals and assertNotSame - */ - public function testPhpUnitArrayEquality() { - $one = array( 'A' => 1, 'B' => 2 ); - $two = array( 'B' => 2, 'A' => 1 ); - $this->assertEquals( $one, $two ); // == - $this->assertNotSame( $one, $two ); // === - } - - /** - * @dataProvider provideInvalidConstructorArg - * @expectedException MWException - */ - public function testConstructorGivenInvalidValue( $maxSize ) { - new ProcessCacheLRUTestable( $maxSize ); - } - - /** - * Value which are forbidden by the constructor - */ - public static function provideInvalidConstructorArg() { - return array( - array( null ), - array( array() ), - array( new stdClass() ), - array( 0 ), - array( '5' ), - array( -1 ), - ); - } - - public function testAddAndGetAKey() { - $oneCache = new ProcessCacheLRUTestable( 1 ); - $this->assertCacheEmpty( $oneCache ); - - // First set just one value - $oneCache->set( 'cache-key', 'prop1', 'value1' ); - $this->assertEquals( 1, $oneCache->getEntriesCount() ); - $this->assertTrue( $oneCache->has( 'cache-key', 'prop1' ) ); - $this->assertEquals( 'value1', $oneCache->get( 'cache-key', 'prop1' ) ); - } - - public function testDeleteOldKey() { - $oneCache = new ProcessCacheLRUTestable( 1 ); - $this->assertCacheEmpty( $oneCache ); - - $oneCache->set( 'cache-key', 'prop1', 'value1' ); - $oneCache->set( 'cache-key', 'prop1', 'value2' ); - $this->assertEquals( 'value2', $oneCache->get( 'cache-key', 'prop1' ) ); - } - - /** - * This test that we properly overflow when filling a cache with - * a sequence of always different cache-keys. Meant to verify we correclty - * delete the older key. - * - * @dataProvider provideCacheFilling - * @param $cacheMaxEntries Maximum entry the created cache will hold - * @param $entryToFill Number of entries to insert in the created cache. - */ - public function testFillingCache( $cacheMaxEntries, $entryToFill, $msg = '' ) { - $cache = new ProcessCacheLRUTestable( $cacheMaxEntries ); - $this->fillCache( $cache, $entryToFill ); - - $this->assertSame( - $this->getExpectedCache( $cacheMaxEntries, $entryToFill ), - $cache->getCache(), - "Filling a $cacheMaxEntries entries cache with $entryToFill entries" - ); - } - - /** - * Provider for testFillingCache - */ - public static function provideCacheFilling() { - // ($cacheMaxEntries, $entryToFill, $msg='') - return array( - array( 1, 0 ), - array( 1, 1 ), - array( 1, 2 ), # overflow - array( 5, 33 ), # overflow - ); - } - - /** - * Create a cache with only one remaining entry then update - * the first inserted entry. Should bump it to the top. - */ - public function testReplaceExistingKeyShouldBumpEntryToTop() { - $maxEntries = 3; - - $cache = new ProcessCacheLRUTestable( $maxEntries ); - // Fill cache leaving just one remaining slot - $this->fillCache( $cache, $maxEntries - 1 ); - - // Set an existing cache key - $cache->set( "cache-key-1", "prop-1", "new-value-for-1" ); - - $this->assertSame( - array( - 'cache-key-2' => array( 'prop-2' => 'value-2' ), - 'cache-key-1' => array( 'prop-1' => 'new-value-for-1' ), - ), - $cache->getCache() - ); - } - - public function testRecentlyAccessedKeyStickIn() { - $cache = new ProcessCacheLRUTestable( 2 ); - $cache->set( 'first', 'prop1', 'value1' ); - $cache->set( 'second', 'prop2', 'value2' ); - - // Get first - $cache->get( 'first', 'prop1' ); - // Cache a third value, should invalidate the least used one - $cache->set( 'third', 'prop3', 'value3' ); - - $this->assertFalse( $cache->has( 'second', 'prop2' ) ); - } - - /** - * This first create a full cache then update the value for the 2nd - * filled entry. - * 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). - */ - public function testReplaceExistingKeyInAFullCacheShouldBumpToTop() { - $maxEntries = 3; - - $cache = new ProcessCacheLRUTestable( $maxEntries ); - $this->fillCache( $cache, $maxEntries ); - - // Set an existing cache key - $cache->set( "cache-key-2", "prop-2", "new-value-for-2" ); - $this->assertSame( - array( - 'cache-key-1' => array( 'prop-1' => 'value-1' ), - 'cache-key-3' => array( 'prop-3' => 'value-3' ), - 'cache-key-2' => array( 'prop-2' => 'new-value-for-2' ), - ), - $cache->getCache() - ); - $this->assertEquals( 'new-value-for-2', - $cache->get( 'cache-key-2', 'prop-2' ) - ); - } - - public function testBumpExistingKeyToTop() { - $cache = new ProcessCacheLRUTestable( 3 ); - $this->fillCache( $cache, 3 ); - - // Set the very first cache key to a new value - $cache->set( "cache-key-1", "prop-1", "new value for 1" ); - $this->assertEquals( - array( - 'cache-key-2' => array( 'prop-2' => 'value-2' ), - 'cache-key-3' => array( 'prop-3' => 'value-3' ), - 'cache-key-1' => array( 'prop-1' => 'new value for 1' ), - ), - $cache->getCache() - ); - } -} - -/** - * Overrides some ProcessCacheLRU methods and properties accessibility. - */ -class ProcessCacheLRUTestable extends ProcessCacheLRU { - public $cache = array(); - - public function getCache() { - return $this->cache; - } - - public function getEntriesCount() { - return count( $this->cache ); - } -} diff --git a/tests/phpunit/includes/content/ContentHandlerTest.php b/tests/phpunit/includes/content/ContentHandlerTest.php deleted file mode 100644 index aedf594d..00000000 --- a/tests/phpunit/includes/content/ContentHandlerTest.php +++ /dev/null @@ -1,451 +0,0 @@ -<?php - -/** - * @group ContentHandler - * @group Database - * - * @note Declare that we are using the database, because otherwise we'll fail in the "databaseless" test run. - * This is because the LinkHolderArray used by the parser needs database access. - * - */ -class ContentHandlerTest extends MediaWikiTestCase { - - public function setUp() { - global $wgContLang; - parent::setUp(); - - $this->setMwGlobals( array( - 'wgExtraNamespaces' => array( - 12312 => 'Dummy', - 12313 => 'Dummy_talk', - ), - // The below tests assume that namespaces not mentioned here (Help, User, MediaWiki, ..) - // default to CONTENT_MODEL_WIKITEXT. - 'wgNamespaceContentModels' => array( - 12312 => 'testing', - ), - 'wgContentHandlers' => array( - CONTENT_MODEL_WIKITEXT => 'WikitextContentHandler', - CONTENT_MODEL_JAVASCRIPT => 'JavaScriptContentHandler', - CONTENT_MODEL_CSS => 'CssContentHandler', - CONTENT_MODEL_TEXT => 'TextContentHandler', - 'testing' => 'DummyContentHandlerForTesting', - ), - ) ); - - // Reset namespace cache - MWNamespace::getCanonicalNamespaces( true ); - $wgContLang->resetNamespaces(); - } - - public function tearDown() { - global $wgContLang; - - // Reset namespace cache - MWNamespace::getCanonicalNamespaces( true ); - $wgContLang->resetNamespaces(); - - parent::tearDown(); - } - - public static function dataGetDefaultModelFor() { - return array( - array( 'Help:Foo', CONTENT_MODEL_WIKITEXT ), - array( 'Help:Foo.js', CONTENT_MODEL_WIKITEXT ), - array( 'Help:Foo/bar.js', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo.js', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo/bar.js', CONTENT_MODEL_JAVASCRIPT ), - array( 'User:Foo/bar.css', CONTENT_MODEL_CSS ), - array( 'User talk:Foo/bar.css', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo/bar.js.xxx', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo/bar.xxx', CONTENT_MODEL_WIKITEXT ), - array( 'MediaWiki:Foo.js', CONTENT_MODEL_JAVASCRIPT ), - array( 'MediaWiki:Foo.css', CONTENT_MODEL_CSS ), - array( 'MediaWiki:Foo.JS', CONTENT_MODEL_WIKITEXT ), - array( 'MediaWiki:Foo.CSS', CONTENT_MODEL_WIKITEXT ), - array( 'MediaWiki:Foo.css.xxx', CONTENT_MODEL_WIKITEXT ), - ); - } - - /** - * @dataProvider dataGetDefaultModelFor - * @covers ContentHandler::getDefaultModelFor - */ - public function testGetDefaultModelFor( $title, $expectedModelId ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedModelId, ContentHandler::getDefaultModelFor( $title ) ); - } - - /** - * @dataProvider dataGetDefaultModelFor - * @covers ContentHandler::getForTitle - */ - public function testGetForTitle( $title, $expectedContentModel ) { - $title = Title::newFromText( $title ); - $handler = ContentHandler::getForTitle( $title ); - $this->assertEquals( $expectedContentModel, $handler->getModelID() ); - } - - public static function dataGetLocalizedName() { - return array( - array( null, null ), - array( "xyzzy", null ), - - // XXX: depends on content language - array( CONTENT_MODEL_JAVASCRIPT, '/javascript/i' ), - ); - } - - /** - * @dataProvider dataGetLocalizedName - * @covers ContentHandler::getLocalizedName - */ - public function testGetLocalizedName( $id, $expected ) { - $name = ContentHandler::getLocalizedName( $id ); - - if ( $expected ) { - $this->assertNotNull( $name, "no name found for content model $id" ); - $this->assertTrue( preg_match( $expected, $name ) > 0, - "content model name for #$id did not match pattern $expected" - ); - } else { - $this->assertEquals( $id, $name, "localization of unknown model $id should have " - . "fallen back to use the model id directly." - ); - } - } - - public static function dataGetPageLanguage() { - global $wgLanguageCode; - - return array( - array( "Main", $wgLanguageCode ), - array( "Dummy:Foo", $wgLanguageCode ), - array( "MediaWiki:common.js", 'en' ), - array( "User:Foo/common.js", 'en' ), - array( "MediaWiki:common.css", 'en' ), - array( "User:Foo/common.css", 'en' ), - array( "User:Foo", $wgLanguageCode ), - - array( CONTENT_MODEL_JAVASCRIPT, 'javascript' ), - ); - } - - /** - * @dataProvider dataGetPageLanguage - * @covers ContentHandler::getPageLanguage - */ - public function testGetPageLanguage( $title, $expected ) { - if ( is_string( $title ) ) { - $title = Title::newFromText( $title ); - } - - $expected = wfGetLangObj( $expected ); - - $handler = ContentHandler::getForTitle( $title ); - $lang = $handler->getPageLanguage( $title ); - - $this->assertEquals( $expected->getCode(), $lang->getCode() ); - } - - public static function dataGetContentText_Null() { - return array( - array( 'fail' ), - array( 'serialize' ), - array( 'ignore' ), - ); - } - - /** - * @dataProvider dataGetContentText_Null - * @covers ContentHandler::getContentText - */ - public function testGetContentText_Null( $contentHandlerTextFallback ) { - $this->setMwGlobals( 'wgContentHandlerTextFallback', $contentHandlerTextFallback ); - - $content = null; - - $text = ContentHandler::getContentText( $content ); - $this->assertEquals( '', $text ); - } - - public static function dataGetContentText_TextContent() { - return array( - array( 'fail' ), - array( 'serialize' ), - array( 'ignore' ), - ); - } - - /** - * @dataProvider dataGetContentText_TextContent - * @covers ContentHandler::getContentText - */ - public function testGetContentText_TextContent( $contentHandlerTextFallback ) { - $this->setMwGlobals( 'wgContentHandlerTextFallback', $contentHandlerTextFallback ); - - $content = new WikitextContent( "hello world" ); - - $text = ContentHandler::getContentText( $content ); - $this->assertEquals( $content->getNativeData(), $text ); - } - - /** - * 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" ); - - ContentHandler::getContentText( $content ); - } - - /** - * @covers ContentHandler::getContentText - */ - public function testGetContentText_NonTextContent_serialize() { - $this->setMwGlobals( 'wgContentHandlerTextFallback', 'serialize' ); - - $content = new DummyContentForTesting( "hello world" ); - - $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" ); - - $text = ContentHandler::getContentText( $content ); - $this->assertNull( $text ); - } - - /* - public static function makeContent( $text, Title $title, $modelId = null, $format = null ) {} - */ - - public static function dataMakeContent() { - return array( - array( 'hallo', 'Help:Test', null, null, CONTENT_MODEL_WIKITEXT, 'hallo', false ), - array( 'hallo', 'MediaWiki:Test.js', null, null, CONTENT_MODEL_JAVASCRIPT, 'hallo', false ), - array( serialize( 'hallo' ), 'Dummy:Test', null, null, "testing", 'hallo', false ), - - array( 'hallo', 'Help:Test', null, CONTENT_FORMAT_WIKITEXT, CONTENT_MODEL_WIKITEXT, 'hallo', false ), - array( 'hallo', 'MediaWiki:Test.js', null, CONTENT_FORMAT_JAVASCRIPT, CONTENT_MODEL_JAVASCRIPT, 'hallo', false ), - array( serialize( 'hallo' ), 'Dummy:Test', null, "testing", "testing", 'hallo', false ), - - array( 'hallo', 'Help:Test', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, 'hallo', false ), - array( 'hallo', 'MediaWiki:Test.js', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, 'hallo', false ), - array( serialize( 'hallo' ), 'Dummy:Test', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, serialize( 'hallo' ), false ), - - array( 'hallo', 'Help:Test', CONTENT_MODEL_WIKITEXT, "testing", null, null, true ), - array( 'hallo', 'MediaWiki:Test.js', CONTENT_MODEL_CSS, "testing", null, null, true ), - array( 'hallo', 'Dummy:Test', CONTENT_MODEL_JAVASCRIPT, "testing", null, null, true ), - ); - } - - /** - * @dataProvider dataMakeContent - * @covers ContentHandler::makeContent - */ - public function testMakeContent( $data, $title, $modelId, $format, $expectedModelId, $expectedNativeData, $shouldFail ) { - $title = Title::newFromText( $title ); - - try { - $content = ContentHandler::makeContent( $data, $title, $modelId, $format ); - - if ( $shouldFail ) { - $this->fail( "ContentHandler::makeContent should have failed!" ); - } - - $this->assertEquals( $expectedModelId, $content->getModel(), 'bad model id' ); - $this->assertEquals( $expectedNativeData, $content->getNativeData(), 'bads native data' ); - } catch ( MWException $ex ) { - if ( !$shouldFail ) { - $this->fail( "ContentHandler::makeContent failed unexpectedly: " . $ex->getMessage() ); - } else { - // dummy, so we don't get the "test did not perform any assertions" message. - $this->assertTrue( true ); - } - } - } - - /* - public function testSupportsSections() { - $this->markTestIncomplete( "not yet implemented" ); - } - */ - - /** - * @covers ContentHandler::runLegacyHooks - */ - public function testRunLegacyHooks() { - Hooks::register( 'testRunLegacyHooks', __CLASS__ . '::dummyHookHandler' ); - - $content = new WikitextContent( 'test text' ); - $ok = ContentHandler::runLegacyHooks( 'testRunLegacyHooks', array( 'foo', &$content, 'bar' ), false ); - - $this->assertTrue( $ok, "runLegacyHooks should have returned true" ); - $this->assertEquals( "TEST TEXT", $content->getNativeData() ); - } - - public static function dummyHookHandler( $foo, &$text, $bar ) { - if ( $text === null || $text === false ) { - return false; - } - - $text = strtoupper( $text ); - - return true; - } -} - -class DummyContentHandlerForTesting extends ContentHandler { - - public function __construct( $dataModel ) { - parent::__construct( $dataModel, array( "testing" ) ); - } - - /** - * Serializes Content object of the type supported by this ContentHandler. - * - * @param Content $content the Content object to serialize - * @param null $format the desired serialization format - * @return String serialized form of the content - */ - public function serializeContent( Content $content, $format = null ) { - return $content->serialize(); - } - - /** - * Unserializes a Content object of the type supported by this ContentHandler. - * - * @param $blob String serialized form of the content - * @param null $format the format used for serialization - * @return Content the Content object created by deserializing $blob - */ - public function unserializeContent( $blob, $format = null ) { - $d = unserialize( $blob ); - - return new DummyContentForTesting( $d ); - } - - /** - * Creates an empty Content object of the type supported by this ContentHandler. - * - */ - public function makeEmptyContent() { - return new DummyContentForTesting( '' ); - } -} - -class DummyContentForTesting extends AbstractContent { - - public function __construct( $data ) { - parent::__construct( "testing" ); - - $this->data = $data; - } - - public function serialize( $format = null ) { - return serialize( $this->data ); - } - - /** - * @return String a string representing the content in a way useful for building a full text search index. - * If no useful representation exists, this method returns an empty string. - */ - public function getTextForSearchIndex() { - return ''; - } - - /** - * @return String the wikitext to include when another page includes this content, or false if the content is not - * includable in a wikitext page. - */ - public function getWikitextForTransclusion() { - return false; - } - - /** - * Returns a textual representation of the content suitable for use in edit summaries and log messages. - * - * @param int $maxlength Maximum length of the summary text. - * @return string The summary text. - */ - public function getTextForSummary( $maxlength = 250 ) { - return ''; - } - - /** - * Returns native represenation of the data. Interpretation depends on the data model used, - * as given by getDataModel(). - * - * @return mixed the native representation of the content. Could be a string, a nested array - * structure, an object, a binary blob... anything, really. - */ - public function getNativeData() { - return $this->data; - } - - /** - * returns the content's nominal size in bogo-bytes. - * - * @return int - */ - public function getSize() { - return strlen( $this->data ); - } - - /** - * Return a copy of this Content object. The following must be true for the object returned - * if $copy = $original->copy() - * - * * get_class($original) === get_class($copy) - * * $original->getModel() === $copy->getModel() - * * $original->equals( $copy ) - * - * If and only if the Content object is imutable, the copy() method can and should - * return $this. That is, $copy === $original may be true, but only for imutable content - * objects. - * - * @return Content. A copy of this object. - */ - public function copy() { - return $this; - } - - /** - * Returns true if this content is countable as a "real" wiki page, provided - * that it's also in a countable location (e.g. a current revision in the main namespace). - * - * @param boolean $hasLinks if it is known whether this content contains links, provide this information here, - * to avoid redundant parsing to find out. - * @return boolean - */ - public function isCountable( $hasLinks = null ) { - return false; - } - - /** - * @param Title $title - * @param null $revId - * @param null|ParserOptions $options - * @param boolean $generateHtml whether to generate Html (default: true). If false, - * the result of calling getText() on the ParserOutput object returned by - * this method is undefined. - * - * @return ParserOutput - */ - public function getParserOutput( Title $title, $revId = null, ParserOptions $options = null, $generateHtml = true ) { - return new ParserOutput( $this->getNativeData() ); - } -} diff --git a/tests/phpunit/includes/content/CssContentTest.php b/tests/phpunit/includes/content/CssContentTest.php deleted file mode 100644 index bd6d41fe..00000000 --- a/tests/phpunit/includes/content/CssContentTest.php +++ /dev/null @@ -1,87 +0,0 @@ -<?php - -/** - * @group ContentHandler - * @group Database - * ^--- needed, because we do need the database to test link updates - */ -class CssContentTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - // Anon user - $user = new User(); - $user->setName( '127.0.0.1' ); - - $this->setMwGlobals( array( - 'wgUser' => $user, - 'wgTextModelsToParse' => array( - CONTENT_MODEL_CSS, - ) - ) ); - } - - public function newContent( $text ) { - return new CssContent( $text ); - } - - public static function dataGetParserOutput() { - return array( - array( - 'MediaWiki:Test.css', - null, - "hello <world>\n", - "<pre class=\"mw-code mw-css\" dir=\"ltr\">\nhello <world>\n\n</pre>" - ), - array( - 'MediaWiki:Test.css', - null, - "/* hello [[world]] */\n", - "<pre class=\"mw-code mw-css\" dir=\"ltr\">\n/* hello [[world]] */\n\n</pre>", - array( - 'Links' => array( - array( 'World' => 0 ) - ) - ) - ), - - // TODO: more...? - ); - } - - /** - * @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.' ); - - $this->assertEquals( CONTENT_MODEL_CSS, $content->getContentHandler()->getModelID() ); - } - - public static function dataEquals() { - return array( - array( new CssContent( 'hallo' ), null, false ), - array( new CssContent( 'hallo' ), new CssContent( 'hallo' ), true ), - array( new CssContent( 'hallo' ), new WikitextContent( 'hallo' ), false ), - array( new CssContent( 'hallo' ), new CssContent( 'HALLO' ), false ), - ); - } - - /** - * @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 deleted file mode 100644 index c8616ff0..00000000 --- a/tests/phpunit/includes/content/JavaScriptContentTest.php +++ /dev/null @@ -1,287 +0,0 @@ -<?php - -/** - * @group ContentHandler - * @group Database - * ^--- needed, because we do need the database to test link updates - */ -class JavaScriptContentTest extends TextContentTest { - - public function newContent( $text ) { - return new JavaScriptContent( $text ); - } - - public static function dataGetParserOutput() { - return array( - array( - 'MediaWiki:Test.js', - null, - "hello <world>\n", - "<pre class=\"mw-code mw-js\" dir=\"ltr\">\nhello <world>\n\n</pre>" - ), - array( - 'MediaWiki:Test.js', - null, - "hello(); // [[world]]\n", - "<pre class=\"mw-code mw-js\" dir=\"ltr\">\nhello(); // [[world]]\n\n</pre>", - array( - 'Links' => array( - array( 'World' => 0 ) - ) - ) - ), - - // TODO: more...? - ); - } - - // XXX: Unused function - public static function dataGetSection() { - return array( - array( WikitextContentTest::$sections, - '0', - null - ), - array( WikitextContentTest::$sections, - '2', - null - ), - array( WikitextContentTest::$sections, - '8', - null - ), - ); - } - - // XXX: Unused function - public static function dataReplaceSection() { - return array( - array( WikitextContentTest::$sections, - '0', - 'No more', - null, - null - ), - array( WikitextContentTest::$sections, - '', - 'No more', - null, - null - ), - array( WikitextContentTest::$sections, - '2', - "== TEST ==\nmore fun", - null, - null - ), - array( WikitextContentTest::$sections, - '8', - 'No more', - null, - null - ), - array( WikitextContentTest::$sections, - 'new', - 'No more', - 'New', - null - ), - ); - } - - /** - * @covers JavaScriptContent::addSectionHeader - */ - public function testAddSectionHeader() { - $content = $this->newContent( 'hello world' ); - $c = $content->addSectionHeader( 'test' ); - - $this->assertTrue( $content->equals( $c ) ); - } - - // XXX: currently, preSaveTransform is applied to scripts. this may change or become optional. - public static function dataPreSaveTransform() { - return array( - array( 'hello this is ~~~', - "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]", - ), - array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>', - 'hello \'\'this\'\' is <nowiki>~~~</nowiki>', - ), - array( " Foo \n ", - " Foo", - ), - ); - } - - public static function dataPreloadTransform() { - return array( - array( 'hello this is ~~~', - 'hello this is ~~~', - ), - array( 'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>', - 'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>', - ), - ); - } - - public static function dataGetRedirectTarget() { - return array( - array( '#REDIRECT [[Test]]', - null, - ), - array( '#REDIRECT Test', - null, - ), - array( '* #REDIRECT [[Test]]', - null, - ), - ); - } - - /** - * @todo Test needs database! - */ - /* - public function getRedirectChain() { - $text = $this->getNativeData(); - return Title::newFromRedirectArray( $text ); - } - */ - - /** - * @todo Test needs database! - */ - /* - public function getUltimateRedirectTarget() { - $text = $this->getNativeData(); - return Title::newFromRedirectRecurse( $text ); - } - */ - - public static function dataIsCountable() { - return array( - array( '', - null, - 'any', - true - ), - array( 'Foo', - null, - 'any', - true - ), - array( 'Foo', - null, - 'comma', - false - ), - array( 'Foo, bar', - null, - 'comma', - false - ), - array( 'Foo', - null, - 'link', - false - ), - array( 'Foo [[bar]]', - null, - 'link', - false - ), - array( 'Foo', - true, - 'link', - false - ), - array( 'Foo [[bar]]', - false, - 'link', - false - ), - array( '#REDIRECT [[bar]]', - true, - 'any', - true - ), - array( '#REDIRECT [[bar]]', - true, - 'comma', - false - ), - array( '#REDIRECT [[bar]]', - true, - 'link', - false - ), - ); - } - - public static function dataGetTextForSummary() { - return array( - array( "hello\nworld.", - 16, - 'hello world.', - ), - array( 'hello world.', - 8, - 'hello...', - ), - array( '[[hello world]].', - 8, - '[[hel...', - ), - ); - } - - /** - * @covers JavaScriptContent::matchMagicWord - */ - public function testMatchMagicWord() { - $mw = MagicWord::get( "staticredirect" ); - - $content = $this->newContent( "#REDIRECT [[FOO]]\n__STATICREDIRECT__" ); - $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" ); - - $content = $this->newContent( "#REDIRECT [[Someplace]]" ); - $newContent = $content->updateRedirect( $target ); - - $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." ); - - $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $content->getContentHandler()->getModelID() ); - } - - public static function dataEquals() { - return array( - array( new JavaScriptContent( "hallo" ), null, false ), - array( new JavaScriptContent( "hallo" ), new JavaScriptContent( "hallo" ), true ), - array( new JavaScriptContent( "hallo" ), new CssContent( "hallo" ), false ), - array( new JavaScriptContent( "hallo" ), new JavaScriptContent( "HALLO" ), false ), - ); - } -} diff --git a/tests/phpunit/includes/content/TextContentTest.php b/tests/phpunit/includes/content/TextContentTest.php deleted file mode 100644 index a1f099f3..00000000 --- a/tests/phpunit/includes/content/TextContentTest.php +++ /dev/null @@ -1,458 +0,0 @@ -<?php - -/** - * @group ContentHandler - * @group Database - * ^--- needed, because we do need the database to test link updates - */ -class TextContentTest extends MediaWikiLangTestCase { - protected $context; - - protected function setUp() { - parent::setUp(); - - // Anon user - $user = new User(); - $user->setName( '127.0.0.1' ); - - $this->setMwGlobals( array( - 'wgUser' => $user, - 'wgTextModelsToParse' => array( - CONTENT_MODEL_WIKITEXT, - CONTENT_MODEL_CSS, - CONTENT_MODEL_JAVASCRIPT, - ), - 'wgUseTidy' => false, - 'wgAlwaysUseTidy' => false, - ) ); - - $this->context = new RequestContext( new FauxRequest() ); - $this->context->setTitle( Title::newFromText( 'Test' ) ); - $this->context->setUser( $user ); - } - - public function newContent( $text ) { - return new TextContent( $text ); - } - - public static function dataGetParserOutput() { - return array( - array( - 'TextContentTest_testGetParserOutput', - CONTENT_MODEL_TEXT, - "hello ''world'' & [[stuff]]\n", "hello ''world'' & [[stuff]]", - array( - 'Links' => array() - ) - ), - // TODO: more...? - ); - } - - /** - * @dataProvider dataGetParserOutput - * @covers TextContent::getParserOutput - */ - public function testGetParserOutput( $title, $model, $text, $expectedHtml, $expectedFields = null ) { - $title = Title::newFromText( $title ); - $content = ContentHandler::makeContent( $text, $title, $model ); - - $po = $content->getParserOutput( $title ); - - $html = $po->getText(); - $html = preg_replace( '#<!--.*?-->#sm', '', $html ); // strip comments - - $this->assertEquals( $expectedHtml, trim( $html ) ); - - if ( $expectedFields ) { - foreach ( $expectedFields as $field => $exp ) { - $f = 'get' . ucfirst( $field ); - $v = call_user_func( array( $po, $f ) ); - - if ( is_array( $exp ) ) { - $this->assertArrayEquals( $exp, $v ); - } else { - $this->assertEquals( $exp, $v ); - } - } - } - - // TODO: assert more properties - } - - public static function dataPreSaveTransform() { - return array( - array( - #0: no signature resolution - 'hello this is ~~~', - 'hello this is ~~~', - ), - array( - #1: rtrim - " Foo \n ", - ' Foo', - ), - ); - } - - /** - * @dataProvider dataPreSaveTransform - * @covers TextContent::preSaveTransform - */ - public function testPreSaveTransform( $text, $expected ) { - global $wgContLang; - - $options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang ); - - $content = $this->newContent( $text ); - $content = $content->preSaveTransform( $this->context->getTitle(), $this->context->getUser(), $options ); - - $this->assertEquals( $expected, $content->getNativeData() ); - } - - public static function dataPreloadTransform() { - return array( - array( - 'hello this is ~~~', - 'hello this is ~~~', - ), - ); - } - - /** - * @dataProvider dataPreloadTransform - * @covers TextContent::preloadTransform - */ - public function testPreloadTransform( $text, $expected ) { - global $wgContLang; - $options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang ); - - $content = $this->newContent( $text ); - $content = $content->preloadTransform( $this->context->getTitle(), $options ); - - $this->assertEquals( $expected, $content->getNativeData() ); - } - - public static function dataGetRedirectTarget() { - return array( - array( '#REDIRECT [[Test]]', - null, - ), - ); - } - - /** - * @dataProvider dataGetRedirectTarget - * @covers TextContent::getRedirectTarget - */ - public function testGetRedirectTarget( $text, $expected ) { - $content = $this->newContent( $text ); - $t = $content->getRedirectTarget(); - - if ( is_null( $expected ) ) { - $this->assertNull( $t, "text should not have generated a redirect target: $text" ); - } else { - $this->assertEquals( $expected, $t->getPrefixedText() ); - } - } - - /** - * @dataProvider dataGetRedirectTarget - * @covers TextContent::isRedirect - */ - public function testIsRedirect( $text, $expected ) { - $content = $this->newContent( $text ); - - $this->assertEquals( !is_null( $expected ), $content->isRedirect() ); - } - - /** - * @todo Test needs database! Should be done by a test class in the Database group. - */ - /* - public function getRedirectChain() { - $text = $this->getNativeData(); - return Title::newFromRedirectArray( $text ); - } - */ - - /** - * @todo Test needs database! Should be done by a test class in the Database group. - */ - /* - public function getUltimateRedirectTarget() { - $text = $this->getNativeData(); - return Title::newFromRedirectRecurse( $text ); - } - */ - - public static function dataIsCountable() { - return array( - array( '', - null, - 'any', - true - ), - array( 'Foo', - null, - 'any', - true - ), - array( 'Foo', - null, - 'comma', - false - ), - array( 'Foo, bar', - null, - 'comma', - false - ), - ); - } - - /** - * @dataProvider dataIsCountable - * @group Database - * @covers TextContent::isCountable - */ - public function testIsCountable( $text, $hasLinks, $mode, $expected ) { - $this->setMwGlobals( 'wgArticleCountMethod', $mode ); - - $content = $this->newContent( $text ); - - $v = $content->isCountable( $hasLinks, $this->context->getTitle() ); - - $this->assertEquals( $expected, $v, 'isCountable() returned unexpected value ' . var_export( $v, true ) - . ' instead of ' . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" ); - } - - public static function dataGetTextForSummary() { - return array( - array( "hello\nworld.", - 16, - 'hello world.', - ), - array( 'hello world.', - 8, - 'hello...', - ), - array( '[[hello world]].', - 8, - '[[hel...', - ), - ); - } - - /** - * @dataProvider dataGetTextForSummary - * @covers TextContent::getTextForSummary - */ - public function testGetTextForSummary( $text, $maxlength, $expected ) { - $content = $this->newContent( $text ); - - $this->assertEquals( $expected, $content->getTextForSummary( $maxlength ) ); - } - - /** - * @covers TextContent::getTextForSearchIndex - */ - public function testGetTextForSearchIndex() { - $content = $this->newContent( 'hello world.' ); - - $this->assertEquals( 'hello world.', $content->getTextForSearchIndex() ); - } - - /** - * @covers TextContent::copy - */ - public function testCopy() { - $content = $this->newContent( 'hello world.' ); - $copy = $content->copy(); - - $this->assertTrue( $content->equals( $copy ), 'copy must be equal to original' ); - $this->assertEquals( 'hello world.', $copy->getNativeData() ); - } - - /** - * @covers TextContent::getSize - */ - public function testGetSize() { - $content = $this->newContent( 'hello world.' ); - - $this->assertEquals( 12, $content->getSize() ); - } - - /** - * @covers TextContent::getNativeData - */ - public function testGetNativeData() { - $content = $this->newContent( 'hello world.' ); - - $this->assertEquals( 'hello world.', $content->getNativeData() ); - } - - /** - * @covers TextContent::getWikitextForTransclusion - */ - public function testGetWikitextForTransclusion() { - $content = $this->newContent( 'hello world.' ); - - $this->assertEquals( 'hello world.', $content->getWikitextForTransclusion() ); - } - - /** - * @covers TextContent::getModel - */ - public function testGetModel() { - $content = $this->newContent( "hello world." ); - - $this->assertEquals( CONTENT_MODEL_TEXT, $content->getModel() ); - } - - /** - * @covers TextContent::getContentHandler - */ - public function testGetContentHandler() { - $content = $this->newContent( "hello world." ); - - $this->assertEquals( CONTENT_MODEL_TEXT, $content->getContentHandler()->getModelID() ); - } - - public static function dataIsEmpty() { - return array( - array( '', true ), - array( ' ', false ), - array( '0', false ), - array( 'hallo welt.', false ), - ); - } - - /** - * @dataProvider dataIsEmpty - * @covers TextContent::isEmpty - */ - public function testIsEmpty( $text, $empty ) { - $content = $this->newContent( $text ); - - $this->assertEquals( $empty, $content->isEmpty() ); - } - - public static function dataEquals() { - return array( - array( new TextContent( "hallo" ), null, false ), - array( new TextContent( "hallo" ), new TextContent( "hallo" ), true ), - array( new TextContent( "hallo" ), new JavaScriptContent( "hallo" ), false ), - array( new TextContent( "hallo" ), new WikitextContent( "hallo" ), false ), - array( new TextContent( "hallo" ), new TextContent( "HALLO" ), false ), - ); - } - - /** - * @dataProvider dataEquals - * @covers TextContent::equals - */ - public function testEquals( Content $a, Content $b = null, $equal = false ) { - $this->assertEquals( $equal, $a->equals( $b ) ); - } - - public static function dataGetDeletionUpdates() { - return array( - array( "TextContentTest_testGetSecondaryDataUpdates_1", - CONTENT_MODEL_TEXT, "hello ''world''\n", - array() - ), - array( "TextContentTest_testGetSecondaryDataUpdates_2", - CONTENT_MODEL_TEXT, "hello [[world test 21344]]\n", - array() - ), - // TODO: more...? - ); - } - - /** - * @dataProvider dataGetDeletionUpdates - * @covers TextContent::getDeletionUpdates - */ - public function testDeletionUpdates( $title, $model, $text, $expectedStuff ) { - $ns = $this->getDefaultWikitextNS(); - $title = Title::newFromText( $title, $ns ); - - $content = ContentHandler::makeContent( $text, $title, $model ); - - $page = WikiPage::factory( $title ); - $page->doEditContent( $content, '' ); - - $updates = $content->getDeletionUpdates( $page ); - - // make updates accessible by class name - foreach ( $updates as $update ) { - $class = get_class( $update ); - $updates[$class] = $update; - } - - if ( !$expectedStuff ) { - $this->assertTrue( true ); // make phpunit happy - return; - } - - foreach ( $expectedStuff as $class => $fieldValues ) { - $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" ); - - $update = $updates[$class]; - - foreach ( $fieldValues as $field => $value ) { - $v = $update->$field; #if the field doesn't exist, just crash and burn - $this->assertEquals( $value, $v, "unexpected value for field $field in instance of $class" ); - } - } - - $page->doDeleteArticle( '' ); - } - - public static function provideConvert() { - return array( - array( // #0 - 'Hallo Welt', - CONTENT_MODEL_WIKITEXT, - 'lossless', - 'Hallo Welt' - ), - array( // #1 - 'Hallo Welt', - CONTENT_MODEL_WIKITEXT, - 'lossless', - 'Hallo Welt' - ), - array( // #1 - 'Hallo Welt', - CONTENT_MODEL_CSS, - 'lossless', - 'Hallo Welt' - ), - array( // #1 - 'Hallo Welt', - CONTENT_MODEL_JAVASCRIPT, - 'lossless', - 'Hallo Welt' - ), - ); - } - - /** - * @dataProvider provideConvert - * @covers TextContent::convert - */ - public function testConvert( $text, $model, $lossy, $expectedNative ) { - $content = $this->newContent( $text ); - - $converted = $content->convert( $model, $lossy ); - - if ( $expectedNative === false ) { - $this->assertFalse( $converted, "conversion to $model was expected to fail!" ); - } else { - $this->assertInstanceOf( 'Content', $converted ); - $this->assertEquals( $expectedNative, $converted->getNativeData() ); - } - } -} diff --git a/tests/phpunit/includes/content/WikitextContentHandlerTest.php b/tests/phpunit/includes/content/WikitextContentHandlerTest.php deleted file mode 100644 index 75a72784..00000000 --- a/tests/phpunit/includes/content/WikitextContentHandlerTest.php +++ /dev/null @@ -1,227 +0,0 @@ -<?php - -/** - * @group ContentHandler - */ -class WikitextContentHandlerTest extends MediaWikiLangTestCase { - - /** - * @var ContentHandler - */ - var $handler; - - public function setUp() { - parent::setUp(); - - $this->handler = ContentHandler::getForModelID( CONTENT_MODEL_WIKITEXT ); - } - - /** - * @covers WikitextContentHandler::serializeContent - */ - public function testSerializeContent() { - $content = new WikitextContent( 'hello world' ); - - $this->assertEquals( 'hello world', $this->handler->serializeContent( $content ) ); - $this->assertEquals( 'hello world', $this->handler->serializeContent( $content, CONTENT_FORMAT_WIKITEXT ) ); - - try { - $this->handler->serializeContent( $content, 'dummy/foo' ); - $this->fail( "serializeContent() should have failed on unknown format" ); - } catch ( MWException $e ) { - // ok, as expected - } - } - - /** - * @covers WikitextContentHandler::unserializeContent - */ - public function testUnserializeContent() { - $content = $this->handler->unserializeContent( 'hello world' ); - $this->assertEquals( 'hello world', $content->getNativeData() ); - - $content = $this->handler->unserializeContent( 'hello world', CONTENT_FORMAT_WIKITEXT ); - $this->assertEquals( 'hello world', $content->getNativeData() ); - - try { - $this->handler->unserializeContent( 'hello world', 'dummy/foo' ); - $this->fail( "unserializeContent() should have failed on unknown format" ); - } catch ( MWException $e ) { - // ok, as expected - } - } - - /** - * @covers WikitextContentHandler::makeEmptyContent - */ - public function testMakeEmptyContent() { - $content = $this->handler->makeEmptyContent(); - - $this->assertTrue( $content->isEmpty() ); - $this->assertEquals( '', $content->getNativeData() ); - } - - public static function dataIsSupportedFormat() { - return array( - array( null, true ), - array( CONTENT_FORMAT_WIKITEXT, true ), - array( 99887766, false ), - ); - } - - /** - * @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 ) ); - } - - public static function dataMerge3() { - return array( - array( - "first paragraph - - second paragraph\n", - - "FIRST paragraph - - second paragraph\n", - - "first paragraph - - SECOND paragraph\n", - - "FIRST paragraph - - SECOND paragraph\n", - ), - - array( "first paragraph - second paragraph\n", - - "Bla bla\n", - - "Blubberdibla\n", - - false, - ), - ); - } - - /** - * @dataProvider dataMerge3 - * @covers WikitextContentHandler::merge3 - */ - public function testMerge3( $old, $mine, $yours, $expected ) { - $this->checkHasDiff3(); - - // test merge - $oldContent = new WikitextContent( $old ); - $myContent = new WikitextContent( $mine ); - $yourContent = new WikitextContent( $yours ); - - $merged = $this->handler->merge3( $oldContent, $myContent, $yourContent ); - - $this->assertEquals( $expected, $merged ? $merged->getNativeData() : $merged ); - } - - public static function dataGetAutosummary() { - return array( - array( - 'Hello there, world!', - '#REDIRECT [[Foo]]', - 0, - '/^Redirected page .*Foo/' - ), - - array( - null, - 'Hello world!', - EDIT_NEW, - '/^Created page .*Hello/' - ), - - array( - 'Hello there, world!', - '', - 0, - '/^Blanked/' - ), - - array( - 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut - labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et - ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.', - 'Hello world!', - 0, - '/^Replaced .*Hello/' - ), - - array( - 'foo', - 'bar', - 0, - '/^$/' - ), - ); - } - - /** - * @dataProvider dataGetAutosummary - * @covers WikitextContentHandler::getAutosummary - */ - public function testGetAutosummary( $old, $new, $flags, $expected ) { - $oldContent = is_null( $old ) ? null : new WikitextContent( $old ); - $newContent = is_null( $new ) ? null : new WikitextContent( $new ); - - $summary = $this->handler->getAutosummary( $oldContent, $newContent, $flags ); - - $this->assertTrue( (bool)preg_match( $expected, $summary ), "Autosummary didn't match expected pattern $expected: $summary" ); - } - - /** - * @todo Text case requires database, should be done by a test class in the Database group - */ - /* - public function testGetAutoDeleteReason( Title $title, &$hasHistory ) {} - */ - - /** - * @todo Text case requires database, should be done by a test class in the Database group - */ - /* - 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 deleted file mode 100644 index 9f20073d..00000000 --- a/tests/phpunit/includes/content/WikitextContentTest.php +++ /dev/null @@ -1,404 +0,0 @@ -<?php - -/** - * @group ContentHandler - * - * @group Database - * ^--- needed, because we do need the database to test link updates - */ -class WikitextContentTest extends TextContentTest { - static $sections = "Intro - -== stuff == -hello world - -== test == -just a test - -== foo == -more stuff -"; - - public function newContent( $text ) { - return new WikitextContent( $text ); - } - - public static function dataGetParserOutput() { - return array( - array( - "WikitextContentTest_testGetParserOutput", - CONTENT_MODEL_WIKITEXT, - "hello ''world''\n", - "<p>hello <i>world</i>\n</p>" - ), - // TODO: more...? - ); - } - - public static function dataGetSecondaryDataUpdates() { - return array( - array( "WikitextContentTest_testGetSecondaryDataUpdates_1", - CONTENT_MODEL_WIKITEXT, "hello ''world''\n", - array( - 'LinksUpdate' => array( - 'mRecursive' => true, - 'mLinks' => array() - ) - ) - ), - array( "WikitextContentTest_testGetSecondaryDataUpdates_2", - CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n", - array( - 'LinksUpdate' => array( - 'mRecursive' => true, - 'mLinks' => array( - array( 'World_test_21344' => 0 ) - ) - ) - ) - ), - // TODO: more...? - ); - } - - /** - * @dataProvider dataGetSecondaryDataUpdates - * @group Database - * @covers WikitextContent::getSecondaryDataUpdates - */ - public function testGetSecondaryDataUpdates( $title, $model, $text, $expectedStuff ) { - $ns = $this->getDefaultWikitextNS(); - $title = Title::newFromText( $title, $ns ); - - $content = ContentHandler::makeContent( $text, $title, $model ); - - $page = WikiPage::factory( $title ); - $page->doEditContent( $content, '' ); - - $updates = $content->getSecondaryDataUpdates( $title ); - - // make updates accessible by class name - foreach ( $updates as $update ) { - $class = get_class( $update ); - $updates[$class] = $update; - } - - foreach ( $expectedStuff as $class => $fieldValues ) { - $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" ); - - $update = $updates[$class]; - - foreach ( $fieldValues as $field => $value ) { - $v = $update->$field; #if the field doesn't exist, just crash and burn - $this->assertEquals( $value, $v, "unexpected value for field $field in instance of $class" ); - } - } - - $page->doDeleteArticle( '' ); - } - - public static function dataGetSection() { - return array( - array( WikitextContentTest::$sections, - "0", - "Intro" - ), - array( WikitextContentTest::$sections, - "2", - "== test == -just a test" - ), - array( WikitextContentTest::$sections, - "8", - false - ), - ); - } - - /** - * @dataProvider dataGetSection - * @covers WikitextContent::getSection - */ - public function testGetSection( $text, $sectionId, $expectedText ) { - $content = $this->newContent( $text ); - - $sectionContent = $content->getSection( $sectionId ); - if ( is_object( $sectionContent ) ) { - $sectionText = $sectionContent->getNativeData(); - } else { - $sectionText = $sectionContent; - } - - $this->assertEquals( $expectedText, $sectionText ); - } - - public static function dataReplaceSection() { - return array( - array( WikitextContentTest::$sections, - "0", - "No more", - null, - trim( preg_replace( '/^Intro/sm', 'No more', WikitextContentTest::$sections ) ) - ), - array( WikitextContentTest::$sections, - "", - "No more", - null, - "No more" - ), - array( WikitextContentTest::$sections, - "2", - "== TEST ==\nmore fun", - null, - trim( preg_replace( '/^== test ==.*== foo ==/sm', "== TEST ==\nmore fun\n\n== foo ==", WikitextContentTest::$sections ) ) - ), - array( WikitextContentTest::$sections, - "8", - "No more", - null, - WikitextContentTest::$sections - ), - array( WikitextContentTest::$sections, - "new", - "No more", - "New", - trim( WikitextContentTest::$sections ) . "\n\n\n== New ==\n\nNo more" - ), - ); - } - - /** - * @dataProvider dataReplaceSection - * @covers WikitextContent::replaceSection - */ - public function testReplaceSection( $text, $section, $with, $sectionTitle, $expected ) { - $content = $this->newContent( $text ); - $c = $content->replaceSection( $section, $this->newContent( $with ), $sectionTitle ); - - $this->assertEquals( $expected, is_null( $c ) ? null : $c->getNativeData() ); - } - - /** - * @covers WikitextContent::addSectionHeader - */ - public function testAddSectionHeader() { - $content = $this->newContent( 'hello world' ); - $content = $content->addSectionHeader( 'test' ); - - $this->assertEquals( "== test ==\n\nhello world", $content->getNativeData() ); - } - - public static function dataPreSaveTransform() { - return array( - array( 'hello this is ~~~', - "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]", - ), - array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>', - 'hello \'\'this\'\' is <nowiki>~~~</nowiki>', - ), - array( // rtrim - " Foo \n ", - " Foo", - ), - ); - } - - public static function dataPreloadTransform() { - return array( - array( 'hello this is ~~~', - "hello this is ~~~", - ), - array( 'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>', - 'hello \'\'this\'\' is bar', - ), - ); - } - - public static function dataGetRedirectTarget() { - return array( - array( '#REDIRECT [[Test]]', - 'Test', - ), - array( '#REDIRECT Test', - null, - ), - array( '* #REDIRECT [[Test]]', - null, - ), - ); - } - - public static function dataGetTextForSummary() { - return array( - array( "hello\nworld.", - 16, - 'hello world.', - ), - array( 'hello world.', - 8, - 'hello...', - ), - array( '[[hello world]].', - 8, - 'hel...', - ), - ); - } - - /** - * @todo Test needs database! Should be done by a test class in the Database group. - */ - /* - public function getRedirectChain() { - $text = $this->getNativeData(); - return Title::newFromRedirectArray( $text ); - } - */ - - /** - * @todo Test needs database! Should be done by a test class in the Database group. - */ - /* - public function getUltimateRedirectTarget() { - $text = $this->getNativeData(); - return Title::newFromRedirectRecurse( $text ); - } - */ - - public static function dataIsCountable() { - return array( - array( '', - null, - 'any', - true - ), - array( 'Foo', - null, - 'any', - true - ), - array( 'Foo', - null, - 'comma', - false - ), - array( 'Foo, bar', - null, - 'comma', - true - ), - array( 'Foo', - null, - 'link', - false - ), - array( 'Foo [[bar]]', - null, - 'link', - true - ), - array( 'Foo', - true, - 'link', - true - ), - array( 'Foo [[bar]]', - false, - 'link', - false - ), - array( '#REDIRECT [[bar]]', - true, - 'any', - false - ), - array( '#REDIRECT [[bar]]', - true, - 'comma', - false - ), - array( '#REDIRECT [[bar]]', - true, - 'link', - false - ), - ); - } - - /** - * @covers WikitextContent::matchMagicWord - */ - public function testMatchMagicWord() { - $mw = MagicWord::get( "staticredirect" ); - - $content = $this->newContent( "#REDIRECT [[FOO]]\n__STATICREDIRECT__" ); - $this->assertTrue( $content->matchMagicWord( $mw ), "should have matched magic word" ); - - $content = $this->newContent( "#REDIRECT [[FOO]]" ); - $this->assertFalse( $content->matchMagicWord( $mw ), "should not have matched magic word" ); - } - - /** - * @covers WikitextContent::updateRedirect - */ - public function testUpdateRedirect() { - $target = Title::newFromText( "testUpdateRedirect_target" ); - - // test with non-redirect page - $content = $this->newContent( "hello world." ); - $newContent = $content->updateRedirect( $target ); - - $this->assertTrue( $content->equals( $newContent ), "content should be unchanged" ); - - // test with actual redirect - $content = $this->newContent( "#REDIRECT [[Someplace]]" ); - $newContent = $content->updateRedirect( $target ); - - $this->assertFalse( $content->equals( $newContent ), "content should have changed" ); - $this->assertTrue( $newContent->isRedirect(), "new content should be a redirect" ); - - $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." ); - - $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getContentHandler()->getModelID() ); - } - - public static function dataEquals() { - return array( - array( new WikitextContent( "hallo" ), null, false ), - array( new WikitextContent( "hallo" ), new WikitextContent( "hallo" ), true ), - array( new WikitextContent( "hallo" ), new JavaScriptContent( "hallo" ), false ), - array( new WikitextContent( "hallo" ), new TextContent( "hallo" ), false ), - array( new WikitextContent( "hallo" ), new WikitextContent( "HALLO" ), false ), - ); - } - - public static function dataGetDeletionUpdates() { - return array( - array( "WikitextContentTest_testGetSecondaryDataUpdates_1", - CONTENT_MODEL_WIKITEXT, "hello ''world''\n", - array( 'LinksDeletionUpdate' => array() ) - ), - array( "WikitextContentTest_testGetSecondaryDataUpdates_2", - CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n", - array( 'LinksDeletionUpdate' => array() ) - ), - // @todo more...? - ); - } -} diff --git a/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php b/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php deleted file mode 100644 index ba63c091..00000000 --- a/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php +++ /dev/null @@ -1,209 +0,0 @@ -<?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 deleted file mode 100644 index bdd567e7..00000000 --- a/tests/phpunit/includes/db/DatabaseSQLTest.php +++ /dev/null @@ -1,721 +0,0 @@ -<?php - -/** - * Test the abstract database layer - * This is a non DBMS depending test. - */ -class DatabaseSQLTest extends MediaWikiTestCase { - - /** - * @var DatabaseTestHelper - */ - private $database; - - protected function setUp() { - parent::setUp(); - $this->database = new DatabaseTestHelper( __CLASS__ ); - } - - protected function assertLastSql( $sqlText ) { - $this->assertEquals( - $this->database->getLastSqls(), - $sqlText - ); - } - - /** - * @dataProvider provideSelect - * @covers DatabaseBase::select - */ - 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() - ); - $this->assertLastSql( $sqlText ); - } - - public static function provideSelect() { - return array( - array( - array( - 'tables' => 'table', - 'fields' => array( 'field', 'alias' => 'field2' ), - 'conds' => array( 'alias' => 'text' ), - ), - "SELECT field,field2 AS alias " . - "FROM table " . - "WHERE alias = 'text'" - ), - array( - array( - 'tables' => 'table', - 'fields' => array( 'field', 'alias' => 'field2' ), - 'conds' => array( 'alias' => 'text' ), - 'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ), - ), - "SELECT field,field2 AS alias " . - "FROM table " . - "WHERE alias = 'text' " . - "ORDER BY field " . - "LIMIT 1" - ), - array( - array( - 'tables' => array( 'table', 't2' => 'table2' ), - 'fields' => array( 'tid', 'field', 'alias' => 'field2', 't2.id' ), - 'conds' => array( 'alias' => 'text' ), - 'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ), - 'join_conds' => array( 't2' => array( - 'LEFT JOIN', 'tid = t2.id' - ) ), - ), - "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" - ), - array( - array( - 'tables' => array( 'table', 't2' => 'table2' ), - 'fields' => array( 'tid', 'field', 'alias' => 'field2', 't2.id' ), - 'conds' => array( 'alias' => 'text' ), - 'options' => array( 'LIMIT' => 1, 'GROUP BY' => 'field', 'HAVING' => 'COUNT(*) > 1' ), - 'join_conds' => array( 't2' => array( - 'LEFT JOIN', 'tid = t2.id' - ) ), - ), - "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" - ), - array( - array( - 'tables' => array( 'table', 't2' => 'table2' ), - 'fields' => array( 'tid', 'field', 'alias' => 'field2', 't2.id' ), - 'conds' => array( 'alias' => 'text' ), - 'options' => array( 'LIMIT' => 1, 'GROUP BY' => array( 'field', 'field2' ), 'HAVING' => array( 'COUNT(*) > 1', 'field' => 1 ) ), - 'join_conds' => array( 't2' => array( - 'LEFT JOIN', 'tid = t2.id' - ) ), - ), - "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 - */ - public function testConditional( $sql, $sqlText ) { - $this->assertEquals( trim( $this->database->conditional( - $sql['conds'], - $sql['true'], - $sql['false'] - ) ), $sqlText ); - } - - public static function provideConditional() { - return array( - array( - array( - 'conds' => array( 'field' => 'text' ), - 'true' => 1, - 'false' => 'NULL', - ), - "(CASE WHEN field = 'text' THEN 1 ELSE NULL END)" - ), - array( - array( - 'conds' => array( 'field' => 'text', 'field2' => 'anothertext' ), - 'true' => 1, - 'false' => 'NULL', - ), - "(CASE WHEN field = 'text' AND field2 = 'anothertext' THEN 1 ELSE NULL END)" - ), - array( - array( - 'conds' => 'field=1', - 'true' => 1, - 'false' => 'NULL', - ), - "(CASE WHEN field=1 THEN 1 ELSE NULL END)" - ), - ); - } - - /** - * @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 deleted file mode 100644 index 70ee9465..00000000 --- a/tests/phpunit/includes/db/DatabaseSqliteTest.php +++ /dev/null @@ -1,421 +0,0 @@ -<?php - -class MockDatabaseSqlite extends DatabaseSqliteStandalone { - var $lastQuery; - - function __construct() { - parent::__construct( ':memory:' ); - } - - function query( $sql, $fname = '', $tempIgnore = false ) { - $this->lastQuery = $sql; - - return true; - } - - /** - * Override parent visibility to public - */ - public function replaceVars( $s ) { - return parent::replaceVars( $s ); - } -} - -/** - * @group sqlite - * @group Database - * @group medium - */ -class DatabaseSqliteTest extends MediaWikiTestCase { - - /** - * @var MockDatabaseSqlite - */ - var $db; - - protected function setUp() { - parent::setUp(); - - if ( !Sqlite::isPresent() ) { - $this->markTestSkipped( 'No SQLite support detected' ); - } - $this->db = new MockDatabaseSqlite(); - if ( version_compare( $this->db->getServerVersion(), '3.6.0', '<' ) ) { - $this->markTestSkipped( "SQLite at least 3.6 required, {$this->db->getServerVersion()} found" ); - } - } - - private function replaceVars( $sql ) { - // normalize spacing to hide implementation details - return preg_replace( '/\s+/', ' ', $this->db->replaceVars( $sql ) ); - } - - private function assertResultIs( $expected, $res ) { - $this->assertNotNull( $res ); - $i = 0; - foreach ( $res as $row ) { - foreach ( $expected[$i] as $key => $value ) { - $this->assertTrue( isset( $row->$key ) ); - $this->assertEquals( $value, $row->$key ); - } - $i++; - } - $this->assertEquals( count( $expected ), $i, 'Unexpected number of rows' ); - } - - public static function provideAddQuotes() { - return array( - array( // #0: empty - '', "''" - ), - array( // #1: simple - 'foo bar', "'foo bar'" - ), - array( // #2: including quote - 'foo\'bar', "'foo''bar'" - ), - array( // #3: including \0 (must be represented as hex, per https://bugs.php.net/bug.php?id=63419) - "x\0y", - "x'780079'", - ), - array( // #4: blob object (must be represented as hex) - new Blob( "hello" ), - "x'68656c6c6f'", - ), - ); - } - - /** - * @dataProvider provideAddQuotes() - * @covers DatabaseSqlite::addQuotes - */ - public function testAddQuotes( $value, $expected ) { - // check quoting - $db = new DatabaseSqliteStandalone( ':memory:' ); - $this->assertEquals( $expected, $db->addQuotes( $value ), 'string not quoted as expected' ); - - // ok, quoting works as expected, now try a round trip. - $re = $db->query( 'select ' . $db->addQuotes( $value ) ); - - $this->assertTrue( $re !== false, 'query failed' ); - - if ( $row = $re->fetchRow() ) { - if ( $value instanceof Blob ) { - $value = $value->fetch(); - } - - $this->assertEquals( $value, $row[0], 'string mangled by the database' ); - } else { - $this->fail( 'query returned no result' ); - } - } - - /** - * @covers DatabaseSqlite::replaceVars - */ - public function testReplaceVars() { - $this->assertEquals( 'foo', $this->replaceVars( 'foo' ), "Don't break anything accidentally" ); - - $this->assertEquals( "CREATE TABLE /**/foo (foo_key INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " - . "foo_bar TEXT, foo_name TEXT NOT NULL DEFAULT '', foo_int INTEGER, foo_int2 INTEGER );", - $this->replaceVars( "CREATE TABLE /**/foo (foo_key int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - foo_bar char(13), foo_name varchar(255) binary NOT NULL DEFAULT '', foo_int tinyint ( 8 ), foo_int2 int(16) ) ENGINE=MyISAM;" ) - ); - - $this->assertEquals( "CREATE TABLE foo ( foo1 REAL, foo2 REAL, foo3 REAL );", - $this->replaceVars( "CREATE TABLE foo ( foo1 FLOAT, foo2 DOUBLE( 1,10), foo3 DOUBLE PRECISION );" ) - ); - - $this->assertEquals( "CREATE TABLE foo ( foo_binary1 BLOB, foo_binary2 BLOB );", - $this->replaceVars( "CREATE TABLE foo ( foo_binary1 binary(16), foo_binary2 varbinary(32) );" ) - ); - - $this->assertEquals( "CREATE TABLE text ( text_foo TEXT );", - $this->replaceVars( "CREATE TABLE text ( text_foo tinytext );" ), - 'Table name changed' - ); - - $this->assertEquals( "CREATE TABLE foo ( foobar INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL );", - $this->replaceVars( "CREATE TABLE foo ( foobar INT PRIMARY KEY NOT NULL AUTO_INCREMENT );" ) - ); - $this->assertEquals( "CREATE TABLE foo ( foobar INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL );", - $this->replaceVars( "CREATE TABLE foo ( foobar INT PRIMARY KEY AUTO_INCREMENT NOT NULL );" ) - ); - - $this->assertEquals( "CREATE TABLE enums( enum1 TEXT, myenum TEXT)", - $this->replaceVars( "CREATE TABLE enums( enum1 ENUM('A', 'B'), myenum ENUM ('X', 'Y'))" ) - ); - - $this->assertEquals( "ALTER TABLE foo ADD COLUMN foo_bar INTEGER DEFAULT 42", - $this->replaceVars( "ALTER TABLE foo\nADD COLUMN foo_bar int(10) unsigned DEFAULT 42" ) - ); - } - - /** - * @covers DatabaseSqlite::tableName - */ - public function testTableName() { - // @todo Moar! - $db = new DatabaseSqliteStandalone( ':memory:' ); - $this->assertEquals( 'foo', $db->tableName( 'foo' ) ); - $this->assertEquals( 'sqlite_master', $db->tableName( 'sqlite_master' ) ); - $db->tablePrefix( 'foo' ); - $this->assertEquals( 'sqlite_master', $db->tableName( 'sqlite_master' ) ); - $this->assertEquals( 'foobar', $db->tableName( 'bar' ) ); - } - - /** - * @covers DatabaseSqlite::duplicateTableStructure - */ - public function testDuplicateTableStructure() { - $db = new DatabaseSqliteStandalone( ':memory:' ); - $db->query( 'CREATE TABLE foo(foo, barfoo)' ); - - $db->duplicateTableStructure( 'foo', 'bar' ); - $this->assertEquals( 'CREATE TABLE "bar"(foo, barfoo)', - $db->selectField( 'sqlite_master', 'sql', array( 'name' => 'bar' ) ), - 'Normal table duplication' - ); - - $db->duplicateTableStructure( 'foo', 'baz', true ); - $this->assertEquals( 'CREATE TABLE "baz"(foo, barfoo)', - $db->selectField( 'sqlite_temp_master', 'sql', array( 'name' => 'baz' ) ), - 'Creation of temporary duplicate' - ); - $this->assertEquals( 0, - $db->selectField( 'sqlite_master', 'COUNT(*)', array( 'name' => 'baz' ) ), - 'Create a temporary duplicate only' - ); - } - - /** - * @covers DatabaseSqlite::duplicateTableStructure - */ - public function testDuplicateTableStructureVirtual() { - $db = new DatabaseSqliteStandalone( ':memory:' ); - if ( $db->getFulltextSearchModule() != 'FTS3' ) { - $this->markTestSkipped( 'FTS3 not supported, cannot create virtual tables' ); - } - $db->query( 'CREATE VIRTUAL TABLE "foo" USING FTS3(foobar)' ); - - $db->duplicateTableStructure( 'foo', 'bar' ); - $this->assertEquals( 'CREATE VIRTUAL TABLE "bar" USING FTS3(foobar)', - $db->selectField( 'sqlite_master', 'sql', array( 'name' => 'bar' ) ), - 'Duplication of virtual tables' - ); - - $db->duplicateTableStructure( 'foo', 'baz', true ); - $this->assertEquals( 'CREATE VIRTUAL TABLE "baz" USING FTS3(foobar)', - $db->selectField( 'sqlite_master', 'sql', array( 'name' => 'baz' ) ), - "Can't create temporary virtual tables, should fall back to non-temporary duplication" - ); - } - - /** - * @covers DatabaseSqlite::deleteJoin - */ - public function testDeleteJoin() { - $db = new DatabaseSqliteStandalone( ':memory:' ); - $db->query( 'CREATE TABLE a (a_1)', __METHOD__ ); - $db->query( 'CREATE TABLE b (b_1, b_2)', __METHOD__ ); - $db->insert( 'a', array( - array( 'a_1' => 1 ), - array( 'a_1' => 2 ), - array( 'a_1' => 3 ), - ), - __METHOD__ - ); - $db->insert( 'b', array( - array( 'b_1' => 2, 'b_2' => 'a' ), - array( 'b_1' => 3, 'b_2' => 'b' ), - ), - __METHOD__ - ); - $db->deleteJoin( 'a', 'b', 'a_1', 'b_1', array( 'b_2' => 'a' ), __METHOD__ ); - $res = $db->query( "SELECT * FROM a", __METHOD__ ); - $this->assertResultIs( array( - array( 'a_1' => 1 ), - array( 'a_1' => 3 ), - ), - $res - ); - } - - public function testEntireSchema() { - global $IP; - - $result = Sqlite::checkSqlSyntax( "$IP/maintenance/tables.sql" ); - if ( $result !== true ) { - $this->fail( $result ); - } - $this->assertTrue( true ); // avoid test being marked as incomplete due to lack of assertions - } - - /** - * Runs upgrades of older databases and compares results with current schema - * @todo Currently only checks list of tables - */ - public function testUpgrades() { - global $IP, $wgVersion, $wgProfileToDatabase; - - // Versions tested - $versions = array( - //'1.13', disabled for now, was totally screwed up - // SQLite wasn't included in 1.14 - '1.15', - '1.16', - '1.17', - '1.18', - ); - - // Mismatches for these columns we can safely ignore - $ignoredColumns = array( - 'user_newtalk.user_last_timestamp', // r84185 - ); - - $currentDB = new DatabaseSqliteStandalone( ':memory:' ); - $currentDB->sourceFile( "$IP/maintenance/tables.sql" ); - if ( $wgProfileToDatabase ) { - $currentDB->sourceFile( "$IP/maintenance/sqlite/archives/patch-profiling.sql" ); - } - $currentTables = $this->getTables( $currentDB ); - sort( $currentTables ); - - foreach ( $versions as $version ) { - $versions = "upgrading from $version to $wgVersion"; - $db = $this->prepareDB( $version ); - $tables = $this->getTables( $db ); - $this->assertEquals( $currentTables, $tables, "Different tables $versions" ); - foreach ( $tables as $table ) { - $currentCols = $this->getColumns( $currentDB, $table ); - $cols = $this->getColumns( $db, $table ); - $this->assertEquals( - array_keys( $currentCols ), - array_keys( $cols ), - "Mismatching columns for table \"$table\" $versions" - ); - foreach ( $currentCols as $name => $column ) { - $fullName = "$table.$name"; - $this->assertEquals( - (bool)$column->pk, - (bool)$cols[$name]->pk, - "PRIMARY KEY status does not match for column $fullName $versions" - ); - if ( !in_array( $fullName, $ignoredColumns ) ) { - $this->assertEquals( - (bool)$column->notnull, - (bool)$cols[$name]->notnull, - "NOT NULL status does not match for column $fullName $versions" - ); - $this->assertEquals( - $column->dflt_value, - $cols[$name]->dflt_value, - "Default values does not match for column $fullName $versions" - ); - } - } - $currentIndexes = $this->getIndexes( $currentDB, $table ); - $indexes = $this->getIndexes( $db, $table ); - $this->assertEquals( - array_keys( $currentIndexes ), - array_keys( $indexes ), - "mismatching indexes for table \"$table\" $versions" - ); - } - $db->close(); - } - } - - /** - * @covers DatabaseSqlite::insertId - */ - public function testInsertIdType() { - $db = new DatabaseSqliteStandalone( ':memory:' ); - - $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" ); - } - - private function prepareDB( $version ) { - static $maint = null; - if ( $maint === null ) { - $maint = new FakeMaintenance(); - $maint->loadParamsAndArgs( null, array( 'quiet' => 1 ) ); - } - - global $IP; - $db = new DatabaseSqliteStandalone( ':memory:' ); - $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', - 'searchindex_content', - 'searchindex_segments', - 'searchindex_segdir', - // FTS4 ready!!1 - 'searchindex_docsize', - 'searchindex_stat', - ); - foreach ( $excluded as $t ) { - unset( $list[$t] ); - } - $list = array_flip( $list ); - sort( $list ); - - return $list; - } - - private function getColumns( $db, $table ) { - $cols = array(); - $res = $db->query( "PRAGMA table_info($table)" ); - $this->assertNotNull( $res ); - foreach ( $res as $col ) { - $cols[$col->name] = $col; - } - ksort( $cols ); - - return $cols; - } - - private function getIndexes( $db, $table ) { - $indexes = array(); - $res = $db->query( "PRAGMA index_list($table)" ); - $this->assertNotNull( $res ); - foreach ( $res as $index ) { - $res2 = $db->query( "PRAGMA index_info({$index->name})" ); - $this->assertNotNull( $res2 ); - $index->columns = array(); - foreach ( $res2 as $col ) { - $index->columns[] = $col; - } - $indexes[$index->name] = $index; - } - ksort( $indexes ); - - return $indexes; - } - - public function testCaseInsensitiveLike() { - // TODO: Test this for all databases - $db = new DatabaseSqliteStandalone( ':memory:' ); - $res = $db->query( 'SELECT "a" LIKE "A" AS a' ); - $row = $res->fetchRow(); - $this->assertFalse( (bool)$row['a'] ); - } -} diff --git a/tests/phpunit/includes/db/DatabaseTest.php b/tests/phpunit/includes/db/DatabaseTest.php deleted file mode 100644 index 301fc990..00000000 --- a/tests/phpunit/includes/db/DatabaseTest.php +++ /dev/null @@ -1,234 +0,0 @@ -<?php - -/** - * @group Database - * @group DatabaseBase - */ -class DatabaseTest extends MediaWikiTestCase { - /** - * @var DatabaseBase - */ - var $db; - var $functionTest = false; - - protected function setUp() { - parent::setUp(); - $this->db = wfGetDB( DB_MASTER ); - } - - protected function tearDown() { - parent::tearDown(); - if ( $this->functionTest ) { - $this->dropFunctions(); - $this->functionTest = false; - } - } - /** - * @covers DatabaseBase::dropTable - */ - public function testAddQuotesNull() { - $check = "NULL"; - if ( $this->db->getType() === 'sqlite' || $this->db->getType() === 'oracle' ) { - $check = "''"; - } - $this->assertEquals( $check, $this->db->addQuotes( null ) ); - } - - public function testAddQuotesInt() { - # returning just "1234" should be ok too, though... - # maybe - $this->assertEquals( - "'1234'", - $this->db->addQuotes( 1234 ) ); - } - - public function testAddQuotesFloat() { - # returning just "1234.5678" would be ok too, though - $this->assertEquals( - "'1234.5678'", - $this->db->addQuotes( 1234.5678 ) ); - } - - public function testAddQuotesString() { - $this->assertEquals( - "'string'", - $this->db->addQuotes( 'string' ) ); - } - - public function testAddQuotesStringQuote() { - $check = "'string''s cause trouble'"; - if ( $this->db->getType() === 'mysql' ) { - $check = "'string\'s cause trouble'"; - } - $this->assertEquals( - $check, - $this->db->addQuotes( "string's cause trouble" ) ); - } - - private function getSharedTableName( $table, $database, $prefix, $format = 'quoted' ) { - global $wgSharedDB, $wgSharedTables, $wgSharedPrefix; - - $oldName = $wgSharedDB; - $oldTables = $wgSharedTables; - $oldPrefix = $wgSharedPrefix; - - $wgSharedDB = $database; - $wgSharedTables = array( $table ); - $wgSharedPrefix = $prefix; - - $ret = $this->db->tableName( $table, $format ); - - $wgSharedDB = $oldName; - $wgSharedTables = $oldTables; - $wgSharedPrefix = $oldPrefix; - - return $ret; - } - - private function prefixAndQuote( $table, $database = null, $prefix = null, $format = 'quoted' ) { - if ( $this->db->getType() === 'sqlite' || $format !== 'quoted' ) { - $quote = ''; - } elseif ( $this->db->getType() === 'mysql' ) { - $quote = '`'; - } elseif ( $this->db->getType() === 'oracle' ) { - $quote = '/*Q*/'; - } else { - $quote = '"'; - } - - if ( $database !== null ) { - if ( $this->db->getType() === 'oracle' ) { - $database = $quote . $database . '.'; - } else { - $database = $quote . $database . $quote . '.'; - } - } - - if ( $prefix === null ) { - $prefix = $this->dbPrefix(); - } - - if ( $this->db->getType() === 'oracle' ) { - return strtoupper($database . $quote . $prefix . $table); - } else { - return $database . $quote . $prefix . $table . $quote; - } - } - - public function testTableNameLocal() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename' ), - $this->db->tableName( 'tablename' ) - ); - } - - public function testTableNameRawLocal() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename', null, null, 'raw' ), - $this->db->tableName( 'tablename', 'raw' ) - ); - } - - public function testTableNameShared() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'sharedatabase', 'sh_' ), - $this->getSharedTableName( 'tablename', 'sharedatabase', 'sh_' ) - ); - - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'sharedatabase', null ), - $this->getSharedTableName( 'tablename', 'sharedatabase', null ) - ); - } - - public function testTableNameRawShared() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'sharedatabase', 'sh_', 'raw' ), - $this->getSharedTableName( 'tablename', 'sharedatabase', 'sh_', 'raw' ) - ); - - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'sharedatabase', null, 'raw' ), - $this->getSharedTableName( 'tablename', 'sharedatabase', null, 'raw' ) - ); - } - - public function testTableNameForeign() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'databasename', '' ), - $this->db->tableName( 'databasename.tablename' ) - ); - } - - public function testTableNameRawForeign() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'databasename', '', 'raw' ), - $this->db->tableName( 'databasename.tablename', 'raw' ) - ); - } - - public function testFillPreparedEmpty() { - $sql = $this->db->fillPrepared( - 'SELECT * FROM interwiki', array() ); - $this->assertEquals( - "SELECT * FROM interwiki", - $sql ); - } - - public function testFillPreparedQuestion() { - $sql = $this->db->fillPrepared( - 'SELECT * FROM cur WHERE cur_namespace=? AND cur_title=?', - array( 4, "Snicker's_paradox" ) ); - - $check = "SELECT * FROM cur WHERE cur_namespace='4' AND cur_title='Snicker''s_paradox'"; - if ( $this->db->getType() === 'mysql' ) { - $check = "SELECT * FROM cur WHERE cur_namespace='4' AND cur_title='Snicker\'s_paradox'"; - } - $this->assertEquals( $check, $sql ); - } - - public function testFillPreparedBang() { - $sql = $this->db->fillPrepared( - 'SELECT user_id FROM ! WHERE user_name=?', - array( '"user"', "Slash's Dot" ) ); - - $check = "SELECT user_id FROM \"user\" WHERE user_name='Slash''s Dot'"; - if ( $this->db->getType() === 'mysql' ) { - $check = "SELECT user_id FROM \"user\" WHERE user_name='Slash\'s Dot'"; - } - $this->assertEquals( $check, $sql ); - } - - public function testFillPreparedRaw() { - $sql = $this->db->fillPrepared( - "SELECT * FROM cur WHERE cur_title='This_\\&_that,_WTF\\?\\!'", - array( '"user"', "Slash's Dot" ) ); - $this->assertEquals( - "SELECT * FROM cur WHERE cur_title='This_&_that,_WTF?!'", - $sql ); - } - - public function testStoredFunctions() { - if ( !in_array( wfGetDB( DB_MASTER )->getType(), array( 'mysql', 'postgres' ) ) ) { - $this->markTestSkipped( 'MySQL or Postgres required' ); - } - global $IP; - $this->dropFunctions(); - $this->functionTest = true; - $this->assertTrue( $this->db->sourceFile( "$IP/tests/phpunit/data/db/{$this->db->getType()}/functions.sql" ) ); - $res = $this->db->query( 'SELECT mw_test_function() AS test', __METHOD__ ); - $this->assertEquals( 42, $res->fetchObject()->test ); - } - - private function dropFunctions() { - $this->db->query( 'DROP FUNCTION IF EXISTS mw_test_function' - . ( $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 deleted file mode 100644 index 790f273c..00000000 --- a/tests/phpunit/includes/db/DatabaseTestHelper.php +++ /dev/null @@ -1,166 +0,0 @@ -<?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 deleted file mode 100644 index 27d4d0e8..00000000 --- a/tests/phpunit/includes/db/ORMRowTest.php +++ /dev/null @@ -1,226 +0,0 @@ -<?php - -/** - * Abstract class to construct tests for ORMRow deriving classes. - * - * 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 - * @since 1.20 - * - * @ingroup Test - * - * @group ORM - * - * The database group has as a side effect that temporal database tables are created. This makes - * it possible to test without poisoning a production database. - * @group Database - * - * Some of the tests takes more time, and needs therefor longer time before they can be aborted - * as non-functional. The reason why tests are aborted is assumed to be set up of temporal databases - * that hold the first tests in a pending state awaiting access to the database. - * @group medium - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - */ -abstract class ORMRowTest extends \MediaWikiTestCase { - - /** - * @since 1.20 - * @return string - */ - abstract protected function getRowClass(); - - /** - * @since 1.20 - * @return IORMTable - */ - abstract protected function getTableInstance(); - - /** - * @since 1.20 - * @return array - */ - abstract public function constructorTestProvider(); - - /** - * @since 1.20 - * @param IORMRow $row - * @param array $data - */ - protected function verifyFields( IORMRow $row, array $data ) { - foreach ( array_keys( $data ) as $fieldName ) { - $this->assertEquals( $data[$fieldName], $row->getField( $fieldName ) ); - } - } - - /** - * @since 1.20 - * @param array $data - * @param boolean $loadDefaults - * @return IORMRow - */ - protected function getRowInstance( array $data, $loadDefaults ) { - $class = $this->getRowClass(); - - return new $class( $this->getTableInstance(), $data, $loadDefaults ); - } - - /** - * @since 1.20 - * @return array - */ - protected function getMockValues() { - return array( - 'id' => 1, - 'str' => 'foobar4645645', - 'int' => 42, - 'float' => 4.2, - 'bool' => true, - 'array' => array( 42, 'foobar' ), - 'blob' => new stdClass() - ); - } - - /** - * @since 1.20 - * @return array - */ - protected function getMockFields() { - $mockValues = $this->getMockValues(); - $mockFields = array(); - - foreach ( $this->getTableInstance()->getFields() as $name => $type ) { - if ( $name !== 'id' ) { - $mockFields[$name] = $mockValues[$type]; - } - } - - return $mockFields; - } - - /** - * @since 1.20 - * @return array of IORMRow - */ - public function instanceProvider() { - $instances = array(); - - foreach ( $this->constructorTestProvider() as $arguments ) { - $instances[] = array( call_user_func_array( array( $this, 'getRowInstance' ), $arguments ) ); - } - - return $instances; - } - - /** - * @dataProvider constructorTestProvider - */ - public function testConstructor( array $data, $loadDefaults ) { - $this->verifyFields( $this->getRowInstance( $data, $loadDefaults ), $data ); - } - - /** - * @dataProvider constructorTestProvider - */ - public function testSaveAndRemove( array $data, $loadDefaults ) { - $item = $this->getRowInstance( $data, $loadDefaults ); - - $this->assertTrue( $item->save() ); - - $this->assertTrue( $item->hasIdField() ); - $this->assertTrue( is_integer( $item->getId() ) ); - - $id = $item->getId(); - - $this->assertTrue( $item->save() ); - - $this->assertEquals( $id, $item->getId() ); - - $this->verifyFields( $item, $data ); - - $this->assertTrue( $item->remove() ); - - $this->assertFalse( $item->hasIdField() ); - - $this->assertTrue( $item->save() ); - - $this->verifyFields( $item, $data ); - - $this->assertTrue( $item->remove() ); - - $this->assertFalse( $item->hasIdField() ); - - $this->verifyFields( $item, $data ); - } - - /** - * @dataProvider instanceProvider - */ - public function testSetField( IORMRow $item ) { - foreach ( $this->getMockFields() as $name => $value ) { - $item->setField( $name, $value ); - $this->assertEquals( $value, $item->getField( $name ) ); - } - } - - /** - * @since 1.20 - * @param array $expected - * @param IORMRow $item - */ - protected function assertFieldValues( array $expected, IORMRow $item ) { - foreach ( $expected as $name => $type ) { - if ( $name !== 'id' ) { - $this->assertEquals( $expected[$name], $item->getField( $name ) ); - } - } - } - - /** - * @dataProvider instanceProvider - */ - public function testSetFields( IORMRow $item ) { - $originalValues = $item->getFields(); - - $item->setFields( array(), false ); - - foreach ( $item->getTable()->getFields() as $name => $type ) { - $originalHas = array_key_exists( $name, $originalValues ); - $newHas = $item->hasField( $name ); - - $this->assertEquals( $originalHas, $newHas ); - - if ( $originalHas && $newHas ) { - $this->assertEquals( $originalValues[$name], $item->getField( $name ) ); - } - } - - $mockFields = $this->getMockFields(); - - $item->setFields( $mockFields, false ); - - $this->assertFieldValues( $originalValues, $item ); - - $item->setFields( $mockFields, true ); - - $this->assertFieldValues( $mockFields, $item ); - } - - // TODO: test all of the methods! - -} diff --git a/tests/phpunit/includes/db/ORMTableTest.php b/tests/phpunit/includes/db/ORMTableTest.php deleted file mode 100644 index e583d1bc..00000000 --- a/tests/phpunit/includes/db/ORMTableTest.php +++ /dev/null @@ -1,146 +0,0 @@ -<?php -/** - * Abstract class to construct tests for ORMTable deriving classes. - * - * 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 - * @since 1.21 - * - * @ingroup Test - * - * @group ORM - * @group Database - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - * @author Daniel Kinzler - */ -class ORMTableTest extends MediaWikiTestCase { - - /** - * @since 1.21 - * @return string - */ - protected function getTableClass() { - return 'PageORMTableForTesting'; - } - - /** - * @since 1.21 - * @return IORMTable - */ - public function getTable() { - $class = $this->getTableClass(); - - return $class::singleton(); - } - - /** - * @since 1.21 - * @return string - */ - public function getRowClass() { - return $this->getTable()->getRowClass(); - } - - /** - * @since 1.21 - */ - public function testSingleton() { - $class = $this->getTableClass(); - - $this->assertInstanceOf( $class, $class::singleton() ); - $this->assertTrue( $class::singleton() === $class::singleton() ); - } - - /** - * @since 1.21 - */ - public function testIgnoreErrorsOverride() { - $table = $this->getTable(); - - $db = $table->getReadDbConnection(); - $db->ignoreErrors( true ); - - try { - $table->rawSelect( "this is invalid" ); - $this->fail( "An invalid query should trigger a DBQueryError even if ignoreErrors is enabled." ); - } catch ( DBQueryError $ex ) { - $this->assertTrue( true, "just making phpunit happy" ); - } - - $db->ignoreErrors( false ); - } -} - -/** - * Dummy ORM table for testing, reading Title objects from the page table. - * - * @since 1.21 - */ - -class PageORMTableForTesting extends ORMTable { - - /** - * @see ORMTable::getName - * - * @return string - */ - public function getName() { - return 'page'; - } - - /** - * @see ORMTable::getRowClass - * - * @return string - */ - public function getRowClass() { - return 'Title'; - } - - /** - * @see ORMTable::newRow - * - * @return IORMRow - */ - public function newRow( array $data, $loadDefaults = false ) { - return Title::makeTitle( $data['namespace'], $data['title'] ); - } - - /** - * @see ORMTable::getFields - * - * @return array - */ - public function getFields() { - return array( - 'id' => 'int', - 'namespace' => 'int', - 'title' => 'str', - ); - } - - /** - * @see ORMTable::getFieldPrefix - * - * @return string - */ - protected function getFieldPrefix() { - return 'page_'; - } -} diff --git a/tests/phpunit/includes/db/TestORMRowTest.php b/tests/phpunit/includes/db/TestORMRowTest.php deleted file mode 100644 index f65642b8..00000000 --- a/tests/phpunit/includes/db/TestORMRowTest.php +++ /dev/null @@ -1,215 +0,0 @@ -<?php - -/** - * Tests for the TestORMRow class. - * TestORMRow is a dummy class to be able to test the abstract ORMRow class. - * - * 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 - * @since 1.20 - * - * @ingroup Test - * - * @group ORM - * - * The database group has as a side effect that temporal database tables are created. This makes - * it possible to test without poisoning a production database. - * @group Database - * - * Some of the tests takes more time, and needs therefor longer time before they can be aborted - * as non-functional. The reason why tests are aborted is assumed to be set up of temporal databases - * that hold the first tests in a pending state awaiting access to the database. - * @group medium - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - */ -require_once __DIR__ . "/ORMRowTest.php"; - -class TestORMRowTest extends ORMRowTest { - - /** - * @since 1.20 - * @return string - */ - protected function getRowClass() { - return 'TestORMRow'; - } - - /** - * @since 1.20 - * @return IORMTable - */ - protected function getTableInstance() { - return TestORMTable::singleton(); - } - - protected function setUp() { - parent::setUp(); - - $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'; - - 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() { - $dbw = wfGetDB( DB_MASTER ); - $dbw->dropTable( 'orm_test', __METHOD__ ); - - parent::tearDown(); - } - - public function constructorTestProvider() { - $dbw = wfGetDB( DB_MASTER ); - return array( - array( - array( - 'name' => 'Foobar', - 'time' => $dbw->timestamp( '20120101020202' ), - 'age' => 42, - 'height' => 9000.1, - 'awesome' => true, - 'stuff' => array( 13, 11, 7, 5, 3, 2 ), - 'moarstuff' => (object)array( 'foo' => 'bar', 'bar' => array( 4, 2 ), 'baz' => true ) - ), - true - ), - ); - } - - /** - * @since 1.21 - * @return array - */ - protected function getMockValues() { - return array( - 'id' => 1, - 'str' => 'foobar4645645', - 'int' => 42, - 'float' => 4.2, - 'bool' => '', - 'array' => array( 42, 'foobar' ), - 'blob' => new stdClass() - ); - } -} - -class TestORMRow extends ORMRow { -} - -class TestORMTable extends ORMTable { - - /** - * Returns the name of the database table objects of this type are stored in. - * - * @since 1.20 - * - * @return string - */ - public function getName() { - return 'orm_test'; - } - - /** - * Returns the name of a IORMRow implementing class that - * represents single rows in this table. - * - * @since 1.20 - * - * @return string - */ - public function getRowClass() { - return 'TestORMRow'; - } - - /** - * Returns an array with the fields and their types this object contains. - * This corresponds directly to the fields in the database, without prefix. - * - * field name => type - * - * Allowed types: - * * id - * * str - * * int - * * float - * * bool - * * array - * * blob - * - * @since 1.20 - * - * @return array - */ - public function getFields() { - return array( - 'id' => 'id', - 'name' => 'str', - 'age' => 'int', - 'height' => 'float', - 'awesome' => 'bool', - 'stuff' => 'array', - 'moarstuff' => 'blob', - 'time' => 'str', // TS_MW - ); - } - - /** - * Gets the db field prefix. - * - * @since 1.20 - * - * @return string - */ - protected function getFieldPrefix() { - return 'test_'; - } -} diff --git a/tests/phpunit/includes/debug/MWDebugTest.php b/tests/phpunit/includes/debug/MWDebugTest.php deleted file mode 100644 index 6926b1c8..00000000 --- a/tests/phpunit/includes/debug/MWDebugTest.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php - -class MWDebugTest extends MediaWikiTestCase { - - - protected function setUp() { - parent::setUp(); - // Make sure MWDebug class is enabled - static $MWDebugEnabled = false; - if ( !$MWDebugEnabled ) { - MWDebug::init(); - $MWDebugEnabled = true; - } - /** Clear log before each test */ - MWDebug::clearLog(); - wfSuppressWarnings(); - } - - protected function tearDown() { - wfRestoreWarnings(); - parent::tearDown(); - } - - public function testAddLog() { - MWDebug::log( 'logging a string' ); - $this->assertEquals( - array( array( - 'msg' => 'logging a string', - 'type' => 'log', - 'caller' => __METHOD__, - ) ), - MWDebug::getLog() - ); - } - - public function testAddWarning() { - MWDebug::warning( 'Warning message' ); - $this->assertEquals( - array( array( - 'msg' => 'Warning message', - 'type' => 'warn', - 'caller' => 'MWDebugTest::testAddWarning', - ) ), - MWDebug::getLog() - ); - } - - public function testAvoidDuplicateDeprecations() { - MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); - MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); - - // assertCount() not available on WMF integration server - $this->assertEquals( 1, - count( MWDebug::getLog() ), - "Only one deprecated warning per function should be kept" - ); - } - - public function testAvoidNonConsecutivesDuplicateDeprecations() { - MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); - MWDebug::warning( 'some warning' ); - MWDebug::log( 'we could have logged something too' ); - // Another deprecation - MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); - - // assertCount() not available on WMF integration server - $this->assertEquals( 3, - count( MWDebug::getLog() ), - "Only one deprecated warning per function should be kept" - ); - } -} diff --git a/tests/phpunit/includes/filebackend/FileBackendTest.php b/tests/phpunit/includes/filebackend/FileBackendTest.php deleted file mode 100644 index fcfa724f..00000000 --- a/tests/phpunit/includes/filebackend/FileBackendTest.php +++ /dev/null @@ -1,2306 +0,0 @@ -<?php - -/** - * @group FileRepo - * @group FileBackend - * @group medium - */ -class FileBackendTest extends MediaWikiTestCase { - - /** @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(); - $uniqueId = time() . '-' . mt_rand(); - $tmpPrefix = wfTempDir() . '/filebackend-unittest-' . $uniqueId; - if ( $this->getCliArg( 'use-filebackend=' ) ) { - if ( self::$backendToUse ) { - $this->singleBackend = self::$backendToUse; - } else { - $name = $this->getCliArg( 'use-filebackend=' ); - $useConfig = array(); - foreach ( $wgFileBackends as $conf ) { - if ( $conf['name'] == $name ) { - $useConfig = $conf; - break; - } - } - $useConfig['name'] = 'localtesting'; // swap name - $useConfig['shardViaHashLevels'] = array( // test sharding - 'unittest-cont1' => array( 'levels' => 1, 'base' => 16, 'repeat' => 1 ) - ); - $class = $useConfig['class']; - self::$backendToUse = new $class( $useConfig ); - $this->singleBackend = self::$backendToUse; - } - } else { - $this->singleBackend = new FSFileBackend( array( - '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', - 'lockManager' => 'fsLockManager', - 'parallelize' => 'implicit', - 'wikiId' => wfWikiId() . $uniqueId, - 'backends' => array( - array( - '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', - 'containerPaths' => array( - 'unittest-cont1' => "{$tmpPrefix}-localtestingmulti2-cont1", - 'unittest-cont2' => "{$tmpPrefix}-localtestingmulti2-cont2" ), - 'isMultiMaster' => true - ) - ) - ) ); - $this->filesToPrune = array(); - } - - private static function baseStorePath() { - return 'mwstore://localtesting'; - } - - private function backendClass() { - return get_class( $this->backend ); - } - - /** - * @dataProvider provider_testIsStoragePath - * @covers FileBackend::isStoragePath - */ - public function testIsStoragePath( $path, $isStorePath ) { - $this->assertEquals( $isStorePath, FileBackend::isStoragePath( $path ), - "FileBackend::isStoragePath on path '$path'" ); - } - - public static function provider_testIsStoragePath() { - return array( - array( 'mwstore://', true ), - array( 'mwstore://backend', true ), - array( 'mwstore://backend/container', true ), - array( 'mwstore://backend/container/', true ), - array( 'mwstore://backend/container/path', true ), - array( 'mwstore://backend//container/', true ), - array( 'mwstore://backend//container//', true ), - array( 'mwstore://backend//container//path', true ), - array( 'mwstore:///', true ), - array( 'mwstore:/', false ), - array( 'mwstore:', false ), - ); - } - - /** - * @dataProvider provider_testSplitStoragePath - * @covers FileBackend::splitStoragePath - */ - public function testSplitStoragePath( $path, $res ) { - $this->assertEquals( $res, FileBackend::splitStoragePath( $path ), - "FileBackend::splitStoragePath on path '$path'" ); - } - - public static function provider_testSplitStoragePath() { - return array( - array( 'mwstore://backend/container', array( 'backend', 'container', '' ) ), - array( 'mwstore://backend/container/', array( 'backend', 'container', '' ) ), - array( 'mwstore://backend/container/path', array( 'backend', 'container', 'path' ) ), - array( 'mwstore://backend/container//path', array( 'backend', 'container', '/path' ) ), - array( 'mwstore://backend//container/path', array( null, null, null ) ), - array( 'mwstore://backend//container//path', array( null, null, null ) ), - array( 'mwstore://', array( null, null, null ) ), - array( 'mwstore://backend', array( null, null, null ) ), - array( 'mwstore:///', array( null, null, null ) ), - array( 'mwstore:/', array( null, null, null ) ), - array( 'mwstore:', array( null, null, null ) ) - ); - } - - /** - * @dataProvider provider_normalizeStoragePath - * @covers FileBackend::normalizeStoragePath - */ - public function testNormalizeStoragePath( $path, $res ) { - $this->assertEquals( $res, FileBackend::normalizeStoragePath( $path ), - "FileBackend::normalizeStoragePath on path '$path'" ); - } - - public static function provider_normalizeStoragePath() { - return array( - array( 'mwstore://backend/container', 'mwstore://backend/container' ), - array( 'mwstore://backend/container/', 'mwstore://backend/container' ), - array( 'mwstore://backend/container/path', 'mwstore://backend/container/path' ), - array( 'mwstore://backend/container//path', 'mwstore://backend/container/path' ), - array( 'mwstore://backend/container///path', 'mwstore://backend/container/path' ), - array( 'mwstore://backend/container///path//to///obj', 'mwstore://backend/container/path/to/obj' ), - array( 'mwstore://', null ), - array( 'mwstore://backend', null ), - array( 'mwstore://backend//container/path', null ), - array( 'mwstore://backend//container//path', null ), - array( 'mwstore:///', null ), - array( 'mwstore:/', null ), - array( 'mwstore:', null ), - ); - } - - /** - * @dataProvider provider_testParentStoragePath - * @covers FileBackend::parentStoragePath - */ - public function testParentStoragePath( $path, $res ) { - $this->assertEquals( $res, FileBackend::parentStoragePath( $path ), - "FileBackend::parentStoragePath on path '$path'" ); - } - - 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' ), - array( 'mwstore://backend/container/path', 'mwstore://backend/container' ), - array( 'mwstore://backend/container', null ), - array( 'mwstore://backend/container/path/to/obj/', 'mwstore://backend/container/path/to' ), - array( 'mwstore://backend/container/path/to/', 'mwstore://backend/container/path' ), - array( 'mwstore://backend/container/path/', 'mwstore://backend/container' ), - array( 'mwstore://backend/container/', null ), - ); - } - - /** - * @dataProvider provider_testExtensionFromPath - * @covers FileBackend::extensionFromPath - */ - public function testExtensionFromPath( $path, $res ) { - $this->assertEquals( $res, FileBackend::extensionFromPath( $path ), - "FileBackend::extensionFromPath on path '$path'" ); - } - - public static function provider_testExtensionFromPath() { - return array( - array( 'mwstore://backend/container/path.txt', 'txt' ), - array( 'mwstore://backend/container/path.svg.png', 'png' ), - array( 'mwstore://backend/container/path', '' ), - array( 'mwstore://backend/container/path.', '' ), - ); - } - - /** - * @dataProvider provider_testStore - */ - public function testStore( $op ) { - $this->filesToPrune[] = $op['src']; - - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestStore( $op ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestStore( $op ); - $this->filesToPrune[] = $op['src']; # avoid file leaking - $this->tearDownFiles(); - } - - /** - * @covers FileBackend::doOperation - */ - private function doTestStore( $op ) { - $backendName = $this->backendClass(); - - $source = $op['src']; - $dest = $op['dst']; - $this->prepare( array( 'dir' => dirname( $dest ) ) ); - - file_put_contents( $source, "Unit test file" ); - - if ( isset( $op['overwrite'] ) || isset( $op['overwriteSame'] ) ) { - $this->backend->store( $op ); - } - - $status = $this->backend->doOperation( $op ); - - $this->assertGoodStatus( $status, - "Store from $source to $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Store from $source to $dest succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Store from $source to $dest has proper 'success' field in Status ($backendName)." ); - $this->assertEquals( true, file_exists( $source ), - "Source file $source still exists ($backendName)." ); - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ), - "Destination file $dest exists ($backendName)." ); - - $this->assertEquals( filesize( $source ), - $this->backend->getFileSize( array( 'src' => $dest ) ), - "Destination file $dest has correct size ($backendName)." ); - - $props1 = FSFile::getPropsFromPath( $source ); - $props2 = $this->backend->getFileProps( array( 'src' => $dest ) ); - $this->assertEquals( $props1, $props2, - "Source and destination have the same props ($backendName)." ); - - $this->assertBackendPathsConsistent( array( $dest ) ); - } - - public static function provider_testStore() { - $cases = array(); - - $tmpName = TempFSFile::factory( "unittests_", 'txt' )->getPath(); - $toPath = self::baseStorePath() . '/unittest-cont1/e/fun/obj1.txt'; - $op = array( 'op' => 'store', 'src' => $tmpName, 'dst' => $toPath ); - $cases[] = array( - $op, // operation - $tmpName, // source - $toPath, // dest - ); - - $op2 = $op; - $op2['overwrite'] = true; - $cases[] = array( - $op2, // operation - $tmpName, // source - $toPath, // dest - ); - - $op2 = $op; - $op2['overwriteSame'] = true; - $cases[] = array( - $op2, // operation - $tmpName, // source - $toPath, // dest - ); - - return $cases; - } - - /** - * @dataProvider provider_testCopy - * @covers FileBackend::doOperation - */ - public function testCopy( $op ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestCopy( $op ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestCopy( $op ); - $this->tearDownFiles(); - } - - private function doTestCopy( $op ) { - $backendName = $this->backendClass(); - - $source = $op['src']; - $dest = $op['dst']; - $this->prepare( array( 'dir' => dirname( $source ) ) ); - $this->prepare( array( 'dir' => dirname( $dest ) ) ); - - if ( isset( $op['ignoreMissingSource'] ) ) { - $status = $this->backend->doOperation( $op ); - $this->assertGoodStatus( $status, - "Move from $source to $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Move from $source to $dest has proper 'success' field in Status ($backendName)." ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $source ) ), - "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 - } - - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) ); - $this->assertGoodStatus( $status, - "Creation of file at $source succeeded ($backendName)." ); - - if ( isset( $op['overwrite'] ) || isset( $op['overwriteSame'] ) ) { - $this->backend->copy( $op ); - } - - $status = $this->backend->doOperation( $op ); - - $this->assertGoodStatus( $status, - "Copy from $source to $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Copy from $source to $dest succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Copy from $source to $dest has proper 'success' field in Status ($backendName)." ); - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $source ) ), - "Source file $source still exists ($backendName)." ); - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ), - "Destination file $dest exists after copy ($backendName)." ); - - $this->assertEquals( - $this->backend->getFileSize( array( 'src' => $source ) ), - $this->backend->getFileSize( array( 'src' => $dest ) ), - "Destination file $dest has correct size ($backendName)." ); - - $props1 = $this->backend->getFileProps( array( 'src' => $source ) ); - $props2 = $this->backend->getFileProps( array( 'src' => $dest ) ); - $this->assertEquals( $props1, $props2, - "Source and destination have the same props ($backendName)." ); - - $this->assertBackendPathsConsistent( array( $source, $dest ) ); - } - - public static function provider_testCopy() { - $cases = array(); - - $source = self::baseStorePath() . '/unittest-cont1/e/file.txt'; - $dest = self::baseStorePath() . '/unittest-cont2/a/fileMoved.txt'; - - $op = array( 'op' => 'copy', 'src' => $source, 'dst' => $dest ); - $cases[] = array( - $op, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['overwrite'] = true; - $cases[] = array( - $op2, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['overwriteSame'] = true; - $cases[] = array( - $op2, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['ignoreMissingSource'] = true; - $cases[] = array( - $op2, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['ignoreMissingSource'] = true; - $cases[] = array( - $op2, // operation - self::baseStorePath() . '/unittest-cont-bad/e/file.txt', // source - $dest, // dest - ); - - return $cases; - } - - /** - * @dataProvider provider_testMove - * @covers FileBackend::doOperation - */ - public function testMove( $op ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestMove( $op ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestMove( $op ); - $this->tearDownFiles(); - } - - private function doTestMove( $op ) { - $backendName = $this->backendClass(); - - $source = $op['src']; - $dest = $op['dst']; - $this->prepare( array( 'dir' => dirname( $source ) ) ); - $this->prepare( array( 'dir' => dirname( $dest ) ) ); - - if ( isset( $op['ignoreMissingSource'] ) ) { - $status = $this->backend->doOperation( $op ); - $this->assertGoodStatus( $status, - "Move from $source to $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Move from $source to $dest has proper 'success' field in Status ($backendName)." ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $source ) ), - "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 - } - - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) ); - $this->assertGoodStatus( $status, - "Creation of file at $source succeeded ($backendName)." ); - - if ( isset( $op['overwrite'] ) || isset( $op['overwriteSame'] ) ) { - $this->backend->copy( $op ); - } - - $status = $this->backend->doOperation( $op ); - $this->assertGoodStatus( $status, - "Move from $source to $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Move from $source to $dest succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Move from $source to $dest has proper 'success' field in Status ($backendName)." ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $source ) ), - "Source file $source does not still exists ($backendName)." ); - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ), - "Destination file $dest exists after move ($backendName)." ); - - $this->assertNotEquals( - $this->backend->getFileSize( array( 'src' => $source ) ), - $this->backend->getFileSize( array( 'src' => $dest ) ), - "Destination file $dest has correct size ($backendName)." ); - - $props1 = $this->backend->getFileProps( array( 'src' => $source ) ); - $props2 = $this->backend->getFileProps( array( 'src' => $dest ) ); - $this->assertEquals( false, $props1['fileExists'], - "Source file does not exist accourding to props ($backendName)." ); - $this->assertEquals( true, $props2['fileExists'], - "Destination file exists accourding to props ($backendName)." ); - - $this->assertBackendPathsConsistent( array( $source, $dest ) ); - } - - public static function provider_testMove() { - $cases = array(); - - $source = self::baseStorePath() . '/unittest-cont1/e/file.txt'; - $dest = self::baseStorePath() . '/unittest-cont2/a/fileMoved.txt'; - - $op = array( 'op' => 'move', 'src' => $source, 'dst' => $dest ); - $cases[] = array( - $op, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['overwrite'] = true; - $cases[] = array( - $op2, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['overwriteSame'] = true; - $cases[] = array( - $op2, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['ignoreMissingSource'] = true; - $cases[] = array( - $op2, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['ignoreMissingSource'] = true; - $cases[] = array( - $op2, // operation - self::baseStorePath() . '/unittest-cont-bad/e/file.txt', // source - $dest, // dest - ); - - return $cases; - } - - /** - * @dataProvider provider_testDelete - * @covers FileBackend::doOperation - */ - public function testDelete( $op, $withSource, $okStatus ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestDelete( $op, $withSource, $okStatus ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestDelete( $op, $withSource, $okStatus ); - $this->tearDownFiles(); - } - - private function doTestDelete( $op, $withSource, $okStatus ) { - $backendName = $this->backendClass(); - - $source = $op['src']; - $this->prepare( array( 'dir' => dirname( $source ) ) ); - - if ( $withSource ) { - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) ); - $this->assertGoodStatus( $status, - "Creation of file at $source succeeded ($backendName)." ); - } - - $status = $this->backend->doOperation( $op ); - if ( $okStatus ) { - $this->assertGoodStatus( $status, - "Deletion of file at $source succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Deletion of file at $source succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Deletion of file at $source has proper 'success' field in Status ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Deletion of file at $source failed ($backendName)." ); - } - - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $source ) ), - "Source file $source does not exist after move ($backendName)." ); - - $this->assertFalse( - $this->backend->getFileSize( array( 'src' => $source ) ), - "Source file $source has correct size (false) ($backendName)." ); - - $props1 = $this->backend->getFileProps( array( 'src' => $source ) ); - $this->assertFalse( $props1['fileExists'], - "Source file $source does not exist according to props ($backendName)." ); - - $this->assertBackendPathsConsistent( array( $source ) ); - } - - public static function provider_testDelete() { - $cases = array(); - - $source = self::baseStorePath() . '/unittest-cont1/e/myfacefile.txt'; - - $op = array( 'op' => 'delete', 'src' => $source ); - $cases[] = array( - $op, // operation - true, // with source - true // succeeds - ); - - $cases[] = array( - $op, // operation - false, // without source - false // fails - ); - - $op['ignoreMissingSource'] = true; - $cases[] = array( - $op, // operation - false, // without source - true // succeeds - ); - - $op['ignoreMissingSource'] = true; - $op['src'] = self::baseStorePath() . '/unittest-cont-bad/e/file.txt'; - $cases[] = array( - $op, // operation - false, // without source - true // succeeds - ); - - return $cases; - } - - /** - * @dataProvider provider_testDescribe - * @covers FileBackend::doOperation - */ - public function testDescribe( $op, $withSource, $okStatus ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestDescribe( $op, $withSource, $okStatus ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestDescribe( $op, $withSource, $okStatus ); - $this->tearDownFiles(); - } - - private function doTestDescribe( $op, $withSource, $okStatus ) { - $backendName = $this->backendClass(); - - $source = $op['src']; - $this->prepare( array( 'dir' => dirname( $source ) ) ); - - if ( $withSource ) { - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) ); - $this->assertGoodStatus( $status, - "Creation of file at $source succeeded ($backendName)." ); - } - - $status = $this->backend->doOperation( $op ); - if ( $okStatus ) { - $this->assertGoodStatus( $status, - "Describe of file at $source succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Describe of file at $source succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Describe of file at $source has proper 'success' field in Status ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Describe of file at $source failed ($backendName)." ); - } - - $this->assertBackendPathsConsistent( array( $source ) ); - } - - public static function provider_testDescribe() { - $cases = array(); - - $source = self::baseStorePath() . '/unittest-cont1/e/myfacefile.txt'; - - $op = array( 'op' => 'describe', 'src' => $source, - 'headers' => array( 'X-Content-Length' => '91.3', 'Content-Old-Header' => '' ), - 'disposition' => 'inline' ); - $cases[] = array( - $op, // operation - true, // with source - true // succeeds - ); - - $cases[] = array( - $op, // operation - false, // without source - false // fails - ); - - return $cases; - } - - /** - * @dataProvider provider_testCreate - * @covers FileBackend::doOperation - */ - public function testCreate( $op, $alreadyExists, $okStatus, $newSize ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestCreate( $op, $alreadyExists, $okStatus, $newSize ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestCreate( $op, $alreadyExists, $okStatus, $newSize ); - $this->tearDownFiles(); - } - - private function doTestCreate( $op, $alreadyExists, $okStatus, $newSize ) { - $backendName = $this->backendClass(); - - $dest = $op['dst']; - $this->prepare( array( 'dir' => dirname( $dest ) ) ); - - $oldText = 'blah...blah...waahwaah'; - if ( $alreadyExists ) { - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => $oldText, 'dst' => $dest ) ); - $this->assertGoodStatus( $status, - "Creation of file at $dest succeeded ($backendName)." ); - } - - $status = $this->backend->doOperation( $op ); - if ( $okStatus ) { - $this->assertGoodStatus( $status, - "Creation of file at $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Creation of file at $dest succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Creation of file at $dest has proper 'success' field in Status ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Creation of file at $dest failed ($backendName)." ); - } - - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ), - "Destination file $dest exists after creation ($backendName)." ); - - $props1 = $this->backend->getFileProps( array( 'src' => $dest ) ); - $this->assertEquals( true, $props1['fileExists'], - "Destination file $dest exists according to props ($backendName)." ); - if ( $okStatus ) { // file content is what we saved - $this->assertEquals( $newSize, $props1['size'], - "Destination file $dest has expected size according to props ($backendName)." ); - $this->assertEquals( $newSize, - $this->backend->getFileSize( array( 'src' => $dest ) ), - "Destination file $dest has correct size ($backendName)." ); - } else { // file content is some other previous text - $this->assertEquals( strlen( $oldText ), $props1['size'], - "Destination file $dest has original size according to props ($backendName)." ); - $this->assertEquals( strlen( $oldText ), - $this->backend->getFileSize( array( 'src' => $dest ) ), - "Destination file $dest has original size according to props ($backendName)." ); - } - - $this->assertBackendPathsConsistent( array( $dest ) ); - } - - /** - * @dataProvider provider_testCreate - */ - public static function provider_testCreate() { - $cases = array(); - - $dest = self::baseStorePath() . '/unittest-cont2/a/myspacefile.txt'; - - $op = array( 'op' => 'create', 'content' => 'test test testing', 'dst' => $dest ); - $cases[] = array( - $op, // operation - false, // no dest already exists - true, // succeeds - strlen( $op['content'] ) - ); - - $op2 = $op; - $op2['content'] = "\n"; - $cases[] = array( - $op2, // operation - false, // no dest already exists - true, // succeeds - strlen( $op2['content'] ) - ); - - $op2 = $op; - $op2['content'] = "fsf\n waf 3kt"; - $cases[] = array( - $op2, // operation - true, // dest already exists - false, // fails - strlen( $op2['content'] ) - ); - - $op2 = $op; - $op2['content'] = "egm'g gkpe gpqg eqwgwqg"; - $op2['overwrite'] = true; - $cases[] = array( - $op2, // operation - true, // dest already exists - true, // succeeds - strlen( $op2['content'] ) - ); - - $op2 = $op; - $op2['content'] = "39qjmg3-qg"; - $op2['overwriteSame'] = true; - $cases[] = array( - $op2, // operation - true, // dest already exists - false, // succeeds - strlen( $op2['content'] ) - ); - - return $cases; - } - - /** - * @covers FileBackend::doQuickOperations - */ - public function testDoQuickOperations() { - $this->backend = $this->singleBackend; - $this->doTestDoQuickOperations(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->doTestDoQuickOperations(); - $this->tearDownFiles(); - } - - private function doTestDoQuickOperations() { - $backendName = $this->backendClass(); - - $base = self::baseStorePath(); - $files = array( - "$base/unittest-cont1/e/fileA.a", - "$base/unittest-cont1/e/fileB.a", - "$base/unittest-cont1/e/fileC.a" - ); - $createOps = array(); - $purgeOps = array(); - foreach ( $files as $path ) { - $status = $this->prepare( array( 'dir' => dirname( $path ) ) ); - $this->assertGoodStatus( $status, - "Preparing $path succeeded without warnings ($backendName)." ); - $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' ); - - $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." ); - } - - $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." ); - } - } - - /** - * @dataProvider provider_testConcatenate - */ - public function testConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ) { - $this->filesToPrune[] = $op['dst']; - - $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; - $this->tearDownFiles(); - $this->doTestConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ); - $this->filesToPrune[] = $op['dst']; # avoid file leaking - $this->tearDownFiles(); - } - - private function doTestConcatenate( $params, $srcs, $srcsContent, $alreadyExists, $okStatus ) { - $backendName = $this->backendClass(); - - $expContent = ''; - // Create sources - $ops = array(); - foreach ( $srcs as $i => $source ) { - $this->prepare( array( 'dir' => dirname( $source ) ) ); - $ops[] = array( - 'op' => 'create', // operation - 'dst' => $source, // source - 'content' => $srcsContent[$i] - ); - $expContent .= $srcsContent[$i]; - } - $status = $this->backend->doOperations( $ops ); - - $this->assertGoodStatus( $status, - "Creation of source files succeeded ($backendName)." ); - - $dest = $params['dst']; - if ( $alreadyExists ) { - $ok = file_put_contents( $dest, 'blah...blah...waahwaah' ) !== false; - $this->assertEquals( true, $ok, - "Creation of file at $dest succeeded ($backendName)." ); - } else { - $ok = file_put_contents( $dest, '' ) !== false; - $this->assertEquals( true, $ok, - "Creation of 0-byte file at $dest succeeded ($backendName)." ); - } - - // Combine the files into one - $status = $this->backend->concatenate( $params ); - if ( $okStatus ) { - $this->assertGoodStatus( $status, - "Creation of concat file at $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Creation of concat file at $dest succeeded ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Creation of concat file at $dest failed ($backendName)." ); - } - - if ( $okStatus ) { - $this->assertEquals( true, is_file( $dest ), - "Dest concat file $dest exists after creation ($backendName)." ); - } else { - $this->assertEquals( true, is_file( $dest ), - "Dest concat file $dest exists after failed creation ($backendName)." ); - } - - $contents = file_get_contents( $dest ); - $this->assertNotEquals( false, $contents, "File at $dest exists ($backendName)." ); - - if ( $okStatus ) { - $this->assertEquals( $expContent, $contents, - "Concat file at $dest has correct contents ($backendName)." ); - } else { - $this->assertNotEquals( $expContent, $contents, - "Concat file at $dest has correct contents ($backendName)." ); - } - } - - public static function provider_testConcatenate() { - $cases = array(); - - $rand = mt_rand( 0, 2000000000 ) . time(); - $dest = wfTempDir() . "/randomfile!$rand.txt"; - $srcs = array( - self::baseStorePath() . '/unittest-cont1/e/file1.txt', - self::baseStorePath() . '/unittest-cont1/e/file2.txt', - self::baseStorePath() . '/unittest-cont1/e/file3.txt', - self::baseStorePath() . '/unittest-cont1/e/file4.txt', - self::baseStorePath() . '/unittest-cont1/e/file5.txt', - self::baseStorePath() . '/unittest-cont1/e/file6.txt', - self::baseStorePath() . '/unittest-cont1/e/file7.txt', - self::baseStorePath() . '/unittest-cont1/e/file8.txt', - self::baseStorePath() . '/unittest-cont1/e/file9.txt', - self::baseStorePath() . '/unittest-cont1/e/file10.txt' - ); - $content = array( - 'egfage', - 'ageageag', - 'rhokohlr', - 'shgmslkg', - 'kenga', - 'owagmal', - 'kgmae', - 'g eak;g', - 'lkaem;a', - 'legma' - ); - $params = array( 'srcs' => $srcs, 'dst' => $dest ); - - $cases[] = array( - $params, // operation - $srcs, // sources - $content, // content for each source - false, // no dest already exists - true, // succeeds - ); - - $cases[] = array( - $params, // operation - $srcs, // sources - $content, // content for each source - true, // dest already exists - false, // succeeds - ); - - return $cases; - } - - /** - * @dataProvider provider_testGetFileStat - * @covers FileBackend::getFileStat - */ - public function testGetFileStat( $path, $content, $alreadyExists ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetFileStat( $path, $content, $alreadyExists ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetFileStat( $path, $content, $alreadyExists ); - $this->tearDownFiles(); - } - - private function doTestGetFileStat( $path, $content, $alreadyExists ) { - $backendName = $this->backendClass(); - - if ( $alreadyExists ) { - $this->prepare( array( 'dir' => dirname( $path ) ) ); - $status = $this->create( array( 'dst' => $path, 'content' => $content ) ); - $this->assertGoodStatus( $status, - "Creation of file at $path succeeded ($backendName)." ); - - $size = $this->backend->getFileSize( array( 'src' => $path ) ); - $time = $this->backend->getFileTimestamp( array( 'src' => $path ) ); - $stat = $this->backend->getFileStat( array( 'src' => $path ) ); - - $this->assertEquals( strlen( $content ), $size, - "Correct file size of '$path'" ); - $this->assertTrue( abs( time() - wfTimestamp( TS_UNIX, $time ) ) < 10, - "Correct file timestamp of '$path'" ); - - $size = $stat['size']; - $time = $stat['mtime']; - $this->assertEquals( strlen( $content ), $size, - "Correct file size of '$path'" ); - $this->assertTrue( abs( time() - wfTimestamp( TS_UNIX, $time ) ) < 10, - "Correct file timestamp of '$path'" ); - - $this->backend->clearCache( array( $path ) ); - - $size = $this->backend->getFileSize( array( 'src' => $path ) ); - - $this->assertEquals( strlen( $content ), $size, - "Correct file size of '$path'" ); - - $this->backend->preloadCache( array( $path ) ); - - $size = $this->backend->getFileSize( array( 'src' => $path ) ); - - $this->assertEquals( strlen( $content ), $size, - "Correct file size of '$path'" ); - } else { - $size = $this->backend->getFileSize( array( 'src' => $path ) ); - $time = $this->backend->getFileTimestamp( array( 'src' => $path ) ); - $stat = $this->backend->getFileStat( array( 'src' => $path ) ); - - $this->assertFalse( $size, "Correct file size of '$path'" ); - $this->assertFalse( $time, "Correct file timestamp of '$path'" ); - $this->assertFalse( $stat, "Correct file stat of '$path'" ); - } - } - - public static function provider_testGetFileStat() { - $cases = array(); - - $base = self::baseStorePath(); - $cases[] = array( "$base/unittest-cont1/e/b/z/some_file.txt", "some file contents", true ); - $cases[] = array( "$base/unittest-cont1/e/b/some-other_file.txt", "", true ); - $cases[] = array( "$base/unittest-cont1/e/b/some-diff_file.txt", null, false ); - - return $cases; - } - - /** - * @dataProvider provider_testGetFileContents - * @covers FileBackend::getFileContents - * @covers FileBackend::getFileContentsMulti - */ - public function testGetFileContents( $source, $content ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetFileContents( $source, $content ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetFileContents( $source, $content ); - $this->tearDownFiles(); - } - - private function doTestGetFileContents( $source, $content ) { - $backendName = $this->backendClass(); - - $srcs = (array)$source; - $content = (array)$content; - foreach ( $srcs as $i => $src ) { - $this->prepare( array( 'dir' => dirname( $src ) ) ); - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => $content[$i], 'dst' => $src ) ); - $this->assertGoodStatus( $status, - "Creation of file at $src succeeded ($backendName)." ); - } - - if ( is_array( $source ) ) { - $contents = $this->backend->getFileContentsMulti( array( 'srcs' => $source ) ); - foreach ( $contents as $path => $data ) { - $this->assertNotEquals( false, $data, "Contents of $path exists ($backendName)." ); - $this->assertEquals( current( $content ), $data, "Contents of $path is correct ($backendName)." ); - next( $content ); - } - $this->assertEquals( $source, array_keys( $contents ), "Contents in right order ($backendName)." ); - $this->assertEquals( count( $source ), count( $contents ), "Contents array size correct ($backendName)." ); - } else { - $data = $this->backend->getFileContents( array( 'src' => $source ) ); - $this->assertNotEquals( false, $data, "Contents of $source exists ($backendName)." ); - $this->assertEquals( $content[0], $data, "Contents of $source is correct ($backendName)." ); - } - } - - public static function provider_testGetFileContents() { - $cases = array(); - - $base = self::baseStorePath(); - $cases[] = array( "$base/unittest-cont1/e/b/z/some_file.txt", "some file contents" ); - $cases[] = array( "$base/unittest-cont1/e/b/some-other_file.txt", "more file contents" ); - $cases[] = array( - array( "$base/unittest-cont1/e/a/x.txt", "$base/unittest-cont1/e/a/y.txt", - "$base/unittest-cont1/e/a/z.txt" ), - array( "contents xx", "contents xy", "contents xz" ) - ); - - return $cases; - } - - /** - * @dataProvider provider_testGetLocalCopy - * @covers FileBackend::getLocalCopy - */ - public function testGetLocalCopy( $source, $content ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetLocalCopy( $source, $content ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetLocalCopy( $source, $content ); - $this->tearDownFiles(); - } - - private function doTestGetLocalCopy( $source, $content ) { - $backendName = $this->backendClass(); - - $srcs = (array)$source; - $content = (array)$content; - foreach ( $srcs as $i => $src ) { - $this->prepare( array( 'dir' => dirname( $src ) ) ); - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => $content[$i], 'dst' => $src ) ); - $this->assertGoodStatus( $status, - "Creation of file at $src succeeded ($backendName)." ); - } - - if ( is_array( $source ) ) { - $tmpFiles = $this->backend->getLocalCopyMulti( array( 'srcs' => $source ) ); - foreach ( $tmpFiles as $path => $tmpFile ) { - $this->assertNotNull( $tmpFile, - "Creation of local copy of $path succeeded ($backendName)." ); - $contents = file_get_contents( $tmpFile->getPath() ); - $this->assertNotEquals( false, $contents, "Local copy of $path exists ($backendName)." ); - $this->assertEquals( current( $content ), $contents, "Local copy of $path is correct ($backendName)." ); - next( $content ); - } - $this->assertEquals( $source, array_keys( $tmpFiles ), "Local copies in right order ($backendName)." ); - $this->assertEquals( count( $source ), count( $tmpFiles ), "Local copies array size correct ($backendName)." ); - } else { - $tmpFile = $this->backend->getLocalCopy( array( 'src' => $source ) ); - $this->assertNotNull( $tmpFile, - "Creation of local copy of $source succeeded ($backendName)." ); - $contents = file_get_contents( $tmpFile->getPath() ); - $this->assertNotEquals( false, $contents, "Local copy of $source exists ($backendName)." ); - $this->assertEquals( $content[0], $contents, "Local copy of $source is correct ($backendName)." ); - } - - $obj = new stdClass(); - $tmpFile->bind( $obj ); - } - - public static function provider_testGetLocalCopy() { - $cases = array(); - - $base = self::baseStorePath(); - $cases[] = array( "$base/unittest-cont1/e/a/z/some_file.txt", "some file contents" ); - $cases[] = array( "$base/unittest-cont1/e/a/some-other_file.txt", "more file contents" ); - $cases[] = array( "$base/unittest-cont1/e/a/\$odd&.txt", "test file contents" ); - $cases[] = array( - array( "$base/unittest-cont1/e/a/x.txt", "$base/unittest-cont1/e/a/y.txt", - "$base/unittest-cont1/e/a/z.txt" ), - array( "contents xx", "contents xy", "contents xz" ) - ); - - return $cases; - } - - /** - * @dataProvider provider_testGetLocalReference - * @covers FileBackend::getLocalReference - */ - public function testGetLocalReference( $source, $content ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetLocalReference( $source, $content ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetLocalReference( $source, $content ); - $this->tearDownFiles(); - } - - private function doTestGetLocalReference( $source, $content ) { - $backendName = $this->backendClass(); - - $srcs = (array)$source; - $content = (array)$content; - foreach ( $srcs as $i => $src ) { - $this->prepare( array( 'dir' => dirname( $src ) ) ); - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => $content[$i], 'dst' => $src ) ); - $this->assertGoodStatus( $status, - "Creation of file at $src succeeded ($backendName)." ); - } - - if ( is_array( $source ) ) { - $tmpFiles = $this->backend->getLocalReferenceMulti( array( 'srcs' => $source ) ); - foreach ( $tmpFiles as $path => $tmpFile ) { - $this->assertNotNull( $tmpFile, - "Creation of local copy of $path succeeded ($backendName)." ); - $contents = file_get_contents( $tmpFile->getPath() ); - $this->assertNotEquals( false, $contents, "Local ref of $path exists ($backendName)." ); - $this->assertEquals( current( $content ), $contents, "Local ref of $path is correct ($backendName)." ); - next( $content ); - } - $this->assertEquals( $source, array_keys( $tmpFiles ), "Local refs in right order ($backendName)." ); - $this->assertEquals( count( $source ), count( $tmpFiles ), "Local refs array size correct ($backendName)." ); - } else { - $tmpFile = $this->backend->getLocalReference( array( 'src' => $source ) ); - $this->assertNotNull( $tmpFile, - "Creation of local copy of $source succeeded ($backendName)." ); - $contents = file_get_contents( $tmpFile->getPath() ); - $this->assertNotEquals( false, $contents, "Local ref of $source exists ($backendName)." ); - $this->assertEquals( $content[0], $contents, "Local ref of $source is correct ($backendName)." ); - } - } - - public static function provider_testGetLocalReference() { - $cases = array(); - - $base = self::baseStorePath(); - $cases[] = array( "$base/unittest-cont1/e/a/z/some_file.txt", "some file contents" ); - $cases[] = array( "$base/unittest-cont1/e/a/some-other_file.txt", "more file contents" ); - $cases[] = array( "$base/unittest-cont1/e/a/\$odd&.txt", "test file contents" ); - $cases[] = array( - array( "$base/unittest-cont1/e/a/x.txt", "$base/unittest-cont1/e/a/y.txt", - "$base/unittest-cont1/e/a/z.txt" ), - array( "contents xx", "contents xy", "contents xz" ) - ); - - return $cases; - } - - /** - * @covers FileBackend::getLocalCopy - * @covers FileBackend::getLocalReference - */ - public function testGetLocalCopyAndReference404() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetLocalCopyAndReference404(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetLocalCopyAndReference404(); - $this->tearDownFiles(); - } - - public function doTestGetLocalCopyAndReference404() { - $backendName = $this->backendClass(); - - $base = self::baseStorePath(); - - $tmpFile = $this->backend->getLocalCopy( array( - 'src' => "$base/unittest-cont1/not-there" ) ); - $this->assertEquals( null, $tmpFile, "Local copy of not existing file is null ($backendName)." ); - - $tmpFile = $this->backend->getLocalReference( array( - 'src' => "$base/unittest-cont1/not-there" ) ); - $this->assertEquals( null, $tmpFile, "Local ref of not existing file is null ($backendName)." ); - } - - /** - * @dataProvider provider_testGetFileHttpUrl - * @covers FileBackend::getFileHttpUrl - */ - public function testGetFileHttpUrl( $source, $content ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetFileHttpUrl( $source, $content ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetFileHttpUrl( $source, $content ); - $this->tearDownFiles(); - } - - private function doTestGetFileHttpUrl( $source, $content ) { - $backendName = $this->backendClass(); - - $this->prepare( array( 'dir' => dirname( $source ) ) ); - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => $content, 'dst' => $source ) ); - $this->assertGoodStatus( $status, - "Creation of file at $source succeeded ($backendName)." ); - - $url = $this->backend->getFileHttpUrl( array( 'src' => $source ) ); - - if ( $url !== null ) { // supported - $data = Http::request( "GET", $url ); - $this->assertEquals( $content, $data, - "HTTP GET of URL has right contents ($backendName)." ); - } - } - - public static function provider_testGetFileHttpUrl() { - $cases = array(); - - $base = self::baseStorePath(); - $cases[] = array( "$base/unittest-cont1/e/a/z/some_file.txt", "some file contents" ); - $cases[] = array( "$base/unittest-cont1/e/a/some-other_file.txt", "more file contents" ); - $cases[] = array( "$base/unittest-cont1/e/a/\$odd&.txt", "test file contents" ); - - return $cases; - } - - /** - * @dataProvider provider_testPrepareAndClean - * @covers FileBackend::prepare - * @covers FileBackend::clean - */ - public function testPrepareAndClean( $path, $isOK ) { - $this->backend = $this->singleBackend; - $this->doTestPrepareAndClean( $path, $isOK ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->doTestPrepareAndClean( $path, $isOK ); - $this->tearDownFiles(); - } - - 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 ), - # Specific to FS backend with no basePath field set - #array( "$base/unittest-cont3/a/z/some_file3.txt", false ), - ); - } - - private function doTestPrepareAndClean( $path, $isOK ) { - $backendName = $this->backendClass(); - - $status = $this->prepare( array( 'dir' => dirname( $path ) ) ); - if ( $isOK ) { - $this->assertGoodStatus( $status, - "Preparing dir $path succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Preparing dir $path succeeded ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Preparing dir $path failed ($backendName)." ); - } - - $status = $this->backend->clean( array( 'dir' => dirname( $path ) ) ); - if ( $isOK ) { - $this->assertGoodStatus( $status, - "Cleaning dir $path succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Cleaning dir $path succeeded ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Cleaning dir $path failed ($backendName)." ); - } - } - - public function testRecursiveClean() { - $this->backend = $this->singleBackend; - $this->doTestRecursiveClean(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->doTestRecursiveClean(); - $this->tearDownFiles(); - } - - /** - * @covers FileBackend::clean - */ - private function doTestRecursiveClean() { - $backendName = $this->backendClass(); - - $base = self::baseStorePath(); - $dirs = array( - "$base/unittest-cont1", - "$base/unittest-cont1/e", - "$base/unittest-cont1/e/a", - "$base/unittest-cont1/e/a/b", - "$base/unittest-cont1/e/a/b/c", - "$base/unittest-cont1/e/a/b/c/d0", - "$base/unittest-cont1/e/a/b/c/d1", - "$base/unittest-cont1/e/a/b/c/d2", - "$base/unittest-cont1/e/a/b/c/d0/1", - "$base/unittest-cont1/e/a/b/c/d0/2", - "$base/unittest-cont1/e/a/b/c/d1/3", - "$base/unittest-cont1/e/a/b/c/d1/4", - "$base/unittest-cont1/e/a/b/c/d2/5", - "$base/unittest-cont1/e/a/b/c/d2/6" - ); - foreach ( $dirs as $dir ) { - $status = $this->prepare( array( 'dir' => $dir ) ); - $this->assertGoodStatus( $status, - "Preparing dir $dir succeeded without warnings ($backendName)." ); - } - - if ( $this->backend instanceof FSFileBackend ) { - foreach ( $dirs as $dir ) { - $this->assertEquals( true, $this->backend->directoryExists( array( 'dir' => $dir ) ), - "Dir $dir exists ($backendName)." ); - } - } - - $status = $this->backend->clean( - array( 'dir' => "$base/unittest-cont1", 'recursive' => 1 ) ); - $this->assertGoodStatus( $status, - "Recursive cleaning of dir $dir succeeded without warnings ($backendName)." ); - - foreach ( $dirs as $dir ) { - $this->assertEquals( false, $this->backend->directoryExists( array( 'dir' => $dir ) ), - "Dir $dir no longer exists ($backendName)." ); - } - } - - // @todo testSecure - - /** - * @covers FileBackend::doOperations - */ - public function testDoOperations() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestDoOperations(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestDoOperations(); - $this->tearDownFiles(); - } - - private function doTestDoOperations() { - $base = self::baseStorePath(); - - $fileA = "$base/unittest-cont1/e/a/b/fileA.txt"; - $fileAContents = '3tqtmoeatmn4wg4qe-mg3qt3 tq'; - $fileB = "$base/unittest-cont1/e/a/b/fileB.txt"; - $fileBContents = 'g-jmq3gpqgt3qtg q3GT '; - $fileC = "$base/unittest-cont1/e/a/b/fileC.txt"; - $fileCContents = 'eigna[ogmewt 3qt g3qg flew[ag'; - $fileD = "$base/unittest-cont1/e/a/b/fileD.txt"; - - $this->prepare( array( 'dir' => dirname( $fileA ) ) ); - $this->create( array( 'dst' => $fileA, 'content' => $fileAContents ) ); - $this->prepare( array( 'dir' => dirname( $fileB ) ) ); - $this->create( array( 'dst' => $fileB, 'content' => $fileBContents ) ); - $this->prepare( array( 'dir' => dirname( $fileC ) ) ); - $this->create( array( 'dst' => $fileC, 'content' => $fileCContents ) ); - $this->prepare( array( 'dir' => dirname( $fileD ) ) ); - - $status = $this->backend->doOperations( array( - array( 'op' => 'describe', 'src' => $fileA, - 'headers' => array( 'X-Content-Length' => '91.3' ), 'disposition' => 'inline' ), - array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC, 'overwrite' => 1 ), - // Now: A:<A>, B:<B>, C:<A>, D:<empty> (file:<orginal contents>) - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileA, 'overwriteSame' => 1 ), - // Now: A:<A>, B:<B>, C:<A>, D:<empty> - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileD, 'overwrite' => 1 ), - // Now: A:<A>, B:<B>, C:<empty>, D:<A> - array( 'op' => 'move', 'src' => $fileB, 'dst' => $fileC ), - // Now: A:<A>, B:<empty>, C:<B>, D:<A> - array( 'op' => 'move', 'src' => $fileD, 'dst' => $fileA, 'overwriteSame' => 1 ), - // Now: A:<A>, B:<empty>, C:<B>, D:<empty> - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileA, 'overwrite' => 1 ), - // Now: A:<B>, B:<empty>, C:<empty>, D:<empty> - array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC ), - // Now: A:<B>, B:<empty>, C:<B>, D:<empty> - array( 'op' => 'move', 'src' => $fileA, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Now: A:<empty>, B:<empty>, C:<B>, D:<empty> - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ), - // Does nothing - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Does nothing - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ), - // Does nothing - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Does nothing - array( 'op' => 'null' ), - // Does nothing - ) ); - - $this->assertGoodStatus( $status, "Operation batch succeeded" ); - $this->assertEquals( true, $status->isOK(), "Operation batch succeeded" ); - $this->assertEquals( 14, count( $status->success ), - "Operation batch has correct success array" ); - - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileA ) ), - "File does not exist at $fileA" ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileB ) ), - "File does not exist at $fileB" ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileD ) ), - "File does not exist at $fileD" ); - - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $fileC ) ), - "File exists at $fileC" ); - $this->assertEquals( $fileBContents, - $this->backend->getFileContents( array( 'src' => $fileC ) ), - "Correct file contents of $fileC" ); - $this->assertEquals( strlen( $fileBContents ), - $this->backend->getFileSize( array( 'src' => $fileC ) ), - "Correct file size of $fileC" ); - $this->assertEquals( wfBaseConvert( sha1( $fileBContents ), 16, 36, 31 ), - $this->backend->getFileSha1Base36( array( 'src' => $fileC ) ), - "Correct file SHA-1 of $fileC" ); - } - - /** - * @covers FileBackend::doOperations - */ - public function testDoOperationsPipeline() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestDoOperationsPipeline(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestDoOperationsPipeline(); - $this->tearDownFiles(); - } - - // concurrency orientated - private function doTestDoOperationsPipeline() { - $base = self::baseStorePath(); - - $fileAContents = '3tqtmoeatmn4wg4qe-mg3qt3 tq'; - $fileBContents = 'g-jmq3gpqgt3qtg q3GT '; - $fileCContents = 'eigna[ogmewt 3qt g3qg flew[ag'; - - $tmpNameA = TempFSFile::factory( "unittests_", 'txt' )->getPath(); - file_put_contents( $tmpNameA, $fileAContents ); - $tmpNameB = TempFSFile::factory( "unittests_", 'txt' )->getPath(); - file_put_contents( $tmpNameB, $fileBContents ); - $tmpNameC = TempFSFile::factory( "unittests_", 'txt' )->getPath(); - file_put_contents( $tmpNameC, $fileCContents ); - - $this->filesToPrune[] = $tmpNameA; # avoid file leaking - $this->filesToPrune[] = $tmpNameB; # avoid file leaking - $this->filesToPrune[] = $tmpNameC; # avoid file leaking - - $fileA = "$base/unittest-cont1/e/a/b/fileA.txt"; - $fileB = "$base/unittest-cont1/e/a/b/fileB.txt"; - $fileC = "$base/unittest-cont1/e/a/b/fileC.txt"; - $fileD = "$base/unittest-cont1/e/a/b/fileD.txt"; - - $this->prepare( array( 'dir' => dirname( $fileA ) ) ); - $this->create( array( 'dst' => $fileA, 'content' => $fileAContents ) ); - $this->prepare( array( 'dir' => dirname( $fileB ) ) ); - $this->prepare( array( 'dir' => dirname( $fileC ) ) ); - $this->prepare( array( 'dir' => dirname( $fileD ) ) ); - - $status = $this->backend->doOperations( array( - array( 'op' => 'store', 'src' => $tmpNameA, 'dst' => $fileA, 'overwriteSame' => 1 ), - array( 'op' => 'store', 'src' => $tmpNameB, 'dst' => $fileB, 'overwrite' => 1 ), - array( 'op' => 'store', 'src' => $tmpNameC, 'dst' => $fileC, 'overwrite' => 1 ), - array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC, 'overwrite' => 1 ), - // Now: A:<A>, B:<B>, C:<A>, D:<empty> (file:<orginal contents>) - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileA, 'overwriteSame' => 1 ), - // Now: A:<A>, B:<B>, C:<A>, D:<empty> - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileD, 'overwrite' => 1 ), - // Now: A:<A>, B:<B>, C:<empty>, D:<A> - array( 'op' => 'move', 'src' => $fileB, 'dst' => $fileC ), - // Now: A:<A>, B:<empty>, C:<B>, D:<A> - array( 'op' => 'move', 'src' => $fileD, 'dst' => $fileA, 'overwriteSame' => 1 ), - // Now: A:<A>, B:<empty>, C:<B>, D:<empty> - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileA, 'overwrite' => 1 ), - // Now: A:<B>, B:<empty>, C:<empty>, D:<empty> - array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC ), - // Now: A:<B>, B:<empty>, C:<B>, D:<empty> - array( 'op' => 'move', 'src' => $fileA, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Now: A:<empty>, B:<empty>, C:<B>, D:<empty> - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ), - // Does nothing - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Does nothing - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ), - // Does nothing - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Does nothing - array( 'op' => 'null' ), - // Does nothing - ) ); - - $this->assertGoodStatus( $status, "Operation batch succeeded" ); - $this->assertEquals( true, $status->isOK(), "Operation batch succeeded" ); - $this->assertEquals( 16, count( $status->success ), - "Operation batch has correct success array" ); - - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileA ) ), - "File does not exist at $fileA" ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileB ) ), - "File does not exist at $fileB" ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileD ) ), - "File does not exist at $fileD" ); - - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $fileC ) ), - "File exists at $fileC" ); - $this->assertEquals( $fileBContents, - $this->backend->getFileContents( array( 'src' => $fileC ) ), - "Correct file contents of $fileC" ); - $this->assertEquals( strlen( $fileBContents ), - $this->backend->getFileSize( array( 'src' => $fileC ) ), - "Correct file size of $fileC" ); - $this->assertEquals( wfBaseConvert( sha1( $fileBContents ), 16, 36, 31 ), - $this->backend->getFileSha1Base36( array( 'src' => $fileC ) ), - "Correct file SHA-1 of $fileC" ); - } - - /** - * @covers FileBackend::doOperations - */ - public function testDoOperationsFailing() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestDoOperationsFailing(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestDoOperationsFailing(); - $this->tearDownFiles(); - } - - private function doTestDoOperationsFailing() { - $base = self::baseStorePath(); - - $fileA = "$base/unittest-cont2/a/b/fileA.txt"; - $fileAContents = '3tqtmoeatmn4wg4qe-mg3qt3 tq'; - $fileB = "$base/unittest-cont2/a/b/fileB.txt"; - $fileBContents = 'g-jmq3gpqgt3qtg q3GT '; - $fileC = "$base/unittest-cont2/a/b/fileC.txt"; - $fileCContents = 'eigna[ogmewt 3qt g3qg flew[ag'; - $fileD = "$base/unittest-cont2/a/b/fileD.txt"; - - $this->prepare( array( 'dir' => dirname( $fileA ) ) ); - $this->create( array( 'dst' => $fileA, 'content' => $fileAContents ) ); - $this->prepare( array( 'dir' => dirname( $fileB ) ) ); - $this->create( array( 'dst' => $fileB, 'content' => $fileBContents ) ); - $this->prepare( array( 'dir' => dirname( $fileC ) ) ); - $this->create( array( 'dst' => $fileC, 'content' => $fileCContents ) ); - - $status = $this->backend->doOperations( array( - array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC, 'overwrite' => 1 ), - // Now: A:<A>, B:<B>, C:<A>, D:<empty> (file:<orginal contents>) - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileA, 'overwriteSame' => 1 ), - // Now: A:<A>, B:<B>, C:<A>, D:<empty> - array( 'op' => 'copy', 'src' => $fileB, 'dst' => $fileD, 'overwrite' => 1 ), - // Now: A:<A>, B:<B>, C:<A>, D:<B> - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileD ), - // Now: A:<A>, B:<B>, C:<A>, D:<empty> (failed) - array( 'op' => 'move', 'src' => $fileB, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Now: A:<A>, B:<B>, C:<A>, D:<empty> (failed) - array( 'op' => 'move', 'src' => $fileB, 'dst' => $fileA, 'overwrite' => 1 ), - // Now: A:<B>, B:<empty>, C:<A>, D:<empty> - array( 'op' => 'delete', 'src' => $fileD ), - // Now: A:<B>, B:<empty>, C:<A>, D:<empty> - array( 'op' => 'null' ), - // Does nothing - ), array( 'force' => 1 ) ); - - $this->assertNotEquals( array(), $status->errors, "Operation had warnings" ); - $this->assertEquals( true, $status->isOK(), "Operation batch succeeded" ); - $this->assertEquals( 8, count( $status->success ), - "Operation batch has correct success array" ); - - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileB ) ), - "File does not exist at $fileB" ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileD ) ), - "File does not exist at $fileD" ); - - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $fileA ) ), - "File does not exist at $fileA" ); - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $fileC ) ), - "File exists at $fileC" ); - $this->assertEquals( $fileBContents, - $this->backend->getFileContents( array( 'src' => $fileA ) ), - "Correct file contents of $fileA" ); - $this->assertEquals( strlen( $fileBContents ), - $this->backend->getFileSize( array( 'src' => $fileA ) ), - "Correct file size of $fileA" ); - $this->assertEquals( wfBaseConvert( sha1( $fileBContents ), 16, 36, 31 ), - $this->backend->getFileSha1Base36( array( 'src' => $fileA ) ), - "Correct file SHA-1 of $fileA" ); - } - - /** - * @covers FileBackend::getFileList - */ - public function testGetFileList() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetFileList(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetFileList(); - $this->tearDownFiles(); - } - - private function doTestGetFileList() { - $backendName = $this->backendClass(); - $base = self::baseStorePath(); - - // Should have no errors - $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont-notexists" ) ); - - $files = array( - "$base/unittest-cont1/e/test1.txt", - "$base/unittest-cont1/e/test2.txt", - "$base/unittest-cont1/e/test3.txt", - "$base/unittest-cont1/e/subdir1/test1.txt", - "$base/unittest-cont1/e/subdir1/test2.txt", - "$base/unittest-cont1/e/subdir2/test3.txt", - "$base/unittest-cont1/e/subdir2/test4.txt", - "$base/unittest-cont1/e/subdir2/subdir/test1.txt", - "$base/unittest-cont1/e/subdir2/subdir/test2.txt", - "$base/unittest-cont1/e/subdir2/subdir/test3.txt", - "$base/unittest-cont1/e/subdir2/subdir/test4.txt", - "$base/unittest-cont1/e/subdir2/subdir/test5.txt", - "$base/unittest-cont1/e/subdir2/subdir/sub/test0.txt", - "$base/unittest-cont1/e/subdir2/subdir/sub/120-px-file.txt", - ); - - // Add the files - $ops = array(); - foreach ( $files as $file ) { - $this->prepare( array( 'dir' => dirname( $file ) ) ); - $ops[] = array( 'op' => 'create', 'content' => 'xxy', 'dst' => $file ); - } - $status = $this->backend->doQuickOperations( $ops ); - $this->assertGoodStatus( $status, - "Creation of files succeeded ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Creation of files succeeded with OK status ($backendName)." ); - - // Expected listing at root - $expected = array( - "e/test1.txt", - "e/test2.txt", - "e/test3.txt", - "e/subdir1/test1.txt", - "e/subdir1/test2.txt", - "e/subdir2/test3.txt", - "e/subdir2/test4.txt", - "e/subdir2/subdir/test1.txt", - "e/subdir2/subdir/test2.txt", - "e/subdir2/subdir/test3.txt", - "e/subdir2/subdir/test4.txt", - "e/subdir2/subdir/test5.txt", - "e/subdir2/subdir/sub/test0.txt", - "e/subdir2/subdir/sub/120-px-file.txt", - ); - sort( $expected ); - - // Actual listing (no trailing slash) at root - $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1" ) ); - $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) 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 at subdir - $expected = array( - "test1.txt", - "test2.txt", - "test3.txt", - "test4.txt", - "test5.txt", - "sub/test0.txt", - "sub/120-px-file.txt", - ); - sort( $expected ); - - // Actual listing (no trailing slash) at subdir - $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir" ) ); - $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) 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 = $this->listToArray( $iter ); - sort( $list ); - $this->assertEquals( $expected, $list, "Correct file listing ($backendName), second iteration." ); - - // 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", - "test3.txt", - "test4.txt", - "test5.txt" - ); - sort( $expected ); - - // Actual listing (top files only) at subdir - $iter = $this->backend->getTopFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir" ) ); - $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 - $this->backend->doOperation( array( 'op' => 'delete', 'src' => $file ) ); - } - - $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/not/exists" ) ); - foreach ( $iter as $iter ) { - // no errors - } - } - - /** - * @covers FileBackend::getTopDirectoryList - * @covers FileBackend::getDirectoryList - */ - public function testGetDirectoryList() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetDirectoryList(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetDirectoryList(); - $this->tearDownFiles(); - } - - private function doTestGetDirectoryList() { - $backendName = $this->backendClass(); - - $base = self::baseStorePath(); - $files = array( - "$base/unittest-cont1/e/test1.txt", - "$base/unittest-cont1/e/test2.txt", - "$base/unittest-cont1/e/test3.txt", - "$base/unittest-cont1/e/subdir1/test1.txt", - "$base/unittest-cont1/e/subdir1/test2.txt", - "$base/unittest-cont1/e/subdir2/test3.txt", - "$base/unittest-cont1/e/subdir2/test4.txt", - "$base/unittest-cont1/e/subdir2/subdir/test1.txt", - "$base/unittest-cont1/e/subdir3/subdir/test2.txt", - "$base/unittest-cont1/e/subdir4/subdir/test3.txt", - "$base/unittest-cont1/e/subdir4/subdir/test4.txt", - "$base/unittest-cont1/e/subdir4/subdir/test5.txt", - "$base/unittest-cont1/e/subdir4/subdir/sub/test0.txt", - "$base/unittest-cont1/e/subdir4/subdir/sub/120-px-file.txt", - ); - - // Add the files - $ops = array(); - foreach ( $files as $file ) { - $this->prepare( array( 'dir' => dirname( $file ) ) ); - $ops[] = array( 'op' => 'create', 'content' => 'xxy', 'dst' => $file ); - } - $status = $this->backend->doQuickOperations( $ops ); - $this->assertGoodStatus( $status, - "Creation of files succeeded ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Creation of files succeeded with OK status ($backendName)." ); - - $this->assertEquals( true, - $this->backend->directoryExists( array( 'dir' => "$base/unittest-cont1/e/subdir1" ) ), - "Directory exists in ($backendName)." ); - $this->assertEquals( true, - $this->backend->directoryExists( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir" ) ), - "Directory exists in ($backendName)." ); - $this->assertEquals( false, - $this->backend->directoryExists( array( 'dir' => "$base/unittest-cont1/e/subdir2/test1.txt" ) ), - "Directory does not exists in ($backendName)." ); - - // Expected listing - $expected = array( - "e", - ); - sort( $expected ); - - // Actual listing (no trailing slash) - $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName)." ); - - // Expected listing - $expected = array( - "subdir1", - "subdir2", - "subdir3", - "subdir4", - ); - sort( $expected ); - - // Actual listing (no trailing slash) - $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/e" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName)." ); - - // Actual listing (with trailing slash) - $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/e/" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName)." ); - - // Expected listing - $expected = array( - "subdir", - ); - sort( $expected ); - - // Actual listing (no trailing slash) - $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir2" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName)." ); - - // Actual listing (with trailing slash) - $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir2/" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName)." ); - - // Actual listing (using iterator second time) - $list = array(); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName), second iteration." ); - - // Expected listing (recursive) - $expected = array( - "e", - "e/subdir1", - "e/subdir2", - "e/subdir3", - "e/subdir4", - "e/subdir2/subdir", - "e/subdir3/subdir", - "e/subdir4/subdir", - "e/subdir4/subdir/sub", - ); - sort( $expected ); - - // Actual listing (recursive) - $list = array(); - $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct dir listing ($backendName)." ); - - // Expected listing (recursive) - $expected = array( - "subdir", - "subdir/sub", - ); - sort( $expected ); - - // Actual listing (recursive) - $list = array(); - $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir4" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct dir listing ($backendName)." ); - - // Actual listing (recursive, second time) - $list = array(); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct dir listing ($backendName)." ); - - $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir1" ) ); - $items = $this->listToArray( $iter ); - $this->assertEquals( array(), $items, "Directory listing is empty." ); - - foreach ( $files as $file ) { // clean up - $this->backend->doOperation( array( 'op' => 'delete', 'src' => $file ) ); - } - - $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/not/exists" ) ); - 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 = $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(); - } - - private function doTestLockCalls() { - $backendName = $this->backendClass(); - - $paths = array( - "test1.txt", - "test2.txt", - "test3.txt", - "subdir1", - "subdir1", // duplicate - "subdir1/test1.txt", - "subdir1/test2.txt", - "subdir2", - "subdir2", // duplicate - "subdir2/test3.txt", - "subdir2/test4.txt", - "subdir2/subdir", - "subdir2/subdir/test1.txt", - "subdir2/subdir/test2.txt", - "subdir2/subdir/test3.txt", - "subdir2/subdir/test4.txt", - "subdir2/subdir/test5.txt", - "subdir2/subdir/sub", - "subdir2/subdir/sub/test0.txt", - "subdir2/subdir/sub/120-px-file.txt", - ); - - 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)." ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName) ($i)." ); - - $status = $this->backend->lockFiles( $paths, LockManager::LOCK_SH ); - $this->assertEquals( print_r( array(), true ), print_r( $status->errors, true ), - "Locking of files succeeded ($backendName) ($i)." ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName) ($i)." ); - - $status = $this->backend->unlockFiles( $paths, LockManager::LOCK_SH ); - $this->assertEquals( print_r( array(), true ), print_r( $status->errors, true ), - "Locking of files succeeded ($backendName) ($i)." ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName) ($i)." ); - - $status = $this->backend->unlockFiles( $paths, LockManager::LOCK_EX ); - $this->assertEquals( print_r( array(), true ), print_r( $status->errors, true ), - "Locking of files succeeded ($backendName). ($i)" ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName) ($i)." ); - - ## Flip the acquire/release ordering around ## - - $status = $this->backend->lockFiles( $paths, LockManager::LOCK_SH ); - $this->assertEquals( print_r( array(), true ), print_r( $status->errors, true ), - "Locking of files succeeded ($backendName) ($i)." ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName) ($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)." ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName) ($i)." ); - - $status = $this->backend->unlockFiles( $paths, LockManager::LOCK_EX ); - $this->assertEquals( print_r( array(), true ), print_r( $status->errors, true ), - "Locking of files succeeded ($backendName). ($i)" ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName) ($i)." ); - - $status = $this->backend->unlockFiles( $paths, LockManager::LOCK_SH ); - $this->assertEquals( print_r( array(), true ), print_r( $status->errors, true ), - "Locking of files succeeded ($backendName) ($i)." ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName) ($i)." ); - } - - $status = Status::newGood(); - $sl = $this->backend->getScopedFileLocks( $paths, LockManager::LOCK_EX, $status ); - $this->assertType( 'ScopedLock', $sl, - "Scoped locking of files succeeded ($backendName)." ); - $this->assertEquals( array(), $status->errors, - "Scoped locking of files succeeded ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Scoped locking of files succeeded with OK status ($backendName)." ); - - ScopedLock::release( $sl ); - $this->assertEquals( null, $sl, - "Scoped unlocking of files succeeded ($backendName)." ); - $this->assertEquals( array(), $status->errors, - "Scoped unlocking of files succeeded ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "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 ); - } - - // 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 ) { - if ( is_file( $file ) ) { - unlink( $file ); - } - } - $containers = array( 'unittest-cont1', 'unittest-cont2' ); - foreach ( $containers as $container ) { - $this->deleteFiles( $container ); - } - $this->filesToPrune = array(); - } - - private function deleteFiles( $container ) { - $base = self::baseStorePath(); - $iter = $this->backend->getFileList( array( 'dir' => "$base/$container" ) ); - if ( $iter ) { - foreach ( $iter as $file ) { - $this->backend->quickDelete( array( 'src' => "$base/$container/$file" ) ); - } - // free the directory, to avoid Permission denied under windows on rmdir - unset( $iter ); - } - $this->backend->clean( array( 'dir' => "$base/$container", 'recursive' => 1 ) ); - } - - function assertBackendPathsConsistent( array $paths ) { - if ( $this->backend instanceof FileBackendMultiWrite ) { - $status = $this->backend->consistencyCheck( $paths ); - $this->assertGoodStatus( $status, "Files synced: " . implode( ',', $paths ) ); - } - } - - function assertGoodStatus( $status, $msg ) { - $this->assertEquals( print_r( array(), 1 ), print_r( $status->errors, 1 ), $msg ); - } -} diff --git a/tests/phpunit/includes/filerepo/FileRepoTest.php b/tests/phpunit/includes/filerepo/FileRepoTest.php deleted file mode 100644 index e3a75567..00000000 --- a/tests/phpunit/includes/filerepo/FileRepoTest.php +++ /dev/null @@ -1,55 +0,0 @@ -<?php - -class FileRepoTest extends MediaWikiTestCase { - - /** - * @expectedException MWException - * @covers FileRepo::__construct - */ - public function testFileRepoConstructionOptionCanNotBeNull() { - new FileRepo(); - } - - /** - * @expectedException MWException - * @covers FileRepo::__construct - */ - public function testFileRepoConstructionOptionCanNotBeAnEmptyArray() { - new FileRepo( array() ); - } - - /** - * @expectedException MWException - * @covers FileRepo::__construct - */ - public function testFileRepoConstructionOptionNeedNameKey() { - new FileRepo( array( - 'backend' => 'foobar' - ) ); - } - - /** - * @expectedException MWException - * @covers FileRepo::__construct - */ - public function testFileRepoConstructionOptionNeedBackendKey() { - new FileRepo( array( - 'name' => 'foobar' - ) ); - } - - /** - * @covers FileRepo::__construct - */ - public function testFileRepoConstructionWithRequiredOptions() { - $f = new FileRepo( array( - 'name' => 'FileRepoTestRepository', - 'backend' => new FSFileBackend( array( - 'name' => 'local-testing', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array() - ) ) - ) ); - $this->assertInstanceOf( 'FileRepo', $f ); - } -} diff --git a/tests/phpunit/includes/filerepo/StoreBatchTest.php b/tests/phpunit/includes/filerepo/StoreBatchTest.php deleted file mode 100644 index b33c1bbb..00000000 --- a/tests/phpunit/includes/filerepo/StoreBatchTest.php +++ /dev/null @@ -1,134 +0,0 @@ -<?php - -/** - * @group FileRepo - * @group medium - */ -class StoreBatchTest extends MediaWikiTestCase { - - protected $createdFiles; - protected $date; - /** @var FileRepo */ - protected $repo; - - protected function setUp() { - global $wgFileBackends; - parent::setUp(); - - # Forge a FSRepo object to not have to rely on local wiki settings - $tmpPrefix = wfTempDir() . '/storebatch-test-' . time() . '-' . mt_rand(); - if ( $this->getCliArg( 'use-filebackend=' ) ) { - $name = $this->getCliArg( 'use-filebackend=' ); - $useConfig = array(); - foreach ( $wgFileBackends as $conf ) { - if ( $conf['name'] == $name ) { - $useConfig = $conf; - } - } - $useConfig['name'] = 'local-testing'; // swap name - $class = $useConfig['class']; - $backend = new $class( $useConfig ); - } else { - $backend = new FSFileBackend( array( - 'name' => 'local-testing', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( - 'unittests-public' => "{$tmpPrefix}-public", - 'unittests-thumb' => "{$tmpPrefix}-thumb", - 'unittests-temp' => "{$tmpPrefix}-temp", - 'unittests-deleted' => "{$tmpPrefix}-deleted", - ) - ) ); - } - $this->repo = new FileRepo( array( - 'name' => 'unittests', - 'backend' => $backend - ) ); - - $this->date = gmdate( "YmdHis" ); - $this->createdFiles = array(); - } - - protected function tearDown() { - $this->repo->cleanupBatch( $this->createdFiles ); // delete files - foreach ( $this->createdFiles as $tmp ) { // delete dirs - $tmp = $this->repo->resolveVirtualUrl( $tmp ); - while ( $tmp = FileBackend::parentStoragePath( $tmp ) ) { - $this->repo->getBackend()->clean( array( 'dir' => $tmp ) ); - } - } - parent::tearDown(); - } - - /** - * Store a file or virtual URL source into a media file name. - * - * @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 ); - $dstRel = "$hashPath{$this->date}!$originalName"; - $dstUrlRel = $hashPath . $this->date . '!' . rawurlencode( $originalName ); - - $result = $this->repo->store( $srcPath, 'temp', $dstRel, $flags ); - $result->value = $this->repo->getVirtualUrl( 'temp' ) . '/' . $dstUrlRel; - $this->createdFiles[] = $result->value; - - return $result; - } - - /** - * Test storing a file using different flags. - * - * @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 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 ); - $this->assertTrue( $f->isOK(), 'failed to store a new file' ); - $this->assertEquals( $f->failCount, 0, "counts wrong {$f->successCount} {$f->failCount}" ); - $this->assertEquals( $f->successCount, 1, "counts wrong {$f->successCount} {$f->failCount}" ); - if ( $fromrepo ) { - $f = $this->storeit( "Other-$fn", $infn, FileRepo::OVERWRITE ); - $infn = $f->value; - } - // This should work because we're allowed to overwrite - $f = $this->storeit( $fn, $infn, FileRepo::OVERWRITE ); - $this->assertTrue( $f->isOK(), 'We should be allowed to overwrite' ); - $this->assertEquals( $f->failCount, 0, "counts wrong {$f->successCount} {$f->failCount}" ); - $this->assertEquals( $f->successCount, 1, "counts wrong {$f->successCount} {$f->failCount}" ); - // This should fail because we're overwriting. - $f = $this->storeit( $fn, $infn, 0 ); - $this->assertFalse( $f->isOK(), 'We should not be allowed to overwrite' ); - $this->assertEquals( $f->failCount, 1, "counts wrong {$f->successCount} {$f->failCount}" ); - $this->assertEquals( $f->successCount, 0, "counts wrong {$f->successCount} {$f->failCount}" ); - // This should succeed because we're overwriting the same content. - $f = $this->storeit( $fn, $infn, FileRepo::OVERWRITE_SAME ); - $this->assertTrue( $f->isOK(), 'We should be able to overwrite the same content' ); - $this->assertEquals( $f->failCount, 0, "counts wrong {$f->successCount} {$f->failCount}" ); - $this->assertEquals( $f->successCount, 1, "counts wrong {$f->successCount} {$f->failCount}" ); - // This should fail because we're overwriting different content. - if ( $fromrepo ) { - $f = $this->storeit( "Other-$fn", $otherfn, FileRepo::OVERWRITE ); - $otherfn = $f->value; - } - $f = $this->storeit( $fn, $otherfn, FileRepo::OVERWRITE_SAME ); - $this->assertFalse( $f->isOK(), 'We should not be allowed to overwrite different content' ); - $this->assertEquals( $f->failCount, 1, "counts wrong {$f->successCount} {$f->failCount}" ); - $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 ); - $this->storecohort( "Test2.png", "$IP/skins/monobook/wiki.png", "$IP/skins/monobook/video.png", true ); - } -} diff --git a/tests/phpunit/includes/installer/InstallDocFormatterTest.php b/tests/phpunit/includes/installer/InstallDocFormatterTest.php deleted file mode 100644 index 0e5f2671..00000000 --- a/tests/phpunit/includes/installer/InstallDocFormatterTest.php +++ /dev/null @@ -1,65 +0,0 @@ -<?php -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ - -class InstallDocFormatterTest extends MediaWikiTestCase { - /** - * @covers InstallDocFormatter::format - * @dataProvider provideDocFormattingTests - */ - public function testFormat( $expected, $unformattedText, $message = '' ) { - $this->assertEquals( - $expected, - InstallDocFormatter::format( $unformattedText ), - $message - ); - } - - /** - * Provider for testFormat() - */ - 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} - array( ':One indentation', "\tOne indentation", 'Replacing a single \t' ), - array( '::Two indentations', "\t\tTwo indentations", 'Replacing 2 x \t' ), - - # Transform 'bug 123' links - array( - '<span class="config-plainlink">[https://bugzilla.wikimedia.org/123 bug 123]</span>', - 'bug 123', 'Testing bug 123 links' ), - array( - '(<span class="config-plainlink">[https://bugzilla.wikimedia.org/987654 bug 987654]</span>)', - '(bug 987654)', 'Testing (bug 987654) links' ), - - # "bug abc" shouldn't work - array( 'bug foobar', 'bug foobar', "Don't match bug followed by non-digits" ), - array( 'bug !!fakefake!!', 'bug !!fakefake!!', "Don't match bug followed by non-digits" ), - - # Transform '$wgFooBar' links - array( - '<span class="config-plainlink">[http://www.mediawiki.org/wiki/Manual:$wgFooBar $wgFooBar]</span>', - '$wgFooBar', 'Testing basic $wgFooBar' ), - array( - '<span class="config-plainlink">[http://www.mediawiki.org/wiki/Manual:$wgFooBar45 $wgFooBar45]</span>', - '$wgFooBar45', 'Testing $wgFooBar45 (with numbers)' ), - array( - '<span class="config-plainlink">[http://www.mediawiki.org/wiki/Manual:$wgFoo_Bar $wgFoo_Bar]</span>', - '$wgFoo_Bar', 'Testing $wgFoo_Bar (with underscore)' ), - - # Icky variables that shouldn't link - array( '$myAwesomeVariable', '$myAwesomeVariable', 'Testing $myAwesomeVariable (not starting with $wg)' ), - array( '$()not!a&Var', '$()not!a&Var', 'Testing $()not!a&Var (obviously not a variable)' ), - ); - } -} diff --git a/tests/phpunit/includes/installer/OracleInstallerTest.php b/tests/phpunit/includes/installer/OracleInstallerTest.php deleted file mode 100644 index 66e65592..00000000 --- a/tests/phpunit/includes/installer/OracleInstallerTest.php +++ /dev/null @@ -1,48 +0,0 @@ -<?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 deleted file mode 100644 index 4e51c4fc..00000000 --- a/tests/phpunit/includes/jobqueue/JobQueueTest.php +++ /dev/null @@ -1,329 +0,0 @@ -<?php - -/** - * @group JobQueue - * @group medium - * @group Database - */ -class JobQueueTest extends MediaWikiTestCase { - protected $key; - protected $queueRand, $queueRandTTL, $queueFifo, $queueFifoTTL; - - function __construct( $name = null, array $data = array(), $dataName = '' ) { - parent::__construct( $name, $data, $dataName ); - - $this->tablesUsed[] = 'job'; - } - - protected function setUp() { - global $wgJobTypeConf; - parent::setUp(); - - $this->setMwGlobals( 'wgMemc', new HashBagOStuff() ); - - if ( $this->getCliArg( 'use-jobqueue=' ) ) { - $name = $this->getCliArg( 'use-jobqueue=' ); - if ( !isset( $wgJobTypeConf[$name] ) ) { - throw new MWException( "No \$wgJobTypeConf entry for '$name'." ); - } - $baseConfig = $wgJobTypeConf[$name]; - } else { - $baseConfig = array( 'class' => 'JobQueueDB' ); - } - $baseConfig['type'] = 'null'; - $baseConfig['wiki'] = wfWikiID(); - $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() { - parent::tearDown(); - foreach ( - array( - 'queueRand', 'queueRandTTL', 'queueTimestamp', 'queueTimestampTTL', - 'queueFifo', 'queueFifoTTL' - ) as $q - ) { - if ( $this->$q ) { - $this->$q->delete(); - } - $this->$q = null; - } - } - - /** - * @dataProvider provider_queueLists - */ - 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)" ); - } - - /** - * @dataProvider provider_queueLists - */ - public function testBasicOperations( $queue, $recycles, $desc ) { - $queue = $this->$queue; - if ( !$queue ) { - $this->markTestSkipped( $desc ); - } - - $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); - - $queue->flushCaches(); - $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" ); - $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" ); - - $this->assertTrue( $queue->push( $this->newJob() ), "Push worked ($desc)" ); - $this->assertTrue( $queue->batchPush( array( $this->newJob() ) ), "Push worked ($desc)" ); - - $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" ); - - $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)" ); - - $queue->flushCaches(); - $this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" ); - - $queue->flushCaches(); - if ( $recycles ) { - $this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } else { - $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } - - $job2 = $queue->pop(); - $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); - $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" ); - - $queue->flushCaches(); - if ( $recycles ) { - $this->assertEquals( 2, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } else { - $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } - - $queue->ack( $job1 ); - - $queue->flushCaches(); - if ( $recycles ) { - $this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } else { - $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } - - $queue->ack( $job2 ); - - $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 - */ - public function testBasicDeduplication( $queue, $recycles, $desc ) { - $queue = $this->$queue; - if ( !$queue ) { - $this->markTestSkipped( $desc ); - } - - $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); - - $queue->flushCaches(); - $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() ) - ), - "Push worked ($desc)" ); - - $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" ); - - $queue->flushCaches(); - $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->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" ); - - $queue->flushCaches(); - $this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" ); - $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" ); - - $job1 = $queue->pop(); - $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); - - $queue->flushCaches(); - $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" ); - if ( $recycles ) { - $this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } else { - $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } - - $queue->ack( $job1 ); - - $queue->flushCaches(); - $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } - - /** - * @dataProvider provider_queueLists - */ - public function testRootDeduplication( $queue, $recycles, $desc ) { - $queue = $this->$queue; - if ( !$queue ) { - $this->markTestSkipped( $desc ); - } - - $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); - - $queue->flushCaches(); - $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" ); - $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" ); - - $id = wfRandomString( 32 ); - $root1 = Job::newRootJobParams( "nulljobspam:$id" ); // task ID/timestamp - for ( $i = 0; $i < 5; ++$i ) { - $this->assertTrue( $queue->push( $this->newJob( 0, $root1 ) ), "Push worked ($desc)" ); - } - $queue->deduplicateRootJob( $this->newJob( 0, $root1 ) ); - sleep( 1 ); // roo job timestamp will increase - $root2 = Job::newRootJobParams( "nulljobspam:$id" ); // task ID/timestamp - $this->assertNotEquals( $root1['rootJobTimestamp'], $root2['rootJobTimestamp'], - "Root job signatures have different timestamps." ); - for ( $i = 0; $i < 5; ++$i ) { - $this->assertTrue( $queue->push( $this->newJob( 0, $root2 ) ), "Push worked ($desc)" ); - } - $queue->deduplicateRootJob( $this->newJob( 0, $root2 ) ); - - $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" ); - - $queue->flushCaches(); - $this->assertEquals( 10, $queue->getSize(), "Queue size is correct ($desc)" ); - $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" ); - - $dupcount = 0; - $jobs = array(); - do { - $job = $queue->pop(); - if ( $job ) { - $jobs[] = $job; - $queue->ack( $job ); - } - if ( $job instanceof DuplicateJob ) { - ++$dupcount; - } - } while ( $job ); - - $this->assertEquals( 10, count( $jobs ), "Correct number of jobs popped ($desc)" ); - $this->assertEquals( 5, $dupcount, "Correct number of duplicate jobs popped ($desc)" ); - } - - /** - * @dataProvider provider_fifoQueueLists - */ - public function testJobOrder( $queue, $recycles, $desc ) { - $queue = $this->$queue; - if ( !$queue ) { - $this->markTestSkipped( $desc ); - } - - $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); - - $queue->flushCaches(); - $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" ); - $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" ); - - for ( $i = 0; $i < 10; ++$i ) { - $this->assertTrue( $queue->push( $this->newJob( $i ) ), "Push worked ($desc)" ); - } - - for ( $i = 0; $i < 10; ++$i ) { - $job = $queue->pop(); - $this->assertTrue( $job instanceof Job, "Jobs popped from queue ($desc)" ); - $params = $job->getParams(); - $this->assertEquals( $i, $params['i'], "Job popped from queue is FIFO ($desc)" ); - $queue->ack( $job ); - } - - $this->assertFalse( $queue->pop(), "Queue is not empty ($desc)" ); - - $queue->flushCaches(); - $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" ); - $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" ); - } - - public static function provider_queueLists() { - return array( - 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()' ) - ); - } - - public static function provider_fifoQueueLists() { - return array( - array( 'queueFifo', false, 'Ordered queue without ack()' ), - array( 'queueFifoTTL', true, 'Ordered queue with ack()' ) - ); - } - - function newJob( $i = 0, $rootJob = array() ) { - return new NullJob( Title::newMainPage(), - array( 'lives' => 0, 'usleep' => 0, 'removeDuplicates' => 0, 'i' => $i ) + $rootJob ); - } - - function newDedupedJob( $i = 0, $rootJob = array() ) { - return new NullJob( Title::newMainPage(), - array( 'lives' => 0, 'usleep' => 0, 'removeDuplicates' => 1, 'i' => $i ) + $rootJob ); - } -} diff --git a/tests/phpunit/includes/json/FormatJsonTest.php b/tests/phpunit/includes/json/FormatJsonTest.php deleted file mode 100644 index 149be05b..00000000 --- a/tests/phpunit/includes/json/FormatJsonTest.php +++ /dev/null @@ -1,161 +0,0 @@ -<?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/libs/CSSJanusTest.php b/tests/phpunit/includes/libs/CSSJanusTest.php deleted file mode 100644 index 5a3c1619..00000000 --- a/tests/phpunit/includes/libs/CSSJanusTest.php +++ /dev/null @@ -1,606 +0,0 @@ -<?php -/** - * Based on the test suite of the original Python - * 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 - */ - public function testTransform( $cssA, $cssB = null ) { - - if ( $cssB ) { - $transformedA = CSSJanus::transform( $cssA ); - $this->assertEquals( $transformedA, $cssB, 'Test A-B transformation' ); - - $transformedB = CSSJanus::transform( $cssB ); - $this->assertEquals( $transformedB, $cssA, 'Test B-A transformation' ); - } else { - // If no B version is provided, it means - // the output should equal the input. - $transformedA = CSSJanus::transform( $cssA ); - $this->assertEquals( $transformedA, $cssA, 'Nothing was flipped' ); - } - } - - /** - * @dataProvider provideTransformAdvancedCases - */ - public function testTransformAdvanced( $code, $expectedOutput, $options = array() ) { - $swapLtrRtlInURL = isset( $options['swapLtrRtlInURL'] ) ? $options['swapLtrRtlInURL'] : false; - $swapLeftRightInURL = isset( $options['swapLeftRightInURL'] ) ? $options['swapLeftRightInURL'] : false; - - $flipped = CSSJanus::transform( $code, $swapLtrRtlInURL, $swapLeftRightInURL ); - - $this->assertEquals( $expectedOutput, $flipped, - 'Test flipping, options: url-ltr-rtl=' . ( $swapLtrRtlInURL ? 'true' : 'false' ) - . ' url-left-right=' . ( $swapLeftRightInURL ? 'true' : 'false' ) - ); - } - - /** - * @dataProvider provideTransformBrokenCases - * @group Broken - */ - public function testTransformBroken( $code, $expectedOutput ) { - $flipped = CSSJanus::transform( $code ); - - $this->assertEquals( $expectedOutput, $flipped, 'Test flipping' ); - } - - /** - * These transform cases are tested *in both directions* - * No need to declare a principle twice in both directions here. - */ - public static function provideTransformCases() { - return array( - // Property keys - array( - '.foo { left: 0; }', - '.foo { right: 0; }' - ), - // Guard against partial keys - // (CSS currently doesn't have flippable properties - // that contain the direction as part of the key without - // dash separation) - array( - '.foo { alright: 0; }' - ), - array( - '.foo { balleft: 0; }' - ), - - // Dashed property keys - array( - '.foo { padding-left: 0; }', - '.foo { padding-right: 0; }' - ), - array( - '.foo { margin-left: 0; }', - '.foo { margin-right: 0; }' - ), - array( - '.foo { border-left: 0; }', - '.foo { border-right: 0; }' - ), - - // Double-dashed property keys - array( - '.foo { border-left-color: red; }', - '.foo { border-right-color: red; }' - ), - array( - // Includes unknown properties? - '.foo { x-left-y: 0; }', - '.foo { x-right-y: 0; }' - ), - - // Multi-value properties - array( - '.foo { padding: 0; }' - ), - array( - '.foo { padding: 0 1px; }' - ), - array( - '.foo { padding: 0 1px 2px; }' - ), - array( - '.foo { padding: 0 1px 2px 3px; }', - '.foo { padding: 0 3px 2px 1px; }' - ), - - // Shorthand / Four notation - array( - '.foo { padding: .25em 15px 0pt 0ex; }', - '.foo { padding: .25em 0ex 0pt 15px; }' - ), - array( - '.foo { margin: 1px -4px 3px 2px; }', - '.foo { margin: 1px 2px 3px -4px; }' - ), - array( - '.foo { padding: 0 15px .25em 0; }', - '.foo { padding: 0 0 .25em 15px; }' - ), - array( - '.foo { padding: 1px 4.1grad 3px 2%; }', - '.foo { padding: 1px 2% 3px 4.1grad; }' - ), - array( - '.foo { padding: 1px 2px 3px auto; }', - '.foo { padding: 1px auto 3px 2px; }' - ), - array( - '.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: 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( - '.foo barpx 0 2% { opacity: 0; }' - ), - array( - '#settings td p strong' - ), - array( - // 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( - // 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 - array( - '.foo { margin: 1em 0 .25em; }' - ), - array( - '.foo { margin:-1.5em 0 -.75em; }' - ), - - // Shorthand / Two notation - array( - '.foo { padding: 1px 2px; }' - ), - - // Shorthand / One notation - array( - '.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. - array( - '.foo { direction: ltr; }', - '.foo { direction: rtl; }' - ), - array( - '.foo { direction: rtl; }', - '.foo { direction: ltr; }' - ), - array( - 'input { direction: ltr; }', - 'input { direction: rtl; }' - ), - array( - 'input { direction: rtl; }', - 'input { direction: ltr; }' - ), - array( - 'body { direction: ltr; }', - 'body { direction: rtl; }' - ), - array( - '.foo, body, input { direction: ltr; }', - '.foo, body, input { direction: rtl; }' - ), - array( - 'body { padding: 10px; direction: ltr; }', - 'body { padding: 10px; direction: rtl; }' - ), - array( - 'body { direction: ltr } .myClass { direction: ltr }', - 'body { direction: rtl } .myClass { direction: rtl }' - ), - - // Left/right values - array( - '.foo { float: left; }', - '.foo { float: right; }' - ), - array( - '.foo { text-align: left; }', - '.foo { text-align: right; }' - ), - array( - '.foo { -x-unknown: left; }', - '.foo { -x-unknown: right; }' - ), - // Guard against selectors that look flippable - array( - '.column-left { width: 0; }' - ), - array( - 'a.left { width: 0; }' - ), - array( - 'a.leftification { width: 0; }' - ), - array( - 'a.ltr { width: 0; }' - ), - array( - # <div class="a-ltr png"> - '.a-ltr.png { width: 0; }' - ), - array( - # <foo-ltr attr="x"> - 'foo-ltr[attr="x"] { width: 0; }' - ), - array( - 'div.left > span.right+span.left { width: 0; }' - ), - array( - '.thisclass .left .myclass { width: 0; }' - ), - array( - '.thisclass .left .myclass #myid { width: 0; }' - ), - - // Cursor values (east/west) - array( - '.foo { cursor: e-resize; }', - '.foo { cursor: w-resize; }' - ), - array( - '.foo { cursor: se-resize; }', - '.foo { cursor: sw-resize; }' - ), - array( - '.foo { cursor: ne-resize; }', - '.foo { cursor: nw-resize; }' - ), - - // Background - array( - '.foo { background-position: top left; }', - '.foo { background-position: top right; }' - ), - array( - '.foo { background: url(/foo/bar.png) top left; }', - '.foo { background: url(/foo/bar.png) top right; }' - ), - array( - '.foo { background: url(/foo/bar.png) top left no-repeat; }', - '.foo { background: url(/foo/bar.png) top right no-repeat; }' - ), - array( - '.foo { background: url(/foo/bar.png) no-repeat top left; }', - '.foo { background: url(/foo/bar.png) no-repeat top right; }' - ), - array( - '.foo { background: #fff url(/foo/bar.png) no-repeat top left; }', - '.foo { background: #fff url(/foo/bar.png) no-repeat top right; }' - ), - array( - '.foo { background-position: 100% 40%; }', - '.foo { background-position: 0% 40%; }' - ), - array( - '.foo { background-position: 23% 0; }', - '.foo { background-position: 77% 0; }' - ), - array( - '.foo { background-position: 23% auto; }', - '.foo { background-position: 77% auto; }' - ), - array( - '.foo { background-position-x: 23%; }', - '.foo { background-position-x: 77%; }' - ), - array( - '.foo { background-position-y: 23%; }', - '.foo { background-position-y: 23%; }' - ), - array( - '.foo { background:url(../foo.png) no-repeat 75% 50%; }', - '.foo { background:url(../foo.png) no-repeat 25% 50%; }' - ), - array( - '.foo { background: 10% 20% } .bar { background: 40% 30% }', - '.foo { background: 90% 20% } .bar { background: 60% 30% }' - ), - - // Multiple rules - array( - 'body { direction: rtl; float: right; } .foo { direction: ltr; float: right; }', - 'body { direction: ltr; float: left; } .foo { direction: rtl; float: left; }', - ), - - // Duplicate properties - array( - '.foo { float: left; float: right; float: left; }', - '.foo { float: right; float: left; float: right; }', - ), - - // Preserve comments - array( - '/* left /* right */left: 10px', - '/* left /* right */right: 10px' - ), - array( - '/*left*//*left*/left: 10px', - '/*left*//*left*/right: 10px' - ), - array( - '/* Going right is cool */ .foo { width: 0 }', - ), - array( - "/* padding-right 1 2 3 4 */\n#test { width: 0}\n/*right*/" - ), - array( - "/** Two line comment\n * left\n \*/\n#test {width: 0}" - ), - - // @noflip annotation - array( - // before selector (single) - '/* @noflip */ div { float: left; }' - ), - array( - // before selector (multiple) - '/* @noflip */ div, .notme { float: left; }' - ), - array( - // inside selector - 'div, /* @noflip */ .foo { float: left; }' - ), - array( - // after selector - 'div, .notme /* @noflip */ { float: left; }' - ), - array( - // before multiple rules - '/* @noflip */ div { float: left; } .foo { float: left; }', - '/* @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; }' - ), - array( - // before multiple properties - 'div { /* @noflip */ float: left; text-align: left; }', - 'div { /* @noflip */ float: left; text-align: right; }' - ), - array( - // after multiple properties - 'div { float: left; /* @noflip */ text-align: left; }', - 'div { float: right; /* @noflip */ text-align: left; }' - ), - - // Guard against css3 stuff - array( - 'background-image: -moz-linear-gradient(#326cc1, #234e8c);' - ), - array( - 'background-image: -webkit-gradient(linear, 100% 0%, 0% 0%, from(#666666), to(#ffffff));' - ), - - // CSS syntax / white-space variations - // spaces, no spaces, tabs, new lines, omitting semi-colons - array( - ".foo { left: 0; }", - ".foo { right: 0; }" - ), - array( - ".foo{ left: 0; }", - ".foo{ right: 0; }" - ), - array( - ".foo{ left: 0 }", - ".foo{ right: 0 }" - ), - array( - ".foo{left:0 }", - ".foo{right:0 }" - ), - array( - ".foo{left:0}", - ".foo{right:0}" - ), - array( - ".foo { left : 0 ; }", - ".foo { right : 0 ; }" - ), - array( - ".foo\n { left : 0 ; }", - ".foo\n { right : 0 ; }" - ), - array( - ".foo\n { \nleft : 0 ; }", - ".foo\n { \nright : 0 ; }" - ), - array( - ".foo\n { \n left : 0 ; }", - ".foo\n { \n right : 0 ; }" - ), - array( - ".foo\n { \n left\n : 0; }", - ".foo\n { \n right\n : 0; }" - ), - array( - ".foo \n { \n left\n : 0; }", - ".foo \n { \n right\n : 0; }" - ), - array( - ".foo\n{\nleft\n:\n0;}", - ".foo\n{\nright\n:\n0;}" - ), - array( - ".foo\n.bar {\n\tleft: 0;\n}", - ".foo\n.bar {\n\tright: 0;\n}" - ), - array( - ".foo\t{\tleft\t:\t0;}", - ".foo\t{\tright\t:\t0;}" - ), - - // Guard against partial keys - array( - '.foo { leftxx: 0; }', - '.foo { leftxx: 0; }' - ), - array( - '.foo { rightxx: 0; }', - '.foo { rightxx: 0; }' - ), - ); - } - - /** - * These cases are tested in one way only (format: actual, expected, msg). - * If both ways can be tested, either put both versions in here or move - * it to provideTransformCases(). - */ - public static function provideTransformAdvancedCases() { - $bgPairs = array( - # [ - _ . ] <-> [ left right ltr rtl ] - 'foo.jpg' => 'foo.jpg', - 'left.jpg' => 'right.jpg', - 'ltr.jpg' => 'rtl.jpg', - - 'foo-left.png' => 'foo-right.png', - 'foo_left.png' => 'foo_right.png', - 'foo.left.png' => 'foo.right.png', - - 'foo-ltr.png' => 'foo-rtl.png', - 'foo_ltr.png' => 'foo_rtl.png', - 'foo.ltr.png' => 'foo.rtl.png', - - 'left-foo.png' => 'right-foo.png', - 'left_foo.png' => 'right_foo.png', - 'left.foo.png' => 'right.foo.png', - - 'ltr-foo.png' => 'rtl-foo.png', - 'ltr_foo.png' => 'rtl_foo.png', - 'ltr.foo.png' => 'rtl.foo.png', - - 'foo-ltr-left.gif' => 'foo-rtl-right.gif', - 'foo_ltr_left.gif' => 'foo_rtl_right.gif', - 'foo.ltr.left.gif' => 'foo.rtl.right.gif', - 'foo-ltr_left.gif' => 'foo-rtl_right.gif', - 'foo_ltr.left.gif' => 'foo_rtl.right.gif', - ); - $provider = array(); - foreach ( $bgPairs as $left => $right ) { - # By default '-rtl' and '-left' etc. are not touched, - # Only when the appropiate parameter is set. - $provider[] = array( - ".foo { background: url(images/$left); }", - ".foo { background: url(images/$left); }" - ); - $provider[] = array( - ".foo { background: url(images/$right); }", - ".foo { background: url(images/$right); }" - ); - $provider[] = array( - ".foo { background: url(images/$left); }", - ".foo { background: url(images/$right); }", - array( - 'swapLtrRtlInURL' => true, - 'swapLeftRightInURL' => true, - ) - ); - $provider[] = array( - ".foo { background: url(images/$right); }", - ".foo { background: url(images/$left); }", - array( - 'swapLtrRtlInURL' => true, - 'swapLeftRightInURL' => true, - ) - ); - } - - return $provider; - } - - /** - * Cases that are currently failing, but - * should be looked at in the future as enhancements and/or bug fix - */ - public static function provideTransformBrokenCases() { - return array( - // Guard against selectors that look flippable - array( - # <foo-left-x attr="x"> - 'foo-left-x[attr="x"] { width: 0; }', - 'foo-left-x[attr="x"] { width: 0; }' - ), - array( - # <div class="foo" data-left="x"> - '.foo[data-left="x"] { width: 0; }', - '.foo[data-left="x"] { width: 0; }' - ), - ); - } -} diff --git a/tests/phpunit/includes/libs/CSSMinTest.php b/tests/phpunit/includes/libs/CSSMinTest.php deleted file mode 100644 index 951dd7b9..00000000 --- a/tests/phpunit/includes/libs/CSSMinTest.php +++ /dev/null @@ -1,133 +0,0 @@ -<?php -/** - * This file test the CSSMin library shipped with Mediawiki. - * - * @author Timo Tijhof - */ - -class CSSMinTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - $server = 'http://doc.example.org'; - - $this->setMwGlobals( array( - 'wgServer' => $server, - 'wgCanonicalServer' => $server, - ) ); - } - - /** - * @dataProvider provideMinifyCases - */ - public function testMinify( $code, $expectedOutput ) { - $minified = CSSMin::minify( $code ); - - $this->assertEquals( $expectedOutput, $minified, 'Minified output should be in the form expected.' ); - } - - public static function provideMinifyCases() { - return array( - // Whitespace - array( "\r\t\f \v\n\r", "" ), - array( "foo, bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ), - - // Loose comments - array( "/* foo */", "" ), - array( "/*******\n foo\n *******/", "" ), - array( "/*!\n foo\n */", "" ), - - // Inline comments in various different places - array( "/* comment */foo, bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ), - array( "foo/* comment */, bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ), - array( "foo,/* comment */ bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ), - array( "foo, bar/* comment */ {\n\tprop: value;\n}", "foo,bar{prop:value}" ), - array( "foo, bar {\n\t/* comment */prop: value;\n}", "foo,bar{prop:value}" ), - array( "foo, bar {\n\tprop: /* comment */value;\n}", "foo,bar{prop:value}" ), - array( "foo, bar {\n\tprop: value /* comment */;\n}", "foo,bar{prop:value }" ), - array( "foo, bar {\n\tprop: value; /* comment */\n}", "foo,bar{prop:value; }" ), - - // Keep track of things that aren't as minified as much as they - // could be (bug 35493) - array( 'foo { prop: value ;}', 'foo{prop:value }' ), - array( 'foo { prop : value; }', 'foo{prop :value}' ), - array( 'foo { prop: value ; }', 'foo{prop:value }' ), - array( 'foo { font-family: "foo" , "bar"; }', 'foo{font-family:"foo" ,"bar"}' ), - array( "foo { src:\n\turl('foo') ,\n\turl('bar') ; }", "foo{src:url('foo') ,url('bar') }" ), - - // Interesting cases with string values - // - Double quotes, single quotes - array( 'foo { content: ""; }', 'foo{content:""}' ), - array( "foo { content: ''; }", "foo{content:''}" ), - array( 'foo { content: "\'"; }', 'foo{content:"\'"}' ), - array( "foo { content: '\"'; }", "foo{content:'\"'}" ), - // - Whitespace in string values - array( 'foo { content: " "; }', 'foo{content:" "}' ), - ); - } - - /** - * @dataProvider provideRemapCases - */ - 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 ); - } - - public static function provideRemapCases() { - // Parameter signature: - // CSSMin::remap( $code, $local, $remote, $embedData = true ) - return array( - array( - 'Simple case', - array( 'foo { prop: url(bar.png); }', false, 'http://example.org', false ), - 'foo { prop: url(http://example.org/bar.png); }', - ), - array( - 'Without trailing slash', - array( 'foo { prop: url(../bar.png); }', false, 'http://example.org/quux', false ), - 'foo { prop: url(http://example.org/quux/../bar.png); }', - ), - array( - 'With trailing slash on remote (bug 27052)', - array( 'foo { prop: url(../bar.png); }', false, 'http://example.org/quux/', false ), - 'foo { prop: url(http://example.org/quux/../bar.png); }', - ), - array( - 'Guard against stripping double slashes from query', - array( 'foo { prop: url(bar.png?corge=//grault); }', false, 'http://example.org/quux/', false ), - 'foo { prop: url(http://example.org/quux/bar.png?corge=//grault); }', - ), - array( - 'Expand absolute paths', - array( 'foo { prop: url(/w/skin/images/bar.png); }', false, 'http://example.org/quux', false ), - 'foo { prop: url(http://doc.example.org/w/skin/images/bar.png); }', - ), - ); - } - - /** - * Seperated because they are currently broken (bug 35492) - * - * @group Broken - * @dataProvider provideStringCases - */ - public function testMinifyWithCSSStringValues( $code, $expectedOutput ) { - $this->testMinifyOutput( $code, $expectedOutput ); - } - - public static function provideStringCases() { - return array( - // String values should be respected - // - More than one space in a string value - array( 'foo { content: " "; }', 'foo{content:" "}' ), - // - Using a tab in a string value (turns into a space) - array( "foo { content: '\t'; }", "foo{content:'\t'}" ), - // - Using css-like syntax in string values - array( 'foo::after { content: "{;}"; position: absolute; }', 'foo::after{content:"{;}";position:absolute}' ), - ); - } -} diff --git a/tests/phpunit/includes/libs/GenericArrayObjectTest.php b/tests/phpunit/includes/libs/GenericArrayObjectTest.php deleted file mode 100644 index 7436c43c..00000000 --- a/tests/phpunit/includes/libs/GenericArrayObjectTest.php +++ /dev/null @@ -1,263 +0,0 @@ -<?php - -/** - * Tests for the GenericArrayObject and deriving classes. - * - * 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 - * @since 1.20 - * - * @ingroup Test - * @group GenericArrayObject - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - */ -abstract class GenericArrayObjectTest extends MediaWikiTestCase { - - /** - * Returns objects that can serve as elements in the concrete GenericArrayObject deriving class being tested. - * - * @since 1.20 - * - * @return array - */ - abstract public function elementInstancesProvider(); - - /** - * Returns the name of the concrete class being tested. - * - * @since 1.20 - * - * @return string - */ - abstract public function getInstanceClass(); - - /** - * Provides instances of the concrete class being tested. - * - * @since 1.20 - * - * @return array - */ - public function instanceProvider() { - $instances = array(); - - foreach ( $this->elementInstancesProvider() as $elementInstances ) { - $instances[] = $this->getNew( $elementInstances[0] ); - } - - return $this->arrayWrap( $instances ); - } - - /** - * @since 1.20 - * - * @param array $elements - * - * @return GenericArrayObject - */ - protected function getNew( array $elements = array() ) { - $class = $this->getInstanceClass(); - - return new $class( $elements ); - } - - /** - * @dataProvider elementInstancesProvider - * - * @since 1.20 - * - * @param array $elements - */ - public function testConstructor( array $elements ) { - $arrayObject = $this->getNew( $elements ); - - $this->assertEquals( count( $elements ), $arrayObject->count() ); - } - - /** - * @dataProvider elementInstancesProvider - * - * @since 1.20 - * - * @param array $elements - */ - public function testIsEmpty( array $elements ) { - $arrayObject = $this->getNew( $elements ); - - $this->assertEquals( $elements === array(), $arrayObject->isEmpty() ); - } - - /** - * @dataProvider instanceProvider - * - * @since 1.20 - * - * @param GenericArrayObject $list - */ - public function testUnset( GenericArrayObject $list ) { - if ( $list->isEmpty() ) { - $this->assertTrue( true ); // We cannot test unset if there are no elements - } else { - $offset = $list->getIterator()->key(); - $count = $list->count(); - $list->offsetUnset( $offset ); - $this->assertEquals( $count - 1, $list->count() ); - } - - if ( !$list->isEmpty() ) { - $offset = $list->getIterator()->key(); - $count = $list->count(); - unset( $list[$offset] ); - $this->assertEquals( $count - 1, $list->count() ); - } - } - - /** - * @dataProvider elementInstancesProvider - * - * @since 1.20 - * - * @param array $elements - */ - public function testAppend( array $elements ) { - $list = $this->getNew(); - - $listSize = count( $elements ); - - foreach ( $elements as $element ) { - $list->append( $element ); - } - - $this->assertEquals( $listSize, $list->count() ); - - $list = $this->getNew(); - - foreach ( $elements as $element ) { - $list[] = $element; - } - - $this->assertEquals( $listSize, $list->count() ); - - $this->checkTypeChecks( function ( GenericArrayObject $list, $element ) { - $list->append( $element ); - } ); - } - - /** - * @since 1.20 - * - * @param callback $function - */ - protected function checkTypeChecks( $function ) { - $excption = null; - $list = $this->getNew(); - - $elementClass = $list->getObjectType(); - - foreach ( array( 42, 'foo', array(), new stdClass(), 4.2 ) as $element ) { - $validValid = $element instanceof $elementClass; - - try { - call_user_func( $function, $list, $element ); - $valid = true; - } catch ( InvalidArgumentException $exception ) { - $valid = false; - } - - $this->assertEquals( - $validValid, - $valid, - 'Object of invalid type got successfully added to a GenericArrayObject' - ); - } - } - - /** - * @dataProvider elementInstancesProvider - * - * @since 1.20 - * - * @param array $elements - */ - public function testOffsetSet( array $elements ) { - if ( $elements === array() ) { - $this->assertTrue( true ); - - return; - } - - $list = $this->getNew(); - - $element = reset( $elements ); - $list->offsetSet( 42, $element ); - $this->assertEquals( $element, $list->offsetGet( 42 ) ); - - $list = $this->getNew(); - - $element = reset( $elements ); - $list['oHai'] = $element; - $this->assertEquals( $element, $list['oHai'] ); - - $list = $this->getNew(); - - $element = reset( $elements ); - $list->offsetSet( 9001, $element ); - $this->assertEquals( $element, $list[9001] ); - - $list = $this->getNew(); - - $element = reset( $elements ); - $list->offsetSet( null, $element ); - $this->assertEquals( $element, $list[0] ); - - $list = $this->getNew(); - $offset = 0; - - foreach ( $elements as $element ) { - $list->offsetSet( null, $element ); - $this->assertEquals( $element, $list[$offset++] ); - } - - $this->assertEquals( count( $elements ), $list->count() ); - - $this->checkTypeChecks( function ( GenericArrayObject $list, $element ) { - $list->offsetSet( mt_rand(), $element ); - } ); - } - - /** - * @dataProvider instanceProvider - * - * @since 1.21 - * - * @param GenericArrayObject $list - */ - public function testSerialization( GenericArrayObject $list ) { - $serialization = serialize( $list ); - $copy = unserialize( $serialization ); - - $this->assertEquals( $serialization, serialize( $copy ) ); - $this->assertEquals( count( $list ), count( $copy ) ); - - $list = $list->getArrayCopy(); - $copy = $copy->getArrayCopy(); - - $this->assertArrayEquals( $list, $copy, true, true ); - } -} diff --git a/tests/phpunit/includes/libs/IEUrlExtensionTest.php b/tests/phpunit/includes/libs/IEUrlExtensionTest.php deleted file mode 100644 index 66fe915a..00000000 --- a/tests/phpunit/includes/libs/IEUrlExtensionTest.php +++ /dev/null @@ -1,126 +0,0 @@ -<?php - -/** - * Tests for IEUrlExtension::findIE6Extension - */ -class IEUrlExtensionTest extends MediaWikiTestCase { - public function testSimple() { - $this->assertEquals( - 'y', - IEUrlExtension::findIE6Extension( 'x.y' ), - 'Simple extension' - ); - } - - public function testSimpleNoExt() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( 'x' ), - 'No extension' - ); - } - - public function testEmpty() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( '' ), - 'Empty string' - ); - } - - public function testQuestionMark() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( '?' ), - 'Question mark only' - ); - } - - public function testExtQuestionMark() { - $this->assertEquals( - 'x', - IEUrlExtension::findIE6Extension( '.x?' ), - 'Extension then question mark' - ); - } - - public function testQuestionMarkExt() { - $this->assertEquals( - 'x', - IEUrlExtension::findIE6Extension( '?.x' ), - 'Question mark then extension' - ); - } - - public function testInvalidChar() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( '.x*' ), - 'Extension with invalid character' - ); - } - - public function testInvalidCharThenExtension() { - $this->assertEquals( - 'x', - IEUrlExtension::findIE6Extension( '*.x' ), - 'Invalid character followed by an extension' - ); - } - - public function testMultipleQuestionMarks() { - $this->assertEquals( - 'c', - IEUrlExtension::findIE6Extension( 'a?b?.c?.d?e?f' ), - 'Multiple question marks' - ); - } - - public function testExeException() { - $this->assertEquals( - 'd', - IEUrlExtension::findIE6Extension( 'a?b?.exe?.d?.e' ), - '.exe exception' - ); - } - - public function testExeException2() { - $this->assertEquals( - 'exe', - IEUrlExtension::findIE6Extension( 'a?b?.exe' ), - '.exe exception 2' - ); - } - - public function testHash() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( 'a#b.c' ), - 'Hash character preceding extension' - ); - } - - public function testHash2() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( 'a?#b.c' ), - 'Hash character preceding extension 2' - ); - } - - public function testDotAtEnd() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( '.' ), - 'Dot at end of string' - ); - } - - public function testTwoDots() { - $this->assertEquals( - 'z', - IEUrlExtension::findIE6Extension( 'x.y.z' ), - 'Two dots' - ); - } -} diff --git a/tests/phpunit/includes/libs/JavaScriptMinifierTest.php b/tests/phpunit/includes/libs/JavaScriptMinifierTest.php deleted file mode 100644 index ab72e361..00000000 --- a/tests/phpunit/includes/libs/JavaScriptMinifierTest.php +++ /dev/null @@ -1,170 +0,0 @@ -<?php - -class JavaScriptMinifierTest extends MediaWikiTestCase { - - public static function provideCases() { - return array( - - // Basic whitespace and comments that should be stripped entirely - array( "\r\t\f \v\n\r", "" ), - array( "/* Foo *\n*bar\n*/", "" ), - - /** - * Slashes used inside block comments (bug 26931). - * At some point there was a bug that caused this comment to be ended at '* /', - * causing /M... to be left as the beginning of a regex. - */ - array( "/**\n * Foo\n * {\n * 'bar' : {\n * //Multiple rules with configurable operators\n * 'baz' : false\n * }\n */", "" ), - - /** - * ' Foo \' bar \ - * baz \' quox ' . - */ - array( "' Foo \\' bar \\\n baz \\' quox ' .length", "' Foo \\' bar \\\n baz \\' quox '.length" ), - array( "\" Foo \\\" bar \\\n baz \\\" quox \" .length", "\" Foo \\\" bar \\\n baz \\\" quox \".length" ), - array( "// Foo b/ar baz", "" ), - array( "/ Foo \\/ bar [ / \\] / ] baz / .length", "/ Foo \\/ bar [ / \\] / ] baz /.length" ), - - // HTML comments - array( "<!-- Foo bar", "" ), - array( "<!-- Foo --> bar", "" ), - array( "--> Foo", "" ), - array( "x --> y", "x-->y" ), - - // Semicolon insertion - array( "(function(){return\nx;})", "(function(){return\nx;})" ), - array( "throw\nx;", "throw\nx;" ), - array( "while(p){continue\nx;}", "while(p){continue\nx;}" ), - array( "while(p){break\nx;}", "while(p){break\nx;}" ), - array( "var\nx;", "var x;" ), - array( "x\ny;", "x\ny;" ), - array( "x\n++y;", "x\n++y;" ), - array( "x\n!y;", "x\n!y;" ), - array( "x\n{y}", "x\n{y}" ), - array( "x\n+y;", "x+y;" ), - array( "x\n(y);", "x(y);" ), - array( "5.\nx;", "5.\nx;" ), - array( "0xFF.\nx;", "0xFF.x;" ), - array( "5.3.\nx;", "5.3.x;" ), - - // Semicolon insertion between an expression having an inline - // comment after it, and a statement on the next line (bug 27046). - array( "var a = this //foo bar \n for ( b = 0; c < d; b++ ) {}", "var a=this\nfor(b=0;c<d;b++){}" ), - - // Token separation - array( "x in y", "x in y" ), - array( "/x/g in y", "/x/g in y" ), - array( "x in 30", "x in 30" ), - array( "x + ++ y", "x+ ++y" ), - array( "x ++ + y", "x++ +y" ), - array( "x / /y/.exec(z)", "x/ /y/.exec(z)" ), - - // State machine - array( "/ x/g", "/ x/g" ), - array( "(function(){return/ x/g})", "(function(){return/ x/g})" ), - array( "+/ x/g", "+/ x/g" ), - array( "++/ x/g", "++/ x/g" ), - array( "x/ x/g", "x/x/g" ), - array( "(/ x/g)", "(/ x/g)" ), - array( "if(/ x/g);", "if(/ x/g);" ), - array( "(x/ x/g)", "(x/x/g)" ), - array( "([/ x/g])", "([/ x/g])" ), - array( "+x/ x/g", "+x/x/g" ), - array( "{}/ x/g", "{}/ x/g" ), - array( "+{}/ x/g", "+{}/x/g" ), - array( "(x)/ x/g", "(x)/x/g" ), - array( "if(x)/ x/g", "if(x)/ x/g" ), - array( "for(x;x;{}/ x/g);", "for(x;x;{}/x/g);" ), - array( "x;x;{}/ x/g", "x;x;{}/ x/g" ), - array( "x:{}/ x/g", "x:{}/ x/g" ), - array( "switch(x){case y?z:{}/ x/g:{}/ x/g;}", "switch(x){case y?z:{}/x/g:{}/ x/g;}" ), - array( "function x(){}/ x/g", "function x(){}/ x/g" ), - array( "+function x(){}/ x/g", "+function x(){}/x/g" ), - - // Multiline quoted string - array( "var foo=\"\\\nblah\\\n\";", "var foo=\"\\\nblah\\\n\";" ), - - // Multiline quoted string followed by string with spaces - array( "var foo=\"\\\nblah\\\n\";\nvar baz = \" foo \";\n", "var foo=\"\\\nblah\\\n\";var baz=\" foo \";" ), - - // URL in quoted string ( // is not a comment) - array( "aNode.setAttribute('href','http://foo.bar.org/baz');", "aNode.setAttribute('href','http://foo.bar.org/baz');" ), - - // URL in quoted string after multiline quoted string - array( "var foo=\"\\\nblah\\\n\";\naNode.setAttribute('href','http://foo.bar.org/baz');", "var foo=\"\\\nblah\\\n\";aNode.setAttribute('href','http://foo.bar.org/baz');" ), - - // Division vs. regex nastiness - array( "alert( (10+10) / '/'.charCodeAt( 0 ) + '//' );", "alert((10+10)/'/'.charCodeAt(0)+'//');" ), - array( "if(1)/a /g.exec('Pa ss');", "if(1)/a /g.exec('Pa ss');" ), - - // newline insertion after 1000 chars: break after the "++", not before - array( str_repeat( ';', 996 ) . "if(x++);", str_repeat( ';', 996 ) . "if(x++\n);" ), - - // Unicode letter characters should pass through ok in identifiers (bug 31187) - array( "var KaŝSkatolVal = {}", 'var KaŝSkatolVal={}' ), - - // Per spec unicode char escape values should work in identifiers, - // as long as it's a valid char. In future it might get normalized. - array( "var Ka\\u015dSkatolVal = {}", 'var Ka\\u015dSkatolVal={}' ), - - // Some structures that might look invalid at first sight - array( "var a = 5.;", "var a=5.;" ), - array( "5.0.toString();", "5.0.toString();" ), - array( "5..toString();", "5..toString();" ), - array( "5...toString();", false ), - array( "5.\n.toString();", '5..toString();' ), - ); - } - - /** - * @dataProvider provideCases - */ - public function testJavaScriptMinifierOutput( $code, $expectedOutput ) { - $minified = JavaScriptMinifier::minify( $code ); - - // JSMin+'s parser will throw an exception if output is not valid JS. - // suppression of warnings needed for stupid crap - wfSuppressWarnings(); - $parser = new JSParser(); - wfRestoreWarnings(); - $parser->parse( $minified, 'minify-test.js', 1 ); - - $this->assertEquals( $expectedOutput, $minified, "Minified output should be in the form expected." ); - } - - public static function provideBug32548() { - return array( - array( - // This one gets interpreted all together by the prior code; - // no break at the 'E' happens. - '1.23456789E55', - ), - array( - // This one breaks under the bad code; splits between 'E' and '+' - '1.23456789E+5', - ), - array( - // This one breaks under the bad code; splits between 'E' and '-' - '1.23456789E-5', - ), - ); - } - - /** - * @dataProvider provideBug32548 - */ - 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. - $prefix = 'var longVarName' . str_repeat( '_', 973 ) . '='; - $suffix = ',shortVarName=0;'; - - $input = $prefix . $num . $suffix; - $expected = $prefix . "\n" . $num . $suffix; - - $minified = JavaScriptMinifier::minify( $input ); - - $this->assertEquals( $expected, $minified, "Line breaks must not occur in middle of exponent" ); - } -} diff --git a/tests/phpunit/includes/logging/LogFormatterTest.php b/tests/phpunit/includes/logging/LogFormatterTest.php deleted file mode 100644 index e8ccf433..00000000 --- a/tests/phpunit/includes/logging/LogFormatterTest.php +++ /dev/null @@ -1,207 +0,0 @@ -<?php -/** - * @group Database - */ -class LogFormatterTest extends MediaWikiLangTestCase { - - /** - * @var User - */ - protected $user; - - /** - * @var Title - */ - protected $title; - - /** - * @var RequestContext - */ - protected $context; - - protected function setUp() { - parent::setUp(); - - global $wgLang; - - $this->setMwGlobals( array( - 'wgLogTypes' => array( 'phpunit' ), - 'wgLogActionsHandlers' => array( 'phpunit/test' => 'LogFormatter', - 'phpunit/param' => 'LogFormatter' ), - 'wgUser' => User::newFromName( 'Testuser' ), - 'wgExtensionMessagesFiles' => array( 'LogTests' => __DIR__ . '/LogTests.i18n.php' ), - ) ); - - $wgLang->getLocalisationCache()->recache( $wgLang->getCode() ); - - $this->user = User::newFromName( 'Testuser' ); - $this->title = Title::newMainPage(); - - $this->context = new RequestContext(); - $this->context->setUser( $this->user ); - $this->context->setTitle( $this->title ); - $this->context->setLanguage( $wgLang ); - } - - protected function tearDown() { - parent::tearDown(); - - global $wgLang; - $wgLang->getLocalisationCache()->recache( $wgLang->getCode() ); - } - - public function newLogEntry( $action, $params ) { - $logEntry = new ManualLogEntry( 'phpunit', $action ); - $logEntry->setPerformer( $this->user ); - $logEntry->setTarget( $this->title ); - $logEntry->setComment( 'A very good reason' ); - - $logEntry->setParameters( $params ); - - return $logEntry; - } - - public function testNormalLogParams() { - $entry = $this->newLogEntry( 'test', array() ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $formatter->setShowUserToolLinks( false ); - $paramsWithoutTools = $formatter->getMessageParametersForTesting(); - unset( $formatter->parsedParameters ); - - $formatter->setShowUserToolLinks( true ); - $paramsWithTools = $formatter->getMessageParametersForTesting(); - - $userLink = Linker::userLink( - $this->user->getId(), - $this->user->getName() - ); - - $userTools = Linker::userToolLinksRedContribs( - $this->user->getId(), - $this->user->getName(), - $this->user->getEditCount() - ); - - $titleLink = Linker::link( $this->title, null, array(), array() ); - - // $paramsWithoutTools and $paramsWithTools should be only different - // in index 0 - $this->assertEquals( $paramsWithoutTools[1], $paramsWithTools[1] ); - $this->assertEquals( $paramsWithoutTools[2], $paramsWithTools[2] ); - - $this->assertEquals( $userLink, $paramsWithoutTools[0]['raw'] ); - $this->assertEquals( $userLink . $userTools, $paramsWithTools[0]['raw'] ); - - $this->assertEquals( $this->user->getName(), $paramsWithoutTools[1] ); - - $this->assertEquals( $titleLink, $paramsWithoutTools[2]['raw'] ); - } - - public function testLogParamsTypeRaw() { - $params = array( '4:raw:raw' => Linker::link( $this->title, null, array(), array() ) ); - $expected = Linker::link( $this->title, null, array(), array() ); - - $entry = $this->newLogEntry( 'param', $params ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $logParam = $formatter->getActionText(); - - $this->assertEquals( $expected, $logParam ); - } - - public function testLogParamsTypeMsg() { - $params = array( '4:msg:msg' => 'log-description-phpunit' ); - $expected = wfMessage( 'log-description-phpunit' )->text(); - - $entry = $this->newLogEntry( 'param', $params ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $logParam = $formatter->getActionText(); - - $this->assertEquals( $expected, $logParam ); - } - - public function testLogParamsTypeMsgContent() { - $params = array( '4:msg-content:msgContent' => 'log-description-phpunit' ); - $expected = wfMessage( 'log-description-phpunit' )->inContentLanguage()->text(); - - $entry = $this->newLogEntry( 'param', $params ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $logParam = $formatter->getActionText(); - - $this->assertEquals( $expected, $logParam ); - } - - public function testLogParamsTypeNumber() { - global $wgLang; - - $params = array( '4:number:number' => 123456789 ); - $expected = $wgLang->formatNum( 123456789 ); - - $entry = $this->newLogEntry( 'param', $params ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $logParam = $formatter->getActionText(); - - $this->assertEquals( $expected, $logParam ); - } - - public function testLogParamsTypeUserLink() { - $params = array( '4:user-link:userLink' => $this->user->getName() ); - $expected = Linker::userLink( - $this->user->getId(), - $this->user->getName() - ); - - $entry = $this->newLogEntry( 'param', $params ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $logParam = $formatter->getActionText(); - - $this->assertEquals( $expected, $logParam ); - } - - public function testLogParamsTypeTitleLink() { - $params = array( '4:title-link:titleLink' => $this->title->getText() ); - $expected = Linker::link( $this->title, null, array(), array() ); - - $entry = $this->newLogEntry( 'param', $params ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $logParam = $formatter->getActionText(); - - $this->assertEquals( $expected, $logParam ); - } - - public function testLogParamsTypePlain() { - $params = array( '4:plain:plain' => 'Some plain text' ); - $expected = 'Some plain text'; - - $entry = $this->newLogEntry( 'param', $params ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $logParam = $formatter->getActionText(); - - $this->assertEquals( $expected, $logParam ); - } - - public function testLogComment() { - $entry = $this->newLogEntry( 'test', array() ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $comment = ltrim( Linker::commentBlock( $entry->getComment() ) ); - - $this->assertEquals( $comment, $formatter->getComment() ); - } -} diff --git a/tests/phpunit/includes/logging/LogTests.i18n.php b/tests/phpunit/includes/logging/LogTests.i18n.php deleted file mode 100644 index 78787ba1..00000000 --- a/tests/phpunit/includes/logging/LogTests.i18n.php +++ /dev/null @@ -1,15 +0,0 @@ -<?php -/** - * Internationalisation file for log tests. - * - * @file - */ - -$messages = array(); - -$messages['en'] = array( - 'log-name-phpunit' => 'PHPUnit-log', - 'log-description-phpunit' => 'Log for PHPUnit-tests', - 'logentry-phpunit-test' => '$1 {{GENDER:$2|tests}} with page $3', - 'logentry-phpunit-param' => '$4', -); diff --git a/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php b/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php deleted file mode 100644 index a0e63a8a..00000000 --- a/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php +++ /dev/null @@ -1,167 +0,0 @@ -<?php -class BitmapMetadataHandlerTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( 'wgShowEXIF', false ); - - $this->filePath = __DIR__ . '/../../data/media/'; - } - - /** - * Test if having conflicting metadata values from different - * types of metadata, that the right one takes precedence. - * - * 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() { - if ( !extension_loaded( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } - if ( !extension_loaded( 'xml' ) ) { - $this->markTestSkipped( "This test needs the xml extension." ); - } - - $this->setMwGlobals( 'wgShowEXIF', true ); - - $meta = BitmapMetadataHandler::Jpeg( $this->filePath . - '/Xmp-exif-multilingual_test.jpg' ); - - $expected = array( - 'x-default' => 'right(iptc)', - 'en' => 'right translation', - '_type' => 'lang' - ); - - $this->assertArrayHasKey( 'ImageDescription', $meta, - 'Did not extract any ImageDescription info?!' ); - - $this->assertEquals( $expected, $meta['ImageDescription'] ); - } - - /** - * Test for jpeg comments are being handled by - * BitmapMetadataHandler correctly. - * - * There's more extensive tests of comment extraction in - * JpegMetadataExtractorTests.php - * @covers BitmapMetadataHandler::Jpeg - */ - public function testJpegComment() { - $meta = BitmapMetadataHandler::Jpeg( $this->filePath . - 'jpeg-comment-utf.jpg' ); - - $this->assertEquals( 'UTF-8 JPEG Comment — ¼', - $meta['JPEGFileComment'][0] ); - } - - /** - * 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 . - 'iptc-invalid-psir.jpg' ); - $this->assertEquals( 'Created with GIMP', $meta['JPEGFileComment'][0] ); - } - - /** - * @covers BitmapMetadataHandler::Jpeg - */ - public function testIPTCDates() { - $meta = BitmapMetadataHandler::Jpeg( $this->filePath . - 'iptc-timetest.jpg' ); - - $this->assertEquals( '2020:07:14 01:36:05', $meta['DateTimeDigitized'] ); - $this->assertEquals( '1997:03:02 00:01:02', $meta['DateTimeOriginal'] ); - } - - /** - * 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 . - 'iptc-timetest-invalid.jpg' ); - - $this->assertEquals( '1845:03:02 00:01:02', $meta['DateTimeOriginal'] ); - $this->assertFalse( isset( $meta['DateTimeDigitized'] ) ); - } - - /** - * 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(); - $merger->addMetadata( array( 'foo' => 'xmp' ), 'xmp-general' ); - $merger->addMetadata( array( 'bar' => 'xmp' ), 'xmp-general' ); - $merger->addMetadata( array( 'baz' => 'xmp' ), 'xmp-general' ); - $merger->addMetadata( array( 'fred' => 'xmp' ), 'xmp-general' ); - $merger->addMetadata( array( 'foo' => 'iptc (hash)' ), 'iptc-good-hash' ); - $merger->addMetadata( array( 'bar' => 'iptc (bad hash)' ), 'iptc-bad-hash' ); - $merger->addMetadata( array( 'baz' => 'iptc (bad hash)' ), 'iptc-bad-hash' ); - $merger->addMetadata( array( 'fred' => 'iptc (no hash)' ), 'iptc-no-hash' ); - $merger->addMetadata( array( 'baz' => 'exif' ), 'exif' ); - - $actual = $merger->getMetadataArray(); - $expected = array( - 'foo' => 'xmp', - 'bar' => 'iptc (bad hash)', - 'baz' => 'exif', - 'fred' => 'xmp', - ); - $this->assertEquals( $expected, $actual ); - } - - /** - * @covers BitmapMetadataHandler::png - */ - public function testPNGXMP() { - if ( !extension_loaded( 'xml' ) ) { - $this->markTestSkipped( "This test needs the xml extension." ); - } - $handler = new BitmapMetadataHandler(); - $result = $handler->png( $this->filePath . 'xmp.png' ); - $expected = array( - 'frameCount' => 0, - 'loopCount' => 1, - 'duration' => 0, - 'bitDepth' => 1, - 'colorType' => 'index-coloured', - 'metadata' => array( - 'SerialNumber' => '123456789', - '_MW_PNG_VERSION' => 1, - ), - ); - $this->assertEquals( $expected, $result ); - } - - /** - * @covers BitmapMetadataHandler::png - */ - public function testPNGNative() { - $handler = new BitmapMetadataHandler(); - $result = $handler->png( $this->filePath . 'Png-native-test.png' ); - $expected = 'http://example.com/url'; - $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 deleted file mode 100644 index 9395b660..00000000 --- a/tests/phpunit/includes/media/BitmapScalingTest.php +++ /dev/null @@ -1,137 +0,0 @@ -<?php - -class BitmapScalingTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgMaxImageArea' => 1.25e7, // 3500x3500 - 'wgCustomConvertCommand' => 'dummy', // Set so that we don't get client side rendering - ) ); - } - - /** - * @dataProvider provideNormaliseParams - * @covers BitmapHandler::normaliseParams - */ - public function testNormaliseParams( $fileDimensions, $expectedParams, $params, $msg ) { - $file = new FakeDimensionFile( $fileDimensions ); - $handler = new BitmapHandler; - $valid = $handler->normaliseParams( $file, $params ); - $this->assertTrue( $valid ); - $this->assertEquals( $expectedParams, $params, $msg ); - } - - public static function provideNormaliseParams() { - return array( - /* Regular resize operations */ - array( - array( 1024, 768 ), - array( - 'width' => 512, 'height' => 384, - 'physicalWidth' => 512, 'physicalHeight' => 384, - 'page' => 1, - ), - array( 'width' => 512 ), - 'Resizing with width set', - ), - array( - array( 1024, 768 ), - array( - 'width' => 512, 'height' => 384, - 'physicalWidth' => 512, 'physicalHeight' => 384, - 'page' => 1, - ), - array( 'width' => 512, 'height' => 768 ), - 'Resizing with height set too high', - ), - array( - array( 1024, 768 ), - array( - 'width' => 512, 'height' => 384, - 'physicalWidth' => 512, 'physicalHeight' => 384, - 'page' => 1, - ), - array( 'width' => 1024, 'height' => 384 ), - 'Resizing with height set', - ), - - /* Very tall images */ - array( - array( 1000, 100 ), - array( - 'width' => 5, 'height' => 1, - 'physicalWidth' => 5, 'physicalHeight' => 1, - 'page' => 1, - ), - array( 'width' => 5 ), - 'Very wide image', - ), - - array( - array( 100, 1000 ), - array( - 'width' => 1, 'height' => 10, - 'physicalWidth' => 1, 'physicalHeight' => 10, - 'page' => 1, - ), - array( 'width' => 1 ), - 'Very high image', - ), - array( - array( 100, 1000 ), - array( - 'width' => 1, 'height' => 5, - 'physicalWidth' => 1, 'physicalHeight' => 10, - 'page' => 1, - ), - array( 'width' => 10, 'height' => 5 ), - 'Very high image with height set', - ), - /* Max image area */ - array( - array( 4000, 4000 ), - array( - 'width' => 5000, 'height' => 5000, - 'physicalWidth' => 4000, 'physicalHeight' => 4000, - 'page' => 1, - ), - array( 'width' => 5000 ), - 'Bigger than max image size but doesn\'t need scaling', - ), - ); - } - - /** - * @covers BitmapHandler::doTransform - */ - public function testTooBigImage() { - $file = new FakeDimensionFile( array( 4000, 4000 ) ); - $handler = new BitmapHandler; - $params = array( 'width' => '3700' ); // Still bigger than max size. - $this->assertEquals( 'TransformParameterError', - get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) ); - } - - /** - * @covers BitmapHandler::doTransform - */ - public function testTooBigMustRenderImage() { - $file = new FakeDimensionFile( array( 4000, 4000 ) ); - $file->mustRender = true; - $handler = new BitmapHandler; - $params = array( 'width' => '5000' ); // Still bigger than max size. - $this->assertEquals( 'TransformParameterError', - get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) ); - } - - /** - * @covers BitmapHandler::getImageArea - */ - public function testImageArea() { - $file = new FakeDimensionFile( array( 7, 9 ) ); - $handler = new BitmapHandler; - $this->assertEquals( 63, $handler->getImageArea( $file ) ); - } -} diff --git a/tests/phpunit/includes/media/ExifBitmapTest.php b/tests/phpunit/includes/media/ExifBitmapTest.php deleted file mode 100644 index a2e0eb62..00000000 --- a/tests/phpunit/includes/media/ExifBitmapTest.php +++ /dev/null @@ -1,139 +0,0 @@ -<?php - -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; - - } - - /** - * @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. - * @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 ); - } - - /** - * @covers ExifBitmapHandler::convertMetadataVersion - */ - public function testConvertMetadataLatest() { - $metadata = array( - 'foo' => array( 'First', 'Second', '_type' => 'ol' ), - 'MEDIAWIKI_EXIF_VERSION' => 2 - ); - $res = $this->handler->convertMetadataVersion( $metadata, 2 ); - $this->assertEquals( $metadata, $res ); - } - - /** - * @covers ExifBitmapHandler::convertMetadataVersion - */ - public function testConvertMetadataToOld() { - $metadata = array( - 'foo' => array( 'First', 'Second', '_type' => 'ol' ), - 'bar' => array( 'First', 'Second', '_type' => 'ul' ), - 'baz' => array( 'First', 'Second' ), - 'fred' => 'Single', - 'MEDIAWIKI_EXIF_VERSION' => 2, - ); - $expected = array( - 'foo' => "\n#First\n#Second", - 'bar' => "\n*First\n*Second", - 'baz' => "\n*First\n*Second", - 'fred' => 'Single', - 'MEDIAWIKI_EXIF_VERSION' => 1, - ); - $res = $this->handler->convertMetadataVersion( $metadata, 1 ); - $this->assertEquals( $expected, $res ); - } - - /** - * @covers ExifBitmapHandler::convertMetadataVersion - */ - public function testConvertMetadataSoftware() { - $metadata = array( - 'Software' => array( array( 'GIMP', '1.1' ) ), - 'MEDIAWIKI_EXIF_VERSION' => 2, - ); - $expected = array( - 'Software' => 'GIMP (Version 1.1)', - 'MEDIAWIKI_EXIF_VERSION' => 1, - ); - $res = $this->handler->convertMetadataVersion( $metadata, 1 ); - $this->assertEquals( $expected, $res ); - } - - /** - * @covers ExifBitmapHandler::convertMetadataVersion - */ - public function testConvertMetadataSoftwareNormal() { - $metadata = array( - 'Software' => array( "GIMP 1.2", "vim" ), - 'MEDIAWIKI_EXIF_VERSION' => 2, - ); - $expected = array( - 'Software' => "\n*GIMP 1.2\n*vim", - 'MEDIAWIKI_EXIF_VERSION' => 1, - ); - $res = $this->handler->convertMetadataVersion( $metadata, 1 ); - $this->assertEquals( $expected, $res ); - } -} diff --git a/tests/phpunit/includes/media/ExifRotationTest.php b/tests/phpunit/includes/media/ExifRotationTest.php deleted file mode 100644 index 64276d92..00000000 --- a/tests/phpunit/includes/media/ExifRotationTest.php +++ /dev/null @@ -1,248 +0,0 @@ -<?php -/** - * 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'; - - $tmpDir = $this->getNewTempDirectory(); - - $this->repo = new FSRepo( array( - 'name' => 'temp', - 'url' => 'http://localhost/thumbtest', - 'backend' => new FSFileBackend( array( - 'name' => 'localtesting', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( 'temp-thumb' => $tmpDir, 'data' => $filePath ) - ) ) - ) ); - - $this->setMwGlobals( array( - 'wgShowEXIF' => true, - 'wgEnableAutoRotation' => true, - ) ); - } - - /** - * @dataProvider provideFiles - */ - public function testMetadata( $name, $type, $info ) { - if ( !BitmapHandler::canRotate() ) { - $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." ); - } - $file = $this->dataFile( $name, $type ); - $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" ); - $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" ); - } - - /** - * - * @dataProvider provideFiles - */ - public function testRotationRendering( $name, $type, $info, $thumbs ) { - if ( !BitmapHandler::canRotate() ) { - $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." ); - } - foreach ( $thumbs as $size => $out ) { - if ( preg_match( '/^(\d+)px$/', $size, $matches ) ) { - $params = array( - 'width' => $matches[1], - ); - } elseif ( preg_match( '/^(\d+)x(\d+)px$/', $size, $matches ) ) { - $params = array( - 'width' => $matches[1], - 'height' => $matches[2] - ); - } else { - throw new MWException( 'bogus test data format ' . $size ); - } - - $file = $this->dataFile( $name, $type ); - $thumb = $file->transform( $params, File::RENDER_NOW | File::RENDER_FORCE ); - - $this->assertEquals( $out[0], $thumb->getWidth(), "$name: thumb reported width check for $size" ); - $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" ); - - $gis = getimagesize( $thumb->getLocalCopyPath() ); - if ( $out[0] > $info['width'] ) { - // Physical image won't be scaled bigger than the original. - $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size" ); - $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size" ); - } else { - $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size" ); - $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size" ); - } - } - } - - /* Utility function */ - private function dataFile( $name, $type ) { - return new UnregisteredLocalFile( false, $this->repo, - "mwstore://localtesting/data/$name", $type ); - } - - public static function provideFiles() { - return array( - array( - 'landscape-plain.jpg', - 'image/jpeg', - array( - 'width' => 1024, - 'height' => 768, - ), - array( - '800x600px' => array( 800, 600 ), - '9999x800px' => array( 1067, 800 ), - '800px' => array( 800, 600 ), - '600px' => array( 600, 450 ), - ) - ), - array( - 'portrait-rotated.jpg', - 'image/jpeg', - array( - 'width' => 768, // as rotated - 'height' => 1024, // as rotated - ), - array( - '800x600px' => array( 450, 600 ), - '9999x800px' => array( 600, 800 ), - '800px' => array( 800, 1067 ), - '600px' => array( 600, 800 ), - ) - ) - ); - } - - /** - * Same as before, but with auto-rotation disabled. - * @dataProvider provideFilesNoAutoRotate - */ - 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" ); - } - - /** - * - * @dataProvider provideFilesNoAutoRotate - */ - public function testRotationRenderingNoAutoRotate( $name, $type, $info, $thumbs ) { - $this->setMwGlobals( 'wgEnableAutoRotation', false ); - - foreach ( $thumbs as $size => $out ) { - if ( preg_match( '/^(\d+)px$/', $size, $matches ) ) { - $params = array( - 'width' => $matches[1], - ); - } elseif ( preg_match( '/^(\d+)x(\d+)px$/', $size, $matches ) ) { - $params = array( - 'width' => $matches[1], - 'height' => $matches[2] - ); - } else { - throw new MWException( 'bogus test data format ' . $size ); - } - - $file = $this->dataFile( $name, $type ); - $thumb = $file->transform( $params, File::RENDER_NOW | File::RENDER_FORCE ); - - $this->assertEquals( $out[0], $thumb->getWidth(), "$name: thumb reported width check for $size" ); - $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" ); - - $gis = getimagesize( $thumb->getLocalCopyPath() ); - if ( $out[0] > $info['width'] ) { - // Physical image won't be scaled bigger than the original. - $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size" ); - $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size" ); - } else { - $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size" ); - $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size" ); - } - } - } - - public static function provideFilesNoAutoRotate() { - return array( - array( - 'landscape-plain.jpg', - 'image/jpeg', - array( - 'width' => 1024, - 'height' => 768, - ), - array( - '800x600px' => array( 800, 600 ), - '9999x800px' => array( 1067, 800 ), - '800px' => array( 800, 600 ), - '600px' => array( 600, 450 ), - ) - ), - array( - 'portrait-rotated.jpg', - 'image/jpeg', - array( - 'width' => 1024, // since not rotated - 'height' => 768, // since not rotated - ), - array( - '800x600px' => array( 800, 600 ), - '9999x800px' => array( 1067, 800 ), - '800px' => array( 800, 600 ), - '600px' => array( 600, 450 ), - ) - ) - ); - } - - - const TEST_WIDTH = 100; - const TEST_HEIGHT = 200; - - /** - * @dataProvider provideBitmapExtractPreRotationDimensions - */ - public function testBitmapExtractPreRotationDimensions( $rotation, $expected ) { - $result = $this->handler->extractPreRotationDimensions( array( - 'physicalWidth' => self::TEST_WIDTH, - 'physicalHeight' => self::TEST_HEIGHT, - ), $rotation ); - $this->assertEquals( $expected, $result ); - } - - public static function provideBitmapExtractPreRotationDimensions() { - return array( - array( - 0, - array( self::TEST_WIDTH, self::TEST_HEIGHT ) - ), - array( - 90, - array( self::TEST_HEIGHT, self::TEST_WIDTH ) - ), - array( - 180, - array( self::TEST_WIDTH, self::TEST_HEIGHT ) - ), - array( - 270, - array( self::TEST_HEIGHT, self::TEST_WIDTH ) - ), - ); - } -} diff --git a/tests/phpunit/includes/media/ExifTest.php b/tests/phpunit/includes/media/ExifTest.php deleted file mode 100644 index dea36b03..00000000 --- a/tests/phpunit/includes/media/ExifTest.php +++ /dev/null @@ -1,46 +0,0 @@ -<?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/'; - - - - $this->setMwGlobals( 'wgShowEXIF', true ); - } - - public function testGPSExtraction() { - $filename = $this->mediaPath . 'exif-gps.jpg'; - $seg = JpegMetadataExtractor::segmentSplitter( $filename ); - $exif = new Exif( $filename, $seg['byteOrder'] ); - $data = $exif->getFilteredData(); - $expected = array( - 'GPSLatitude' => 88.5180555556, - 'GPSLongitude' => -21.12357, - 'GPSAltitude' => -3.141592653, - 'GPSDOP' => '5/1', - 'GPSVersionID' => '2.2.0.0', - ); - $this->assertEquals( $expected, $data, '', 0.0000000001 ); - } - - public function testUnicodeUserComment() { - $filename = $this->mediaPath . 'exif-user-comment.jpg'; - $seg = JpegMetadataExtractor::segmentSplitter( $filename ); - $exif = new Exif( $filename, $seg['byteOrder'] ); - $data = $exif->getFilteredData(); - - $expected = array( - 'UserComment' => 'test⁔comment' - ); - $this->assertEquals( $expected, $data ); - } -} diff --git a/tests/phpunit/includes/media/FakeDimensionFile.php b/tests/phpunit/includes/media/FakeDimensionFile.php deleted file mode 100644 index 7926000b..00000000 --- a/tests/phpunit/includes/media/FakeDimensionFile.php +++ /dev/null @@ -1,28 +0,0 @@ -<?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 deleted file mode 100644 index a073e4ca..00000000 --- a/tests/phpunit/includes/media/FormatMetadataTest.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php - -/** - * @todo covers tags - */ -class FormatMetadataTest extends MediaWikiTestCase { - - /** @var FSFileBackend */ - protected $backend; - /** @var FSRepo */ - protected $repo; - - protected function setUp() { - parent::setUp(); - - if ( !extension_loaded( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } - $filePath = __DIR__ . '/../../data/media'; - $this->backend = new FSFileBackend( array( - 'name' => 'localtesting', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( 'data' => $filePath ) - ) ); - $this->repo = new FSRepo( array( - 'name' => 'temp', - 'url' => 'http://localhost/thumbtest', - 'backend' => $this->backend - ) ); - - $this->setMwGlobals( 'wgShowEXIF', true ); - } - - public function testInvalidDate() { - $file = $this->dataFile( 'broken_exif_date.jpg', 'image/jpeg' ); - - // Throws an error if bug hit - $meta = $file->formatMetadata(); - $this->assertNotEquals( false, $meta, 'Valid metadata extracted' ); - - // Find date exif entry - $this->assertArrayHasKey( 'visible', $meta ); - $dateIndex = null; - foreach ( $meta['visible'] as $i => $data ) { - if ( $data['id'] == 'exif-datetimeoriginal' ) { - $dateIndex = $i; - } - } - $this->assertNotNull( $dateIndex, 'Date entry exists in metadata' ); - $this->assertEquals( '0000:01:00 00:02:27', - $meta['visible'][$dateIndex]['value'], - 'File with invalid date metadata (bug 29471)' ); - } - - private function dataFile( $name, $type ) { - return new UnregisteredLocalFile( false, $this->repo, - "mwstore://localtesting/data/$name", $type ); - } -} diff --git a/tests/phpunit/includes/media/GIFMetadataExtractorTest.php b/tests/phpunit/includes/media/GIFMetadataExtractorTest.php deleted file mode 100644 index 9e3f9244..00000000 --- a/tests/phpunit/includes/media/GIFMetadataExtractorTest.php +++ /dev/null @@ -1,107 +0,0 @@ -<?php -class GIFMetadataExtractorTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - $this->mediaPath = __DIR__ . '/../../data/media/'; - } - - /** - * Put in a file, and see if the metadata coming out is as expected. - * @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 ); - $this->assertEquals( $expected, $actual ); - } - - public static function provideGetMetadata() { - - $xmpNugget = <<<EOF -<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?> -<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 7.30'> -<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'> - - <rdf:Description rdf:about='' - xmlns:Iptc4xmpCore='http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/'> - <Iptc4xmpCore:Location>The interwebs</Iptc4xmpCore:Location> - </rdf:Description> - - <rdf:Description rdf:about='' - xmlns:tiff='http://ns.adobe.com/tiff/1.0/'> - <tiff:Artist>Bawolff</tiff:Artist> - <tiff:ImageDescription> - <rdf:Alt> - <rdf:li xml:lang='x-default'>A file to test GIF</rdf:li> - </rdf:Alt> - </tiff:ImageDescription> - </rdf:Description> -</rdf:RDF> -</x:xmpmeta> - - - - - - - - - - - - - - - - - - - - - - - - -<?xpacket end='w'?> -EOF; - $xmpNugget = str_replace( "\r", '', $xmpNugget ); // Windows compat - - return array( - array( - 'nonanimated.gif', - array( - 'comment' => array( 'GIF test file ⁕ Created with GIMP' ), - 'duration' => 0.1, - 'frameCount' => 1, - 'looped' => false, - 'xmp' => '', - ) - ), - array( - 'animated.gif', - array( - 'comment' => array( 'GIF test file . Created with GIMP' ), - 'duration' => 2.4, - 'frameCount' => 4, - 'looped' => true, - 'xmp' => '', - ) - ), - - array( - 'animated-xmp.gif', - array( - 'xmp' => $xmpNugget, - 'duration' => 2.4, - 'frameCount' => 4, - 'looped' => true, - 'comment' => array( 'GIƒ·test·file' ), - ) - ), - ); - } -} diff --git a/tests/phpunit/includes/media/GIFTest.php b/tests/phpunit/includes/media/GIFTest.php deleted file mode 100644 index c8e729c8..00000000 --- a/tests/phpunit/includes/media/GIFTest.php +++ /dev/null @@ -1,120 +0,0 @@ -<?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(); - - $this->filePath = __DIR__ . '/../../data/media'; - $this->backend = new FSFileBackend( array( - 'name' => 'localtesting', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( 'data' => $this->filePath ) - ) ); - $this->repo = new FSRepo( array( - 'name' => 'temp', - 'url' => 'http://localhost/thumbtest', - 'backend' => $this->backend - ) ); - $this->handler = new GIFHandler(); - } - - /** - * @covers GIFHandler::getMetadata - */ - public function testInvalidFile() { - $res = $this->handler->getMetadata( null, $this->filePath . '/README' ); - $this->assertEquals( GIFHandler::BROKEN_FILE, $res ); - } - - /** - * @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' ); - $actual = $this->handler->isAnimatedImage( $file ); - $this->assertEquals( $expected, $actual ); - } - - public static function provideIsAnimated() { - return array( - array( 'animated.gif', true ), - array( 'nonanimated.gif', false ), - ); - } - - /** - * @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' ); - $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() ); - $this->assertEquals( $expected, $actual ); - } - - public static function provideGetImageArea() { - return array( - array( 'animated.gif', 5400 ), - array( 'nonanimated.gif', 1350 ), - ); - } - - /** - * @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 ); - $this->assertEquals( $expected, $actual ); - } - - public static function provideIsMetadataValid() { - return array( - array( GIFHandler::BROKEN_FILE, GIFHandler::METADATA_GOOD ), - array( '', GIFHandler::METADATA_BAD ), - array( null, GIFHandler::METADATA_BAD ), - array( 'Something invalid!', GIFHandler::METADATA_BAD ), - array( 'a:4:{s:10:"frameCount";i:1;s:6:"looped";b:0;s:8:"duration";d:0.1000000000000000055511151231257827021181583404541015625;s:8:"metadata";a:2:{s:14:"GIFFileComment";a:1:{i:0;s:35:"GIF test file ⁕ Created with GIMP";}s:15:"_MW_GIF_VERSION";i:1;}}', GIFHandler::METADATA_GOOD ), - ); - } - - /** - * @param $filename String - * @param $expected String Serialized array - * @dataProvider provideGetMetadata - * @covers GIFHandler::getMetadata - */ - public function testGetMetadata( $filename, $expected ) { - $file = $this->dataFile( $filename, 'image/gif' ); - $actual = $this->handler->getMetadata( $file, "$this->filePath/$filename" ); - $this->assertEquals( unserialize( $expected ), unserialize( $actual ) ); - } - - public static function provideGetMetadata() { - return array( - array( 'nonanimated.gif', 'a:4:{s:10:"frameCount";i:1;s:6:"looped";b:0;s:8:"duration";d:0.1000000000000000055511151231257827021181583404541015625;s:8:"metadata";a:2:{s:14:"GIFFileComment";a:1:{i:0;s:35:"GIF test file ⁕ Created with GIMP";}s:15:"_MW_GIF_VERSION";i:1;}}' ), - array( 'animated-xmp.gif', 'a:4:{s:10:"frameCount";i:4;s:6:"looped";b:1;s:8:"duration";d:2.399999999999999911182158029987476766109466552734375;s:8:"metadata";a:5:{s:6:"Artist";s:7:"Bawolff";s:16:"ImageDescription";a:2:{s:9:"x-default";s:18:"A file to test GIF";s:5:"_type";s:4:"lang";}s:15:"SublocationDest";s:13:"The interwebs";s:14:"GIFFileComment";a:1:{i:0;s:16:"GIƒ·test·file";}s:15:"_MW_GIF_VERSION";i:1;}}' ), - ); - } - - private function dataFile( $name, $type ) { - return new UnregisteredLocalFile( false, $this->repo, - "mwstore://localtesting/data/$name", $type ); - } -} diff --git a/tests/phpunit/includes/media/IPTCTest.php b/tests/phpunit/includes/media/IPTCTest.php deleted file mode 100644 index 81c1d287..00000000 --- a/tests/phpunit/includes/media/IPTCTest.php +++ /dev/null @@ -1,81 +0,0 @@ -<?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 - // (which basically means utf-8 if valid, windows 1252 (iso 8859-1) if not) - $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x06\x1c\x02\x19\x00\x01\xBC"; - $res = IPTC::Parse( $iptcData ); - $this->assertEquals( array( '¼' ), $res['Keywords'] ); - } - - /** - * @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. - * 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" - . "\x1c\x01\x5A\x00\x03\x1B\x25\x47"; - $res = IPTC::Parse( $iptcData ); - $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 - * @covers IPTC::Parse - */ - public function testIPTCParseMulti() { - $iptcData = /* identifier */ "Photoshop 3.0\08BIM\4\4" - /* length */ . "\0\0\0\0\0\x0D" - . "\x1c\x02\x19" . "\x00\x01" . "\xBC" - . "\x1c\x02\x19" . "\x00\x02" . "\xBC\xBD"; - $res = IPTC::Parse( $iptcData ); - $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 deleted file mode 100644 index eafc8a2e..00000000 --- a/tests/phpunit/includes/media/JpegMetadataExtractorTest.php +++ /dev/null @@ -1,109 +0,0 @@ -<?php -/** - * @todo Could use a test of extended XMP segments. Hard to find programs that - * create example files, and creating my own in vim propbably wouldn't - * 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(); - - $this->filePath = __DIR__ . '/../../data/media/'; - } - - /** - * We also use this test to test padding bytes don't - * screw stuff up - * - * @param string $file filename - * - * @dataProvider provideUtf8Comment - */ - public function testUtf8Comment( $file ) { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . $file ); - $this->assertEquals( array( 'UTF-8 JPEG Comment — ¼' ), $res['COM'] ); - } - - public static function provideUtf8Comment() { - return array( - array( 'jpeg-comment-utf.jpg' ), - array( 'jpeg-padding-even.jpg' ), - array( 'jpeg-padding-odd.jpg' ), - ); - } - - /** The file is iso-8859-1, but it should get auto converted */ - public function testIso88591Comment() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-iso8859-1.jpg' ); - $this->assertEquals( array( 'ISO-8859-1 JPEG Comment - ¼' ), $res['COM'] ); - } - - /** Comment values that are non-textual (random binary junk) should not be shown. - * The example test file has a comment with a 0x5 byte in it which is a control character - * and considered binary junk for our purposes. - */ - public function testBinaryCommentStripped() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-binary.jpg' ); - $this->assertEmpty( $res['COM'] ); - } - - /* Very rarely a file can have multiple comments. - * Order of comments is based on order inside the file. - */ - public function testMultipleComment() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-multiple.jpg' ); - $this->assertEquals( array( 'foo', 'bar' ), $res['COM'] ); - } - - public function testXMPExtraction() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-psir.jpg' ); - $expected = file_get_contents( $this->filePath . 'jpeg-xmp-psir.xmp' ); - $this->assertEquals( $expected, $res['XMP'] ); - } - - public function testPSIRExtraction() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-psir.jpg' ); - $expected = '50686f746f73686f7020332e30003842494d04040000000000181c02190004746573741c02190003666f6f1c020000020004'; - $this->assertEquals( $expected, bin2hex( $res['PSIR'][0] ) ); - } - - public function testXMPExtractionAltAppId() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-alt.jpg' ); - $expected = file_get_contents( $this->filePath . 'jpeg-xmp-psir.xmp' ); - $this->assertEquals( $expected, $res['XMP'] ); - } - - - public function testIPTCHashComparisionNoHash() { - $segments = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-psir.jpg' ); - $res = JpegMetadataExtractor::doPSIR( $segments['PSIR'][0] ); - - $this->assertEquals( 'iptc-no-hash', $res ); - } - - public function testIPTCHashComparisionBadHash() { - $segments = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-iptc-bad-hash.jpg' ); - $res = JpegMetadataExtractor::doPSIR( $segments['PSIR'][0] ); - - $this->assertEquals( 'iptc-bad-hash', $res ); - } - - public function testIPTCHashComparisionGoodHash() { - $segments = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-iptc-good-hash.jpg' ); - $res = JpegMetadataExtractor::doPSIR( $segments['PSIR'][0] ); - - $this->assertEquals( 'iptc-good-hash', $res ); - } - - public function testExifByteOrder() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'exif-user-comment.jpg' ); - $expected = 'BE'; - $this->assertEquals( $expected, $res['byteOrder'] ); - } -} diff --git a/tests/phpunit/includes/media/JpegTest.php b/tests/phpunit/includes/media/JpegTest.php deleted file mode 100644 index 9af4f1e1..00000000 --- a/tests/phpunit/includes/media/JpegTest.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * @todo covers tags - */ -class JpegTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - if ( !extension_loaded( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } - - $this->filePath = __DIR__ . '/../../data/media/'; - - - $this->setMwGlobals( 'wgShowEXIF', true ); - } - - public function testInvalidFile() { - $jpeg = new JpegHandler; - $res = $jpeg->getMetadata( null, $this->filePath . 'README' ); - $this->assertEquals( ExifBitmapHandler::BROKEN_FILE, $res ); - } - - public function testJpegMetadataExtraction() { - $h = new JpegHandler; - $res = $h->getMetadata( null, $this->filePath . 'test.jpg' ); - $expected = 'a:7:{s:16:"ImageDescription";s:9:"Test file";s:11:"XResolution";s:4:"72/1";s:11:"YResolution";s:4:"72/1";s:14:"ResolutionUnit";i:2;s:16:"YCbCrPositioning";i:1;s:15:"JPEGFileComment";a:1:{i:0;s:17:"Created with GIMP";}s:22:"MEDIAWIKI_EXIF_VERSION";i:2;}'; - - // Unserialize in case serialization format ever changes. - $this->assertEquals( unserialize( $expected ), unserialize( $res ) ); - } -} diff --git a/tests/phpunit/includes/media/MediaHandlerTest.php b/tests/phpunit/includes/media/MediaHandlerTest.php deleted file mode 100644 index c28898bb..00000000 --- a/tests/phpunit/includes/media/MediaHandlerTest.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php - -class MediaHandlerTest extends MediaWikiTestCase { - - /** - * @covers MediaHandler::fitBoxWidth - * @todo split into a dataprovider and test method - */ - public function testFitBoxWidth() { - $vals = array( - array( - 'width' => 50, - 'height' => 50, - 'tests' => array( - 50 => 50, - 17 => 17, - 18 => 18 ) ), - array( - 'width' => 366, - 'height' => 300, - 'tests' => array( - 50 => 61, - 17 => 21, - 18 => 22 ) ), - array( - 'width' => 300, - 'height' => 366, - 'tests' => array( - 50 => 41, - 17 => 14, - 18 => 15 ) ), - array( - 'width' => 100, - 'height' => 400, - 'tests' => array( - 50 => 12, - 17 => 4, - 18 => 4 ) ) ); - foreach ( $vals as $row ) { - $tests = $row['tests']; - $height = $row['height']; - $width = $row['width']; - foreach ( $tests as $max => $expected ) { - $y = round( $expected * $height / $width ); - $result = MediaHandler::fitBoxWidth( $width, $height, $max ); - $y2 = round( $result * $height / $width ); - $this->assertEquals( $expected, - $result, - "($width, $height, $max) wanted: {$expected}x$y, got: {$result}x$y2" ); - } - } - } -} diff --git a/tests/phpunit/includes/media/PNGMetadataExtractorTest.php b/tests/phpunit/includes/media/PNGMetadataExtractorTest.php deleted file mode 100644 index 939f2cfc..00000000 --- a/tests/phpunit/includes/media/PNGMetadataExtractorTest.php +++ /dev/null @@ -1,155 +0,0 @@ -<?php - -/** - * @todo covers tags - */ -class PNGMetadataExtractorTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - $this->filePath = __DIR__ . '/../../data/media/'; - } - - /** - * Tests zTXt tag (compressed textual metadata) - */ - public function testPngNativetZtxt() { - $this->checkPHPExtension( 'zlib' ); - - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - $expected = "foo bar baz foo foo foo foof foo foo foo foo"; - $this->assertArrayHasKey( 'text', $meta ); - $meta = $meta['text']; - $this->assertArrayHasKey( 'Make', $meta ); - $this->assertArrayHasKey( 'x-default', $meta['Make'] ); - - $this->assertEquals( $expected, $meta['Make']['x-default'] ); - } - - /** - * Test tEXt tag (Uncompressed textual metadata) - */ - public function testPngNativeText() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - $expected = "Some long image desc"; - $this->assertArrayHasKey( 'text', $meta ); - $meta = $meta['text']; - $this->assertArrayHasKey( 'ImageDescription', $meta ); - $this->assertArrayHasKey( 'x-default', $meta['ImageDescription'] ); - $this->assertArrayHasKey( '_type', $meta['ImageDescription'] ); - - $this->assertEquals( $expected, $meta['ImageDescription']['x-default'] ); - } - - /** - * tEXt tags must be encoded iso-8859-1 (vs iTXt which are utf-8) - * Make sure non-ascii characters get converted properly - */ - public function testPngNativeTextNonAscii() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - - // Note the Copyright symbol here is a utf-8 one - // (aka \xC2\xA9) where in the file its iso-8859-1 - // encoded as just \xA9. - $expected = "© 2010 Bawolff"; - - $this->assertArrayHasKey( 'text', $meta ); - $meta = $meta['text']; - $this->assertArrayHasKey( 'Copyright', $meta ); - $this->assertArrayHasKey( 'x-default', $meta['Copyright'] ); - - $this->assertEquals( $expected, $meta['Copyright']['x-default'] ); - } - - /** - * Test extraction of pHYs tags, which can tell what the - * actual resolution of the image is (aka in dots per meter). - */ - /* - public function testPngPhysTag() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - - $this->assertArrayHasKey( 'text', $meta ); - $meta = $meta['text']; - - $this->assertEquals( '2835/100', $meta['XResolution'] ); - $this->assertEquals( '2835/100', $meta['YResolution'] ); - $this->assertEquals( 3, $meta['ResolutionUnit'] ); // 3 = cm - } - */ - - /** - * Given a normal static PNG, check the animation metadata returned. - */ - public function testStaticPngAnimationMetadata() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - - $this->assertEquals( 0, $meta['frameCount'] ); - $this->assertEquals( 1, $meta['loopCount'] ); - $this->assertEquals( 0, $meta['duration'] ); - } - - /** - * Given an animated APNG image file - * check it gets animated metadata right. - */ - public function testApngAnimationMetadata() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Animated_PNG_example_bouncing_beach_ball.png' ); - - $this->assertEquals( 20, $meta['frameCount'] ); - // Note loop count of 0 = infinity - $this->assertEquals( 0, $meta['loopCount'] ); - $this->assertEquals( 1.5, $meta['duration'], '', 0.00001 ); - } - - public function testPngBitDepth8() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - - $this->assertEquals( 8, $meta['bitDepth'] ); - } - - public function testPngBitDepth1() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - '1bit-png.png' ); - $this->assertEquals( 1, $meta['bitDepth'] ); - } - - - public function testPngIndexColour() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - - $this->assertEquals( 'index-coloured', $meta['colorType'] ); - } - - public function testPngRgbColour() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'rgb-png.png' ); - $this->assertEquals( 'truecolour-alpha', $meta['colorType'] ); - } - - public function testPngRgbNoAlphaColour() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'rgb-na-png.png' ); - $this->assertEquals( 'truecolour', $meta['colorType'] ); - } - - public function testPngGreyscaleColour() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'greyscale-png.png' ); - $this->assertEquals( 'greyscale-alpha', $meta['colorType'] ); - } - - 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 deleted file mode 100644 index ad4c2493..00000000 --- a/tests/phpunit/includes/media/PNGTest.php +++ /dev/null @@ -1,123 +0,0 @@ -<?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(); - - $this->filePath = __DIR__ . '/../../data/media'; - $this->backend = new FSFileBackend( array( - 'name' => 'localtesting', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( 'data' => $this->filePath ) - ) ); - $this->repo = new FSRepo( array( - 'name' => 'temp', - 'url' => 'http://localhost/thumbtest', - 'backend' => $this->backend - ) ); - $this->handler = new PNGHandler(); - } - - /** - * @covers PNGHandler::getMetadata - */ - public function testInvalidFile() { - $res = $this->handler->getMetadata( null, $this->filePath . '/README' ); - $this->assertEquals( PNGHandler::BROKEN_FILE, $res ); - } - - /** - * @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' ); - $actual = $this->handler->isAnimatedImage( $file ); - $this->assertEquals( $expected, $actual ); - } - - public static function provideIsAnimated() { - return array( - array( 'Animated_PNG_example_bouncing_beach_ball.png', true ), - array( '1bit-png.png', false ), - ); - } - - /** - * @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' ); - $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() ); - $this->assertEquals( $expected, $actual ); - } - - public static function provideGetImageArea() { - return array( - array( '1bit-png.png', 2500 ), - array( 'greyscale-png.png', 2500 ), - array( 'Png-native-test.png', 126000 ), - array( 'Animated_PNG_example_bouncing_beach_ball.png', 10000 ), - ); - } - - /** - * @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 ); - $this->assertEquals( $expected, $actual ); - } - - public static function provideIsMetadataValid() { - return array( - array( PNGHandler::BROKEN_FILE, PNGHandler::METADATA_GOOD ), - array( '', PNGHandler::METADATA_BAD ), - array( null, PNGHandler::METADATA_BAD ), - array( 'Something invalid!', PNGHandler::METADATA_BAD ), - array( 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:8;s:9:"colorType";s:10:"truecolour";s:8:"metadata";a:1:{s:15:"_MW_PNG_VERSION";i:1;}}', PNGHandler::METADATA_GOOD ), - ); - } - - /** - * @param $filename String - * @param $expected String Serialized array - * @dataProvider provideGetMetadata - * @covers PNGHandler::getMetadata - */ - public function testGetMetadata( $filename, $expected ) { - $file = $this->dataFile( $filename, 'image/png' ); - $actual = $this->handler->getMetadata( $file, "$this->filePath/$filename" ); -// $this->assertEquals( unserialize( $expected ), unserialize( $actual ) ); - $this->assertEquals( ( $expected ), ( $actual ) ); - } - - public static function provideGetMetadata() { - return array( - array( 'rgb-na-png.png', 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:8;s:9:"colorType";s:10:"truecolour";s:8:"metadata";a:1:{s:15:"_MW_PNG_VERSION";i:1;}}' ), - array( 'xmp.png', 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:1;s:9:"colorType";s:14:"index-coloured";s:8:"metadata";a:2:{s:12:"SerialNumber";s:9:"123456789";s:15:"_MW_PNG_VERSION";i:1;}}' ), - ); - } - - private function dataFile( $name, $type ) { - return new UnregisteredLocalFile( false, $this->repo, - "mwstore://localtesting/data/$name", $type ); - } -} diff --git a/tests/phpunit/includes/media/SVGMetadataExtractorTest.php b/tests/phpunit/includes/media/SVGMetadataExtractorTest.php deleted file mode 100644 index 257009b0..00000000 --- a/tests/phpunit/includes/media/SVGMetadataExtractorTest.php +++ /dev/null @@ -1,112 +0,0 @@ -<?php - -/** - * @todo covers tags - */ -class SVGMetadataExtractorTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - AutoLoader::loadClass( 'SVGMetadataExtractorTest' ); - } - - /** - * @dataProvider provideSvgFiles - */ - public function testGetMetadata( $infile, $expected ) { - $this->assertMetadata( $infile, $expected ); - } - - /** - * @dataProvider provideSvgFilesWithXMLMetadata - */ - 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 ); - } - - function assertMetadata( $infile, $expected ) { - try { - $data = SVGMetadataExtractor::getMetadata( $infile ); - $this->assertEquals( $expected, $data, 'SVG metadata extraction test' ); - } catch ( MWException $e ) { - if ( $expected === false ) { - $this->assertTrue( true, 'SVG metadata extracted test (expected failure)' ); - } else { - throw $e; - } - } - } - - public static function provideSvgFiles() { - $base = __DIR__ . '/../../data/media'; - - return array( - array( - "$base/Wikimedia-logo.svg", - array( - 'width' => 1024, - 'height' => 1024, - 'originalWidth' => '1024', - 'originalHeight' => '1024', - ) - ), - array( - "$base/QA_icon.svg", - array( - 'width' => 60, - 'height' => 60, - 'originalWidth' => '60', - 'originalHeight' => '60', - ) - ), - array( - "$base/Gtk-media-play-ltr.svg", - array( - 'width' => 60, - 'height' => 60, - 'originalWidth' => '60.0000000', - 'originalHeight' => '60.0000000', - ) - ), - array( - "$base/Toll_Texas_1.svg", - // This file triggered bug 31719, needs entity expansion in the xmlns checks - array( - 'width' => 385, - 'height' => 385, - 'originalWidth' => '385', - 'originalHeight' => '385.0004883', - ) - ) - ); - } - - public static function provideSvgFilesWithXMLMetadata() { - $base = __DIR__ . '/../../data/media'; - $metadata = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> - <ns4:Work xmlns:ns4="http://creativecommons.org/ns#" rdf:about=""> - <ns5:format xmlns:ns5="http://purl.org/dc/elements/1.1/">image/svg+xml</ns5:format> - <ns5:type xmlns:ns5="http://purl.org/dc/elements/1.1/" rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> - </ns4:Work> - </rdf:RDF>'; - $metadata = str_replace( "\r", '', $metadata ); // Windows compat - return array( - array( - "$base/US_states_by_total_state_tax_revenue.svg", - array( - 'height' => 593, - 'metadata' => $metadata, - 'width' => 959, - 'originalWidth' => '958.69', - 'originalHeight' => '592.78998', - ) - ), - ); - } -} diff --git a/tests/phpunit/includes/media/TiffTest.php b/tests/phpunit/includes/media/TiffTest.php deleted file mode 100644 index 8d74b98d..00000000 --- a/tests/phpunit/includes/media/TiffTest.php +++ /dev/null @@ -1,39 +0,0 @@ -<?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 ); - - $this->filePath = __DIR__ . '/../../data/media/'; - $this->handler = new TiffHandler; - } - - /** - * @covers TiffHandler::getMetadata - */ - public function testInvalidFile() { - $res = $this->handler->getMetadata( null, $this->filePath . 'README' ); - $this->assertEquals( ExifBitmapHandler::BROKEN_FILE, $res ); - } - - /** - * @covers TiffHandler::getMetadata - */ - public function testTiffMetadataExtraction() { - $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 - // of php serialize stuff. - $this->assertEquals( unserialize( $expected ), unserialize( $res ) ); - } -} diff --git a/tests/phpunit/includes/media/XMPTest.php b/tests/phpunit/includes/media/XMPTest.php deleted file mode 100644 index d12e9b00..00000000 --- a/tests/phpunit/includes/media/XMPTest.php +++ /dev/null @@ -1,166 +0,0 @@ -<?php - -/** - * @todo covers tags - */ -class XMPTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - if ( !extension_loaded( 'xml' ) ) { - $this->markTestSkipped( 'Requires libxml to do XMP parsing' ); - } - } - - /** - * Put XMP in, compare what comes out... - * - * @param $xmp String the actual xml data. - * @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 ) { - if ( !is_string( $xmp ) || !is_array( $expected ) ) { - throw new Exception( "Invalid data provided to " . __METHOD__ ); - } - $reader = new XMPReader; - $reader->parse( $xmp ); - $this->assertEquals( $expected, $reader->getResults(), $info, 0.0000000001 ); - } - - public static function provideXMPParse() { - $xmpPath = __DIR__ . '/../../data/xmp/'; - $data = array(); - - // $xmpFiles format: array of arrays with first arg file base name, - // with the actual file having .xmp on the end for the xmp - // and .result.php on the end for a php file containing the result - // array. Second argument is some info on what's being tested. - $xmpFiles = array( - array( '1', 'parseType=Resource test' ), - array( '2', 'Structure with mixed attribute and element props' ), - array( '3', 'Extra qualifiers (that should be ignored)' ), - array( '3-invalid', 'Test ignoring qualifiers that look like normal props' ), - array( '4', 'Flash as qualifier' ), - array( '5', 'Flash as qualifier 2' ), - array( '6', 'Multiple rdf:Description' ), - array( '7', 'Generic test of several property types' ), - array( 'flash', 'Test of Flash property' ), - array( 'invalid-child-not-struct', 'Test child props not in struct or ignored' ), - array( 'no-recognized-props', 'Test namespace and no recognized props' ), - array( 'no-namespace', 'Test non-namespaced attributes are ignored' ), - array( 'bag-for-seq', "Allow bag's instead of seq's. (bug 27105)" ), - array( 'utf16BE', 'UTF-16BE encoding' ), - array( 'utf16LE', 'UTF-16LE encoding' ), - array( 'utf32BE', 'UTF-32BE encoding' ), - array( 'utf32LE', 'UTF-32LE encoding' ), - array( 'xmpExt', 'Extended XMP missing second part' ), - array( 'gps', 'Handling of exif GPS parameters in XMP' ), - ); - - foreach ( $xmpFiles as $file ) { - $xmp = file_get_contents( $xmpPath . $file[0] . '.xmp' ); - // I'm not sure if this is the best way to handle getting the - // result array, but it seems kind of big to put directly in the test - // file. - $result = null; - include $xmpPath . $file[0] . '.result.php'; - $data[] = array( $xmp, $result, '[' . $file[0] . '.xmp] ' . $file[1] ); - } - - return $data; - } - - /** Test ExtendedXMP block support. (Used when the XMP has to be split - * over multiple jpeg segments, due to 64k size limit on jpeg segments. - * - * @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. - */ - public function testExtendedXMP() { - $xmpPath = __DIR__ . '/../../data/xmp/'; - $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' ); - $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' ); - - $md5sum = '28C74E0AC2D796886759006FBE2E57B7'; // of xmpExt2.xmp - $length = pack( 'N', strlen( $extendedXMP ) ); - $offset = pack( 'N', 0 ); - $extendedPacket = $md5sum . $length . $offset . $extendedXMP; - - $reader = new XMPReader(); - $reader->parse( $standardXMP ); - $reader->parseExtended( $extendedPacket ); - $actual = $reader->getResults(); - - $expected = array( - 'xmp-exif' => array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => 9, - 'FNumber' => '2/10', - ) - ); - - $this->assertEquals( $expected, $actual ); - } - - /** - * This test has an extended XMP block with a wrong guid (md5sum) - * and thus should only return the StandardXMP, not the ExtendedXMP. - */ - public function testExtendedXMPWithWrongGUID() { - $xmpPath = __DIR__ . '/../../data/xmp/'; - $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' ); - $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' ); - - $md5sum = '28C74E0AC2D796886759006FBE2E57B9'; // Note last digit. - $length = pack( 'N', strlen( $extendedXMP ) ); - $offset = pack( 'N', 0 ); - $extendedPacket = $md5sum . $length . $offset . $extendedXMP; - - $reader = new XMPReader(); - $reader->parse( $standardXMP ); - $reader->parseExtended( $extendedPacket ); - $actual = $reader->getResults(); - - $expected = array( - 'xmp-exif' => array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => 9, - ) - ); - - $this->assertEquals( $expected, $actual ); - } - - /** - * Have a high offset to simulate a missing packet, - * which should cause it to ignore the ExtendedXMP packet. - */ - public function testExtendedXMPMissingPacket() { - $xmpPath = __DIR__ . '/../../data/xmp/'; - $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' ); - $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' ); - - $md5sum = '28C74E0AC2D796886759006FBE2E57B7'; // of xmpExt2.xmp - $length = pack( 'N', strlen( $extendedXMP ) ); - $offset = pack( 'N', 2048 ); - $extendedPacket = $md5sum . $length . $offset . $extendedXMP; - - $reader = new XMPReader(); - $reader->parse( $standardXMP ); - $reader->parseExtended( $extendedPacket ); - $actual = $reader->getResults(); - - $expected = array( - 'xmp-exif' => array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => 9, - ) - ); - - $this->assertEquals( $expected, $actual ); - } -} diff --git a/tests/phpunit/includes/media/XMPValidateTest.php b/tests/phpunit/includes/media/XMPValidateTest.php deleted file mode 100644 index 96bf5e47..00000000 --- a/tests/phpunit/includes/media/XMPValidateTest.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -class XMPValidateTest extends MediaWikiTestCase { - - /** - * @dataProvider provideDates - * @covers XMPValidate::validateDate - */ - public function testValidateDate( $value, $expected ) { - // The method should modify $value. - XMPValidate::validateDate( array(), $value, true ); - $this->assertEquals( $expected, $value ); - } - - public static function provideDates() { - /* For reference valid date formats are: - * YYYY - * YYYY-MM - * YYYY-MM-DD - * YYYY-MM-DDThh:mmTZD - * YYYY-MM-DDThh:mm:ssTZD - * YYYY-MM-DDThh:mm:ss.sTZD - * (Time zone is optional) - */ - return array( - array( '1992', '1992' ), - array( '1992-04', '1992:04' ), - array( '1992-02-01', '1992:02:01' ), - array( '2011-09-29', '2011:09:29' ), - array( '1982-12-15T20:12', '1982:12:15 20:12' ), - array( '1982-12-15T20:12Z', '1982:12:15 20:12' ), - array( '1982-12-15T20:12+02:30', '1982:12:15 22:42' ), - array( '1982-12-15T01:12-02:30', '1982:12:14 22:42' ), - array( '1982-12-15T20:12:11', '1982:12:15 20:12:11' ), - array( '1982-12-15T20:12:11Z', '1982:12:15 20:12:11' ), - array( '1982-12-15T20:12:11+01:10', '1982:12:15 21:22:11' ), - array( '2045-12-15T20:12:11', '2045:12:15 20:12:11' ), - array( '1867-06-01T15:00:00', '1867:06:01 15:00:00' ), - /* some invalid ones */ - array( '2001--12', null ), - array( '2001-5-12', null ), - array( '2001-5-12TZ', null ), - 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 deleted file mode 100644 index 52dd2ef5..00000000 --- a/tests/phpunit/includes/normal/CleanUpTest.php +++ /dev/null @@ -1,409 +0,0 @@ -<?php -/** - * Tests for UtfNormal::cleanUp() function. - * - * Copyright © 2004 Brion Vibber <brion@pobox.com> - * http://www.mediawiki.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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - */ - -/** - * Additional tests for UtfNormal::cleanUp() function, inclusion - * regression checks for known problems. - * Requires PHPUnit. - * - * @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 */ - public function testAscii() { - $text = 'This is plain ASCII text.'; - $this->assertEquals( $text, UtfNormal::cleanUp( $text ) ); - } - - /** @todo document */ - public function testNull() { - $text = "a \x00 null"; - $expect = "a \xef\xbf\xbd null"; - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - public function testLatin() { - $text = "L'\xc3\xa9cole"; - $this->assertEquals( $text, UtfNormal::cleanUp( $text ) ); - } - - /** @todo document */ - public function testLatinNormal() { - $text = "L'e\xcc\x81cole"; - $expect = "L'\xc3\xa9cole"; - $this->assertEquals( $expect, UtfNormal::cleanUp( $text ) ); - } - - /** - * This test is *very* expensive! - * @todo document - */ - function XtestAllChars() { - $rep = UTF8_REPLACEMENT; - for ( $i = 0x0; $i < UNICODE_MAX; $i++ ) { - $char = codepointToUtf8( $i ); - $clean = UtfNormal::cleanUp( $char ); - $x = sprintf( "%04X", $i ); - - if ( $i % 0x1000 == 0 ) { - echo "U+$x\n"; - } - - if ( $i == 0x0009 || - $i == 0x000a || - $i == 0x000d || - ( $i > 0x001f && $i < UNICODE_SURROGATE_FIRST ) || - ( $i > UNICODE_SURROGATE_LAST && $i < 0xfffe ) || - ( $i > 0xffff && $i <= UNICODE_MAX ) - ) { - if ( isset( UtfNormal::$utfCanonicalComp[$char] ) || isset( UtfNormal::$utfCanonicalDecomp[$char] ) ) { - $comp = UtfNormal::NFC( $char ); - $this->assertEquals( - bin2hex( $comp ), - bin2hex( $clean ), - "U+$x should be decomposed" ); - } else { - $this->assertEquals( - bin2hex( $char ), - bin2hex( $clean ), - "U+$x should be intact" ); - } - } else { - $this->assertEquals( bin2hex( $rep ), bin2hex( $clean ), $x ); - } - } - } - - /** @todo document */ - public function testAllBytes() { - $this->doTestBytes( '', '' ); - $this->doTestBytes( 'x', '' ); - $this->doTestBytes( '', 'x' ); - $this->doTestBytes( 'x', 'x' ); - } - - /** @todo document */ - function doTestBytes( $head, $tail ) { - for ( $i = 0x0; $i < 256; $i++ ) { - $char = $head . chr( $i ) . $tail; - $clean = UtfNormal::cleanUp( $char ); - $x = sprintf( "%02X", $i ); - - if ( $i == 0x0009 || - $i == 0x000a || - $i == 0x000d || - ( $i > 0x001f && $i < 0x80 ) - ) { - $this->assertEquals( - bin2hex( $char ), - bin2hex( $clean ), - "ASCII byte $x should be intact" ); - if ( $char != $clean ) { - return; - } - } else { - $norm = $head . UTF8_REPLACEMENT . $tail; - $this->assertEquals( - bin2hex( $norm ), - bin2hex( $clean ), - "Forbidden byte $x should be rejected" ); - if ( $norm != $clean ) { - return; - } - } - } - } - - /** @todo document */ - public function testDoubleBytes() { - $this->doTestDoubleBytes( '', '' ); - $this->doTestDoubleBytes( 'x', '' ); - $this->doTestDoubleBytes( '', 'x' ); - $this->doTestDoubleBytes( 'x', 'x' ); - } - - /** - * @todo document - */ - function doTestDoubleBytes( $head, $tail ) { - for ( $first = 0xc0; $first < 0x100; $first += 2 ) { - for ( $second = 0x80; $second < 0x100; $second += 2 ) { - $char = $head . chr( $first ) . chr( $second ) . $tail; - $clean = UtfNormal::cleanUp( $char ); - $x = sprintf( "%02X,%02X", $first, $second ); - if ( $first > 0xc1 && - $first < 0xe0 && - $second < 0xc0 - ) { - $norm = UtfNormal::NFC( $char ); - $this->assertEquals( - bin2hex( $norm ), - bin2hex( $clean ), - "Pair $x should be intact" ); - if ( $norm != $clean ) { - return; - } - } elseif ( $first > 0xfd || $second > 0xbf ) { - # fe and ff are not legal head bytes -- expect two replacement chars - $norm = $head . UTF8_REPLACEMENT . UTF8_REPLACEMENT . $tail; - $this->assertEquals( - bin2hex( $norm ), - bin2hex( $clean ), - "Forbidden pair $x should be rejected" ); - if ( $norm != $clean ) { - return; - } - } else { - $norm = $head . UTF8_REPLACEMENT . $tail; - $this->assertEquals( - bin2hex( $norm ), - bin2hex( $clean ), - "Forbidden pair $x should be rejected" ); - if ( $norm != $clean ) { - return; - } - } - } - } - } - - /** @todo document */ - public function testTripleBytes() { - $this->doTestTripleBytes( '', '' ); - $this->doTestTripleBytes( 'x', '' ); - $this->doTestTripleBytes( '', 'x' ); - $this->doTestTripleBytes( 'x', 'x' ); - } - - /** @todo document */ - function doTestTripleBytes( $head, $tail ) { - for ( $first = 0xc0; $first < 0x100; $first += 2 ) { - for ( $second = 0x80; $second < 0x100; $second += 2 ) { - #for( $third = 0x80; $third < 0x100; $third++ ) { - for ( $third = 0x80; $third < 0x81; $third++ ) { - $char = $head . chr( $first ) . chr( $second ) . chr( $third ) . $tail; - $clean = UtfNormal::cleanUp( $char ); - $x = sprintf( "%02X,%02X,%02X", $first, $second, $third ); - - if ( $first >= 0xe0 && - $first < 0xf0 && - $second < 0xc0 && - $third < 0xc0 - ) { - if ( $first == 0xe0 && $second < 0xa0 ) { - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Overlong triplet $x should be rejected" ); - } elseif ( $first == 0xed && - ( chr( $first ) . chr( $second ) . chr( $third ) ) >= UTF8_SURROGATE_FIRST - ) { - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Surrogate triplet $x should be rejected" ); - } else { - $this->assertEquals( - bin2hex( UtfNormal::NFC( $char ) ), - bin2hex( $clean ), - "Triplet $x should be intact" ); - } - } elseif ( $first > 0xc1 && $first < 0xe0 && $second < 0xc0 ) { - $this->assertEquals( - bin2hex( UtfNormal::NFC( $head . chr( $first ) . chr( $second ) ) . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Valid 2-byte $x + broken tail" ); - } elseif ( $second > 0xc1 && $second < 0xe0 && $third < 0xc0 ) { - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . UtfNormal::NFC( chr( $second ) . chr( $third ) . $tail ) ), - bin2hex( $clean ), - "Broken head + valid 2-byte $x" ); - } elseif ( ( $first > 0xfd || $second > 0xfd ) && - ( ( $second > 0xbf && $third > 0xbf ) || - ( $second < 0xc0 && $third < 0xc0 ) || - ( $second > 0xfd ) || - ( $third > 0xfd ) ) - ) { - # fe and ff are not legal head bytes -- expect three replacement chars - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . UTF8_REPLACEMENT . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Forbidden triplet $x should be rejected" ); - } elseif ( $first > 0xc2 && $second < 0xc0 && $third < 0xc0 ) { - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Forbidden triplet $x should be rejected" ); - } else { - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Forbidden triplet $x should be rejected" ); - } - } - } - } - } - - /** @todo document */ - public function testChunkRegression() { - # Check for regression against a chunking bug - $text = "\x46\x55\xb8" . - "\xdc\x96" . - "\xee" . - "\xe7" . - "\x44" . - "\xaa" . - "\x2f\x25"; - $expect = "\x46\x55\xef\xbf\xbd" . - "\xdc\x96" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\x44" . - "\xef\xbf\xbd" . - "\x2f\x25"; - - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - public function testInterposeRegression() { - $text = "\x4e\x30" . - "\xb1" . # bad tail - "\x3a" . - "\x92" . # bad tail - "\x62\x3a" . - "\x84" . # bad tail - "\x43" . - "\xc6" . # bad head - "\x3f" . - "\x92" . # bad tail - "\xad" . # bad tail - "\x7d" . - "\xd9\x95"; - - $expect = "\x4e\x30" . - "\xef\xbf\xbd" . - "\x3a" . - "\xef\xbf\xbd" . - "\x62\x3a" . - "\xef\xbf\xbd" . - "\x43" . - "\xef\xbf\xbd" . - "\x3f" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\x7d" . - "\xd9\x95"; - - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - public function testOverlongRegression() { - $text = "\x67" . - "\x1a" . # forbidden ascii - "\xea" . # bad head - "\xc1\xa6" . # overlong sequence - "\xad" . # bad tail - "\x1c" . # forbidden ascii - "\xb0" . # bad tail - "\x3c" . - "\x9e"; # bad tail - $expect = "\x67" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\x3c" . - "\xef\xbf\xbd"; - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - public function testSurrogateRegression() { - $text = "\xed\xb4\x96" . # surrogate 0xDD16 - "\x83" . # bad tail - "\xb4" . # bad tail - "\xac"; # bad head - $expect = "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd"; - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - public function testBomRegression() { - $text = "\xef\xbf\xbe" . # U+FFFE, illegal char - "\xb2" . # bad tail - "\xef" . # bad head - "\x59"; - $expect = "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\x59"; - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - public function testForbiddenRegression() { - $text = "\xef\xbf\xbf"; # U+FFFF, illegal char - $expect = "\xef\xbf\xbd"; - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - public function testHangulRegression() { - $text = "\xed\x9c\xaf" . # Hangul char - "\xe1\x87\x81"; # followed by another final jamo - $expect = $text; # Should *not* change. - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } -} diff --git a/tests/phpunit/includes/objectcache/BagOStuffTest.php b/tests/phpunit/includes/objectcache/BagOStuffTest.php deleted file mode 100644 index aa783943..00000000 --- a/tests/phpunit/includes/objectcache/BagOStuffTest.php +++ /dev/null @@ -1,149 +0,0 @@ -<?php -/** - * This class will test BagOStuff. - * - * @author Matthias Mullie <mmullie@wikimedia.org> - */ -class BagOStuffTest extends MediaWikiTestCase { - private $cache; - - protected function setUp() { - parent::setUp(); - - // type defined through parameter - if ( $this->getCliArg( 'use-bagostuff=' ) ) { - $name = $this->getCliArg( 'use-bagostuff=' ); - - $this->cache = ObjectCache::newFromId( $name ); - } else { - // no type defined - use simple hash - $this->cache = new HashBagOStuff; - } - - $this->cache->delete( wfMemcKey( 'test' ) ); - } - - protected function tearDown() { - } - - public function testMerge() { - $key = wfMemcKey( 'test' ); - - $usleep = 0; - - /** - * Callback method: append "merged" to whatever is in cache. - * - * @param BagOStuff $cache - * @param string $key - * @param int $existingValue - * @use int $usleep - * @return int - */ - $callback = function ( BagOStuff $cache, $key, $existingValue ) use ( &$usleep ) { - // let's pretend this is an expensive callback to test concurrent merge attempts - usleep( $usleep ); - - if ( $existingValue === false ) { - return 'merged'; - } - - return $existingValue . 'merged'; - }; - - // merge on non-existing value - $merged = $this->cache->merge( $key, $callback, 0 ); - $this->assertTrue( $merged ); - $this->assertEquals( $this->cache->get( $key ), 'merged' ); - - // merge on existing value - $merged = $this->cache->merge( $key, $callback, 0 ); - $this->assertTrue( $merged ); - $this->assertEquals( $this->cache->get( $key ), 'mergedmerged' ); - - /* - * Test concurrent merges by forking this process, if: - * - not manually called with --use-bagostuff - * - pcntl_fork is supported by the system - * - cache type will correctly support calls over forks - */ - $fork = (bool)$this->getCliArg( 'use-bagostuff=' ); - $fork &= function_exists( 'pcntl_fork' ); - $fork &= !$this->cache instanceof HashBagOStuff; - $fork &= !$this->cache instanceof EmptyBagOStuff; - $fork &= !$this->cache instanceof MultiWriteBagOStuff; - if ( $fork ) { - // callback should take awhile now so that we can test concurrent merge attempts - $usleep = 5000; - - $pid = pcntl_fork(); - if ( $pid == -1 ) { - // can't fork, ignore this test... - } elseif ( $pid ) { - // wait a little, making sure that the child process is calling merge - usleep( 3000 ); - - // attempt a merge - this should fail - $merged = $this->cache->merge( $key, $callback, 0, 1 ); - - // merge has failed because child process was merging (and we only attempted once) - $this->assertFalse( $merged ); - - // make sure the child's merge is completed and verify - usleep( 3000 ); - $this->assertEquals( $this->cache->get( $key ), 'mergedmergedmerged' ); - } else { - $this->cache->merge( $key, $callback, 0, 1 ); - - // Note: I'm not even going to check if the merge worked, I'll - // compare values in the parent process to test if this merge worked. - // I'm just going to exit this child process, since I don't want the - // child to output any test results (would be rather confusing to - // have test output twice) - exit; - } - } - } - - public function testAdd() { - $key = wfMemcKey( 'test' ); - $this->assertTrue( $this->cache->add( $key, 'test' ) ); - } - - public function testGet() { - $value = array( 'this' => 'is', 'a' => 'test' ); - - $key = wfMemcKey( 'test' ); - $this->cache->add( $key, $value ); - $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' ); - - $key1 = wfMemcKey( 'test1' ); - $key2 = wfMemcKey( 'test2' ); - - $this->cache->add( $key1, $value1 ); - $this->cache->add( $key2, $value2 ); - - $this->assertEquals( $this->cache->getMulti( array( $key1, $key2 ) ), array( $key1 => $value1, $key2 => $value2 ) ); - - // cleanup - $this->cache->delete( $key1 ); - $this->cache->delete( $key2 ); - } -} diff --git a/tests/phpunit/includes/parser/MagicVariableTest.php b/tests/phpunit/includes/parser/MagicVariableTest.php deleted file mode 100644 index c2c97c01..00000000 --- a/tests/phpunit/includes/parser/MagicVariableTest.php +++ /dev/null @@ -1,242 +0,0 @@ -<?php -/** - * This file is intended to test magic variables in the parser - * It was inspired by Raymond & Matěj Grabovský commenting about r66200 - * - * As of february 2011, it only tests some revisions and date related - * magic variables. - * - * @author Antoine Musso - * @copyright Copyright © 2011, Antoine Musso - * @file - * @todo covers tags - */ - -class MagicVariableTest extends MediaWikiTestCase { - /** - * @var Parser - */ - private $testParser = null; - - /** - * An array of magicword returned as type integer by the parser - * They are usually returned as a string for i18n since we support - * persan numbers for example, but some magic explicitly return - * them as integer. - * @see MagicVariableTest::assertMagic() - */ - private $expectedAsInteger = array( - 'revisionday', - 'revisionmonth1', - ); - - /** setup a basic parser object */ - protected function setUp() { - parent::setUp(); - - $contLang = Language::factory( 'en' ); - $this->setMwGlobals( array( - 'wgLanguageCode' => 'en', - 'wgContLang' => $contLang, - ) ); - - $this->testParser = new Parser(); - $this->testParser->Options( ParserOptions::newFromUserAndLang( new User, $contLang ) ); - - # initialize parser output - $this->testParser->clearState(); - - # Needs a title to do magic word stuff - $title = Title::newFromText( 'Tests' ); - $title->mRedirect = false; # Else it needs a db connection just to check if it's a redirect (when deciding the page language) - - $this->testParser->setTitle( $title ); - } - - /** - * @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 ); - } - - /** - * @return array of days numbers (as an integer) - */ - public static function provideDays() { - return self::createProviderUpTo( 31 ); - } - - ############### TESTS ############################################# - # @todo FIXME: - # - those got copy pasted, we can probably make them cleaner - # - tests are lacking useful messages - - # day - - /** @dataProvider provideDays */ - public function testCurrentdayIsUnPadded( $day ) { - $this->assertUnPadded( 'currentday', $day ); - } - - /** @dataProvider provideDays */ - public function testCurrentdaytwoIsZeroPadded( $day ) { - $this->assertZeroPadded( 'currentday2', $day ); - } - - /** @dataProvider provideDays */ - public function testLocaldayIsUnPadded( $day ) { - $this->assertUnPadded( 'localday', $day ); - } - - /** @dataProvider provideDays */ - public function testLocaldaytwoIsZeroPadded( $day ) { - $this->assertZeroPadded( 'localday2', $day ); - } - - # month - - /** @dataProvider provideMonths */ - public function testCurrentmonthIsZeroPadded( $month ) { - $this->assertZeroPadded( 'currentmonth', $month ); - } - - /** @dataProvider provideMonths */ - public function testCurrentmonthoneIsUnPadded( $month ) { - $this->assertUnPadded( 'currentmonth1', $month ); - } - - /** @dataProvider provideMonths */ - public function testLocalmonthIsZeroPadded( $month ) { - $this->assertZeroPadded( 'localmonth', $month ); - } - - /** @dataProvider provideMonths */ - public function testLocalmonthoneIsUnPadded( $month ) { - $this->assertUnPadded( 'localmonth1', $month ); - } - - # revision day - - /** @dataProvider provideDays */ - public function testRevisiondayIsUnPadded( $day ) { - $this->assertUnPadded( 'revisionday', $day ); - } - - /** @dataProvider provideDays */ - public function testRevisiondaytwoIsZeroPadded( $day ) { - $this->assertZeroPadded( 'revisionday2', $day ); - } - - # revision month - - /** @dataProvider provideMonths */ - public function testRevisionmonthIsZeroPadded( $month ) { - $this->assertZeroPadded( 'revisionmonth', $month ); - } - - /** @dataProvider provideMonths */ - public function testRevisionmonthoneIsUnPadded( $month ) { - $this->assertUnPadded( 'revisionmonth1', $month ); - } - - /** - * Rough tests for {{SERVERNAME}} magic word - * Bug 31176 - * @group Database - * @dataProvider provideDataServernameFromDifferentProtocols - */ - public function testServernameFromDifferentProtocols( $server ) { - $this->setMwGlobals( 'wgServer', $server ); - - $this->assertMagic( 'localhost', 'servername' ); - } - - 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 ) { - $this->assertMagicPadding( $magic, $value, '%02d' ); - } - - /** assertion helper expecting a magic output which is unpadded */ - public function assertUnPadded( $magic, $value ) { - $this->assertMagicPadding( $magic, $value, '%d' ); - } - - /** - * Main assertion helper for magic variables padding - * @param $magic string Magic variable name - * @param $value mixed Month or day - * @param $format string sprintf format for $value - */ - private function assertMagicPadding( $magic, $value, $format ) { - # Initialize parser timestamp as year 2010 at 12h34 56s. - # month and day are given by the caller ($value). Month < 12! - if ( $value > 12 ) { - $month = $value % 12; - } else { - $month = $value; - } - - $this->setParserTS( - sprintf( '2010%02d%02d123456', $month, $value ) - ); - - # please keep the following commented line of code. It helps debugging. - //print "\nDEBUG (value $value):" . sprintf( '2010%02d%02d123456', $value, $value ) . "\n"; - - # format expectation and test it - $expected = sprintf( $format, $value ); - $this->assertMagic( $expected, $magic ); - } - - /** helper to set the parser timestamp and revision timestamp */ - private function setParserTS( $ts ) { - $this->testParser->Options()->setTimestamp( $ts ); - $this->testParser->mRevisionTimestamp = $ts; - } - - /** - * Assertion helper to test a magic variable output - */ - private function assertMagic( $expected, $magic ) { - if ( in_array( $magic, $this->expectedAsInteger ) ) { - $expected = (int)$expected; - } - - # Generate a message for the assertion - $msg = sprintf( "Magic %s should be <%s:%s>", - $magic, - $expected, - gettype( $expected ) - ); - - $this->assertSame( - $expected, - $this->testParser->getVariableValue( $magic ), - $msg - ); - } -} diff --git a/tests/phpunit/includes/parser/MediaWikiParserTest.php b/tests/phpunit/includes/parser/MediaWikiParserTest.php deleted file mode 100644 index c120ca34..00000000 --- a/tests/phpunit/includes/parser/MediaWikiParserTest.php +++ /dev/null @@ -1,120 +0,0 @@ -<?php -require_once __DIR__ . '/NewParserTest.php'; - -/** - * The UnitTest must be either a class that inherits from MediaWikiTestCase - * or a class that provides a public static suite() method which returns - * an PHPUnit_Framework_Test object - * - * @group Parser - * @group Database - */ -class MediaWikiParserTest { - - /** - * @defgroup filtering_constants Filtering constants - * - * Limit inclusion of parser tests files coming from MediaWiki core - * @{ - */ - - /** 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 ) ); - - $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 - */ - $parserTestClassName = str_replace( '.', '_', ucfirst( $testsName ) ); - $parserTestClassDefinition = <<<EOT -/** - * @group Database - * @group Parser - * @group ParserTests - * @group ParserTests_$parserTestClassName - */ -class $parserTestClassName extends NewParserTest { - protected \$file = '$escapedFileName'; -} -EOT; - - 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 deleted file mode 100644 index eac4de5c..00000000 --- a/tests/phpunit/includes/parser/NewParserTest.php +++ /dev/null @@ -1,969 +0,0 @@ -<?php - -/** - * Although marked as a stub, can work independently. - * - * @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 - /* The data provider is run on a different instance than the test, so it must be static - * When running tests from several files, all tests will see all articles. - */ - static protected $backendToUse; - - public $keepUploads = false; - public $runDisabled = false; - public $runParsoid = false; - public $regex = ''; - public $showProgress = true; - public $savedWeirdGlobals = array(); - public $savedGlobals = array(); - public $hooks = array(); - public $functionHooks = array(); - - //Fuzz test - public $maxFuzzTestLength = 300; - public $fuzzSeed = 0; - public $memoryLimit = 50; - - protected $file = false; - - public static function setUpBeforeClass() { - // Inject ParserTest well-known interwikis - ParserTest::setupInterwikis(); - } - - protected function setUp() { - global $wgNamespaceAliases, $wgContLang; - global $wgHooks, $IP; - - parent::setUp(); - - //Setup CLI arguments - if ( $this->getCliArg( 'regex=' ) ) { - $this->regex = $this->getCliArg( 'regex=' ); - } else { - # Matches anything - $this->regex = ''; - } - - $this->keepUploads = $this->getCliArg( 'keep-uploads' ); - - $tmpGlobals = array(); - - $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['wgActionPaths'] = array(); - $tmpGlobals['wgVariantArticlePath'] = false; - $tmpGlobals['wgExtensionAssetsPath'] = '/extensions'; - $tmpGlobals['wgStylePath'] = '/skins'; - $tmpGlobals['wgEnableUploads'] = true; - $tmpGlobals['wgThumbnailScriptPath'] = false; - $tmpGlobals['wgLocalFileRepo'] = array( - 'class' => 'LocalRepo', - 'name' => 'local', - 'url' => 'http://example.com/images', - 'hashLevels' => 2, - 'transformVia404' => false, - 'backend' => 'local-backend' - ); - $tmpGlobals['wgForeignFileRepos'] = array(); - $tmpGlobals['wgDefaultExternalStore'] = array(); - $tmpGlobals['wgEnableParserCache'] = false; - $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['wgGroupPermissions'] = array( - '*' => array( - 'createaccount' => true, - 'read' => true, - 'edit' => true, - 'createpage' => true, - 'createtalk' => true, - ) ); - $tmpGlobals['wgNamespaceProtection'] = array( NS_MEDIAWIKI => 'editinterface' ); - - $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'; - - $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' ); - - $this->setMwGlobals( $tmpGlobals ); - - $this->savedWeirdGlobals['image_alias'] = $wgNamespaceAliases['Image']; - $this->savedWeirdGlobals['image_talk_alias'] = $wgNamespaceAliases['Image_talk']; - - $wgNamespaceAliases['Image'] = NS_FILE; - $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - } - - protected function tearDown() { - global $wgNamespaceAliases, $wgContLang; - - $wgNamespaceAliases['Image'] = $this->savedWeirdGlobals['image_alias']; - $wgNamespaceAliases['Image_talk'] = $this->savedWeirdGlobals['image_talk_alias']; - - // Restore backends - 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'; - # disabled for performance - #$this->tablesUsed[] = 'image'; - - # Update certain things in site_stats - $this->db->insert( 'site_stats', - array( 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ), - __METHOD__ - ); - - $user = User::newFromId( 0 ); - LinkCache::singleton()->clear(); # Avoids the odd failure at creating the nullRevision - - # Upload DB table entries for files. - # 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( - '', // archive name - 'Upload of some lame file', - 'Some lame file', - array( - 'size' => 7881, - 'width' => 1941, - 'height' => 220, - 'bits' => 8, - 'media_type' => MEDIATYPE_BITMAP, - 'mime' => 'image/jpeg', - 'metadata' => serialize( array() ), - '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() ) ) ) { - $image->recordUpload2( - '', // archive name - 'zomgnotcensored', - 'Borderline image', - array( - 'size' => 12345, - 'width' => 320, - 'height' => 240, - 'bits' => 24, - 'media_type' => MEDIATYPE_BITMAP, - 'mime' => 'image/jpeg', - 'metadata' => serialize( array() ), - '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 - - /** - * Set up the global variables for a consistent environment for each test. - * Ideally this should replace the global configuration entirely. - */ - protected function setupGlobals( $opts = array(), $config = '' ) { - global $wgFileBackends; - # Find out values for some special options. - $lang = - self::getOptionValue( 'language', $opts, 'en' ); - $variant = - self::getOptionValue( 'variant', $opts, false ); - $maxtoclevel = - self::getOptionValue( 'wgMaxTocLevel', $opts, 999 ); - $linkHolderBatchSize = - self::getOptionValue( 'wgLinkHolderBatchSize', $opts, 1000 ); - - $uploadDir = $this->getUploadDir(); - if ( $this->getCliArg( 'use-filebackend=' ) ) { - if ( self::$backendToUse ) { - $backend = self::$backendToUse; - } else { - $name = $this->getCliArg( 'use-filebackend=' ); - $useConfig = array(); - foreach ( $wgFileBackends as $conf ) { - if ( $conf['name'] == $name ) { - $useConfig = $conf; - } - } - $useConfig['name'] = 'local-backend'; // swap name - $class = $conf['class']; - self::$backendToUse = new $class( $useConfig ); - $backend = self::$backendToUse; - } - } else { - # 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( - 'local-public' => "$uploadDir", - 'local-thumb' => "$uploadDir/thumb", - ) - ) ); - } - - $settings = array( - 'wgLocalFileRepo' => array( - 'class' => 'LocalRepo', - 'name' => 'local', - 'url' => 'http://example.com/images', - 'hashLevels' => 2, - 'transformVia404' => false, - 'backend' => $backend - ), - 'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ), - 'wgLanguageCode' => $lang, - 'wgDBprefix' => $this->db->getType() != 'oracle' ? 'unittest_' : 'ut_', - 'wgRawHtml' => self::getOptionValue( 'wgRawHtml', $opts, false ), - 'wgNamespacesWithSubpages' => array( NS_MAIN => isset( $opts['subpage'] ) ), - 'wgAllowExternalImages' => self::getOptionValue( 'wgAllowExternalImages', $opts, true ), - 'wgMaxTocLevel' => $maxtoclevel, - 'wgUseTeX' => isset( $opts['math'] ) || isset( $opts['texvc'] ), - 'wgMathDirectory' => $uploadDir . '/math', - 'wgDefaultLanguageVariant' => $variant, - 'wgLinkHolderBatchSize' => $linkHolderBatchSize, - ); - - if ( $config ) { - $configLines = explode( "\n", $config ); - - foreach ( $configLines as $line ) { - list( $var, $value ) = explode( '=', $line, 2 ); - - $settings[$var] = eval( "return $value;" ); //??? - } - } - - $this->savedGlobals = array(); - - /** @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]; - } - - $GLOBALS[$var] = $val; - } - - MagicWord::clearCache(); - - # The entries saved into RepoGroup cache with previous globals will be wrong. - RepoGroup::destroySingleton(); - FileBackendGroup::destroySingleton(); - - # Create dummy files in storage - $this->setupUploads(); - - # Publish the articles after we have the final language set - $this->publishTestArticles(); - - MessageCache::destroyInstance(); - - return $context; - } - - /** - * Get an FS upload directory (only applies to FSFileBackend) - * - * @return String: the directory - */ - protected function getUploadDir() { - if ( $this->keepUploads ) { - $dir = wfTempDir() . '/mwParser-images'; - - if ( is_dir( $dir ) ) { - return $dir; - } - } else { - $dir = wfTempDir() . "/mwParser-" . mt_rand() . "-images"; - } - - // wfDebug( "Creating upload directory $dir\n" ); - if ( file_exists( $dir ) ) { - wfDebug( "Already exists!\n" ); - - return $dir; - } - - return $dir; - } - - /** - * Create a dummy uploads directory which will contain a couple - * of files in order to pass existence tests. - * - * @return String: the directory - */ - protected function setupUploads() { - global $IP; - - $base = $this->getBaseDir(); - $backend = RepoGroup::singleton()->getLocalRepo()->getBackend(); - $backend->prepare( array( 'dir' => "$base/local-public/3/3a" ) ); - $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" - ) ); - } - - /** - * Restore default values and perform any necessary clean-up - * after each test runs. - */ - protected function teardownGlobals() { - $this->teardownUploads(); - - foreach ( $this->savedGlobals as $var => $val ) { - $GLOBALS[$var] = $val; - } - } - - /** - * Remove the dummy uploads directory - */ - private function teardownUploads() { - if ( $this->keepUploads ) { - 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( - array( - "$base/local-public/3/3a/Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/180px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/200px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/640px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/120px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/1280px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/20px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/270px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/300px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/30px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/360px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/400px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/40px-Foobar.jpg", - "$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-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", - ) - ); - } - - /** - * Delete the specified files, if they exist. - * @param $files Array: full paths to files to delete. - */ - private static function deleteFiles( $files ) { - $backend = RepoGroup::singleton()->getLocalRepo()->getBackend(); - foreach ( $files as $file ) { - $backend->delete( array( 'src' => $file ), array( 'force' => 1 ) ); - } - foreach ( $files as $file ) { - $tmp = $file; - while ( $tmp = FileBackend::parentStoragePath( $tmp ) ) { - if ( !$backend->clean( array( 'dir' => $tmp ) )->isOK() ) { - break; - } - } - } - } - - protected function getBaseDir() { - return 'mwstore://local-backend'; - } - - public function parserTestProvider() { - if ( $this->file === false ) { - global $wgParserTestFiles; - $this->file = $wgParserTestFiles[0]; - } - - return new TestFileIterator( $this->file, $this ); - } - - /** - * Set the file from whose tests will be run by this instance - */ - public function setParserTestFile( $filename ) { - $this->file = $filename; - } - - /** - * @group medium - * @dataProvider parserTestProvider - */ - public function testParserTest( $desc, $input, $result, $opts, $config ) { - if ( $this->regex != '' && !preg_match( '/' . $this->regex . '/', $desc ) ) { - $this->assertTrue( true ); // XXX: don't flood output with "test made no assertions" - //$this->markTestSkipped( 'Filtered out by the user' ); - return; - } - - 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 - // $wgtContentModelUseDB is false. - $this->markTestSkipped( "Main namespace does not support wikitext," - . "skipping parser test: $desc" ); - } - - wfDebug( "Running parser test: $desc\n" ); - - $opts = $this->parseOptions( $opts ); - $context = $this->setupGlobals( $opts, $config ); - - $user = $context->getUser(); - $options = ParserOptions::newFromContext( $context ); - - if ( isset( $opts['title'] ) ) { - $titleText = $opts['title']; - } else { - $titleText = 'Parser test'; - } - - $local = isset( $opts['local'] ); - $preprocessor = isset( $opts['preprocessor'] ) ? $opts['preprocessor'] : null; - $parser = $this->getParser( $preprocessor ); - - $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'] ) ) { - $out = $parser->transformMsg( $input, $options, $title ); - } elseif ( isset( $opts['section'] ) ) { - $section = $opts['section']; - $out = $parser->getSection( $input, $section ); - } elseif ( isset( $opts['replace'] ) ) { - $section = $opts['replace'][0]; - $replace = $opts['replace'][1]; - $out = $parser->replaceSection( $input, $section, $replace ); - } elseif ( isset( $opts['comment'] ) ) { - $out = Linker::formatComment( $input, $title, $local ); - } elseif ( isset( $opts['preload'] ) ) { - $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'] ) ) { - if ( $output->getTitleText() ) { - $title = $output->getTitleText(); - } - - $out = "$title\n$out"; - } - - if ( isset( $opts['ill'] ) ) { - $out = $this->tidy( implode( ' ', $output->getLanguageLinks() ) ); - } elseif ( isset( $opts['cat'] ) ) { - $outputPage = $context->getOutput(); - $outputPage->addCategoryLinks( $output->getCategories() ); - $cats = $outputPage->getCategoryLinks(); - - if ( isset( $cats['normal'] ) ) { - $out = $this->tidy( implode( ' ', $cats['normal'] ) ); - } else { - $out = ''; - } - } - $parser->mPreprocessor = null; - - $result = $this->tidy( $result ); - } - - $this->teardownGlobals(); - - $this->assertEquals( $result, $out, $desc ); - } - - /** - * Run a fuzz test series - * Draw input from a set of test files - * - * @todo fixme Needs some work to not eat memory until the world explodes - * - * @group ParserFuzz - */ - public function testFuzzTests() { - global $wgParserTestFiles; - - $files = $wgParserTestFiles; - - if ( $this->getCliArg( 'file=' ) ) { - $files = array( $this->getCliArg( 'file=' ) ); - } - - $dict = $this->getFuzzInput( $files ); - $dictSize = strlen( $dict ); - $logMaxLength = log( $this->maxFuzzTestLength ); - - ini_set( 'memory_limit', $this->memoryLimit * 1048576 ); - - $user = new User; - $opts = ParserOptions::newFromUser( $user ); - $title = Title::makeTitle( NS_MAIN, 'Parser_test' ); - - $id = 1; - - while ( true ) { - - // Generate test input - mt_srand( ++$this->fuzzSeed ); - $totalLength = mt_rand( 1, $this->maxFuzzTestLength ); - $input = ''; - - while ( strlen( $input ) < $totalLength ) { - $logHairLength = mt_rand( 0, 1000000 ) / 1000000 * $logMaxLength; - $hairLength = min( intval( exp( $logHairLength ) ), $dictSize ); - $offset = mt_rand( 0, $dictSize - $hairLength ); - $input .= substr( $dict, $offset, $hairLength ); - } - - $this->setupGlobals(); - $parser = $this->getParser(); - - // Run the test - try { - $parser->parse( $input, $title, $opts ); - $this->assertTrue( true, "Test $id, fuzz seed {$this->fuzzSeed}" ); - } catch ( Exception $exception ) { - $input_dump = sprintf( "string(%d) \"%s\"\n", strlen( $input ), $input ); - - $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(); - $parser->__destruct(); - - if ( $id % 100 == 0 ) { - $usage = intval( memory_get_usage( true ) / $this->memoryLimit / 1048576 * 100 ); - //echo "{$this->fuzzSeed}: $numSuccess/$numTotal (mem: $usage%)\n"; - if ( $usage > 90 ) { - $ret = "Out of memory:\n"; - $memStats = $this->getMemoryBreakdown(); - - foreach ( $memStats as $name => $usage ) { - $ret .= "$name: $usage\n"; - } - - throw new MWException( $ret ); - } - } - - $id++; - } - } - - //Various getter functions - - /** - * Get an input dictionary from a set of parser test files - */ - function getFuzzInput( $filenames ) { - $dict = ''; - - foreach ( $filenames as $filename ) { - $contents = file_get_contents( $filename ); - preg_match_all( '/!!\s*input\n(.*?)\n!!\s*result/s', $contents, $matches ); - - foreach ( $matches[1] as $match ) { - $dict .= $match . "\n"; - } - } - - return $dict; - } - - /** - * Get a memory usage breakdown - */ - function getMemoryBreakdown() { - $memStats = array(); - - foreach ( $GLOBALS as $name => $value ) { - $memStats['$' . $name] = strlen( serialize( $value ) ); - } - - $classes = get_declared_classes(); - - foreach ( $classes as $class ) { - $rc = new ReflectionClass( $class ); - $props = $rc->getStaticProperties(); - $memStats[$class] = strlen( serialize( $props ) ); - $methods = $rc->getMethods(); - - foreach ( $methods as $method ) { - $memStats[$class] += strlen( serialize( $method->getStaticVariables() ) ); - } - } - - $functions = get_defined_functions(); - - foreach ( $functions['user'] as $function ) { - $rf = new ReflectionFunction( $function ); - $memStats["$function()"] = strlen( serialize( $rf->getStaticVariables() ) ); - } - - asort( $memStats ); - - return $memStats; - } - - /** - * Get a Parser object - */ - function getParser( $preprocessor = null ) { - global $wgParserConf; - - $class = $wgParserConf['class']; - $parser = new $class( array( 'preprocessorClass' => $preprocessor ) + $wgParserConf ); - - wfRunHooks( 'ParserTestParser', array( &$parser ) ); - - return $parser; - } - - //Various action functions - - public function addArticle( $name, $text, $line ) { - self::$articles[$name] = array( $text, $line ); - } - - public function publishTestArticles() { - if ( empty( self::$articles ) ) { - return; - } - - foreach ( self::$articles as $name => $info ) { - list( $text, $line ) = $info; - ParserTest::addArticle( $name, $text, $line, 'ignoreduplicate' ); - } - } - - /** - * Steal a callback function from the primary parser, save it for - * application to our scary parser. If the hook is not installed, - * abort processing of this file. - * - * @param $name String - * @return Bool true if tag hook is present - */ - public function requireHook( $name ) { - global $wgParser; - $wgParser->firstCallInit(); // make sure hooks are loaded. - return isset( $wgParser->mTagHooks[$name] ); - } - - public function requireFunctionHook( $name ) { - global $wgParser; - $wgParser->firstCallInit(); // make sure hooks are loaded. - return isset( $wgParser->mFunctionHooks[$name] ); - } - - //Various "cleanup" functions - - /** - * Run the "tidy" command on text if the $wgUseTidy - * global is true - * - * @param $text String: the text to tidy - * @return String - */ - protected function tidy( $text ) { - global $wgUseTidy; - - if ( $wgUseTidy ) { - $text = MWTidy::tidy( $text ); - } - - return $text; - } - - /** - * Remove last character if it is a newline - */ - public function removeEndingNewline( $s ) { - if ( substr( $s, -1 ) === "\n" ) { - return substr( $s, 0, -1 ); - } else { - return $s; - } - } - - //Test options parser functions - - protected function parseOptions( $instring ) { - $opts = array(); - // foo - // foo=bar - // foo="bar baz" - // foo=[[bar baz]] - // foo=bar,"baz quux" - $regex = '/\b - ([\w-]+) # Key - \b - (?:\s* - = # First sub-value - \s* - ( - " - [^"]* # Quoted val - " - | - \[\[ - [^]]* # Link target - \]\] - | - [\w-]+ # Plain word - ) - (?:\s* - , # Sub-vals 1..N - \s* - ( - "[^"]*" # Quoted val - | - \[\[[^]]*\]\] # Link target - | - [\w-]+ # Plain word - ) - )* - )? - /x'; - - if ( preg_match_all( $regex, $instring, $matches, PREG_SET_ORDER ) ) { - foreach ( $matches as $bits ) { - array_shift( $bits ); - $key = strtolower( array_shift( $bits ) ); - if ( count( $bits ) == 0 ) { - $opts[$key] = true; - } elseif ( count( $bits ) == 1 ) { - $opts[$key] = $this->cleanupOption( array_shift( $bits ) ); - } else { - // Array! - $opts[$key] = array_map( array( $this, 'cleanupOption' ), $bits ); - } - } - } - - return $opts; - } - - protected function cleanupOption( $opt ) { - if ( substr( $opt, 0, 1 ) == '"' ) { - return substr( $opt, 1, -1 ); - } - - if ( substr( $opt, 0, 2 ) == '[[' ) { - return substr( $opt, 2, -2 ); - } - - return $opt; - } - - /** - * 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 $default Mixed: default value returned if not found - */ - protected static function getOptionValue( $key, $opts, $default ) { - $key = strtolower( $key ); - - if ( isset( $opts[$key] ) ) { - return $opts[$key]; - } else { - return $default; - } - } -} diff --git a/tests/phpunit/includes/parser/ParserMethodsTest.php b/tests/phpunit/includes/parser/ParserMethodsTest.php deleted file mode 100644 index e5c5cb21..00000000 --- a/tests/phpunit/includes/parser/ParserMethodsTest.php +++ /dev/null @@ -1,95 +0,0 @@ -<?php - -class ParserMethodsTest extends MediaWikiLangTestCase { - - public static function providePreSaveTransform() { - return array( - array( 'hello this is ~~~', - "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]", - ), - array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>', - 'hello \'\'this\'\' is <nowiki>~~~</nowiki>', - ), - ); - } - - /** - * @dataProvider providePreSaveTransform - * @covers Parser::preSaveTransform - */ - public function testPreSaveTransform( $text, $expected ) { - global $wgParser; - - $title = Title::newFromText( str_replace( '::', '__', __METHOD__ ) ); - $user = new User(); - $user->setName( "127.0.0.1" ); - $popts = ParserOptions::newFromUser( $user ); - $text = $wgParser->preSaveTransform( $text, $title, $user, $popts ); - - $this->assertEquals( $expected, $text ); - } - - /** - * @covers Parser::callParserFunction - */ - public function testCallParserFunction() { - global $wgParser; - - // Normal parses test passing PPNodes. Test passing an array. - $title = Title::newFromText( str_replace( '::', '__', __METHOD__ ) ); - $wgParser->startExternalParse( $title, new ParserOptions(), Parser::OT_HTML ); - $frame = $wgParser->getPreprocessor()->newFrame(); - $ret = $wgParser->callParserFunction( $frame, '#tag', - array( 'pre', 'foo', 'style' => 'margin-left: 1.6em' ) - ); - $ret['text'] = $wgParser->mStripState->unstripBoth( $ret['text'] ); - $this->assertSame( array( - 'found' => true, - 'text' => '<pre style="margin-left: 1.6em">foo</pre>', - ), $ret, 'callParserFunction works for {{#tag:pre|foo|style=margin-left: 1.6em}}' ); - } - - /** - * @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 deleted file mode 100644 index c73666da..00000000 --- a/tests/phpunit/includes/parser/ParserOutputTest.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php - -class ParserOutputTest extends MediaWikiTestCase { - - public static function provideIsLinkInternal() { - return array( - // Different domains - array( false, 'http://example.org', 'http://mediawiki.org' ), - // Same domains - array( true, 'http://example.org', 'http://example.org' ), - array( true, 'https://example.org', 'https://example.org' ), - array( true, '//example.org', '//example.org' ), - // Same domain different cases - array( true, 'http://example.org', 'http://EXAMPLE.ORG' ), - // Paths, queries, and fragments are not relevant - array( true, 'http://example.org', 'http://example.org/wiki/Main_Page' ), - array( true, 'http://example.org', 'http://example.org?my=query' ), - array( true, 'http://example.org', 'http://example.org#its-a-fragment' ), - // Different protocols - array( false, 'http://example.org', 'https://example.org' ), - array( false, 'https://example.org', 'http://example.org' ), - // Protocol relative servers always match http and https links - array( true, '//example.org', 'http://example.org' ), - array( true, '//example.org', 'https://example.org' ), - // But they don't match strange things like this - array( false, '//example.org', 'irc://example.org' ), - ); - } - - /** - * Test to make sure ParserOutput::isLinkInternal behaves properly - * @dataProvider provideIsLinkInternal - * @covers ParserOutput::isLinkInternal - */ - 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(); - - $po->setExtensionData( "one", "Foo" ); - - $this->assertEquals( "Foo", $po->getExtensionData( "one" ) ); - $this->assertNull( $po->getExtensionData( "spam" ) ); - - $po->setExtensionData( "two", "Bar" ); - $this->assertEquals( "Foo", $po->getExtensionData( "one" ) ); - $this->assertEquals( "Bar", $po->getExtensionData( "two" ) ); - - $po->setExtensionData( "one", null ); - $this->assertNull( $po->getExtensionData( "one" ) ); - $this->assertEquals( "Bar", $po->getExtensionData( "two" ) ); - } -} diff --git a/tests/phpunit/includes/parser/ParserPreloadTest.php b/tests/phpunit/includes/parser/ParserPreloadTest.php deleted file mode 100644 index d12fee36..00000000 --- a/tests/phpunit/includes/parser/ParserPreloadTest.php +++ /dev/null @@ -1,80 +0,0 @@ -<?php -/** - * Basic tests for Parser::getPreloadText - * @author Antoine Musso - */ -class ParserPreloadTest extends MediaWikiTestCase { - /** - * @var Parser - */ - private $testParser; - /** - * @var ParserOptions - */ - private $testParserOptions; - /** - * @var Title - */ - private $title; - - protected function setUp() { - global $wgContLang; - - parent::setUp(); - $this->testParserOptions = ParserOptions::newFromUserAndLang( new User, $wgContLang ); - - $this->testParser = new Parser(); - $this->testParser->Options( $this->testParserOptions ); - $this->testParser->clearState(); - - $this->title = Title::newFromText( 'Preload Test' ); - } - - protected function tearDown() { - parent::tearDown(); - - unset( $this->testParser ); - unset( $this->title ); - } - - /** - * @covers Parser::getPreloadText - */ - public function testPreloadSimpleText() { - $this->assertPreloaded( 'simple', 'simple' ); - } - - /** - * @covers Parser::getPreloadText - */ - public function testPreloadedPreIsUnstripped() { - $this->assertPreloaded( - '<pre>monospaced</pre>', - '<pre>monospaced</pre>', - '<pre> in preloaded text must be unstripped (bug 27467)' - ); - } - - /** - * @covers Parser::getPreloadText - */ - public function testPreloadedNowikiIsUnstripped() { - $this->assertPreloaded( - '<nowiki>[[Dummy title]]</nowiki>', - '<nowiki>[[Dummy title]]</nowiki>', - '<nowiki> in preloaded text must be unstripped (bug 27467)' - ); - } - - protected function assertPreloaded( $expected, $text, $msg = '' ) { - $this->assertEquals( - $expected, - $this->testParser->getPreloadText( - $text, - $this->title, - $this->testParserOptions - ), - $msg - ); - } -} diff --git a/tests/phpunit/includes/parser/PreprocessorTest.php b/tests/phpunit/includes/parser/PreprocessorTest.php deleted file mode 100644 index 8aee937c..00000000 --- a/tests/phpunit/includes/parser/PreprocessorTest.php +++ /dev/null @@ -1,239 +0,0 @@ -<?php - -class PreprocessorTest extends MediaWikiTestCase { - protected $mTitle = 'Page title'; - protected $mPPNodeCount = 0; - /** - * @var ParserOptions - */ - protected $mOptions; - /** - * @var Preprocessor - */ - protected $mPreprocessor; - - protected function setUp() { - global $wgParserConf, $wgContLang; - parent::setUp(); - $this->mOptions = ParserOptions::newFromUserAndLang( new User, $wgContLang ); - $name = isset( $wgParserConf['preprocessorClass'] ) ? $wgParserConf['preprocessorClass'] : 'Preprocessor_DOM'; - - $this->mPreprocessor = new $name( $this ); - } - - function getStripList() { - return array( 'gallery', 'display map' /* Used by Maps, see r80025 CR */, '/foo' ); - } - - public static function provideCases() { - return array( - array( "Foo", "<root>Foo</root>" ), - array( "<!-- Foo -->", "<root><comment><!-- Foo --></comment></root>" ), - array( "<!-- Foo --><!-- Bar -->", "<root><comment><!-- Foo --></comment><comment><!-- Bar --></comment></root>" ), - array( "<!-- Foo --> <!-- Bar -->", "<root><comment><!-- Foo --></comment> <comment><!-- Bar --></comment></root>" ), - array( "<!-- Foo --> \n <!-- Bar -->", "<root><comment><!-- Foo --></comment> \n <comment><!-- Bar --></comment></root>" ), - array( "<!-- Foo --> \n <!-- Bar -->\n", "<root><comment><!-- Foo --></comment> \n<comment> <!-- Bar -->\n</comment></root>" ), - array( "<!-- Foo --> <!-- Bar -->\n", "<root><comment><!-- Foo --></comment> <comment><!-- Bar --></comment>\n</root>" ), - array( "<!-->Bar", "<root><comment><!-->Bar</comment></root>" ), - array( "<!-- Comment -- comment", "<root><comment><!-- Comment -- comment</comment></root>" ), - array( "== Foo ==\n <!-- Bar -->\n== Baz ==\n", "<root><h level=\"2\" i=\"1\">== Foo ==</h>\n<comment> <!-- Bar -->\n</comment><h level=\"2\" i=\"2\">== Baz ==</h>\n</root>" ), - array( "<gallery/>", "<root><ext><name>gallery</name><attr></attr></ext></root>" ), - array( "Foo <gallery/> Bar", "<root>Foo <ext><name>gallery</name><attr></attr></ext> Bar</root>" ), - array( "<gallery></gallery>", "<root><ext><name>gallery</name><attr></attr><inner></inner><close></gallery></close></ext></root>" ), - array( "<foo> <gallery></gallery>", "<root><foo> <ext><name>gallery</name><attr></attr><inner></inner><close></gallery></close></ext></root>" ), - array( "<foo> <gallery><gallery></gallery>", "<root><foo> <ext><name>gallery</name><attr></attr><inner><gallery></inner><close></gallery></close></ext></root>" ), - array( "<noinclude> Foo bar </noinclude>", "<root><ignore><noinclude></ignore> Foo bar <ignore></noinclude></ignore></root>" ), - array( "<noinclude>\n{{Foo}}\n</noinclude>", "<root><ignore><noinclude></ignore>\n<template lineStart=\"1\"><title>Foo</title></template>\n<ignore></noinclude></ignore></root>" ), - array( "<noinclude>\n{{Foo}}\n</noinclude>\n", "<root><ignore><noinclude></ignore>\n<template lineStart=\"1\"><title>Foo</title></template>\n<ignore></noinclude></ignore>\n</root>" ), - array( "<gallery>foo bar", "<root><ext><name>gallery</name><attr></attr><inner>foo bar</inner></ext></root>" ), - array( "<{{foo}}>", "<root><<template><title>foo</title></template>></root>" ), - array( "<{{{foo}}}>", "<root><<tplarg><title>foo</title></tplarg>></root>" ), - array( "<gallery></gallery</gallery>", "<root><ext><name>gallery</name><attr></attr><inner></gallery</inner><close></gallery></close></ext></root>" ), - array( "=== Foo === ", "<root><h level=\"3\" i=\"1\">=== Foo === </h></root>" ), - array( "==<!-- -->= Foo === ", "<root><h level=\"2\" i=\"1\">==<comment><!-- --></comment>= Foo === </h></root>" ), - array( "=== Foo ==<!-- -->= ", "<root><h level=\"1\" i=\"1\">=== Foo ==<comment><!-- --></comment>= </h></root>" ), - array( "=== Foo ===<!-- -->\n", "<root><h level=\"3\" i=\"1\">=== Foo ===<comment><!-- --></comment></h>\n</root>" ), - array( "=== Foo ===<!-- --> <!-- -->\n", "<root><h level=\"3\" i=\"1\">=== Foo ===<comment><!-- --></comment> <comment><!-- --></comment></h>\n</root>" ), - array( "== Foo ==\n== Bar == \n", "<root><h level=\"2\" i=\"1\">== Foo ==</h>\n<h level=\"2\" i=\"2\">== Bar == </h>\n</root>" ), - array( "===========", "<root><h level=\"5\" i=\"1\">===========</h></root>" ), - array( "Foo\n=\n==\n=\n", "<root>Foo\n=\n==\n=\n</root>" ), - array( "{{Foo}}", "<root><template><title>Foo</title></template></root>" ), - array( "\n{{Foo}}", "<root>\n<template lineStart=\"1\"><title>Foo</title></template></root>" ), - array( "{{Foo|bar}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part></template></root>" ), - array( "{{Foo|bar}}a", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part></template>a</root>" ), - array( "{{Foo|bar|baz}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name index=\"2\" /><value>baz</value></part></template></root>" ), - array( "{{Foo|1=bar}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part></template></root>" ), - array( "{{Foo|=bar}}", "<root><template><title>Foo</title><part><name></name>=<value>bar</value></part></template></root>" ), - array( "{{Foo|bar=baz}}", "<root><template><title>Foo</title><part><name>bar</name>=<value>baz</value></part></template></root>" ), - array( "{{Foo|{{bar}}=baz}}", "<root><template><title>Foo</title><part><name><template><title>bar</title></template></name>=<value>baz</value></part></template></root>" ), - array( "{{Foo|1=bar|baz}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part><part><name index=\"1\" /><value>baz</value></part></template></root>" ), - array( "{{Foo|1=bar|2=baz}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part><part><name>2</name>=<value>baz</value></part></template></root>" ), - array( "{{Foo|bar|foo=baz}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name>foo</name>=<value>baz</value></part></template></root>" ), - array( "{{{1}}}", "<root><tplarg><title>1</title></tplarg></root>" ), - array( "{{{1|}}}", "<root><tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg></root>" ), - array( "{{{Foo}}}", "<root><tplarg><title>Foo</title></tplarg></root>" ), - array( "{{{Foo|}}}", "<root><tplarg><title>Foo</title><part><name index=\"1\" /><value></value></part></tplarg></root>" ), - array( "{{{Foo|bar|baz}}}", "<root><tplarg><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name index=\"2\" /><value>baz</value></part></tplarg></root>" ), - array( "{<!-- -->{Foo}}", "<root>{<comment><!-- --></comment>{Foo}}</root>" ), - array( "{{{{Foobar}}}}", "<root>{<tplarg><title>Foobar</title></tplarg>}</root>" ), - array( "{{{ {{Foo}} }}}", "<root><tplarg><title> <template><title>Foo</title></template> </title></tplarg></root>" ), - array( "{{ {{{Foo}}} }}", "<root><template><title> <tplarg><title>Foo</title></tplarg> </title></template></root>" ), - array( "{{{{{Foo}}}}}", "<root><template><title><tplarg><title>Foo</title></tplarg></title></template></root>" ), - array( "{{{{{Foo}} }}}", "<root><tplarg><title><template><title>Foo</title></template> </title></tplarg></root>" ), - array( "{{{{{{Foo}}}}}}", "<root><tplarg><title><tplarg><title>Foo</title></tplarg></title></tplarg></root>" ), - array( "{{{{{{Foo}}}}}", "<root>{<template><title><tplarg><title>Foo</title></tplarg></title></template></root>" ), - array( "[[[Foo]]", "<root>[[[Foo]]</root>" ), - array( "{{Foo|[[[[bar]]|baz]]}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>[[[[bar]]|baz]]</value></part></template></root>" ), // This test is important, since it means the difference between having the [[ rule stacked or not - array( "{{Foo|[[[[bar]|baz]]}}", "<root>{{Foo|[[[[bar]|baz]]}}</root>" ), - array( "{{Foo|Foo [[[[bar]|baz]]}}", "<root>{{Foo|Foo [[[[bar]|baz]]}}</root>" ), - array( "Foo <display map>Bar</display map >Baz", "<root>Foo <ext><name>display map</name><attr></attr><inner>Bar</inner><close></display map ></close></ext>Baz</root>" ), - array( "Foo <display map foo>Bar</display map >Baz", "<root>Foo <ext><name>display map</name><attr> foo</attr><inner>Bar</inner><close></display map ></close></ext>Baz</root>" ), - array( "Foo <gallery bar=\"baz\" />", "<root>Foo <ext><name>gallery</name><attr> bar="baz" </attr></ext></root>" ), - array( "Foo <gallery bar=\"1\" baz=2 />", "<root>Foo <ext><name>gallery</name><attr> bar="1" baz=2 </attr></ext></root>" ), - array( "</foo>Foo<//foo>", "<root><ext><name>/foo</name><attr></attr><inner>Foo</inner><close><//foo></close></ext></root>" ), # Worth blacklisting IMHO - array( "{{#ifexpr: ({{{1|1}}} = 2) | Foo | Bar }}", "<root><template><title>#ifexpr: (<tplarg><title>1</title><part><name index=\"1\" /><value>1</value></part></tplarg> = 2) </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> Bar </value></part></template></root>" ), - array( "{{#if: {{{1|}}} | Foo | {{Bar}} }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> <template><title>Bar</title></template> </value></part></template></root>" ), - array( "{{#if: {{{1|}}} | Foo | [[Bar]] }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> [[Bar]] </value></part></template></root>" ), - array( "{{#if: {{{1|}}} | [[Foo]] | Bar }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> [[Foo]] </value></part><part><name index=\"2\" /><value> Bar </value></part></template></root>" ), - array( "{{#if: {{{1|}}} | 1 | {{#if: {{{1|}}} | 2 | 3 }} }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> 1 </value></part><part><name index=\"2\" /><value> <template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> 2 </value></part><part><name index=\"2\" /><value> 3 </value></part></template> </value></part></template></root>" ), - array( "{{ {{Foo}}", "<root>{{ <template><title>Foo</title></template></root>" ), - array( "{{Foobar {{Foo}} {{Bar}} {{Baz}} ", "<root>{{Foobar <template><title>Foo</title></template> <template><title>Bar</title></template> <template><title>Baz</title></template> </root>" ), - array( "[[Foo]] |", "<root>[[Foo]] |</root>" ), - array( "{{Foo|Bar|", "<root>{{Foo|Bar|</root>" ), - array( "[[Foo]", "<root>[[Foo]</root>" ), - array( "[[Foo|Bar]", "<root>[[Foo|Bar]</root>" ), - array( "{{Foo| [[Bar] }}", "<root>{{Foo| [[Bar] }}</root>" ), - array( "{{Foo| [[Bar|Baz] }}", "<root>{{Foo| [[Bar|Baz] }}</root>" ), - array( "{{Foo|bar=[[baz]}}", "<root>{{Foo|bar=[[baz]}}</root>" ), - array( "{{foo|", "<root>{{foo|</root>" ), - array( "{{foo|}", "<root>{{foo|}</root>" ), - array( "{{foo|} }}", "<root><template><title>foo</title><part><name index=\"1\" /><value>} </value></part></template></root>" ), - array( "{{foo|bar=|}", "<root>{{foo|bar=|}</root>" ), - array( "{{Foo|} Bar=", "<root>{{Foo|} Bar=</root>" ), - array( "{{Foo|} Bar=}}", "<root><template><title>Foo</title><part><name>} Bar</name>=<value></value></part></template></root>" ), - /* array( file_get_contents( __DIR__ . '/QuoteQuran.txt' ), file_get_contents( __DIR__ . '/QuoteQuranExpanded.txt' ) ), */ - ); - } - - /** - * Get XML preprocessor tree from the preprocessor (which may not be the - * native XML-based one). - * - * @param string $wikiText - * @return string - */ - protected function preprocessToXml( $wikiText ) { - if ( method_exists( $this->mPreprocessor, 'preprocessToXml' ) ) { - return $this->normalizeXml( $this->mPreprocessor->preprocessToXml( $wikiText ) ); - } - - $dom = $this->mPreprocessor->preprocessToObj( $wikiText ); - if ( is_callable( array( $dom, 'saveXML' ) ) ) { - return $dom->saveXML(); - } else { - return $this->normalizeXml( $dom->__toString() ); - } - } - - /** - * Normalize XML string to the form that a DOMDocument saves out. - * - * @param string $xml - * @return string - */ - protected function normalizeXml( $xml ) { - return preg_replace( '!<([a-z]+)/>!', '<$1></$1>', str_replace( ' />', '/>', $xml ) ); - } - - /** - * @dataProvider provideCases - * @covers Preprocessor_DOM::preprocessToXml - */ - public function testPreprocessorOutput( $wikiText, $expectedXml ) { - $this->assertEquals( $this->normalizeXml( $expectedXml ), $this->preprocessToXml( $wikiText ) ); - } - - /** - * These are more complex test cases taken out of wiki articles. - */ - 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 - array( "All_system_messages" ), # http://tl.wiktionary.org/w/index.php?title=Suleras:All_system_messages&oldid=2765 GPL text generated by MediaWiki - array( "Fundraising" ), # http://tl.wiktionary.org/w/index.php?title=MediaWiki:Sitenotice&oldid=5716 GFDL + CC-BY-SA, copied there by Sky Harbor. - array( "NestedTemplates" ), # bug 27936 - ); - } - - /** - * @dataProvider provideFiles - * @covers Preprocessor_DOM::preprocessToXml - */ - public function testPreprocessorOutputFiles( $filename ) { - $folder = __DIR__ . "/../../../parser/preprocess"; - $wikiText = file_get_contents( "$folder/$filename.txt" ); - $output = $this->preprocessToXml( $wikiText ); - - $expectedFilename = "$folder/$filename.expected"; - if ( file_exists( $expectedFilename ) ) { - $expectedXml = $this->normalizeXml( file_get_contents( $expectedFilename ) ); - $this->assertEquals( $expectedXml, $output ); - } else { - $tempFilename = tempnam( $folder, "$filename." ); - file_put_contents( $tempFilename, $output ); - $this->markTestIncomplete( "File $expectedFilename missing. Output stored as $tempFilename" ); - } - } - - /** - * Tests from Bug 28642 · https://bugzilla.wikimedia.org/28642 - */ - 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>" ), - 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>" ), - 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>" ), - 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>" ), - array( "== h == <!--c1--> <!--c2--> ", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment> <comment><!--c2--></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--> <!--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--><!--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--><!--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--> <!--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--> <!--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 == 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>" ), - ); - } - - /** - * @dataProvider provideHeadings - * @covers Preprocessor_DOM::preprocessToXml - */ - 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 deleted file mode 100644 index 61cbe45d..00000000 --- a/tests/phpunit/includes/parser/TagHooksTest.php +++ /dev/null @@ -1,82 +0,0 @@ -<?php - -/** - * @group Parser - */ -class TagHookTest extends MediaWikiTestCase { - public static function provideValidNames() { - return array( array( 'foo' ), array( 'foo-bar' ), array( 'foo_bar' ), array( 'FOO-BAR' ), array( 'foo bar' ) ); - } - - public static function provideBadNames() { - return array( array( "foo<bar" ), array( "foo>bar" ), array( "foo\nbar" ), array( "foo\rbar" ) ); - } - - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( 'wgAlwaysUseTidy', false ); - } - - /** - * @dataProvider provideValidNames - */ - public function testTagHooks( $tag ) { - global $wgParserConf, $wgContLang; - $parser = new Parser( $wgParserConf ); - - $parser->setHook( $tag, array( $this, 'tagCallback' ) ); - $parserOutput = $parser->parse( "Foo<$tag>Bar</$tag>Baz", Title::newFromText( 'Test' ), ParserOptions::newFromUserAndLang( new User, $wgContLang ) ); - $this->assertEquals( "<p>FooOneBaz\n</p>", $parserOutput->getText() ); - - $parser->mPreprocessor = null; # Break the Parser <-> Preprocessor cycle - } - - /** - * @dataProvider provideBadNames - * @expectedException MWException - */ - public function testBadTagHooks( $tag ) { - global $wgParserConf, $wgContLang; - $parser = new Parser( $wgParserConf ); - - $parser->setHook( $tag, array( $this, 'tagCallback' ) ); - $parser->parse( "Foo<$tag>Bar</$tag>Baz", Title::newFromText( 'Test' ), ParserOptions::newFromUserAndLang( new User, $wgContLang ) ); - $this->fail( 'Exception not thrown.' ); - } - - /** - * @dataProvider provideValidNames - */ - public function testFunctionTagHooks( $tag ) { - global $wgParserConf, $wgContLang; - $parser = new Parser( $wgParserConf ); - - $parser->setFunctionTagHook( $tag, array( $this, 'functionTagCallback' ), 0 ); - $parserOutput = $parser->parse( "Foo<$tag>Bar</$tag>Baz", Title::newFromText( 'Test' ), ParserOptions::newFromUserAndLang( new User, $wgContLang ) ); - $this->assertEquals( "<p>FooOneBaz\n</p>", $parserOutput->getText() ); - - $parser->mPreprocessor = null; # Break the Parser <-> Preprocessor cycle - } - - /** - * @dataProvider provideBadNames - * @expectedException MWException - */ - public function testBadFunctionTagHooks( $tag ) { - global $wgParserConf, $wgContLang; - $parser = new Parser( $wgParserConf ); - - $parser->setFunctionTagHook( $tag, array( $this, 'functionTagCallback' ), SFH_OBJECT_ARGS ); - $parser->parse( "Foo<$tag>Bar</$tag>Baz", Title::newFromText( 'Test' ), ParserOptions::newFromUserAndLang( new User, $wgContLang ) ); - $this->fail( 'Exception not thrown.' ); - } - - function tagCallback( $text, $params, $parser ) { - return str_rot13( $text ); - } - - function functionTagCallback( &$parser, $frame, $code, $attribs ) { - return str_rot13( $code ); - } -} diff --git a/tests/phpunit/includes/parser/TidyTest.php b/tests/phpunit/includes/parser/TidyTest.php deleted file mode 100644 index 57a88b9d..00000000 --- a/tests/phpunit/includes/parser/TidyTest.php +++ /dev/null @@ -1,44 +0,0 @@ -<?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 deleted file mode 100644 index 87067038..00000000 --- a/tests/phpunit/includes/search/SearchEngineTest.php +++ /dev/null @@ -1,176 +0,0 @@ -<?php - -/** - * @group Search - * @group Database - */ -class SearchEngineTest extends MediaWikiLangTestCase { - protected $search, $pageList; - - /** - * Checks for database type & version. - * Will skip current test if DB does not support search. - */ - protected function setUp() { - parent::setUp(); - - // Search tests require MySQL or SQLite with FTS - # Get database type and version - $dbType = $this->db->getType(); - $dbSupported = - ( $dbType === 'mysql' ) - || ( $dbType === 'sqlite' && $this->db->getFulltextSearchModule() == 'FTS3' ); - - if ( !$dbSupported ) { - $this->markTestSkipped( "MySQL or SQLite with FTS3 only" ); - } - - $searchType = $this->db->getSearchEngine(); - $this->search = new $searchType( $this->db ); - } - - protected function tearDown() { - unset( $this->search ); - - parent::tearDown(); - } - - function pageExists( $title ) { - return false; - } - - function addDBData() { - if ( $this->pageExists( 'Not_Main_Page' ) ) { - return; - } - - if ( !$this->isWikitextNS( NS_MAIN ) ) { - // @todo cover the case of non-wikitext content in the main namespace - return; - } - - $this->insertPage( "Not_Main_Page", "This is not a main page", 0 ); - $this->insertPage( 'Talk:Not_Main_Page', 'This is not a talk page to the main page, see [[smithee]]', 1 ); - $this->insertPage( 'Smithee', 'A smithee is one who smiths. See also [[Alan Smithee]]', 0 ); - $this->insertPage( 'Talk:Smithee', 'This article sucks.', 1 ); - $this->insertPage( 'Unrelated_page', 'Nothing in this page is about the S word.', 0 ); - $this->insertPage( 'Another_page', 'This page also is unrelated.', 0 ); - $this->insertPage( 'Help:Help', 'Help me!', 4 ); - $this->insertPage( 'Thppt', 'Blah blah', 0 ); - $this->insertPage( 'Alan_Smithee', 'yum', 0 ); - $this->insertPage( 'Pages', 'are\'food', 0 ); - $this->insertPage( 'HalfOneUp', 'AZ', 0 ); - $this->insertPage( 'FullOneUp', 'AZ', 0 ); - $this->insertPage( 'HalfTwoLow', 'az', 0 ); - $this->insertPage( 'FullTwoLow', 'az', 0 ); - $this->insertPage( 'HalfNumbers', '1234567890', 0 ); - $this->insertPage( 'FullNumbers', '1234567890', 0 ); - $this->insertPage( 'DomainName', 'example.com', 0 ); - } - - function fetchIds( $results ) { - if ( !$this->isWikitextNS( NS_MAIN ) ) { - $this->markTestIncomplete( __CLASS__ . " does no yet support non-wikitext content " - . "in the main namespace" ); - } - - $this->assertTrue( is_object( $results ) ); - - $matches = array(); - $row = $results->next(); - while ( $row ) { - $matches[] = $row->getTitle()->getPrefixedText(); - $row = $results->next(); - } - $results->free(); - # Search is not guaranteed to return results in a certain order; - # sort them numerically so we will compare simply that we received - # the expected matches. - sort( $matches ); - - return $matches; - } - - /** - * Insert a new page - * - * @param $pageName String: page name - * @param $text String: page's content - * @param $n Integer: unused - */ - function insertPage( $pageName, $text, $ns ) { - $title = Title::newFromText( $pageName, $ns ); - - $user = User::newFromName( 'WikiSysop' ); - $comment = 'Search Test'; - - // avoid memory leak...? - LinkCache::singleton()->clear(); - - $page = WikiPage::factory( $title ); - $page->doEditContent( ContentHandler::makeContent( $text, $title ), $comment, 0, false, $user ); - - $this->pageList[] = array( $title, $page->getId() ); - - return true; - } - - public function testFullWidth() { - $this->assertEquals( - array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), - $this->fetchIds( $this->search->searchText( 'AZ' ) ), - "Search for normalized from Half-width Upper" ); - $this->assertEquals( - array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), - $this->fetchIds( $this->search->searchText( 'az' ) ), - "Search for normalized from Half-width Lower" ); - $this->assertEquals( - array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), - $this->fetchIds( $this->search->searchText( 'AZ' ) ), - "Search for normalized from Full-width Upper" ); - $this->assertEquals( - array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), - $this->fetchIds( $this->search->searchText( 'az' ) ), - "Search for normalized from Full-width Lower" ); - } - - public function testTextSearch() { - $this->assertEquals( - array( 'Smithee' ), - $this->fetchIds( $this->search->searchText( 'smithee' ) ), - "Plain search failed" ); - } - - public function testTextPowerSearch() { - $this->search->setNamespaces( array( 0, 1, 4 ) ); - $this->assertEquals( - array( - 'Smithee', - 'Talk:Not Main Page', - ), - $this->fetchIds( $this->search->searchText( 'smithee' ) ), - "Power search failed" ); - } - - public function testTitleSearch() { - $this->assertEquals( - array( - 'Alan Smithee', - 'Smithee', - ), - $this->fetchIds( $this->search->searchTitle( 'smithee' ) ), - "Title search failed" ); - } - - public function testTextTitlePowerSearch() { - $this->search->setNamespaces( array( 0, 1, 4 ) ); - $this->assertEquals( - array( - 'Alan Smithee', - 'Smithee', - 'Talk:Smithee', - ), - $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 deleted file mode 100644 index 2f4fd501..00000000 --- a/tests/phpunit/includes/search/SearchUpdateTest.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php - -class MockSearch extends SearchEngine { - public static $id; - public static $title; - public static $text; - - public function __construct( $db ) { - } - - public function update( $id, $title, $text ) { - self::$id = $id; - self::$title = $title; - self::$text = $text; - } -} - -/** - * @group Search - * @group Database - */ -class SearchUpdateTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - $this->setMwGlobals( 'wgSearchType', 'MockSearch' ); - } - - function updateText( $text ) { - return trim( SearchUpdate::updateText( $text ) ); - } - - public function testUpdateText() { - $this->assertEquals( - 'test', - $this->updateText( '<div>TeSt</div>' ), - 'HTML stripped, text lowercased' - ); - - $this->assertEquals( - 'foo bar boz quux', - $this->updateText( <<<EOT -<table style="color:red; font-size:100px"> - <tr class="scary"><td><div>foo</div></td><tr>bar</td></tr> - <tr><td>boz</td><tr>quux</td></tr> -</table> -EOT - ), 'Stripping HTML tables' ); - - $this->assertEquals( - 'a b', - $this->updateText( 'a > b' ), - 'Handle unclosed tags' - ); - - $text = str_pad( "foo <barbarbar \n", 10000, 'x' ); - - $this->assertNotEquals( - '', - $this->updateText( $text ), - 'Bug 18609' - ); - } - - public function testBug32712() { - $text = "text „http://example.com“ text"; - $result = $this->updateText( $text ); - $processed = preg_replace( '/Q/u', 'Q', $result ); - $this->assertTrue( - $processed != '', - 'Link surrounded by unicode quotes should not fail UTF-8 validation' - ); - } -} diff --git a/tests/phpunit/includes/site/MediaWikiSiteTest.php b/tests/phpunit/includes/site/MediaWikiSiteTest.php deleted file mode 100644 index c5d52d33..00000000 --- a/tests/phpunit/includes/site/MediaWikiSiteTest.php +++ /dev/null @@ -1,90 +0,0 @@ -<?php - -/** - * Tests for the MediaWikiSite class. - * - * 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 - * @since 1.21 - * - * @ingroup Site - * @ingroup Test - * - * @group Site - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - */ -class MediaWikiSiteTest extends SiteTest { - - public function testNormalizePageTitle() { - $site = new MediaWikiSite(); - $site->setGlobalId( 'enwiki' ); - - //NOTE: this does not actually call out to the enwiki site to perform the normalization, - // but uses a local Title object to do so. This is hardcoded on SiteLink::normalizePageTitle - // for the case that MW_PHPUNIT_TEST is set. - $this->assertEquals( 'Foo', $site->normalizePageName( ' foo ' ) ); - } - - public function fileUrlProvider() { - return array( - // url, filepath, path arg, expected - array( 'https://en.wikipedia.org', '/w/$1', 'api.php', 'https://en.wikipedia.org/w/api.php' ), - array( 'https://en.wikipedia.org', '/w/', 'api.php', 'https://en.wikipedia.org/w/' ), - array( 'https://en.wikipedia.org', '/foo/page.php?name=$1', 'api.php', 'https://en.wikipedia.org/foo/page.php?name=api.php' ), - array( 'https://en.wikipedia.org', '/w/$1', '', 'https://en.wikipedia.org/w/' ), - array( 'https://en.wikipedia.org', '/w/$1', 'foo/bar/api.php', 'https://en.wikipedia.org/w/foo/bar/api.php' ), - ); - } - - /** - * @dataProvider fileUrlProvider - * @covers MediaWikiSite::getFileUrl - */ - public function testGetFileUrl( $url, $filePath, $pathArgument, $expected ) { - $site = new MediaWikiSite(); - $site->setFilePath( $url . $filePath ); - - $this->assertEquals( $expected, $site->getFileUrl( $pathArgument ) ); - } - - public static function provideGetPageUrl() { - return array( - // path, page, expected substring - array( 'http://acme.test/wiki/$1', 'Berlin', '/wiki/Berlin' ), - array( 'http://acme.test/wiki/', 'Berlin', '/wiki/' ), - array( 'http://acme.test/w/index.php?title=$1', 'Berlin', '/w/index.php?title=Berlin' ), - array( 'http://acme.test/wiki/$1', '', '/wiki/' ), - array( 'http://acme.test/wiki/$1', 'Berlin/sub page', '/wiki/Berlin/sub_page' ), - array( 'http://acme.test/wiki/$1', 'Cork (city) ', '/Cork_(city)' ), - array( 'http://acme.test/wiki/$1', 'M&M', '/wiki/M%26M' ), - ); - } - - /** - * @dataProvider provideGetPageUrl - * @covers MediaWikiSite::getPageUrl - */ - public function testGetPageUrl( $path, $page, $expected ) { - $site = new MediaWikiSite(); - $site->setLinkPath( $path ); - - $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 deleted file mode 100644 index 8af2fc1b..00000000 --- a/tests/phpunit/includes/site/SiteListTest.php +++ /dev/null @@ -1,197 +0,0 @@ -<?php - -/** - * Tests for the SiteList class. - * - * 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 - * @since 1.21 - * - * @ingroup Site - * @ingroup Test - * - * @group Site - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - */ -class SiteListTest extends MediaWikiTestCase { - - /** - * Returns instances of SiteList implementing objects. - * @return array - */ - public function siteListProvider() { - $sitesArrays = $this->siteArrayProvider(); - - $listInstances = array(); - - foreach ( $sitesArrays as $sitesArray ) { - $listInstances[] = new SiteList( $sitesArray[0] ); - } - - return $this->arrayWrap( $listInstances ); - } - - /** - * Returns arrays with instances of Site implementing objects. - * @return array - */ - public function siteArrayProvider() { - $sites = TestSites::getSites(); - - $siteArrays = array(); - - $siteArrays[] = $sites; - - $siteArrays[] = array( array_shift( $sites ) ); - - $siteArrays[] = array( array_shift( $sites ), array_shift( $sites ) ); - - return $this->arrayWrap( $siteArrays ); - } - - /** - * @dataProvider siteListProvider - * @param SiteList $sites - * @covers SiteList::isEmpty - */ - public function testIsEmpty( SiteList $sites ) { - $this->assertEquals( count( $sites ) === 0, $sites->isEmpty() ); - } - - /** - * @dataProvider siteListProvider - * @param SiteList $sites - * @covers SiteList::getSite - */ - public function testGetSiteByGlobalId( SiteList $sites ) { - if ( $sites->isEmpty() ) { - $this->assertTrue( true ); - } else { - /** - * @var Site $site - */ - foreach ( $sites as $site ) { - $this->assertEquals( $site, $sites->getSite( $site->getGlobalId() ) ); - } - } - } - - /** - * @dataProvider siteListProvider - * @param SiteList $sites - * @covers SiteList::getSiteByInternalId - */ - public function testGetSiteByInternalId( $sites ) { - /** - * @var Site $site - */ - foreach ( $sites as $site ) { - if ( is_integer( $site->getInternalId() ) ) { - $this->assertEquals( $site, $sites->getSiteByInternalId( $site->getInternalId() ) ); - } - } - - $this->assertTrue( true ); - } - - /** - * @dataProvider siteListProvider - * @param SiteList $sites - * @covers SiteList::hasSite - */ - public function testHasGlobalId( $sites ) { - $this->assertFalse( $sites->hasSite( 'non-existing-global-id' ) ); - $this->assertFalse( $sites->hasInternalId( 720101010 ) ); - - if ( !$sites->isEmpty() ) { - /** - * @var Site $site - */ - foreach ( $sites as $site ) { - $this->assertTrue( $sites->hasSite( $site->getGlobalId() ) ); - } - } - } - - /** - * @dataProvider siteListProvider - * @param SiteList $sites - * @covers SiteList::hasInternalId - */ - public function testHasInternallId( $sites ) { - /** - * @var Site $site - */ - foreach ( $sites as $site ) { - if ( is_integer( $site->getInternalId() ) ) { - $this->assertTrue( $site, $sites->hasInternalId( $site->getInternalId() ) ); - } - } - - $this->assertFalse( $sites->hasInternalId( -1 ) ); - } - - /** - * @dataProvider siteListProvider - * @param SiteList $sites - * @covers SiteList::getGlobalIdentifiers - */ - public function testGetGlobalIdentifiers( SiteList $sites ) { - $identifiers = $sites->getGlobalIdentifiers(); - - $this->assertTrue( is_array( $identifiers ) ); - - $expected = array(); - - /** - * @var Site $site - */ - foreach ( $sites as $site ) { - $expected[] = $site->getGlobalId(); - } - - $this->assertArrayEquals( $expected, $identifiers ); - } - - /** - * @dataProvider siteListProvider - * - * @since 1.21 - * - * @param SiteList $list - * @covers SiteList::getSerializationData - * @covers SiteList::unserialize - */ - public function testSerialization( SiteList $list ) { - $serialization = serialize( $list ); - /** - * @var SiteArray $copy - */ - $copy = unserialize( $serialization ); - - $this->assertArrayEquals( $list->getGlobalIdentifiers(), $copy->getGlobalIdentifiers() ); - - /** - * @var Site $site - */ - foreach ( $list as $site ) { - $this->assertTrue( $copy->hasInternalId( $site->getInternalId() ) ); - } - } -} diff --git a/tests/phpunit/includes/site/SiteSQLStoreTest.php b/tests/phpunit/includes/site/SiteSQLStoreTest.php deleted file mode 100644 index 6002c1a1..00000000 --- a/tests/phpunit/includes/site/SiteSQLStoreTest.php +++ /dev/null @@ -1,134 +0,0 @@ -<?php - -/** - * Tests for the SiteSQLStore class. - * - * 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 - * @since 1.21 - * - * @ingroup Site - * @ingroup Test - * - * @group Site - * @group Database - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - */ -class SiteSQLStoreTest extends MediaWikiTestCase { - - /** - * @covers SiteSQLStore::getSites - */ - public function testGetSites() { - $expectedSites = TestSites::getSites(); - TestSites::insertIntoDb(); - - $store = SiteSQLStore::newInstance(); - - $sites = $store->getSites(); - - $this->assertInstanceOf( 'SiteList', $sites ); - - /** - * @var Site $site - */ - foreach ( $sites as $site ) { - $this->assertInstanceOf( 'Site', $site ); - } - - foreach ( $expectedSites as $site ) { - if ( $site->getGlobalId() !== null ) { - $this->assertTrue( $sites->hasSite( $site->getGlobalId() ) ); - } - } - } - - /** - * @covers SiteSQLStore::saveSites - */ - public function testSaveSites() { - $store = SiteSQLStore::newInstance(); - - $sites = array(); - - $site = new Site(); - $site->setGlobalId( 'ertrywuutr' ); - $site->setLanguageCode( 'en' ); - $sites[] = $site; - - $site = new MediaWikiSite(); - $site->setGlobalId( 'sdfhxujgkfpth' ); - $site->setLanguageCode( 'nl' ); - $sites[] = $site; - - $this->assertTrue( $store->saveSites( $sites ) ); - - $site = $store->getSite( 'ertrywuutr' ); - $this->assertInstanceOf( 'Site', $site ); - $this->assertEquals( 'en', $site->getLanguageCode() ); - $this->assertTrue( is_integer( $site->getInternalId() ) ); - $this->assertTrue( $site->getInternalId() >= 0 ); - - $site = $store->getSite( 'sdfhxujgkfpth' ); - $this->assertInstanceOf( 'Site', $site ); - $this->assertEquals( 'nl', $site->getLanguageCode() ); - $this->assertTrue( is_integer( $site->getInternalId() ) ); - $this->assertTrue( $site->getInternalId() >= 0 ); - } - - /** - * @covers SiteSQLStore::reset - */ - public function testReset() { - $store1 = SiteSQLStore::newInstance(); - $store2 = SiteSQLStore::newInstance(); - - // initialize internal cache - $this->assertGreaterThan( 0, $store1->getSites()->count() ); - $this->assertGreaterThan( 0, $store2->getSites()->count() ); - - // Clear actual data. Will purge the external cache and reset the internal - // cache in $store1, but not the internal cache in store2. - $this->assertTrue( $store1->clear() ); - - // sanity check: $store2 should have a stale cache now - $this->assertNotNull( $store2->getSite( 'enwiki' ) ); - - // purge cache - $store2->reset(); - - // ...now the internal cache of $store2 should be updated and thus empty. - $site = $store2->getSite( 'enwiki' ); - $this->assertNull( $site ); - } - - /** - * @covers SiteSQLStore::clear - */ - public function testClear() { - $store = SiteSQLStore::newInstance(); - $this->assertTrue( $store->clear() ); - - $site = $store->getSite( 'enwiki' ); - $this->assertNull( $site ); - - $sites = $store->getSites(); - $this->assertEquals( 0, $sites->count() ); - } -} diff --git a/tests/phpunit/includes/site/SiteTest.php b/tests/phpunit/includes/site/SiteTest.php deleted file mode 100644 index 29c1ff33..00000000 --- a/tests/phpunit/includes/site/SiteTest.php +++ /dev/null @@ -1,296 +0,0 @@ -<?php - -/** - * Tests for the Site class. - * - * 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 - * @since 1.21 - * - * @ingroup Site - * @ingroup Test - * - * @group Site - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - */ -class SiteTest extends MediaWikiTestCase { - - public function instanceProvider() { - return $this->arrayWrap( TestSites::getSites() ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::getInterwikiIds - */ - public function testGetInterwikiIds( Site $site ) { - $this->assertInternalType( 'array', $site->getInterwikiIds() ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::getNavigationIds - */ - public function testGetNavigationIds( Site $site ) { - $this->assertInternalType( 'array', $site->getNavigationIds() ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::addNavigationId - */ - public function testAddNavigationId( Site $site ) { - $site->addNavigationId( 'foobar' ); - $this->assertTrue( in_array( 'foobar', $site->getNavigationIds(), true ) ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::addInterwikiId - */ - public function testAddInterwikiId( Site $site ) { - $site->addInterwikiId( 'foobar' ); - $this->assertTrue( in_array( 'foobar', $site->getInterwikiIds(), true ) ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::getLanguageCode - */ - public function testGetLanguageCode( Site $site ) { - $this->assertTypeOrValue( 'string', $site->getLanguageCode(), null ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::setLanguageCode - */ - public function testSetLanguageCode( Site $site ) { - $site->setLanguageCode( 'en' ); - $this->assertEquals( 'en', $site->getLanguageCode() ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::normalizePageName - */ - public function testNormalizePageName( Site $site ) { - $this->assertInternalType( 'string', $site->normalizePageName( 'Foobar' ) ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::getGlobalId - */ - public function testGetGlobalId( Site $site ) { - $this->assertTypeOrValue( 'string', $site->getGlobalId(), null ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::setGlobalId - */ - public function testSetGlobalId( Site $site ) { - $site->setGlobalId( 'foobar' ); - $this->assertEquals( 'foobar', $site->getGlobalId() ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::getType - */ - public function testGetType( Site $site ) { - $this->assertInternalType( 'string', $site->getType() ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::getPath - */ - public function testGetPath( Site $site ) { - $this->assertTypeOrValue( 'string', $site->getPath( 'page_path' ), null ); - $this->assertTypeOrValue( 'string', $site->getPath( 'file_path' ), null ); - $this->assertTypeOrValue( 'string', $site->getPath( 'foobar' ), null ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::getAllPaths - */ - public function testGetAllPaths( Site $site ) { - $this->assertInternalType( 'array', $site->getAllPaths() ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::setPath - * @covers Site::removePath - */ - public function testSetAndRemovePath( Site $site ) { - $count = count( $site->getAllPaths() ); - - $site->setPath( 'spam', 'http://www.wikidata.org/$1' ); - $site->setPath( 'spam', 'http://www.wikidata.org/foo/$1' ); - $site->setPath( 'foobar', 'http://www.wikidata.org/bar/$1' ); - - $this->assertEquals( $count + 2, count( $site->getAllPaths() ) ); - - $this->assertInternalType( 'string', $site->getPath( 'foobar' ) ); - $this->assertEquals( 'http://www.wikidata.org/foo/$1', $site->getPath( 'spam' ) ); - - $site->removePath( 'spam' ); - $site->removePath( 'foobar' ); - - $this->assertEquals( $count, count( $site->getAllPaths() ) ); - - $this->assertNull( $site->getPath( 'foobar' ) ); - $this->assertNull( $site->getPath( 'spam' ) ); - } - - /** - * @covers Site::setLinkPath - */ - public function testSetLinkPath() { - $site = new Site(); - $path = "TestPath/$1"; - - $site->setLinkPath( $path ); - $this->assertEquals( $path, $site->getLinkPath() ); - } - - /** - * @covers Site::getLinkPathType - */ - public function testGetLinkPathType() { - $site = new Site(); - - $path = 'TestPath/$1'; - $site->setLinkPath( $path ); - $this->assertEquals( $path, $site->getPath( $site->getLinkPathType() ) ); - - $path = 'AnotherPath/$1'; - $site->setPath( $site->getLinkPathType(), $path ); - $this->assertEquals( $path, $site->getLinkPath() ); - } - - /** - * @covers Site::setPath - */ - public function testSetPath() { - $site = new Site(); - - $path = 'TestPath/$1'; - $site->setPath( 'foo', $path ); - - $this->assertEquals( $path, $site->getPath( 'foo' ) ); - } - - /** - * @covers Site::setPath - * @covers Site::getProtocol - */ - public function testProtocolRelativePath() { - $site = new Site(); - - $type = $site->getLinkPathType(); - $path = '//acme.com/'; // protocol-relative URL - $site->setPath( $type, $path ); - - $this->assertEquals( '', $site->getProtocol() ); - } - - 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. - // Subclasses need to override this provider appropriately. - - return array( - array( #0 - 'http://acme.test/TestPath/$1', - 'Foo', - '/TestPath/Foo', - ), - array( #1 - 'http://acme.test/TestScript?x=$1&y=bla', - 'Foo', - 'TestScript?x=Foo&y=bla', - ), - array( #2 - 'http://acme.test/TestPath/$1', - 'foo & bar/xyzzy (quux-shmoox?)', - '/TestPath/foo%20%26%20bar%2Fxyzzy%20%28quux-shmoox%3F%29', - ), - ); - } - - /** - * @dataProvider provideGetPageUrl - * @covers Site::getPageUrl - */ - public function testGetPageUrl( $path, $page, $expected ) { - $site = new Site(); - - //NOTE: the assumption that getPageUrl is based on getLinkPath - // is true for Site but not guaranteed for subclasses. - // Subclasses need to override this test case appropriately. - $site->setLinkPath( $path ); - $this->assertContains( $path, $site->getPageUrl() ); - - $this->assertContains( $expected, $site->getPageUrl( $page ) ); - } - - protected function assertTypeOrFalse( $type, $value ) { - if ( $value === false ) { - $this->assertTrue( true ); - } else { - $this->assertInternalType( $type, $value ); - } - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::serialize - * @covers Site::unserialize - */ - public function testSerialization( Site $site ) { - $this->assertInstanceOf( 'Serializable', $site ); - - $serialization = serialize( $site ); - $newInstance = unserialize( $serialization ); - - $this->assertInstanceOf( 'Site', $newInstance ); - - $this->assertEquals( $serialization, serialize( $newInstance ) ); - } -} diff --git a/tests/phpunit/includes/site/TestSites.php b/tests/phpunit/includes/site/TestSites.php deleted file mode 100644 index f224b7d7..00000000 --- a/tests/phpunit/includes/site/TestSites.php +++ /dev/null @@ -1,100 +0,0 @@ -<?php - -/** - * Holds sites for testing purposes. - * - * 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 - * @since 1.21 - * - * @ingroup Site - * @ingroup Test - * - * @group Site - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - */ -class TestSites { - - /** - * @since 1.21 - * - * @return array - */ - public static function getSites() { - $sites = array(); - - $site = new Site(); - $site->setGlobalId( 'foobar' ); - $sites[] = $site; - - $site = new MediaWikiSite(); - $site->setGlobalId( 'enwiktionary' ); - $site->setGroup( 'wiktionary' ); - $site->setLanguageCode( 'en' ); - $site->addNavigationId( 'enwiktionary' ); - $site->setPath( MediaWikiSite::PATH_PAGE, "https://en.wiktionary.org/wiki/$1" ); - $site->setPath( MediaWikiSite::PATH_FILE, "https://en.wiktionary.org/w/$1" ); - $sites[] = $site; - - $site = new MediaWikiSite(); - $site->setGlobalId( 'dewiktionary' ); - $site->setGroup( 'wiktionary' ); - $site->setLanguageCode( 'de' ); - $site->addInterwikiId( 'dewiktionary' ); - $site->addInterwikiId( 'wiktionaryde' ); - $site->setPath( MediaWikiSite::PATH_PAGE, "https://de.wiktionary.org/wiki/$1" ); - $site->setPath( MediaWikiSite::PATH_FILE, "https://de.wiktionary.org/w/$1" ); - $sites[] = $site; - - $site = new Site(); - $site->setGlobalId( 'spam' ); - $site->setGroup( 'spam' ); - $site->setLanguageCode( 'en' ); - $site->addNavigationId( 'spam' ); - $site->addNavigationId( 'spamz' ); - $site->addInterwikiId( 'spamzz' ); - $site->setLinkPath( "http://spamzz.test/testing/" ); - $sites[] = $site; - - foreach ( array( 'en', 'de', 'nl', 'sv', 'sr', 'no', 'nn' ) as $langCode ) { - $site = new MediaWikiSite(); - $site->setGlobalId( $langCode . 'wiki' ); - $site->setGroup( 'wikipedia' ); - $site->setLanguageCode( $langCode ); - $site->addInterwikiId( $langCode ); - $site->addNavigationId( $langCode ); - $site->setPath( MediaWikiSite::PATH_PAGE, "https://$langCode.wikipedia.org/wiki/$1" ); - $site->setPath( MediaWikiSite::PATH_FILE, "https://$langCode.wikipedia.org/w/$1" ); - $sites[] = $site; - } - - return $sites; - } - - /** - * Inserts sites into the database for the unit tests that need them. - * - * @since 0.1 - */ - public static function insertIntoDb() { - $sitesTable = SiteSQLStore::newInstance(); - $sitesTable->clear(); - $sitesTable->saveSites( TestSites::getSites() ); - } -} diff --git a/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php b/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php deleted file mode 100644 index a806b4ac..00000000 --- a/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php +++ /dev/null @@ -1,79 +0,0 @@ -<?php -/** - * Test class to run the query of most of all our special pages - * - * Copyright © 2011, Antoine Musso - * - * @author Antoine Musso - * @group Database - */ - -if ( !defined( 'MEDIAWIKI' ) ) { - die( 1 ); -} - -global $IP; -require_once "$IP/includes/QueryPage.php"; // Needed to populate $wgQueryPages - -class QueryAllSpecialPagesTest extends MediaWikiTestCase { - - /** List query pages that can not be tested automatically */ - protected $manualTest = array( - 'LinkSearchPage' - ); - - /** - * Pages whose query use the same DB table more than once. - * This is used to skip testing those pages when run against a MySQL backend - * which does not support reopening a temporary table. See upstream bug: - * http://bugs.mysql.com/bug.php?id=10327 - */ - protected $reopensTempTable = array( - 'BrokenRedirects', - ); - - /** - * Initialize all query page objects - */ - function __construct() { - parent::__construct(); - - global $wgQueryPages; - foreach ( $wgQueryPages as $page ) { - $class = $page[0]; - if ( !in_array( $class, $this->manualTest ) ) { - $this->queryPages[$class] = new $class; - } - } - } - - /** - * Test SQL for each of our QueryPages objects - * @group Database - */ - public function testQuerypageSqlQuery() { - global $wgDBtype; - - foreach ( $this->queryPages as $page ) { - - // With MySQL, skips special pages reopening a temporary table - // See http://bugs.mysql.com/bug.php?id=10327 - if ( - $wgDBtype === 'mysql' - && in_array( $page->getName(), $this->reopensTempTable ) - ) { - $this->markTestSkipped( "SQL query for page {$page->getName()} can not be tested on MySQL backend (it reopens a temporary table)" ); - continue; - } - - $msg = "SQL query for page {$page->getName()} should give a result wrapper object"; - - $result = $page->reallyDoQuery( 50 ); - if ( $result instanceof ResultWrapper ) { - $this->assertTrue( true, $msg ); - } else { - $this->assertFalse( false, $msg ); - } - } - } -} diff --git a/tests/phpunit/includes/specials/SpecialPreferencesTest.php b/tests/phpunit/includes/specials/SpecialPreferencesTest.php deleted file mode 100644 index 6c637c65..00000000 --- a/tests/phpunit/includes/specials/SpecialPreferencesTest.php +++ /dev/null @@ -1,60 +0,0 @@ -<?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 deleted file mode 100644 index 436eb2e2..00000000 --- a/tests/phpunit/includes/specials/SpecialRecentchangesTest.php +++ /dev/null @@ -1,125 +0,0 @@ -<?php -/** - * Test class for SpecialRecentchanges class - * - * Copyright © 2011, Antoine Musso - * - * @author Antoine Musso - * @group Database - */ -class SpecialRecentchangesTest extends MediaWikiTestCase { - - /** - * @var SpecialRecentChanges - */ - protected $rc; - - /** helper to test SpecialRecentchanges::buildMainQueryConds() */ - private function assertConditions( $expected, $requestOptions = null, $message = '' ) { - $context = new RequestContext; - $context->setRequest( new FauxRequest( $requestOptions ) ); - - # setup the rc object - $this->rc = new SpecialRecentChanges(); - $this->rc->setContext( $context ); - $formOptions = $this->rc->setup( null ); - - # Filter out rc_timestamp conditions which depends on the test runtime - # This condition is not needed as of march 2, 2011 -- hashar - # @todo FIXME: Find a way to generate the correct rc_timestamp - $queryConditions = array_filter( - $this->rc->buildMainQueryConds( $formOptions ), - 'SpecialRecentchangesTest::filterOutRcTimestampCondition' - ); - - $this->assertEquals( - $expected, - $queryConditions, - $message - ); - } - - /** return false if condition begin with 'rc_timestamp ' */ - private static function filterOutRcTimestampCondition( $var ) { - return ( false === strpos( $var, 'rc_timestamp ' ) ); - } - - public function testRcNsFilter() { - $this->assertConditions( - array( # expected - 'rc_bot' => 0, - #0 => "rc_timestamp >= '20110223000000'", - 1 => "rc_namespace = '0'", - ), - array( - 'namespace' => NS_MAIN, - ), - "rc conditions with no options (aka default setting)" - ); - } - - public function testRcNsFilterInversion() { - $this->assertConditions( - array( # expected - #0 => "rc_timestamp >= '20110223000000'", - 'rc_bot' => 0, - 1 => sprintf( "rc_namespace != '%s'", NS_MAIN ), - ), - array( - 'namespace' => NS_MAIN, - 'invert' => 1, - ), - "rc conditions with namespace inverted" - ); - } - - /** - * @bug 2429 - * @dataProvider provideNamespacesAssociations - */ - public function testRcNsFilterAssociation( $ns1, $ns2 ) { - $this->assertConditions( - array( # expected - #0 => "rc_timestamp >= '20110223000000'", - 'rc_bot' => 0, - 1 => sprintf( "(rc_namespace = '%s' OR rc_namespace = '%s')", $ns1, $ns2 ), - ), - array( - 'namespace' => $ns1, - 'associated' => 1, - ), - "rc conditions with namespace inverted" - ); - } - - /** - * @bug 2429 - * @dataProvider provideNamespacesAssociations - */ - public function testRcNsFilterAssociationWithInversion( $ns1, $ns2 ) { - $this->assertConditions( - array( # expected - #0 => "rc_timestamp >= '20110223000000'", - 'rc_bot' => 0, - 1 => sprintf( "(rc_namespace != '%s' AND rc_namespace != '%s')", $ns1, $ns2 ), - ), - array( - 'namespace' => $ns1, - 'associated' => 1, - 'invert' => 1, - ), - "rc conditions with namespace inverted" - ); - } - - /** - * Provides associated namespaces to test recent changes - * namespaces association filtering. - */ - public static function provideNamespacesAssociations() { - return array( # (NS => Associated_NS) - array( NS_MAIN, NS_TALK ), - array( NS_TALK, NS_MAIN ), - ); - } -} diff --git a/tests/phpunit/includes/specials/SpecialSearchTest.php b/tests/phpunit/includes/specials/SpecialSearchTest.php deleted file mode 100644 index 17e883fd..00000000 --- a/tests/phpunit/includes/specials/SpecialSearchTest.php +++ /dev/null @@ -1,139 +0,0 @@ -<?php -/** - * Test class for SpecialSearch class - * Copyright © 2012, Antoine Musso - * - * @author Antoine Musso - * @group Database - */ - -class SpecialSearchTest extends MediaWikiTestCase { - private $search; - - /** - * @covers SpecialSearch::load - * @dataProvider provideSearchOptionsTests - * @param $requested Array Request parameters. For example array( 'ns5' => true, 'ns6' => true). NULL to use default options. - * @param $userOptions Array User options to test with. For example array('searchNs5' => 1 );. NULL to use default options. - * @param $expectedProfile An expected search profile name - * @param $expectedNs Array Expected namespaces - */ - public function testProfileAndNamespaceLoading( - $requested, $userOptions, $expectedProfile, $expectedNS, - $message = 'Profile name and namespaces mismatches!' - ) { - $context = new RequestContext; - $context->setUser( - $this->newUserWithSearchNS( $userOptions ) - ); - /* - $context->setRequest( new FauxRequest( array( - 'ns5'=>true, - 'ns6'=>true, - ) )); - */ - $context->setRequest( new FauxRequest( $requested ) ); - $search = new SpecialSearch(); - $search->setContext( $context ); - $search->load(); - - /** - * Verify profile name and namespace in the same assertion to make - * sure we will be able to fully compare the above code. PHPUnit stop - * after an assertion fail. - */ - $this->assertEquals( - array( /** Expected: */ - 'ProfileName' => $expectedProfile, - 'Namespaces' => $expectedNS, - ) - , array( /** Actual: */ - 'ProfileName' => $search->getProfile(), - 'Namespaces' => $search->getNamespaces(), - ) - , $message - ); - } - - public static function provideSearchOptionsTests() { - $defaultNS = SearchEngine::defaultNamespaces(); - $EMPTY_REQUEST = array(); - $NO_USER_PREF = null; - - return array( - /** - * Parameters: - * <Web Request>, <User options> - * Followed by expected values: - * <ProfileName>, <NSList> - * Then an optional message. - */ - array( - $EMPTY_REQUEST, $NO_USER_PREF, - 'default', $defaultNS, - 'Bug 33270: No request nor user preferences should give default profile' - ), - array( - array( 'ns5' => 1 ), $NO_USER_PREF, - 'advanced', array( 5 ), - 'Web request with specific NS should override user preference' - ), - array( - $EMPTY_REQUEST, array( - 'searchNs2' => 1, - 'searchNs14' => 1, - ) + array_fill_keys( array_map( function ( $ns ) { - return "searchNs$ns"; - }, $defaultNS ), 0 ), - 'advanced', array( 2, 14 ), - 'Bug 33583: search with no option should honor User search preferences' - . ' and have all other namespace disabled' - ), - ); - } - - /** - * Helper to create a new User object with given options - * User remains anonymous though - */ - function newUserWithSearchNS( $opt = null ) { - $u = User::newFromId( 0 ); - if ( $opt === null ) { - return $u; - } - foreach ( $opt as $name => $value ) { - $u->setOption( $name, $value ); - } - - return $u; - } - - /** - * Verify we do not expand search term in <title> on search result page - * https://gerrit.wikimedia.org/r/4841 - */ - public function testSearchTermIsNotExpanded() { - - # Initialize [[Special::Search]] - $search = new SpecialSearch(); - $search->getContext()->setTitle( Title::newFromText( 'Special:Search' ) ); - $search->load(); - - # Simulate a user searching for a given term - $term = '{{SITENAME}}'; - $search->showResults( $term ); - - # Lookup the HTML page title set for that page - $pageTitle = $search - ->getContext() - ->getOutput() - ->getHTMLTitle(); - - # Compare :-] - $this->assertRegExp( - '/' . preg_quote( $term ) . '/', - $pageTitle, - "Search term '{$term}' should not be expanded in Special:Search <title>" - ); - } -} diff --git a/tests/phpunit/includes/upload/UploadBaseTest.php b/tests/phpunit/includes/upload/UploadBaseTest.php deleted file mode 100644 index 982b46b2..00000000 --- a/tests/phpunit/includes/upload/UploadBaseTest.php +++ /dev/null @@ -1,147 +0,0 @@ -<?php - -/** - * @group Upload - */ -class UploadBaseTest extends MediaWikiTestCase { - - /** @var UploadTestHandler */ - protected $upload; - - protected function setUp() { - global $wgHooks; - parent::setUp(); - - $this->upload = new UploadTestHandler; - $this->hooks = $wgHooks; - $wgHooks['InterwikiLoadPrefix'][] = function ( $prefix, &$data ) { - return false; - }; - } - - protected function tearDown() { - global $wgHooks; - $wgHooks = $this->hooks; - - parent::tearDown(); - } - - - /** - * First checks the return code - * 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 */ - $this->assertEquals( $code, - $this->upload->testTitleValidation( $srcFilename ), - "$msg code" ); - - /* If we expect a valid title, check the title itself. */ - if ( $code == UploadBase::OK ) { - $this->assertEquals( $dstFilename, - $this->upload->getTitle()->getText(), - "$msg text" ); - } - } - - /** - * Test various forms of valid and invalid titles that can be supplied. - */ - public static function provideTestTitleValidation() { - return array( - /* Test a valid title */ - array( 'ValidTitle.jpg', 'ValidTitle.jpg', UploadBase::OK, - 'upload valid title' ), - /* A title with a slash */ - array( 'A/B.jpg', 'B.jpg', UploadBase::OK, - 'upload title with slash' ), - /* A title with illegal char */ - array( 'A:B.jpg', 'A-B.jpg', UploadBase::OK, - 'upload title with colon' ), - /* Stripping leading File: prefix */ - array( 'File:C.jpg', 'C.jpg', UploadBase::OK, - 'upload title with File prefix' ), - /* Test illegal suggested title (r94601) */ - array( '%281%29.JPG', null, UploadBase::ILLEGAL_FILENAME, - 'illegal title for upload' ), - /* A title without extension */ - array( 'A', null, UploadBase::FILETYPE_MISSING, - 'upload title without extension' ), - /* A title with no basename */ - array( '.jpg', null, UploadBase::MIN_LENGTH_PARTNAME, - 'upload title without basename' ), - /* A title that is longer than 255 bytes */ - array( str_repeat( 'a', 255 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG, - 'upload title longer than 255 bytes' ), - /* A title that is longer than 240 bytes */ - array( str_repeat( 'a', 240 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG, - 'upload title longer than 240 bytes' ), - ); - } - - /** - * Test the upload verification functions - * @covers UploadBase::verifyUpload - */ - public function testVerifyUpload() { - /* Setup with zero file size */ - $this->upload->initializePathInfo( '', '', 0 ); - $result = $this->upload->verifyUpload(); - $this->assertEquals( UploadBase::EMPTY_FILE, - $result['status'], - 'upload empty file' ); - } - - // Helper used to create an empty file of size $size. - private function createFileOfSize( $size ) { - $filename = tempnam( wfTempDir(), "mwuploadtest" ); - - $fh = fopen( $filename, 'w' ); - ftruncate( $fh, $size ); - fclose( $fh ); - - return $filename; - } - - /** - * test uploading a 100 bytes file with $wgMaxUploadSize = 100 - * - * This method should be abstracted so we can test different settings. - */ - public function testMaxUploadSize() { - global $wgMaxUploadSize; - $savedGlobal = $wgMaxUploadSize; // save global - global $wgFileExtensions; - $wgFileExtensions[] = 'txt'; - - $wgMaxUploadSize = 100; - - $filename = $this->createFileOfSize( $wgMaxUploadSize ); - $this->upload->initializePathInfo( basename( $filename ) . '.txt', $filename, 100 ); - $result = $this->upload->verifyUpload(); - unlink( $filename ); - - $this->assertEquals( - array( 'status' => UploadBase::OK ), $result ); - - $wgMaxUploadSize = $savedGlobal; // restore global - } -} - -class UploadTestHandler extends UploadBase { - 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 deleted file mode 100644 index a75fba69..00000000 --- a/tests/phpunit/includes/upload/UploadFromUrlTest.php +++ /dev/null @@ -1,350 +0,0 @@ -<?php - -/** - * @group Broken - * @group Upload - * @group Database - */ -class UploadFromUrlTest extends ApiTestCase { - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgEnableUploads' => true, - 'wgAllowCopyUploads' => true, - 'wgAllowAsyncCopyUploads' => true, - ) ); - wfSetupSession(); - - if ( wfLocalFile( 'UploadFromUrlTest.png' )->exists() ) { - $this->deleteFile( 'UploadFromUrlTest.png' ); - } - } - - protected function doApiRequest( array $params, array $unused = null, $appendModule = false, User $user = null ) { - $sessionId = session_id(); - session_write_close(); - - $req = new FauxRequest( $params, true, $_SESSION ); - $module = new ApiMain( $req, true ); - $module->execute(); - - wfSetupSession( $sessionId ); - - return array( $module->getResultData(), $req ); - } - - /** - * Ensure that the job queue is empty before continuing - */ - public function testClearQueue() { - $job = JobQueueGroup::singleton()->pop(); - while ( $job ) { - $job = JobQueueGroup::singleton()->pop(); - } - $this->assertFalse( $job ); - } - - /** - * @todo Document why we test login, since the $wgUser hack used doesn't - * require login - */ - public function testLogin() { - $data = $this->doApiRequest( array( - 'action' => 'login', - 'lgname' => $this->user->userName, - 'lgpassword' => $this->user->passWord ) ); - $this->assertArrayHasKey( "login", $data[0] ); - $this->assertArrayHasKey( "result", $data[0]['login'] ); - $this->assertEquals( "NeedToken", $data[0]['login']['result'] ); - $token = $data[0]['login']['token']; - - $data = $this->doApiRequest( array( - 'action' => 'login', - "lgtoken" => $token, - 'lgname' => $this->user->userName, - 'lgpassword' => $this->user->passWord ) ); - - $this->assertArrayHasKey( "login", $data[0] ); - $this->assertArrayHasKey( "result", $data[0]['login'] ); - $this->assertEquals( "Success", $data[0]['login']['result'] ); - $this->assertArrayHasKey( 'lgtoken', $data[0]['login'] ); - - return $data; - } - - /** - * @depends testLogin - * @depends testClearQueue - */ - public function testSetupUrlDownload( $data ) { - $token = $this->user->getEditToken(); - $exception = false; - - try { - $this->doApiRequest( array( - 'action' => 'upload', - ) ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "The token parameter must be set", $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload', - 'token' => $token, - ), $data ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "One of the parameters sessionkey, file, url, statuskey is required", - $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload', - 'url' => 'http://www.example.com/test.png', - 'token' => $token, - ), $data ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "The filename parameter must be set", $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - - $this->user->removeGroup( 'sysop' ); - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload', - 'url' => 'http://www.example.com/test.png', - 'filename' => 'UploadFromUrlTest.png', - 'token' => $token, - ), $data ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "Permission denied", $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - - $this->user->addGroup( 'sysop' ); - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'asyncdownload' => 1, - 'filename' => 'UploadFromUrlTest.png', - 'token' => $token, - ), $data ); - - $this->assertEquals( $data[0]['upload']['result'], 'Queued', 'Queued upload' ); - - $job = JobQueueGroup::singleton()->pop(); - $this->assertThat( $job, $this->isInstanceOf( 'UploadFromUrlJob' ), 'Queued upload inserted' ); - } - - /** - * @depends testLogin - * @depends testClearQueue - */ - public function testAsyncUpload( $data ) { - $token = $this->user->getEditToken(); - - $this->user->addGroup( 'users' ); - - $data = $this->doAsyncUpload( $token, true ); - $this->assertEquals( $data[0]['upload']['result'], 'Success' ); - $this->assertEquals( $data[0]['upload']['filename'], 'UploadFromUrlTest.png' ); - $this->assertTrue( wfLocalFile( $data[0]['upload']['filename'] )->exists() ); - - $this->deleteFile( 'UploadFromUrlTest.png' ); - - return $data; - } - - /** - * @depends testLogin - * @depends testClearQueue - */ - public function testAsyncUploadWarning( $data ) { - $token = $this->user->getEditToken(); - - $this->user->addGroup( 'users' ); - - $data = $this->doAsyncUpload( $token ); - - $this->assertEquals( $data[0]['upload']['result'], 'Warning' ); - $this->assertTrue( isset( $data[0]['upload']['sessionkey'] ) ); - - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'sessionkey' => $data[0]['upload']['sessionkey'], - 'filename' => 'UploadFromUrlTest.png', - 'ignorewarnings' => 1, - 'token' => $token, - ) ); - $this->assertEquals( $data[0]['upload']['result'], 'Success' ); - $this->assertEquals( $data[0]['upload']['filename'], 'UploadFromUrlTest.png' ); - $this->assertTrue( wfLocalFile( $data[0]['upload']['filename'] )->exists() ); - - $this->deleteFile( 'UploadFromUrlTest.png' ); - - return $data; - } - - /** - * @depends testLogin - * @depends testClearQueue - */ - public function testSyncDownload( $data ) { - $token = $this->user->getEditToken(); - - $job = JobQueueGroup::singleton()->pop(); - $this->assertFalse( $job, 'Starting with an empty jobqueue' ); - - $this->user->addGroup( 'users' ); - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'filename' => 'UploadFromUrlTest.png', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'ignorewarnings' => true, - 'token' => $token, - ), $data ); - - $job = JobQueueGroup::singleton()->pop(); - $this->assertFalse( $job ); - - $this->assertEquals( 'Success', $data[0]['upload']['result'] ); - $this->deleteFile( 'UploadFromUrlTest.png' ); - - return $data; - } - - public function testLeaveMessage() { - $token = $this->user->user->getEditToken(); - - $talk = $this->user->user->getTalkPage(); - if ( $talk->exists() ) { - $page = WikiPage::factory( $talk ); - $page->doDeleteArticle( '' ); - } - - $this->assertFalse( (bool)$talk->getArticleID( Title::GAID_FOR_UPDATE ), 'User talk does not exist' ); - - $this->doApiRequest( array( - 'action' => 'upload', - 'filename' => 'UploadFromUrlTest.png', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'asyncdownload' => 1, - 'token' => $token, - 'leavemessage' => 1, - 'ignorewarnings' => 1, - ) ); - - $job = JobQueueGroup::singleton()->pop(); - $this->assertEquals( 'UploadFromUrlJob', get_class( $job ) ); - $job->run(); - - $this->assertTrue( wfLocalFile( 'UploadFromUrlTest.png' )->exists() ); - $this->assertTrue( (bool)$talk->getArticleID( Title::GAID_FOR_UPDATE ), 'User talk exists' ); - - $this->deleteFile( 'UploadFromUrlTest.png' ); - - $talkRev = Revision::newFromTitle( $talk ); - $talkSize = $talkRev->getSize(); - - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload', - 'filename' => 'UploadFromUrlTest.png', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'asyncdownload' => 1, - 'token' => $token, - 'leavemessage' => 1, - ) ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( 'Using leavemessage without ignorewarnings is not supported', $e->getMessage() ); - } - $this->assertTrue( $exception ); - - $job = JobQueueGroup::singleton()->pop(); - $this->assertFalse( $job ); - - return; - /* - // Broken until using leavemessage with ignorewarnings is supported - $job->run(); - - $this->assertFalse( wfLocalFile( 'UploadFromUrlTest.png' )->exists() ); - - $talkRev = Revision::newFromTitle( $talk ); - $this->assertTrue( $talkRev->getSize() > $talkSize, 'New message left' ); - */ - } - - /** - * Helper function to perform an async upload, execute the job and fetch - * the status - * - * @return array The result of action=upload&statuskey=key - */ - private function doAsyncUpload( $token, $ignoreWarnings = false, $leaveMessage = false ) { - $params = array( - 'action' => 'upload', - 'filename' => 'UploadFromUrlTest.png', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'asyncdownload' => 1, - 'token' => $token, - ); - if ( $ignoreWarnings ) { - $params['ignorewarnings'] = 1; - } - if ( $leaveMessage ) { - $params['leavemessage'] = 1; - } - - $data = $this->doApiRequest( $params ); - $this->assertEquals( $data[0]['upload']['result'], 'Queued' ); - $this->assertTrue( isset( $data[0]['upload']['statuskey'] ) ); - $statusKey = $data[0]['upload']['statuskey']; - - $job = JobQueueGroup::singleton()->pop(); - $this->assertEquals( 'UploadFromUrlJob', get_class( $job ) ); - - $status = $job->run(); - $this->assertTrue( $status ); - - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'statuskey' => $statusKey, - 'token' => $token, - ) ); - - return $data; - } - - /** - * - */ - protected function deleteFile( $name ) { - $t = Title::newFromText( $name, NS_FILE ); - $this->assertTrue( $t->exists(), "File '$name' exists" ); - - if ( $t->exists() ) { - $file = wfFindFile( $name, array( 'ignoreRedirect' => true ) ); - $empty = ""; - FileDeleteForm::doDelete( $t, $file, $empty, "none", true ); - $page = WikiPage::factory( $t ); - $page->doDeleteArticle( "testing" ); - } - $t = Title::newFromText( $name, NS_FILE ); - - $this->assertFalse( $t->exists(), "File '$name' was deleted" ); - } -} diff --git a/tests/phpunit/includes/upload/UploadStashTest.php b/tests/phpunit/includes/upload/UploadStashTest.php deleted file mode 100644 index 7a0fea48..00000000 --- a/tests/phpunit/includes/upload/UploadStashTest.php +++ /dev/null @@ -1,76 +0,0 @@ -<?php -/** - * @group Database - */ -class UploadStashTest extends MediaWikiTestCase { - /** - * @var Array of UploadStashTestUser - */ - public static $users; - - protected function setUp() { - parent::setUp(); - - // Setup a file for bug 29408 - $this->bug29408File = __DIR__ . '/bug29408'; - file_put_contents( $this->bug29408File, "\x00" ); - - self::$users = array( - 'sysop' => new TestUser( - 'Uploadstashtestsysop', - 'Upload Stash Test Sysop', - 'upload_stash_test_sysop@example.com', - array( 'sysop' ) - ), - 'uploader' => new TestUser( - 'Uploadstashtestuser', - 'Upload Stash Test User', - 'upload_stash_test_user@example.com', - array() - ) - ); - } - - protected function tearDown() { - if ( file_exists( $this->bug29408File . "." ) ) { - unlink( $this->bug29408File . "." ); - } - - if ( file_exists( $this->bug29408File ) ) { - unlink( $this->bug29408File ); - } - - parent::tearDown(); - } - - public function testBug29408() { - $this->setMwGlobals( 'wgUser', self::$users['uploader']->user ); - - $repo = RepoGroup::singleton()->getLocalRepo(); - $stash = new UploadStash( $repo ); - - // Throws exception caught by PHPUnit on failure - $file = $stash->stashFile( $this->bug29408File ); - // We'll never reach this point if we hit bug 29408 - $this->assertTrue( true, 'Unrecognized file without extension' ); - - $stash->removeFile( $file->getFileKey() ); - } - - public function testValidRequest() { - $request = new FauxRequest( array( 'wpFileKey' => 'foo' ) ); - $this->assertFalse( UploadFromStash::isValidRequest( $request ), 'Check failure on bad wpFileKey' ); - - $request = new FauxRequest( array( 'wpSessionKey' => 'foo' ) ); - $this->assertFalse( UploadFromStash::isValidRequest( $request ), 'Check failure on bad wpSessionKey' ); - - $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test' ) ); - $this->assertTrue( UploadFromStash::isValidRequest( $request ), 'Check good wpFileKey' ); - - $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test' ) ); - $this->assertTrue( UploadFromStash::isValidRequest( $request ), 'Check good wpSessionKey' ); - - $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test', 'wpSessionKey' => 'foo' ) ); - $this->assertTrue( UploadFromStash::isValidRequest( $request ), 'Check key precedence' ); - } -} diff --git a/tests/phpunit/install-phpunit.sh b/tests/phpunit/install-phpunit.sh deleted file mode 100644 index 1f602935..00000000 --- a/tests/phpunit/install-phpunit.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -has_binary () { - if [ -z `which $1` ]; then - return 1 - fi - return 0 -} - -if [ `id -u` -ne 0 ]; then - echo '*** ERROR: Must be root to run' - exit 1 -fi - -if ( has_binary phpunit ); then - echo PHPUnit already installed -else if ( has_binary pear ); then - echo Installing phpunit with pear - pear channel-discover pear.phpunit.de - pear channel-discover components.ez.no - pear channel-discover pear.symfony.com - pear update-channels - pear install --alldeps phpunit/PHPUnit -else if ( has_binary apt-get ); then - echo Installing phpunit with apt-get - apt-get install phpunit -else if ( has_binary yum ); then - echo Installing phpunit with yum - yum install phpunit -else if ( has_binary port ); then - echo Installing phpunit with macports - port install php5-unit -fi -fi -fi -fi -fi diff --git a/tests/phpunit/languages/LanguageAmTest.php b/tests/phpunit/languages/LanguageAmTest.php deleted file mode 100644 index a644f5e0..00000000 --- a/tests/phpunit/languages/LanguageAmTest.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/LanguageAm.php */ -class LanguageAmTest extends LanguageClassesTestCase { - /** - * @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 ) ); - } - - public static function providePlural() { - return array( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageArTest.php b/tests/phpunit/languages/LanguageArTest.php deleted file mode 100644 index 7b48f236..00000000 --- a/tests/phpunit/languages/LanguageArTest.php +++ /dev/null @@ -1,87 +0,0 @@ -<?php -/** - * Based on LanguagMlTest - * @file - */ - -/** Tests for MediaWiki languages/LanguageAr.php */ -class LanguageArTest extends LanguageClassesTestCase { - /** - * @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 ) ); - } - - /** - * Mostly to test the raw ascii feature. - * @dataProvider providerSprintfDate - * @covers Language::sprintfDate - */ - public function testSprintfDate( $format, $date, $expected ) { - $this->assertEquals( $expected, $this->getLang()->sprintfDate( $format, $date ) ); - } - - public static function providerSprintfDate() { - return array( - array( - 'xg "vs" g', - '20120102030410', - 'يناير vs ٣' - ), - array( - 'xmY', - '20120102030410', - '١٤٣٣' - ), - array( - 'xnxmY', - '20120102030410', - '1433' - ), - array( - 'xN xmj xmn xN xmY', - '20120102030410', - ' 7 2 ١٤٣٣' - ), - ); - } - - /** - * @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 ) ); - } - - /** - * @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 ), - array( 'two', 2 ), - array( 'few', 3 ), - array( 'few', 9 ), - array( 'few', 110 ), - array( 'many', 11 ), - array( 'many', 15 ), - array( 'many', 99 ), - array( 'many', 9999 ), - array( 'other', 100 ), - array( 'other', 102 ), - array( 'other', 1000 ), - array( 'other', 1.7 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageBeTest.php b/tests/phpunit/languages/LanguageBeTest.php deleted file mode 100644 index 7bd586af..00000000 --- a/tests/phpunit/languages/LanguageBeTest.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/LanguageBe.php */ -class LanguageBeTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'few', 'many', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'one', 1 ), - array( 'many', 11 ), - array( 'one', 91 ), - array( 'one', 121 ), - array( 'few', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'few', 334 ), - array( 'many', 5 ), - array( 'many', 15 ), - array( 'many', 120 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageBe_taraskTest.php b/tests/phpunit/languages/LanguageBe_taraskTest.php deleted file mode 100644 index dbdb5889..00000000 --- a/tests/phpunit/languages/LanguageBe_taraskTest.php +++ /dev/null @@ -1,95 +0,0 @@ -<?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. - */ - public function testBeTaraskTestsUsesBeTaraskCode() { - $this->assertEquals( 'be-tarask', - $this->getLang()->getCode() - ); - } - - /** - * @see bug 23156 & r64981 - * @covers Language::commafy - */ - public function testSearchRightSingleQuotationMarkAsApostroph() { - $this->assertEquals( - "'", - $this->getLang()->normalizeForSearch( '’' ), - 'bug 23156: U+2019 conversion to U+0027' - ); - } - - /** - * @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 - * @covers Language::commafy - */ - public function testDoesNotCommafyFourDigitsNumber() { - $this->assertEquals( '1234', $this->getLang()->commafy( '1234' ) ); - } - - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'few', 'many', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'one', 1 ), - array( 'many', 11 ), - array( 'one', 91 ), - array( 'one', 121 ), - array( 'few', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'few', 334 ), - array( 'many', 5 ), - array( 'many', 15 ), - array( 'many', 120 ), - ); - } - - /** - * @dataProvider providePluralTwoForms - * @covers Language::convertPlural - */ - public function testPluralTwoForms( $result, $value ) { - $forms = array( '1=one', 'other' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); - } - - public static function providePluralTwoForms() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'other', 11 ), - array( 'other', 91 ), - array( 'other', 121 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageBhoTest.php b/tests/phpunit/languages/LanguageBhoTest.php deleted file mode 100644 index 187bfbbc..00000000 --- a/tests/phpunit/languages/LanguageBhoTest.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/LanguageBho.php */ -class LanguageBhoTest extends LanguageClassesTestCase { - /** - * @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 ) ); - } - - public static function providePlural() { - return array( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageBsTest.php b/tests/phpunit/languages/LanguageBsTest.php deleted file mode 100644 index 7aca2ab1..00000000 --- a/tests/phpunit/languages/LanguageBsTest.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for Croatian (hrvatski) */ -class LanguageBsTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'few', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 4 ), - array( 'other', 5 ), - array( 'other', 11 ), - array( 'other', 20 ), - array( 'one', 21 ), - array( 'few', 24 ), - array( 'other', 25 ), - array( 'other', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageClassesTestCase.php b/tests/phpunit/languages/LanguageClassesTestCase.php deleted file mode 100644 index 632e037f..00000000 --- a/tests/phpunit/languages/LanguageClassesTestCase.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php -/** - * Helping class to run tests using a clean language instance. - * - * This is intended for the MediaWiki language class tests under - * tests/phpunit/languages. - * - * Before each tests, a new language object is build which you - * can retrieve in your test using the $this->getLang() method: - * - * @par Using the crafted language object: - * @code - * function testHasLanguageObject() { - * $langObject = $this->getLang(); - * $this->assertInstanceOf( 'LanguageFoo', - * $langObject - * ); - * } - * @endcode - */ -abstract class LanguageClassesTestCase extends MediaWikiTestCase { - /** - * Internal language object - * - * A new object is created before each tests thanks to PHPUnit - * setUp() method, it is deleted after each test too. To get - * this object you simply use the getLang method. - * - * You must have setup a language code first. See $LanguageClassCode - * @code - * function testWeAreTheChampions() { - * $this->getLang(); # language object - * } - * @endcode - */ - private $languageObject; - - /** - * @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] ); - } else { - # Fallback to english language - $m[1] = 'en'; - wfDebug( - __METHOD__ . " could not extract a language name " - . "out of " . get_called_class() . " failling back to 'en'\n" - ); - } - // @todo validate $m[1] which should be a valid language code - $this->languageObject = Language::factory( $m[1] ); - } - - /** - * Delete the internal language object so each test start - * out with a fresh language instance. - */ - protected function tearDown() { - unset( $this->languageObject ); - parent::tearDown(); - } -} diff --git a/tests/phpunit/languages/LanguageCsTest.php b/tests/phpunit/languages/LanguageCsTest.php deleted file mode 100644 index da9e6b88..00000000 --- a/tests/phpunit/languages/LanguageCsTest.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/classes/Languagecs.php */ -class LanguageCsTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'few', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'other', 5 ), - array( 'other', 11 ), - array( 'other', 20 ), - array( 'other', 25 ), - array( 'other', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageCuTest.php b/tests/phpunit/languages/LanguageCuTest.php deleted file mode 100644 index 07193172..00000000 --- a/tests/phpunit/languages/LanguageCuTest.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/LanguageCu.php */ -class LanguageCuTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'two', 'few', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'two', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'other', 5 ), - array( 'one', 11 ), - array( 'other', 20 ), - array( 'two', 22 ), - array( 'few', 223 ), - array( 'other', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageCyTest.php b/tests/phpunit/languages/LanguageCyTest.php deleted file mode 100644 index eaf663a8..00000000 --- a/tests/phpunit/languages/LanguageCyTest.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageCy.php */ -class LanguageCyTest extends LanguageClassesTestCase { - /** - * @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 ) ); - } - - /** - * @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 ), - array( 'two', 2 ), - array( 'few', 3 ), - array( 'many', 6 ), - array( 'other', 4 ), - array( 'other', 5 ), - array( 'other', 11 ), - array( 'other', 20 ), - array( 'other', 22 ), - array( 'other', 223 ), - array( 'other', 200.00 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageDsbTest.php b/tests/phpunit/languages/LanguageDsbTest.php deleted file mode 100644 index 94c11bcc..00000000 --- a/tests/phpunit/languages/LanguageDsbTest.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageDsb.php */ -class LanguageDsbTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'two', 'few', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'one', 101 ), - array( 'one', 90001 ), - array( 'two', 2 ), - array( 'few', 3 ), - array( 'few', 203 ), - array( 'few', 4 ), - array( 'other', 99 ), - array( 'other', 555 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageFrTest.php b/tests/phpunit/languages/LanguageFrTest.php deleted file mode 100644 index 46b65011..00000000 --- a/tests/phpunit/languages/LanguageFrTest.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageFr.php */ -class LanguageFrTest extends LanguageClassesTestCase { - /** - * @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 ) ); - } - - public static function providePlural() { - return array( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageGaTest.php b/tests/phpunit/languages/LanguageGaTest.php deleted file mode 100644 index c009f56b..00000000 --- a/tests/phpunit/languages/LanguageGaTest.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageGa.php */ -class LanguageGaTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'two', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'two', 2 ), - array( 'other', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageGdTest.php b/tests/phpunit/languages/LanguageGdTest.php deleted file mode 100644 index 0b2612b2..00000000 --- a/tests/phpunit/languages/LanguageGdTest.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012-2013, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageGd.php */ -class LanguageGdTest extends LanguageClassesTestCase { - /** - * @dataProvider providerPlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'two', 'few', 'other' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); - } - - public static function providerPlural() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'two', 2 ), - array( 'one', 11 ), - array( 'two', 12 ), - array( 'few', 3 ), - array( 'few', 19 ), - array( 'other', 200 ), - ); - } - - /** - * @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 ) ); - } - - 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 deleted file mode 100644 index fc58022a..00000000 --- a/tests/phpunit/languages/LanguageGvTest.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * Test for Manx (Gaelg) language - * - * @author Santhosh Thottingal - * @copyright Copyright © 2013, Santhosh Thottingal - * @file - */ - -class LanguageGvTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'two', 'few', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'few', 0 ), - array( 'one', 1 ), - array( 'two', 2 ), - array( 'other', 3 ), - array( 'few', 20 ), - array( 'one', 21 ), - array( 'two', 22 ), - array( 'other', 23 ), - array( 'other', 50 ), - array( 'few', 60 ), - array( 'other', 80 ), - array( 'few', 100 ) - ); - } -} diff --git a/tests/phpunit/languages/LanguageHeTest.php b/tests/phpunit/languages/LanguageHeTest.php deleted file mode 100644 index 8edc6ddf..00000000 --- a/tests/phpunit/languages/LanguageHeTest.php +++ /dev/null @@ -1,132 +0,0 @@ -<?php -/** - * @author Amir E. Aharoni - * @copyright Copyright © 2012, Amir E. Aharoni - * @file - */ - -/** 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. - */ - - // @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 ) ); - } - - /** - * @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( 'one', 1 ), // Singular - 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 - ); - } - - 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 - ); - } - - public static function provideFourPluralForms() { - return array( - array( 'other', 0 ), // Zero - plural - array( 'one', 1 ), // Singular - 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 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. - public static function provideGrammar() { - return array( - array( - /* result */'וויקיפדיה', - /* word */'ויקיפדיה', - /* case */'תחילית', - ), - array( - /* result */'וולפגנג', - /* word */'וולפגנג', - /* case */'prefixed', - ), - array( - /* result */'קובץ', - /* word */'הקובץ', - /* case */'תחילית', - ), - array( - /* result */'־Wikipedia', - /* word */'Wikipedia', - /* case */'תחילית', - ), - array( - /* result */'־1995', - /* word */'1995', - /* case */'תחילית', - ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageHiTest.php b/tests/phpunit/languages/LanguageHiTest.php deleted file mode 100644 index f6d2c9e9..00000000 --- a/tests/phpunit/languages/LanguageHiTest.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/LanguageHi.php */ -class LanguageHiTest extends LanguageClassesTestCase { - /** - * @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 ) ); - } - - public static function providePlural() { - return array( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageHrTest.php b/tests/phpunit/languages/LanguageHrTest.php deleted file mode 100644 index 644c5255..00000000 --- a/tests/phpunit/languages/LanguageHrTest.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageHr.php */ -class LanguageHrTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'few', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 4 ), - array( 'other', 5 ), - array( 'other', 11 ), - array( 'other', 20 ), - array( 'one', 21 ), - array( 'few', 24 ), - array( 'other', 25 ), - array( 'other', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageHsbTest.php b/tests/phpunit/languages/LanguageHsbTest.php deleted file mode 100644 index f95a43bf..00000000 --- a/tests/phpunit/languages/LanguageHsbTest.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageHsb.php */ -class LanguageHsbTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'two', 'few', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'one', 101 ), - array( 'one', 90001 ), - array( 'two', 2 ), - array( 'few', 3 ), - array( 'few', 203 ), - array( 'few', 4 ), - array( 'other', 99 ), - array( 'other', 555 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageHuTest.php b/tests/phpunit/languages/LanguageHuTest.php deleted file mode 100644 index ee9197d7..00000000 --- a/tests/phpunit/languages/LanguageHuTest.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/LanguageHu.php */ -class LanguageHuTest extends LanguageClassesTestCase { - /** - * @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 ) ); - } - - public static function providePlural() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageHyTest.php b/tests/phpunit/languages/LanguageHyTest.php deleted file mode 100644 index 92e0ef94..00000000 --- a/tests/phpunit/languages/LanguageHyTest.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for Armenian (Հայերեն) */ -class LanguageHyTest extends LanguageClassesTestCase { - /** - * @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 ) ); - } - - public static function providePlural() { - return array( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageKshTest.php b/tests/phpunit/languages/LanguageKshTest.php deleted file mode 100644 index 568a3780..00000000 --- a/tests/phpunit/languages/LanguageKshTest.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageKsh.php */ -class LanguageKshTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'other', 'zero' ); - $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 ) ); - } - - public static function providePlural() { - return array( - array( 'zero', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageLnTest.php b/tests/phpunit/languages/LanguageLnTest.php deleted file mode 100644 index 10b3234f..00000000 --- a/tests/phpunit/languages/LanguageLnTest.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageLn.php */ -class LanguageLnTest extends LanguageClassesTestCase { - /** - * @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 ) ); - } - - public static function providePlural() { - return array( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageLtTest.php b/tests/phpunit/languages/LanguageLtTest.php deleted file mode 100644 index 30642f62..00000000 --- a/tests/phpunit/languages/LanguageLtTest.php +++ /dev/null @@ -1,63 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/LanguageLt.php */ -class LanguageLtTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'few', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 9 ), - array( 'other', 10 ), - array( 'other', 11 ), - array( 'other', 20 ), - array( 'one', 21 ), - array( 'few', 32 ), - array( 'one', 41 ), - array( 'one', 40001 ), - ); - } - - /** - * @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( '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 deleted file mode 100644 index 7120cfe3..00000000 --- a/tests/phpunit/languages/LanguageLvTest.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for Latvian */ -class LanguageLvTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'zero', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'zero', 0 ), - array( 'one', 1 ), - array( 'zero', 11 ), - array( 'one', 21 ), - array( 'zero', 411 ), - array( 'other', 2 ), - array( 'other', 9 ), - array( 'zero', 12 ), - array( 'other', 12.345 ), - array( 'zero', 20 ), - array( 'other', 22 ), - array( 'one', 31 ), - array( 'zero', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageMgTest.php b/tests/phpunit/languages/LanguageMgTest.php deleted file mode 100644 index 65e8fd7b..00000000 --- a/tests/phpunit/languages/LanguageMgTest.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageMg.php */ -class LanguageMgTest extends LanguageClassesTestCase { - /** - * @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 ) ); - } - - public static function providePlural() { - return array( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - array( 'other', 123.3434 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageMkTest.php b/tests/phpunit/languages/LanguageMkTest.php deleted file mode 100644 index ed155263..00000000 --- a/tests/phpunit/languages/LanguageMkTest.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for македонски/Macedonian */ -class LanguageMkTest extends LanguageClassesTestCase { - /** - * @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 ) ); - } - - public static function providePlural() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'one', 11 ), - array( 'one', 21 ), - 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 deleted file mode 100644 index 4fa45ce3..00000000 --- a/tests/phpunit/languages/LanguageMlTest.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2011, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/LanguageMl.php */ -class LanguageMlTest extends LanguageClassesTestCase { - - /** - * @dataProvider providerFormatNum - * @see bug 29495 - * @covers Language::formatNum - */ - public function testFormatNum( $result, $value ) { - $this->assertEquals( $result, $this->getLang()->formatNum( $value ) ); - } - - public static function providerFormatNum() { - return array( - array( '12,34,567', '1234567' ), - array( '12,345', '12345' ), - array( '1', '1' ), - array( '123', '123' ), - array( '1,234', '1234' ), - array( '12,345.56', '12345.56' ), - array( '12,34,56,79,81,23,45,678', '12345679812345678' ), - array( '.12345', '.12345' ), - array( '-12,00,000', '-1200000' ), - array( '-98', '-98' ), - array( '-98', -98 ), - array( '-1,23,45,678', -12345678 ), - array( '', '' ), - array( '', null ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageMoTest.php b/tests/phpunit/languages/LanguageMoTest.php deleted file mode 100644 index e0e54ca8..00000000 --- a/tests/phpunit/languages/LanguageMoTest.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageMo.php */ -class LanguageMoTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'few', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'few', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 19 ), - array( 'other', 20 ), - array( 'other', 99 ), - array( 'other', 100 ), - array( 'few', 101 ), - array( 'few', 119 ), - array( 'other', 120 ), - array( 'other', 200 ), - array( 'few', 201 ), - array( 'few', 219 ), - array( 'other', 220 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageMtTest.php b/tests/phpunit/languages/LanguageMtTest.php deleted file mode 100644 index 96d2bc92..00000000 --- a/tests/phpunit/languages/LanguageMtTest.php +++ /dev/null @@ -1,77 +0,0 @@ -<?php -/** - * @author Amir E. Aharoni - * @copyright Copyright © 2012, Amir E. Aharoni - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageMt.php */ -class LanguageMtTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'few', 'many', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'few', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 10 ), - array( 'many', 11 ), - array( 'many', 19 ), - array( 'other', 20 ), - array( 'other', 99 ), - array( 'other', 100 ), - array( 'other', 101 ), - array( 'few', 102 ), - array( 'few', 110 ), - array( 'many', 111 ), - array( 'many', 119 ), - array( 'other', 120 ), - array( 'other', 201 ), - ); - } - - /** - * @dataProvider providePluralTwoForms - * @covers Language::convertPlural - */ - public function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); - } - - public static function providePluralTwoForms() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - 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 deleted file mode 100644 index 26bd691a..00000000 --- a/tests/phpunit/languages/LanguageNlTest.php +++ /dev/null @@ -1,24 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2011, Santhosh Thottingal - * @file - */ - -/** Tests for MediaWiki languages/LanguageNl.php */ -class LanguageNlTest extends LanguageClassesTestCase { - - /** - * @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' ) ); - $this->assertEquals( '123', $this->getLang()->formatNum( '123' ) ); - $this->assertEquals( '1.234', $this->getLang()->formatNum( '1234' ) ); - $this->assertEquals( '12.345,56', $this->getLang()->formatNum( '12345.56' ) ); - $this->assertEquals( ',1234556', $this->getLang()->formatNum( '.1234556' ) ); - } -} diff --git a/tests/phpunit/languages/LanguageNsoTest.php b/tests/phpunit/languages/LanguageNsoTest.php deleted file mode 100644 index 18efd736..00000000 --- a/tests/phpunit/languages/LanguageNsoTest.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php -/** - * @author Amir E. Aharoni - * @copyright Copyright © 2012, Amir E. Aharoni - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageNso.php */ -class LanguageNsoTest extends LanguageClassesTestCase { - /** - * @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 ) ); - } - - public static function providePlural() { - return array( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguagePlTest.php b/tests/phpunit/languages/LanguagePlTest.php deleted file mode 100644 index d180037b..00000000 --- a/tests/phpunit/languages/LanguagePlTest.php +++ /dev/null @@ -1,77 +0,0 @@ -<?php -/** - * @author Amir E. Aharoni - * @copyright Copyright © 2012, Amir E. Aharoni - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguagePl.php */ -class LanguagePlTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'few', 'many' ); - $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 ) ); - } - - public static function providePlural() { - return array( - array( 'many', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'many', 5 ), - array( 'many', 9 ), - array( 'many', 10 ), - array( 'many', 11 ), - array( 'many', 21 ), - array( 'few', 22 ), - array( 'few', 23 ), - array( 'few', 24 ), - array( 'many', 25 ), - array( 'many', 200 ), - array( 'many', 201 ), - ); - } - - /** - * @dataProvider providePluralTwoForms - * @covers Language::convertPlural - */ - public function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); - } - - public static function providePluralTwoForms() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - 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 deleted file mode 100644 index ae7816bc..00000000 --- a/tests/phpunit/languages/LanguageRoTest.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php -/** - * @author Amir E. Aharoni - * @copyright Copyright © 2012, Amir E. Aharoni - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageRo.php */ -class LanguageRoTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'few', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'few', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 19 ), - array( 'other', 20 ), - array( 'other', 99 ), - array( 'other', 100 ), - array( 'few', 101 ), - array( 'few', 119 ), - array( 'other', 120 ), - array( 'other', 200 ), - array( 'few', 201 ), - array( 'few', 219 ), - array( 'other', 220 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageRuTest.php b/tests/phpunit/languages/LanguageRuTest.php deleted file mode 100644 index e17c7085..00000000 --- a/tests/phpunit/languages/LanguageRuTest.php +++ /dev/null @@ -1,105 +0,0 @@ -<?php -/** - * @author Amir E. Aharoni - * based on LanguageBe_tarask.php - * @copyright Copyright © 2012, Amir E. Aharoni - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageRu.php */ -class LanguageRuTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'many', 'other' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); - } - - /** - * Test explicit plural forms - n=FormN forms - * @covers Language::convertPlural - */ - public function testExplicitPlural() { - $forms = array( 'one','many', 'other', '12=dozen' ); - $this->assertEquals( 'dozen', $this->getLang()->convertPlural( 12, $forms ) ); - $forms = array( 'one', 'many', '100=hundred', 'other', '12=dozen' ); - $this->assertEquals( 'hundred', $this->getLang()->convertPlural( 100, $forms ) ); - } - - /** - * @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 ), - array( 'one', 91 ), - array( 'one', 121 ), - array( 'other', 2 ), - array( 'other', 3 ), - array( 'other', 4 ), - array( 'other', 334 ), - array( 'many', 5 ), - array( 'many', 15 ), - array( 'many', 120 ), - ); - } - - /** - * @dataProvider providePluralTwoForms - * @covers Language::convertPlural - */ - public function testPluralTwoForms( $result, $value ) { - $forms = array( '1=one', 'other' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); - } - - public static function providePluralTwoForms() { - return array( - array( 'one', 1 ), - array( 'other', 11 ), - array( 'other', 91 ), - array( 'other', 121 ), - ); - } - - /** - * @dataProvider providerGrammar - * @covers Language::convertGrammar - */ - public function testGrammar( $result, $word, $case ) { - $this->assertEquals( $result, $this->getLang()->convertGrammar( $word, $case ) ); - } - - public static function providerGrammar() { - return array( - array( - 'Википедии', - 'Википедия', - 'genitive', - ), - array( - 'Викитеки', - 'Викитека', - 'genitive', - ), - array( - 'Викитеке', - 'Викитека', - 'prepositional', - ), - array( - 'Викиданных', - 'Викиданные', - 'prepositional', - ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageSeTest.php b/tests/phpunit/languages/LanguageSeTest.php deleted file mode 100644 index 533aa2bc..00000000 --- a/tests/phpunit/languages/LanguageSeTest.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -/** - * @author Amir E. Aharoni - * @copyright Copyright © 2012, Amir E. Aharoni - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageSe.php */ -class LanguageSeTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'two', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'two', 2 ), - array( 'other', 3 ), - ); - } - - /** - * @dataProvider providePluralTwoForms - * @covers Language::convertPlural - */ - public function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); - } - - public static function providePluralTwoForms() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 3 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageSgsTest.php b/tests/phpunit/languages/LanguageSgsTest.php deleted file mode 100644 index fa49a4dd..00000000 --- a/tests/phpunit/languages/LanguageSgsTest.php +++ /dev/null @@ -1,71 +0,0 @@ -<?php -/** - * @author Amir E. Aharoni - * @copyright Copyright © 2012, Amir E. Aharoni - * @file - */ - -/** Tests for Samogitian */ -class LanguageSgsTest extends LanguageClassesTestCase { - /** - * @dataProvider providePluralAllForms - * @covers Language::convertPlural - */ - public function testPluralAllForms( $result, $value ) { - $forms = array( 'one', 'two', 'few', 'other' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); - } - - /** - * @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 ), - array( 'two', 2 ), - array( 'other', 3 ), - array( 'few', 10 ), - array( 'few', 11 ), - array( 'few', 12 ), - array( 'few', 19 ), - array( 'other', 20 ), - array( 'few', 100 ), - array( 'one', 101 ), - array( 'few', 111 ), - array( 'few', 112 ), - ); - } - - /** - * @dataProvider providePluralTwoForms - * @covers Language::convertPlural - */ - public function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); - } - - public static function providePluralTwoForms() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 3 ), - array( 'other', 10 ), - array( 'other', 11 ), - array( 'other', 12 ), - array( 'other', 19 ), - array( 'other', 20 ), - array( 'other', 100 ), - array( 'one', 101 ), - array( 'other', 111 ), - array( 'other', 112 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageShTest.php b/tests/phpunit/languages/LanguageShTest.php deleted file mode 100644 index 1b390872..00000000 --- a/tests/phpunit/languages/LanguageShTest.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** - * @author Amir E. Aharoni - * @copyright Copyright © 2012, Amir E. Aharoni - * @file - */ - -/** Tests for srpskohrvatski / српскохрватски / Serbocroatian */ -class LanguageShTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'few', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 4 ), - array( 'other', 5 ), - array( 'other', 10 ), - array( 'other', 11 ), - array( 'other', 12 ), - array( 'one', 101 ), - array( 'few', 102 ), - array( 'other', 111 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageSkTest.php b/tests/phpunit/languages/LanguageSkTest.php deleted file mode 100644 index cb8a13b8..00000000 --- a/tests/phpunit/languages/LanguageSkTest.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Amir E. Aharoni - * based on LanguageSkTest.php - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageSk.php */ -class LanguageSkTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'few', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'other', 5 ), - array( 'other', 11 ), - array( 'other', 20 ), - array( 'other', 25 ), - array( 'other', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageSlTest.php b/tests/phpunit/languages/LanguageSlTest.php deleted file mode 100644 index 9783dd80..00000000 --- a/tests/phpunit/languages/LanguageSlTest.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * @author Santhosh Thottingal - * @copyright Copyright © 2012, Amir E. Aharoni - * based on LanguageSkTest.php - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageSl.php */ -class LanguageSlTest extends LanguageClassesTestCase { - /** - * @dataProvider providerPlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'two', 'few', 'other' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); - } - - /** - * @dataProvider providerPlural - * @covers Language::getPluralRuleType - */ - public function testGetPluralRuleType( $result, $value ) { - $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); - } - - public static function providerPlural() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'two', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'other', 5 ), - array( 'other', 99 ), - array( 'other', 100 ), - array( 'one', 101 ), - array( 'two', 102 ), - array( 'few', 103 ), - array( 'one', 201 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageSmaTest.php b/tests/phpunit/languages/LanguageSmaTest.php deleted file mode 100644 index 95cb333c..00000000 --- a/tests/phpunit/languages/LanguageSmaTest.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -/** - * @author Amir E. Aharoni - * @copyright Copyright © 2012, Amir E. Aharoni - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageSma.php */ -class LanguageSmaTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'two', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'two', 2 ), - array( 'other', 3 ), - ); - } - - /** - * @dataProvider providePluralTwoForms - * @covers Language::convertPlural - */ - public function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); - } - - public static function providePluralTwoForms() { - return array( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 3 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageSrTest.php b/tests/phpunit/languages/LanguageSrTest.php deleted file mode 100644 index d6fedb57..00000000 --- a/tests/phpunit/languages/LanguageSrTest.php +++ /dev/null @@ -1,246 +0,0 @@ -<?php -/** - * PHPUnit tests for the Serbian language. - * The language can be represented using two scripts: - * - Latin (SR_el) - * - Cyrillic (SR_ec) - * Both representations seems to be bijective, hence MediaWiki can convert - * from one script to the other. - * - * @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.. - */ - -/** Tests for MediaWiki languages/LanguageSr.php */ -class LanguageSrTest extends LanguageClassesTestCase { - /** - * @covers LanguageConverter::convertTo - */ - public function testEasyConversions() { - $this->assertCyrillic( - 'шђчћжШЂЧЋЖ', - 'Cyrillic guessing characters' - ); - $this->assertLatin( - 'šđč枊ĐČĆŽ', - 'Latin guessing characters' - ); - } - - /** - * @covers LanguageConverter::convertTo - */ - public function testMixedConversions() { - $this->assertCyrillic( - 'шђчћжШЂЧЋЖ - šđčćž', - 'Mostly cyrillic characters' - ); - $this->assertLatin( - 'šđč枊ĐČĆŽ - шђчћж', - 'Mostly latin characters' - ); - } - - /** - * @covers LanguageConverter::convertTo - */ - public function testSameAmountOfLatinAndCyrillicGetConverted() { - $this->assertConverted( - '4 latin: šđčć | 4 cyrillic: шђчћ', - 'sr-ec' - ); - $this->assertConverted( - '4 latin: šđčć | 4 cyrillic: шђчћ', - 'sr-el' - ); - } - - /** - * @author Nikola Smolenski - * @covers LanguageConverter::convertTo - */ - public function testConversionToCyrillic() { - //A simple convertion of Latin to Cyrillic - $this->assertEquals( 'абвг', - $this->convertToCyrillic( 'abvg' ) - ); - //Same as above, but assert that -{}-s must be removed and not converted - $this->assertEquals( 'ljабnjвгdž', - $this->convertToCyrillic( '-{lj}-ab-{nj}-vg-{dž}-' ) - ); - //A simple convertion of Cyrillic to Cyrillic - $this->assertEquals( 'абвг', - $this->convertToCyrillic( 'абвг' ) - ); - //Same as above, but assert that -{}-s must be removed and not converted - $this->assertEquals( 'ljабnjвгdž', - $this->convertToCyrillic( '-{lj}-аб-{nj}-вг-{dž}-' ) - ); - //This text has some Latin, but is recognized as Cyrillic, so it should not be converted - $this->assertEquals( 'abvgшђжчћ', - $this->convertToCyrillic( 'abvgшђжчћ' ) - ); - //Same as above, but assert that -{}-s must be removed - $this->assertEquals( 'љabvgњшђжчћџ', - $this->convertToCyrillic( '-{љ}-abvg-{њ}-шђжчћ-{џ}-' ) - ); - //This text has some Cyrillic, but is recognized as Latin, so it should be converted - $this->assertEquals( 'абвгшђжчћ', - $this->convertToCyrillic( 'абвгšđžčć' ) - ); - //Same as above, but assert that -{}-s must be removed and not converted - $this->assertEquals( 'ljабвгnjшђжчћdž', - $this->convertToCyrillic( '-{lj}-абвг-{nj}-šđžčć-{dž}-' ) - ); - // Roman numerals are not converted - $this->assertEquals( 'а I б II в III г IV шђжчћ', - $this->convertToCyrillic( 'a I b II v III g IV šđžčć' ) - ); - } - - /** - * @covers LanguageConverter::convertTo - */ - public function testConversionToLatin() { - //A simple convertion of Latin to Latin - $this->assertEquals( 'abcd', - $this->convertToLatin( 'abcd' ) - ); - //A simple convertion of Cyrillic to Latin - $this->assertEquals( 'abcd', - $this->convertToLatin( 'абцд' ) - ); - //This text has some Latin, but is recognized as Cyrillic, so it should be converted - $this->assertEquals( 'abcdšđžčć', - $this->convertToLatin( 'abcdшђжчћ' ) - ); - //This text has some Cyrillic, but is recognized as Latin, so it should not be converted - $this->assertEquals( 'абцдšđžčć', - $this->convertToLatin( 'абцдšđžčć' ) - ); - } - - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'few', '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 ) ); - } - - public static function providePlural() { - return array( - array( 'one', 1 ), - array( 'other', 11 ), - array( 'one', 91 ), - array( 'one', 121 ), - array( 'few', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'few', 334 ), - array( 'other', 5 ), - array( 'other', 15 ), - array( 'other', 120 ), - ); - } - - /** - * @dataProvider providePluralTwoForms - * @covers Language::convertPlural - */ - public function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); - } - - public static function providePluralTwoForms() { - return array( - array( 'one', 1 ), - array( 'other', 11 ), - array( 'other', 4 ), - array( 'one', 91 ), - array( 'one', 121 ), - ); - } - - ##### HELPERS ##################################################### - /** - *Wrapper to verify text stay the same after applying conversion - * @param $text string Text to convert - * @param $variant string Language variant 'sr-ec' or 'sr-el' - * @param $msg string Optional message - */ - protected function assertUnConverted( $text, $variant, $msg = '' ) { - $this->assertEquals( - $text, - $this->convertTo( $text, $variant ), - $msg - ); - } - - /** - * Wrapper to verify a text is different once converted to a variant. - * @param $text string Text to convert - * @param $variant string Language variant 'sr-ec' or 'sr-el' - * @param $msg string Optional message - */ - protected function assertConverted( $text, $variant, $msg = '' ) { - $this->assertNotEquals( - $text, - $this->convertTo( $text, $variant ), - $msg - ); - } - - /** - * Verifiy the given Cyrillic text is not converted when using - * using the cyrillic variant and converted to Latin when using - * the Latin variant. - */ - protected function assertCyrillic( $text, $msg = '' ) { - $this->assertUnConverted( $text, 'sr-ec', $msg ); - $this->assertConverted( $text, 'sr-el', $msg ); - } - - /** - * Verifiy the given Latin text is not converted when using - * using the Latin variant and converted to Cyrillic when using - * the Cyrillic variant. - */ - protected function assertLatin( $text, $msg = '' ) { - $this->assertUnConverted( $text, 'sr-el', $msg ); - $this->assertConverted( $text, 'sr-ec', $msg ); - } - - - /** Wrapper for converter::convertTo() method*/ - protected function convertTo( $text, $variant ) { - return $this->getLang() - ->mConverter - ->convertTo( - $text, $variant - ); - } - - protected function convertToCyrillic( $text ) { - return $this->convertTo( $text, 'sr-ec' ); - } - - protected function convertToLatin( $text ) { - return $this->convertTo( $text, 'sr-el' ); - } -} diff --git a/tests/phpunit/languages/LanguageTest.php b/tests/phpunit/languages/LanguageTest.php deleted file mode 100644 index 78929e23..00000000 --- a/tests/phpunit/languages/LanguageTest.php +++ /dev/null @@ -1,1567 +0,0 @@ -<?php - -class LanguageTest extends LanguageClassesTestCase { - /** - * @covers Language::convertDoubleWidth - * @covers Language::normalizeForSearch - */ - public function testLanguageConvertDoubleWidthToSingleWidth() { - $this->assertEquals( - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", - $this->getLang()->normalizeForSearch( - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - ), - 'convertDoubleWidth() with the full alphabet and digits' - ); - } - - /** - * @dataProvider provideFormattableTimes# - * @covers Language::formatTimePeriod - */ - public function testFormatTimePeriod( $seconds, $format, $expected, $desc ) { - $this->assertEquals( $expected, $this->getLang()->formatTimePeriod( $seconds, $format ), $desc ); - } - - public static function provideFormattableTimes() { - return array( - array( - 9.45, - array(), - '9.5 s', - 'formatTimePeriod() rounding (<10s)' - ), - array( - 9.45, - array( 'noabbrevs' => true ), - '9.5 seconds', - 'formatTimePeriod() rounding (<10s)' - ), - array( - 9.95, - array(), - '10 s', - 'formatTimePeriod() rounding (<10s)' - ), - array( - 9.95, - array( 'noabbrevs' => true ), - '10 seconds', - 'formatTimePeriod() rounding (<10s)' - ), - array( - 59.55, - array(), - '1 min 0 s', - 'formatTimePeriod() rounding (<60s)' - ), - array( - 59.55, - array( 'noabbrevs' => true ), - '1 minute 0 seconds', - 'formatTimePeriod() rounding (<60s)' - ), - array( - 119.55, - array(), - '2 min 0 s', - 'formatTimePeriod() rounding (<1h)' - ), - array( - 119.55, - array( 'noabbrevs' => true ), - '2 minutes 0 seconds', - 'formatTimePeriod() rounding (<1h)' - ), - array( - 3599.55, - array(), - '1 h 0 min 0 s', - 'formatTimePeriod() rounding (<1h)' - ), - array( - 3599.55, - array( 'noabbrevs' => true ), - '1 hour 0 minutes 0 seconds', - 'formatTimePeriod() rounding (<1h)' - ), - array( - 7199.55, - array(), - '2 h 0 min 0 s', - 'formatTimePeriod() rounding (>=1h)' - ), - array( - 7199.55, - array( 'noabbrevs' => true ), - '2 hours 0 minutes 0 seconds', - 'formatTimePeriod() rounding (>=1h)' - ), - array( - 7199.55, - 'avoidseconds', - '2 h 0 min', - 'formatTimePeriod() rounding (>=1h), avoidseconds' - ), - array( - 7199.55, - array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), - '2 hours 0 minutes', - 'formatTimePeriod() rounding (>=1h), avoidseconds' - ), - array( - 7199.55, - 'avoidminutes', - '2 h 0 min', - 'formatTimePeriod() rounding (>=1h), avoidminutes' - ), - array( - 7199.55, - array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ), - '2 hours 0 minutes', - 'formatTimePeriod() rounding (>=1h), avoidminutes' - ), - array( - 172799.55, - 'avoidseconds', - '48 h 0 min', - 'formatTimePeriod() rounding (=48h), avoidseconds' - ), - array( - 172799.55, - array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), - '48 hours 0 minutes', - 'formatTimePeriod() rounding (=48h), avoidseconds' - ), - array( - 259199.55, - 'avoidminutes', - '3 d 0 h', - 'formatTimePeriod() rounding (>48h), avoidminutes' - ), - array( - 259199.55, - array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ), - '3 days 0 hours', - 'formatTimePeriod() rounding (>48h), avoidminutes' - ), - array( - 176399.55, - 'avoidseconds', - '2 d 1 h 0 min', - 'formatTimePeriod() rounding (>48h), avoidseconds' - ), - array( - 176399.55, - array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), - '2 days 1 hour 0 minutes', - 'formatTimePeriod() rounding (>48h), avoidseconds' - ), - array( - 176399.55, - 'avoidminutes', - '2 d 1 h', - 'formatTimePeriod() rounding (>48h), avoidminutes' - ), - array( - 176399.55, - array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ), - '2 days 1 hour', - 'formatTimePeriod() rounding (>48h), avoidminutes' - ), - array( - 259199.55, - 'avoidseconds', - '3 d 0 h 0 min', - 'formatTimePeriod() rounding (>48h), avoidseconds' - ), - array( - 259199.55, - array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), - '3 days 0 hours 0 minutes', - 'formatTimePeriod() rounding (>48h), avoidseconds' - ), - array( - 172801.55, - 'avoidseconds', - '2 d 0 h 0 min', - 'formatTimePeriod() rounding, (>48h), avoidseconds' - ), - array( - 172801.55, - array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), - '2 days 0 hours 0 minutes', - 'formatTimePeriod() rounding, (>48h), avoidseconds' - ), - array( - 176460.55, - array(), - '2 d 1 h 1 min 1 s', - 'formatTimePeriod() rounding, recursion, (>48h)' - ), - array( - 176460.55, - array( 'noabbrevs' => true ), - '2 days 1 hour 1 minute 1 second', - 'formatTimePeriod() rounding, recursion, (>48h)' - ), - ); - } - - /** - * @covers Language::truncate - */ - public function testTruncate() { - $this->assertEquals( - "XXX", - $this->getLang()->truncate( "1234567890", 0, 'XXX' ), - 'truncate prefix, len 0, small ellipsis' - ); - - $this->assertEquals( - "12345XXX", - $this->getLang()->truncate( "1234567890", 8, 'XXX' ), - 'truncate prefix, small ellipsis' - ); - - $this->assertEquals( - "123456789", - $this->getLang()->truncate( "123456789", 5, 'XXXXXXXXXXXXXXX' ), - 'truncate prefix, large ellipsis' - ); - - $this->assertEquals( - "XXX67890", - $this->getLang()->truncate( "1234567890", -8, 'XXX' ), - 'truncate suffix, small ellipsis' - ); - - $this->assertEquals( - "123456789", - $this->getLang()->truncate( "123456789", -5, 'XXXXXXXXXXXXXXX' ), - 'truncate suffix, large ellipsis' - ); - } - - /** - * @dataProvider provideHTMLTruncateData - * @covers Language::truncateHTML - */ - public function testTruncateHtml( $len, $ellipsis, $input, $expected ) { - // Actual HTML... - $this->assertEquals( - $expected, - $this->getLang()->truncateHTML( $input, $len, $ellipsis ) - ); - } - - /** - * @return array format is ($len, $ellipsis, $input, $expected) - */ - public static function provideHTMLTruncateData() { - return array( - array( 0, 'XXX', "1234567890", "XXX" ), - array( 8, 'XXX', "1234567890", "12345XXX" ), - array( 5, 'XXXXXXXXXXXXXXX', '1234567890', "1234567890" ), - array( 2, '***', - '<p><span style="font-weight:bold;"></span></p>', - '<p><span style="font-weight:bold;"></span></p>', - ), - array( 2, '***', - '<p><span style="font-weight:bold;">123456789</span></p>', - '<p><span style="font-weight:bold;">***</span></p>', - ), - array( 2, '***', - '<p><span style="font-weight:bold;"> 23456789</span></p>', - '<p><span style="font-weight:bold;">***</span></p>', - ), - array( 3, '***', - '<p><span style="font-weight:bold;">123456789</span></p>', - '<p><span style="font-weight:bold;">***</span></p>', - ), - array( 4, '***', - '<p><span style="font-weight:bold;">123456789</span></p>', - '<p><span style="font-weight:bold;">1***</span></p>', - ), - array( 5, '***', - '<tt><span style="font-weight:bold;">123456789</span></tt>', - '<tt><span style="font-weight:bold;">12***</span></tt>', - ), - array( 6, '***', - '<p><a href="www.mediawiki.org">123456789</a></p>', - '<p><a href="www.mediawiki.org">123***</a></p>', - ), - array( 6, '***', - '<p><a href="www.mediawiki.org">12 456789</a></p>', - '<p><a href="www.mediawiki.org">12 ***</a></p>', - ), - array( 7, '***', - '<small><span style="font-weight:bold;">123<p id="#moo">456</p>789</span></small>', - '<small><span style="font-weight:bold;">123<p id="#moo">4***</p></span></small>', - ), - array( 8, '***', - '<div><span style="font-weight:bold;">123<span>4</span>56789</span></div>', - '<div><span style="font-weight:bold;">123<span>4</span>5***</span></div>', - ), - array( 9, '***', - '<p><table style="font-weight:bold;"><tr><td>123456789</td></tr></table></p>', - '<p><table style="font-weight:bold;"><tr><td>123456789</td></tr></table></p>', - ), - array( 10, '***', - '<p><font style="font-weight:bold;">123456789</font></p>', - '<p><font style="font-weight:bold;">123456789</font></p>', - ), - ); - } - - /** - * Test Language::isWellFormedLanguageTag() - * @dataProvider provideWellFormedLanguageTags - * @covers Language::isWellFormedLanguageTag - */ - public function testWellFormedLanguageTag( $code, $message = '' ) { - $this->assertTrue( - Language::isWellFormedLanguageTag( $code ), - "validating code $code $message" - ); - } - - /** - * The test cases are based on the tests in the GaBuZoMeu parser - * written by Stéphane Bortzmeyer <bortzmeyer@nic.fr> - * and distributed as free software, under the GNU General Public Licence. - * http://www.bortzmeyer.org/gabuzomeu-parsing-language-tags.html - */ - public static function provideWellFormedLanguageTags() { - return array( - array( 'fr', 'two-letter code' ), - array( 'fr-latn', 'two-letter code with lower case script code' ), - array( 'fr-Latn-FR', 'two-letter code with title case script code and uppercase country code' ), - array( 'fr-Latn-419', 'two-letter code with title case script code and region number' ), - array( 'fr-FR', 'two-letter code with uppercase' ), - array( 'ax-TZ', 'Not in the registry, but well-formed' ), - array( 'fr-shadok', 'two-letter code with variant' ), - array( 'fr-y-myext-myext2', 'non-x singleton' ), - array( 'fra-Latn', 'ISO 639 can be 3-letters' ), - array( 'fra', 'three-letter language code' ), - array( 'fra-FX', 'three-letter language code with country code' ), - array( 'i-klingon', 'grandfathered with singleton' ), - array( 'I-kLINgon', 'tags are case-insensitive...' ), - array( 'no-bok', 'grandfathered without singleton' ), - array( 'i-enochian', 'Grandfathered' ), - array( 'x-fr-CH', 'private use' ), - array( 'es-419', 'two-letter code with region number' ), - array( 'en-Latn-GB-boont-r-extended-sequence-x-private', 'weird, but well-formed' ), - array( 'ab-x-abc-x-abc', 'anything goes after x' ), - array( 'ab-x-abc-a-a', 'anything goes after x, including several non-x singletons' ), - array( 'i-default', 'grandfathered' ), - array( 'abcd-Latn', 'Language of 4 chars reserved for future use' ), - array( 'AaBbCcDd-x-y-any-x', 'Language of 5-8 chars, registered' ), - array( 'de-CH-1901', 'with country and year' ), - array( 'en-US-x-twain', 'with country and singleton' ), - array( 'zh-cmn', 'three-letter variant' ), - array( 'zh-cmn-Hant', 'three-letter variant and script' ), - array( 'zh-cmn-Hant-HK', 'three-letter variant, script and country' ), - array( 'xr-p-lze', 'Extension' ), - ); - } - - /** - * Negative test for Language::isWellFormedLanguageTag() - * @dataProvider provideMalformedLanguageTags - * @covers Language::isWellFormedLanguageTag - */ - public function testMalformedLanguageTag( $code, $message = '' ) { - $this->assertFalse( - Language::isWellFormedLanguageTag( $code ), - "validating that code $code is a malformed language tag - $message" - ); - } - - /** - * The test cases are based on the tests in the GaBuZoMeu parser - * written by Stéphane Bortzmeyer <bortzmeyer@nic.fr> - * and distributed as free software, under the GNU General Public Licence. - * http://www.bortzmeyer.org/gabuzomeu-parsing-language-tags.html - */ - public static function provideMalformedLanguageTags() { - return array( - array( 'f', 'language too short' ), - array( 'f-Latn', 'language too short with script' ), - array( 'xr-lxs-qut', 'variants too short' ), # extlangS - array( 'fr-Latn-F', 'region too short' ), - array( 'a-value', 'language too short with region' ), - array( 'tlh-a-b-foo', 'valid three-letter with wrong variant' ), - array( 'i-notexist', 'grandfathered but not registered: invalid, even if we only test well-formedness' ), - array( 'abcdefghi-012345678', 'numbers too long' ), - array( 'ab-abc-abc-abc-abc', 'invalid extensions' ), - array( 'ab-abcd-abc', 'invalid extensions' ), - array( 'ab-ab-abc', 'invalid extensions' ), - array( 'ab-123-abc', 'invalid extensions' ), - array( 'a-Hant-ZH', 'short language with valid extensions' ), - array( 'a1-Hant-ZH', 'invalid character in language' ), - array( 'ab-abcde-abc', 'invalid extensions' ), - array( 'ab-1abc-abc', 'invalid characters in extensions' ), - array( 'ab-ab-abcd', 'invalid order of extensions' ), - array( 'ab-123-abcd', 'invalid order of extensions' ), - array( 'ab-abcde-abcd', 'invalid extensions' ), - array( 'ab-1abc-abcd', 'invalid characters in extensions' ), - array( 'ab-a-b', 'extensions too short' ), - array( 'ab-a-x', 'extensions too short, even with singleton' ), - array( 'ab--ab', 'two separators' ), - array( 'ab-abc-', 'separator in the end' ), - array( '-ab-abc', 'separator in the beginning' ), - array( 'abcd-efg', 'language too long' ), - array( 'aabbccddE', 'tag too long' ), - array( 'pa_guru', 'A tag with underscore is invalid in strict mode' ), - array( 'de-f', 'subtag too short' ), - ); - } - - /** - * Negative test for Language::isWellFormedLanguageTag() - * @covers Language::isWellFormedLanguageTag - */ - public function testLenientLanguageTag() { - $this->assertTrue( - Language::isWellFormedLanguageTag( 'pa_guru', true ), - 'pa_guru is a well-formed language tag in lenient mode' - ); - } - - /** - * Test Language::isValidBuiltInCode() - * @dataProvider provideLanguageCodes - * @covers Language::isValidBuiltInCode - */ - public function testBuiltInCodeValidation( $code, $message = '' ) { - $this->assertTrue( - (bool)Language::isValidBuiltInCode( $code ), - "validating code $code $message" - ); - } - - /** - * @covers Language::isValidBuiltInCode - */ - public function testBuiltInCodeValidationRejectUnderscore() { - $this->assertFalse( - (bool)Language::isValidBuiltInCode( 'be_tarask' ), - "reject underscore in language code" - ); - } - - public static function provideLanguageCodes() { - return array( - array( 'fr', 'Two letters, minor case' ), - array( 'EN', 'Two letters, upper case' ), - array( 'tyv', 'Three letters' ), - array( 'tokipona', 'long language code' ), - array( 'be-tarask', 'With dash' ), - array( 'Zh-classical', 'Begin with upper case, dash' ), - array( 'Be-x-old', 'With extension (two dashes)' ), - ); - } - - /** - * Test Language::isKnownLanguageTag() - * @dataProvider provideKnownLanguageTags - * @covers Language::isKnownLanguageTag - */ - public function testKnownLanguageTag( $code, $message = '' ) { - $this->assertTrue( - (bool)Language::isKnownLanguageTag( $code ), - "validating code $code - $message" - ); - } - - public static function provideKnownLanguageTags() { - return array( - array( 'fr', 'simple code' ), - array( 'bat-smg', 'an MW legacy tag' ), - array( 'sgs', 'an internal standard MW name, for which a legacy tag is used externally' ), - ); - } - - /** - * @covers Language::isKnownLanguageTag - */ - public function testKnownCldrLanguageTag() { - if ( !class_exists( 'LanguageNames' ) ) { - $this->markTestSkipped( 'The LanguageNames class is not available. The cldr extension is probably not installed.' ); - } - - $this->assertTrue( - (bool)Language::isKnownLanguageTag( 'pal' ), - 'validating code "pal" an ancient language, which probably will not appear in Names.php, but appears in CLDR in English' - ); - } - - /** - * Negative tests for Language::isKnownLanguageTag() - * @dataProvider provideUnKnownLanguageTags - * @covers Language::isKnownLanguageTag - */ - public function testUnknownLanguageTag( $code, $message = '' ) { - $this->assertFalse( - (bool)Language::isKnownLanguageTag( $code ), - "checking that code $code is invalid - $message" - ); - } - - 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 - */ - public function testSprintfDate( $format, $ts, $expected, $msg ) { - $this->assertEquals( - $expected, - $this->getLang()->sprintfDate( $format, $ts ), - "sprintfDate('$format', '$ts'): $msg" - ); - } - - /** - * sprintfDate should always use UTC when no zone is given. - * @dataProvider provideSprintfDateSamples - * @covers Language::sprintfDate - */ - public function testSprintfDateNoZone( $format, $ts, $expected, $ignore, $msg ) { - $oldTZ = date_default_timezone_get(); - $res = date_default_timezone_set( 'Asia/Seoul' ); - if ( !$res ) { - $this->markTestSkipped( "Error setting Timezone" ); - } - - $this->assertEquals( - $expected, - $this->getLang()->sprintfDate( $format, $ts ), - "sprintfDate('$format', '$ts'): $msg" - ); - - date_default_timezone_set( $oldTZ ); - } - - /** - * 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 - array( - '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' - ), - - ); - } - - /** - * @dataProvider provideFormatSizes - * @covers Language::formatSize - */ - public function testFormatSize( $size, $expected, $msg ) { - $this->assertEquals( - $expected, - $this->getLang()->formatSize( $size ), - "formatSize('$size'): $msg" - ); - } - - public static function provideFormatSizes() { - return array( - array( - 0, - "0 B", - "Zero bytes" - ), - array( - 1024, - "1 KB", - "1 kilobyte" - ), - array( - 1024 * 1024, - "1 MB", - "1,024 megabytes" - ), - array( - 1024 * 1024 * 1024, - "1 GB", - "1 gigabytes" - ), - array( - pow( 1024, 4 ), - "1 TB", - "1 terabyte" - ), - array( - pow( 1024, 5 ), - "1 PB", - "1 petabyte" - ), - array( - pow( 1024, 6 ), - "1 EB", - "1,024 exabyte" - ), - array( - pow( 1024, 7 ), - "1 ZB", - "1 zetabyte" - ), - array( - pow( 1024, 8 ), - "1 YB", - "1 yottabyte" - ), - // How big!? THIS BIG! - ); - } - - /** - * @dataProvider provideFormatBitrate - * @covers Language::formatBitrate - */ - public function testFormatBitrate( $bps, $expected, $msg ) { - $this->assertEquals( - $expected, - $this->getLang()->formatBitrate( $bps ), - "formatBitrate('$bps'): $msg" - ); - } - - public static function provideFormatBitrate() { - return array( - array( - 0, - "0 bps", - "0 bits per second" - ), - array( - 999, - "999 bps", - "999 bits per second" - ), - array( - 1000, - "1 kbps", - "1 kilobit per second" - ), - array( - 1000 * 1000, - "1 Mbps", - "1 megabit per second" - ), - array( - pow( 10, 9 ), - "1 Gbps", - "1 gigabit per second" - ), - array( - pow( 10, 12 ), - "1 Tbps", - "1 terabit per second" - ), - array( - pow( 10, 15 ), - "1 Pbps", - "1 petabit per second" - ), - array( - pow( 10, 18 ), - "1 Ebps", - "1 exabit per second" - ), - array( - pow( 10, 21 ), - "1 Zbps", - "1 zetabit per second" - ), - array( - pow( 10, 24 ), - "1 Ybps", - "1 yottabit per second" - ), - array( - pow( 10, 27 ), - "1,000 Ybps", - "1,000 yottabits per second" - ), - ); - } - - - /** - * @dataProvider provideFormatDuration - * @covers Language::formatDuration - */ - public function testFormatDuration( $duration, $expected, $intervals = array() ) { - $this->assertEquals( - $expected, - $this->getLang()->formatDuration( $duration, $intervals ), - "formatDuration('$duration'): $expected" - ); - } - - public static function provideFormatDuration() { - return array( - array( - 0, - '0 seconds', - ), - array( - 1, - '1 second', - ), - array( - 2, - '2 seconds', - ), - array( - 60, - '1 minute', - ), - array( - 2 * 60, - '2 minutes', - ), - array( - 3600, - '1 hour', - ), - array( - 2 * 3600, - '2 hours', - ), - array( - 24 * 3600, - '1 day', - ), - array( - 2 * 86400, - '2 days', - ), - array( - // ( 365 + ( 24 * 3 + 25 ) / 400 ) * 86400 = 31556952 - ( 365 + ( 24 * 3 + 25 ) / 400.0 ) * 86400, - '1 year', - ), - array( - 2 * 31556952, - '2 years', - ), - array( - 10 * 31556952, - '1 decade', - ), - array( - 20 * 31556952, - '2 decades', - ), - array( - 100 * 31556952, - '1 century', - ), - array( - 200 * 31556952, - '2 centuries', - ), - array( - 1000 * 31556952, - '1 millennium', - ), - array( - 2000 * 31556952, - '2 millennia', - ), - array( - 9001, - '2 hours, 30 minutes and 1 second' - ), - array( - 3601, - '1 hour and 1 second' - ), - array( - 31556952 + 2 * 86400 + 9000, - '1 year, 2 days, 2 hours and 30 minutes' - ), - array( - 42 * 1000 * 31556952 + 42, - '42 millennia and 42 seconds' - ), - array( - 60, - '60 seconds', - array( 'seconds' ), - ), - array( - 61, - '61 seconds', - array( 'seconds' ), - ), - array( - 1, - '1 second', - array( 'seconds' ), - ), - array( - 31556952 + 2 * 86400 + 9000, - '1 year, 2 days and 150 minutes', - array( 'years', 'days', 'minutes' ), - ), - array( - 42, - '0 days', - array( 'years', 'days' ), - ), - array( - 31556952 + 2 * 86400 + 9000, - '1 year, 2 days and 150 minutes', - array( 'minutes', 'days', 'years' ), - ), - array( - 42, - '0 days', - array( 'days', 'years' ), - ), - ); - } - - /** - * @dataProvider provideCheckTitleEncodingData - * @covers Language::checkTitleEncoding - */ - public function testCheckTitleEncoding( $s ) { - $this->assertEquals( - $s, - $this->getLang()->checkTitleEncoding( $s ), - "checkTitleEncoding('$s')" - ); - } - - public static function provideCheckTitleEncodingData() { - return array( - array( "" ), - array( "United States of America" ), // 7bit ASCII - array( rawurldecode( "S%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e" ) ), - array( - rawurldecode( - "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn" - ) - ), - // The following two data sets come from bug 36839. They fail if checkTitleEncoding uses a regexp to test for - // valid UTF-8 encoding and the pcre.recursion_limit is low (like, say, 1024). They succeed if checkTitleEncoding - // uses mb_check_encoding for its test. - array( - rawurldecode( - "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn%7C" - . "Catherine%20Willows%7CDavid%20Hodges%7CDavid%20Phillips%7CGil%20Grissom%7CGreg%20Sanders%7CHodges%7C" - . "Internet%20Movie%20Database%7CJim%20Brass%7CLady%20Heather%7C" - . "Les%20Experts%20(s%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e)%7CLes%20Experts%20:%20Manhattan%7C" - . "Les%20Experts%20:%20Miami%7CListe%20des%20personnages%20des%20Experts%7C" - . "Liste%20des%20%C3%A9pisodes%20des%20Experts%7CMod%C3%A8le%20discussion:Palette%20Les%20Experts%7C" - . "Nick%20Stokes%7CPersonnage%20de%20fiction%7CPersonnage%20fictif%7CPersonnage%20de%20fiction%7C" - . "Personnages%20r%C3%A9currents%20dans%20Les%20Experts%7CRaymond%20Langston%7CRiley%20Adams%7C" - . "Saison%201%20des%20Experts%7CSaison%2010%20des%20Experts%7CSaison%2011%20des%20Experts%7C" - . "Saison%2012%20des%20Experts%7CSaison%202%20des%20Experts%7CSaison%203%20des%20Experts%7C" - . "Saison%204%20des%20Experts%7CSaison%205%20des%20Experts%7CSaison%206%20des%20Experts%7C" - . "Saison%207%20des%20Experts%7CSaison%208%20des%20Experts%7CSaison%209%20des%20Experts%7C" - . "Sara%20Sidle%7CSofia%20Curtis%7CS%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e%7CWallace%20Langham%7C" - . "Warrick%20Brown%7CWendy%20Simms%7C%C3%89tats-Unis" - ), - ), - array( - rawurldecode( - "Mod%C3%A8le%3AArrondissements%20homonymes%7CMod%C3%A8le%3ABandeau%20standard%20pour%20page%20d'homonymie%7C" - . "Mod%C3%A8le%3ABatailles%20homonymes%7CMod%C3%A8le%3ACantons%20homonymes%7C" - . "Mod%C3%A8le%3ACommunes%20fran%C3%A7aises%20homonymes%7CMod%C3%A8le%3AFilms%20homonymes%7C" - . "Mod%C3%A8le%3AGouvernements%20homonymes%7CMod%C3%A8le%3AGuerres%20homonymes%7CMod%C3%A8le%3AHomonymie%7C" - . "Mod%C3%A8le%3AHomonymie%20bateau%7CMod%C3%A8le%3AHomonymie%20d'%C3%A9tablissements%20scolaires%20ou" - . "%20universitaires%7CMod%C3%A8le%3AHomonymie%20d'%C3%AEles%7CMod%C3%A8le%3AHomonymie%20de%20clubs%20sportifs%7C" - . "Mod%C3%A8le%3AHomonymie%20de%20comt%C3%A9s%7CMod%C3%A8le%3AHomonymie%20de%20monument%7C" - . "Mod%C3%A8le%3AHomonymie%20de%20nom%20romain%7CMod%C3%A8le%3AHomonymie%20de%20parti%20politique%7C" - . "Mod%C3%A8le%3AHomonymie%20de%20route%7CMod%C3%A8le%3AHomonymie%20dynastique%7C" - . "Mod%C3%A8le%3AHomonymie%20vid%C3%A9oludique%7CMod%C3%A8le%3AHomonymie%20%C3%A9difice%20religieux%7C" - . "Mod%C3%A8le%3AInternationalisation%7CMod%C3%A8le%3AIsom%C3%A9rie%7CMod%C3%A8le%3AParonymie%7C" - . "Mod%C3%A8le%3APatronyme%7CMod%C3%A8le%3APatronyme%20basque%7CMod%C3%A8le%3APatronyme%20italien%7C" - . "Mod%C3%A8le%3APatronymie%7CMod%C3%A8le%3APersonnes%20homonymes%7CMod%C3%A8le%3ASaints%20homonymes%7C" - . "Mod%C3%A8le%3ATitres%20homonymes%7CMod%C3%A8le%3AToponymie%7CMod%C3%A8le%3AUnit%C3%A9s%20homonymes%7C" - . "Mod%C3%A8le%3AVilles%20homonymes%7CMod%C3%A8le%3A%C3%89difices%20religieux%20homonymes" - ) - ) - ); - } - - /** - * @dataProvider provideRomanNumeralsData - * @covers Language::romanNumeral - */ - public function testRomanNumerals( $num, $numerals ) { - $this->assertEquals( - $numerals, - Language::romanNumeral( $num ), - "romanNumeral('$num')" - ); - } - - public static function provideRomanNumeralsData() { - return array( - array( 1, 'I' ), - array( 2, 'II' ), - array( 3, 'III' ), - array( 4, 'IV' ), - array( 5, 'V' ), - array( 6, 'VI' ), - array( 7, 'VII' ), - array( 8, 'VIII' ), - array( 9, 'IX' ), - array( 10, 'X' ), - array( 20, 'XX' ), - array( 30, 'XXX' ), - array( 40, 'XL' ), - array( 49, 'XLIX' ), - array( 50, 'L' ), - array( 60, 'LX' ), - array( 70, 'LXX' ), - array( 80, 'LXXX' ), - array( 90, 'XC' ), - array( 99, 'XCIX' ), - array( 100, 'C' ), - array( 200, 'CC' ), - array( 300, 'CCC' ), - array( 400, 'CD' ), - array( 500, 'D' ), - array( 600, 'DC' ), - array( 700, 'DCC' ), - array( 800, 'DCCC' ), - array( 900, 'CM' ), - array( 999, 'CMXCIX' ), - array( 1000, 'M' ), - array( 1989, 'MCMLXXXIX' ), - array( 2000, 'MM' ), - array( 3000, 'MMM' ), - array( 4000, 'MMMM' ), - array( 5000, 'MMMMM' ), - array( 6000, 'MMMMMM' ), - array( 7000, 'MMMMMMM' ), - array( 8000, 'MMMMMMMM' ), - array( 9000, 'MMMMMMMMM' ), - array( 9999, 'MMMMMMMMMCMXCIX' ), - array( 10000, 'MMMMMMMMMM' ), - ); - } - - /** - * @dataProvider providePluralData - * @covers Language::convertPlural - */ - public function testConvertPlural( $expected, $number, $forms ) { - $chosen = $this->getLang()->convertPlural( $number, $forms ); - $this->assertEquals( $expected, $chosen ); - } - - public static function providePluralData() { - // Params are: [expected text, number given, [the plural forms]] - return array( - array( 'plural', 0, array( - 'singular', 'plural' - ) ), - array( 'explicit zero', 0, array( - '0=explicit zero', 'singular', 'plural' - ) ), - array( 'explicit one', 1, array( - 'singular', 'plural', '1=explicit one', - ) ), - array( 'singular', 1, array( - 'singular', 'plural', '0=explicit zero', - ) ), - array( 'plural', 3, array( - '0=explicit zero', '1=explicit one', 'singular', 'plural' - ) ), - array( 'explicit eleven', 11, array( - 'singular', 'plural', '11=explicit eleven', - ) ), - array( 'plural', 12, array( - 'singular', 'plural', '11=explicit twelve', - ) ), - array( 'plural', 12, array( - 'singular', 'plural', '=explicit form', - ) ), - array( 'other', 2, array( - 'kissa=kala', '1=2=3', 'other', - ) ), - array( '', 2, array( - '0=explicit zero', '1=explicit one', - ) ), - ); - } - - /** - * @covers Language::translateBlockExpiry() - * @dataProvider provideTranslateBlockExpiry - */ - public function testTranslateBlockExpiry( $expectedData, $str, $desc ) { - $lang = $this->getLang(); - if ( is_array( $expectedData ) ) { - list( $func, $arg ) = $expectedData; - $expected = $lang->$func( $arg ); - } else { - $expected = $expectedData; - } - $this->assertEquals( $expected, $lang->translateBlockExpiry( $str ), $desc ); - } - - public static function provideTranslateBlockExpiry() { - return array( - array( '2 hours', '2 hours', 'simple data from ipboptions' ), - array( 'indefinite', 'infinite', 'infinite from ipboptions' ), - array( 'indefinite', 'infinity', 'alternative infinite from ipboptions' ), - array( 'indefinite', 'indefinite', 'another alternative infinite from ipboptions' ), - array( array( 'formatDuration', 1023 * 60 * 60 ), '1023 hours', 'relative' ), - array( array( 'formatDuration', -1023 ), '-1023 seconds', 'negative relative' ), - array( array( 'formatDuration', 0 ), 'now', 'now' ), - array( array( 'timeanddate', '20120102070000' ), '2012-1-1 7:00 +1 day', 'mixed, handled as absolute' ), - array( array( 'timeanddate', '19910203040506' ), '1991-2-3 4:05:06', 'absolute' ), - array( array( 'timeanddate', '19700101000000' ), '1970-1-1 0:00:00', 'absolute at epoch' ), - array( array( 'timeanddate', '19691231235959' ), '1969-12-31 23:59:59', 'time before epoch' ), - array( 'dummy', 'dummy', 'return garbage as is' ), - ); - } - - /** - * @covers Language::commafy() - * @dataProvider provideCommafyData - */ - public function testCommafy( $number, $numbersWithCommas ) { - $this->assertEquals( - $numbersWithCommas, - $this->getLang()->commafy( $number ), - "commafy('$number')" - ); - } - - public static function provideCommafyData() { - return array( - array( 1, '1' ), - array( 10, '10' ), - array( 100, '100' ), - array( 1000, '1,000' ), - array( 10000, '10,000' ), - array( 100000, '100,000' ), - array( 1000000, '1,000,000' ), - array( 1.0001, '1.0001' ), - array( 10.0001, '10.0001' ), - array( 100.0001, '100.0001' ), - array( 1000.0001, '1,000.0001' ), - array( 10000.0001, '10,000.0001' ), - array( 100000.0001, '100,000.0001' ), - array( 1000000.0001, '1,000,000.0001' ), - ); - } - - /** - * @covers Language::listToText - */ - public function testListToText() { - $lang = $this->getLang(); - $and = $lang->getMessageFromDB( 'and' ); - $s = $lang->getMessageFromDB( 'word-separator' ); - $c = $lang->getMessageFromDB( 'comma-separator' ); - - $this->assertEquals( '', $lang->listToText( array() ) ); - $this->assertEquals( 'a', $lang->listToText( array( 'a' ) ) ); - $this->assertEquals( "a{$and}{$s}b", $lang->listToText( array( 'a', 'b' ) ) ); - $this->assertEquals( "a{$c}b{$and}{$s}c", $lang->listToText( array( 'a', 'b', 'c' ) ) ); - $this->assertEquals( "a{$c}b{$c}c{$and}{$s}d", $lang->listToText( array( 'a', 'b', 'c', 'd' ) ) ); - } - - /** - * @dataProvider provideIsSupportedLanguage - * @covers Language::isSupportedLanguage - */ - public function testIsSupportedLanguage( $code, $expected, $comment ) { - $this->assertEquals( $expected, Language::isSupportedLanguage( $code ), $comment ); - } - - public static function provideIsSupportedLanguage() { - return array( - array( 'en', true, 'is supported language' ), - array( 'fi', true, 'is supported language' ), - array( 'bunny', false, 'is not supported language' ), - 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 deleted file mode 100644 index e225af97..00000000 --- a/tests/phpunit/languages/LanguageTiTest.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php -/** - * @author Amir E. Aharoni - * @copyright Copyright © 2012, Amir E. Aharoni - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageTi.php */ -class LanguageTiTest extends LanguageClassesTestCase { - /** - * @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 ) ); - } - - public static function providePlural() { - return array( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageTlTest.php b/tests/phpunit/languages/LanguageTlTest.php deleted file mode 100644 index 7ac51c69..00000000 --- a/tests/phpunit/languages/LanguageTlTest.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php -/** - * @author Amir E. Aharoni - * @copyright Copyright © 2012, Amir E. Aharoni - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageTl.php */ -class LanguageTlTest extends LanguageClassesTestCase { - /** - * @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 ) ); - } - - public static function providePlural() { - return array( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageTrTest.php b/tests/phpunit/languages/LanguageTrTest.php deleted file mode 100644 index 8fc2795c..00000000 --- a/tests/phpunit/languages/LanguageTrTest.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php -/** - * @author Antoine Musso - * @copyright Copyright © 2011, Antoine Musso - * @file - */ - -/** Tests for MediaWiki languages/LanguageTr.php */ -class LanguageTrTest extends LanguageClassesTestCase { - - /** - * See @bug 28040 - * Credits to irc://irc.freenode.net/wikipedia-tr users: - * - berm - * - []LuCkY[] - * - Emperyan - * @see http://en.wikipedia.org/wiki/Dotted_and_dotless_I - * @dataProvider provideDottedAndDotlessI - */ - public function testDottedAndDotlessI( $func, $input, $inputCase, $expected ) { - if ( $func == 'ucfirst' ) { - $res = $this->getLang()->ucfirst( $input ); - } elseif ( $func == 'lcfirst' ) { - $res = $this->getLang()->lcfirst( $input ); - } else { - throw new MWException( __METHOD__ . " given an invalid function name '$func'" ); - } - - $msg = "Converting $inputCase case '$input' with $func should give '$expected'"; - - $this->assertEquals( $expected, $res, $msg ); - } - - public static function provideDottedAndDotlessI() { - return array( - # function, input, input case, expected - # Case changed: - array( 'ucfirst', 'ı', 'lower', 'I' ), - array( 'ucfirst', 'i', 'lower', 'İ' ), - array( 'lcfirst', 'I', 'upper', 'ı' ), - array( 'lcfirst', 'İ', 'upper', 'i' ), - - # Already using the correct case - array( 'ucfirst', 'I', 'upper', 'I' ), - array( 'ucfirst', 'İ', 'upper', 'İ' ), - array( 'lcfirst', 'ı', 'lower', 'ı' ), - array( 'lcfirst', 'i', 'lower', 'i' ), - - # A real example taken from bug 28040 using - # http://tr.wikipedia.org/wiki/%C4%B0Phone - array( 'lcfirst', 'iPhone', 'lower', 'iPhone' ), - - # next case is valid in Turkish but are different words if we - # consider IPhone is English! - array( 'lcfirst', 'IPhone', 'upper', 'ıPhone' ), - - ); - } -} diff --git a/tests/phpunit/languages/LanguageUkTest.php b/tests/phpunit/languages/LanguageUkTest.php deleted file mode 100644 index 9051bcff..00000000 --- a/tests/phpunit/languages/LanguageUkTest.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -/** - * @author Amir E. Aharoni - * based on LanguageBe_tarask.php - * @copyright Copyright © 2012, Amir E. Aharoni - * @file - */ - -/** Tests for Ukrainian */ -class LanguageUkTest extends LanguageClassesTestCase { - /** - * @dataProvider providePlural - * @covers Language::convertPlural - */ - public function testPlural( $result, $value ) { - $forms = array( 'one', 'few', 'many', 'other' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); - } - - /** - * Test explicit plural forms - n=FormN forms - * @covers Language::convertPlural - */ - public function testExplicitPlural() { - $forms = array( 'one', 'few', 'many', 'other', '12=dozen' ); - $this->assertEquals( 'dozen', $this->getLang()->convertPlural( 12, $forms ) ); - $forms = array( 'one', 'few', 'many', '100=hundred', 'other', '12=dozen' ); - $this->assertEquals( 'hundred', $this->getLang()->convertPlural( 100, $forms ) ); - } - - /** - * @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 ), - array( 'one', 91 ), - array( 'one', 121 ), - array( 'few', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'few', 334 ), - array( 'many', 5 ), - array( 'many', 15 ), - array( 'many', 120 ), - ); - } - - /** - * @dataProvider providePluralTwoForms - * @covers Language::convertPlural - */ - public function testPluralTwoForms( $result, $value ) { - $forms = array( '1=one', 'other' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); - } - - public static function providePluralTwoForms() { - return array( - array( 'one', 1 ), - array( 'other', 11 ), - array( 'other', 91 ), - array( 'other', 121 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageUzTest.php b/tests/phpunit/languages/LanguageUzTest.php deleted file mode 100644 index 13f57c16..00000000 --- a/tests/phpunit/languages/LanguageUzTest.php +++ /dev/null @@ -1,121 +0,0 @@ -<?php -/** - * PHPUnit tests for the Uzbek language. - * The language can be represented using two scripts: - * - Latin (uz-latn) - * - Cyrillic (uz-cyrl) - * - * @author Robin Pepermans - * @author Antoine Musso <hashar at free dot fr> - * @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.. - */ - -/** Tests for MediaWiki languages/LanguageUz.php */ -class LanguageUzTest extends LanguageClassesTestCase { - - /** - * @author Nikola Smolenski - * @covers LanguageConverter::convertTo - */ - public function testConversionToCyrillic() { - // A convertion of Latin to Cyrillic - $this->assertEquals( 'абвгғ', - $this->convertToCyrillic( 'abvggʻ' ) - ); - // Same as above, but assert that -{}-s must be removed and not converted - $this->assertEquals( 'ljабnjвгўоdb', - $this->convertToCyrillic( '-{lj}-ab-{nj}-vgoʻo-{db}-' ) - ); - // A simple convertion of Cyrillic to Cyrillic - $this->assertEquals( 'абвг', - $this->convertToCyrillic( 'абвг' ) - ); - // Same as above, but assert that -{}-s must be removed and not converted - $this->assertEquals( 'ljабnjвгdaž', - $this->convertToCyrillic( '-{lj}-аб-{nj}-вг-{da}-ž' ) - ); - } - - /** - * @covers LanguageConverter::convertTo - */ - public function testConversionToLatin() { - // A simple convertion of Latin to Latin - $this->assertEquals( 'abdef', - $this->convertToLatin( 'abdef' ) - ); - // A convertion of Cyrillic to Latin - $this->assertEquals( 'gʻabtsdOʻQyo', - $this->convertToLatin( 'ғабцдЎҚё' ) - ); - } - - ##### HELPERS ##################################################### - /** - * Wrapper to verify text stay the same after applying conversion - * @param $text string Text to convert - * @param $variant string Language variant 'uz-cyrl' or 'uz-latn' - * @param $msg string Optional message - */ - protected function assertUnConverted( $text, $variant, $msg = '' ) { - $this->assertEquals( - $text, - $this->convertTo( $text, $variant ), - $msg - ); - } - - /** - * Wrapper to verify a text is different once converted to a variant. - * @param $text string Text to convert - * @param $variant string Language variant 'uz-cyrl' or 'uz-latn' - * @param $msg string Optional message - */ - protected function assertConverted( $text, $variant, $msg = '' ) { - $this->assertNotEquals( - $text, - $this->convertTo( $text, $variant ), - $msg - ); - } - - /** - * Verifiy the given Cyrillic text is not converted when using - * using the cyrillic variant and converted to Latin when using - * the Latin variant. - */ - protected function assertCyrillic( $text, $msg = '' ) { - $this->assertUnConverted( $text, 'uz-cyrl', $msg ); - $this->assertConverted( $text, 'uz-latn', $msg ); - } - - /** - * Verifiy the given Latin text is not converted when using - * using the Latin variant and converted to Cyrillic when using - * the Cyrillic variant. - */ - protected function assertLatin( $text, $msg = '' ) { - $this->assertUnConverted( $text, 'uz-latn', $msg ); - $this->assertConverted( $text, 'uz-cyrl', $msg ); - } - - - /** Wrapper for converter::convertTo() method*/ - protected function convertTo( $text, $variant ) { - return $this->getLang()->mConverter->convertTo( $text, $variant ); - } - - protected function convertToCyrillic( $text ) { - return $this->convertTo( $text, 'uz-cyrl' ); - } - - protected function convertToLatin( $text ) { - return $this->convertTo( $text, 'uz-latn' ); - } -} diff --git a/tests/phpunit/languages/LanguageWaTest.php b/tests/phpunit/languages/LanguageWaTest.php deleted file mode 100644 index d05196c0..00000000 --- a/tests/phpunit/languages/LanguageWaTest.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php -/** - * @author Amir E. Aharoni - * @copyright Copyright © 2012, Amir E. Aharoni - * @file - */ - -/** Tests for MediaWiki languages/classes/LanguageWa.php */ -class LanguageWaTest extends LanguageClassesTestCase { - /** - * @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 ) ); - } - - public static function providePlural() { - return array( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - ); - } -} diff --git a/tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php b/tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php deleted file mode 100644 index bd3809d7..00000000 --- a/tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php +++ /dev/null @@ -1,145 +0,0 @@ -<?php -/** - * @author Niklas Laxström - * @file - */ - -class CLDRPluralRuleEvaluatorTest extends MediaWikiTestCase { - /** - * @dataProvider validTestCases - */ - function testValidRules( $expected, $rules, $number, $comment ) { - $result = CLDRPluralRuleEvaluator::evaluate( $number, (array)$rules ); - $this->assertEquals( $expected, $result, $comment ); - } - - /** - * @dataProvider invalidTestCases - * @expectedException CLDRPluralRuleError - */ - function testInvalidRules( $rules, $comment ) { - CLDRPluralRuleEvaluator::evaluate( 1, (array)$rules ); - } - - function validTestCases() { - $tests = array( - # expected, number, rule, comment - array( 0, 'n is 1', 1, 'integer number and is' ), - array( 0, 'n is 1', "1", 'string integer number and is' ), - array( 0, 'n is 1', 1.0, 'float number and is' ), - array( 0, 'n is 1', "1.0", 'string float number and is' ), - array( 1, 'n is 1', 1.1, 'float number and is' ), - array( 1, 'n is 1', 2, 'float number and is' ), - - array( 0, 'n in 1,3,5', 3, '' ), - array( 1, 'n not in 1,3,5', 5, '' ), - - array( 1, 'n in 1,3,5', 2, '' ), - array( 0, 'n not in 1,3,5', 4, '' ), - - array( 0, 'n in 1..3', 2, '' ), - array( 0, 'n in 1..3', 3, 'in is inclusive' ), - array( 1, 'n in 1..3', 0, '' ), - - array( 1, 'n not in 1..3', 2, '' ), - array( 1, 'n not in 1..3', 3, 'in is inclusive' ), - array( 0, 'n not in 1..3', 0, '' ), - - array( 1, 'n is not 1 and n is not 2 and n is not 3', 1, 'and relation' ), - array( 0, 'n is not 1 and n is not 2 and n is not 4', 3, 'and relation' ), - - array( 0, 'n is not 1 or n is 1', 1, 'or relation' ), - array( 1, 'n is 1 or n is 2', 3, 'or relation' ), - - array( 0, 'n is 1', 1, 'extra whitespace' ), - - array( 0, 'n mod 3 is 1', 7, 'mod' ), - array( 0, 'n mod 3 is not 1', 4.3, 'mod with floats' ), - - array( 0, 'n within 1..3', 2, 'within with integer' ), - array( 0, 'n within 1..3', 2.5, 'within with float' ), - array( 0, 'n in 1..3', 2, 'in with integer' ), - array( 1, 'n in 1..3', 2.5, 'in with float' ), - - array( 0, 'n in 3 or n is 4 and n is 5', 3, 'and binds more tightly than or' ), - array( 1, 'n is 3 or n is 4 and n is 5', 4, 'and binds more tightly than or' ), - - array( 0, 'n mod 10 in 3..4,9 and n mod 100 not in 10..19,70..79,90..99', 24, 'breton rule' ), - array( 1, 'n mod 10 in 3..4,9 and n mod 100 not in 10..19,70..79,90..99', 25, 'breton rule' ), - - array( 0, 'n within 0..2 and n is not 2', 0, 'french rule' ), - array( 0, 'n within 0..2 and n is not 2', 1, 'french rule' ), - array( 0, 'n within 0..2 and n is not 2', 1.2, 'french rule' ), - array( 1, 'n within 0..2 and n is not 2', 2, 'french rule' ), - - array( 1, 'n in 3..10,13..19', 2, 'scottish rule - ranges with comma' ), - array( 0, 'n in 3..10,13..19', 4, 'scottish rule - ranges with comma' ), - array( 1, 'n in 3..10,13..19', 12.999, 'scottish rule - ranges with comma' ), - array( 0, 'n in 3..10,13..19', 13, 'scottish rule - ranges with comma' ), - - array( 0, '5 mod 3 is n', 2, 'n as result of mod - no need to pass' ), - - # Revision 33 new operand examples - # expected, rule, number, comment - array( 0, 'i is 1', '1.00', 'new operand i' ), - array( 0, 'v is 2', '1.00', 'new operand v' ), - array( 0, 'w is 0', '1.00', 'new operand w' ), - array( 0, 'f is 0', '1.00', 'new operand f' ), - array( 0, 't is 0', '1.00', 'new operand t' ), - - array( 0, 'i is 1', '1.30', 'new operand i' ), - array( 0, 'v is 2', '1.30', 'new operand v' ), - array( 0, 'w is 1', '1.30', 'new operand w' ), - array( 0, 'f is 30', '1.30', 'new operand f' ), - array( 0, 't is 3', '1.30', 'new operand t' ), - - array( 0, 'i is 1', '1.03', 'new operand i' ), - array( 0, 'v is 2', '1.03', 'new operand v' ), - array( 0, 'w is 2', '1.03', 'new operand w' ), - array( 0, 'f is 3', '1.03', 'new operand f' ), - array( 0, 't is 3', '1.03', 'new operand t' ), - - # Revision 33 new operator aliases - # expected, rule, number, comment - array( 0, 'n % 3 is 1', 7, 'new % operator' ), - array( 0, 'n = 1,3,5', 3, 'new = operator' ), - array( 1, 'n != 1,3,5', 5, 'new != operator' ), - - # Revision 33 samples - # expected, rule, number, comment - array( 0, 'n in 1,3,5@integer 3~10, 103~110, 1003, … @decimal 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 103.0, 1003.0, …', 3, 'samples' ), - - # Revision 33 some test cases from CLDR - array( 0, 'i = 1 and v = 0 or i = 0 and t = 1', '0.1', 'pt one' ), - array( 0, 'i = 1 and v = 0 or i = 0 and t = 1', '0.01', 'pt one' ), - array( 0, 'i = 1 and v = 0 or i = 0 and t = 1', '0.10', 'pt one' ), - array( 0, 'i = 1 and v = 0 or i = 0 and t = 1', '0.010', 'pt one' ), - array( 0, 'i = 1 and v = 0 or i = 0 and t = 1', '0.100', 'pt one' ), - array( 1, 'i = 1 and v = 0 or i = 0 and t = 1', '0.0', 'pt other' ), - array( 1, 'i = 1 and v = 0 or i = 0 and t = 1', '0.2', 'pt other' ), - array( 1, 'i = 1 and v = 0 or i = 0 and t = 1', '10.0', 'pt other' ), - array( 1, 'i = 1 and v = 0 or i = 0 and t = 1', '100.0', 'pt other' ), - array( 0, 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14', '2', 'bs few' ), - array( 0, 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14', '4', 'bs few' ), - array( 0, 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14', '22', 'bs few' ), - array( 0, 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14', '102', 'bs few' ), - array( 0, 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14', '0.2', 'bs few' ), - array( 0, 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14', '0.4', 'bs few' ), - array( 0, 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14', '10.2', 'bs few' ), - array( 1, 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14', '10.0', 'bs other' ), - - ); - - return $tests; - } - - function invalidTestCases() { - $tests = array( - array( 'n mod mod 5 is 1', 'mod mod' ), - 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 deleted file mode 100644 index 83d8c71d..00000000 --- a/tests/phpunit/maintenance/DumpTestCase.php +++ /dev/null @@ -1,379 +0,0 @@ -<?php - -/** - * Base TestCase for dumps - */ -abstract class DumpTestCase extends MediaWikiLangTestCase { - - /** - * exception to be rethrown once in sound PHPUnit surrounding - * - * As the current MediaWikiTestCase::run is not robust enough to recover - * from thrown exceptions directly, we cannot throw frow within - * self::addDBData, although it would be appropriate. Hence, we catch the - * exception and store it until we are in setUp and may finally rethrow - * the exception without crashing the test suite. - * - * @var Exception|null - */ - protected $exceptionFromAddDBData = null; - - /** - * Holds the xmlreader used for analyzing an xml dump - * - * @var XMLReader|null - */ - protected $xml = null; - - /** - * Adds a revision to a page, while returning the resuting revision's id - * - * @param $page WikiPage: page to add the revision to - * @param $text string: revisions text - * @param $text string: revisions summare - * - * @throws MWExcepion - */ - protected function addRevision( Page $page, $text, $summary ) { - $status = $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), $summary ); - if ( $status->isGood() ) { - $value = $status->getValue(); - $revision = $value['revision']; - $revision_id = $revision->getId(); - $text_id = $revision->getTextId(); - if ( ( $revision_id > 0 ) && ( $text_id > 0 ) ) { - return array( $revision_id, $text_id ); - } - } - throw new MWException( "Could not determine revision id (" . $status->getWikiText() . ")" ); - } - - - /** - * gunzips the given file and stores the result in the original file name - * - * @param $fname string: filename to read the gzipped data from and stored - * the gunzipped data into - */ - protected function gunzip( $fname ) { - $gzipped_contents = file_get_contents( $fname ); - if ( $gzipped_contents === false ) { - $this->fail( "Could not get contents of $fname" ); - } - - $contents = gzdecode( $gzipped_contents ); - - $this->assertEquals( - strlen( $contents ), - file_put_contents( $fname, $contents ), - '# bytes written' - ); - } - - /** - * Default set up function. - * - * Clears $wgUser, and reports errors from addDBData to PHPUnit - */ - protected function setUp() { - parent::setUp(); - - // Check if any Exception is stored for rethrowing from addDBData - // @see self::exceptionFromAddDBData - if ( $this->exceptionFromAddDBData !== null ) { - throw $this->exceptionFromAddDBData; - } - - $this->setMwGlobals( 'wgUser', new User() ); - } - - /** - * Checks for test output consisting only of lines containing ETA announcements - */ - function expectETAOutput() { - // Newer PHPUnits require assertion about the output using PHPUnit's own - // expectOutput[...] functions. However, the PHPUnit shipped prediactes - // do not allow to check /each/ line of the output using /readable/ REs. - // So we ... - // - // 1. ... add a dummy output checking to make PHPUnit not complain - // about unchecked test output - $this->expectOutputRegex( '//' ); - - // 2. Do the real output checking on our own. - $lines = explode( "\n", $this->getActualOutput() ); - $this->assertGreaterThan( 1, count( $lines ), "Minimal lines of produced output" ); - $this->assertEquals( '', array_pop( $lines ), "Output ends in LF" ); - $timestamp_re = "[0-9]{4}-[01][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-6][0-9]"; - foreach ( $lines as $line ) { - $this->assertRegExp( "/$timestamp_re: .* \(ID [0-9]+\) [0-9]* pages .*, [0-9]* revs .*, ETA/", $line ); - } - } - - - /** - * Step the current XML reader until node end of given name is found. - * - * @param $name string: name of the closing element to look for - * (e.g.: "mediawiki" when looking for </mediawiki>) - * - * @return bool: true if the end node could be found. false otherwise. - */ - protected function skipToNodeEnd( $name ) { - while ( $this->xml->read() ) { - if ( $this->xml->nodeType == XMLReader::END_ELEMENT && - $this->xml->name == $name - ) { - return true; - } - } - - return false; - } - - /** - * Step the current XML reader to the first element start after the node - * end of a given name. - * - * @param $name string: name of the closing element to look for - * (e.g.: "mediawiki" when looking for </mediawiki>) - * - * @return bool: true iff new element after the closing of $name could be - * found. false otherwise. - */ - protected function skipPastNodeEnd( $name ) { - $this->assertTrue( $this->skipToNodeEnd( $name ), - "Skipping to end of $name" ); - while ( $this->xml->read() ) { - if ( $this->xml->nodeType == XMLReader::ELEMENT ) { - return true; - } - } - - return false; - } - - /** - * Opens an XML file to analyze and optionally skips past siteinfo. - * - * @param $fname string: name of file to analyze - * @param $skip_siteinfo bool: (optional) If true, step the xml reader - * to the first element after </siteinfo> - */ - protected function assertDumpStart( $fname, $skip_siteinfo = true ) { - $this->xml = new XMLReader(); - $this->assertTrue( $this->xml->open( $fname ), - "Opening temporary file $fname via XMLReader failed" ); - if ( $skip_siteinfo ) { - $this->assertTrue( $this->skipPastNodeEnd( "siteinfo" ), - "Skipping past end of siteinfo" ); - } - } - - /** - * Asserts that the xml reader is at the final closing tag of an xml file and - * closes the reader. - * - * @param $tag string: (optional) the name of the final tag - * (e.g.: "mediawiki" for </mediawiki>) - */ - protected function assertDumpEnd( $name = "mediawiki" ) { - $this->assertNodeEnd( $name, false ); - if ( $this->xml->read() ) { - $this->skipWhitespace(); - } - $this->assertEquals( $this->xml->nodeType, XMLReader::NONE, - "No proper entity left to parse" ); - $this->xml->close(); - } - - /** - * Steps the xml reader over white space - */ - protected function skipWhitespace() { - $cont = true; - while ( $cont && ( ( $this->xml->nodeType == XMLReader::WHITESPACE ) - || ( $this->xml->nodeType == XMLReader::SIGNIFICANT_WHITESPACE ) ) ) { - $cont = $this->xml->read(); - } - } - - /** - * Asserts that the xml reader is at an element of given name, and optionally - * skips past it. - * - * @param $name string: the name of the element to check for - * (e.g.: "mediawiki" for <mediawiki>) - * @param $skip bool: (optional) if true, skip past the found element - */ - protected function assertNodeStart( $name, $skip = true ) { - $this->assertEquals( $name, $this->xml->name, "Node name" ); - $this->assertEquals( XMLReader::ELEMENT, $this->xml->nodeType, "Node type" ); - if ( $skip ) { - $this->assertTrue( $this->xml->read(), "Skipping past start tag" ); - } - } - - /** - * Asserts that the xml reader is at an closing element of given name, and optionally - * skips past it. - * - * @param $name string: the name of the closing element to check for - * (e.g.: "mediawiki" for </mediawiki>) - * @param $skip bool: (optional) if true, skip past the found element - */ - protected function assertNodeEnd( $name, $skip = true ) { - $this->assertEquals( $name, $this->xml->name, "Node name" ); - $this->assertEquals( XMLReader::END_ELEMENT, $this->xml->nodeType, "Node type" ); - if ( $skip ) { - $this->assertTrue( $this->xml->read(), "Skipping past end tag" ); - } - } - - - /** - * Asserts that the xml reader is at an element of given tag that contains a given text, - * and skips over the element. - * - * @param $name string: the name of the element to check for - * (e.g.: "mediawiki" for <mediawiki>...</mediawiki>) - * @param $text string|false: If string, check if it equals the elements text. - * If false, ignore the element's text - * @param $skip_ws bool: (optional) if true, skip past white spaces that trail the - * closing element. - */ - protected function assertTextNode( $name, $text, $skip_ws = true ) { - $this->assertNodeStart( $name ); - - if ( $text !== false ) { - $this->assertEquals( $text, $this->xml->value, "Text of node " . $name ); - } - $this->assertTrue( $this->xml->read(), "Skipping past processed text of " . $name ); - $this->assertNodeEnd( $name ); - - if ( $skip_ws ) { - $this->skipWhitespace(); - } - } - - /** - * Asserts that the xml reader is at the start of a page element and skips over the first - * tags, after checking them. - * - * Besides the opening page element, this function also checks for and skips over the - * title, ns, and id tags. Hence after this function, the xml reader is at the first - * revision of the current page. - * - * @param $id int: id of the page to assert - * @param $ns int: number of namespage to assert - * @param $name string: title of the current page - */ - protected function assertPageStart( $id, $ns, $name ) { - - $this->assertNodeStart( "page" ); - $this->skipWhitespace(); - - $this->assertTextNode( "title", $name ); - $this->assertTextNode( "ns", $ns ); - $this->assertTextNode( "id", $id ); - } - - /** - * Asserts that the xml reader is at the page's closing element and skips to the next - * element. - */ - protected function assertPageEnd() { - $this->assertNodeEnd( "page" ); - $this->skipWhitespace(); - } - - /** - * Asserts that the xml reader is at a revision and checks its representation before - * skipping over it. - * - * @param $id int: id of the revision - * @param $summary string: summary of the revision - * @param $text_id int: id of the revision's text - * @param $text_bytes int: # of bytes in the revision's text - * @param $text_sha1 string: the base36 SHA-1 of the revision's text - * @param $text string|false: (optional) The revision's string, or false to check for a - * revision stub - * @param $model String: the expected content model id (default: CONTENT_MODEL_WIKITEXT) - * @param $format String: the expected format model id (default: CONTENT_FORMAT_WIKITEXT) - * @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 - ) { - $this->assertNodeStart( "revision" ); - $this->skipWhitespace(); - - $this->assertTextNode( "id", $id ); - if ( $parentid !== false ) { - $this->assertTextNode( "parentid", $parentid ); - } - $this->assertTextNode( "timestamp", false ); - - $this->assertNodeStart( "contributor" ); - $this->skipWhitespace(); - $this->assertTextNode( "ip", false ); - $this->assertNodeEnd( "contributor" ); - $this->skipWhitespace(); - - $this->assertTextNode( "comment", $summary ); - $this->skipWhitespace(); - - if ( $this->xml->name == "text" ) { - // note: <text> tag may occur here or at the very end. - $text_found = true; - $this->assertText( $id, $text_id, $text_bytes, $text ); - } else { - $text_found = false; - } - - $this->assertTextNode( "sha1", $text_sha1 ); - - $this->assertTextNode( "model", $model ); - $this->skipWhitespace(); - - $this->assertTextNode( "format", $format ); - $this->skipWhitespace(); - - if ( !$text_found ) { - $this->assertText( $id, $text_id, $text_bytes, $text ); - } - - $this->assertNodeEnd( "revision" ); - $this->skipWhitespace(); - } - - protected function assertText( $id, $text_id, $text_bytes, $text ) { - $this->assertNodeStart( "text", false ); - if ( $text_bytes !== false ) { - $this->assertEquals( $this->xml->getAttribute( "bytes" ), $text_bytes, - "Attribute 'bytes' of revision " . $id ); - } - - if ( $text === false ) { - // Testing for a stub - $this->assertEquals( $this->xml->getAttribute( "id" ), $text_id, - "Text id of revision " . $id ); - $this->assertFalse( $this->xml->hasValue, "Revision has text" ); - $this->assertTrue( $this->xml->read(), "Skipping text start tag" ); - if ( ( $this->xml->nodeType == XMLReader::END_ELEMENT ) - && ( $this->xml->name == "text" ) - ) { - - $this->xml->read(); - } - $this->skipWhitespace(); - } else { - // Testing for a real dump - $this->assertTrue( $this->xml->read(), "Skipping text start tag" ); - $this->assertEquals( $text, $this->xml->value, "Text of revision " . $id ); - $this->assertTrue( $this->xml->read(), "Skipping past text" ); - $this->assertNodeEnd( "text" ); - $this->skipWhitespace(); - } - } -} diff --git a/tests/phpunit/maintenance/MaintenanceTest.php b/tests/phpunit/maintenance/MaintenanceTest.php deleted file mode 100644 index 318ce0da..00000000 --- a/tests/phpunit/maintenance/MaintenanceTest.php +++ /dev/null @@ -1,816 +0,0 @@ -<?php - -// It would be great if we were able to use PHPUnit's getMockForAbstractClass -// instead of the MaintenanceFixup hack below. However, we cannot do -// without changing the visibility and without working around hacks in -// Maintenance.php -// -// For the same reason, we cannot just use FakeMaintenance. - -/** - * makes parts of the API of Maintenance that is hidden by protected visibily - * visible for testing, and makes up for a stream closing hack in Maintenance.php. - * - * This class is solely used for being able to test Maintenance right now - * without having to apply major refactorings to fix some design issues in - * Maintenance.php. Before adding more functions here, please consider whether - * this approach is correct, or a refactoring Maintenance to separate concers - * is more appropriate. - * - * Upon refactoring, keep in mind that besides the maintenance scrits themselves - * and tests right here, also at least Extension:Maintenance make use of - * Maintenance. - * - * Due to a hack in Maintenance.php using register_shutdown_function, be sure to - * finally call simulateShutdown on MaintenanceFixup instance before a test - * ends. - * - */ -class MaintenanceFixup extends Maintenance { - - // --- Making up for the register_shutdown_function hack in Maintenance.php - - /** - * The test case that generated this instance. - * - * This member is motivated by allowing the destructor to check whether or not - * the test failed, in order to avoid unnecessary nags about omitted shutdown - * simulation. - * But as it is already available, we also usi it to flagging tests as failed - * - * @var MediaWikiTestCase - */ - private $testCase; - - /** - * shutdownSimulated === true if simulateShutdown has done it's work - * - * @var bool - */ - private $shutdownSimulated = false; - - /** - * Simulates what Maintenance wants to happen at script's end. - */ - public function simulateShutdown() { - - if ( $this->shutdownSimulated ) { - $this->testCase->fail( __METHOD__ . " called more than once" ); - } - - // The cleanup action. - $this->outputChanneled( false ); - - // Bookkeeping that we simulated the clean up. - $this->shutdownSimulated = true; - } - - // Note that the "public" here does not change visibility - public function outputChanneled( $msg, $channel = null ) { - if ( $this->shutdownSimulated ) { - if ( $msg !== false ) { - $this->testCase->fail( "Already past simulated shutdown, but msg is " - . "not false. Did the hack in Maintenance.php change? Please " - . "adapt the test case or Maintenance.php" ); - } - - // The current call is the one registered via register_shutdown_function. - // We can safely ignore it, as we simulated this one via simulateShutdown - // before (if we did not, the destructor of this instance will warn about - // it) - return; - } - - return call_user_func_array( array( "parent", __FUNCTION__ ), func_get_args() ); - } - - /** - * Safety net around register_shutdown_function of Maintenance.php - */ - public function __destruct() { - if ( !$this->shutdownSimulated ) { - // Someone generated a MaintenanceFixup instance without calling - // simulateShutdown. We'd have to raise a PHPUnit exception to correctly - // flag this illegal usage. However, we are already in a destruktor, which - // would trigger undefined behavior. Hence, we can only report to the - // error output :( Hopefully people read the PHPUnit output. - $name = $this->testCase->getName(); - fwrite( STDERR, "ERROR! Instance of " . __CLASS__ . " for test $name " - . "destructed without calling simulateShutdown method. Call " - . "simulateShutdown on the instance before it gets destructed." ); - } - - // The following guard is required, as PHP does not offer default destructors :( - if ( is_callable( "parent::__destruct" ) ) { - parent::__destruct(); - } - } - - public function __construct( MediaWikiTestCase $testCase ) { - parent::__construct(); - $this->testCase = $testCase; - } - - - // --- Making protected functions visible for test - - public function output( $out, $channel = null ) { - // Just to make PHP not nag about signature mismatches, we copied - // Maintenance::output signature. However, we do not use (or rely on) - // those variables. Instead we pass to Maintenance::output whatever we - // receive at runtime. - return call_user_func_array( array( "parent", __FUNCTION__ ), func_get_args() ); - } - - - // --- Requirements for getting instance of abstract class - - public function execute() { - $this->testCase->fail( __METHOD__ . " called unexpectedly" ); - } -} - -class MaintenanceTest extends MediaWikiTestCase { - - - /** - * The main Maintenance instance that is used for testing. - * - * @var MaintenanceFixup - */ - private $m; - - - protected function setUp() { - parent::setUp(); - $this->m = new MaintenanceFixup( $this ); - } - - protected function tearDown() { - if ( $this->m ) { - $this->m->simulateShutdown(); - $this->m = null; - } - parent::tearDown(); - } - - - /** - * asserts the output before and after simulating shutdown - * - * This function simulates shutdown of self::m. - * - * @param $preShutdownOutput string: expected output before simulating shutdown - * @param $expectNLAppending bool: Whether or not shutdown simulation is expected - * to add a newline to the output. If false, $preShutdownOutput is the - * expected output after shutdown simulation. Otherwise, - * $preShutdownOutput with an appended newline is the expected output - * after shutdown simulation. - */ - private function assertOutputPrePostShutdown( $preShutdownOutput, $expectNLAppending ) { - - $this->assertEquals( $preShutdownOutput, $this->getActualOutput(), - "Output before shutdown simulation" ); - - $this->m->simulateShutdown(); - $this->m = null; - - $postShutdownOutput = $preShutdownOutput . ( $expectNLAppending ? "\n" : "" ); - $this->expectOutputString( $postShutdownOutput ); - } - - - // Although the following tests do not seem to be too consistent (compare for - // example the newlines within the test.*StringString tests, or the - // 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 ); - } - - function testOutputString() { - $this->m->output( "foo" ); - $this->assertOutputPrePostShutdown( "foo", false ); - } - - function testOutputStringString() { - $this->m->output( "foo" ); - $this->m->output( "bar" ); - $this->assertOutputPrePostShutdown( "foobar", false ); - } - - function testOutputStringNL() { - $this->m->output( "foo\n" ); - $this->assertOutputPrePostShutdown( "foo\n", false ); - } - - function testOutputStringNLNL() { - $this->m->output( "foo\n\n" ); - $this->assertOutputPrePostShutdown( "foo\n\n", false ); - } - - function testOutputStringNLString() { - $this->m->output( "foo\nbar" ); - $this->assertOutputPrePostShutdown( "foo\nbar", false ); - } - - function testOutputStringNLStringNL() { - $this->m->output( "foo\nbar\n" ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testOutputStringNLStringNLLinewise() { - $this->m->output( "foo\n" ); - $this->m->output( "bar\n" ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testOutputStringNLStringNLArbitrary() { - $this->m->output( "" ); - $this->m->output( "foo" ); - $this->m->output( "" ); - $this->m->output( "\n" ); - $this->m->output( "ba" ); - $this->m->output( "" ); - $this->m->output( "r\n" ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testOutputStringNLStringNLArbitraryAgain() { - $this->m->output( "" ); - $this->m->output( "foo" ); - $this->m->output( "" ); - $this->m->output( "\nb" ); - $this->m->output( "a" ); - $this->m->output( "" ); - $this->m->output( "r\n" ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testOutputWNullChannelEmpty() { - $this->m->output( "", null ); - $this->assertOutputPrePostShutdown( "", false ); - } - - function testOutputWNullChannelString() { - $this->m->output( "foo", null ); - $this->assertOutputPrePostShutdown( "foo", false ); - } - - function testOutputWNullChannelStringString() { - $this->m->output( "foo", null ); - $this->m->output( "bar", null ); - $this->assertOutputPrePostShutdown( "foobar", false ); - } - - function testOutputWNullChannelStringNL() { - $this->m->output( "foo\n", null ); - $this->assertOutputPrePostShutdown( "foo\n", false ); - } - - function testOutputWNullChannelStringNLNL() { - $this->m->output( "foo\n\n", null ); - $this->assertOutputPrePostShutdown( "foo\n\n", false ); - } - - function testOutputWNullChannelStringNLString() { - $this->m->output( "foo\nbar", null ); - $this->assertOutputPrePostShutdown( "foo\nbar", false ); - } - - function testOutputWNullChannelStringNLStringNL() { - $this->m->output( "foo\nbar\n", null ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testOutputWNullChannelStringNLStringNLLinewise() { - $this->m->output( "foo\n", null ); - $this->m->output( "bar\n", null ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testOutputWNullChannelStringNLStringNLArbitrary() { - $this->m->output( "", null ); - $this->m->output( "foo", null ); - $this->m->output( "", null ); - $this->m->output( "\n", null ); - $this->m->output( "ba", null ); - $this->m->output( "", null ); - $this->m->output( "r\n", null ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testOutputWNullChannelStringNLStringNLArbitraryAgain() { - $this->m->output( "", null ); - $this->m->output( "foo", null ); - $this->m->output( "", null ); - $this->m->output( "\nb", null ); - $this->m->output( "a", null ); - $this->m->output( "", null ); - $this->m->output( "r\n", null ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testOutputWChannelString() { - $this->m->output( "foo", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo", true ); - } - - function testOutputWChannelStringNL() { - $this->m->output( "foo\n", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo", true ); - } - - function testOutputWChannelStringNLNL() { - // If this test fails, note that output takes strings with double line - // endings (although output's implementation in this situation calls - // outputChanneled with a string ending in a nl ... which is not allowed - // according to the documentation of outputChanneled) - $this->m->output( "foo\n\n", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\n", true ); - } - - function testOutputWChannelStringNLString() { - $this->m->output( "foo\nbar", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar", true ); - } - - function testOutputWChannelStringNLStringNL() { - $this->m->output( "foo\nbar\n", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar", true ); - } - - function testOutputWChannelStringNLStringNLLinewise() { - $this->m->output( "foo\n", "bazChannel" ); - $this->m->output( "bar\n", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar", true ); - } - - function testOutputWChannelStringNLStringNLArbitrary() { - $this->m->output( "", "bazChannel" ); - $this->m->output( "foo", "bazChannel" ); - $this->m->output( "", "bazChannel" ); - $this->m->output( "\n", "bazChannel" ); - $this->m->output( "ba", "bazChannel" ); - $this->m->output( "", "bazChannel" ); - $this->m->output( "r\n", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar", true ); - } - - function testOutputWChannelStringNLStringNLArbitraryAgain() { - $this->m->output( "", "bazChannel" ); - $this->m->output( "foo", "bazChannel" ); - $this->m->output( "", "bazChannel" ); - $this->m->output( "\nb", "bazChannel" ); - $this->m->output( "a", "bazChannel" ); - $this->m->output( "", "bazChannel" ); - $this->m->output( "r\n", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar", true ); - } - - function testOutputWMultipleChannelsChannelChange() { - $this->m->output( "foo", "bazChannel" ); - $this->m->output( "bar", "bazChannel" ); - $this->m->output( "qux", "quuxChannel" ); - $this->m->output( "corge", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", true ); - } - - function testOutputWMultipleChannelsChannelChangeNL() { - $this->m->output( "foo", "bazChannel" ); - $this->m->output( "bar\n", "bazChannel" ); - $this->m->output( "qux\n", "quuxChannel" ); - $this->m->output( "corge", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", true ); - } - - function testOutputWAndWOChannelStringStartWO() { - $this->m->output( "foo" ); - $this->m->output( "bar", "bazChannel" ); - $this->m->output( "qux" ); - $this->m->output( "quux", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar\nquxquux", true ); - } - - function testOutputWAndWOChannelStringStartW() { - $this->m->output( "foo", "bazChannel" ); - $this->m->output( "bar" ); - $this->m->output( "qux", "bazChannel" ); - $this->m->output( "quux" ); - $this->assertOutputPrePostShutdown( "foo\nbarqux\nquux", false ); - } - - function testOutputWChannelTypeSwitch() { - $this->m->output( "foo", 1 ); - $this->m->output( "bar", 1.0 ); - $this->assertOutputPrePostShutdown( "foo\nbar", true ); - } - - function testOutputIntermittentEmpty() { - $this->m->output( "foo" ); - $this->m->output( "" ); - $this->m->output( "bar" ); - $this->assertOutputPrePostShutdown( "foobar", false ); - } - - function testOutputIntermittentFalse() { - $this->m->output( "foo" ); - $this->m->output( false ); - $this->m->output( "bar" ); - $this->assertOutputPrePostShutdown( "foobar", false ); - } - - function testOutputIntermittentFalseAfterOtherChannel() { - $this->m->output( "qux", "quuxChannel" ); - $this->m->output( "foo" ); - $this->m->output( false ); - $this->m->output( "bar" ); - $this->assertOutputPrePostShutdown( "qux\nfoobar", false ); - } - - function testOutputWNullChannelIntermittentEmpty() { - $this->m->output( "foo", null ); - $this->m->output( "", null ); - $this->m->output( "bar", null ); - $this->assertOutputPrePostShutdown( "foobar", false ); - } - - function testOutputWNullChannelIntermittentFalse() { - $this->m->output( "foo", null ); - $this->m->output( false, null ); - $this->m->output( "bar", null ); - $this->assertOutputPrePostShutdown( "foobar", false ); - } - - function testOutputWChannelIntermittentEmpty() { - $this->m->output( "foo", "bazChannel" ); - $this->m->output( "", "bazChannel" ); - $this->m->output( "bar", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar", true ); - } - - function testOutputWChannelIntermittentFalse() { - $this->m->output( "foo", "bazChannel" ); - $this->m->output( false, "bazChannel" ); - $this->m->output( "bar", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar", true ); - } - - // Note that (per documentation) outputChanneled does take strings that end - // in \n, hence we do not test such strings. - - function testOutputChanneledEmpty() { - $this->m->outputChanneled( "" ); - $this->assertOutputPrePostShutdown( "\n", false ); - } - - function testOutputChanneledString() { - $this->m->outputChanneled( "foo" ); - $this->assertOutputPrePostShutdown( "foo\n", false ); - } - - function testOutputChanneledStringString() { - $this->m->outputChanneled( "foo" ); - $this->m->outputChanneled( "bar" ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testOutputChanneledStringNLString() { - $this->m->outputChanneled( "foo\nbar" ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testOutputChanneledStringNLStringNLArbitraryAgain() { - $this->m->outputChanneled( "" ); - $this->m->outputChanneled( "foo" ); - $this->m->outputChanneled( "" ); - $this->m->outputChanneled( "\nb" ); - $this->m->outputChanneled( "a" ); - $this->m->outputChanneled( "" ); - $this->m->outputChanneled( "r" ); - $this->assertOutputPrePostShutdown( "\nfoo\n\n\nb\na\n\nr\n", false ); - } - - function testOutputChanneledWNullChannelEmpty() { - $this->m->outputChanneled( "", null ); - $this->assertOutputPrePostShutdown( "\n", false ); - } - - function testOutputChanneledWNullChannelString() { - $this->m->outputChanneled( "foo", null ); - $this->assertOutputPrePostShutdown( "foo\n", false ); - } - - function testOutputChanneledWNullChannelStringString() { - $this->m->outputChanneled( "foo", null ); - $this->m->outputChanneled( "bar", null ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testOutputChanneledWNullChannelStringNLString() { - $this->m->outputChanneled( "foo\nbar", null ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testOutputChanneledWNullChannelStringNLStringNLArbitraryAgain() { - $this->m->outputChanneled( "", null ); - $this->m->outputChanneled( "foo", null ); - $this->m->outputChanneled( "", null ); - $this->m->outputChanneled( "\nb", null ); - $this->m->outputChanneled( "a", null ); - $this->m->outputChanneled( "", null ); - $this->m->outputChanneled( "r", null ); - $this->assertOutputPrePostShutdown( "\nfoo\n\n\nb\na\n\nr\n", false ); - } - - function testOutputChanneledWChannelString() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo", true ); - } - - function testOutputChanneledWChannelStringNLString() { - $this->m->outputChanneled( "foo\nbar", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar", true ); - } - - function testOutputChanneledWChannelStringString() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->outputChanneled( "bar", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar", true ); - } - - function testOutputChanneledWChannelStringNLStringNLArbitraryAgain() { - $this->m->outputChanneled( "", "bazChannel" ); - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->outputChanneled( "", "bazChannel" ); - $this->m->outputChanneled( "\nb", "bazChannel" ); - $this->m->outputChanneled( "a", "bazChannel" ); - $this->m->outputChanneled( "", "bazChannel" ); - $this->m->outputChanneled( "r", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar", true ); - } - - function testOutputChanneledWMultipleChannelsChannelChange() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->outputChanneled( "bar", "bazChannel" ); - $this->m->outputChanneled( "qux", "quuxChannel" ); - $this->m->outputChanneled( "corge", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", true ); - } - - function testOutputChanneledWMultipleChannelsChannelChangeEnclosedNull() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->outputChanneled( "bar", null ); - $this->m->outputChanneled( "qux", null ); - $this->m->outputChanneled( "corge", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar\nqux\ncorge", true ); - } - - function testOutputChanneledWMultipleChannelsChannelAfterNullChange() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->outputChanneled( "bar", null ); - $this->m->outputChanneled( "qux", null ); - $this->m->outputChanneled( "corge", "quuxChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar\nqux\ncorge", true ); - } - - function testOutputChanneledWAndWOChannelStringStartWO() { - $this->m->outputChanneled( "foo" ); - $this->m->outputChanneled( "bar", "bazChannel" ); - $this->m->outputChanneled( "qux" ); - $this->m->outputChanneled( "quux", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar\nqux\nquux", true ); - } - - function testOutputChanneledWAndWOChannelStringStartW() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->outputChanneled( "bar" ); - $this->m->outputChanneled( "qux", "bazChannel" ); - $this->m->outputChanneled( "quux" ); - $this->assertOutputPrePostShutdown( "foo\nbar\nqux\nquux\n", false ); - } - - function testOutputChanneledWChannelTypeSwitch() { - $this->m->outputChanneled( "foo", 1 ); - $this->m->outputChanneled( "bar", 1.0 ); - $this->assertOutputPrePostShutdown( "foo\nbar", true ); - } - - function testOutputChanneledWOChannelIntermittentEmpty() { - $this->m->outputChanneled( "foo" ); - $this->m->outputChanneled( "" ); - $this->m->outputChanneled( "bar" ); - $this->assertOutputPrePostShutdown( "foo\n\nbar\n", false ); - } - - function testOutputChanneledWOChannelIntermittentFalse() { - $this->m->outputChanneled( "foo" ); - $this->m->outputChanneled( false ); - $this->m->outputChanneled( "bar" ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testOutputChanneledWNullChannelIntermittentEmpty() { - $this->m->outputChanneled( "foo", null ); - $this->m->outputChanneled( "", null ); - $this->m->outputChanneled( "bar", null ); - $this->assertOutputPrePostShutdown( "foo\n\nbar\n", false ); - } - - function testOutputChanneledWNullChannelIntermittentFalse() { - $this->m->outputChanneled( "foo", null ); - $this->m->outputChanneled( false, null ); - $this->m->outputChanneled( "bar", null ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testOutputChanneledWChannelIntermittentEmpty() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->outputChanneled( "", "bazChannel" ); - $this->m->outputChanneled( "bar", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar", true ); - } - - function testOutputChanneledWChannelIntermittentFalse() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->outputChanneled( false, "bazChannel" ); - $this->m->outputChanneled( "bar", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar", true ); - } - - function testCleanupChanneledClean() { - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "", false ); - } - - function testCleanupChanneledAfterOutput() { - $this->m->output( "foo" ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo", false ); - } - - function testCleanupChanneledAfterOutputWNullChannel() { - $this->m->output( "foo", null ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo", false ); - } - - function testCleanupChanneledAfterOutputWChannel() { - $this->m->output( "foo", "bazChannel" ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo\n", false ); - } - - function testCleanupChanneledAfterNLOutput() { - $this->m->output( "foo\n" ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo\n", false ); - } - - function testCleanupChanneledAfterNLOutputWNullChannel() { - $this->m->output( "foo\n", null ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo\n", false ); - } - - function testCleanupChanneledAfterNLOutputWChannel() { - $this->m->output( "foo\n", "bazChannel" ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo\n", false ); - } - - function testCleanupChanneledAfterOutputChanneledWOChannel() { - $this->m->outputChanneled( "foo" ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo\n", false ); - } - - function testCleanupChanneledAfterOutputChanneledWNullChannel() { - $this->m->outputChanneled( "foo", null ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo\n", false ); - } - - function testCleanupChanneledAfterOutputChanneledWChannel() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo\n", false ); - } - - function testMultipleMaintenanceObjectsInteractionOutput() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->output( "foo" ); - $m2->output( "bar" ); - - $this->assertEquals( "foobar", $this->getActualOutput(), - "Output before shutdown simulation (m2)" ); - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foobar", false ); - } - - function testMultipleMaintenanceObjectsInteractionOutputWNullChannel() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->output( "foo", null ); - $m2->output( "bar", null ); - - $this->assertEquals( "foobar", $this->getActualOutput(), - "Output before shutdown simulation (m2)" ); - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foobar", false ); - } - - function testMultipleMaintenanceObjectsInteractionOutputWChannel() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->output( "foo", "bazChannel" ); - $m2->output( "bar", "bazChannel" ); - - $this->assertEquals( "foobar", $this->getActualOutput(), - "Output before shutdown simulation (m2)" ); - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foobar\n", true ); - } - - function testMultipleMaintenanceObjectsInteractionOutputWNullChannelNL() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->output( "foo\n", null ); - $m2->output( "bar\n", null ); - - $this->assertEquals( "foo\nbar\n", $this->getActualOutput(), - "Output before shutdown simulation (m2)" ); - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testMultipleMaintenanceObjectsInteractionOutputWChannelNL() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->output( "foo\n", "bazChannel" ); - $m2->output( "bar\n", "bazChannel" ); - - $this->assertEquals( "foobar", $this->getActualOutput(), - "Output before shutdown simulation (m2)" ); - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foobar\n", true ); - } - - function testMultipleMaintenanceObjectsInteractionOutputChanneled() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->outputChanneled( "foo" ); - $m2->outputChanneled( "bar" ); - - $this->assertEquals( "foo\nbar\n", $this->getActualOutput(), - "Output before shutdown simulation (m2)" ); - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testMultipleMaintenanceObjectsInteractionOutputChanneledWNullChannel() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->outputChanneled( "foo", null ); - $m2->outputChanneled( "bar", null ); - - $this->assertEquals( "foo\nbar\n", $this->getActualOutput(), - "Output before shutdown simulation (m2)" ); - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foo\nbar\n", false ); - } - - function testMultipleMaintenanceObjectsInteractionOutputChanneledWChannel() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->outputChanneled( "foo", "bazChannel" ); - $m2->outputChanneled( "bar", "bazChannel" ); - - $this->assertEquals( "foobar", $this->getActualOutput(), - "Output before shutdown simulation (m2)" ); - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foobar\n", true ); - } - - function testMultipleMaintenanceObjectsInteractionCleanupChanneledWChannel() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->outputChanneled( "foo", "bazChannel" ); - $m2->outputChanneled( "bar", "bazChannel" ); - - $this->assertEquals( "foobar", $this->getActualOutput(), - "Output before first cleanup" ); - $this->m->cleanupChanneled(); - $this->assertEquals( "foobar\n", $this->getActualOutput(), - "Output after first cleanup" ); - $m2->cleanupChanneled(); - $this->assertEquals( "foobar\n\n", $this->getActualOutput(), - "Output after second cleanup" ); - - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foobar\n\n", false ); - } -} diff --git a/tests/phpunit/maintenance/backupPrefetchTest.php b/tests/phpunit/maintenance/backupPrefetchTest.php deleted file mode 100644 index bc2d7375..00000000 --- a/tests/phpunit/maintenance/backupPrefetchTest.php +++ /dev/null @@ -1,275 +0,0 @@ -<?php - -require_once __DIR__ . "/../../../maintenance/backupPrefetch.inc"; - -/** - * Tests for BaseDump - * - * @group Dump - */ -class BaseDumpTest extends MediaWikiTestCase { - - /** - * @var BaseDump the BaseDump instance used within a test. - * - * If set, this BaseDump gets automatically closed in tearDown. - */ - private $dump = null; - - protected function tearDown() { - if ( $this->dump !== null ) { - $this->dump->close(); - } - - // Bug 37458, parent teardown need to be done after closing the - // dump or it might cause some permissions errors. - parent::tearDown(); - } - - /** - * asserts that a prefetch yields an expected string - * - * @param $expected string|null: the exepcted result of the prefetch - * @param $page int: the page number to prefetch the text for - * @param $revision int: the revision number to prefetch the text for - */ - private function assertPrefetchEquals( $expected, $page, $revision ) { - $this->assertEquals( $expected, $this->dump->prefetch( $page, $revision ), - "Prefetch of page $page revision $revision" ); - } - - function testSequential() { - $fname = $this->setUpPrefetch(); - $this->dump = new BaseDump( $fname ); - - $this->assertPrefetchEquals( "BackupDumperTestP1Text1", 1, 1 ); - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - $this->assertPrefetchEquals( "BackupDumperTestP2Text4 some additional Text", 2, 5 ); - $this->assertPrefetchEquals( "Talk about BackupDumperTestP1 Text1", 4, 8 ); - } - - function testSynchronizeRevisionMissToRevision() { - $fname = $this->setUpPrefetch(); - $this->dump = new BaseDump( $fname ); - - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - $this->assertPrefetchEquals( null, 2, 3 ); - $this->assertPrefetchEquals( "BackupDumperTestP2Text4 some additional Text", 2, 5 ); - } - - function testSynchronizeRevisionMissToPage() { - $fname = $this->setUpPrefetch(); - $this->dump = new BaseDump( $fname ); - - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - $this->assertPrefetchEquals( null, 2, 40 ); - $this->assertPrefetchEquals( "Talk about BackupDumperTestP1 Text1", 4, 8 ); - } - - function testSynchronizePageMiss() { - $fname = $this->setUpPrefetch(); - $this->dump = new BaseDump( $fname ); - - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - $this->assertPrefetchEquals( null, 3, 40 ); - $this->assertPrefetchEquals( "Talk about BackupDumperTestP1 Text1", 4, 8 ); - } - - function testPageMissAtEnd() { - $fname = $this->setUpPrefetch(); - $this->dump = new BaseDump( $fname ); - - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - $this->assertPrefetchEquals( null, 6, 40 ); - } - - function testRevisionMissAtEnd() { - $fname = $this->setUpPrefetch(); - $this->dump = new BaseDump( $fname ); - - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - $this->assertPrefetchEquals( null, 4, 40 ); - } - - function testSynchronizePageMissAtStart() { - $fname = $this->setUpPrefetch(); - $this->dump = new BaseDump( $fname ); - - $this->assertPrefetchEquals( null, 0, 2 ); - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - } - - function testSynchronizeRevisionMissAtStart() { - $fname = $this->setUpPrefetch(); - $this->dump = new BaseDump( $fname ); - - $this->assertPrefetchEquals( null, 1, -2 ); - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - } - - function testSequentialAcrossFiles() { - $fname1 = $this->setUpPrefetch( array( 1 ) ); - $fname2 = $this->setUpPrefetch( array( 2, 4 ) ); - $this->dump = new BaseDump( $fname1 . ";" . $fname2 ); - - $this->assertPrefetchEquals( "BackupDumperTestP1Text1", 1, 1 ); - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - $this->assertPrefetchEquals( "BackupDumperTestP2Text4 some additional Text", 2, 5 ); - $this->assertPrefetchEquals( "Talk about BackupDumperTestP1 Text1", 4, 8 ); - } - - function testSynchronizeSkipAcrossFile() { - $fname1 = $this->setUpPrefetch( array( 1 ) ); - $fname2 = $this->setUpPrefetch( array( 2 ) ); - $fname3 = $this->setUpPrefetch( array( 4 ) ); - $this->dump = new BaseDump( $fname1 . ";" . $fname2 . ";" . $fname3 ); - - $this->assertPrefetchEquals( "BackupDumperTestP1Text1", 1, 1 ); - $this->assertPrefetchEquals( "Talk about BackupDumperTestP1 Text1", 4, 8 ); - } - - function testSynchronizeMissInWholeFirstFile() { - $fname1 = $this->setUpPrefetch( array( 1 ) ); - $fname2 = $this->setUpPrefetch( array( 2 ) ); - $this->dump = new BaseDump( $fname1 . ";" . $fname2 ); - - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - } - - - /** - * Constructs a temporary file that can be used for prefetching - * - * The temporary file is removed by DumpBackup upon tearDown. - * - * @param $requested_pages Array The indices of the page parts that should - * go into the prefetch file. 1,2,4 are available. - * @return String The file name of the created temporary file - */ - private function setUpPrefetch( $requested_pages = array( 1, 2, 4 ) ) { - // The file name, where we store the prepared prefetch file - $fname = $this->getNewTempFile(); - - // The header of every prefetch file - $header = '<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.7/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.7/ http://www.mediawiki.org/xml/export-0.7.xsd" version="0.7" xml:lang="en"> - <siteinfo> - <sitename>wikisvn</sitename> - <base>http://localhost/wiki-svn/index.php/Main_Page</base> - <generator>MediaWiki 1.21alpha</generator> - <case>first-letter</case> - <namespaces> - <namespace key="-2" case="first-letter">Media</namespace> - <namespace key="-1" case="first-letter">Special</namespace> - <namespace key="0" case="first-letter" /> - <namespace key="1" case="first-letter">Talk</namespace> - <namespace key="2" case="first-letter">User</namespace> - <namespace key="3" case="first-letter">User talk</namespace> - <namespace key="4" case="first-letter">Wikisvn</namespace> - <namespace key="5" case="first-letter">Wikisvn talk</namespace> - <namespace key="6" case="first-letter">File</namespace> - <namespace key="7" case="first-letter">File talk</namespace> - <namespace key="8" case="first-letter">MediaWiki</namespace> - <namespace key="9" case="first-letter">MediaWiki talk</namespace> - <namespace key="10" case="first-letter">Template</namespace> - <namespace key="11" case="first-letter">Template talk</namespace> - <namespace key="12" case="first-letter">Help</namespace> - <namespace key="13" case="first-letter">Help talk</namespace> - <namespace key="14" case="first-letter">Category</namespace> - <namespace key="15" case="first-letter">Category talk</namespace> - </namespaces> - </siteinfo> -'; - - // An array holding the pages that are available for prefetch - $available_pages = array(); - - // Simple plain page - $available_pages[1] = ' <page> - <title>BackupDumperTestP1</title> - <ns>0</ns> - <id>1</id> - <revision> - <id>1</id> - <timestamp>2012-04-01T16:46:05Z</timestamp> - <contributor> - <ip>127.0.0.1</ip> - </contributor> - <comment>BackupDumperTestP1Summary1</comment> - <sha1>0bolhl6ol7i6x0e7yq91gxgaan39j87</sha1> - <text xml:space="preserve">BackupDumperTestP1Text1</text> - <model name="wikitext">1</model> - <format mime="text/x-wiki">1</format> - </revision> - </page> -'; - // Page with more than one revisions. Hole in rev ids. - $available_pages[2] = ' <page> - <title>BackupDumperTestP2</title> - <ns>0</ns> - <id>2</id> - <revision> - <id>2</id> - <timestamp>2012-04-01T16:46:05Z</timestamp> - <contributor> - <ip>127.0.0.1</ip> - </contributor> - <comment>BackupDumperTestP2Summary1</comment> - <sha1>jprywrymfhysqllua29tj3sc7z39dl2</sha1> - <text xml:space="preserve">BackupDumperTestP2Text1</text> - <model name="wikitext">1</model> - <format mime="text/x-wiki">1</format> - </revision> - <revision> - <id>5</id> - <parentid>2</parentid> - <timestamp>2012-04-01T16:46:05Z</timestamp> - <contributor> - <ip>127.0.0.1</ip> - </contributor> - <comment>BackupDumperTestP2Summary4 extra</comment> - <sha1>6o1ciaxa6pybnqprmungwofc4lv00wv</sha1> - <text xml:space="preserve">BackupDumperTestP2Text4 some additional Text</text> - <model name="wikitext">1</model> - <format mime="text/x-wiki">1</format> - </revision> - </page> -'; - // Page with id higher than previous id + 1 - $available_pages[4] = ' <page> - <title>Talk:BackupDumperTestP1</title> - <ns>1</ns> - <id>4</id> - <revision> - <id>8</id> - <timestamp>2012-04-01T16:46:05Z</timestamp> - <contributor> - <ip>127.0.0.1</ip> - </contributor> - <comment>Talk BackupDumperTestP1 Summary1</comment> - <sha1>nktofwzd0tl192k3zfepmlzxoax1lpe</sha1> - <model name="wikitext">1</model> - <format mime="text/x-wiki">1</format> - <text xml:space="preserve">Talk about BackupDumperTestP1 Text1</text> - </revision> - </page> -'; - - // The common ending for all files - $tail = '</mediawiki> -'; - - // Putting together the content of the prefetch files - $content = $header; - foreach ( $requested_pages as $i ) { - $this->assertTrue( array_key_exists( $i, $available_pages ), - "Check for availability of requested page " . $i ); - $content .= $available_pages[$i]; - } - $content .= $tail; - - $this->assertEquals( strlen( $content ), file_put_contents( - $fname, $content ), "Length of prepared prefetch" ); - - return $fname; - } -} diff --git a/tests/phpunit/maintenance/backupTextPassTest.php b/tests/phpunit/maintenance/backupTextPassTest.php deleted file mode 100644 index 653a1145..00000000 --- a/tests/phpunit/maintenance/backupTextPassTest.php +++ /dev/null @@ -1,581 +0,0 @@ -<?php - -require_once __DIR__ . "/../../../maintenance/backupTextPass.inc"; - -/** - * Tests for page dumps of BackupDumper - * - * @group Database - * @group Dump - */ -class TextPassDumperTest extends DumpTestCase { - - // We'll add several pages, revision and texts. The following variables hold the - // corresponding ids. - private $pageId1, $pageId2, $pageId3, $pageId4; - private static $numOfPages = 4; - private $revId1_1, $textId1_1; - private $revId2_1, $textId2_1, $revId2_2, $textId2_2; - private $revId2_3, $textId2_3, $revId2_4, $textId2_4; - private $revId3_1, $textId3_1, $revId3_2, $textId3_2; - private $revId4_1, $textId4_1; - private static $numOfRevs = 8; - - function addDBData() { - $this->tablesUsed[] = 'page'; - $this->tablesUsed[] = 'revision'; - $this->tablesUsed[] = 'text'; - - $ns = $this->getDefaultWikitextNS(); - - try { - // Simple page - $title = Title::newFromText( 'BackupDumperTestP1', $ns ); - $page = WikiPage::factory( $title ); - list( $this->revId1_1, $this->textId1_1 ) = $this->addRevision( $page, - "BackupDumperTestP1Text1", "BackupDumperTestP1Summary1" ); - $this->pageId1 = $page->getId(); - - // Page with more than one revision - $title = Title::newFromText( 'BackupDumperTestP2', $ns ); - $page = WikiPage::factory( $title ); - list( $this->revId2_1, $this->textId2_1 ) = $this->addRevision( $page, - "BackupDumperTestP2Text1", "BackupDumperTestP2Summary1" ); - list( $this->revId2_2, $this->textId2_2 ) = $this->addRevision( $page, - "BackupDumperTestP2Text2", "BackupDumperTestP2Summary2" ); - list( $this->revId2_3, $this->textId2_3 ) = $this->addRevision( $page, - "BackupDumperTestP2Text3", "BackupDumperTestP2Summary3" ); - list( $this->revId2_4, $this->textId2_4 ) = $this->addRevision( $page, - "BackupDumperTestP2Text4 some additional Text ", - "BackupDumperTestP2Summary4 extra " ); - $this->pageId2 = $page->getId(); - - // Deleted page. - $title = Title::newFromText( 'BackupDumperTestP3', $ns ); - $page = WikiPage::factory( $title ); - list( $this->revId3_1, $this->textId3_1 ) = $this->addRevision( $page, - "BackupDumperTestP3Text1", "BackupDumperTestP2Summary1" ); - list( $this->revId3_2, $this->textId3_2 ) = $this->addRevision( $page, - "BackupDumperTestP3Text2", "BackupDumperTestP2Summary2" ); - $this->pageId3 = $page->getId(); - $page->doDeleteArticle( "Testing ;)" ); - - // Page from non-default namespace - - if ( $ns === NS_TALK ) { - // @todo work around this. - throw new MWException( "The default wikitext namespace is the talk namespace. " - . " We can't currently deal with that." ); - } - - $title = Title::newFromText( 'BackupDumperTestP1', NS_TALK ); - $page = WikiPage::factory( $title ); - list( $this->revId4_1, $this->textId4_1 ) = $this->addRevision( $page, - "Talk about BackupDumperTestP1 Text1", - "Talk BackupDumperTestP1 Summary1" ); - $this->pageId4 = $page->getId(); - } catch ( Exception $e ) { - // We'd love to pass $e directly. However, ... see - // documentation of exceptionFromAddDBData in - // DumpTestCase - $this->exceptionFromAddDBData = $e; - } - } - - protected function setUp() { - parent::setUp(); - - // Since we will restrict dumping by page ranges (to allow - // working tests, even if the db gets prepopulated by a base - // class), we have to assert, that the page id are consecutively - // increasing - $this->assertEquals( - array( $this->pageId2, $this->pageId3, $this->pageId4 ), - array( $this->pageId1 + 1, $this->pageId2 + 1, $this->pageId3 + 1 ), - "Page ids increasing without holes" ); - } - - function testPlain() { - // Setting up the dump - $nameStub = $this->setUpStub(); - $nameFull = $this->getNewTempFile(); - $dumper = new TextPassDumper( array( "--stub=file:" . $nameStub, - "--output=file:" . $nameFull ) ); - $dumper->reporting = false; - $dumper->setDb( $this->db ); - - // Performing the dump - $dumper->dump( WikiExporter::FULL, WikiExporter::TEXT ); - - // Checking for correctness of the dumped data - $this->assertDumpStart( $nameFull ); - - // Page 1 - $this->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" ); - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87", - "BackupDumperTestP1Text1" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" ); - $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1", - $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2", - "BackupDumperTestP2Text1" ); - $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2", - $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95", - "BackupDumperTestP2Text2", $this->revId2_1 ); - $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3", - $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r", - "BackupDumperTestP2Text3", $this->revId2_2 ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv", - "BackupDumperTestP2Text4 some additional Text", $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - $this->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" ); - $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe", - "Talk about BackupDumperTestP1 Text1" ); - $this->assertPageEnd(); - - $this->assertDumpEnd(); - } - - function testPrefetchPlain() { - // The mapping between ids and text, for the hits of the prefetch mock - $prefetchMap = array( - array( $this->pageId1, $this->revId1_1, "Prefetch_________1Text1" ), - array( $this->pageId2, $this->revId2_3, "Prefetch_________2Text3" ) - ); - - // The mock itself - $prefetchMock = $this->getMock( 'BaseDump', array( 'prefetch' ), array(), '', false ); - $prefetchMock->expects( $this->exactly( 6 ) ) - ->method( 'prefetch' ) - ->will( $this->returnValueMap( $prefetchMap ) ); - - // Setting up of the dump - $nameStub = $this->setUpStub(); - $nameFull = $this->getNewTempFile(); - $dumper = new TextPassDumper( array( "--stub=file:" - . $nameStub, "--output=file:" . $nameFull ) ); - $dumper->prefetch = $prefetchMock; - $dumper->reporting = false; - $dumper->setDb( $this->db ); - - // Performing the dump - $dumper->dump( WikiExporter::FULL, WikiExporter::TEXT ); - - // Checking for correctness of the dumped data - $this->assertDumpStart( $nameFull ); - - // Page 1 - $this->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" ); - // Prefetch kicks in. This is still the SHA-1 of the original text, - // But the actual text (with different SHA-1) comes from prefetch. - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87", - "Prefetch_________1Text1" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" ); - $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1", - $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2", - "BackupDumperTestP2Text1" ); - $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2", - $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95", - "BackupDumperTestP2Text2", $this->revId2_1 ); - // Prefetch kicks in. This is still the SHA-1 of the original text, - // But the actual text (with different SHA-1) comes from prefetch. - $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3", - $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r", - "Prefetch_________2Text3", $this->revId2_2 ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv", - "BackupDumperTestP2Text4 some additional Text", $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - $this->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" ); - $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe", - "Talk about BackupDumperTestP1 Text1" ); - $this->assertPageEnd(); - - $this->assertDumpEnd(); - } - - /** - * Ensures that checkpoint dumps are used and written, by successively increasing the - * stub size and dumping until the duration crosses a threshold. - * - * @param $checkpointFormat string: Either "file" for plain text or "gzip" for gzipped - * checkpoint files. - */ - private function checkpointHelper( $checkpointFormat = "file" ) { - // Getting temporary names - $nameStub = $this->getNewTempFile(); - $nameOutputDir = $this->getNewTempDirectory(); - - $stderr = fopen( 'php://output', 'a' ); - if ( $stderr === false ) { - $this->fail( "Could not open stream for stderr" ); - } - - $iterations = 32; // We'll start with that many iterations of revisions in stub - $lastDuration = 0; - $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. - while ( $lastDuration < $minDuration ) { - - // Setting up the dump - wfRecursiveRemoveDir( $nameOutputDir ); - $this->assertTrue( wfMkdirParents( $nameOutputDir ), - "Creating temporary output directory " ); - $this->setUpStub( $nameStub, $iterations ); - $dumper = new TextPassDumper( array( "--stub=file:" . $nameStub, - "--output=" . $checkpointFormat . ":" . $nameOutputDir . "/full", - "--maxtime=1" /*This is in minutes. Fixup is below*/, - "--checkpointfile=checkpoint-%s-%s.xml.gz" ) ); - $dumper->setDb( $this->db ); - $dumper->maxTimeAllowed = $checkpointAfter; // Patching maxTime from 1 minute - $dumper->stderr = $stderr; - - // The actual dump and taking time - $ts_before = microtime( true ); - $dumper->dump( WikiExporter::FULL, WikiExporter::TEXT ); - $ts_after = microtime( true ); - $lastDuration = $ts_after - $ts_before; - - // Handling increasing the iteration count for the stubs - if ( $lastDuration < $minDuration ) { - $old_iterations = $iterations; - if ( $lastDuration > 0.2 ) { - // lastDuration is big enough, to allow an educated guess - $factor = ( $minDuration + 0.5 ) / $lastDuration; - if ( ( $factor > 1.1 ) && ( $factor < 100 ) ) { - // educated guess is reasonable - $iterations = (int)( $iterations * $factor ); - } - } - - if ( $old_iterations == $iterations ) { - // Heuristics were not applied, so we just *2. - $iterations *= 2; - } - - $this->assertLessThan( 50000, $iterations, - "Emergency stop against infinitely increasing iteration " - . "count ( last duration: $lastDuration )" ); - } - } - - // The dump (hopefully) did take long enough to produce more than one - // checkpoint file. - // - // We now check all the checkpoint files for validity. - - $files = scandir( $nameOutputDir ); - $this->assertTrue( asort( $files ), "Sorting files in temporary directory" ); - $fileOpened = false; - $lookingForPage = 1; - $checkpointFiles = 0; - - // Each run of the following loop body tries to handle exactly 1 /page/ (not - // iteration of stub content). $i is only increased after having treated page 4. - for ( $i = 0; $i < $iterations; ) { - - // 1. Assuring a file is opened and ready. Skipping across header if - // necessary. - if ( !$fileOpened ) { - $this->assertNotEmpty( $files, "No more existing dump files, " - . "but not yet all pages found" ); - $fname = array_shift( $files ); - while ( $fname == "." || $fname == ".." ) { - $this->assertNotEmpty( $files, "No more existing dump" - . " files, but not yet all pages found" ); - $fname = array_shift( $files ); - } - if ( $checkpointFormat == "gzip" ) { - $this->gunzip( $nameOutputDir . "/" . $fname ); - } - $this->assertDumpStart( $nameOutputDir . "/" . $fname ); - $fileOpened = true; - $checkpointFiles++; - } - - // 2. Performing a single page check - switch ( $lookingForPage ) { - case 1: - // Page 1 - $this->assertPageStart( $this->pageId1 + $i * self::$numOfPages, NS_MAIN, - "BackupDumperTestP1" ); - $this->assertRevision( $this->revId1_1 + $i * self::$numOfRevs, "BackupDumperTestP1Summary1", - $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87", - "BackupDumperTestP1Text1" ); - $this->assertPageEnd(); - - $lookingForPage = 2; - break; - - case 2: - // Page 2 - $this->assertPageStart( $this->pageId2 + $i * self::$numOfPages, NS_MAIN, - "BackupDumperTestP2" ); - $this->assertRevision( $this->revId2_1 + $i * self::$numOfRevs, "BackupDumperTestP2Summary1", - $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2", - "BackupDumperTestP2Text1" ); - $this->assertRevision( $this->revId2_2 + $i * self::$numOfRevs, "BackupDumperTestP2Summary2", - $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95", - "BackupDumperTestP2Text2", $this->revId2_1 + $i * self::$numOfRevs ); - $this->assertRevision( $this->revId2_3 + $i * self::$numOfRevs, "BackupDumperTestP2Summary3", - $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r", - "BackupDumperTestP2Text3", $this->revId2_2 + $i * self::$numOfRevs ); - $this->assertRevision( $this->revId2_4 + $i * self::$numOfRevs, - "BackupDumperTestP2Summary4 extra", - $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv", - "BackupDumperTestP2Text4 some additional Text", - $this->revId2_3 + $i * self::$numOfRevs ); - $this->assertPageEnd(); - - $lookingForPage = 4; - break; - - case 4: - // Page 4 - $this->assertPageStart( $this->pageId4 + $i * self::$numOfPages, NS_TALK, - "Talk:BackupDumperTestP1" ); - $this->assertRevision( $this->revId4_1 + $i * self::$numOfRevs, - "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe", - "Talk about BackupDumperTestP1 Text1" ); - $this->assertPageEnd(); - - $lookingForPage = 1; - - // We dealt with the whole iteration. - $i++; - break; - - default: - $this->fail( "Bad setting for lookingForPage ($lookingForPage)" ); - } - - // 3. Checking for the end of the current checkpoint file - if ( $this->xml->nodeType == XMLReader::END_ELEMENT - && $this->xml->name == "mediawiki" - ) { - $this->assertDumpEnd(); - $fileOpened = false; - } - } - - // Assuring we completely read all files ... - $this->assertFalse( $fileOpened, "Currently read file still open?" ); - $this->assertEmpty( $files, "Remaining unchecked files" ); - - // ... and have dealt with more than one checkpoint file - $this->assertGreaterThan( 1, $checkpointFiles, "expected more than 1 checkpoint to have been created. Checkpoint interval is $checkpointAfter seconds, maybe your computer is too fast?" ); - - $this->expectETAOutput(); - } - - /** - * @group large - */ - function testCheckpointPlain() { - $this->checkpointHelper(); - } - - /** - * tests for working checkpoint generation in gzip format work. - * - * We keep this test in addition to the simpler self::testCheckpointPlain, as there - * were once problems when the used sinks were DumpPipeOutputs. - * - * xmldumps-backup typically uses bzip2 instead of gzip. However, as bzip2 requires - * PHP extensions, we go for gzip instead, which triggers the same relevant code - * paths while still being testable on more systems. - * - * @group large - */ - function testCheckpointGzip() { - $this->checkHasGzip(); - $this->checkpointHelper( "gzip" ); - } - - - /** - * Creates a stub file that is used for testing the text pass of dumps - * - * @param $fname string: (Optional) Absolute name of the file to write - * the stub into. If this parameter is null, a new temporary - * file is generated that is automatically removed upon - * tearDown. - * @param $iterations integer: (Optional) specifies how often the block - * of 3 pages should go into the stub file. The page and - * revision id increase further and further, while the text - * id of the first iteration is reused. The pages and revision - * of iteration > 1 have no corresponding representation in the - * database. - * @return string absolute filename of the stub - */ - private function setUpStub( $fname = null, $iterations = 1 ) { - if ( $fname === null ) { - $fname = $this->getNewTempFile(); - } - $header = '<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.7/" ' - . 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' - . 'xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.7/ ' - . 'http://www.mediawiki.org/xml/export-0.7.xsd" version="0.7" xml:lang="en"> - <siteinfo> - <sitename>wikisvn</sitename> - <base>http://localhost/wiki-svn/index.php/Main_Page</base> - <generator>MediaWiki 1.21alpha</generator> - <case>first-letter</case> - <namespaces> - <namespace key="-2" case="first-letter">Media</namespace> - <namespace key="-1" case="first-letter">Special</namespace> - <namespace key="0" case="first-letter" /> - <namespace key="1" case="first-letter">Talk</namespace> - <namespace key="2" case="first-letter">User</namespace> - <namespace key="3" case="first-letter">User talk</namespace> - <namespace key="4" case="first-letter">Wikisvn</namespace> - <namespace key="5" case="first-letter">Wikisvn talk</namespace> - <namespace key="6" case="first-letter">File</namespace> - <namespace key="7" case="first-letter">File talk</namespace> - <namespace key="8" case="first-letter">MediaWiki</namespace> - <namespace key="9" case="first-letter">MediaWiki talk</namespace> - <namespace key="10" case="first-letter">Template</namespace> - <namespace key="11" case="first-letter">Template talk</namespace> - <namespace key="12" case="first-letter">Help</namespace> - <namespace key="13" case="first-letter">Help talk</namespace> - <namespace key="14" case="first-letter">Category</namespace> - <namespace key="15" case="first-letter">Category talk</namespace> - </namespaces> - </siteinfo> -'; - $tail = '</mediawiki> -'; - - $content = $header; - $iterations = intval( $iterations ); - for ( $i = 0; $i < $iterations; $i++ ) { - - $page1 = ' <page> - <title>BackupDumperTestP1</title> - <ns>0</ns> - <id>' . ( $this->pageId1 + $i * self::$numOfPages ) . '</id> - <revision> - <id>' . ( $this->revId1_1 + $i * self::$numOfRevs ) . '</id> - <timestamp>2012-04-01T16:46:05Z</timestamp> - <contributor> - <ip>127.0.0.1</ip> - </contributor> - <comment>BackupDumperTestP1Summary1</comment> - <sha1>0bolhl6ol7i6x0e7yq91gxgaan39j87</sha1> - <model>wikitext</model> - <format>text/x-wiki</format> - <text id="' . $this->textId1_1 . '" bytes="23" /> - </revision> - </page> -'; - $page2 = ' <page> - <title>BackupDumperTestP2</title> - <ns>0</ns> - <id>' . ( $this->pageId2 + $i * self::$numOfPages ) . '</id> - <revision> - <id>' . ( $this->revId2_1 + $i * self::$numOfRevs ) . '</id> - <timestamp>2012-04-01T16:46:05Z</timestamp> - <contributor> - <ip>127.0.0.1</ip> - </contributor> - <comment>BackupDumperTestP2Summary1</comment> - <sha1>jprywrymfhysqllua29tj3sc7z39dl2</sha1> - <model>wikitext</model> - <format>text/x-wiki</format> - <text id="' . $this->textId2_1 . '" bytes="23" /> - </revision> - <revision> - <id>' . ( $this->revId2_2 + $i * self::$numOfRevs ) . '</id> - <parentid>' . ( $this->revId2_1 + $i * self::$numOfRevs ) . '</parentid> - <timestamp>2012-04-01T16:46:05Z</timestamp> - <contributor> - <ip>127.0.0.1</ip> - </contributor> - <comment>BackupDumperTestP2Summary2</comment> - <sha1>b7vj5ks32po5m1z1t1br4o7scdwwy95</sha1> - <model>wikitext</model> - <format>text/x-wiki</format> - <text id="' . $this->textId2_2 . '" bytes="23" /> - </revision> - <revision> - <id>' . ( $this->revId2_3 + $i * self::$numOfRevs ) . '</id> - <parentid>' . ( $this->revId2_2 + $i * self::$numOfRevs ) . '</parentid> - <timestamp>2012-04-01T16:46:05Z</timestamp> - <contributor> - <ip>127.0.0.1</ip> - </contributor> - <comment>BackupDumperTestP2Summary3</comment> - <sha1>jfunqmh1ssfb8rs43r19w98k28gg56r</sha1> - <model>wikitext</model> - <format>text/x-wiki</format> - <text id="' . $this->textId2_3 . '" bytes="23" /> - </revision> - <revision> - <id>' . ( $this->revId2_4 + $i * self::$numOfRevs ) . '</id> - <parentid>' . ( $this->revId2_3 + $i * self::$numOfRevs ) . '</parentid> - <timestamp>2012-04-01T16:46:05Z</timestamp> - <contributor> - <ip>127.0.0.1</ip> - </contributor> - <comment>BackupDumperTestP2Summary4 extra</comment> - <sha1>6o1ciaxa6pybnqprmungwofc4lv00wv</sha1> - <model>wikitext</model> - <format>text/x-wiki</format> - <text id="' . $this->textId2_4 . '" bytes="44" /> - </revision> - </page> -'; - // page 3 not in stub - - $page4 = ' <page> - <title>Talk:BackupDumperTestP1</title> - <ns>1</ns> - <id>' . ( $this->pageId4 + $i * self::$numOfPages ) . '</id> - <revision> - <id>' . ( $this->revId4_1 + $i * self::$numOfRevs ) . '</id> - <timestamp>2012-04-01T16:46:05Z</timestamp> - <contributor> - <ip>127.0.0.1</ip> - </contributor> - <comment>Talk BackupDumperTestP1 Summary1</comment> - <sha1>nktofwzd0tl192k3zfepmlzxoax1lpe</sha1> - <model>wikitext</model> - <format>text/x-wiki</format> - <text id="' . $this->textId4_1 . '" bytes="35" /> - </revision> - </page> -'; - $content .= $page1 . $page2 . $page4; - } - $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 deleted file mode 100644 index 98d81653..00000000 --- a/tests/phpunit/maintenance/backup_LogTest.php +++ /dev/null @@ -1,228 +0,0 @@ -<?php -/** - * Tests for log dumps of BackupDumper - * - * @group Database - * @group Dump - */ -class BackupDumperLoggerTest extends DumpTestCase { - - - // We'll add several log entries and users for this test. The following - // variables hold the corresponding ids. - private $userId1, $userId2; - private $logId1, $logId2, $logId3; - - /** - * adds a log entry to the database. - * - * @param $type string: type of the log entry - * @param $subtype string: subtype of the log entry - * @param $user User: user that performs the logged operation - * @param $ns int: number of the namespace for the entry's target's title - * @param $title string: title of the entry's target - * @param $comment string: comment of the log entry - * @param $parameters Array: (optional) accompanying data that is attached - * to the entry - * - * @return int id of the added log entry - */ - private function addLogEntry( $type, $subtype, User $user, $ns, $title, - $comment = null, $parameters = null - ) { - $logEntry = new ManualLogEntry( $type, $subtype ); - $logEntry->setPerformer( $user ); - $logEntry->setTarget( Title::newFromText( $title, $ns ) ); - if ( $comment !== null ) { - $logEntry->setComment( $comment ); - } - if ( $parameters !== null ) { - $logEntry->setParameters( $parameters ); - } - - return $logEntry->insert(); - } - - function addDBData() { - $this->tablesUsed[] = 'logging'; - $this->tablesUsed[] = 'user'; - - try { - $user1 = User::newFromName( 'BackupDumperLogUserA' ); - $this->userId1 = $user1->getId(); - if ( $this->userId1 === 0 ) { - $user1->addToDatabase(); - $this->userId1 = $user1->getId(); - } - $this->assertGreaterThan( 0, $this->userId1 ); - - $user2 = User::newFromName( 'BackupDumperLogUserB' ); - $this->userId2 = $user2->getId(); - if ( $this->userId2 === 0 ) { - $user2->addToDatabase(); - $this->userId2 = $user2->getId(); - } - $this->assertGreaterThan( 0, $this->userId2 ); - - $this->logId1 = $this->addLogEntry( 'type', 'subtype', - $user1, NS_MAIN, "PageA" ); - $this->assertGreaterThan( 0, $this->logId1 ); - - $this->logId2 = $this->addLogEntry( 'supress', 'delete', - $user2, NS_TALK, "PageB", "SomeComment" ); - $this->assertGreaterThan( 0, $this->logId2 ); - - $this->logId3 = $this->addLogEntry( 'move', 'delete', - $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; - } - } - - - /** - * asserts that the xml reader is at the beginning of a log entry and skips over - * it while analyzing it. - * - * @param $id int: id of the log entry - * @param $user_name string: user name of the log entry's performer - * @param $user_id int: user id of the log entry 's performer - * @param $comment string|null: comment of the log entry. If null, the comment - * text is ignored. - * @param $type string: type of the log entry - * @param $subtype string: subtype of the log entry - * @param $title string: title of the log entry's target - * @param $parameters array: (optional) unserialized data accompanying the log entry - */ - private function assertLogItem( $id, $user_name, $user_id, $comment, $type, - $subtype, $title, $parameters = array() - ) { - - $this->assertNodeStart( "logitem" ); - $this->skipWhitespace(); - - $this->assertTextNode( "id", $id ); - $this->assertTextNode( "timestamp", false ); - - $this->assertNodeStart( "contributor" ); - $this->skipWhitespace(); - $this->assertTextNode( "username", $user_name ); - $this->assertTextNode( "id", $user_id ); - $this->assertNodeEnd( "contributor" ); - $this->skipWhitespace(); - - if ( $comment !== null ) { - $this->assertTextNode( "comment", $comment ); - } - $this->assertTextNode( "type", $type ); - $this->assertTextNode( "action", $subtype ); - $this->assertTextNode( "logtitle", $title ); - - $this->assertNodeStart( "params" ); - $parameters_xml = unserialize( $this->xml->value ); - $this->assertEquals( $parameters, $parameters_xml ); - $this->assertTrue( $this->xml->read(), "Skipping past processed text of params" ); - $this->assertNodeEnd( "params" ); - $this->skipWhitespace(); - - $this->assertNodeEnd( "logitem" ); - $this->skipWhitespace(); - } - - function testPlain() { - global $wgContLang; - - // Preparing the dump - $fname = $this->getNewTempFile(); - $dumper = new BackupDumper( array( "--output=file:" . $fname ) ); - $dumper->startId = $this->logId1; - $dumper->endId = $this->logId3 + 1; - $dumper->reporting = false; - $dumper->setDb( $this->db ); - - // Performing the dump - $dumper->dump( WikiExporter::LOGS, WikiExporter::TEXT ); - - // Analyzing the dumped data - $this->assertDumpStart( $fname ); - - $this->assertLogItem( $this->logId1, "BackupDumperLogUserA", - $this->userId1, null, "type", "subtype", "PageA" ); - - $this->assertNotNull( $wgContLang, "Content language object validation" ); - $namespace = $wgContLang->getNsText( NS_TALK ); - $this->assertInternalType( 'string', $namespace ); - $this->assertGreaterThan( 0, strlen( $namespace ) ); - $this->assertLogItem( $this->logId2, "BackupDumperLogUserB", - $this->userId2, "SomeComment", "supress", "delete", - $namespace . ":PageB" ); - - $this->assertLogItem( $this->logId3, "BackupDumperLogUserB", - $this->userId2, "SomeOtherComment", "move", "delete", - "PageA", array( 'key1' => 1, 3 => 'value3' ) ); - - $this->assertDumpEnd(); - } - - function testXmlDumpsBackupUseCaseLogging() { - global $wgContLang; - - $this->checkHasGzip(); - - // Preparing the dump - $fname = $this->getNewTempFile(); - $dumper = new BackupDumper( array( "--output=gzip:" . $fname, - "--reporting=2" ) ); - $dumper->startId = $this->logId1; - $dumper->endId = $this->logId3 + 1; - $dumper->setDb( $this->db ); - - // xmldumps-backup demands reporting, although this is currently not - // implemented in BackupDumper, when dumping logging data. We - // nevertheless capture the output of the dump process already now, - // to be able to alert (once dumping produces reports) that this test - // needs updates. - $dumper->stderr = fopen( 'php://output', 'a' ); - if ( $dumper->stderr === false ) { - $this->fail( "Could not open stream for stderr" ); - } - - // Performing the dump - $dumper->dump( WikiExporter::LOGS, WikiExporter::TEXT ); - - $this->assertTrue( fclose( $dumper->stderr ), "Closing stderr handle" ); - - // Analyzing the dumped data - $this->gunzip( $fname ); - - $this->assertDumpStart( $fname ); - - $this->assertLogItem( $this->logId1, "BackupDumperLogUserA", - $this->userId1, null, "type", "subtype", "PageA" ); - - $this->assertNotNull( $wgContLang, "Content language object validation" ); - $namespace = $wgContLang->getNsText( NS_TALK ); - $this->assertInternalType( 'string', $namespace ); - $this->assertGreaterThan( 0, strlen( $namespace ) ); - $this->assertLogItem( $this->logId2, "BackupDumperLogUserB", - $this->userId2, "SomeComment", "supress", "delete", - $namespace . ":PageB" ); - - $this->assertLogItem( $this->logId3, "BackupDumperLogUserB", - $this->userId2, "SomeOtherComment", "move", "delete", - "PageA", array( 'key1' => 1, 3 => 'value3' ) ); - - $this->assertDumpEnd(); - - // Currently, no reporting is implemented. Alert via failure, once - // this changes. - // If reporting for log dumps has been implemented, please update - // 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 deleted file mode 100644 index 99bd2700..00000000 --- a/tests/phpunit/maintenance/backup_PageTest.php +++ /dev/null @@ -1,404 +0,0 @@ -<?php -/** - * Tests for page dumps of BackupDumper - * - * @group Database - * @group Dump - */ -class BackupDumperPageTest extends DumpTestCase { - - // We'll add several pages, revision and texts. The following variables hold the - // corresponding ids. - private $pageId1, $pageId2, $pageId3, $pageId4, $pageId5; - private $pageTitle1, $pageTitle2, $pageTitle3, $pageTitle4, $pageTitle5; - private $revId1_1, $textId1_1; - private $revId2_1, $textId2_1, $revId2_2, $textId2_2; - private $revId2_3, $textId2_3, $revId2_4, $textId2_4; - private $revId3_1, $textId3_1, $revId3_2, $textId3_2; - private $revId4_1, $textId4_1; - private $namespace, $talk_namespace; - - function addDBData() { - // be sure, titles created here using english namespace names - $this->setMwGlobals( array( - 'wgLanguageCode' => 'en', - 'wgContLang' => Language::factory( 'en' ), - ) ); - - $this->tablesUsed[] = 'page'; - $this->tablesUsed[] = 'revision'; - $this->tablesUsed[] = 'text'; - - try { - $this->namespace = $this->getDefaultWikitextNS(); - $this->talk_namespace = NS_TALK; - - if ( $this->namespace === $this->talk_namespace ) { - // @todo work around this. - throw new MWException( "The default wikitext namespace is the talk namespace. " - . " We can't currently deal with that." ); - } - - $this->pageTitle1 = Title::newFromText( 'BackupDumperTestP1', $this->namespace ); - $page = WikiPage::factory( $this->pageTitle1 ); - list( $this->revId1_1, $this->textId1_1 ) = $this->addRevision( $page, - "BackupDumperTestP1Text1", "BackupDumperTestP1Summary1" ); - $this->pageId1 = $page->getId(); - - $this->pageTitle2 = Title::newFromText( 'BackupDumperTestP2', $this->namespace ); - $page = WikiPage::factory( $this->pageTitle2 ); - list( $this->revId2_1, $this->textId2_1 ) = $this->addRevision( $page, - "BackupDumperTestP2Text1", "BackupDumperTestP2Summary1" ); - list( $this->revId2_2, $this->textId2_2 ) = $this->addRevision( $page, - "BackupDumperTestP2Text2", "BackupDumperTestP2Summary2" ); - list( $this->revId2_3, $this->textId2_3 ) = $this->addRevision( $page, - "BackupDumperTestP2Text3", "BackupDumperTestP2Summary3" ); - list( $this->revId2_4, $this->textId2_4 ) = $this->addRevision( $page, - "BackupDumperTestP2Text4 some additional Text ", - "BackupDumperTestP2Summary4 extra " ); - $this->pageId2 = $page->getId(); - - $this->pageTitle3 = Title::newFromText( 'BackupDumperTestP3', $this->namespace ); - $page = WikiPage::factory( $this->pageTitle3 ); - list( $this->revId3_1, $this->textId3_1 ) = $this->addRevision( $page, - "BackupDumperTestP3Text1", "BackupDumperTestP2Summary1" ); - list( $this->revId3_2, $this->textId3_2 ) = $this->addRevision( $page, - "BackupDumperTestP3Text2", "BackupDumperTestP2Summary2" ); - $this->pageId3 = $page->getId(); - $page->doDeleteArticle( "Testing ;)" ); - - $this->pageTitle4 = Title::newFromText( 'BackupDumperTestP1', $this->talk_namespace ); - $page = WikiPage::factory( $this->pageTitle4 ); - list( $this->revId4_1, $this->textId4_1 ) = $this->addRevision( $page, - "Talk about BackupDumperTestP1 Text1", - "Talk BackupDumperTestP1 Summary1" ); - $this->pageId4 = $page->getId(); - } catch ( Exception $e ) { - // We'd love to pass $e directly. However, ... see - // documentation of exceptionFromAddDBData in - // DumpTestCase - $this->exceptionFromAddDBData = $e; - } - } - - protected function setUp() { - parent::setUp(); - - // Since we will restrict dumping by page ranges (to allow - // working tests, even if the db gets prepopulated by a base - // class), we have to assert, that the page id are consecutively - // increasing - $this->assertEquals( - array( $this->pageId2, $this->pageId3, $this->pageId4 ), - array( $this->pageId1 + 1, $this->pageId2 + 1, $this->pageId3 + 1 ), - "Page ids increasing without holes" ); - } - - function testFullTextPlain() { - // Preparing the dump - $fname = $this->getNewTempFile(); - $dumper = new BackupDumper( array( "--output=file:" . $fname ) ); - $dumper->startId = $this->pageId1; - $dumper->endId = $this->pageId4 + 1; - $dumper->reporting = false; - $dumper->setDb( $this->db ); - - // Performing the dump - $dumper->dump( WikiExporter::FULL, WikiExporter::TEXT ); - - // Checking the dumped data - $this->assertDumpStart( $fname ); - - // Page 1 - $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() ); - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87", - "BackupDumperTestP1Text1" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() ); - $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1", - $this->textId2_1, 23, "jprywrymfhysqllua29tj3sc7z39dl2", - "BackupDumperTestP2Text1" ); - $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2", - $this->textId2_2, 23, "b7vj5ks32po5m1z1t1br4o7scdwwy95", - "BackupDumperTestP2Text2", $this->revId2_1 ); - $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3", - $this->textId2_3, 23, "jfunqmh1ssfb8rs43r19w98k28gg56r", - "BackupDumperTestP2Text3", $this->revId2_2 ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", - "BackupDumperTestP2Text4 some additional Text", $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - $this->assertPageStart( $this->pageId4, $this->talk_namespace, $this->pageTitle4->getPrefixedText() ); - $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe", - "Talk about BackupDumperTestP1 Text1" ); - $this->assertPageEnd(); - - $this->assertDumpEnd(); - } - - function testFullStubPlain() { - // Preparing the dump - $fname = $this->getNewTempFile(); - $dumper = new BackupDumper( array( "--output=file:" . $fname ) ); - $dumper->startId = $this->pageId1; - $dumper->endId = $this->pageId4 + 1; - $dumper->reporting = false; - $dumper->setDb( $this->db ); - - // Performing the dump - $dumper->dump( WikiExporter::FULL, WikiExporter::STUB ); - - // Checking the dumped data - $this->assertDumpStart( $fname ); - - // Page 1 - $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() ); - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() ); - $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1", - $this->textId2_1, 23, "jprywrymfhysqllua29tj3sc7z39dl2" ); - $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2", - $this->textId2_2, 23, "b7vj5ks32po5m1z1t1br4o7scdwwy95", false, $this->revId2_1 ); - $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3", - $this->textId2_3, 23, "jfunqmh1ssfb8rs43r19w98k28gg56r", false, $this->revId2_2 ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - $this->assertPageStart( $this->pageId4, $this->talk_namespace, $this->pageTitle4->getPrefixedText() ); - $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" ); - $this->assertPageEnd(); - - $this->assertDumpEnd(); - } - - function testCurrentStubPlain() { - // Preparing the dump - $fname = $this->getNewTempFile(); - $dumper = new BackupDumper( array( "--output=file:" . $fname ) ); - $dumper->startId = $this->pageId1; - $dumper->endId = $this->pageId4 + 1; - $dumper->reporting = false; - $dumper->setDb( $this->db ); - - // Performing the dump - $dumper->dump( WikiExporter::CURRENT, WikiExporter::STUB ); - - // Checking the dumped data - $this->assertDumpStart( $fname ); - - // Page 1 - $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() ); - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - $this->assertPageStart( $this->pageId4, $this->talk_namespace, $this->pageTitle4->getPrefixedText() ); - $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" ); - $this->assertPageEnd(); - - $this->assertDumpEnd(); - } - - function testCurrentStubGzip() { - $this->checkHasGzip(); - - // Preparing the dump - $fname = $this->getNewTempFile(); - $dumper = new BackupDumper( array( "--output=gzip:" . $fname ) ); - $dumper->startId = $this->pageId1; - $dumper->endId = $this->pageId4 + 1; - $dumper->reporting = false; - $dumper->setDb( $this->db ); - - // Performing the dump - $dumper->dump( WikiExporter::CURRENT, WikiExporter::STUB ); - - // Checking the dumped data - $this->gunzip( $fname ); - $this->assertDumpStart( $fname ); - - // Page 1 - $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() ); - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - $this->assertPageStart( $this->pageId4, $this->talk_namespace, $this->pageTitle4->getPrefixedText() ); - $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" ); - $this->assertPageEnd(); - - $this->assertDumpEnd(); - } - - - function testXmlDumpsBackupUseCase() { - // xmldumps-backup typically performs a single dump that that writes - // out three files - // * gzipped stubs of everything (meta-history) - // * gzipped stubs of latest revisions of all pages (meta-current) - // * gzipped stubs of latest revisions of all pages of namespage 0 - // (articles) - // - // We reproduce such a setup with our mini fixture, although we omit - // chunks, and all the other gimmicks of xmldumps-backup. - // - $this->checkHasGzip(); - - $fnameMetaHistory = $this->getNewTempFile(); - $fnameMetaCurrent = $this->getNewTempFile(); - $fnameArticles = $this->getNewTempFile(); - - $dumper = new BackupDumper( array( "--output=gzip:" . $fnameMetaHistory, - "--output=gzip:" . $fnameMetaCurrent, "--filter=latest", - "--output=gzip:" . $fnameArticles, "--filter=latest", - "--filter=notalk", "--filter=namespace:!NS_USER", - "--reporting=1000" ) ); - $dumper->startId = $this->pageId1; - $dumper->endId = $this->pageId4 + 1; - $dumper->setDb( $this->db ); - - // xmldumps-backup uses reporting. We will not check the exact reported - // message, as they are dependent on the processing power of the used - // computer. We only check that reporting does not crash the dumping - // and that something is reported - $dumper->stderr = fopen( 'php://output', 'a' ); - if ( $dumper->stderr === false ) { - $this->fail( "Could not open stream for stderr" ); - } - - // Performing the dump - $dumper->dump( WikiExporter::FULL, WikiExporter::STUB ); - - $this->assertTrue( fclose( $dumper->stderr ), "Closing stderr handle" ); - - // Checking meta-history ------------------------------------------------- - - $this->gunzip( $fnameMetaHistory ); - $this->assertDumpStart( $fnameMetaHistory ); - - // Page 1 - $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() ); - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() ); - $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1", - $this->textId2_1, 23, "jprywrymfhysqllua29tj3sc7z39dl2" ); - $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2", - $this->textId2_2, 23, "b7vj5ks32po5m1z1t1br4o7scdwwy95", false, $this->revId2_1 ); - $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3", - $this->textId2_3, 23, "jfunqmh1ssfb8rs43r19w98k28gg56r", false, $this->revId2_2 ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - $this->assertPageStart( $this->pageId4, $this->talk_namespace, $this->pageTitle4->getPrefixedText() ); - $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" ); - $this->assertPageEnd(); - - $this->assertDumpEnd(); - - // Checking meta-current ------------------------------------------------- - - $this->gunzip( $fnameMetaCurrent ); - $this->assertDumpStart( $fnameMetaCurrent ); - - // Page 1 - $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() ); - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - $this->assertPageStart( $this->pageId4, $this->talk_namespace, $this->pageTitle4->getPrefixedText() ); - $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" ); - $this->assertPageEnd(); - - $this->assertDumpEnd(); - - // Checking articles ------------------------------------------------- - - $this->gunzip( $fnameArticles ); - $this->assertDumpStart( $fnameArticles ); - - // Page 1 - $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() ); - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - // -> Page is not in $this->namespace. Hence not visible - - $this->assertDumpEnd(); - - $this->expectETAOutput(); - } -} diff --git a/tests/phpunit/maintenance/fetchTextTest.php b/tests/phpunit/maintenance/fetchTextTest.php deleted file mode 100644 index e8df199e..00000000 --- a/tests/phpunit/maintenance/fetchTextTest.php +++ /dev/null @@ -1,238 +0,0 @@ -<?php - -require_once __DIR__ . "/../../../maintenance/fetchText.php"; - -/** - * Mock for the input/output of FetchText - * - * FetchText internally tries to access stdin and stdout. We mock those aspects - * for testing. - */ -class SemiMockedFetchText extends FetchText { - - /** - * @var String|null Text to pass as stdin - */ - private $mockStdinText = null; - - /** - * @var bool Whether or not a text for stdin has been provided - */ - private $mockSetUp = false; - - /** - * @var Array Invocation counters for the mocked aspects - */ - private $mockInvocations = array( 'getStdin' => 0 ); - - - /** - * Data for the fake stdin - * - * @param $stdin String The string to be used instead of stdin - */ - function mockStdin( $stdin ) { - $this->mockStdinText = $stdin; - $this->mockSetUp = true; - } - - /** - * Gets invocation counters for mocked methods. - * - * @return Array An array, whose keys are function names. The corresponding values - * denote the number of times the function has been invoked. - */ - function mockGetInvocations() { - return $this->mockInvocations; - } - - // ----------------------------------------------------------------- - // Mocked functions from FetchText follow. - - function getStdin( $len = null ) { - $this->mockInvocations['getStdin']++; - if ( $len !== null ) { - throw new PHPUnit_Framework_ExpectationFailedException( - "Tried to get stdin with non null parameter" ); - } - - if ( !$this->mockSetUp ) { - throw new PHPUnit_Framework_ExpectationFailedException( - "Tried to get stdin before setting up rerouting" ); - } - - return fopen( 'data://text/plain,' . $this->mockStdinText, 'r' ); - } -} - -/** - * TestCase for FetchText - * - * @group Database - * @group Dump - */ -class FetchTextTest extends MediaWikiTestCase { - - // We add 5 Revisions for this test. Their corresponding text id's - // are stored in the following 5 variables. - private $textId1; - private $textId2; - private $textId3; - private $textId4; - private $textId5; - - - /** - * @var Exception|null As the current MediaWikiTestCase::run is not - * robust enough to recover from thrown exceptions directly, we cannot - * throw frow within addDBData, although it would be appropriate. Hence, - * we catch the exception and store it until we are in setUp and may - * finally rethrow the exception without crashing the test suite. - */ - private $exceptionFromAddDBData; - - /** - * @var FetchText the (mocked) FetchText that is to test - */ - private $fetchText; - - /** - * Adds a revision to a page, while returning the resuting text's id - * - * @param $page WikiPage The page to add the revision to - * @param $text String The revisions text - * @param $text String The revisions summare - * - * @throws MWExcepion - */ - private function addRevision( $page, $text, $summary ) { - $status = $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), $summary ); - if ( $status->isGood() ) { - $value = $status->getValue(); - $revision = $value['revision']; - $id = $revision->getTextId(); - if ( $id > 0 ) { - return $id; - } - } - throw new MWException( "Could not determine text id" ); - } - - - function addDBData() { - $this->tablesUsed[] = 'page'; - $this->tablesUsed[] = 'revision'; - $this->tablesUsed[] = 'text'; - - $wikitextNamespace = $this->getDefaultWikitextNS(); - - try { - $title = Title::newFromText( 'FetchTextTestPage1', $wikitextNamespace ); - $page = WikiPage::factory( $title ); - $this->textId1 = $this->addRevision( $page, "FetchTextTestPage1Text1", "FetchTextTestPage1Summary1" ); - - $title = Title::newFromText( 'FetchTextTestPage2', $wikitextNamespace ); - $page = WikiPage::factory( $title ); - $this->textId2 = $this->addRevision( $page, "FetchTextTestPage2Text1", "FetchTextTestPage2Summary1" ); - $this->textId3 = $this->addRevision( $page, "FetchTextTestPage2Text2", "FetchTextTestPage2Summary2" ); - $this->textId4 = $this->addRevision( $page, "FetchTextTestPage2Text3", "FetchTextTestPage2Summary3" ); - $this->textId5 = $this->addRevision( $page, "FetchTextTestPage2Text4 some additional Text ", "FetchTextTestPage2Summary4 extra " ); - } catch ( Exception $e ) { - // We'd love to pass $e directly. However, ... see - // documentation of exceptionFromAddDBData - $this->exceptionFromAddDBData = $e; - } - } - - - protected function setUp() { - parent::setUp(); - - // Check if any Exception is stored for rethrowing from addDBData - if ( $this->exceptionFromAddDBData !== null ) { - throw $this->exceptionFromAddDBData; - } - - $this->fetchText = new SemiMockedFetchText(); - } - - - /** - * Helper to relate FetchText's input and output - */ - private function assertFilter( $input, $expectedOutput ) { - $this->fetchText->mockStdin( $input ); - $this->fetchText->execute(); - $invocations = $this->fetchText->mockGetInvocations(); - $this->assertEquals( 1, $invocations['getStdin'], - "getStdin invocation counter" ); - $this->expectOutputString( $expectedOutput ); - } - - - // Instead of the following functions, a data provider would be great. - // However, as data providers are evaluated /before/ addDBData, a data - // provider would not know the required ids. - - function testExistingSimple() { - $this->assertFilter( $this->textId2, - $this->textId2 . "\n23\nFetchTextTestPage2Text1" ); - } - - function testExistingSimpleWithNewline() { - $this->assertFilter( $this->textId2 . "\n", - $this->textId2 . "\n23\nFetchTextTestPage2Text1" ); - } - - function testExistingSeveral() { - $this->assertFilter( "$this->textId1\n$this->textId5\n" - . "$this->textId3\n$this->textId3", - implode( "", array( - $this->textId1 . "\n23\nFetchTextTestPage1Text1", - $this->textId5 . "\n44\nFetchTextTestPage2Text4 " - . "some additional Text", - $this->textId3 . "\n23\nFetchTextTestPage2Text2", - $this->textId3 . "\n23\nFetchTextTestPage2Text2" - ) ) ); - } - - function testEmpty() { - $this->assertFilter( "", null ); - } - - function testNonExisting() { - $this->assertFilter( $this->textId5 + 10, ( $this->textId5 + 10 ) . "\n-1\n" ); - } - - function testNegativeInteger() { - $this->assertFilter( "-42", "-42\n-1\n" ); - } - - function testFloatingPointNumberExisting() { - // float -> int -> revision - $this->assertFilter( $this->textId3 + 0.14159, - $this->textId3 . "\n23\nFetchTextTestPage2Text2" ); - } - - function testFloatingPointNumberNonExisting() { - $this->assertFilter( $this->textId5 + 3.14159, - ( $this->textId5 + 3 ) . "\n-1\n" ); - } - - function testCharacters() { - $this->assertFilter( "abc", "0\n-1\n" ); - } - - function testMix() { - $this->assertFilter( "ab\n" . $this->textId4 . ".5cd\n\nefg\n" . $this->textId2 - . "\n" . $this->textId3, - implode( "", array( - "0\n-1\n", - $this->textId4 . "\n23\nFetchTextTestPage2Text3", - "0\n-1\n", - "0\n-1\n", - $this->textId2 . "\n23\nFetchTextTestPage2Text1", - $this->textId3 . "\n23\nFetchTextTestPage2Text2" - ) ) ); - } -} diff --git a/tests/phpunit/maintenance/getSlaveServerTest.php b/tests/phpunit/maintenance/getSlaveServerTest.php deleted file mode 100644 index 2c848862..00000000 --- a/tests/phpunit/maintenance/getSlaveServerTest.php +++ /dev/null @@ -1,67 +0,0 @@ -<?php - -require_once __DIR__ . "/../../../maintenance/getSlaveServer.php"; - -/** - * Tests for getSlaveServer - * - * @group Database - */ -class GetSlaveServerTest extends MediaWikiTestCase { - - /** - * Yields a regular expression that matches a good DB server name - * - * It matches IPs or hostnames, both optionally followed by a - * port specification - * - * @return String the regular expression - */ - private function getServerRE() { - if ( $this->db->getType() === 'sqlite' ) { - // for SQLite, only the empty string is a good server name - return ''; - } - - $octet = '([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])'; - $ip = "(($octet\.){3}$octet)"; - - $label = '([a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)'; - $hostname = "($label(\.$label)*)"; - - return "($ip|$hostname)(:[0-9]{1,5})?"; - } - - function testPlain() { - $gss = new GetSlaveServer(); - $gss->execute(); - - $this->expectOutputRegex( "/^" . self::getServerRE() . "\n$/D" ); - } - - function testXmlDumpsBackupUseCase() { - global $wgDBprefix; - - global $argv; - $argv = array( null, "--globals" ); - - $gss = new GetSlaveServer(); - $gss->loadParamsAndArgs(); - $gss->execute(); - $gss->globals(); - - // The main answer - $output = $this->getActualOutput(); - $firstLineEndPos = strpos( $output, "\n" ); - if ( $firstLineEndPos === false ) { - $this->fail( "Could not find end of first line of output" ); - } - $firstLine = substr( $output, 0, $firstLineEndPos ); - $this->assertRegExp( "/^" . self::getServerRE() . "$/D", - $firstLine, "DB Server" ); - - // xmldumps-backup relies on the wgDBprefix in the output. - $this->expectOutputRegex( "/^[[:space:]]*\[wgDBprefix\][[:space:]]*=> " - . $wgDBprefix . "$/m" ); - } -} diff --git a/tests/phpunit/mocks/filebackend/MockFSFile.php b/tests/phpunit/mocks/filebackend/MockFSFile.php deleted file mode 100644 index e0463281..00000000 --- a/tests/phpunit/mocks/filebackend/MockFSFile.php +++ /dev/null @@ -1,69 +0,0 @@ -<?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 deleted file mode 100644 index 49aefbd1..00000000 --- a/tests/phpunit/mocks/filebackend/MockFileBackend.php +++ /dev/null @@ -1,122 +0,0 @@ -<?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 deleted file mode 100644 index 742b41e4..00000000 --- a/tests/phpunit/mocks/media/MockBitmapHandler.php +++ /dev/null @@ -1,92 +0,0 @@ -<?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 deleted file mode 100644 index 1d65e521..00000000 --- a/tests/phpunit/phpunit.php +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env php -<?php -/** - * Bootstrapping for MediaWiki PHPUnit tests - * - * @file - */ - -/* Configuration */ - -// Set a flag which can be used to detect when other scripts have been entered through this entry point or not -define( 'MW_PHPUNIT_TEST', true ); - -// Start up MediaWiki in command-line mode -require_once dirname( dirname( __DIR__ ) ) . "/maintenance/Maintenance.php"; - -class PHPUnitMaintClass extends Maintenance { - - function __construct() { - parent::__construct(); - $this->addOption( 'with-phpunitdir', - 'Directory to include PHPUnit from, for example when using a git fetchout from upstream. Path will be prepended to PHP `include_path`.', - false, # not required - true # need arg - ); - } - - public function finalSetup() { - parent::finalSetup(); - - global $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType; - global $wgLanguageConverterCacheType, $wgUseDatabaseMessages; - global $wgLocaltimezone, $wgLocalisationCacheConf; - global $wgDevelopmentWarnings; - - // Inject test autoloader - require_once __DIR__ . '/../TestsAutoLoader.php'; - - // wfWarn should cause tests to fail - $wgDevelopmentWarnings = true; - - $wgMainCacheType = CACHE_NONE; - $wgMessageCacheType = CACHE_NONE; - $wgParserCacheType = CACHE_NONE; - $wgLanguageConverterCacheType = CACHE_NONE; - - $wgUseDatabaseMessages = false; # Set for future resets - - // Assume UTC for testing purposes - $wgLocaltimezone = 'UTC'; - - $wgLocalisationCacheConf['storeClass'] = 'LCStore_Null'; - - // Bug 44192 Do not attempt to send a real e-mail - Hooks::clear( 'AlternateUserMailer' ); - Hooks::register( - 'AlternateUserMailer', - function () { - return false; - } - ); - } - - public function execute() { - global $IP; - - # Make sure we have --configuration or PHPUnit might complain - if ( !in_array( '--configuration', $_SERVER['argv'] ) ) { - //Hack to eliminate the need to use the Makefile (which sucks ATM) - array_splice( $_SERVER['argv'], 1, 0, - array( '--configuration', $IP . '/tests/phpunit/suite.xml' ) ); - } - - # --with-phpunitdir let us override the default PHPUnit version - if ( $phpunitDir = $this->getOption( 'with-phpunitdir' ) ) { - # Sanity checks - if ( !is_dir( $phpunitDir ) ) { - $this->error( "--with-phpunitdir should be set to an existing directory", 1 ); - } - if ( !is_readable( $phpunitDir . "/PHPUnit/Runner/Version.php" ) ) { - $this->error( "No usable PHPUnit installation in $phpunitDir.\nAborting.\n", 1 ); - } - - # Now prepends provided PHPUnit directory - $this->output( "Will attempt loading PHPUnit from `$phpunitDir`\n" ); - set_include_path( $phpunitDir - . PATH_SEPARATOR . get_include_path() ); - - # Cleanup $args array so the option and its value do not - # pollute PHPUnit - $key = array_search( '--with-phpunitdir', $_SERVER['argv'] ); - unset( $_SERVER['argv'][$key] ); // the option - unset( $_SERVER['argv'][$key + 1] ); // its value - $_SERVER['argv'] = array_values( $_SERVER['argv'] ); - } - } - - public function getDbType() { - return Maintenance::DB_ADMIN; - } -} - -$maintClass = 'PHPUnitMaintClass'; -require RUN_MAINTENANCE_IF_MAIN; - -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" ); -} - -if ( !class_exists( 'PHPUnit_TextUI_Command' ) ) { - require_once 'PHPUnit/Autoload.php'; -} -MediaWikiPHPUnitCommand::main(); diff --git a/tests/phpunit/run-tests.bat b/tests/phpunit/run-tests.bat deleted file mode 100644 index e6eb3e0c..00000000 --- a/tests/phpunit/run-tests.bat +++ /dev/null @@ -1 +0,0 @@ -php phpunit.php --configuration suite.xml %* diff --git a/tests/phpunit/skins/SideBarTest.php b/tests/phpunit/skins/SideBarTest.php deleted file mode 100644 index 9cb630fb..00000000 --- a/tests/phpunit/skins/SideBarTest.php +++ /dev/null @@ -1,223 +0,0 @@ -<?php - -/** - * @group Skin - */ -class SideBarTest extends MediaWikiLangTestCase { - - /** - * A skin template, reinitialized before each test - * @var SkinTemplate - */ - private $skin; - /** Local cache for sidebar messages */ - private $messages; - - /** Build $this->messages array */ - private function initMessagesHref() { - # List of default messages for the sidebar. The sidebar doesn't care at - # all whether they are full URLs, interwiki links or local titles. - $URL_messages = array( - 'mainpage', - 'portal-url', - 'currentevents-url', - 'recentchanges-url', - 'randompage-url', - 'helppage', - ); - - # We're assuming that isValidURI works as advertised: it's also - # tested separately, in tests/phpunit/includes/HttpTest.php. - foreach ( $URL_messages as $m ) { - $titleName = MessageCache::singleton()->get( $m ); - if ( Http::isValidURI( $titleName ) ) { - $this->messages[$m]['href'] = $titleName; - } else { - $title = Title::newFromText( $titleName ); - $this->messages[$m]['href'] = $title->getLocalURL(); - } - } - } - - protected function setUp() { - parent::setUp(); - $this->initMessagesHref(); - $this->skin = new SkinTemplate(); - $this->skin->getContext()->setLanguage( Language::factory( 'en' ) ); - } - - /** - * 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(); - $this->skin->addToSidebarPlain( $bar, $text ); - $this->assertEquals( $expected, $bar, $message ); - } - - /** - * @covers SkinTemplate::addToSidebarPlain - */ - public function testSidebarWithOnlyTwoTitles() { - $this->assertSideBar( - array( - 'Title1' => array(), - 'Title2' => array(), - ), - '* Title1 -* Title2 -' - ); - } - - /** - * @covers SkinTemplate::addToSidebarPlain - */ - public function testExpandMessages() { - $this->setMwGlobals( array( - 'wgNoFollowDomainExceptions' => array( 'mediawiki.org' ), - ) ); - $this->assertSidebar( - array( 'Title' => array( - array( - 'text' => 'Help', - 'href' => $this->messages['helppage']['href'], - 'id' => 'n-help', - 'active' => null - ) - ) ), - '* Title -** helppage|help -' - ); - } - - /** - * @covers SkinTemplate::addToSidebarPlain - */ - public function testExternalUrlsRequireADescription() { - $this->setMwGlobals( array( - 'wgNoFollowLinks' => true, - 'wgNoFollowDomainExceptions' => array(), - 'wgNoFollowNsExceptions' => array(), - ) ); - $this->assertSidebar( - array( 'Title' => array( - # ** http://www.mediawiki.org/| Home - array( - 'text' => 'Home', - 'href' => 'http://www.mediawiki.org/', - 'id' => 'n-Home', - 'active' => null, - 'rel' => 'nofollow', - ), - # ** http://valid.no.desc.org/ - # ... skipped since it is missing a pipe with a description - ) ), - '* Title -** http://www.mediawiki.org/| Home -** http://valid.no.desc.org/ -' - ); - } - - /** - * bug 33321 - Make sure there's a | after transforming. - * @group Database - * @covers SkinTemplate::addToSidebarPlain - */ - public function testTrickyPipe() { - $this->assertSidebar( - array( 'Title' => array( - # The first 2 are skipped - # Doesn't really test the url properly - # because it will vary with $wgArticlePath et al. - # ** Baz|Fred - array( - 'text' => 'Fred', - 'href' => Title::newFromText( 'Baz' )->getLocalURL(), - 'id' => 'n-Fred', - 'active' => null, - ), - array( - 'text' => 'title-to-display', - 'href' => Title::newFromText( 'page-to-go-to' )->getLocalURL(), - 'id' => 'n-title-to-display', - 'active' => null, - ), - ) ), - '* Title -** {{PAGENAME|Foo}} -** Bar -** Baz|Fred -** {{PLURAL:1|page-to-go-to{{int:pipe-separator/en}}title-to-display|branch not taken}} -' - ); - } - - - #### Attributes for external links ########################## - private function getAttribs() { - # Sidebar text we will use everytime - $text = '* Title -** http://www.mediawiki.org/| Home'; - - $bar = array(); - $this->skin->addToSideBarPlain( $bar, $text ); - - return $bar['Title'][0]; - } - - /** - * Simple test to verify our helper assertAttribs() is functional - */ - public function testTestAttributesAssertionHelper() { - $this->setMwGlobals( array( - 'wgNoFollowLinks' => true, - 'wgNoFollowDomainExceptions' => array(), - 'wgNoFollowNsExceptions' => array(), - 'wgExternalLinkTarget' => false, - ) ); - $attribs = $this->getAttribs(); - - $this->assertArrayHasKey( 'rel', $attribs ); - $this->assertEquals( 'nofollow', $attribs['rel'] ); - - $this->assertArrayNotHasKey( 'target', $attribs ); - } - - /** - * Test $wgNoFollowLinks in sidebar - */ - 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' - ); - } - - /** - * Test $wgExternaLinkTarget in sidebar - * @dataProvider dataRespectExternallinktarget - */ - public function testRespectExternallinktarget( $externalLinkTarget ) { - $this->setMwGlobals( 'wgExternalLinkTarget', $externalLinkTarget ); - - $attribs = $this->getAttribs(); - $this->assertArrayHasKey( 'target', $attribs ); - $this->assertEquals( $attribs['target'], $externalLinkTarget ); - } - - public static function dataRespectExternallinktarget() { - return array( - array( '_blank' ), - array( '_self' ), - ); - } -} diff --git a/tests/phpunit/structure/AutoLoaderTest.php b/tests/phpunit/structure/AutoLoaderTest.php deleted file mode 100644 index 205ea360..00000000 --- a/tests/phpunit/structure/AutoLoaderTest.php +++ /dev/null @@ -1,56 +0,0 @@ -<?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(); - - $this->assertEquals( - $results['expected'], - $results['actual'] - ); - } - - protected static function checkAutoLoadConf() { - global $wgAutoloadLocalClasses, $wgAutoloadClasses, $IP; - $supportsParsekit = function_exists( 'parsekit_compile_file' ); - - // wgAutoloadLocalClasses has precedence, just like in includes/AutoLoader.php - $expected = $wgAutoloadLocalClasses + $wgAutoloadClasses; - $actual = array(); - - $files = array_unique( $expected ); - - foreach ( $files as $file ) { - // Only prefix $IP if it doesn't have it already. - // Generally local classes don't have it, and those from extensions and test suites do. - if ( substr( $file, 0, 1 ) != '/' && substr( $file, 1, 1 ) != ':' ) { - $filePath = "$IP/$file"; - } else { - $filePath = $file; - } - if ( $supportsParsekit ) { - $parseInfo = parsekit_compile_file( "$filePath" ); - $classes = array_keys( $parseInfo['class_table'] ); - } else { - $contents = file_get_contents( "$filePath" ); - $m = array(); - preg_match_all( '/\n\s*(?:final)?\s*(?:abstract)?\s*(?:class|interface)\s+([a-zA-Z0-9_]+)/', $contents, $m, PREG_PATTERN_ORDER ); - $classes = $m[1]; - } - foreach ( $classes as $class ) { - $actual[$class] = $file; - } - } - - return array( - 'expected' => $expected, - 'actual' => $actual, - ); - } -} diff --git a/tests/phpunit/structure/ResourcesTest.php b/tests/phpunit/structure/ResourcesTest.php deleted file mode 100644 index fe823fa4..00000000 --- a/tests/phpunit/structure/ResourcesTest.php +++ /dev/null @@ -1,131 +0,0 @@ -<?php -/** - * Sanity checks for making sure registered resources are sane. - * - * @file - * @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 { - - /** - * @dataProvider provideResourceFiles - */ - public function testFileExistence( $filename, $module, $resource ) { - $this->assertFileExists( $filename, - "File '$resource' referenced by '$module' must exist." - ); - } - - /** - * This ask the ResouceLoader for all registered files from modules - * created by ResourceLoaderFileModule (or one of its descendants). - * - * - * Since the raw data is stored in protected properties, we have to - * overrride this through ReflectionObject methods. - */ - public static function provideResourceFiles() { - global $wgEnableJavaScriptTest; - - // Test existance of test suite files as well - // (can't use setUp or setMwGlobals because providers are static) - $live_wgEnableJavaScriptTest = $wgEnableJavaScriptTest; - $wgEnableJavaScriptTest = true; - - // Array with arguments for the test function - $cases = array(); - - // Initialize ResourceLoader - $rl = new ResourceLoader(); - - // See also ResourceLoaderFileModule::__construct - $filePathProps = array( - // Lists of file paths - 'lists' => array( - 'scripts', - 'debugScripts', - 'loaderScripts', - 'styles', - ), - - // Collated lists of file paths - 'nested-lists' => array( - 'languageScripts', - 'skinScripts', - 'skinStyles', - ), - ); - - foreach ( $rl->getModuleNames() as $moduleName ) { - $module = $rl->getModule( $moduleName ); - if ( !$module instanceof ResourceLoaderFileModule ) { - continue; - } - - $reflectedModule = new ReflectionObject( $module ); - - $files = array(); - - foreach ( $filePathProps['lists'] as $propName ) { - $property = $reflectedModule->getProperty( $propName ); - $property->setAccessible( true ); - $list = $property->getValue( $module ); - foreach ( $list as $key => $value ) { - // 'scripts' are numeral arrays. - // 'styles' can be numeral or associative. - // In case of associative the key is the file path - // and the value is the 'media' attribute. - if ( is_int( $key ) ) { - $files[] = $value; - } else { - $files[] = $key; - } - } - } - - foreach ( $filePathProps['nested-lists'] as $propName ) { - $property = $reflectedModule->getProperty( $propName ); - $property->setAccessible( true ); - $lists = $property->getValue( $module ); - foreach ( $lists as $list ) { - foreach ( $list as $key => $value ) { - // We need the same filter as for 'lists', - // due to 'skinStyles'. - if ( is_int( $key ) ) { - $files[] = $value; - } else { - $files[] = $key; - } - } - } - } - - // Get method for resolving the paths to full paths - $method = $reflectedModule->getMethod( 'getLocalPath' ); - $method->setAccessible( true ); - - // Populate cases - foreach ( $files as $file ) { - $cases[] = array( - $method->invoke( $module, $file ), - $module->getName(), - $file, - ); - } - } - - // Restore settings - $wgEnableJavaScriptTest = $live_wgEnableJavaScriptTest; - - return $cases; - } -} diff --git a/tests/phpunit/structure/StructureTest.php b/tests/phpunit/structure/StructureTest.php deleted file mode 100644 index df00d4df..00000000 --- a/tests/phpunit/structure/StructureTest.php +++ /dev/null @@ -1,63 +0,0 @@ -<?php -/** - * The tests here verify the structure of the code. This is for outright bugs, - * not just style issues. - */ - -class StructureTest extends MediaWikiTestCase { - /** - * Verify all files that appear to be tests have file names ending in - * Test. If the file names do not end in Test, they will not be run. - * @group medium - */ - public function testUnitTestFileNamesEndWithTest() { - if ( wfIsWindows() ) { - $this->markTestSkipped( 'This test does not work on Windows' ); - } - $rootPath = escapeshellarg( __DIR__ . '/..' ); - $testClassRegex = implode( '|', array( - 'ApiFormatTestBase', - 'ApiTestCase', - 'ApiQueryTestBase', - 'ApiQueryContinueTestBase', - 'MediaWikiLangTestCase', - 'MediaWikiTestCase', - 'PHPUnit_Framework_TestCase', - 'DumpTestCase', - ) ); - $testClassRegex = "^class .* extends ($testClassRegex)"; - $finder = "find $rootPath -name '*.php' '!' -name '*Test.php'" . - " | xargs grep -El '$testClassRegex|function suite\('"; - - $results = null; - $exitCode = null; - exec( $finder, $results, $exitCode ); - - $this->assertEquals( - 0, - $exitCode, - 'Verify find/grep command succeeds.' - ); - - $results = array_filter( - $results, - array( $this, 'filterSuites' ) - ); - $strip = strlen( $rootPath ) - 1; - foreach ( $results as $k => $v ) { - $results[$k] = substr( $v, $strip ); - } - $this->assertEquals( - array(), - $results, - "Unit test file in $rootPath must end with Test." - ); - } - - /** - * Filter to remove testUnitTestFileNamesEndWithTest false positives. - */ - public function filterSuites( $filename ) { - return strpos( $filename, __DIR__ . '/../suites/' ) !== 0; - } -} diff --git a/tests/phpunit/suite.xml b/tests/phpunit/suite.xml deleted file mode 100644 index 7a9122fa..00000000 --- a/tests/phpunit/suite.xml +++ /dev/null @@ -1,51 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- colors don't work on Windows! --> -<phpunit bootstrap="./bootstrap.php" - 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> - </testsuite> - <testsuite name="languages"> - <directory>languages</directory> - </testsuite> - <testsuite name="skins"> - <directory>skins</directory> - </testsuite> - <!-- As there is a class Maintenance, we cannot use the - name "maintenance" directly --> - <testsuite name="maintenance_suite"> - <directory>maintenance</directory> - </testsuite> - <testsuite name="structure"> - <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> - <exclude> - <group>Utility</group> - <group>Broken</group> - <group>ParserFuzz</group> - <group>Stub</group> - </exclude> - </groups> -</phpunit> diff --git a/tests/phpunit/suites/ExtensionsParserTestSuite.php b/tests/phpunit/suites/ExtensionsParserTestSuite.php deleted file mode 100644 index 3d68b241..00000000 --- a/tests/phpunit/suites/ExtensionsParserTestSuite.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -class ExtensionsParserTestSuite extends PHPUnit_Framework_TestSuite { - - public static function suite() { - return MediaWikiParserTest::suite( MediaWikiParserTest::NO_CORE ); - } - -} diff --git a/tests/phpunit/suites/ExtensionsTestSuite.php b/tests/phpunit/suites/ExtensionsTestSuite.php deleted file mode 100644 index eec773db..00000000 --- a/tests/phpunit/suites/ExtensionsTestSuite.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * This test suite runs unit tests registered by extensions. - * See http://www.mediawiki.org/wiki/Manual:Hooks/UnitTestsList for details of how to register your tests. - */ - -class ExtensionsTestSuite extends PHPUnit_Framework_TestSuite { - public function __construct() { - parent::__construct(); - $files = array(); - wfRunHooks( 'UnitTestsList', array( &$files ) ); - foreach ( $files as $file ) { - $this->addTestFile( $file ); - } - if ( !count( $files ) ) { - $this->addTest( new DummyExtensionsTest( 'testNothing' ) ); - } - } - - public static function suite() { - return new self; - } -} - -/** - * Needed to avoid warnings like 'No tests found in class "ExtensionsTestSuite".' - * when no extensions with tests are used. - */ -class DummyExtensionsTest extends MediaWikiTestCase { - public function testNothing() { - $this->assertTrue( true ); - } -} diff --git a/tests/phpunit/suites/UploadFromUrlTestSuite.php b/tests/phpunit/suites/UploadFromUrlTestSuite.php deleted file mode 100644 index 7eb599e3..00000000 --- a/tests/phpunit/suites/UploadFromUrlTestSuite.php +++ /dev/null @@ -1,207 +0,0 @@ -<?php - -require_once dirname( __DIR__ ) . '/includes/upload/UploadFromUrlTest.php'; - -class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite { - public $savedGlobals = array(); - - public static function addTables( &$tables ) { - $tables[] = 'user_properties'; - $tables[] = 'filearchive'; - $tables[] = 'logging'; - $tables[] = 'updatelog'; - $tables[] = 'iwlinks'; - - return true; - } - - protected function setUp() { - 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['wgStylePath'] = '/skins'; - $tmpGlobals['wgThumbnailScriptPath'] = false; - $tmpGlobals['wgLocalFileRepo'] = array( - 'class' => 'LocalRepo', - 'name' => 'local', - 'url' => 'http://example.com/images', - 'hashLevels' => 2, - 'transformVia404' => false, - 'backend' => new FSFileBackend( array( - 'name' => 'local-backend', - 'lockManager' => 'fsLockManager', - 'containerPaths' => array( - 'local-public' => wfTempDir() . '/test-repo/public', - 'local-thumb' => wfTempDir() . '/test-repo/thumb', - 'local-temp' => wfTempDir() . '/test-repo/temp', - 'local-deleted' => wfTempDir() . '/test-repo/delete', - ) - ) ), - ); - foreach ( $tmpGlobals as $var => $val ) { - if ( array_key_exists( $var, $GLOBALS ) ) { - $this->savedGlobals[$var] = $GLOBALS[$var]; - } - $GLOBALS[$var] = $val; - } - - $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; - $wgNamespaceAliases['Image'] = NS_FILE; - $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; - - $wgEnableParserCache = false; - DeferredUpdates::clearPendingUpdates(); - $wgMemc = wfGetMainCache(); - $messageMemc = wfGetMessageCacheStorage(); - $parserMemc = wfGetParserCacheStorage(); - - // $wgContLang = new StubContLang; - $wgUser = new User; - $context = new RequestContext; - $wgLang = $context->getLanguage(); - $wgOut = $context->getOutput(); - $wgParser = new StubObject( 'wgParser', $wgParserConf['class'], array( $wgParserConf ) ); - $wgRequest = $context->getRequest(); - - if ( $wgStyleDirectory === false ) { - $wgStyleDirectory = "$IP/skins"; - } - - RepoGroup::destroySingleton(); - FileBackendGroup::destroySingleton(); - } - - protected function tearDown() { - foreach ( $this->savedGlobals as $var => $val ) { - $GLOBALS[$var] = $val; - } - // Restore backends - RepoGroup::destroySingleton(); - FileBackendGroup::destroySingleton(); - - $this->teardownUploadDir( $this->uploadDir ); - - parent::tearDown(); - } - - private $uploadDir; - private $keepUploads; - - /** - * Remove the dummy uploads directory - */ - private function teardownUploadDir( $dir ) { - if ( $this->keepUploads ) { - return; - } - - // delete the files first, then the dirs. - self::deleteFiles( - array( - "$dir/3/3a/Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg", - - "$dir/0/09/Bad.jpg", - ) - ); - - self::deleteDirs( - array( - "$dir/3/3a", - "$dir/3", - "$dir/thumb/6/65", - "$dir/thumb/6", - "$dir/thumb/3/3a/Foobar.jpg", - "$dir/thumb/3/3a", - "$dir/thumb/3", - - "$dir/0/09/", - "$dir/0/", - - "$dir/thumb", - "$dir", - ) - ); - } - - /** - * Delete the specified files, if they exist. - * - * @param $files Array: full paths to files to delete. - */ - private static function deleteFiles( $files ) { - foreach ( $files as $file ) { - if ( file_exists( $file ) ) { - unlink( $file ); - } - } - } - - /** - * Delete the specified directories, if they exist. Must be empty. - * - * @param $dirs Array: full paths to directories to delete. - */ - private static function deleteDirs( $dirs ) { - foreach ( $dirs as $dir ) { - if ( is_dir( $dir ) ) { - rmdir( $dir ); - } - } - } - - /** - * Create a dummy uploads directory which will contain a couple - * of files in order to pass existence tests. - * - * @return String: the directory - */ - private function setupUploadDir() { - global $IP; - - if ( $this->keepUploads ) { - $dir = wfTempDir() . '/mwParser-images'; - - if ( is_dir( $dir ) ) { - return $dir; - } - } else { - $dir = wfTempDir() . "/mwParser-" . mt_rand() . "-images"; - } - - wfDebug( "Creating upload directory $dir\n" ); - - if ( file_exists( $dir ) ) { - wfDebug( "Already exists!\n" ); - - return $dir; - } - - wfMkdirParents( $dir . '/3/3a', null, __METHOD__ ); - copy( "$IP/skins/monobook/headbg.jpg", "$dir/3/3a/Foobar.jpg" ); - - wfMkdirParents( $dir . '/0/09', null, __METHOD__ ); - copy( "$IP/skins/monobook/headbg.jpg", "$dir/0/09/Bad.jpg" ); - - return $dir; - } - - public static function suite() { - // Hack to invoke the autoloader required to get phpunit to recognize - // the UploadFromUrlTest class - class_exists( 'UploadFromUrlTest' ); - $suite = new UploadFromUrlTestSuite( 'UploadFromUrlTest' ); - - return $suite; - } -} |