ConfigTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. <?php defined('SYSPATH') OR die('Kohana bootstrap needs to be included before tests run');
  2. /**
  3. * Tests the Config lib that's shipped with kohana
  4. *
  5. * @group kohana
  6. * @group kohana.core
  7. * @group kohana.core.config
  8. *
  9. * @package Kohana
  10. * @category Tests
  11. * @author Kohana Team
  12. * @author Jeremy Bush <[email protected]>
  13. * @author Matt Button <[email protected]>
  14. * @copyright (c) 2008-2012 Kohana Team
  15. * @license http://kohanaframework.org/license
  16. */
  17. class Kohana_ConfigTest extends Unittest_TestCase
  18. {
  19. /**
  20. * When a config object is initially created there should be
  21. * no readers attached
  22. *
  23. * @test
  24. * @covers Config
  25. */
  26. public function test_initially_there_are_no_sources()
  27. {
  28. $config = new Config;
  29. $this->assertAttributeSame(array(), '_sources', $config);
  30. }
  31. /**
  32. * Test that calling attach() on a kohana config object
  33. * adds the specified reader to the config object
  34. *
  35. * @test
  36. * @covers Config::attach
  37. */
  38. public function test_attach_adds_reader_and_returns_this()
  39. {
  40. $config = new Config;
  41. $reader = $this->getMock('Kohana_Config_Reader');
  42. $this->assertSame($config, $config->attach($reader));
  43. $this->assertAttributeContains($reader, '_sources', $config);
  44. }
  45. /**
  46. * By default (or by passing TRUE as the second parameter) the config object
  47. * should prepend the reader to the front of the readers queue
  48. *
  49. * @test
  50. * @covers Config::attach
  51. */
  52. public function test_attach_adds_reader_to_front_of_queue()
  53. {
  54. $config = new Config;
  55. $reader1 = $this->getMock('Kohana_Config_Reader');
  56. $reader2 = $this->getMock('Kohana_Config_Reader');
  57. $config->attach($reader1);
  58. $config->attach($reader2);
  59. // Rather than do two assertContains we'll do an assertSame to assert
  60. // the order of the readers
  61. $this->assertAttributeSame(array($reader2, $reader1), '_sources', $config);
  62. // Now we test using the second parameter
  63. $config = new Config;
  64. $config->attach($reader1);
  65. $config->attach($reader2, TRUE);
  66. $this->assertAttributeSame(array($reader2, $reader1), '_sources', $config);
  67. }
  68. /**
  69. * Test that attaching a new reader (and passing FALSE as second param) causes
  70. * phpunit to append the reader rather than prepend
  71. *
  72. * @test
  73. * @covers Config::attach
  74. */
  75. public function test_attach_can_add_reader_to_end_of_queue()
  76. {
  77. $config = new Config;
  78. $reader1 = $this->getMock('Kohana_Config_Reader');
  79. $reader2 = $this->getMock('Kohana_Config_Reader');
  80. $config->attach($reader1);
  81. $config->attach($reader2, FALSE);
  82. $this->assertAttributeSame(array($reader1, $reader2), '_sources', $config);
  83. }
  84. /**
  85. * Calling detach() on a config object should remove it from the queue of readers
  86. *
  87. * @test
  88. * @covers Config::detach
  89. */
  90. public function test_detach_removes_reader_and_returns_this()
  91. {
  92. $config = new Config;
  93. // Due to the way phpunit mock generator works if you try and mock a class
  94. // that has already been used then it just re-uses the first's name
  95. // To get around this we have to specify a totally random name for the second mock object
  96. $reader1 = $this->getMock('Kohana_Config_Reader');
  97. $reader2 = $this->getMock('Kohana_Config_Reader', array(), array(), 'MY_AWESOME_READER');
  98. $config->attach($reader1);
  99. $config->attach($reader2);
  100. $this->assertSame($config, $config->detach($reader1));
  101. $this->assertAttributeNotContains($reader1, '_sources', $config);
  102. $this->assertAttributeContains($reader2, '_sources', $config);
  103. $this->assertSame($config, $config->detach($reader2));
  104. $this->assertAttributeNotContains($reader2, '_sources', $config);
  105. }
  106. /**
  107. * detach() should return $this even if the specified reader does not exist
  108. *
  109. * @test
  110. * @covers Config::detach
  111. */
  112. public function test_detach_returns_this_even_when_reader_dnx()
  113. {
  114. $config = new Config;
  115. $reader = $this->getMock('Kohana_Config_Reader');
  116. $this->assertSame($config, $config->detach($reader));
  117. }
  118. /**
  119. * If we request a config variable with a dot path then
  120. * Config::load() should load the group and return the requested variable
  121. *
  122. * @test
  123. * @covers Config::load
  124. */
  125. public function test_load_can_get_var_from_dot_path()
  126. {
  127. $config = new Config;
  128. $reader = $this->getMock('Kohana_Config_Reader', array('load'));
  129. $reader
  130. ->expects($this->once())
  131. ->method('load')
  132. ->with('beer')
  133. ->will($this->returnValue(array('stout' => 'Guinness')));
  134. $config->attach($reader);
  135. $this->assertSame('Guinness', $config->load('beer.stout'));
  136. }
  137. /**
  138. * If we've already loaded a config group then the correct variable
  139. * should be returned if we use the dot path notation to to request
  140. * a var
  141. *
  142. * @test
  143. * @covers Config::load
  144. */
  145. public function test_load_can_get_var_from_dot_path_for_loaded_group()
  146. {
  147. $config = new Config;
  148. $reader = $this->getMock('Kohana_Config_Reader', array('load'));
  149. $reader
  150. ->expects($this->once())
  151. ->method('load')
  152. ->with('beer')
  153. ->will($this->returnValue(array('stout' => 'Guinness')));
  154. $config->attach($reader);
  155. $config->load('beer');
  156. $this->assertSame('Guinness', $config->load('beer.stout'));
  157. }
  158. /**
  159. * If load() is called and there are no readers present then it should throw
  160. * a kohana exception
  161. *
  162. * @test
  163. * @covers Config::load
  164. * @expectedException Kohana_Exception
  165. */
  166. public function test_load_throws_exception_if_there_are_no_sources()
  167. {
  168. // The following code should throw an exception and phpunit will catch / handle it
  169. // (see the @expectedException doccomment)
  170. $config = new Kohana_config;
  171. $config->load('random');
  172. }
  173. /**
  174. * Provides test data for test_load_throws_exception_if_no_group_is_given()
  175. *
  176. * @return array
  177. */
  178. public function provider_load_throws_exception_if_no_group_is_given()
  179. {
  180. return array(
  181. array(NULL),
  182. array(''),
  183. array(array()),
  184. array(array('foo' => 'bar')),
  185. array(new StdClass),
  186. );
  187. }
  188. /**
  189. * If an invalid group name is specified then an exception should be thrown.
  190. *
  191. * Invalid means it's either a non-string value, or empty
  192. *
  193. * @test
  194. * @dataProvider provider_load_throws_exception_if_no_group_is_given
  195. * @covers Config::load
  196. * @expectedException Kohana_Exception
  197. */
  198. public function test_load_throws_exception_if_invalid_group($value)
  199. {
  200. $config = new Kohana_Config;
  201. $reader = $this->getMock('Kohana_Config_Reader');
  202. $config->attach($reader);
  203. $config->load($value);
  204. }
  205. /**
  206. * Make sure that _write_config() passes the changed configuration to all
  207. * writers in the queue
  208. *
  209. * @test
  210. * @covers Kohana_Config
  211. */
  212. public function test_write_config_passes_changed_config_to_all_writers()
  213. {
  214. $config = new Kohana_Config;
  215. $reader1 = $this->getMock('Kohana_Config_Reader');
  216. $writer1 = $this->getMock('Kohana_Config_Writer', array('write'));
  217. $writer2 = $this->getMock('Kohana_Config_Writer', array('write'));
  218. $writer1
  219. ->expects($this->once())
  220. ->method('write')
  221. ->with('some_group', 'key', 'value');
  222. $writer2
  223. ->expects($this->once())
  224. ->method('write')
  225. ->with('some_group', 'key', 'value');
  226. $config->attach($reader1)->attach($writer1)->attach($writer2);
  227. $config->_write_config('some_group', 'key', 'value');
  228. }
  229. /**
  230. * Config sources are stored in a stack, make sure that config at the bottom
  231. * of the stack is overriden by config at the top
  232. *
  233. * @test
  234. * @covers Config::load
  235. */
  236. public function test_config_is_loaded_from_top_to_bottom_of_stack()
  237. {
  238. $group_name = 'lolumns';
  239. $reader1 = $this->getMock('Kohana_Config_Reader', array('load'), array(), 'Unittest_Config_Reader_1');
  240. $reader2 = $this->getMock('Kohana_Config_Reader', array('load'), array(), 'Unittest_Config_Reader_2');
  241. $reader1
  242. ->expects($this->once())
  243. ->method('load')
  244. ->with($group_name)
  245. ->will($this->returnValue(array('foo' => 'bar', 'kohana' => 'awesome', 'life' => array('normal', 'fated'))));
  246. $reader2
  247. ->expects($this->once())
  248. ->method('load')
  249. ->with($group_name)
  250. ->will($this->returnValue(array('kohana' => 'sweet', 'music' => 'tasteful', 'life' => array('extraordinary', 'destined'))));
  251. $config = new Kohana_Config;
  252. // Attach $reader1 at the "top" and reader2 at the "bottom"
  253. $config->attach($reader1)->attach($reader2, FALSE);
  254. $this->assertSame(
  255. array(
  256. 'kohana' => 'awesome',
  257. 'music' => 'tasteful',
  258. 'life' => array(
  259. 'extraordinary',
  260. 'destined',
  261. 'normal',
  262. 'fated',
  263. ),
  264. 'foo' => 'bar',
  265. ),
  266. $config->load($group_name)->as_array()
  267. );
  268. }
  269. /**
  270. * load() should keep a record of what config groups have been requested and if
  271. * a group is requested more than once the first instance should be returned
  272. *
  273. * @test
  274. * @covers Config::load
  275. */
  276. public function test_load_reuses_config_groups()
  277. {
  278. $reader = $this->getMock('Kohana_Config_Reader', array('load'));
  279. $reader
  280. ->expects($this->once())
  281. ->method('load')
  282. ->with('something')
  283. ->will($this->returnValue(array()));
  284. $config = new Kohana_Config;
  285. $config->attach($reader);
  286. $group = $config->load('something');
  287. $this->assertSame($group, $config->load('something'));
  288. }
  289. /**
  290. * When we call copy() we expect it to copy the merged config to all writers
  291. *
  292. * @TODO This test sucks due to limitations in the phpunit mock generator. MAKE THIS AWESOME AGAIN!
  293. * @test
  294. * @covers Kohana_Config::copy
  295. */
  296. public function test_copy_copies_merged_config_to_all_writers()
  297. {
  298. $config = new Kohana_Config;
  299. $reader1 = $this->getMock('Kohana_Config_Reader', array('load'));
  300. $reader2 = $this->getMock('Kohana_Config_Reader', array('load'));
  301. $reader1
  302. ->expects($this->once())
  303. ->method('load')
  304. ->with('something')
  305. ->will($this->returnValue(array('pie' => 'good', 'kohana' => 'awesome')));
  306. $reader2
  307. ->expects($this->once())
  308. ->method('load')
  309. ->with('something')
  310. ->will($this->returnValue(array('kohana' => 'good')));
  311. $writer1 = $this->getMock('Kohana_Config_Writer', array('write'));
  312. $writer2 = $this->getMock('Kohana_Config_Writer', array('write'));
  313. // Due to crazy limitations in phpunit's mocking engine we have to be fairly
  314. // liberal here as to what order we receive the config items
  315. // Good news is that order shouldn't matter *yay*
  316. //
  317. // Now save your eyes and skip the next... 13 lines!
  318. $key = $this->logicalOr('pie', 'kohana');
  319. $val = $this->logicalOr('good', 'awesome');
  320. $writer1
  321. ->expects($this->exactly(2))
  322. ->method('write')
  323. ->with('something', clone $key, clone $val);
  324. $writer2
  325. ->expects($this->exactly(2))
  326. ->method('write')
  327. ->with('something', clone $key, clone $val);
  328. $config
  329. ->attach($reader1)->attach($reader2, FALSE)
  330. ->attach($writer1)->attach($writer2);
  331. // Now let's get this thing going!
  332. $config->copy('something');
  333. }
  334. }