Merge "Exclude redirects from Special:Fewestrevisions"
[lhc/web/wiklou.git] / tests / phpunit / bootstrap.php
index 79cb5be..4400475 100644 (file)
@@ -1,34 +1,95 @@
 <?php
+
 /**
- * Bootstrapping for MediaWiki PHPUnit tests
- * This file is included by phpunit and is NOT in the global scope.
+ * PHPUnit bootstrap 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 Testing
  */
 
-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";
+if ( PHP_SAPI !== 'cli' ) {
+       die( 'This file is only meant to be executed indirectly by PHPUnit\'s bootstrap process!' );
 }
 
-// The PHPUnit_TextUI_TestRunner class will run each test suite and may call
-// exit() with an exit status code. As such, we cannot run code "after the last test"
-// by adding statements to PHPUnitMaintClass::execute or MediaWikiPHPUnitCommand::run.
-// Instead, we work around it by registering a shutdown callback from the bootstrap
-// file, which runs before PHPUnit starts.
-// @todo Once we use PHPUnit 8 or higher, use the 'AfterLastTestHook' feature.
-// https://phpunit.readthedocs.io/en/8.0/extending-phpunit.html#available-hook-interfaces
-register_shutdown_function( function () {
-       // This will:
-       // - clear the temporary job queue.
-       // - allow extensions to delete any temporary tables they created.
-       // - restore ability to connect to the real database,
-       //   (for logging profiling data).
-       MediaWikiTestCase::teardownTestDB();
-
-       // Log profiling data, e.g. in the database or UDP
-       wfLogProfilingData();
-} );
+/**
+ * PHPUnit includes the bootstrap file inside a method body, while most MediaWiki startup files
+ * assume to be included in the global scope.
+ * This utility provides a way to include these files: it makes all globals available in the
+ * inclusion scope before including the file, then exports all new or changed globals.
+ *
+ * @param string $fileName the file to include
+ */
+function wfRequireOnceInGlobalScope( $fileName ) {
+       // phpcs:disable MediaWiki.Usage.ForbiddenFunctions.extract
+       extract( $GLOBALS, EXTR_REFS | EXTR_SKIP );
+       // phpcs:enable
+
+       require_once $fileName;
+
+       foreach ( get_defined_vars() as $varName => $value ) {
+               $GLOBALS[$varName] = $value;
+       }
+}
+
+define( 'MEDIAWIKI', true );
+define( 'MW_PHPUNIT_TEST', true );
+
+// We don't use a settings file here but some code still assumes that one exists
+define( 'MW_CONFIG_FILE', 'LocalSettings.php' );
+
+$IP = realpath( __DIR__ . '/../../' );
+
+// these variables must be defined before setup runs
+$GLOBALS['IP'] = $IP;
+// Set bootstrap globals to reuse in MediaWikiUnitTestCase
+$bootstrapGlobals = [];
+foreach ( $GLOBALS as $key => $value ) {
+       $bootstrapGlobals[ $key ] = $value;
+}
+$GLOBALS['wgPhpUnitBootstrapGlobals'] = $bootstrapGlobals;
+// Faking for Setup.php
+$GLOBALS['wgScopeTest'] = 'MediaWiki Setup.php scope test';
+$GLOBALS['wgCommandLineMode'] = true;
+$GLOBALS['wgAutoloadClasses'] = [];
+
+require_once "$IP/tests/common/TestSetup.php";
+
+wfRequireOnceInGlobalScope( "$IP/includes/AutoLoader.php" );
+wfRequireOnceInGlobalScope( "$IP/tests/common/TestsAutoLoader.php" );
+wfRequireOnceInGlobalScope( "$IP/includes/Defines.php" );
+wfRequireOnceInGlobalScope( "$IP/includes/DefaultSettings.php" );
+wfRequireOnceInGlobalScope( "$IP/includes/GlobalFunctions.php" );
+
+// Load extensions/skins present in filesystem so that classes can be discovered.
+$directoryToJsonMap = [
+       'extensions' => [ 'extension.json', 'extension-wip.json' ],
+       'skins' => [ 'skin.json', 'skin-wip.json' ]
+];
+foreach ( $directoryToJsonMap as $directory => $jsonFile ) {
+       foreach ( new DirectoryIterator( __DIR__ . '/../../' . $directory ) as $iterator ) {
+               foreach ( $jsonFile as $file ) {
+                       $jsonPath = $iterator->getPathname() . '/' . $file;
+                       if ( file_exists( $jsonPath ) ) {
+                               $json = file_get_contents( $jsonPath );
+                               $info = json_decode( $json, true );
+                               $dir = dirname( $jsonPath );
+                               ExtensionRegistry::exportAutoloadClassesAndNamespaces( $dir, $info );
+                       }
+               }
+       }
+}