ConfigTest.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <?php
  2. namespace think\tests;
  3. use org\bovigo\vfs\vfsStream;
  4. use PHPUnit\Framework\TestCase;
  5. use think\Config;
  6. class ConfigTest extends TestCase
  7. {
  8. public function testLoad()
  9. {
  10. $root = vfsStream::setup();
  11. $file = vfsStream::newFile('test.php')->setContent("<?php return ['key1'=> 'value1','key2'=>'value2'];");
  12. $root->addChild($file);
  13. $config = new Config();
  14. $config->load($file->url(), 'test');
  15. $this->assertEquals('value1', $config->get('test.key1'));
  16. $this->assertEquals('value2', $config->get('test.key2'));
  17. $this->assertSame(['key1' => 'value1', 'key2' => 'value2'], $config->get('test'));
  18. }
  19. public function testSetAndGet()
  20. {
  21. $config = new Config();
  22. $config->set([
  23. 'key1' => 'value1',
  24. 'key2' => [
  25. 'key3' => 'value3',
  26. ],
  27. ], 'test');
  28. $this->assertTrue($config->has('test.key1'));
  29. $this->assertEquals('value1', $config->get('test.key1'));
  30. $this->assertEquals('value3', $config->get('test.key2.key3'));
  31. $this->assertEquals(['key3' => 'value3'], $config->get('test.key2'));
  32. $this->assertFalse($config->has('test.key3'));
  33. $this->assertEquals('none', $config->get('test.key3', 'none'));
  34. }
  35. public function testGlobalHook()
  36. {
  37. $config = new Config();
  38. // Set initial config
  39. $config->set(['key1' => 'original_value'], 'test');
  40. // Register global hook
  41. $config->hook(function ($name, $value) {
  42. if ($name === 'test.key1') {
  43. return 'hooked_value';
  44. }
  45. if ($name === 'test.key2' && is_null($value)) {
  46. return 'default_from_hook';
  47. }
  48. return $value;
  49. });
  50. // Test hook modifies existing value
  51. $this->assertEquals('hooked_value', $config->get('test.key1'));
  52. // Test hook provides default for non-existent key
  53. $this->assertEquals('default_from_hook', $config->get('test.key2'));
  54. // Test hook returns original value for other keys
  55. $config->set(['key3' => 'unchanged'], 'test');
  56. $this->assertEquals('unchanged', $config->get('test.key3'));
  57. }
  58. public function testSpecificKeyHook()
  59. {
  60. $config = new Config();
  61. // Set initial config
  62. $config->set([
  63. 'key1' => 'value1',
  64. 'key2' => 'value2'
  65. ], 'test');
  66. $config->set([
  67. 'key1' => 'value1'
  68. ], 'other');
  69. // Register hook for specific key 'test'
  70. $config->hook(function ($name, $value) {
  71. if (str_contains($name, 'key1')) {
  72. return 'test_hooked_' . $value;
  73. }
  74. return $value;
  75. }, 'test');
  76. // Register hook for specific key 'other'
  77. $config->hook(function ($name, $value) {
  78. if (str_contains($name, 'key1')) {
  79. return 'other_hooked_' . $value;
  80. }
  81. return $value;
  82. }, 'other');
  83. // Test specific hook for 'test' configuration
  84. $this->assertEquals('test_hooked_value1', $config->get('test.key1'));
  85. $this->assertEquals('value2', $config->get('test.key2')); // No hook for key2
  86. // Test specific hook for 'other' configuration
  87. $this->assertEquals('other_hooked_value1', $config->get('other.key1'));
  88. }
  89. public function testHookPriority()
  90. {
  91. $config = new Config();
  92. // Set initial config
  93. $config->set(['key1' => 'value1'], 'test');
  94. // Register global hook first
  95. $config->hook(function ($name, $value) {
  96. return 'global_' . $value;
  97. });
  98. // Register specific key hook (should override global)
  99. $config->hook(function ($name, $value) {
  100. return 'specific_' . $value;
  101. }, 'test');
  102. // Specific hook should take priority over global hook
  103. $this->assertEquals('specific_value1', $config->get('test.key1'));
  104. }
  105. public function testHookWithNullReturn()
  106. {
  107. $config = new Config();
  108. // Register hook that returns null
  109. $config->hook(function ($name, $value) {
  110. if ($name === 'test.nonexistent') {
  111. return null; // This should trigger default value
  112. }
  113. return $value;
  114. });
  115. // Test with default value when hook returns null
  116. $this->assertEquals('default_value', $config->get('test.nonexistent', 'default_value'));
  117. }
  118. public function testHookWithTopLevelConfig()
  119. {
  120. $config = new Config();
  121. // Set top-level config
  122. $config->set(['key1' => 'value1', 'key2' => 'value2'], 'database');
  123. // Register hook for database config
  124. $config->hook(function ($name, $value) {
  125. if ($name === 'database') {
  126. return array_merge($value, ['key3' => 'added_by_hook']);
  127. }
  128. return $value;
  129. }, 'database');
  130. // Test hook modifies entire config section
  131. $result = $config->get('database');
  132. $this->assertIsArray($result);
  133. $this->assertEquals('value1', $result['key1']);
  134. $this->assertEquals('value2', $result['key2']);
  135. $this->assertEquals('added_by_hook', $result['key3']);
  136. }
  137. public function testLazyLoadingBehavior()
  138. {
  139. $config = new Config();
  140. // Counter to verify hook is called
  141. $hookCallCount = 0;
  142. // Register hook with counter
  143. $config->hook(function ($name, $value) use (&$hookCallCount) {
  144. $hookCallCount++;
  145. return $value ? $value . '_processed' : 'processed_default';
  146. });
  147. // Set config value
  148. $config->set(['key1' => 'value1'], 'test');
  149. // First call should trigger hook
  150. $result1 = $config->get('test.key1');
  151. $this->assertEquals('value1_processed', $result1);
  152. $this->assertEquals(1, $hookCallCount);
  153. // Second call should also trigger hook (no caching)
  154. $result2 = $config->get('test.key1');
  155. $this->assertEquals('value1_processed', $result2);
  156. $this->assertEquals(2, $hookCallCount);
  157. // Test with non-existent key
  158. $result3 = $config->get('test.nonexistent', 'default');
  159. $this->assertEquals('processed_default', $result3);
  160. $this->assertEquals(3, $hookCallCount);
  161. }
  162. }