Merge branch 'Wikidata' into master.
[lhc/web/wiklou.git] / tests / phpunit / MediaWikiTestCase.php
index 8d78e50..ff13702 100644 (file)
@@ -19,16 +19,6 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        protected $reuseDB = false;
        protected $tablesUsed = array(); // tables with data
 
-       protected $restoreGlobals = array( // global variables to restore for each test
-               'wgLang',
-               'wgContLang',
-               'wgLanguageCode',
-               'wgUser',
-               'wgTitle',
-       );
-
-       private $savedGlobals = array();
-
        private static $dbSetup = false;
 
        /**
@@ -39,6 +29,13 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
         */
        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.
@@ -129,21 +126,42 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                return $fname;
        }
 
-       protected function setup() {
-               parent::setup();
-
-               foreach ( $this->restoreGlobals as $var ) {
-                       $v = $GLOBALS[ $var ];
+       /**
+        * setUp and tearDown should (where significant)
+        * happen in reverse order.
+        */
+       protected function setUp() {
+               parent::setUp();
+
+               /*
+               //@todo: global variables to restore for *every* test
+               array(
+                       'wgLang',
+                       'wgContLang',
+                       'wgLanguageCode',
+                       'wgUser',
+                       'wgTitle',
+               );
+               */
 
-                       if ( is_object( $v ) ) {
-                               $v = clone $v;
+               // Cleaning up temporary files
+               foreach ( $this->tmpfiles as $fname ) {
+                       if ( is_file( $fname ) || ( is_link( $fname ) ) ) {
+                               unlink( $fname );
+                       } elseif ( is_dir( $fname ) ) {
+                               wfRecursiveRemoveDir( $fname );
                        }
+               }
 
-                       $this->savedGlobals[$var] = $v;
+               // Clean up open transactions
+               if ( $this->needsDB() && $this->db ) {
+                       while( $this->db->trxLevel() > 0 ) {
+                               $this->db->rollback();
+                       }
                }
        }
 
-       protected function teardown() {
+       protected function tearDown() {
                // Cleaning up temporary files
                foreach ( $this->tmpfiles as $fname ) {
                        if ( is_file( $fname ) || ( is_link( $fname ) ) ) {
@@ -153,19 +171,93 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                        }
                }
 
-               // clean up open transactions
-               if( $this->needsDB() && $this->db ) {
+               // Clean up open transactions
+               if ( $this->needsDB() && $this->db ) {
                        while( $this->db->trxLevel() > 0 ) {
                                $this->db->rollback();
                        }
                }
 
-               // restore saved globals
-               foreach ( $this->savedGlobals as $k => $v ) {
-                       $GLOBALS[ $k ] = $v;
+               // Restore mw globals
+               foreach ( $this->mwGlobals as $key => $value ) {
+                       $GLOBALS[$key] = $value;
+               }
+               $this->mwGlobals = array();
+
+               parent::tearDown();
+       }
+
+       /**
+        * 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 ) {
+               if ( !is_array( $pairs ) ) {
+                       $key = $pairs;
+                       $this->mwGlobals[$key] = $GLOBALS[$key];
+                       $GLOBALS[$key] = $value;
+               } else {
+                       foreach ( $pairs as $key => $value ) {
+                               $this->mwGlobals[$key] = $GLOBALS[$key];
+                               $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;
+                       }
                }
 
-               parent::teardown();
+               $this->setMwGlobals( $name, $merged );
        }
 
        function dbPrefix() {