diff --git a/src/Application/Base.php b/src/Application/Base.php index 710ccb1..24e35a3 100644 --- a/src/Application/Base.php +++ b/src/Application/Base.php @@ -717,7 +717,16 @@ protected function initSettings( ?ISettingSource $source ): void try { - $this->_settings = new SettingManager( $source ); + // If source is already a SettingManager, use it directly (avoids double-wrapping) + // Otherwise wrap the raw source in a SettingManager (backward compatibility) + if( $source instanceof SettingManager ) + { + $this->_settings = $source; + } + else + { + $this->_settings = new SettingManager( $source ); + } $basePath = $this->getSetting( 'system','base_path' ) ?? $defaultBasePath; $fallback = new Env( Data\Env::getInstance( "$basePath/.env" ) ); diff --git a/tests/Application/ApplicationTest.php b/tests/Application/ApplicationTest.php index a7e718c..ca6e743 100644 --- a/tests/Application/ApplicationTest.php +++ b/tests/Application/ApplicationTest.php @@ -534,5 +534,62 @@ public function testInitSettingsUsesEnvVariable() $this->assertNotNull($app->getSettingManager()); } + + public function testInitSettingsWithSettingManagerUsesItDirectly() + { + // Clear registry + Registry::getInstance()->set(RegistryKeys::SETTINGS, null); + + // Create a SettingManager with a raw source + $rawSource = new Ini('examples/config/application.ini'); + $settingManager = new \Neuron\Data\Settings\SettingManager($rawSource); + + // Pass the SettingManager to the app + $app = new AppMock("2.0", $settingManager); + + // The app should use the SettingManager directly (not wrap it again) + $appSettings = $app->getSettingManager(); + $this->assertSame($settingManager, $appSettings); + + // Verify we don't have double-wrapping by checking the internal source + // If double-wrapped, getSource() would return a SettingManager instead of the raw Ini + $this->assertInstanceOf(Ini::class, $appSettings->getSource()); + $this->assertNotInstanceOf(\Neuron\Data\Settings\SettingManager::class, $appSettings->getSource()); + } + + public function testInitSettingsWithRawSourceWrapsIt() + { + // Clear registry + Registry::getInstance()->set(RegistryKeys::SETTINGS, null); + + // Pass a raw source (not a SettingManager) + $rawSource = new Ini('examples/config/application.ini'); + $app = new AppMock("2.0", $rawSource); + + // The app should wrap it in a SettingManager + $appSettings = $app->getSettingManager(); + $this->assertInstanceOf(\Neuron\Data\Settings\SettingManager::class, $appSettings); + + // Verify the raw source is wrapped + $this->assertInstanceOf(Ini::class, $appSettings->getSource()); + } + + public function testInitSettingsSetsEnvFallbackWhenNoneProvided() + { + // Clear registry + Registry::getInstance()->set(RegistryKeys::SETTINGS, null); + + // Create a SettingManager without a fallback + $rawSource = new Ini('examples/config/application.ini'); + $settingManager = new \Neuron\Data\Settings\SettingManager($rawSource); + + // Pass the SettingManager to the app + $app = new AppMock("2.0", $settingManager); + + // The app should set a fallback (env variables) + $appSettings = $app->getSettingManager(); + $this->assertNotNull($appSettings->getFallback()); + $this->assertInstanceOf(\Neuron\Data\Settings\Source\Env::class, $appSettings->getFallback()); + } } diff --git a/versionlog.md b/versionlog.md index 9dcca0a..63d82f3 100644 --- a/versionlog.md +++ b/versionlog.md @@ -1,16 +1,14 @@ ## 0.8.16 +* Fix to support setting managers or sources correctly without incurring a manager that contains a manager. ## 0.8.15 2026-01-13 - ## 0.8.14 2026-01-12 - ## 0.8.13 2026-01-06 ## 0.8.12 2026-01-01 * Added psr-11 container support. ## 0.8.11 2025-12-26 - ## 0.8.10 2025-11-28 ## 0.8.9 2025-11-27 @@ -25,20 +23,16 @@ * Renamed config.yaml to neuron.yaml ## 0.8.5 2025-11-11 - ## 0.8.4 2025-11-10 - ## 0.8.3 2025-11-10 * Improved error handling. ## 0.8.2 2025-11-08 - ## 0.8.1 2025-11-06 * Added getSettingManager() method to provide access to SettingManager instance ## 0.7.1 2025-11-04 - ## 0.7.0 2025-08-14 * Refactored get/set setting methods. @@ -46,9 +40,7 @@ * Added the Crashed state. ## 0.6.32 2025-05-21 - ## 0.6.31 - ## 0.6.30 2025-02-06 * Transitioned from core package to application.