Merge "Fix reset interwiki table between tests"
[lhc/web/wiklou.git] / tests / phpunit / MediaWikiTestCase.php
index ebca9df..310ba29 100644 (file)
@@ -97,6 +97,12 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
         */
        private $mwGlobalsToUnset = [];
 
+       /**
+        * Holds original contents of interwiki table
+        * @var IResultWrapper
+        */
+       private $interwikiTable = null;
+
        /**
         * Holds original loggers which have been replaced by setLogger()
         * @var LoggerInterface[]
@@ -269,7 +275,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
         *        MediaWikiServices.
         * @return MediaWikiServices
         */
-       protected static function resetGlobalServices( Config $bootstrapConfig = null ) {
+       private static function resetGlobalServices( Config $bootstrapConfig = null ) {
                $oldServices = MediaWikiServices::getInstance();
                $oldConfigFactory = $oldServices->getConfigFactory();
                $oldLoadBalancerFactory = $oldServices->getDBLoadBalancerFactory();
@@ -563,6 +569,12 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                        }
                }
 
+               // Store contents of interwiki table in case it changes.  Unfortunately, we seem to have no
+               // way to do this only when needed, because tablesUsed can be changed mid-test.
+               if ( $this->db ) {
+                       $this->interwikiTable = $this->db->select( 'interwiki', '*', '', __METHOD__ );
+               }
+
                // Reset all caches between tests.
                $this->doLightweightServiceReset();
 
@@ -616,6 +628,12 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                foreach ( $this->mwGlobalsToUnset as $value ) {
                        unset( $GLOBALS[$value] );
                }
+               if (
+                       array_key_exists( 'wgExtraNamespaces', $this->mwGlobals ) ||
+                       in_array( 'wgExtraNamespaces', $this->mwGlobalsToUnset )
+               ) {
+                       $this->resetNamespaces();
+               }
                $this->mwGlobals = [];
                $this->mwGlobalsToUnset = [];
                $this->restoreLoggers();
@@ -751,6 +769,26 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                foreach ( $pairs as $key => $value ) {
                        $GLOBALS[$key] = $value;
                }
+
+               if ( array_key_exists( 'wgExtraNamespaces', $pairs ) ) {
+                       $this->resetNamespaces();
+               }
+       }
+
+       /**
+        * Must be called whenever namespaces are changed, e.g., $wgExtraNamespaces is altered.
+        * Otherwise old namespace data will lurk and cause bugs.
+        */
+       private function resetNamespaces() {
+               MWNamespace::clearCaches();
+               Language::clearCaches();
+
+               // We can't have the TitleFormatter holding on to an old Language object either
+               // @todo We shouldn't need to reset all the aliases here.
+               $services = MediaWikiServices::getInstance();
+               $services->resetServiceForTesting( 'TitleFormatter' );
+               $services->resetServiceForTesting( 'TitleParser' );
+               $services->resetServiceForTesting( '_MediaWikiTitleCodec' );
        }
 
        /**
@@ -1723,11 +1761,6 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
 
                        $truncate = in_array( $db->getType(), [ 'oracle', 'mysql' ] );
                        foreach ( $tablesUsed as $tbl ) {
-                               // TODO: reset interwiki table to its original content.
-                               if ( $tbl == 'interwiki' ) {
-                                       continue;
-                               }
-
                                if ( !$db->tableExists( $tbl ) ) {
                                        continue;
                                }
@@ -1743,6 +1776,19 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                                        $db->resetSequenceForTable( $tbl, __METHOD__ );
                                }
 
+                               if ( $tbl === 'interwiki' ) {
+                                       if ( !$this->interwikiTable ) {
+                                               // @todo We should probably throw here, but this causes test failures that I
+                                               // can't figure out, so for now we silently continue.
+                                               continue;
+                                       }
+                                       $db->insert(
+                                               'interwiki',
+                                               array_values( array_map( 'get_object_vars', iterator_to_array( $this->interwikiTable ) ) ),
+                                               __METHOD__
+                                       );
+                               }
+
                                if ( $tbl === 'page' ) {
                                        // Forget about the pages since they don't
                                        // exist in the DB.
@@ -2186,6 +2232,18 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                return $loaded;
        }
 
+       /**
+        * Skip the test if using the specified database type
+        *
+        * @param string $type Database type
+        * @since 1.32
+        */
+       protected function markTestSkippedIfDbType( $type ) {
+               if ( $this->db->getType() === $type ) {
+                       $this->markTestSkipped( "The $type database type isn't supported for this test" );
+               }
+       }
+
        /**
         * Used as a marker to prevent wfResetOutputBuffers from breaking PHPUnit.
         * @param string $buffer