diff --git a/src/Config/Settings.php b/src/Config/Settings.php index b2729fa..7ac4fdc 100644 --- a/src/Config/Settings.php +++ b/src/Config/Settings.php @@ -2,6 +2,7 @@ namespace CodeIgniter\Settings\Config; +use CodeIgniter\Settings\Handlers\ArrayHandler; use CodeIgniter\Settings\Handlers\DatabaseHandler; class Settings @@ -15,6 +16,14 @@ class Settings */ public $handlers = ['database']; + /** + * Array handler settings. + */ + public $array = [ + 'class' => ArrayHandler::class, + 'writeable' => true, + ]; + /** * Database handler settings. */ diff --git a/src/Handlers/ArrayHandler.php b/src/Handlers/ArrayHandler.php new file mode 100644 index 0000000..60b1cce --- /dev/null +++ b/src/Handlers/ArrayHandler.php @@ -0,0 +1,116 @@ + ['property' => ['value', 'type']]] + * + * @var array> + */ + private $general = []; + + /** + * Storage for context settings. + * Format: ['context' => ['class' => ['property' => ['value', 'type']]]] + * + * @var array + */ + private $contexts = []; + + public function has(string $class, string $property, ?string $context = null): bool + { + return $this->hasStored($class, $property, $context); + } + + public function get(string $class, string $property, ?string $context = null) + { + return $this->getStored($class, $property, $context); + } + + public function set(string $class, string $property, $value = null, ?string $context = null) + { + $this->setStored($class, $property, $value, $context); + } + + public function forget(string $class, string $property, ?string $context = null) + { + $this->forgetStored($class, $property, $context); + } + + /** + * Checks whether this value is in storage. + */ + protected function hasStored(string $class, string $property, ?string $context): bool + { + if ($context === null) { + return isset($this->general[$class]) + ? array_key_exists($property, $this->general[$class]) + : false; + } + + return isset($this->contexts[$context][$class]) + ? array_key_exists($property, $this->contexts[$context][$class]) + : false; + } + + /** + * Retrieves a value from storage. + * + * @return mixed|null + */ + protected function getStored(string $class, string $property, ?string $context) + { + if (! $this->has($class, $property, $context)) { + return null; + } + + return $context === null + ? $this->parseValue(...$this->general[$class][$property]) + : $this->parseValue(...$this->contexts[$context][$class][$property]); + } + + /** + * Adds values to storage. + * + * @param mixed $value + */ + protected function setStored(string $class, string $property, $value, ?string $context): void + { + $type = gettype($value); + $value = $this->prepareValue($value); + + if ($context === null) { + $this->general[$class][$property] = [ + $value, + $type, + ]; + } else { + $this->contexts[$context][$class][$property] = [ + $value, + $type, + ]; + } + } + + /** + * Deletes an item from storage. + */ + protected function forgetStored(string $class, string $property, ?string $context): void + { + if ($context === null) { + unset($this->general[$class][$property]); + } else { + unset($this->contexts[$context][$class][$property]); + } + } +} diff --git a/src/Handlers/DatabaseHandler.php b/src/Handlers/DatabaseHandler.php index bf67202..3351efe 100644 --- a/src/Handlers/DatabaseHandler.php +++ b/src/Handlers/DatabaseHandler.php @@ -6,10 +6,10 @@ use RuntimeException; /** - * Provides database storage for Settings. - * Uses local storage to minimize database calls. + * Provides database persistence for Settings. + * Uses ArrayHandler for storage to minimize database calls. */ -class DatabaseHandler extends BaseHandler +class DatabaseHandler extends ArrayHandler { /** * The database table to use. @@ -19,20 +19,11 @@ class DatabaseHandler extends BaseHandler private $table; /** - * Storage for cached general settings. - * Format: ['class' => ['property' => ['value', 'type']]] + * Array of contexts that have been stored. * - * @var array>|null Will be null until hydrated + * @var ?string[] */ - private $general; - - /** - * Storage for cached context settings. - * Format: ['context' => ['class' => ['property' => ['value', 'type']]]] - * - * @var array - */ - private $contexts = []; + private $hydrated = []; /** * Stores the configured database table. @@ -49,15 +40,7 @@ public function has(string $class, string $property, ?string $context = null): b { $this->hydrate($context); - if ($context === null) { - return isset($this->general[$class]) - ? array_key_exists($property, $this->general[$class]) - : false; - } - - return isset($this->contexts[$context][$class]) - ? array_key_exists($property, $this->contexts[$context][$class]) - : false; + return $this->hasStored($class, $property, $context); } /** @@ -70,13 +53,7 @@ public function has(string $class, string $property, ?string $context = null): b */ public function get(string $class, string $property, ?string $context = null) { - if (! $this->has($class, $property, $context)) { - return null; - } - - return $context === null - ? $this->parseValue(...$this->general[$class][$property]) - : $this->parseValue(...$this->contexts[$context][$class][$property]); + return $this->getStored($class, $property, $context); } /** @@ -90,9 +67,9 @@ public function get(string $class, string $property, ?string $context = null) */ public function set(string $class, string $property, $value = null, ?string $context = null) { - $time = Time::now()->format('Y-m-d H:i:s'); - $type = gettype($value); - $value = $this->prepareValue($value); + $time = Time::now()->format('Y-m-d H:i:s'); + $type = gettype($value); + $prepared = $this->prepareValue($value); // If it was stored then we need to update if ($this->has($class, $property, $context)) { @@ -101,7 +78,7 @@ public function set(string $class, string $property, $value = null, ?string $con ->where('key', $property) ->where('context', $context) ->update([ - 'value' => $value, + 'value' => $prepared, 'type' => $type, 'context' => $context, 'updated_at' => $time, @@ -112,7 +89,7 @@ public function set(string $class, string $property, $value = null, ?string $con ->insert([ 'class' => $class, 'key' => $property, - 'value' => $value, + 'value' => $prepared, 'type' => $type, 'context' => $context, 'created_at' => $time, @@ -120,23 +97,13 @@ public function set(string $class, string $property, $value = null, ?string $con ]); } - // Update storage - if ($result === true) { - if ($context === null) { - $this->general[$class][$property] = [ - $value, - $type, - ]; - } else { - $this->contexts[$context][$class][$property] = [ - $value, - $type, - ]; - } - } else { + if ($result !== true) { throw new RuntimeException(db_connect()->error()['message'] ?? 'Error writing to the database.'); } + // Update storage + $this->setStored($class, $property, $value, $context); + return $result; } @@ -160,47 +127,39 @@ public function forget(string $class, string $property, ?string $context = null) } // Delete from local storage - if ($context === null) { - unset($this->general[$class][$property]); - } else { - unset($this->contexts[$context][$class][$property]); - } + $this->forgetStored($class, $property, $context); return $result; } /** * Fetches values from the database in bulk to minimize calls. - * General is always fetched once, contexts are fetched in their - * entirety for each new request. + * General (null) is always fetched once, contexts are fetched + * in their entirety for each new request. * * @throws RuntimeException For database failures */ private function hydrate(?string $context) { + // Check for completion + if (in_array($context, $this->hydrated, true)) { + return; + } + if ($context === null) { - // Check for completion - if ($this->general !== null) { - return; - } + $this->hydrated[] = null; - $this->general = []; - $query = db_connect()->table($this->table)->where('context', null); + $query = db_connect()->table($this->table)->where('context', null); } else { - // Check for completion - if (isset($this->contexts[$context])) { - return; - } - $query = db_connect()->table($this->table)->where('context', $context); // If general has not been hydrated we will do that at the same time - if ($this->general === null) { - $this->general = []; + if (! in_array(null, $this->hydrated, true)) { + $this->hydrated[] = null; $query->orWhere('context', null); } - $this->contexts[$context] = []; + $this->hydrated[] = $context; } if (is_bool($result = $query->get())) { @@ -208,16 +167,7 @@ private function hydrate(?string $context) } foreach ($result->getResultObject() as $row) { - $tuple = [ - $row->value, - $row->type, - ]; - - if ($row->context === null) { - $this->general[$row->class][$row->key] = $tuple; - } else { - $this->contexts[$row->context][$row->class][$row->key] = $tuple; - } + $this->setStored($row->class, $row->key, $this->parseValue($row->value, $row->type), $row->context); } } } diff --git a/tests/DatabaseHandlerTest.php b/tests/DatabaseHandlerTest.php new file mode 100644 index 0000000..e322735 --- /dev/null +++ b/tests/DatabaseHandlerTest.php @@ -0,0 +1,236 @@ +handlers = ['database']; + + $this->settings = new Settings($config); + $this->table = $config->database['table']; + } + + public function testSetInsertsNewRows() + { + $results = $this->settings->set('Test.siteName', 'Foo'); + + $this->assertTrue($results); + $this->seeInDatabase($this->table, [ + 'class' => 'Tests\Support\Config\Test', + 'key' => 'siteName', + 'value' => 'Foo', + 'type' => 'string', + ]); + } + + public function testSetInsertsBoolTrue() + { + $results = $this->settings->set('Test.siteName', true); + + $this->assertTrue($results); + $this->seeInDatabase($this->table, [ + 'class' => 'Tests\Support\Config\Test', + 'key' => 'siteName', + 'value' => '1', + 'type' => 'boolean', + ]); + + $this->assertTrue($this->settings->get('Test.siteName')); + } + + public function testSetInsertsBoolFalse() + { + $results = $this->settings->set('Test.siteName', false); + + $this->assertTrue($results); + $this->seeInDatabase($this->table, [ + 'class' => 'Tests\Support\Config\Test', + 'key' => 'siteName', + 'value' => '0', + 'type' => 'boolean', + ]); + + $this->assertFalse($this->settings->get('Test.siteName')); + } + + public function testSetInsertsNull() + { + $results = $this->settings->set('Test.siteName', null); + + $this->assertTrue($results); + $this->seeInDatabase($this->table, [ + 'class' => 'Tests\Support\Config\Test', + 'key' => 'siteName', + 'value' => null, + 'type' => 'NULL', + ]); + + $this->assertNull($this->settings->get('Test.siteName')); + } + + public function testSetInsertsArray() + { + $data = ['foo' => 'bar']; + $results = $this->settings->set('Test.siteName', $data); + + $this->assertTrue($results); + $this->seeInDatabase($this->table, [ + 'class' => 'Tests\Support\Config\Test', + 'key' => 'siteName', + 'value' => serialize($data), + 'type' => 'array', + ]); + + $this->assertSame($data, $this->settings->get('Test.siteName')); + } + + public function testSetInsertsObject() + { + $data = (object) ['foo' => 'bar']; + $results = $this->settings->set('Test.siteName', $data); + + $this->assertTrue($results); + $this->seeInDatabase($this->table, [ + 'class' => 'Tests\Support\Config\Test', + 'key' => 'siteName', + 'value' => serialize($data), + 'type' => 'object', + ]); + + $this->assertSame((array) $data, (array) $this->settings->get('Test.siteName')); + } + + public function testSetUpdatesExistingRows() + { + $this->hasInDatabase($this->table, [ + 'class' => 'Tests\Support\Config\Test', + 'key' => 'siteName', + 'value' => 'foo', + 'created_at' => Time::now()->toDateTimeString(), + 'updated_at' => Time::now()->toDateTimeString(), + ]); + + $results = $this->settings->set('Test.siteName', 'Bar'); + + $this->assertTrue($results); + $this->seeInDatabase($this->table, [ + 'class' => 'Tests\Support\Config\Test', + 'key' => 'siteName', + 'value' => 'Bar', + ]); + } + + public function testWorksWithoutConfigClass() + { + $results = $this->settings->set('Nada.siteName', 'Bar'); + + $this->assertTrue($results); + $this->seeInDatabase($this->table, [ + 'class' => 'Nada', + 'key' => 'siteName', + 'value' => 'Bar', + ]); + + $this->assertSame('Bar', $this->settings->get('Nada.siteName')); + } + + public function testForgetSuccess() + { + $this->hasInDatabase($this->table, [ + 'class' => 'Tests\Support\Config\Test', + 'key' => 'siteName', + 'value' => 'foo', + 'created_at' => Time::now()->toDateTimeString(), + 'updated_at' => Time::now()->toDateTimeString(), + ]); + + $results = $this->settings->forget('Test.siteName'); + + $this->assertTrue($results); + $this->dontSeeInDatabase($this->table, [ + 'class' => 'Tests\Support\Config\Test', + 'key' => 'siteName', + ]); + } + + public function testForgetWithNoStoredRecord() + { + $results = $this->settings->forget('Test.siteName'); + + $this->assertTrue($results); + } + + public function testSetWithContext() + { + $results = $this->settings->set('Test.siteName', 'Banana', 'environment:test'); + + $this->assertTrue($results); + $this->seeInDatabase($this->table, [ + 'class' => 'Tests\Support\Config\Test', + 'key' => 'siteName', + 'value' => 'Banana', + 'type' => 'string', + 'context' => 'environment:test', + ]); + } + + /** + * @see https://github.com/codeigniter4/settings/issues/20 + */ + public function testSetUpdatesContextOnly() + { + $this->settings->set('Test.siteName', 'Humpty'); + $this->settings->set('Test.siteName', 'Jack', 'context:male'); + $this->settings->set('Test.siteName', 'Jill', 'context:female'); + $this->settings->set('Test.siteName', 'Jane', 'context:female'); + + $this->seeInDatabase($this->table, [ + 'class' => 'Tests\Support\Config\Test', + 'key' => 'siteName', + 'value' => 'Jane', + 'type' => 'string', + 'context' => 'context:female', + ]); + + $this->seeInDatabase($this->table, [ + 'class' => 'Tests\Support\Config\Test', + 'key' => 'siteName', + 'value' => 'Humpty', + 'type' => 'string', + 'context' => null, + ]); + $this->seeInDatabase($this->table, [ + 'class' => 'Tests\Support\Config\Test', + 'key' => 'siteName', + 'value' => 'Jack', + 'type' => 'string', + 'context' => 'context:male', + ]); + } +} diff --git a/tests/HelperTest.php b/tests/HelperTest.php index 3ac49e2..a058c00 100644 --- a/tests/HelperTest.php +++ b/tests/HelperTest.php @@ -2,7 +2,6 @@ namespace CodeIgniter4\Tests; -use CodeIgniter\I18n\Time; use CodeIgniter\Settings\Settings; use CodeIgniter\Test\DatabaseTestTrait; use Tests\Support\TestCase; @@ -38,50 +37,24 @@ public function testSetsNull() { setting('Foo.bam', null); - $this->seeInDatabase($this->table, [ - 'class' => 'Foo', - 'key' => 'bam', - 'value' => null, - 'type' => 'NULL', - ]); - + $this->assertNull(service('settings')->get('Foo.bam')); $this->assertNull(setting('Foo.bam')); } public function testReturnsValueDotArray() { - $this->hasInDatabase($this->table, [ - 'class' => 'Foo', - 'key' => 'bar', - 'value' => 'baz', - 'type' => 'string', - 'created_at' => Time::now()->toDateTimeString(), - 'updated_at' => Time::now()->toDateTimeString(), - ]); + service('settings')->set('Foo.bar', 'baz'); $this->assertSame('baz', setting('Foo.bar')); } public function testSettingValueDotArray() { - $this->hasInDatabase($this->table, [ - 'class' => 'Foo', - 'key' => 'bar', - 'value' => 'baz', - 'type' => 'string', - 'created_at' => Time::now()->toDateTimeString(), - 'updated_at' => Time::now()->toDateTimeString(), - ]); + service('settings')->set('Foo.bar', 'baz'); setting('Foo.bar', false); - $this->seeInDatabase($this->table, [ - 'class' => 'Foo', - 'key' => 'bar', - 'value' => '0', - 'type' => 'boolean', - ]); - + $this->assertFalse(service('settings')->get('Foo.bar')); $this->assertFalse(setting('Foo.bar')); } } diff --git a/tests/SettingsTest.php b/tests/SettingsTest.php index bcdc36a..2c72d51 100644 --- a/tests/SettingsTest.php +++ b/tests/SettingsTest.php @@ -2,20 +2,15 @@ namespace Tests; -use CodeIgniter\I18n\Time; use CodeIgniter\Settings\Settings; -use CodeIgniter\Test\DatabaseTestTrait; +use Config\Services; use Tests\Support\TestCase; /** - * NOTE: $this->table is set in the TestCase itself - * * @internal */ final class SettingsTest extends TestCase { - use DatabaseTestTrait; - public function testSettingsUsesParameter() { $config = config('Settings'); @@ -27,271 +22,52 @@ public function testSettingsUsesParameter() $this->assertSame([], $result); } - public function testSettingsGetsFromConfig() - { - $settings = new Settings(config('Settings')); - - $this->assertSame(config('Test')->siteName, $settings->get('Test.siteName')); - } - - public function testSettingsDatabaseNotFound() - { - $settings = new Settings(config('Settings')); - - $this->assertSame(config('Test')->siteName, $settings->get('Test.siteName')); - } - - public function testSetInsertsNewRows() - { - $settings = new Settings(config('Settings')); - - $results = $settings->set('Test.siteName', 'Foo'); - - $this->assertTrue($results); - $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', - 'key' => 'siteName', - 'value' => 'Foo', - 'type' => 'string', - ]); - } - - public function testSetInsertsBoolTrue() - { - $settings = new Settings(config('Settings')); - - $results = $settings->set('Test.siteName', true); - - $this->assertTrue($results); - $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', - 'key' => 'siteName', - 'value' => '1', - 'type' => 'boolean', - ]); - - $this->assertTrue($settings->get('Test.siteName')); - } - - public function testSetInsertsBoolFalse() - { - $settings = new Settings(config('Settings')); - - $results = $settings->set('Test.siteName', false); - - $this->assertTrue($results); - $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', - 'key' => 'siteName', - 'value' => '0', - 'type' => 'boolean', - ]); - - $this->assertFalse($settings->get('Test.siteName')); - } - - public function testSetInsertsNull() + public function testServiceUsesConfig() { - $settings = new Settings(config('Settings')); - - $results = $settings->set('Test.siteName', null); - - $this->assertTrue($results); - $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', - 'key' => 'siteName', - 'value' => null, - 'type' => 'NULL', - ]); + Services::resetSingle('settings'); - $this->assertNull($settings->get('Test.siteName')); - } - - public function testSetInsertsArray() - { - $settings = new Settings(config('Settings')); - $data = ['foo' => 'bar']; - - $results = $settings->set('Test.siteName', $data); - - $this->assertTrue($results); - $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', - 'key' => 'siteName', - 'value' => serialize($data), - 'type' => 'array', - ]); - - $this->assertSame($data, $settings->get('Test.siteName')); - } - - public function testSetInsertsObject() - { - $settings = new Settings(config('Settings')); - $data = (object) ['foo' => 'bar']; - - $results = $settings->set('Test.siteName', $data); - - $this->assertTrue($results); - $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', - 'key' => 'siteName', - 'value' => serialize($data), - 'type' => 'object', - ]); - - $this->assertSame((array) $data, (array) $settings->get('Test.siteName')); - } - - public function testSetUpdatesExistingRows() - { - $settings = new Settings(config('Settings')); - - $this->hasInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', - 'key' => 'siteName', - 'value' => 'foo', - 'created_at' => Time::now()->toDateTimeString(), - 'updated_at' => Time::now()->toDateTimeString(), - ]); - - $results = $settings->set('Test.siteName', 'Bar'); - - $this->assertTrue($results); - $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', - 'key' => 'siteName', - 'value' => 'Bar', - ]); - } - - public function testWorksWithoutConfigClass() - { - $settings = new Settings(config('Settings')); - - $results = $settings->set('Nada.siteName', 'Bar'); - - $this->assertTrue($results); - $this->seeInDatabase($this->table, [ - 'class' => 'Nada', - 'key' => 'siteName', - 'value' => 'Bar', - ]); - - $this->assertSame('Bar', $settings->get('Nada.siteName')); - } - - public function testForgetSuccess() - { - $settings = new Settings(config('Settings')); - - $this->hasInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', - 'key' => 'siteName', - 'value' => 'foo', - 'created_at' => Time::now()->toDateTimeString(), - 'updated_at' => Time::now()->toDateTimeString(), - ]); + $config = config('Settings'); + $config->handlers = []; - $results = $settings->forget('Test.siteName'); + $settings = service('settings'); + $result = $this->getPrivateProperty($settings, 'handlers'); - $this->assertTrue($results); - $this->dontSeeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', - 'key' => 'siteName', - ]); + $this->assertSame([], $result); } - public function testForgetWithNoStoredRecord() + public function testSettingsGetsFromConfig() { - $settings = new Settings(config('Settings')); - - $results = $settings->forget('Test.siteName'); - - $this->assertTrue($results); + $this->assertSame(config('Test')->siteName, $this->settings->get('Test.siteName')); } - public function testSetWithContext() + public function testSettingsNotFound() { - $settings = new Settings(config('Settings')); - - $results = $settings->set('Test.siteName', 'Banana', 'environment:test'); - - $this->assertTrue($results); - $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', - 'key' => 'siteName', - 'value' => 'Banana', - 'type' => 'string', - 'context' => 'environment:test', - ]); + $this->assertSame(config('Test')->siteName, $this->settings->get('Test.siteName')); } public function testGetWithContext() { - $settings = new Settings(config('Settings')); + $this->settings->set('Test.siteName', 'NoContext'); + $this->settings->set('Test.siteName', 'YesContext', 'testing:true'); - $settings->set('Test.siteName', 'NoContext'); - $settings->set('Test.siteName', 'YesContext', 'testing:true'); - - $this->assertSame('NoContext', $settings->get('Test.siteName')); - $this->assertSame('YesContext', $settings->get('Test.siteName', 'testing:true')); + $this->assertSame('NoContext', $this->settings->get('Test.siteName')); + $this->assertSame('YesContext', $this->settings->get('Test.siteName', 'testing:true')); } public function testGetWithoutContextUsesGlobal() { - $settings = new Settings(config('Settings')); - - $settings->set('Test.siteName', 'NoContext'); + $this->settings->set('Test.siteName', 'NoContext'); - $this->assertSame('NoContext', $settings->get('Test.siteName', 'testing:true')); + $this->assertSame('NoContext', $this->settings->get('Test.siteName', 'testing:true')); } public function testForgetWithContext() { - $settings = new Settings(config('Settings')); - - $settings->set('Test.siteName', 'Bar'); - $settings->set('Test.siteName', 'Amnesia', 'category:disease'); - - $settings->forget('Test.siteName', 'category:disease'); - - $this->assertSame('Bar', $settings->get('Test.siteName', 'category:disease')); - } - - /** - * @see https://github.com/codeigniter4/settings/issues/20 - */ - public function testSetUpdatesContextOnly() - { - $settings = new Settings(config('Settings')); - - $settings->set('Test.siteName', 'Humpty'); - $settings->set('Test.siteName', 'Jack', 'context:male'); - $settings->set('Test.siteName', 'Jill', 'context:female'); - $settings->set('Test.siteName', 'Jane', 'context:female'); + $this->settings->set('Test.siteName', 'Bar'); + $this->settings->set('Test.siteName', 'Amnesia', 'category:disease'); - $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', - 'key' => 'siteName', - 'value' => 'Jane', - 'type' => 'string', - 'context' => 'context:female', - ]); + $this->settings->forget('Test.siteName', 'category:disease'); - $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', - 'key' => 'siteName', - 'value' => 'Humpty', - 'type' => 'string', - 'context' => null, - ]); - $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', - 'key' => 'siteName', - 'value' => 'Jack', - 'type' => 'string', - 'context' => 'context:male', - ]); + $this->assertSame('Bar', $this->settings->get('Test.siteName', 'category:disease')); } } diff --git a/tests/_support/TestCase.php b/tests/_support/TestCase.php index b64ffd5..ba2d39b 100644 --- a/tests/_support/TestCase.php +++ b/tests/_support/TestCase.php @@ -2,26 +2,33 @@ namespace Tests\Support; +use CodeIgniter\Settings\Handlers\ArrayHandler; +use CodeIgniter\Settings\Settings; use CodeIgniter\Test\CIUnitTestCase; +use Config\Services; use Nexus\PHPUnit\Extension\Expeditable; abstract class TestCase extends CIUnitTestCase { use Expeditable; - protected $namespace = 'CodeIgniter\Settings'; - protected $refresh = true; - /** - * @var string + * @var Settings */ - protected $table; + protected $settings; + /** + * Sets up the ArrayHandler for faster & easier tests. + */ protected function setUp(): void { parent::setUp(); - $this->table = config('Settings')->database['table']; + $config = config('Settings'); + $config->handlers = ['array']; + $this->settings = new Settings($config); + + Services::injectMock('settings', $this->settings); } protected function tearDown(): void