diff --git a/.github/workflows/deptrac.yml b/.github/workflows/deptrac.yml index ebaf4df..f481772 100644 --- a/.github/workflows/deptrac.yml +++ b/.github/workflows/deptrac.yml @@ -20,4 +20,4 @@ on: jobs: deptrac: - uses: codeigniter4/.github/.github/workflows/deptrac.yml@main + uses: codeigniter4/.github/.github/workflows/deptrac.yml@CI46 diff --git a/.github/workflows/phpcpd.yml b/.github/workflows/phpcpd.yml index 8ef9e2f..ce66866 100644 --- a/.github/workflows/phpcpd.yml +++ b/.github/workflows/phpcpd.yml @@ -16,6 +16,6 @@ on: jobs: phpcpd: - uses: codeigniter4/.github/.github/workflows/phpcpd.yml@main + uses: codeigniter4/.github/.github/workflows/phpcpd.yml@CI46 with: dirs: "src/ tests/" diff --git a/.github/workflows/phpcsfixer.yml b/.github/workflows/phpcsfixer.yml index ee1221a..773c0dc 100644 --- a/.github/workflows/phpcsfixer.yml +++ b/.github/workflows/phpcsfixer.yml @@ -16,4 +16,4 @@ on: jobs: phpcsfixer: - uses: codeigniter4/.github/.github/workflows/phpcsfixer.yml@main + uses: codeigniter4/.github/.github/workflows/phpcsfixer.yml@CI46 diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 58e2add..01d9b36 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -20,4 +20,4 @@ on: jobs: phpstan: - uses: codeigniter4/.github/.github/workflows/phpstan.yml@main + uses: codeigniter4/.github/.github/workflows/phpstan.yml@CI46 diff --git a/.github/workflows/phpunit-lowest.yml b/.github/workflows/phpunit-lowest.yml index 242a898..f9a81c7 100644 --- a/.github/workflows/phpunit-lowest.yml +++ b/.github/workflows/phpunit-lowest.yml @@ -20,4 +20,4 @@ on: jobs: phpunit: - uses: codeigniter4/.github/.github/workflows/phpunit-lowest.yml@main + uses: codeigniter4/.github/.github/workflows/phpunit-lowest.yml@CI46 diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 9bcd5ec..68b9dbc 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -20,4 +20,4 @@ on: jobs: phpunit: - uses: codeigniter4/.github/.github/workflows/phpunit.yml@main + uses: codeigniter4/.github/.github/workflows/phpunit.yml@CI46 diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml index 53c76e7..cf704fd 100644 --- a/.github/workflows/psalm.yml +++ b/.github/workflows/psalm.yml @@ -20,4 +20,4 @@ on: jobs: psalm: - uses: codeigniter4/.github/.github/workflows/psalm.yml@main + uses: codeigniter4/.github/.github/workflows/psalm.yml@CI46 diff --git a/.github/workflows/rector.yml b/.github/workflows/rector.yml index 8c19b16..9a60447 100644 --- a/.github/workflows/rector.yml +++ b/.github/workflows/rector.yml @@ -20,4 +20,4 @@ on: jobs: rector: - uses: codeigniter4/.github/.github/workflows/rector.yml@main + uses: codeigniter4/.github/.github/workflows/rector.yml@CI46 diff --git a/.github/workflows/unused.yml b/.github/workflows/unused.yml index 1758dda..5695e90 100644 --- a/.github/workflows/unused.yml +++ b/.github/workflows/unused.yml @@ -18,4 +18,4 @@ on: jobs: unused: - uses: codeigniter4/.github/.github/workflows/unused.yml@main + uses: codeigniter4/.github/.github/workflows/unused.yml@CI46 diff --git a/README.md b/README.md index 16ecd1c..9f7e782 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ config classes for CodeIgniter 4 framework. [![](https://github.com/codeigniter4/settings/workflows/Deptrac/badge.svg)](https://github.com/codeigniter4/settings/actions/workflows/inspect.yml) [![Coverage Status](https://coveralls.io/repos/github/codeigniter4/settings/badge.svg?branch=develop)](https://coveralls.io/github/codeigniter4/settings?branch=develop) -![PHP](https://img.shields.io/badge/PHP-%5E7.4-blue) +![PHP](https://img.shields.io/badge/PHP-%5E8.1-blue) ![CodeIgniter](https://img.shields.io/badge/CodeIgniter-%5E4.2.3-blue) ![License](https://img.shields.io/badge/License-MIT-blue) diff --git a/composer.json b/composer.json index ab76dd0..79ed4cf 100644 --- a/composer.json +++ b/composer.json @@ -17,14 +17,11 @@ ], "homepage": "https://github.com/codeigniter4/settings", "require": { - "php": "^7.4 || ^8.0" + "php": "^8.1" }, "require-dev": { - "codeigniter/coding-standard": "1.7.*", - "codeigniter4/devkit": "^1.1.2", - "codeigniter4/framework": "^4.2.3", - "phpunit/phpunit": "^9.6", - "rector/rector": "1.2.8" + "codeigniter4/devkit": "^1.3", + "codeigniter4/framework": "^4.2.3" }, "minimum-stability": "dev", "prefer-stable": true, diff --git a/docs/index.md b/docs/index.md index 373dd63..abe0333 100644 --- a/docs/index.md +++ b/docs/index.md @@ -29,7 +29,7 @@ service('settings')->forget('App.siteName'); ### Requirements -![PHP](https://img.shields.io/badge/PHP-%5E7.4-red) +![PHP](https://img.shields.io/badge/PHP-%5E8.1-red) ![CodeIgniter](https://img.shields.io/badge/CodeIgniter-%5E4.2.3-red) ### Acknowledgements diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..8018c72 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,13 @@ +parameters: + ignoreErrors: + - + message: '#^Offset string does not exist on list\\.$#' + identifier: offsetAccess.notFound + count: 1 + path: src/Settings.php + + - + message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) with ''CodeIgniter\\\\Settings\\\\Settings'' and CodeIgniter\\Settings\\Settings will always evaluate to true\.$#' + identifier: method.alreadyNarrowedType + count: 1 + path: tests/HelperTest.php diff --git a/phpstan.neon.dist b/phpstan.neon.dist index f27f414..94a3657 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,22 +1,21 @@ +includes: + - phpstan-baseline.neon parameters: - tmpDir: build/phpstan - level: 5 - paths: - - src/ - - tests/ - bootstrapFiles: - - vendor/codeigniter4/framework/system/Test/bootstrap.php - excludePaths: - - src/Config/Routes.php - - src/Views/* - ignoreErrors: - universalObjectCratesClasses: - - CodeIgniter\Entity - - CodeIgniter\Entity\Entity - - Faker\Generator - scanDirectories: - - vendor/codeigniter4/framework/system/Helpers - dynamicConstantNames: - - APP_NAMESPACE - - CI_DEBUG - - ENVIRONMENT + tmpDir: build/phpstan + level: 5 + paths: + - src/ + - tests/ + bootstrapFiles: + - vendor/codeigniter4/framework/system/Test/bootstrap.php + excludePaths: + universalObjectCratesClasses: + - CodeIgniter\Entity + - CodeIgniter\Entity\Entity + - Faker\Generator + scanDirectories: + - vendor/codeigniter4/framework/system/Helpers + dynamicConstantNames: + - APP_NAMESPACE + - CI_DEBUG + - ENVIRONMENT diff --git a/phpunit.xml.dist b/phpunit.xml.dist index ac88cfc..c4ddfec 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,102 +1,83 @@ + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" + bootstrap="vendor/codeigniter4/framework/system/Test/bootstrap.php" + backupGlobals="false" + beStrictAboutOutputDuringTests="true" + colors="true" + executionOrder="random" + failOnRisky="true" + failOnWarning="true" + stopOnError="false" + stopOnFailure="false" + stopOnIncomplete="false" + stopOnSkipped="false" + cacheDirectory="build/.phpunit.cache" + beStrictAboutCoverageMetadata="true"> - - - ./src/ - - - ./src/Config - ./src/Views - - - - - - - - - + + + + + + + + + - - - ./tests - - + + + ./tests + + - - - - - - 0.50 - - - 30 - - - 2 - - - true - - - true - - - - - + + + + + + + - - - - - + + + + + - - - + + + - - + + - - + + - - + + - - + + - - - - + + + + + + + ./src/ + + + ./src/Config + + diff --git a/psalm.xml b/psalm.xml index df72f6d..6b0fb24 100644 --- a/psalm.xml +++ b/psalm.xml @@ -11,6 +11,7 @@ errorBaseline="psalm-baseline.xml" findUnusedBaselineEntry="false" findUnusedCode="false" + ensureOverrideAttribute="false" > diff --git a/rector.php b/rector.php index c999c21..d6575f1 100644 --- a/rector.php +++ b/rector.php @@ -1,5 +1,16 @@ + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + use Rector\CodeQuality\Rector\BooleanAnd\SimplifyEmptyArrayCheckRector; use Rector\CodeQuality\Rector\Expression\InlineIfToExplicitIfRector; use Rector\CodeQuality\Rector\Foreach_\UnusedForeachValueToArrayKeysRector; @@ -89,9 +100,5 @@ $rectorConfig->rule(FuncGetArgsToVariadicParamRector::class); $rectorConfig->rule(MakeInheritedMethodVisibilitySameAsParentRector::class); $rectorConfig->rule(SimplifyEmptyArrayCheckRector::class); - $rectorConfig - ->ruleWithConfiguration(TypedPropertyFromAssignsRector::class, [ - // Set to false if you use in libraries, or it does create breaking changes. - TypedPropertyFromAssignsRector::INLINE_PUBLIC => false, - ]); + $rectorConfig->rule(TypedPropertyFromAssignsRector::class); }; diff --git a/src/Handlers/BaseHandler.php b/src/Handlers/BaseHandler.php index 861588f..d8b01a5 100644 --- a/src/Handlers/BaseHandler.php +++ b/src/Handlers/BaseHandler.php @@ -156,7 +156,7 @@ protected function isSerialized($data, $strict = true): bool if ('"' !== substr($data, -2, 1)) { return false; } - } elseif (false === strpos($data, '"')) { + } elseif (! str_contains($data, '"')) { return false; } diff --git a/src/Settings.php b/src/Settings.php index da4bbe7..cd4e577 100644 --- a/src/Settings.php +++ b/src/Settings.php @@ -170,7 +170,7 @@ private function prepareClassAndProperty(string $key): array // Use a fully qualified class name if the // config file was found. if ($config !== null) { - $class = get_class($config); + $class = $config::class; } return [$class, $property, $config]; diff --git a/tests/DatabaseHandlerTest.php b/tests/DatabaseHandlerTest.php index 691ff15..7e77682 100644 --- a/tests/DatabaseHandlerTest.php +++ b/tests/DatabaseHandlerTest.php @@ -46,10 +46,10 @@ protected function setUp(): void public function testSetInsertsNewRows() { - $this->settings->set('Test.siteName', 'Foo'); + $this->settings->set('Example.siteName', 'Foo'); $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', 'value' => 'Foo', 'type' => 'string', @@ -67,7 +67,7 @@ public function testInvalidGroup() $this->settings = new Settings($config); - $this->settings->set('Test.siteName', true); + $this->settings->set('Example.siteName', true); } public function testSetDefaultGroup() @@ -77,104 +77,104 @@ public function testSetDefaultGroup() $config->handlers = ['database']; $config->database['group'] = 'default'; - $this->settings->set('Test.siteName', true); + $this->settings->set('Example.siteName', true); $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', 'value' => '1', 'type' => 'boolean', ]); - $this->assertTrue($this->settings->get('Test.siteName')); + $this->assertTrue($this->settings->get('Example.siteName')); } public function testSetInsertsBoolTrue() { - $this->settings->set('Test.siteName', true); + $this->settings->set('Example.siteName', true); $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', 'value' => '1', 'type' => 'boolean', ]); - $this->assertTrue($this->settings->get('Test.siteName')); + $this->assertTrue($this->settings->get('Example.siteName')); } public function testSetInsertsBoolFalse() { - $this->settings->set('Test.siteName', false); + $this->settings->set('Example.siteName', false); $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', 'value' => '0', 'type' => 'boolean', ]); - $this->assertFalse($this->settings->get('Test.siteName')); + $this->assertFalse($this->settings->get('Example.siteName')); } public function testSetInsertsNull() { - $this->settings->set('Test.siteName', null); + $this->settings->set('Example.siteName', null); $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', 'value' => null, 'type' => 'NULL', ]); - $this->assertNull($this->settings->get('Test.siteName')); + $this->assertNull($this->settings->get('Example.siteName')); } public function testSetInsertsArray() { $data = ['foo' => 'bar']; - $this->settings->set('Test.siteName', $data); + $this->settings->set('Example.siteName', $data); $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', 'value' => serialize($data), 'type' => 'array', ]); - $this->assertSame($data, $this->settings->get('Test.siteName')); + $this->assertSame($data, $this->settings->get('Example.siteName')); } public function testSetInsertsObject() { $data = (object) ['foo' => 'bar']; - $this->settings->set('Test.siteName', $data); + $this->settings->set('Example.siteName', $data); $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', 'value' => serialize($data), 'type' => 'object', ]); - $this->assertSame((array) $data, (array) $this->settings->get('Test.siteName')); + $this->assertSame((array) $data, (array) $this->settings->get('Example.siteName')); } public function testSetUpdatesExistingRows() { $this->hasInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', 'value' => 'foo', 'created_at' => Time::now()->toDateTimeString(), 'updated_at' => Time::now()->toDateTimeString(), ]); - $this->settings->set('Test.siteName', 'Bar'); + $this->settings->set('Example.siteName', 'Bar'); $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', 'value' => 'Bar', ]); @@ -196,27 +196,27 @@ public function testWorksWithoutConfigClass() public function testForgetSuccess() { $this->hasInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', 'value' => 'foo', 'created_at' => Time::now()->toDateTimeString(), 'updated_at' => Time::now()->toDateTimeString(), ]); - $this->settings->forget('Test.siteName'); + $this->settings->forget('Example.siteName'); $this->dontSeeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', ]); } public function testForgetWithNoStoredRecord() { - $this->settings->forget('Test.siteName'); + $this->settings->forget('Example.siteName'); $this->dontSeeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', ]); } @@ -224,30 +224,30 @@ public function testForgetWithNoStoredRecord() public function testFlush() { // Default value in the config file - $this->assertSame('Settings Test', $this->settings->get('Test.siteName')); + $this->assertSame('Settings Test', $this->settings->get('Example.siteName')); - $this->settings->set('Test.siteName', 'Foo'); + $this->settings->set('Example.siteName', 'Foo'); // Should be the last value set - $this->assertSame('Foo', $this->settings->get('Test.siteName')); + $this->assertSame('Foo', $this->settings->get('Example.siteName')); $this->settings->flush(); $this->dontSeeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', ]); // Should be back to the default value - $this->assertSame('Settings Test', $this->settings->get('Test.siteName')); + $this->assertSame('Settings Test', $this->settings->get('Example.siteName')); } public function testSetWithContext() { - $this->settings->set('Test.siteName', 'Banana', 'environment:test'); + $this->settings->set('Example.siteName', 'Banana', 'environment:test'); $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', 'value' => 'Banana', 'type' => 'string', @@ -260,13 +260,13 @@ public function testSetWithContext() */ 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->settings->set('Example.siteName', 'Humpty'); + $this->settings->set('Example.siteName', 'Jack', 'context:male'); + $this->settings->set('Example.siteName', 'Jill', 'context:female'); + $this->settings->set('Example.siteName', 'Jane', 'context:female'); $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', 'value' => 'Jane', 'type' => 'string', @@ -274,14 +274,14 @@ public function testSetUpdatesContextOnly() ]); $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', 'value' => 'Humpty', 'type' => 'string', 'context' => null, ]); $this->seeInDatabase($this->table, [ - 'class' => 'Tests\Support\Config\Test', + 'class' => 'Tests\Support\Config\Example', 'key' => 'siteName', 'value' => 'Jack', 'type' => 'string', diff --git a/tests/SettingsTest.php b/tests/SettingsTest.php index 2c72d51..a519142 100644 --- a/tests/SettingsTest.php +++ b/tests/SettingsTest.php @@ -37,37 +37,37 @@ public function testServiceUsesConfig() public function testSettingsGetsFromConfig() { - $this->assertSame(config('Test')->siteName, $this->settings->get('Test.siteName')); + $this->assertSame(config('Example')->siteName, $this->settings->get('Example.siteName')); } public function testSettingsNotFound() { - $this->assertSame(config('Test')->siteName, $this->settings->get('Test.siteName')); + $this->assertSame(config('Example')->siteName, $this->settings->get('Example.siteName')); } public function testGetWithContext() { - $this->settings->set('Test.siteName', 'NoContext'); - $this->settings->set('Test.siteName', 'YesContext', 'testing:true'); + $this->settings->set('Example.siteName', 'NoContext'); + $this->settings->set('Example.siteName', 'YesContext', 'testing:true'); - $this->assertSame('NoContext', $this->settings->get('Test.siteName')); - $this->assertSame('YesContext', $this->settings->get('Test.siteName', 'testing:true')); + $this->assertSame('NoContext', $this->settings->get('Example.siteName')); + $this->assertSame('YesContext', $this->settings->get('Example.siteName', 'testing:true')); } public function testGetWithoutContextUsesGlobal() { - $this->settings->set('Test.siteName', 'NoContext'); + $this->settings->set('Example.siteName', 'NoContext'); - $this->assertSame('NoContext', $this->settings->get('Test.siteName', 'testing:true')); + $this->assertSame('NoContext', $this->settings->get('Example.siteName', 'testing:true')); } public function testForgetWithContext() { - $this->settings->set('Test.siteName', 'Bar'); - $this->settings->set('Test.siteName', 'Amnesia', 'category:disease'); + $this->settings->set('Example.siteName', 'Bar'); + $this->settings->set('Example.siteName', 'Amnesia', 'category:disease'); - $this->settings->forget('Test.siteName', 'category:disease'); + $this->settings->forget('Example.siteName', 'category:disease'); - $this->assertSame('Bar', $this->settings->get('Test.siteName', 'category:disease')); + $this->assertSame('Bar', $this->settings->get('Example.siteName', 'category:disease')); } } diff --git a/tests/_support/Config/Test.php b/tests/_support/Config/Example.php similarity index 78% rename from tests/_support/Config/Test.php rename to tests/_support/Config/Example.php index f6c7d5f..e0137c8 100644 --- a/tests/_support/Config/Test.php +++ b/tests/_support/Config/Example.php @@ -7,7 +7,7 @@ /** * @internal */ -final class Test extends BaseConfig +final class Example extends BaseConfig { public $siteName = 'Settings Test'; } diff --git a/tests/_support/TestCase.php b/tests/_support/TestCase.php index ba2d39b..a147ac6 100644 --- a/tests/_support/TestCase.php +++ b/tests/_support/TestCase.php @@ -6,12 +6,9 @@ use CodeIgniter\Settings\Settings; use CodeIgniter\Test\CIUnitTestCase; use Config\Services; -use Nexus\PHPUnit\Extension\Expeditable; abstract class TestCase extends CIUnitTestCase { - use Expeditable; - /** * @var Settings */