X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=tests%2Fphpunit%2FMediaWikiTestCase.php;h=3742a54618b1e0c1376dc7de909936968508fb3f;hb=928c8c401da84de2cf4593ad673c13151813a49e;hp=87e214cb9e03f90d0508428dbc1ee32e4133f1eb;hpb=68e8c6ca53c2c59d265d01a9583de85161fbfff8;p=lhc%2Fweb%2Fwiklou.git diff --git a/tests/phpunit/MediaWikiTestCase.php b/tests/phpunit/MediaWikiTestCase.php index 87e214cb9e..3742a54618 100644 --- a/tests/phpunit/MediaWikiTestCase.php +++ b/tests/phpunit/MediaWikiTestCase.php @@ -1,9 +1,9 @@ backupGlobals = false; $this->backupStaticAttributes = false; } - function run( PHPUnit_Framework_TestResult $result = null ) { + public 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. @@ -130,22 +141,29 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { } } - function usesTemporaryTables() { + /** + * @since 1.21 + * + * @return bool + */ + public function usesTemporaryTables() { return self::$useTemporaryTables; } /** - * obtains a new temporary file name + * Obtains a new temporary file name * * The obtained filename is enlisted to be removed upon tearDown * - * @return string: absolute name of the temporary file + * @since 1.20 + * + * @return string absolute name of the temporary file */ protected function getNewTempFile() { - $fname = tempnam( wfTempDir(), 'MW_PHPUnit_' . get_class( $this ) . '_' ); - $this->tmpfiles[] = $fname; + $fileName = tempnam( wfTempDir(), 'MW_PHPUnit_' . get_class( $this ) . '_' ); + $this->tmpFiles[] = $fileName; - return $fname; + return $fileName; } /** @@ -154,26 +172,24 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * The obtained directory is enlisted to be removed (recursively with all its contained * files) upon tearDown. * - * @return string: absolute name of the temporary directory + * @since 1.20 + * + * @return string Absolute name of the temporary directory */ protected function getNewTempDirectory() { // Starting of with a temporary /file/. - $fname = $this->getNewTempFile(); + $fileName = $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 ) ); + unlink( $fileName ); + $this->assertTrue( wfMkdirParents( $fileName ) ); - return $fname; + return $fileName; } - /** - * setUp and tearDown should (where significant) - * happen in reverse order. - */ protected function setUp() { wfProfileIn( __METHOD__ ); parent::setUp(); @@ -181,23 +197,12 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { $this->phpErrorLevel = intval( ini_get( 'error_reporting' ) ); - /* - // @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 ); + foreach ( $this->tmpFiles as $fileName ) { + if ( is_file( $fileName ) || ( is_link( $fileName ) ) ) { + unlink( $fileName ); + } elseif ( is_dir( $fileName ) ) { + wfRecursiveRemoveDir( $fileName ); } } @@ -218,11 +223,11 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { 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 ); + foreach ( $this->tmpFiles as $fileName ) { + if ( is_file( $fileName ) || ( is_link( $fileName ) ) ) { + unlink( $fileName ); + } elseif ( is_dir( $fileName ) ) { + wfRecursiveRemoveDir( $fileName ); } } @@ -269,13 +274,11 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { } /** - * 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). + * Sets a global, maintaining a stashed version of the previous global to be + * restored in tearDown + * + * The key is added to the array of globals that will be reset afterwards + * in the tearDown(). * * @example * @@ -299,24 +302,61 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * of key/value pairs. * @param mixed $value Value to set the global to (ignored * if an array is given as first argument). + * + * @since 1.21 */ protected function setMwGlobals( $pairs, $value = null ) { - - // Normalize (string, value) to an array if ( is_string( $pairs ) ) { $pairs = array( $pairs => $value ); } + $this->stashMwGlobals( array_keys( $pairs ) ); + foreach ( $pairs as $key => $value ) { + $GLOBALS[$key] = $value; + } + } + + /** + * Stashes the global, will be restored in tearDown() + * + * Individual test functions may override globals through the setMwGlobals() function + * or directly. When directly overriding globals their keys should first be passed to this + * method in setUp to avoid breaking global state for other tests + * + * 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). + * + * @param array|string $globalKeys Key to the global variable, or an array of keys. + * + * @throws Exception when trying to stash an unset global + * @since 1.23 + */ + protected function stashMwGlobals( $globalKeys ) { + if ( is_string( $globalKeys ) ) { + $globalKeys = array( $globalKeys ); + } + + foreach ( $globalKeys as $globalKey ) { // 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]; + if ( !array_key_exists( $globalKey, $this->mwGlobals ) ) { + if ( !array_key_exists( $globalKey, $GLOBALS ) ) { + throw new Exception( "Global with key {$globalKey} doesn't exist and cant be stashed" ); + } + // NOTE: we serialize then unserialize the value in case it is an object + // this stops any objects being passed by reference. We could use clone + // and if is_object but this does account for objects within objects! + try { + $this->mwGlobals[$globalKey] = unserialize( serialize( $GLOBALS[$globalKey] ) ); + } + // NOTE; some things such as Closures are not serializable + // in this case just set the value! + catch ( Exception $e ) { + $this->mwGlobals[$globalKey] = $GLOBALS[$globalKey]; + } } - - // Override the global - $GLOBALS[$key] = $value; } } @@ -325,10 +365,12 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * 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 + * @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. + * + * @since 1.21 */ protected function mergeMwGlobalArrayValue( $name, $values ) { if ( !isset( $GLOBALS[$name] ) ) { @@ -348,11 +390,19 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { $this->setMwGlobals( $name, $merged ); } - function dbPrefix() { + /** + * @return string + * @since 1.18 + */ + public function dbPrefix() { return $this->db->getType() == 'oracle' ? self::ORA_DB_PREFIX : self::DB_PREFIX; } - function needsDB() { + /** + * @return bool + * @since 1.18 + */ + public function needsDB() { # if the test says it uses database tables, it needs the database if ( $this->tablesUsed ) { return true; @@ -370,15 +420,13 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { /** * Stub. If a test needs to add additional data to the database, it should * implement this method and do so + * + * @since 1.18 */ - function addDBData() { + public 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 @@ -433,6 +481,8 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * 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). + * + * @since 1.21 */ public static function teardownTestDB() { if ( !self::$dbSetup ) { @@ -453,6 +503,8 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * 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. * + * @since 1.21 + * * @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. * @@ -467,7 +519,8 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { 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 . '"' ); + throw new MWException( + 'Cannot run unit tests, the database prefix is already "' . $prefix . '"' ); } if ( self::$dbSetup ) { @@ -522,17 +575,21 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { } } - function __call( $func, $args ) { + /** + * @since 1.18 + * + * @param string $func + * @param array $args + * + * @return mixed + * @throws MWException + */ + public function __call( $func, $args ) { static $compatibility = array( - 'assertInternalType' => 'assertType', - 'assertNotInternalType' => 'assertNotType', - 'assertInstanceOf' => 'assertType', - 'assertEmpty' => 'assertEmpty2', + 'assertEmpty' => 'assertEmpty2', // assertEmpty was added in phpunit 3.7.32 ); - if ( method_exists( $this->suite, $func ) ) { - return call_user_func_array( array( $this->suite, $func ), $args ); - } elseif ( isset( $compatibility[$func] ) ) { + if ( isset( $compatibility[$func] ) ) { return call_user_func_array( array( $this, $compatibility[$func] ), $args ); } else { throw new MWException( "Called non-existant $func method on " @@ -540,6 +597,9 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { } } + /** + * Used as a compatibility method for phpunit < 3.7.32 + */ private function assertEmpty2( $value, $msg ) { return $this->assertTrue( $value == '', $msg ); } @@ -554,6 +614,13 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { return strpos( $table, 'unittest_' ) !== 0; } + /** + * @since 1.18 + * + * @param DataBaseBase $db + * + * @return array + */ public static function listTables( $db ) { global $wgDBprefix; @@ -581,31 +648,41 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { return $tables; } + /** + * @throws MWException + * @since 1.18 + */ protected function checkDbIsSupported() { if ( !in_array( $this->db->getType(), $this->supportedDBs ) ) { throw new MWException( $this->db->getType() . " is not currently supported for unit testing." ); } } + /** + * @since 1.18 + */ public function getCliArg( $offset ) { - if ( isset( MediaWikiPHPUnitCommand::$additionalOptions[$offset] ) ) { return MediaWikiPHPUnitCommand::$additionalOptions[$offset]; } } + /** + * @since 1.18 + */ public function setCliArg( $offset, $value ) { - MediaWikiPHPUnitCommand::$additionalOptions[$offset] = $value; } /** * Don't throw a warning if $function is deprecated and called later * - * @param $function String + * @since 1.19 + * + * @param string $function * @return null */ - function hideDeprecated( $function ) { + public function hideDeprecated( $function ) { wfSuppressWarnings(); wfDeprecated( $function ); wfRestoreWarnings(); @@ -619,12 +696,12 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * * @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. + * @param string|array $table The table(s) to query + * @param string|array $fields The columns to include in the result (and to sort by) + * @param string|array $condition "where" condition(s) + * @param array $expectedRows An array of arrays giving the expected rows. * - * @throws MWException if this test cases's needsDB() method doesn't return true. + * @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. @@ -687,8 +764,8 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * * @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 + * @param bool $ordered If the order of the values should match + * @param bool $named If the keys should match */ protected function assertArrayEquals( array $expected, array $actual, $ordered = false, $named = false ) { if ( !$ordered ) { @@ -715,9 +792,9 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * * @since 1.20 * - * @param String $expected HTML on oneline - * @param String $actual HTML on oneline - * @param String $msg Optional message + * @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 ); @@ -749,7 +826,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * * @since 1.20 * - * @param $r mixed the array to remove string keys from. + * @param mixed $r The array to remove string keys from. */ protected static function stripStringKeys( &$r ) { if ( !is_array( $r ) ) { @@ -824,9 +901,9 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { /** * 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 + * @throws MWException If there is none. + * @return int The ID of the wikitext Namespace * @since 1.21 */ protected function getDefaultWikitextNS() { @@ -973,8 +1050,10 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * then calls assertValidHtmlDocument(). * The snippet is expected to be HTML 5. * - * @note: Will mark the test as skipped if the "tidy" module is not installed. - * @note: This ignores $wgUseTidy, so we can check for valid HTML even (and especially) + * @since 1.23 + * + * @note Will mark the test as skipped if the "tidy" module is not installed. + * @note This ignores $wgUseTidy, so we can check for valid HTML even (and especially) * when automatic tidying is disabled. * * @param string $html An HTML snippet (treated as the contents of the body tag). @@ -987,8 +1066,10 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { /** * Asserts that the given string is valid HTML document. * - * @note: Will mark the test as skipped if the "tidy" module is not installed. - * @note: This ignores $wgUseTidy, so we can check for valid HTML even (and especially) + * @since 1.23 + * + * @note Will mark the test as skipped if the "tidy" module is not installed. + * @note This ignores $wgUseTidy, so we can check for valid HTML even (and especially) * when automatic tidying is disabled. * * @param string $html A complete HTML document @@ -1017,4 +1098,5 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { $this->assertEmpty( $errors, implode( "\n", $errors ) ); } + }