API Add withConfig method (#9011)

* With config functionality added.
* Update docs/en/02_Developer_Guides/04_Configuration/00_Configuration.md
This commit is contained in:
Mojmir Fendek 2019-10-31 16:12:04 +13:00 committed by Maxime Rainville
parent d814158002
commit e2bea6b41f
3 changed files with 102 additions and 1 deletions

View File

@ -377,6 +377,48 @@ When you have more than one rule for a nested fragment, they're joined like
That is, the fragment will be included if all Only rules match, except if all Except rules match.
</div>
## Unit tests
Sometimes, it's necessary to change a configuration value in your unit tests.
One way to do this is to use the `withConfig` method.
This is especially handy when using data providers.
Example below shows one unit test using a data provider.
This unit test changes configuration before testing functionality.
The test will run three times, each run with different configuration value.
Note that the configuration change is active only within the callback function.
```php
/**
* @dataProvider testValuesProvider
* @param string $value
* @param string $expected
*/
public function testConfigValues($value, $expected)
{
$result = Config::withConfig(function(MutableConfigCollectionInterface $config) use ($value) {
// update your config
$config->set(MyService::class, 'some_setting', $value);
// your test code goes here and it runs with your changed config
return MyService::singleton()->executeSomeFunction();
});
// your config change no longer applies here as it's outside of callback
// assertions can be done here but also inside the callback function
$this->assertEquals($expected, $result);
}
public function testValuesProvider(): array
{
return [
['test value 1', 'expected value 1'],
['test value 2', 'expected value 2'],
['test value 3', 'expected value 3'],
];
}
```
## API Documentation
* [Config](api:SilverStripe\Core\Config\Config)

View File

@ -4,7 +4,6 @@ namespace SilverStripe\Core\Config;
use InvalidArgumentException;
use SilverStripe\Config\Collections\ConfigCollectionInterface;
use SilverStripe\Config\Collections\DeltaConfigCollection;
use SilverStripe\Config\Collections\MutableConfigCollectionInterface;
abstract class Config
@ -119,4 +118,23 @@ abstract class Config
{
return new Config_ForClass($class);
}
/**
* Perform the given operation in an isolated config state.
* On return, the config state will be restored, so any modifications are temporary.
*
* @param callable $callback Callback to run. Will be passed the nested config state as a parameter
* @return mixed Result of callback
*/
public static function withConfig($callback)
{
static::nest();
$config = static::modify();
try {
return $callback($config);
} finally {
static::unnest();
}
}
}

View File

@ -2,6 +2,7 @@
namespace SilverStripe\Core\Tests\Config;
use SilverStripe\Config\Collections\MutableConfigCollectionInterface;
use SilverStripe\Config\MergeStrategy\Priority;
use SilverStripe\Core\Config\Config;
use SilverStripe\Dev\SapphireTest;
@ -322,4 +323,44 @@ class ConfigTest extends SapphireTest
$this->assertTrue(empty($config->bar));
$this->assertNull($config->bar);
}
public function testWithConfig()
{
$oldValue = 'test_1';
$newValue1 = 'new value 1';
$newValue2 = 'new value 2';
$property = 'third';
$this->assertEquals(
$oldValue,
Config::inst()->get(ConfigTest\First::class, $property)
);
Config::withConfig(function (MutableConfigCollectionInterface $config) use ($newValue1, $newValue2, $property) {
$config->set(ConfigTest\First::class, $property, $newValue1);
$this->assertEquals(
$newValue1,
Config::inst()->get(ConfigTest\First::class, $property)
);
$resultValue = Config::withConfig(function (MutableConfigCollectionInterface $config) use ($newValue2, $property) {
$config->set(ConfigTest\First::class, $property, $newValue2);
return Config::inst()->get(ConfigTest\First::class, $property);
});
$this->assertEquals($newValue2, $resultValue);
$this->assertEquals(
$newValue1,
Config::inst()->get(ConfigTest\First::class, $property)
);
});
$this->assertEquals(
$oldValue,
Config::inst()->get(ConfigTest\First::class, $property)
);
}
}