From a07b762c4e5c696f9c11804a471a4d0b97e00bb4 Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Tue, 24 Sep 2024 15:21:01 +0200 Subject: [PATCH 01/11] Added tests & added package banner --- .gitignore | 1 + README.md | 4 ++ art/banner.png | Bin 0 -> 32193 bytes composer.json | 16 +++++- phpunit.xml | 21 +++++++ tests/Assets/.gitignore | 3 + tests/Assets/test.png | Bin 0 -> 32193 bytes tests/TestCase.php | 46 ++++++++++++++++ tests/View/Blade/ResponsiveDirectiveTest.php | 52 ++++++++++++++++++ .../content/assets/test_container.yaml | 1 + 10 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 art/banner.png create mode 100644 phpunit.xml create mode 100644 tests/Assets/.gitignore create mode 100644 tests/Assets/test.png create mode 100644 tests/TestCase.php create mode 100644 tests/View/Blade/ResponsiveDirectiveTest.php create mode 100644 tests/__fixtures__/content/assets/test_container.yaml diff --git a/.gitignore b/.gitignore index 885baa6..47108ec 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ composer.lock node_modules vendor .php_cs.cache +.phpunit.result.cache \ No newline at end of file diff --git a/README.md b/README.md index f46dfca..f134d5a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ + + Banner + + # Statamic glide directive > Blade directive to use glide with images diff --git a/art/banner.png b/art/banner.png new file mode 100644 index 0000000000000000000000000000000000000000..6716abe5599245261b93a04ab22ec64ec6e89867 GIT binary patch literal 32193 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 bYflxQdwdARBLc86&?Pgg3!l!rKm30HA%EqE literal 0 HcmV?d00001 diff --git a/composer.json b/composer.json index eac65dc..8784d3a 100644 --- a/composer.json +++ b/composer.json @@ -3,15 +3,27 @@ "description": "Addon that adds a glide blade directive", "type": "package", "require": { - "php": "^8.0|^8.1", + "php": "^8.1|^8.2", "laravel/framework": "*", - "statamic/cms": "^4.0" + "statamic/cms": "^5.0" + }, + "require-dev": { + "orchestra/testbench": "^9.0", + "phpunit/phpunit": "^11.2" }, "autoload": { "psr-4": { "JustBetter\\GlideDirective\\": "src/" } }, + "autoload-dev": { + "psr-4": { + "JustBetter\\GlideDirective\\Tests\\": "tests" + } + }, + "scripts": { + "test": "phpunit" + }, "config": { "sort-packages": true, "allow-plugins": { diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..bb593ca --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,21 @@ + + + + + ./tests + + + + + + + + + + + + + + + + diff --git a/tests/Assets/.gitignore b/tests/Assets/.gitignore new file mode 100644 index 0000000..0ac405b --- /dev/null +++ b/tests/Assets/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!test.png \ No newline at end of file diff --git a/tests/Assets/test.png b/tests/Assets/test.png new file mode 100644 index 0000000000000000000000000000000000000000..6716abe5599245261b93a04ab22ec64ec6e89867 GIT binary patch literal 32193 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 bYflxQdwdARBLc86&?Pgg3!l!rKm30HA%EqE literal 0 HcmV?d00001 diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 0000000..ca8b8c6 --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,46 @@ +blade = app('blade.compiler'); + } + + public function assetPath(string $file = ''): string + { + $path = __DIR__.'/Assets'; + + if (strlen($file) > 0) { + $path .= '/'.$file; + } + + return $path; + } + + protected function assertDirectiveOutput($expected, $expression, $variables = [], $message = '') + { + $compiled = $this->blade->compileString($expression); + + ob_start(); + extract($variables); + eval(' ?>'.$compiled.'assertSame($expected, $output, $message); + } +} diff --git a/tests/View/Blade/ResponsiveDirectiveTest.php b/tests/View/Blade/ResponsiveDirectiveTest.php new file mode 100644 index 0000000..5e7b88c --- /dev/null +++ b/tests/View/Blade/ResponsiveDirectiveTest.php @@ -0,0 +1,52 @@ +"; + + $this->assertSame($expected, $this->blade->compileString($blade)); + } + + #[Test] + public function test_responsive_directive_tag_handle() + { + config(['filesystems.disks.assets' => [ + 'driver' => 'local', + 'root' => $this->assetPath(), + 'url' => '/test', + ]]); + + $assetContainer = (new AssetContainer) + ->handle('test_container') + ->disk('assets') + ->save(); + + copy($this->assetPath('test.png'), $this->assetPath('upload.png')); + + $file = new UploadedFile($this->assetPath('upload.png'), 'test.png'); + $path = $file->getClientOriginalName(); + $asset = $assetContainer->makeAsset($path)->upload($file); + $view = Responsive::handle($asset); + + $asset->delete(); + + $this->assertStringContainsString('render()); + } +} \ No newline at end of file diff --git a/tests/__fixtures__/content/assets/test_container.yaml b/tests/__fixtures__/content/assets/test_container.yaml new file mode 100644 index 0000000..1bb97e5 --- /dev/null +++ b/tests/__fixtures__/content/assets/test_container.yaml @@ -0,0 +1 @@ +disk: assets From 262de205c83dded742b05d5c3f28c3134abab616 Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Tue, 24 Sep 2024 15:32:34 +0200 Subject: [PATCH 02/11] Changed phpunit version --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 40c89a2..d34b407 100644 --- a/composer.json +++ b/composer.json @@ -10,9 +10,9 @@ "require-dev": { "laravel/pint": "^1.7", "larastan/larastan": "^2.5", - "phpstan/phpstan-mockery": "^1.1", "orchestra/testbench": "^8.0|^9.0", - "phpunit/phpunit": "^11.2" + "phpstan/phpstan-mockery": "^1.1", + "phpunit/phpunit": "^10.0" }, "autoload": { "psr-4": { From fab1f20d8b1be675748db7a70c45b3b82e541d24 Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Tue, 15 Oct 2024 10:48:43 +0200 Subject: [PATCH 03/11] WIP tests --- .github/workflows/coverage.yml | 40 ++++++++++++++++++++++++++++++++ .github/workflows/tests.yml | 42 ++++++++++++++++++++++++++++++++++ phpunit.xml | 42 +++++++++++++++++++--------------- 3 files changed, 105 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/coverage.yml create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..e29c71e --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,40 @@ +name: coverage + +on: ['push', 'pull_request'] + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: true + matrix: + os: [ubuntu-latest] + php: [8.3] + laravel: [10.*, 11.*] + stability: [prefer-stable] + include: + - laravel: 10.* + testbench: 8.* + - laravel: 11.* + testbench: 9.* + + 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, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo, xdebug + coverage: xdebug + + - name: Install dependencies + run: | + composer config allow-plugins.pestphp/pest-plugin true + 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: XDEBUG_MODE=coverage php vendor/bin/phpunit --coverage --min=100 \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..1b5130f --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,42 @@ +name: tests + +on: ['push', 'pull_request'] + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: true + matrix: + os: [ubuntu-latest] + php: [8.1, 8.2, 8.3] + laravel: [10.*, 11.*] + stability: [prefer-lowest, prefer-stable] + include: + - laravel: 10.* + testbench: 8.* + - laravel: 11.* + testbench: 9.* + exclude: + - laravel: 11.* + php: 8.1 + + 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, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo + coverage: none + + - 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: composer test \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml index bb593ca..d2dea63 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,21 +1,25 @@ - - - - ./tests - - - - - - - - - - - - - - - + + + + tests + + + + + + src + + From cba367c8da7c25bf623840db2f91bc4c6d4e0a7e Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Mon, 21 Oct 2024 16:03:41 +0200 Subject: [PATCH 04/11] Added tests --- phpunit.xml | 25 +++----- tests/TestCase.php | 35 +++++++++++ tests/View/Blade/ResponsiveDirectiveTest.php | 64 ++++++++++++++------ tests/__fixtures__/dev-null/.gitkeep | 0 4 files changed, 89 insertions(+), 35 deletions(-) create mode 100644 tests/__fixtures__/dev-null/.gitkeep diff --git a/phpunit.xml b/phpunit.xml index d2dea63..91b8cae 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,25 +1,14 @@ - + - - tests + + ./tests/* - - + + - src + ./src - + \ No newline at end of file diff --git a/tests/TestCase.php b/tests/TestCase.php index ca8b8c6..d9d4aef 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -2,13 +2,33 @@ namespace JustBetter\GlideDirective\Tests; +use Illuminate\Http\UploadedFile; +use Statamic\Assets\AssetContainer; use Statamic\Testing\AddonTestCase; use JustBetter\GlideDirective\ServiceProvider; use Illuminate\Foundation\Testing\Concerns\InteractsWithViews; +use Statamic\Testing\Concerns\PreventsSavingStacheItemsToDisk; abstract class TestCase extends AddonTestCase { use InteractsWithViews; + use PreventsSavingStacheItemsToDisk; + + protected function resolveApplicationConfiguration($app): void + { + parent::resolveApplicationConfiguration($app); + + $app['config']->set('statamic.assets.image_manipulation.driver', 'gd'); + $app['config']->set('statamic.assets.image_manipulation.cache', true); + $app['config']->set('statamic.assets.image_manipulation.cache_path', __DIR__ . '/Assets/img'); + + $app['config']->set('filesystems.disks.assets', [ + 'driver' => 'local', + 'root' => $this->assetPath(), + 'url' => '/test', + ]); + } + protected string $addonServiceProvider = ServiceProvider::class; protected $blade; @@ -43,4 +63,19 @@ protected function assertDirectiveOutput($expected, $expression, $variables = [] $this->assertSame($expected, $output, $message); } + + protected function uploadTestAsset(string $filename) + { + $assetContainer = (new AssetContainer) + ->handle('test_container') + ->disk('assets') + ->save(); + + copy($this->assetPath('test.png'), $this->assetPath($filename)); + + $file = new UploadedFile($this->assetPath($filename), 'test.png'); + $path = $file->getClientOriginalName(); + + return $assetContainer->makeAsset($path)->upload($file); + } } diff --git a/tests/View/Blade/ResponsiveDirectiveTest.php b/tests/View/Blade/ResponsiveDirectiveTest.php index 5e7b88c..4182ffe 100644 --- a/tests/View/Blade/ResponsiveDirectiveTest.php +++ b/tests/View/Blade/ResponsiveDirectiveTest.php @@ -2,11 +2,15 @@ namespace JustBetter\GlideDirective\Tests\View\Blade; +use Illuminate\Support\Facades\Queue; +use JustBetter\GlideDirective\Jobs\GenerateGlideImageJob; use Statamic\Assets\AssetContainer; use Illuminate\Http\UploadedFile; use PHPUnit\Framework\Attributes\Test; use JustBetter\GlideDirective\Tests\TestCase; use JustBetter\GlideDirective\Responsive; +use Statamic\Statamic; +use Illuminate\Foundation\Bus\PendingDispatch; class ResponsiveDirectiveTest extends TestCase { @@ -27,26 +31,52 @@ public function test_responsive_directive_tag() #[Test] public function test_responsive_directive_tag_handle() { - config(['filesystems.disks.assets' => [ - 'driver' => 'local', - 'root' => $this->assetPath(), - 'url' => '/test', - ]]); - - $assetContainer = (new AssetContainer) - ->handle('test_container') - ->disk('assets') - ->save(); - - copy($this->assetPath('test.png'), $this->assetPath('upload.png')); - - $file = new UploadedFile($this->assetPath('upload.png'), 'test.png'); - $path = $file->getClientOriginalName(); - $asset = $assetContainer->makeAsset($path)->upload($file); + $asset = $this->uploadTestAsset('upload.png'); $view = Responsive::handle($asset); - $asset->delete(); $this->assertStringContainsString('render()); } + + #[Test] + public function test_responsive_directive_tag_cant_handle_string() + { + $asset = $this->uploadTestAsset('upload.png'); + $view = Responsive::handle($asset->url()); + $asset->delete(); + + $this->assertSame($view, ""); + } + + #[Test] + public function can_dispatch_glide_job() + { + Queue::fake(); + Queue::assertNothingPushed(); + + $asset = $this->uploadTestAsset('upload.png'); + GenerateGlideImageJob::dispatch($asset, 'xs', '', null); + + Queue::assertPushed(GenerateGlideImageJob::class, 1); + $asset->delete(); + } + + #[Test] + public function can_generate_glide_preset() + { + $asset = $this->uploadTestAsset('upload.png'); + + $glideImage = Statamic::tag('glide')->params( + [ + 'preset' => 'xs', + 'src' => $asset->url(), + 'format' => null, + 'fit' => null + ] + )->fetch(); + + $asset->delete(); + + $this->assertStringContainsString('/containers/test_container/test', $glideImage); + } } \ No newline at end of file diff --git a/tests/__fixtures__/dev-null/.gitkeep b/tests/__fixtures__/dev-null/.gitkeep new file mode 100644 index 0000000..e69de29 From 72c182174571a2ab83e5cebeafb281711a66524f Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Mon, 21 Oct 2024 16:16:12 +0200 Subject: [PATCH 05/11] Updated github actions & moved to pest --- .github/workflows/analyse.yml | 25 ++++++++++++++++++++----- .github/workflows/coverage.yml | 2 +- .github/workflows/tests.yml | 10 +++++----- composer.json | 17 ++++++++++++----- phpstan.neon | 4 +++- 5 files changed, 41 insertions(+), 17 deletions(-) diff --git a/.github/workflows/analyse.yml b/.github/workflows/analyse.yml index 21f448d..887f8cd 100644 --- a/.github/workflows/analyse.yml +++ b/.github/workflows/analyse.yml @@ -3,8 +3,23 @@ name: analyse on: ['push', 'pull_request'] jobs: - analyse: - runs-on: ubuntu-latest + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: true + matrix: + os: [ubuntu-latest] + php: [8.3] + laravel: [10.*, 11.*] + stability: [prefer-stable] + include: + - laravel: 10.* + testbench: 8.* + - laravel: 11.* + testbench: 9.* + + name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} + steps: - name: Checkout code uses: actions/checkout@v4 @@ -12,13 +27,13 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.3 + php-version: ${{ matrix.php }} extensions: dom, curl, libxml, mbstring, zip, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo coverage: none - name: Install dependencies run: | - composer require "laravel/framework:10.*" "orchestra/testbench:8.*" --no-interaction --no-update - composer update --prefer-stable --prefer-dist --no-interaction + composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update + composer update --${{ matrix.stability }} --prefer-dist --no-interaction - name: Analyse run: composer analyse \ No newline at end of file diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index e29c71e..9331e2a 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -37,4 +37,4 @@ jobs: 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: XDEBUG_MODE=coverage php vendor/bin/phpunit --coverage --min=100 \ No newline at end of file + run: XDEBUG_MODE=coverage php vendor/bin/pest --coverage --min=100 \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1b5130f..1caa61f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,6 +1,6 @@ name: tests -on: ['push', 'pull_request'] +on: [ 'push', 'pull_request' ] jobs: test: @@ -8,10 +8,10 @@ jobs: strategy: fail-fast: true matrix: - os: [ubuntu-latest] - php: [8.1, 8.2, 8.3] - laravel: [10.*, 11.*] - stability: [prefer-lowest, prefer-stable] + os: [ ubuntu-latest ] + php: [ 8.1, 8.2, 8.3 ] + laravel: [ 10.*, 11.* ] + stability: [ prefer-lowest, prefer-stable ] include: - laravel: 10.* testbench: 8.* diff --git a/composer.json b/composer.json index d34b407..256ea13 100644 --- a/composer.json +++ b/composer.json @@ -10,9 +10,10 @@ "require-dev": { "laravel/pint": "^1.7", "larastan/larastan": "^2.5", - "orchestra/testbench": "^8.0|^9.0", "phpstan/phpstan-mockery": "^1.1", - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^10.1", + "orchestra/testbench": "^8.0|^9.0", + "pestphp/pest": "^2.0" }, "autoload": { "psr-4": { @@ -27,7 +28,8 @@ "config": { "sort-packages": true, "allow-plugins": { - "pixelfear/composer-dist-plugin": true + "pixelfear/composer-dist-plugin": true, + "pestphp/pest-plugin": true } }, "extra": { @@ -56,8 +58,13 @@ "scripts": { "test": "phpunit", "analyse": "phpstan", - "fix-style": "pint", - "style": "pint --test" + "style": "pint --test", + "quality": [ + "@test", + "@analyse", + "@style" + ], + "fix-style": "pint" }, "minimum-stability": "dev" } diff --git a/phpstan.neon b/phpstan.neon index 71d49fb..ffdbf4b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -5,5 +5,7 @@ includes: parameters: paths: - src + - tests level: 8 - checkMissingIterableValueType: false \ No newline at end of file + ignoreErrors: + - identifier: missingType.iterableValue From ba132f13b1f2cd6e7a49815ea2b5ee70894cbed8 Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Mon, 21 Oct 2024 16:30:38 +0200 Subject: [PATCH 06/11] Updated tests & changed coverage --- .github/workflows/coverage.yml | 2 +- tests/TestCase.php | 3 +++ tests/View/Blade/ResponsiveDirectiveTest.php | 10 ++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 9331e2a..503bcf3 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -37,4 +37,4 @@ jobs: 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: XDEBUG_MODE=coverage php vendor/bin/pest --coverage --min=100 \ No newline at end of file + run: XDEBUG_MODE=coverage php vendor/bin/pest --coverage --min=85 \ No newline at end of file diff --git a/tests/TestCase.php b/tests/TestCase.php index d9d4aef..f6ca6d8 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -66,6 +66,8 @@ protected function assertDirectiveOutput($expected, $expression, $variables = [] protected function uploadTestAsset(string $filename) { + UploadedFile::fake(); + $assetContainer = (new AssetContainer) ->handle('test_container') ->disk('assets') @@ -73,6 +75,7 @@ protected function uploadTestAsset(string $filename) copy($this->assetPath('test.png'), $this->assetPath($filename)); + $file = new UploadedFile($this->assetPath($filename), 'test.png'); $path = $file->getClientOriginalName(); diff --git a/tests/View/Blade/ResponsiveDirectiveTest.php b/tests/View/Blade/ResponsiveDirectiveTest.php index 4182ffe..424306b 100644 --- a/tests/View/Blade/ResponsiveDirectiveTest.php +++ b/tests/View/Blade/ResponsiveDirectiveTest.php @@ -79,4 +79,14 @@ public function can_generate_glide_preset() $this->assertStringContainsString('/containers/test_container/test', $glideImage); } + + #[Test] + public function can_get_presets_for_asset() + { + $asset = $this->uploadTestAsset('upload.png'); + $presets = Responsive::getPresets($asset); + + $this->assertIsArray($presets); + $this->assertArrayHasKey('placeholder', $presets); + } } \ No newline at end of file From 5b79d64140173fd98ff0e28d0206a5b8316808bd Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Mon, 21 Oct 2024 16:46:17 +0200 Subject: [PATCH 07/11] Fixed phpstan notices --- tests/TestCase.php | 20 ++++---------------- tests/View/Blade/ResponsiveDirectiveTest.php | 13 +++++++------ 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/tests/TestCase.php b/tests/TestCase.php index f6ca6d8..39336e4 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -3,6 +3,7 @@ namespace JustBetter\GlideDirective\Tests; use Illuminate\Http\UploadedFile; +use Statamic\Assets\Asset; use Statamic\Assets\AssetContainer; use Statamic\Testing\AddonTestCase; use JustBetter\GlideDirective\ServiceProvider; @@ -31,7 +32,7 @@ protected function resolveApplicationConfiguration($app): void protected string $addonServiceProvider = ServiceProvider::class; - protected $blade; + protected mixed $blade; protected function setUp(): void { @@ -51,23 +52,11 @@ public function assetPath(string $file = ''): string return $path; } - protected function assertDirectiveOutput($expected, $expression, $variables = [], $message = '') - { - $compiled = $this->blade->compileString($expression); - - ob_start(); - extract($variables); - eval(' ?>'.$compiled.'assertSame($expected, $output, $message); - } - - protected function uploadTestAsset(string $filename) + protected function uploadTestAsset(string $filename): Asset { UploadedFile::fake(); + /* @phpstan-ignore-next-line */ $assetContainer = (new AssetContainer) ->handle('test_container') ->disk('assets') @@ -75,7 +64,6 @@ protected function uploadTestAsset(string $filename) copy($this->assetPath('test.png'), $this->assetPath($filename)); - $file = new UploadedFile($this->assetPath($filename), 'test.png'); $path = $file->getClientOriginalName(); diff --git a/tests/View/Blade/ResponsiveDirectiveTest.php b/tests/View/Blade/ResponsiveDirectiveTest.php index 424306b..fbce77c 100644 --- a/tests/View/Blade/ResponsiveDirectiveTest.php +++ b/tests/View/Blade/ResponsiveDirectiveTest.php @@ -20,7 +20,7 @@ public function setUp(): void } #[Test] - public function test_responsive_directive_tag() + public function test_responsive_directive_tag(): void { $blade = "@responsive('test.png')"; $expected = ""; @@ -29,17 +29,18 @@ public function test_responsive_directive_tag() } #[Test] - public function test_responsive_directive_tag_handle() + public function test_responsive_directive_tag_handle(): void { $asset = $this->uploadTestAsset('upload.png'); $view = Responsive::handle($asset); $asset->delete(); + /* @phpstan-ignore-next-line */ $this->assertStringContainsString('render()); } #[Test] - public function test_responsive_directive_tag_cant_handle_string() + public function test_responsive_directive_tag_cant_handle_string(): void { $asset = $this->uploadTestAsset('upload.png'); $view = Responsive::handle($asset->url()); @@ -49,7 +50,7 @@ public function test_responsive_directive_tag_cant_handle_string() } #[Test] - public function can_dispatch_glide_job() + public function can_dispatch_glide_job(): void { Queue::fake(); Queue::assertNothingPushed(); @@ -62,7 +63,7 @@ public function can_dispatch_glide_job() } #[Test] - public function can_generate_glide_preset() + public function can_generate_glide_preset(): void { $asset = $this->uploadTestAsset('upload.png'); @@ -81,7 +82,7 @@ public function can_generate_glide_preset() } #[Test] - public function can_get_presets_for_asset() + public function can_get_presets_for_asset(): void { $asset = $this->uploadTestAsset('upload.png'); $presets = Responsive::getPresets($asset); From 0b25c7766be0a7e0005ea4ed8a567b631da8ec09 Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Mon, 21 Oct 2024 16:48:17 +0200 Subject: [PATCH 08/11] Fixed pint notices --- src/Jobs/GenerateGlideImageJob.php | 9 ++++----- src/Responsive.php | 21 ++++++++++---------- tests/TestCase.php | 6 +++--- tests/View/Blade/ResponsiveDirectiveTest.php | 13 +++++------- 4 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/Jobs/GenerateGlideImageJob.php b/src/Jobs/GenerateGlideImageJob.php index c1ba80b..b0d682a 100644 --- a/src/Jobs/GenerateGlideImageJob.php +++ b/src/Jobs/GenerateGlideImageJob.php @@ -2,28 +2,27 @@ namespace JustBetter\GlideDirective\Jobs; +use Illuminate\Bus\Batchable; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Statamic\Assets\Asset; -use Illuminate\Bus\Batchable; use Statamic\Statamic; class GenerateGlideImageJob implements ShouldQueue { + use Batchable; use Dispatchable; use InteractsWithQueue; use Queueable; - use Batchable; public function __construct( public Asset $asset, public string $preset = '', public string $fit = '', public ?string $format = null, - ) { - } + ) {} public function handle(): void { @@ -34,7 +33,7 @@ public function handle(): void 'preset' => $this->preset, 'src' => $this->asset->url(), 'format' => $this->format, - 'fit' => $this->fit + 'fit' => $this->fit, ] )->fetch(); } diff --git a/src/Responsive.php b/src/Responsive.php index 40ae858..3d771cc 100644 --- a/src/Responsive.php +++ b/src/Responsive.php @@ -2,17 +2,17 @@ namespace JustBetter\GlideDirective; -use JustBetter\GlideDirective\Jobs\GenerateGlideImageJob; -use Statamic\Contracts\Imaging\ImageManipulator; use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\View; +use JustBetter\GlideDirective\Jobs\GenerateGlideImageJob; +use Statamic\Assets\Asset; +use Statamic\Contracts\Imaging\ImageManipulator; use Statamic\Facades\Glide; use Statamic\Facades\Image; use Statamic\Facades\URL; -use Statamic\Assets\Asset; use Statamic\Fields\Value; -use Statamic\Support\Str; use Statamic\Statamic; +use Statamic\Support\Str; class Responsive { @@ -81,7 +81,7 @@ public static function getPresets(Asset $asset): array } if (self::canUseMimeTypeSource()) { - if($glideUrl = self::getGlideUrl($asset, $fit ?? $data['fit'], $preset)) { + if ($glideUrl = self::getGlideUrl($asset, $fit ?? $data['fit'], $preset)) { $presets[$asset->mimeType()] .= $glideUrl.' '.$size; if ($preset !== 'placeholder') { @@ -99,7 +99,7 @@ public static function getPresets(Asset $asset): array $index++; } - if (!$webpSourceFound && !$mimeTypeSourceFound) { + if (! $webpSourceFound && ! $mimeTypeSourceFound) { $presets = ['placeholder' => $asset->url()]; } @@ -107,7 +107,7 @@ public static function getPresets(Asset $asset): array $presets['placeholder'] = Statamic::tag('glide:data_url')->params([ 'preset' => collect($configPresets)->keys()->first(), 'src' => $asset->url(), - 'fit' => 'crop_focal' + 'fit' => 'crop_focal', ])->fetch(); } @@ -121,7 +121,7 @@ protected static function getGlideUrl(Asset $asset, string $preset, string $fit, 'preset' => $preset, 'src' => $asset->url(), 'format' => $format, - 'fit' => $fit + 'fit' => $fit, ])->fetch(); } @@ -133,10 +133,11 @@ protected static function getGlideUrl(Asset $asset, string $preset, string $fit, $params = $manipulator->getParams(); - $manipulationCacheKey = 'asset::' . $asset->id() . '::' . md5(json_encode($params) ? json_encode($params) : ''); + $manipulationCacheKey = 'asset::'.$asset->id().'::'.md5(json_encode($params) ? json_encode($params) : ''); if ($cachedUrl = Glide::cacheStore()->get($manipulationCacheKey)) { - $url = Str::ensureLeft(config('statamic.assets.image_manipulation.route'), '/') . '/' . $cachedUrl; + $url = Str::ensureLeft(config('statamic.assets.image_manipulation.route'), '/').'/'.$cachedUrl; + return URL::encode($url); } diff --git a/tests/TestCase.php b/tests/TestCase.php index 39336e4..879ec07 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -2,12 +2,12 @@ namespace JustBetter\GlideDirective\Tests; +use Illuminate\Foundation\Testing\Concerns\InteractsWithViews; use Illuminate\Http\UploadedFile; +use JustBetter\GlideDirective\ServiceProvider; use Statamic\Assets\Asset; use Statamic\Assets\AssetContainer; use Statamic\Testing\AddonTestCase; -use JustBetter\GlideDirective\ServiceProvider; -use Illuminate\Foundation\Testing\Concerns\InteractsWithViews; use Statamic\Testing\Concerns\PreventsSavingStacheItemsToDisk; abstract class TestCase extends AddonTestCase @@ -21,7 +21,7 @@ protected function resolveApplicationConfiguration($app): void $app['config']->set('statamic.assets.image_manipulation.driver', 'gd'); $app['config']->set('statamic.assets.image_manipulation.cache', true); - $app['config']->set('statamic.assets.image_manipulation.cache_path', __DIR__ . '/Assets/img'); + $app['config']->set('statamic.assets.image_manipulation.cache_path', __DIR__.'/Assets/img'); $app['config']->set('filesystems.disks.assets', [ 'driver' => 'local', diff --git a/tests/View/Blade/ResponsiveDirectiveTest.php b/tests/View/Blade/ResponsiveDirectiveTest.php index fbce77c..75517ee 100644 --- a/tests/View/Blade/ResponsiveDirectiveTest.php +++ b/tests/View/Blade/ResponsiveDirectiveTest.php @@ -4,13 +4,10 @@ use Illuminate\Support\Facades\Queue; use JustBetter\GlideDirective\Jobs\GenerateGlideImageJob; -use Statamic\Assets\AssetContainer; -use Illuminate\Http\UploadedFile; -use PHPUnit\Framework\Attributes\Test; -use JustBetter\GlideDirective\Tests\TestCase; use JustBetter\GlideDirective\Responsive; +use JustBetter\GlideDirective\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; use Statamic\Statamic; -use Illuminate\Foundation\Bus\PendingDispatch; class ResponsiveDirectiveTest extends TestCase { @@ -46,7 +43,7 @@ public function test_responsive_directive_tag_cant_handle_string(): void $view = Responsive::handle($asset->url()); $asset->delete(); - $this->assertSame($view, ""); + $this->assertSame($view, ''); } #[Test] @@ -72,7 +69,7 @@ public function can_generate_glide_preset(): void 'preset' => 'xs', 'src' => $asset->url(), 'format' => null, - 'fit' => null + 'fit' => null, ] )->fetch(); @@ -90,4 +87,4 @@ public function can_get_presets_for_asset(): void $this->assertIsArray($presets); $this->assertArrayHasKey('placeholder', $presets); } -} \ No newline at end of file +} From b22220b1a5c51b4f9ed2fc2e10c0b5919878cdcf Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Mon, 21 Oct 2024 16:52:43 +0200 Subject: [PATCH 09/11] Updated dependencies --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 256ea13..2daa8fc 100644 --- a/composer.json +++ b/composer.json @@ -3,8 +3,8 @@ "description": "Addon that adds a glide blade directive", "type": "package", "require": { - "php": "^8.2|^8.3", - "laravel/framework": "^11.0", + "php": "^8.1|^8.2|^8.3", + "laravel/framework": "^10.0|^11.0", "statamic/cms": "^5.0" }, "require-dev": { From 1e64f0b299adde73095089069dbdb48ec9af4604 Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Mon, 21 Oct 2024 16:56:30 +0200 Subject: [PATCH 10/11] Updated Laravel dependency --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 2daa8fc..dccdd36 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "type": "package", "require": { "php": "^8.1|^8.2|^8.3", - "laravel/framework": "^10.0|^11.0", + "laravel/framework": "^10.40|^11.0", "statamic/cms": "^5.0" }, "require-dev": { From 866119a57f6093d6f5946bb4732cf1fc7dc8253a Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Mon, 21 Oct 2024 17:01:00 +0200 Subject: [PATCH 11/11] Changed minimum Laravel versions --- .github/workflows/analyse.yml | 4 +--- .github/workflows/coverage.yml | 4 +--- .github/workflows/tests.yml | 4 +--- composer.json | 2 +- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/.github/workflows/analyse.yml b/.github/workflows/analyse.yml index 887f8cd..885b94d 100644 --- a/.github/workflows/analyse.yml +++ b/.github/workflows/analyse.yml @@ -10,11 +10,9 @@ jobs: matrix: os: [ubuntu-latest] php: [8.3] - laravel: [10.*, 11.*] + laravel: [11.*] stability: [prefer-stable] include: - - laravel: 10.* - testbench: 8.* - laravel: 11.* testbench: 9.* diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 503bcf3..46cd0f5 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -10,11 +10,9 @@ jobs: matrix: os: [ubuntu-latest] php: [8.3] - laravel: [10.*, 11.*] + laravel: [11.*] stability: [prefer-stable] include: - - laravel: 10.* - testbench: 8.* - laravel: 11.* testbench: 9.* diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1caa61f..e302d85 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,11 +10,9 @@ jobs: matrix: os: [ ubuntu-latest ] php: [ 8.1, 8.2, 8.3 ] - laravel: [ 10.*, 11.* ] + laravel: [ 11.* ] stability: [ prefer-lowest, prefer-stable ] include: - - laravel: 10.* - testbench: 8.* - laravel: 11.* testbench: 9.* exclude: diff --git a/composer.json b/composer.json index dccdd36..028aa27 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "type": "package", "require": { "php": "^8.1|^8.2|^8.3", - "laravel/framework": "^10.40|^11.0", + "laravel/framework": "^11.0", "statamic/cms": "^5.0" }, "require-dev": {