diff --git a/src/Commands/LaravelConfigCheckerCommand.php b/src/Commands/LaravelConfigCheckerCommand.php index e231711..1513ab2 100644 --- a/src/Commands/LaravelConfigCheckerCommand.php +++ b/src/Commands/LaravelConfigCheckerCommand.php @@ -7,7 +7,6 @@ use ChrisDiCarlo\LaravelConfigChecker\Resolvers\BladeFileResolver; use ChrisDiCarlo\LaravelConfigChecker\Resolvers\PhpFileResolver; use ChrisDiCarlo\LaravelConfigChecker\Support\FileChecker; -use ChrisDiCarlo\LaravelConfigChecker\Support\LoadConfigKeys; use Illuminate\Console\Command; use Illuminate\Support\Collection; @@ -26,8 +25,6 @@ class LaravelConfigCheckerCommand extends Command public $description = 'Check all references to config values in PHP and Blade files'; - private Collection $configKeys; - private array $bladeIssues = []; private array $phpIssues = []; @@ -41,12 +38,9 @@ public function getIssues(): Collection } public function handle( - LoadConfigKeys $loadConfigKeys, PhpFileResolver $phpFiles, BladeFileResolver $bladeFiles ): int { - $this->configKeys = $loadConfigKeys(); - if ($this->option('no-progress')) { intro('--no-progress option used. Disabling progress bar.'); @@ -57,7 +51,7 @@ public function handle( foreach ($phpFiles as $file) { $content = file_get_contents($file->getRealPath()); - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); foreach ($fileChecker->check() as $issue) { $this->phpIssues[$file->getRelativePathname()][] = $issue; @@ -70,7 +64,7 @@ public function handle( $bladeFiles = $bladeFiles->resolve(); foreach ($bladeFiles as $file) { $content = file_get_contents($file->getRealPath()); - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); foreach ($fileChecker->check() as $issue) { $this->bladeIssues[$file->getRelativePathname()][] = $issue; @@ -87,7 +81,7 @@ public function handle( $content = file_get_contents($file->getRealPath()); - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); foreach ($fileChecker->check() as $issue) { $this->phpIssues[$file->getRelativePathname()][] = $issue; @@ -104,7 +98,7 @@ public function handle( $progress->hint = "Checking {$file->getRelativePathname()}"; $content = file_get_contents($file->getRealPath()); - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); foreach ($fileChecker->check() as $issue) { $this->bladeIssues[$file->getRelativePathname()][] = $issue; diff --git a/src/Support/FileChecker.php b/src/Support/FileChecker.php index 46d0630..c53cbec 100644 --- a/src/Support/FileChecker.php +++ b/src/Support/FileChecker.php @@ -5,11 +5,11 @@ namespace ChrisDiCarlo\LaravelConfigChecker\Support; use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Config; class FileChecker { public function __construct( - private readonly Collection $configKeys, private readonly string $content, ) {} @@ -46,7 +46,7 @@ private function checkForFacadeUsage(string $content): array $offset = (int) $match[1]; $lineNumber = substr_count(substr($content, 0, $offset), "\n") + 1; - if ($this->configKeys->doesntContain($key)) { + if (! Config::has($key)) { $issues[] = [ 'key' => $key, 'type' => sprintf('Config::%s()', $matches[1][$index][0]), @@ -71,7 +71,7 @@ private function checkForHelperUsage(string $content): array $offset = (int) $match[1]; $lineNumber = substr_count(substr($content, 0, $offset), "\n") + 1; - if ($this->configKeys->doesntContain($key)) { + if (! Config::has($key)) { $issues[] = [ 'key' => $key, 'type' => 'config()', diff --git a/tests/FileCheckerTest.php b/tests/FileCheckerTest.php index 5d58e5b..9b42946 100644 --- a/tests/FileCheckerTest.php +++ b/tests/FileCheckerTest.php @@ -5,13 +5,14 @@ use ChrisDiCarlo\LaravelConfigChecker\Support\FileChecker; use ChrisDiCarlo\LaravelConfigChecker\Support\FileCheckInfo; use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Config; beforeEach(function () { - $this->configKeys = collect([ - 'file', - 'file.valid_key', - 'file.nested', - 'file.nested.key', + Config::set('file', [ + 'valid_key' => 'value', + 'nested' => [ + 'key' => 'value', + ], ]); }); it('returns a collection of FileCheckInfo objects', function () { @@ -20,7 +21,7 @@ Config::get("invalid_key"); PHP; - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); $issues = $fileChecker->check(); @@ -34,7 +35,7 @@ echo "Hello, World!"; PHP; - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); $issues = $fileChecker->check(); @@ -44,7 +45,7 @@ {{ "Hello, World!" }} BLADE; - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); $issues = $fileChecker->check(); @@ -59,7 +60,7 @@ config("file.valid_key"); PHP; - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); $issues = $fileChecker->check(); @@ -71,7 +72,7 @@ {{ config("file.valid_key") }} BLADE; - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); $issues = $fileChecker->check(); @@ -89,7 +90,7 @@ config("file.valid_key"); PHP; - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); $issues = $fileChecker->check(); @@ -117,7 +118,7 @@ {{ config("file.valid_key") }} BLADE; - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); $issues = $fileChecker->check(); @@ -140,7 +141,7 @@ it('handles empty content gracefully', function () { $content = ''; - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); $issues = $fileChecker->check(); @@ -158,12 +159,34 @@ config("file.valid_key"); PHP; - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); $issues = $fileChecker->check(); - expect($issues->contains('key', 'file.valid_key'))->toBeFalse(); - expect($issues->contains('key', 'file.invalid_key'))->toBeTrue(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.invalid_key' && + $issue->type === 'Config::get()'; + }))->toBeTrue(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.invalid_key' && + $issue->type === 'Config::has()'; + }))->toBeTrue(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.invalid_key' && + $issue->type === 'config()'; + }))->toBeTrue(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.valid_key' && + $issue->type === 'Config::get()'; + }))->toBeFalse(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.valid_key' && + $issue->type === 'Config::has()'; + }))->toBeFalse(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.valid_key' && + $issue->type === 'config()'; + }))->toBeFalse(); $content = <<<'BLADE' {{ Config::get("file.invalid_key") }} @@ -174,12 +197,34 @@ {{ config("file.valid_key") }} BLADE; - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); $issues = $fileChecker->check(); - expect($issues->contains('key', 'file.valid_key'))->toBeFalse(); - expect($issues->contains('key', 'file.invalid_key'))->toBeTrue(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.invalid_key' && + $issue->type === 'Config::get()'; + }))->toBeTrue(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.invalid_key' && + $issue->type === 'Config::has()'; + }))->toBeTrue(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.invalid_key' && + $issue->type === 'config()'; + }))->toBeTrue(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.valid_key' && + $issue->type === 'Config::get()'; + }))->toBeFalse(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.valid_key' && + $issue->type === 'Config::has()'; + }))->toBeFalse(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.valid_key' && + $issue->type === 'config()'; + }))->toBeFalse(); }); it('detects issues for invalid nested keys', function () { @@ -193,12 +238,34 @@ config("file.valid_key"); PHP; - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); $issues = $fileChecker->check(); - expect($issues->contains('key', 'file.valid_key'))->toBeFalse(); - expect($issues->contains('key', 'file.nested.invalid_key'))->toBeTrue(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.nested.invalid_key' && + $issue->type === 'Config::get()'; + }))->toBeTrue(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.nested.invalid_key' && + $issue->type === 'Config::has()'; + }))->toBeTrue(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.nested.invalid_key' && + $issue->type === 'config()'; + }))->toBeTrue(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.valid_key' && + $issue->type === 'Config::get()'; + }))->toBeFalse(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.valid_key' && + $issue->type === 'Config::has()'; + }))->toBeFalse(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.valid_key' && + $issue->type === 'config()'; + }))->toBeFalse(); $content = <<<'BLADE' {{ Config::get("file.nested.invalid_key") }} @@ -209,12 +276,34 @@ {{ config("file.valid_key") }} BLADE; - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); $issues = $fileChecker->check(); - expect($issues->contains('key', 'file.valid_key'))->toBeFalse(); - expect($issues->contains('key', 'file.nested.invalid_key'))->toBeTrue(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.nested.invalid_key' && + $issue->type === 'Config::get()'; + }))->toBeTrue(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.nested.invalid_key' && + $issue->type === 'Config::has()'; + }))->toBeTrue(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.nested.invalid_key' && + $issue->type === 'config()'; + }))->toBeTrue(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.valid_key' && + $issue->type === 'Config::get()'; + }))->toBeFalse(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.valid_key' && + $issue->type === 'Config::has()'; + }))->toBeFalse(); + expect($issues->contains(function ($issue) { + return $issue->key === 'file.valid_key' && + $issue->type === 'config()'; + }))->toBeFalse(); }); it('ignores methods called config', function () { @@ -227,7 +316,7 @@ Config::get('some.other.invalid.key'); PHP; - $fileChecker = new FileChecker($this->configKeys, $content); + $fileChecker = new FileChecker($content); $issues = $fileChecker->check(); diff --git a/tests/LaravelConfigCheckerCommandTest.php b/tests/LaravelConfigCheckerCommandTest.php index 46936e9..de5a247 100644 --- a/tests/LaravelConfigCheckerCommandTest.php +++ b/tests/LaravelConfigCheckerCommandTest.php @@ -2,11 +2,16 @@ declare(strict_types=1); +use Illuminate\Support\Facades\Config; + use function Pest\Laravel\artisan; it('displays a message when there are no issues', function () { - // set the base path for the application $this->app->setBasePath(realpath(__DIR__ . '/fixtures/valid')); + Config::set('app.valid_key', 'Laravel Config Checker'); + Config::set('app.nested', [ + 'key' => 'value', + ]); artisan('config:check') ->expectsOutputToContain('No issues found. All config references are valid.') @@ -14,9 +19,13 @@ }); it('displays a message when there are issues', function () { - // set the base path for the application $this->app->setBasePath(realpath(__DIR__ . '/fixtures/invalid')); + Config::set('app.valid_key', 'Laravel Config Checker'); + Config::set('app.nested', [ + 'key' => 'value', + ]); + artisan('config:check') ->expectsOutputToContain('Invalid config references found:') ->expectsOutputToContain('app' . DIRECTORY_SEPARATOR . 'TestClassOne.php') @@ -29,6 +38,11 @@ it('disables the progress bar when the --no-progress option is used', function () { $this->app->setBasePath(realpath(__DIR__ . '/fixtures/valid')); + Config::set('app.valid_key', 'Laravel Config Checker'); + Config::set('app.nested', [ + 'key' => 'value', + ]); + artisan('config:check', ['--no-progress' => true]) ->expectsOutputToContain('--no-progress option used. Disabling progress bar.') ->expectsOutputToContain('Checking PHP files...') @@ -40,6 +54,11 @@ it('skips checking blade files when the --no-blade option is used', function () { $this->app->setBasePath(realpath(__DIR__ . '/fixtures/valid')); + Config::set('app.valid_key', 'Laravel Config Checker'); + Config::set('app.nested', [ + 'key' => 'value', + ]); + artisan('config:check', ['--no-blade' => true]) ->expectsOutputToContain('Checking PHP files...') ->doesntExpectOutputToContain('Checking Blade files...') @@ -56,6 +75,11 @@ it('skips checking php files when the --no-php option is used', function () { $this->app->setBasePath(realpath(__DIR__ . '/fixtures/valid')); + Config::set('app.valid_key', 'Laravel Config Checker'); + Config::set('app.nested', [ + 'key' => 'value', + ]); + artisan('config:check', ['--no-php' => true]) ->expectsOutputToContain('Checking Blade files...') ->doesntExpectOutputToContain('Checking PHP files...')