diff --git a/.editorconfig b/.editorconfig index 665acc3..a7c44dd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,4 +12,4 @@ trim_trailing_whitespace = true trim_trailing_whitespace = false [*.{yml,yaml}] -indent_size = 2 \ No newline at end of file +indent_size = 2 diff --git a/.github/workflows/php-cs-fixer.yml b/.github/workflows/php-cs-fixer.yml new file mode 100644 index 0000000..fbec801 --- /dev/null +++ b/.github/workflows/php-cs-fixer.yml @@ -0,0 +1,23 @@ +name: Check & fix styling + +on: [push] + +jobs: + php-cs-fixer: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} + + - name: Run PHP CS Fixer + uses: docker://oskarstark/php-cs-fixer-ga + with: + args: --config=.php_cs.dist.php --allow-risky=yes + + - name: Commit changes + uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: Fix styling diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml new file mode 100644 index 0000000..e2aabdc --- /dev/null +++ b/.github/workflows/phpstan.yml @@ -0,0 +1,26 @@ +name: PHPStan + +on: + push: + paths: + - '**.php' + - 'phpstan.neon.dist' + +jobs: + phpstan: + name: phpstan + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + coverage: none + + - name: Install composer dependencies + uses: ramsey/composer-install@v2 + + - name: Run PHPStan + run: ./vendor/bin/phpstan --error-format=github diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml new file mode 100644 index 0000000..e46e7fd --- /dev/null +++ b/.github/workflows/run-tests.yml @@ -0,0 +1,45 @@ +name: Tests + +on: [pull_request] + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: true + matrix: + os: [ubuntu-latest, windows-latest] + php: [8.2, 8.3] + laravel: [10.*, 11.*] + stability: [prefer-stable] + include: + - laravel: 10.* + testbench: ^8.0 + - laravel: 11.* + testbench: ^9.0 + + name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo + coverage: none + + - name: Setup problem matchers + run: | + echo "::add-matcher::${{ runner.tool_cache }}/php.json" + echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Install dependencies + run: | + composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update + composer update --${{ matrix.stability }} --prefer-dist --no-interaction + + - name: Execute tests + run: vendor/bin/pest diff --git a/.php_cs.dist.php b/.php_cs.dist.php new file mode 100644 index 0000000..8d8a790 --- /dev/null +++ b/.php_cs.dist.php @@ -0,0 +1,40 @@ +in([ + __DIR__ . '/src', + __DIR__ . '/tests', + ]) + ->name('*.php') + ->notName('*.blade.php') + ->ignoreDotFiles(true) + ->ignoreVCS(true); + +return (new PhpCsFixer\Config()) + ->setRules([ + '@PSR12' => true, + 'array_syntax' => ['syntax' => 'short'], + 'ordered_imports' => ['sort_algorithm' => 'alpha'], + 'no_unused_imports' => true, + 'not_operator_with_successor_space' => true, + 'trailing_comma_in_multiline' => true, + 'phpdoc_scalar' => true, + 'unary_operator_spaces' => true, + 'binary_operator_spaces' => true, + 'blank_line_before_statement' => [ + 'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'], + ], + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_var_without_name' => true, + 'class_attributes_separation' => [ + 'elements' => [ + 'method' => 'one', + ], + ], + 'method_argument_space' => [ + 'on_multiline' => 'ensure_fully_multiline', + 'keep_multiple_spaces_after_comma' => true, + ], + 'single_trait_insert_per_statement' => true, + ]) + ->setFinder($finder); diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index df16b68..0000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,19 +0,0 @@ -filter: - excluded_paths: [tests/*] - -checks: - php: - remove_extra_empty_lines: true - remove_php_closing_tag: true - remove_trailing_whitespace: true - fix_use_statements: - remove_unused: true - preserve_multiple: false - preserve_blanklines: true - order_alphabetically: true - fix_php_opening_tag: true - fix_linefeed: true - fix_line_ending: true - fix_identation_4spaces: true - fix_doc_comments: true - diff --git a/.styleci.yml b/.styleci.yml deleted file mode 100644 index f4d3cbc..0000000 --- a/.styleci.yml +++ /dev/null @@ -1,4 +0,0 @@ -preset: laravel - -disabled: - - single_class_element_per_statement diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 96dd1fe..0000000 --- a/.travis.yml +++ /dev/null @@ -1,40 +0,0 @@ -language: php - -php: - - 7.1 - - 7.2 - - 7.3 - - 7.4 - - 8.0 - -env: - global: - - ILLUMINATE_VERSION="" - - TESTBENCH_VERSION="" - - matrix: - - COMPOSER_FLAGS="--prefer-lowest" - - COMPOSER_FLAGS="" - - ILLUMINATE_VERSION="5.7.*" TESTBENCH_VERSION="3.7.*" - - ILLUMINATE_VERSION="5.8.*" TESTBENCH_VERSION="3.8.*" - - ILLUMINATE_VERSION="6.*" TESTBENCH_VERSION="4.*" - -matrix: - exclude: - - php: 7.1 - env: ILLUMINATE_VERSION="6.*" TESTBENCH_VERSION="4.*" - -before_script: - - travis_retry composer self-update - - if [ "$ILLUMINATE_VERSION" != "" ] && [ "$TESTBENCH_VERSION" != "" ]; then - composer require "illuminate/http:${ILLUMINATE_VERSION}" --no-update; - composer require "illuminate/support:${ILLUMINATE_VERSION}" --no-update; - composer require "orchestra/testbench:${TESTBENCH_VERSION}" --no-update; - fi - - travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-source - -script: - - vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover - -after_script: - - php vendor/bin/ocular code-coverage:upload --format=php-clover coverage.clover diff --git a/README.md b/README.md index e13ac95..93fea52 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ You can completely customize which environments you want to have enabled for the To modify the default values, publish the package configuration file using: -``` +```bash php artisan vendor:publish --provider='BeyondCode\LaravelFavicon\FaviconServiceProvider' --tag='config' ``` diff --git a/composer.json b/composer.json index 5785876..249bff8 100644 --- a/composer.json +++ b/composer.json @@ -16,14 +16,21 @@ } ], "require": { - "php": "^7.1|^8.0|^8.1|^8.2|^8.3", - "illuminate/http": "5.6.*|5.7.*|5.8.*|6.*|7.*|8.*|9.*|^10.0|^11.0", - "illuminate/support": "5.6.*|5.7.*|5.8.*|6.*|7.*|8.*|9.*|^10.0|^11.0", - "intervention/image": "^2.4" + "php": "^8.1|^8.2|^8.3", + "illuminate/http": "^9.0|^10.0|^11.0", + "illuminate/support": "^9.0|^10.0|^11.0", + "intervention/image": "^2.6" }, "require-dev": { - "phpunit/phpunit": "^7.0|^8.0|^9.0|^10.0|^11.0", - "orchestra/testbench": "^3.7|^4.0|^5.0|^6.0|^7.0|^8.0|^9.0" + "nunomaduro/collision": "^7.0", + "nunomaduro/larastan": "^2.0.1", + "orchestra/testbench": "^8.0|^9.0", + "pestphp/pest": "^2.2", + "pestphp/pest-plugin-laravel": "^2.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^10.0|^11.0" }, "autoload": { "psr-4": { @@ -39,12 +46,15 @@ } }, "scripts": { - "test": "vendor/bin/phpunit", - "test-coverage": "vendor/bin/phpunit --coverage-html coverage" - + "test": "vendor/bin/pest", + "test-coverage": "vendor/bin/pest --coverage" }, "config": { - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "pestphp/pest-plugin": true, + "phpstan/extension-installer": true + } }, "extra": { "laravel": { @@ -52,5 +62,7 @@ "BeyondCode\\LaravelFavicon\\FaviconServiceProvider" ] } - } + }, + "minimum-stability": "dev", + "prefer-stable": true } diff --git a/src/Favicon.php b/src/Favicon.php index babd0f7..498f64c 100644 --- a/src/Favicon.php +++ b/src/Favicon.php @@ -6,25 +6,24 @@ class Favicon { - /** @var array */ - protected $config; + protected array $config; public function __construct(array $config) { $this->config = $config; } - public function getFaviconText(string $environment) + public function getFaviconText(string $environment): mixed { return Arr::get($this->config, 'enabled_environments.'.$environment.'.text'); } - public function getFaviconColor(string $environment) + public function getFaviconColor(string $environment): mixed { return Arr::get($this->config, 'enabled_environments.'.$environment.'.color'); } - public function getFaviconBackgroundColor(string $environment) + public function getFaviconBackgroundColor(string $environment): mixed { return Arr::get($this->config, 'enabled_environments.'.$environment.'.background_color'); } diff --git a/src/FaviconServiceProvider.php b/src/FaviconServiceProvider.php index 134b4f3..5effa77 100644 --- a/src/FaviconServiceProvider.php +++ b/src/FaviconServiceProvider.php @@ -12,7 +12,7 @@ class FaviconServiceProvider extends ServiceProvider /** * Bootstrap the application services. */ - public function boot() + public function boot(): void { if ($this->app->runningInConsole()) { $this->publishes([ @@ -26,7 +26,7 @@ public function boot() /** * Register the application services. */ - public function register() + public function register(): void { $this->mergeConfigFrom(__DIR__.'/../config/favicon.php', 'favicon'); @@ -39,7 +39,7 @@ public function register() }); } - protected function registerRoutes() + protected function registerRoutes(): void { Route::get(config('favicon.url_prefix').'/{icon}', FaviconController::class) ->where('icon', '.*'); diff --git a/src/Generators/EnvironmentGenerator.php b/src/Generators/EnvironmentGenerator.php index 29bec33..f9139e2 100644 --- a/src/Generators/EnvironmentGenerator.php +++ b/src/Generators/EnvironmentGenerator.php @@ -12,14 +12,11 @@ class EnvironmentGenerator implements FaviconGenerator { - /** @var Favicon */ - protected $favicon; + protected Favicon $favicon; - /** @var ImageManager */ - protected $manager; + protected ImageManager $manager; - /** @var string */ - protected $environment; + protected string $environment; public function __construct(Favicon $favicon) { @@ -82,7 +79,7 @@ protected function calculateDynamicFontSize(AbstractFont $font, Image $icon, $pa } } - protected function createEnvironmentTextImage(AbstractFont $font) + protected function createEnvironmentTextImage(AbstractFont $font): Image { $size = $font->getBoxSize(); diff --git a/src/Http/Controllers/FaviconController.php b/src/Http/Controllers/FaviconController.php index b105cb6..073e310 100644 --- a/src/Http/Controllers/FaviconController.php +++ b/src/Http/Controllers/FaviconController.php @@ -4,10 +4,11 @@ use BeyondCode\LaravelFavicon\Generators\FaviconGenerator; use Illuminate\Http\Request; +use Illuminate\Http\Response; class FaviconController { - public function __invoke(Request $request, FaviconGenerator $generator) + public function __invoke(Request $request, FaviconGenerator $generator): Response { return $generator->generate($request->route('icon')); } diff --git a/src/helpers.php b/src/helpers.php index b93f886..b68e92f 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -3,7 +3,7 @@ use BeyondCode\LaravelFavicon\Generators\FaviconGenerator; if (! function_exists('favicon')) { - function favicon($image) + function favicon(string $image): string { if (app(FaviconGenerator::class)->shouldGenerateFavicon(app()->environment())) { return rtrim(config('app.url'), '/').'/'.config('favicon.url_prefix')."/$image"; diff --git a/tests/EnvironmentGeneratorTest.php b/tests/EnvironmentGeneratorTest.php index 9c5ea95..e0ad263 100644 --- a/tests/EnvironmentGeneratorTest.php +++ b/tests/EnvironmentGeneratorTest.php @@ -1,33 +1,27 @@ app['config']['app.env'] = 'production'; +test('the helper returns the icon file for invalid environments', function () { + app()['config']['app.env'] = 'production'; - $icon = favicon('some_icon'); + $icon = favicon('some_icon'); - $this->assertSame('some_icon', $icon); - } + expect($icon)->toBe('some_icon'); +}); - /** @test */ - public function the_helper_returns_the_icon_route_for_valid_environments() - { - $this->app['config']['app.env'] = 'local'; +test('the helper returns the icon route for valid environments', function () { + app()['config']['app.env'] = 'local'; - $icon = favicon('some_icon'); + $icon = favicon('some_icon'); - $this->assertSame('/laravel-favicon/some_icon', $icon); - } + expect($icon)->toBe('/laravel-favicon/some_icon'); +}); + +// Helpers +function getPackageProviders($app) +{ + return [FaviconServiceProvider::class]; } diff --git a/tests/FaviconTest.php b/tests/FaviconTest.php index 92f0651..df52f52 100644 --- a/tests/FaviconTest.php +++ b/tests/FaviconTest.php @@ -1,53 +1,39 @@ favicon = new Favicon([ - 'enabled_environments' => [ - 'local' => [ - 'text' => 'DEV', - 'color' => '#000000', - 'background_color' => '#ffffff', - ], +uses(Orchestra\Testbench\TestCase::class); +beforeEach(function () { + $this->favicon = new Favicon([ + 'enabled_environments' => [ + 'local' => [ + 'text' => 'DEV', + 'color' => '#000000', + 'background_color' => '#ffffff', ], - ]); - } + ], + ]); +}); + - protected function getPackageProviders($app) - { - return [FaviconServiceProvider::class]; - } +it('returns environment specific color', function () { + expect($this->favicon->getFaviconColor('unknown'))->toBeNull() + ->and($this->favicon->getFaviconColor('local'))->toBe('#000000'); +}); - /** @test */ - public function it_returns_environment_specific_color() - { - $this->assertNull($this->favicon->getFaviconColor('unknown')); - $this->assertSame('#000000', $this->favicon->getFaviconColor('local')); - } +it('returns environment specific text', function () { + expect($this->favicon->getFaviconText('unknown'))->toBeNull() + ->and($this->favicon->getFaviconText('local'))->toBe('DEV'); +}); - /** @test */ - public function it_returns_environment_specific_text() - { - $this->assertNull($this->favicon->getFaviconText('unknown')); - $this->assertSame('DEV', $this->favicon->getFaviconText('local')); - } +it('returns environment specific background color', function () { + expect($this->favicon->getFaviconBackgroundColor('unknown'))->toBeNull() + ->and($this->favicon->getFaviconBackgroundColor('local'))->toBe('#ffffff'); +}); - /** @test */ - public function it_returns_environment_specific_background_color() - { - $this->assertNull($this->favicon->getFaviconBackgroundColor('unknown')); - $this->assertSame('#ffffff', $this->favicon->getFaviconBackgroundColor('local')); - } +// Helpers +function getPackageProviders($app) +{ + return [FaviconServiceProvider::class]; } diff --git a/tests/Pest.php b/tests/Pest.php new file mode 100644 index 0000000..f9ac1d7 --- /dev/null +++ b/tests/Pest.php @@ -0,0 +1,41 @@ +