SettingsBuilder: allow maintenance scripts to manipulate config

Maintenance scripts often need to manipulate configuration settings.
This introduces a way to do this cleanly via SettingsBuilder,
removing the need to rely on global variables.

Bug: T294739
Bug: T294742
Bug: T300128
Change-Id: Ibf443fd564bbbf388cce8ab4dabba55ebca0dfa4
This commit is contained in:
daniel 2022-01-14 17:40:52 +01:00 committed by Daniel Kinzler
parent f291528169
commit a652f306a5
18 changed files with 228 additions and 88 deletions

View file

@ -37,6 +37,9 @@ class SettingsBuilder {
/** @var ConfigBuilder */
private $configSink;
/** @var Config */
private $config;
/** @var SettingsSource[] */
private $currentBatch;
@ -46,6 +49,16 @@ class SettingsBuilder {
/** @var PhpIniSink */
private $phpIniSink;
/**
* Configuration that applies to SettingsBuilder itself.
* Initialized by the constructor, may be overwritten by regular
* config values. Merge strategies are currently not implemented
* but can be added if needed.
*
* @var array
*/
private $settingsConfig;
/**
* When we're done applying all settings.
*
@ -76,6 +89,10 @@ class SettingsBuilder {
$this->configSink = $configSink;
$this->configSchema = new ConfigSchemaAggregator();
$this->phpIniSink = $phpIniSink;
$this->settingsConfig = [
'ExtensionDirectory' => "$baseDir/extensions",
'StyleDirectory' => "$baseDir/skins",
];
$this->reset();
}
@ -153,7 +170,7 @@ class SettingsBuilder {
* @return StatusValue
*/
public function validate(): StatusValue {
$config = $this->configSink->build();
$config = $this->getConfig();
$validator = new Validator();
$result = StatusValue::newGood();
@ -183,9 +200,12 @@ class SettingsBuilder {
/**
* Return a Config object with all the default settings loaded so far.
*
* @note This will implicitly call apply()
*
* @return Config
*/
public function getDefaultConfig(): Config {
$this->apply();
return new HashConfig( $this->configSchema->getDefaults() );
}
@ -201,7 +221,12 @@ class SettingsBuilder {
* @throws SettingsBuilderException
*/
public function apply(): self {
if ( !$this->currentBatch ) {
return $this;
}
$this->assertNotFinished();
$this->config = null;
$allSettings = $this->loadRecursive( $this->currentBatch );
@ -267,6 +292,16 @@ class SettingsBuilder {
* @param array $settings
*/
private function applySettings( array $settings ) {
// First extract config variables that change the behavior of SettingsBuilder.
// No merge strategies are applied, defaults are set in the constructor.
if ( isset( $settings['config'] ) ) {
foreach ( $this->settingsConfig as $key => $dummy ) {
if ( array_key_exists( $key, $settings['config'] ) ) {
$this->settingsConfig[$key] = $settings['config'][$key];
}
}
}
foreach ( $settings['config'] ?? [] as $key => $value ) {
$this->configSink->set(
$key,
@ -298,10 +333,8 @@ class SettingsBuilder {
// not just queued. We can't do this right now, because we need to preserve
// interoperability with wfLoadExtension() being called from LocalSettings.php.
$config = $this->configSink->build();
if ( isset( $settings['extensions'] ) ) {
$extDir = $config->get( 'ExtensionDirectory' );
$extDir = $this->settingsConfig['ExtensionDirectory'];
foreach ( $settings['extensions'] ?? [] as $ext ) {
$path = "$extDir/$ext/extension.json"; // see wfLoadExtension
$this->extensionRegistry->queue( $path );
@ -309,7 +342,7 @@ class SettingsBuilder {
}
if ( isset( $settings['skins'] ) ) {
$skinDir = $config->get( 'StyleDirectory' );
$skinDir = $this->settingsConfig['StyleDirectory'];
foreach ( $settings['skins'] ?? [] as $skin ) {
$path = "$skinDir/$skin/skin.json"; // see wfLoadSkin
$this->extensionRegistry->queue( $path );
@ -317,6 +350,54 @@ class SettingsBuilder {
}
}
/**
* Sets the value of a config variable.
* This is a shorthand for loadArray().
* @unstable
*
* @param string $key the name of the config setting
* @param mixed $value The value to set
*
* @return $this
*/
public function setConfigValue( string $key, $value ): self {
$this->loadArray( [ 'config' => [ $key => $value ] ] );
return $this;
}
/**
* Sets the value of multiple config variables.
* This is a shorthand for loadArray().
* @unstable
*
* @param array $values An associative array mapping names to values.
*
* @return $this
*/
public function setConfigValues( array $values ): self {
$this->loadArray( [ 'config' => $values ] );
return $this;
}
/**
* Returns the config loaded so far. Implicitly triggers apply() when needed.
*
* @note This will implicitly call apply()
*
* @unstable
* @return Config
*/
public function getConfig(): Config {
if ( $this->config && !$this->currentBatch ) {
return $this->config;
}
$this->apply();
$this->config = $this->configSink->build();
return $this->config;
}
private function reset() {
$this->currentBatch = [];
}

View file

@ -175,7 +175,7 @@ $wgSettings->apply();
*/
if ( defined( 'MW_SETUP_CALLBACK' ) ) {
call_user_func( MW_SETUP_CALLBACK );
call_user_func( MW_SETUP_CALLBACK, $wgSettings );
// Make any additional settings available in globals for use here
$wgSettings->apply();
}

View file

@ -36,6 +36,8 @@
# T17461: Make IE8 turn off content sniffing. Everybody else should ignore this
# We're adding it here so that it's *always* set, even for alternate entry
# points and when $wgOut gets disabled or overridden.
use MediaWiki\Settings\SettingsBuilder;
header( 'X-Content-Type-Options: nosniff' );
# Valid web server entry point, enable includes.
@ -74,7 +76,7 @@ if ( !defined( 'MW_CONFIG_CALLBACK' ) ) {
}
}
function wfWebStartSetup() {
function wfWebStartSetup( SettingsBuilder $settings ) {
// Initialise output buffering
// Check for previously set up buffers, to avoid a mix of gzip and non-gzip output.
if ( ob_get_level() == 0 ) {

View file

@ -25,6 +25,7 @@
* @ingroup Maintenance
*/
use MediaWiki\MediaWikiServices;
use MediaWiki\Settings\SettingsBuilder;
if ( !defined( 'RUN_MAINTENANCE_IF_MAIN' ) ) {
echo "This file must be included after Maintenance.php\n";
@ -70,18 +71,23 @@ if ( !defined( 'MW_CONFIG_CALLBACK' ) && !defined( 'MW_CONFIG_FILE' ) ) {
// Custom setup for Maintenance entry point
if ( !defined( 'MW_SETUP_CALLBACK' ) ) {
function wfMaintenanceSetup() {
global $maintenance, $wgLocalisationCacheConf, $wgCacheDirectory;
function wfMaintenanceSetup( SettingsBuilder $settingsBuilder ) {
global $maintenance;
$config = $settingsBuilder->getConfig();
if ( $maintenance->getDbType() === Maintenance::DB_NONE ) {
if ( $wgLocalisationCacheConf['storeClass'] === false
&& ( $wgLocalisationCacheConf['store'] == 'db'
|| ( $wgLocalisationCacheConf['store'] == 'detect' && !$wgCacheDirectory ) )
$cacheConf = $config->get( 'LocalisationCacheConf' );
if ( $cacheConf['storeClass'] === false
&& ( $cacheConf['store'] == 'db'
|| ( $cacheConf['store'] == 'detect'
&& !$config->get( 'CacheDirectory' ) ) )
) {
$wgLocalisationCacheConf['storeClass'] = LCStoreNull::class;
$cacheConf['storeClass'] = LCStoreNull::class;
$settingsBuilder->setConfigValue( 'LocalisationCacheConf', $cacheConf );
}
}
$maintenance->finalSetup();
$maintenance->finalSetup( $settingsBuilder );
}
define( 'MW_SETUP_CALLBACK', 'wfMaintenanceSetup' );

View file

@ -28,6 +28,7 @@
use MediaWiki\MediaWikiServices;
use MediaWiki\Revision\SlotRecord;
use MediaWiki\Settings\SettingsBuilder;
require_once __DIR__ . '/Maintenance.php';
@ -109,14 +110,19 @@ abstract class DumpIterator extends Maintenance {
$this->error( "Memory peak usage of " . memory_get_peak_usage() . " bytes\n" );
}
public function finalSetup() {
parent::finalSetup();
public function finalSetup( SettingsBuilder $settingsBuilder = null ) {
parent::finalSetup( $settingsBuilder );
if ( $this->getDbType() == Maintenance::DB_NONE ) {
global $wgUseDatabaseMessages, $wgLocalisationCacheConf, $wgHooks;
$wgUseDatabaseMessages = false;
$wgLocalisationCacheConf['storeClass'] = LCStoreNull::class;
// TODO: Allow hooks to be registered via SettingsBuilder as well!
// This matches the idea of unifying SettingsBuilder with ExtensionRegistry.
global $wgHooks;
$wgHooks['InterwikiLoadPrefix'][] = 'DumpIterator::disableInterwikis';
$settingsBuilder->setConfigValues( [
'UseDatabaseMessages' => false,
'LocalisationCacheConf' => [ 'storeClass' => LCStoreNull::class ],
] );
}
}

View file

@ -25,6 +25,7 @@
require_once __DIR__ . '/Maintenance.php';
use MediaWiki\MediaWikiServices;
use MediaWiki\Settings\SettingsBuilder;
use MediaWiki\Storage\BlobAccessException;
use MediaWiki\Storage\BlobStore;
use MediaWiki\Storage\SqlBlobStore;
@ -45,17 +46,16 @@ class FetchText extends Maintenance {
);
}
public function finalSetup() {
public function finalSetup( SettingsBuilder $settingsBuilder = null ) {
// This script should always try to run all db queries in the 'dump' group if such
// a group exists, just like the BackupDumper and TextPassDumper modules.
// To account for parts of MediaWiki that get their own db connection outside of
// Maintenance::getDB(), we set this global variable so that they will attempt
// to use this group.
global $wgDBDefaultGroup;
$wgDBDefaultGroup = "dump";
$settingsBuilder->setConfigValue( 'DBDefaultGroup', 'dump' );
// do this last so that options can override
parent::finalSetup();
parent::finalSetup( $settingsBuilder );
}
/**

View file

@ -23,6 +23,8 @@
* @author Antoine Musso <hashar@free.fr>
*/
use MediaWiki\Settings\SettingsBuilder;
require_once __DIR__ . '/Maintenance.php';
/**
@ -89,9 +91,11 @@ class GetConfiguration extends Maintenance {
/**
* finalSetup() since we need MWException
*
* @param SettingsBuilder|null $settingsBuilder
*/
public function finalSetup() {
parent::finalSetup();
public function finalSetup( SettingsBuilder $settingsBuilder = null ) {
parent::finalSetup( $settingsBuilder );
$this->regex = $this->getOption( 'regex' ) ?: $this->getOption( 'iregex' );
if ( $this->regex ) {

View file

@ -29,6 +29,7 @@ require_once __DIR__ . '/../Maintenance.php';
require_once __DIR__ . '/../../includes/export/WikiExporter.php';
use MediaWiki\MediaWikiServices;
use MediaWiki\Settings\SettingsBuilder;
use Wikimedia\Rdbms\IMaintainableDatabase;
use Wikimedia\Rdbms\LoadBalancer;
@ -150,11 +151,12 @@ abstract class BackupDumper extends Maintenance {
}
}
public function validateParamsAndArgs() {
public function finalSetup( SettingsBuilder $settingsBuilder = null ) {
// re-declare the --schema-version option to include the default schema version
// in the description.
$schemaVersion = $settingsBuilder->getConfig()->get( 'XmlDumpSchemaVersion' );
$this->addOption( 'schema-version', 'Schema version to use for output. ' .
'Default: ' . WikiExporter::schemaVersion(), false, true );
'Default: ' . $schemaVersion, false, true );
parent::validateParamsAndArgs();
}

View file

@ -22,6 +22,7 @@ use MediaWiki\HookContainer\HookContainer;
use MediaWiki\HookContainer\HookRunner;
use MediaWiki\Logger\LoggerFactory;
use MediaWiki\MediaWikiServices;
use MediaWiki\Settings\SettingsBuilder;
use MediaWiki\Shell\Shell;
use Wikimedia\Rdbms\IDatabase;
use Wikimedia\Rdbms\IMaintainableDatabase;
@ -725,7 +726,7 @@ abstract class Maintenance {
$this->loadParamsAndArgs();
# Set the memory limit
# Note we need to set it again later in cache LocalSettings changed it
# Note we need to set it again later in case LocalSettings changed it
$this->adjustMemoryLimit();
# Set max execution time to 0 (no limit). PHP.net says that
@ -1124,34 +1125,46 @@ abstract class Maintenance {
/**
* Handle some last-minute setup here.
*
* @stable to override
*
* @param SettingsBuilder|null $settingsBuilder
*/
public function finalSetup() {
global $wgCommandLineMode, $wgServer, $wgShowExceptionDetails, $wgShowHostnames;
global $wgDBadminuser, $wgDBadminpassword, $wgDBDefaultGroup;
global $wgDBuser, $wgDBpassword, $wgDBservers, $wgLBFactoryConf;
public function finalSetup( SettingsBuilder $settingsBuilder = null ) {
if ( !$settingsBuilder ) {
// HACK for backwards compatibility. All subclasses that override
// finalSetup() should be updated to pass $settingsBuilder along.
// XXX: We don't want the parameter to be nullable! How can we make it required
// without breaking backwards compatibility?
$settingsBuilder = $GLOBALS['wgSettings'];
}
$config = $settingsBuilder->getConfig();
$overrides = [];
$overrides['DBadminuser'] = $config->get( 'DBadminuser' );
$overrides['DBadminpassword'] = $config->get( 'DBadminpassword' );
# Turn off output buffering again, it might have been turned on in the settings files
if ( ob_get_level() ) {
ob_end_flush();
}
# Same with these
$wgCommandLineMode = true;
$overrides['CommandLineMode'] = true;
# Override $wgServer
if ( $this->hasOption( 'server' ) ) {
$wgServer = $this->getOption( 'server', $wgServer );
$overrides['Server'] = $this->getOption( 'server', $config->get( 'Server' ) );
}
# If these were passed, use them
if ( $this->mDbUser ) {
$wgDBadminuser = $this->mDbUser;
$overrides['DBadminuser'] = $this->mDbUser;
}
if ( $this->mDbPass ) {
$wgDBadminpassword = $this->mDbPass;
$overrides['DBadminpassword'] = $this->mDbPass;
}
if ( $this->hasOption( 'dbgroupdefault' ) ) {
$wgDBDefaultGroup = $this->getOption( 'dbgroupdefault', null );
$overrides['DBDefaultGroup'] = $this->getOption( 'dbgroupdefault', null );
// TODO: once MediaWikiServices::getInstance() starts throwing exceptions
// and not deprecation warnings for premature access to service container,
// we can remove this line. This method is called before Setup.php,
@ -1164,23 +1177,27 @@ abstract class Maintenance {
}
}
if ( $this->getDbType() == self::DB_ADMIN && isset( $wgDBadminuser ) ) {
$wgDBuser = $wgDBadminuser;
$wgDBpassword = $wgDBadminpassword;
if ( $this->getDbType() == self::DB_ADMIN && isset( $overrides[ 'DBadminuser' ] ) ) {
$overrides['DBuser'] = $overrides[ 'DBadminuser' ];
$overrides['DBpassword'] = $overrides[ 'DBadminpassword' ];
if ( $wgDBservers ) {
/**
* @var array $wgDBservers
*/
foreach ( $wgDBservers as $i => $server ) {
$wgDBservers[$i]['user'] = $wgDBuser;
$wgDBservers[$i]['password'] = $wgDBpassword;
/** @var array $dbServers */
$dbServers = $config->get( 'DBservers' );
if ( $dbServers ) {
foreach ( $dbServers as $i => $server ) {
$dbServers[$i]['user'] = $overrides['DBuser'];
$dbServers[$i]['password'] = $overrides['DBpassword'];
}
$overrides['DBservers'] = $dbServers;
}
if ( isset( $wgLBFactoryConf['serverTemplate'] ) ) {
$wgLBFactoryConf['serverTemplate']['user'] = $wgDBuser;
$wgLBFactoryConf['serverTemplate']['password'] = $wgDBpassword;
$lbFactoryConf = $config->get( 'LBFactoryConf' );
if ( isset( $lbFactoryConf['serverTemplate'] ) ) {
$lbFactoryConf['serverTemplate']['user'] = $overrides['DBuser'];
$lbFactoryConf['serverTemplate']['password'] = $overrides['DBpassword'];
$overrides['LBFactoryConf'] = $lbFactoryConf;
}
// TODO: once MediaWikiServices::getInstance() starts throwing exceptions
// and not deprecation warnings for premature access to service container,
// we can remove this line. This method is called before Setup.php,
@ -1198,14 +1215,16 @@ abstract class Maintenance {
$this->afterFinalSetup();
$wgShowExceptionDetails = true;
$wgShowHostnames = true;
$overrides['ShowExceptionDetails'] = true;
$overrides['ShowHostname'] = true;
Wikimedia\suppressWarnings();
set_time_limit( 0 );
Wikimedia\restoreWarnings();
$ini = [
'max_execution_time' => 0,
];
$this->adjustMemoryLimit();
$settingsBuilder->loadArray( [ 'config' => $overrides, 'php-ini' => $ini ] );
}
/**

View file

@ -30,6 +30,7 @@ require_once __DIR__ . '/../../includes/export/WikiExporter.php';
use MediaWiki\MediaWikiServices;
use MediaWiki\Revision\SlotRecord;
use MediaWiki\Settings\SettingsBuilder;
use MediaWiki\Shell\Shell;
use MediaWiki\Storage\BlobAccessException;
use MediaWiki\Storage\BlobStore;
@ -151,8 +152,8 @@ TEXT
}
}
public function finalSetup() {
parent::finalSetup();
public function finalSetup( SettingsBuilder $settingsBuilder = null ) {
parent::finalSetup( $settingsBuilder );
SevenZipStream::register();
}

View file

@ -25,6 +25,8 @@
// NO_AUTOLOAD -- file-scope define() used to modify behaviour
# Start from scratch
use MediaWiki\Settings\SettingsBuilder;
define( 'MW_NO_EXTENSION_MESSAGES', 1 );
require_once __DIR__ . '/Maintenance.php';
@ -120,13 +122,12 @@ class MergeMessageFileList extends Maintenance {
}
}
public function finalSetup() {
public function finalSetup( SettingsBuilder $settingsBuilder = null ) {
# This script commonly needs to be run before the l10n cache. But if
# $wgLanguageCode is not 'en', it won't be able to run because there is
# no l10n cache. Break the cycle by forcing $wgLanguageCode = 'en'.
global $wgLanguageCode;
$wgLanguageCode = 'en';
parent::finalSetup();
# LanguageCode is not 'en', it won't be able to run because there is
# no l10n cache. Break the cycle by forcing the LanguageCode setting to 'en'.
$settingsBuilder->setConfigValue( 'LanguageCode', 'en' );
parent::finalSetup( $settingsBuilder );
}
/**

View file

@ -22,6 +22,7 @@
*/
use MediaWiki\MediaWikiServices;
use MediaWiki\Settings\SettingsBuilder;
require_once __DIR__ . '/Maintenance.php';
@ -43,12 +44,11 @@ class RebuildFileCache extends Maintenance {
$this->setBatchSize( 100 );
}
public function finalSetup() {
global $wgUseFileCache;
$this->enabled = $wgUseFileCache;
public function finalSetup( SettingsBuilder $settingsBuilder = null ) {
$this->enabled = $settingsBuilder->getConfig()->get( 'UseFileCache' );
// Script will handle capturing output and saving it itself
$wgUseFileCache = false;
$settingsBuilder->setConfigValue( 'UseFileCache', false );
// Avoid DB writes (like enotif/counters)
MediaWiki\MediaWikiServices::getInstance()->getReadOnlyMode()
->setReason( 'Building cache' );
@ -56,7 +56,7 @@ class RebuildFileCache extends Maintenance {
// Ensure no debug-specific logic ends up in the cache (must be after Setup.php)
MWDebug::deinit();
parent::finalSetup();
parent::finalSetup( $settingsBuilder );
}
public function execute() {

View file

@ -33,6 +33,7 @@ use MediaWiki\Config\ServiceOptions;
use MediaWiki\Languages\LanguageNameUtils;
use MediaWiki\Logger\LoggerFactory;
use MediaWiki\MediaWikiServices;
use MediaWiki\Settings\SettingsBuilder;
require_once __DIR__ . '/Maintenance.php';
@ -76,13 +77,12 @@ class RebuildLocalisationCache extends Maintenance {
);
}
public function finalSetup() {
public function finalSetup( SettingsBuilder $settingsBuilder = null ) {
# This script needs to be run to build the initial l10n cache. But if
# $wgLanguageCode is not 'en', it won't be able to run because there is
# no l10n cache. Break the cycle by forcing $wgLanguageCode = 'en'.
global $wgLanguageCode;
$wgLanguageCode = 'en';
parent::finalSetup();
# LanguageCode is not 'en', it won't be able to run because there is
# no l10n cache. Break the cycle by forcing the LanguageCode setting to 'en'.
$settingsBuilder->setConfigValue( 'LanguageCode', 'en' );
parent::finalSetup( $settingsBuilder );
}
public function execute() {

View file

@ -24,6 +24,7 @@
require_once __DIR__ . '/Maintenance.php';
use MediaWiki\MediaWikiServices;
use MediaWiki\Settings\SettingsBuilder;
/**
* Maintenance script that runs pending jobs.
@ -43,11 +44,11 @@ class RunJobs extends Maintenance {
$this->addOption( 'wait', 'Wait for new jobs instead of exiting', false, false );
}
public function finalSetup() {
public function finalSetup( SettingsBuilder $settingsBuilder = null ) {
// So extensions (and other code) can check whether they're running in job mode.
// This is not defined if this script is included from installer/updater or phpunit.
define( 'MEDIAWIKI_JOB_RUNNER', true );
parent::finalSetup();
parent::finalSetup( $settingsBuilder );
}
public function memoryLimit() {

View file

@ -1,5 +1,7 @@
<?php
use MediaWiki\Settings\SettingsBuilder;
require_once __DIR__ . '/../../maintenance/Maintenance.php';
define( 'MW_PARSER_TEST', true );
@ -25,8 +27,8 @@ class ParserEditTests extends Maintenance {
'defaults.' );
}
public function finalSetup() {
parent::finalSetup();
public function finalSetup( SettingsBuilder $settingsBuilder = null ) {
parent::finalSetup( $settingsBuilder );
self::requireTestsAutoloader();
TestSetup::applyInitialConfig();
}

View file

@ -1,5 +1,6 @@
<?php
use MediaWiki\Settings\SettingsBuilder;
use Wikimedia\ScopedCallback;
require_once __DIR__ . '/../../maintenance/Maintenance.php';
@ -20,7 +21,7 @@ class ParserFuzzTest extends Maintenance {
$this->addOption( 'seed', 'Start the fuzz test from the specified seed', false, true );
}
public function finalSetup() {
public function finalSetup( SettingsBuilder $settingsBuilder = null ) {
// Make RequestContext::resetMain() happy
define( 'MW_PARSER_TEST', 1 );

View file

@ -27,6 +27,7 @@
require_once __DIR__ . '/../../maintenance/Maintenance.php';
use MediaWiki\MediaWikiServices;
use MediaWiki\Settings\SettingsBuilder;
class ParserTestsMaintenance extends Maintenance {
public function __construct() {
@ -72,12 +73,12 @@ class ParserTestsMaintenance extends Maintenance {
'defaults.' );
}
public function finalSetup() {
public function finalSetup( SettingsBuilder $settingsBuilder = null ) {
// Some methods which are discouraged for normal code throw exceptions unless
// we declare this is just a test.
define( 'MW_PARSER_TEST', true );
parent::finalSetup();
parent::finalSetup( $settingsBuilder );
self::requireTestsAutoloader();
TestSetup::applyInitialConfig();
}

View file

@ -33,18 +33,15 @@ class SettingsBuilderTest extends TestCase {
}
public function testLoadingFromFile() {
$configBuilder = new ArrayConfigBuilder();
$phpIniSinkMock = $this->createMock( PhpIniSink::class );
$phpIniSinkMock->expects( $this->once() )->method( 'set' )->with( 'foo', 'bar' );
$setting = $this->newSettingsBuilder( [
'configBuilder' => $configBuilder,
'phpIniSink' => $phpIniSinkMock
] );
$setting->loadFile( 'fixtures/settings.json' )->apply();
$config = $configBuilder->build();
$config = $setting->getConfig();
$this->assertSame( 'TEST', $config->get( 'Something' ) );
}
@ -266,10 +263,26 @@ class SettingsBuilderTest extends TestCase {
}
}
public function testSetConfig() {
$setting = $this->newSettingsBuilder();
$setting->setConfigValues( [ 'a' => 1, 'b' => 2 ] );
$config = $setting->getConfig();
$this->assertSame( 1, $config->get( 'a' ) );
$this->assertSame( 2, $config->get( 'b' ) );
$setting->setConfigValue( 'b', 22 );
$config = $setting->getConfig();
$this->assertSame( 1, $config->get( 'a' ) );
$this->assertSame( 22, $config->get( 'b' ) );
}
public function testApplyPurgesState() {
$configBuilder = new ArrayConfigBuilder();
$setting = $this->newSettingsBuilder( [ 'configBuilder' => $configBuilder ] );
$setting->loadArray( [ 'config' => [ 'MySetting' => 'MyValue', ], ] )
$setting->setConfigValue( 'MySetting', 'MyValue' )
->apply();
$this->assertSame( 'MyValue', $configBuilder->build()->get( 'MySetting' ) );
$configBuilder->set( 'MySetting', 'MyOtherValue' );