123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- <?php
- /**
- * Tests the Config lib that's shipped with ko7
- *
- * @group ko7
- * @group ko7.core
- * @group ko7.core.config
- *
- * @package KO7
- * @category Tests
- *
- * @author Jeremy Bush <contractfrombelow@gmail.com>
- * @author Matt Button <matthew@sigswitch.com>
- * @copyright (c) 2007-2016 Kohana Team
- * @copyright (c) since 2016 Koseven Team
- * @license https://koseven.dev/LICENSE
- */
- class KO7_ConfigTest extends Unittest_TestCase
- {
- /**
- * When a config object is initially created there should be
- * no readers attached
- *
- * @covers Config
- */
- public function test_initially_there_are_no_sources()
- {
- $this->expectException(KO7_Exception::class);
- $this->expectExceptionMessage('No configuration sources attached');
- $config = new Config;
- $config->load('invalid');
- }
- /**
- * Test that calling attach() on a ko7 config object
- * adds the specified reader to the config object
- *
- * @covers Config::attach
- */
- public function test_attach_adds_reader_and_returns_this()
- {
- $config = new Config;
- $reader = $this->createMock('KO7_Config_Reader');
- $this->assertSame($config, $config->attach($reader));
- $this->expectException(KO7_Exception::class);
- $this->expectExceptionMessage('Need to specify a config group');
- $config->load(NULL);
- }
- /**
- * Calling detach() on a config object should remove it from the queue of readers
- *
- * @test
- * @covers Config::detach
- */
- public function test_detach_removes_reader_and_returns_this()
- {
- $config = new Config;
- // Due to the way phpunit mock generator works if you try and mock a class
- // that has already been used then it just re-uses the first's name
- // To get around this we have to specify a totally random name for the second mock object
- $reader1 = $this->createMock('KO7_Config_Reader');
- $reader2 = $this->createMock('KO7_Config_Reader', [], [], 'MY_AWESOME_READER');
- $config->attach($reader1);
- $config->attach($reader2);
- $this->assertSame($config, $config->detach($reader2));
- $this->assertSame($config, $config->detach($reader1));
- $this->expectException(KO7_Exception::class);
- $this->expectExceptionMessage('No configuration sources attached');
- $config->load('invalid');
- }
- /**
- * detach() should return $this even if the specified reader does not exist
- *
- * @test
- * @covers Config::detach
- */
- public function test_detach_returns_this_even_when_reader_dnx()
- {
- $config = new Config;
- $reader = $this->createMock('KO7_Config_Reader');
- $this->assertSame($config, $config->detach($reader));
- }
- /**
- * If we request a config variable with a dot path then
- * Config::load() should load the group and return the requested variable
- *
- * @test
- * @covers Config::load
- */
- public function test_load_can_get_var_from_dot_path()
- {
- $config = new Config;
- $reader = $this->createMock('KO7_Config_Reader', ['load']);
- $reader
- ->expects($this->once())
- ->method('load')
- ->with('beer')
- ->will($this->returnValue(['stout' => 'Guinness']));
- $config->attach($reader);
- $this->assertSame('Guinness', $config->load('beer.stout'));
- }
- /**
- * If we've already loaded a config group then the correct variable
- * should be returned if we use the dot path notation to to request
- * a var
- *
- * @test
- * @covers Config::load
- */
- public function test_load_can_get_var_from_dot_path_for_loaded_group()
- {
- $config = new Config;
- $reader = $this->createMock('KO7_Config_Reader', ['load']);
- $reader
- ->expects($this->once())
- ->method('load')
- ->with('beer')
- ->will($this->returnValue(['stout' => 'Guinness']));
- $config->attach($reader);
- $config->load('beer');
- $this->assertSame('Guinness', $config->load('beer.stout'));
- }
- /**
- * If load() is called and there are no readers present then it should throw
- * a ko7 exception
- *
- * @covers Config::load
- */
- public function test_load_throws_exception_if_there_are_no_sources()
- {
- $this->expectException(KO7_Exception::class);
- // The following code should throw an exception and phpunit will catch / handle it
- $config = new KO7_config;
- $config->load('random');
- }
- /**
- * Provides test data for test_load_throws_exception_if_no_group_is_given()
- *
- * @return array
- */
- public function provider_load_throws_exception_if_no_group_is_given()
- {
- return [
- [NULL],
- [''],
- [[]],
- [['foo' => 'bar']],
- [new StdClass],
- ];
- }
- /**
- * If an invalid group name is specified then an exception should be thrown.
- *
- * Invalid means it's either a non-string value, or empty
- *
- * @dataProvider provider_load_throws_exception_if_no_group_is_given
- * @covers Config::load
- */
- public function test_load_throws_exception_if_invalid_group($value)
- {
- $this->expectException(KO7_Exception::class);
- $config = new KO7_Config;
- $reader = $this->createMock('KO7_Config_Reader');
- $config->attach($reader);
- $config->load($value);
- }
- /**
- * Make sure that _write_config() passes the changed configuration to all
- * writers in the queue
- *
- * @test
- * @covers KO7_Config
- */
- public function test_write_config_passes_changed_config_to_all_writers()
- {
- $config = new KO7_Config;
- $reader1 = $this->createMock('KO7_Config_Reader');
- $writer1 = $this->createMock('KO7_Config_Writer', ['write']);
- $writer2 = $this->createMock('KO7_Config_Writer', ['write']);
- $writer1
- ->expects($this->once())
- ->method('write')
- ->with('some_group', 'key', 'value');
- $writer2
- ->expects($this->once())
- ->method('write')
- ->with('some_group', 'key', 'value');
- $config->attach($reader1)->attach($writer1)->attach($writer2);
- $config->_write_config('some_group', 'key', 'value');
- }
- /**
- * Config sources are stored in a stack, make sure that config at the bottom
- * of the stack is overriden by config at the top
- *
- * @test
- * @covers Config::load
- */
- public function test_config_is_loaded_from_top_to_bottom_of_stack()
- {
- $group_name = 'lolumns';
- $reader1 = $this->createMock('KO7_Config_Reader', ['load'], [], 'Unittest_Config_Reader_1');
- $reader2 = $this->createMock('KO7_Config_Reader', ['load'], [], 'Unittest_Config_Reader_2');
- $reader1
- ->expects($this->once())
- ->method('load')
- ->with($group_name)
- ->will($this->returnValue(['foo' => 'bar', 'ko7' => 'awesome', 'life' => ['normal', 'fated']]));
- $reader2
- ->expects($this->once())
- ->method('load')
- ->with($group_name)
- ->will($this->returnValue(['ko7' => 'sweet', 'music' => 'tasteful', 'life' => ['extraordinary', 'destined']]));
- $config = new KO7_Config;
- // Attach $reader1 at the "top" and reader2 at the "bottom"
- $config->attach($reader1)->attach($reader2, FALSE);
- $this->assertSame(
- [
- 'ko7' => 'awesome',
- 'music' => 'tasteful',
- 'life' => [
- 'extraordinary',
- 'destined',
- 'normal',
- 'fated',
- ],
- 'foo' => 'bar',
- ],
- $config->load($group_name)->as_array()
- );
- }
- /**
- * load() should keep a record of what config groups have been requested and if
- * a group is requested more than once the first instance should be returned
- *
- * @test
- * @covers Config::load
- */
- public function test_load_reuses_config_groups()
- {
- $reader = $this->createMock('KO7_Config_Reader', ['load']);
- $reader
- ->expects($this->once())
- ->method('load')
- ->with('something')
- ->will($this->returnValue([]));
- $config = new KO7_Config;
- $config->attach($reader);
- $group = $config->load('something');
- $this->assertSame($group, $config->load('something'));
- }
- /**
- * When we call copy() we expect it to copy the merged config to all writers
- *
- * @TODO This test sucks due to limitations in the phpunit mock generator. MAKE THIS AWESOME AGAIN!
- * @test
- * @covers KO7_Config::copy
- */
- public function test_copy_copies_merged_config_to_all_writers()
- {
- $config = new KO7_Config;
- $reader1 = $this->createMock('KO7_Config_Reader', ['load']);
- $reader2 = $this->createMock('KO7_Config_Reader', ['load']);
- $reader1
- ->expects($this->once())
- ->method('load')
- ->with('something')
- ->will($this->returnValue(['pie' => 'good', 'ko7' => 'awesome']));
- $reader2
- ->expects($this->once())
- ->method('load')
- ->with('something')
- ->will($this->returnValue(['ko7' => 'good']));
- $writer1 = $this->createMock('KO7_Config_Writer', ['write']);
- $writer2 = $this->createMock('KO7_Config_Writer', ['write']);
- // Due to crazy limitations in phpunit's mocking engine we have to be fairly
- // liberal here as to what order we receive the config items
- // Good news is that order shouldn't matter *yay*
- //
- // Now save your eyes and skip the next... 13 lines!
- $key = $this->logicalOr('pie', 'ko7');
- $val = $this->logicalOr('good', 'awesome');
- $writer1
- ->expects($this->exactly(2))
- ->method('write')
- ->with('something', clone $key, clone $val);
- $writer2
- ->expects($this->exactly(2))
- ->method('write')
- ->with('something', clone $key, clone $val);
- $config
- ->attach($reader1)->attach($reader2, FALSE)
- ->attach($writer1)->attach($writer2);
- // Now let's get this thing going!
- $config->copy('something');
- }
- }
|