*/
private $mwGlobalsToUnset = [];
+ /**
+ * Holds original values of ini settings to be restored
+ * in tearDown().
+ * @see setIniSettings()
+ * @var array
+ */
+ private $iniSettings = [];
+
/**
* Holds original loggers which have been replaced by setLogger()
* @var LoggerInterface[]
*/
private $cliArgs = [];
+ /**
+ * Holds a list of services that were overridden with setService(). Used for printing an error
+ * if overrideMwServices() overrides a service that was previously set.
+ * @var string[]
+ */
+ private $overriddenServices = [];
+
/**
* Table name prefixes. Oracle likes it shorter.
*/
*
* @since 1.28
*
- * @param string[] $groups Groups the test user should be in.
+ * @param string|string[] $groups Groups the test user should be in.
* @return TestUser
*/
public static function getTestUser( $groups = [] ) {
*
* @since 1.28
*
- * @param string[] $groups Groups the test user should be added in.
+ * @param string|string[] $groups Groups the test user should be added in.
* @return TestUser
*/
public static function getMutableTestUser( $groups = [] ) {
parent::run( $result );
+ // We don't mind if we override already-overridden services during cleanup
+ $this->overriddenServices = [];
+
if ( $needsResetDB ) {
$this->resetDB( $this->db, $this->tablesUsed );
}
$this->phpErrorLevel = intval( ini_get( 'error_reporting' ) );
+ $this->overriddenServices = [];
+
// Cleaning up temporary files
foreach ( $this->tmpFiles as $fileName ) {
if ( is_file( $fileName ) || ( is_link( $fileName ) ) ) {
}
}
+ // Re-enable any disabled deprecation warnings
+ MWDebug::clearLog();
// Restore mw globals
foreach ( $this->mwGlobals as $key => $value ) {
$GLOBALS[$key] = $value;
foreach ( $this->mwGlobalsToUnset as $value ) {
unset( $GLOBALS[$value] );
}
+ foreach ( $this->iniSettings as $name => $value ) {
+ ini_set( $name, $value );
+ }
if (
array_key_exists( 'wgExtraNamespaces', $this->mwGlobals ) ||
in_array( 'wgExtraNamespaces', $this->mwGlobalsToUnset )
. 'instance has been replaced by test code.' );
}
+ $this->overriddenServices[] = $name;
+
$this->localServices->disableService( $name );
$this->localServices->redefineService(
$name,
* touch.
*/
private function doSetMwGlobals( $pairs, $value = null ) {
- $this->stashMwGlobals( array_keys( $pairs ) );
+ $this->doStashMwGlobals( array_keys( $pairs ) );
foreach ( $pairs as $key => $value ) {
$GLOBALS[$key] = $value;
}
}
+ /**
+ * Set an ini setting for the duration of the test
+ * @param string $name Name of the setting
+ * @param string $value Value to set
+ * @since 1.32
+ */
+ protected function setIniSetting( $name, $value ) {
+ $original = ini_get( $name );
+ $this->iniSettings[$name] = $original;
+ ini_set( $name, $value );
+ }
+
/**
* Must be called whenever namespaces are changed, e.g., $wgExtraNamespaces is altered.
* Otherwise old namespace data will lurk and cause bugs.
* call overrideMwServices().
*
* @since 1.23
+ * @deprecated since 1.32, use setMwGlobals() and don't alter globals directly
*/
protected function stashMwGlobals( $globalKeys ) {
+ wfDeprecated( __METHOD__, '1.32' );
+ $this->doStashMwGlobals( $globalKeys );
+ }
+
+ private function doStashMwGlobals( $globalKeys ) {
if ( is_string( $globalKeys ) ) {
$globalKeys = [ $globalKeys ];
}
protected function overrideMwServices(
Config $configOverrides = null, array $services = []
) {
+ if ( $this->overriddenServices ) {
+ throw new MWException(
+ 'The following services were set and are now being unset by overrideMwServices: ' .
+ implode( ', ', $this->overriddenServices )
+ );
+ }
$newInstance = self::installMockMwServices( $configOverrides );
if ( $this->localServices ) {
*/
public function setContentLang( $lang ) {
if ( $lang instanceof Language ) {
- $langCode = $lang->getCode();
- $langObj = $lang;
+ $this->setMwGlobals( 'wgLanguageCode', $lang->getCode() );
+ // Set to the exact object requested
+ $this->setService( 'ContentLanguage', $lang );
} else {
- $langCode = $lang;
- $langObj = Language::factory( $langCode );
+ $this->setMwGlobals( 'wgLanguageCode', $lang );
+ // Let the service handler make up the object. Avoid calling setService(), because if
+ // we do, overrideMwServices() will complain if it's called later on.
+ $services = MediaWikiServices::getInstance();
+ $services->resetServiceForTesting( 'ContentLanguage' );
+ $this->doSetMwGlobals( [ 'wgContLang' => $services->getContentLanguage() ] );
}
- $this->setMwGlobals( 'wgLanguageCode', $langCode );
- $this->setService( 'ContentLanguage', $langObj );
}
/**
public function setGroupPermissions( $newPerms, $newKey = null, $newValue = null ) {
global $wgGroupPermissions;
- $this->stashMwGlobals( 'wgGroupPermissions' );
-
if ( is_string( $newPerms ) ) {
$newPerms = [ $newPerms => [ $newKey => $newValue ] ];
}
+ $newPermissions = $wgGroupPermissions;
foreach ( $newPerms as $group => $permissions ) {
foreach ( $permissions as $key => $value ) {
- $wgGroupPermissions[$group][$key] = $value;
+ $newPermissions[$group][$key] = $value;
}
}
+
+ $this->setMwGlobals( 'wgGroupPermissions', $newPermissions );
}
/**