diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d0c8cfb9..7b2eb4dc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,17 +5,25 @@ on: push: branches: [main, next, ci] paths-ignore: ['dist/**', '*.md'] +concurrency: + group: ${{ github.ref_name }} + cancel-in-progress: true jobs: test: - name: ${{ matrix.os[0] }}, PHP ${{ matrix.php }}, Laravel ${{ matrix.laravel }}, prefer-${{ matrix.dependencies }} + name: ${{ matrix.os[0] }}, PHP ${{ matrix.php }}, Laravel ${{ matrix.laravel }} runs-on: ${{ matrix.os[1] }} continue-on-error: ${{ matrix.php == 8.3 }} strategy: matrix: os: [[Ubuntu, ubuntu-latest], [Windows, windows-latest]] - php: [8.1, 8.2] - laravel: [9.*, 10.*] - dependencies: [lowest, highest] + php: [8.1, 8.2, 8.3] + laravel: [9, 10, 11] + exclude: + - php: 8.1 + laravel: 11 + include: + - php: 8.3 + composer: --ignore-platform-req=php+ steps: - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 @@ -24,12 +32,12 @@ jobs: extensions: fileinfo - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20 cache: 'npm' + - run: composer require laravel/framework:"${{ matrix.laravel }}.*" --no-update --no-interaction - uses: ramsey/composer-install@v2 with: - dependency-versions: ${{ matrix.dependencies }} - composer-options: ${{ matrix.php == 8.3 && '--ignore-platform-req=php+' || '' }} + composer-options: ${{ matrix.composer }} - run: vendor/bin/phpunit --testdox --colors=always - run: npm ci && npm run build - run: npm run test diff --git a/README.md b/README.md index 436f3768..88ddf42b 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,6 @@ Ziggy provides a JavaScript `route()` function that works like Laravel's, making it a breeze to use your named Laravel routes in JavaScript. -Ziggy supports all versions of Laravel from `5.4` onward, and all modern browsers. - - [**Installation**](#installation) - [**Usage**](#usage) - [`route()` function](#route-function) diff --git a/composer.json b/composer.json index 98e65f8a..342c2c03 100644 --- a/composer.json +++ b/composer.json @@ -24,13 +24,13 @@ } ], "require": { - "php": "~8.1.0", + "php": ">=8.1", "ext-json": "*", - "laravel/framework": "^9.0" + "laravel/framework": ">=9.0" }, "require-dev": { - "orchestra/testbench": "^7.0", - "phpunit/phpunit": "^9.0" + "orchestra/testbench": "^7.0 || ^8.0 || ^9.0", + "phpunit/phpunit": "^9.5 || ^10.3" }, "autoload": { "psr-4": { diff --git a/src/BladeRouteGenerator.php b/src/BladeRouteGenerator.php index 795f103f..f1b1cea9 100644 --- a/src/BladeRouteGenerator.php +++ b/src/BladeRouteGenerator.php @@ -35,6 +35,6 @@ private function generateMergeJavascript(Ziggy $ziggy, $nonce) private function getRouteFunction() { - return config('ziggy.skip-route-function') ? '' : file_get_contents(__DIR__ . '/../dist/index.js'); + return config('ziggy.skip-route-function') ? '' : file_get_contents(__DIR__ . '/../dist/route.umd.js'); } } diff --git a/src/Output/Types.php b/src/Output/Types.php index 45ba303c..5b7a8fd2 100644 --- a/src/Output/Types.php +++ b/src/Output/Types.php @@ -1,10 +1,10 @@ version())); - - return isset($v) ? $version >= $v : $version; - } - protected function noop(): Closure { return function () { diff --git a/tests/Unit/CommandRouteGeneratorTest.php b/tests/Unit/CommandRouteGeneratorTest.php index d38e4e47..520b4076 100644 --- a/tests/Unit/CommandRouteGeneratorTest.php +++ b/tests/Unit/CommandRouteGeneratorTest.php @@ -165,10 +165,6 @@ public function can_generate_dts_file() /** @test */ public function can_generate_dts_file_with_scoped_bindings() { - if (! $this->laravelVersion(7)) { - $this->markTestSkipped('Requires Laravel >=7'); - } - app('router')->get('posts', $this->noop())->name('posts.index'); app('router')->get('posts/{post}/comments/{comment:uuid}', PostCommentController::class)->name('postComments.show'); app('router')->post('posts/{post}/comments', PostCommentController::class)->name('postComments.store'); @@ -197,7 +193,7 @@ public function can_generate_dts_file_without_routes() Artisan::call('ziggy:generate', ['--types-only' => true]); $this->assertFileExists(base_path('resources/js/ziggy.d.ts')); - $this->assertFileNotExists(base_path('resources/js/ziggy.js')); + $this->assertFileDoesNotExist(base_path('resources/js/ziggy.js')); } /** @test */ @@ -211,7 +207,7 @@ public function can_derive_dts_file_path_from_given_path() Artisan::call('ziggy:generate', ['--types-only' => true]); $this->assertFileExists(base_path('resources/js/custom.d.ts')); - $this->assertFileNotExists(base_path('resources/js/ziggy.d.ts')); + $this->assertFileDoesNotExist(base_path('resources/js/ziggy.d.ts')); } } diff --git a/tests/Unit/RouteModelBindingTest.php b/tests/Unit/RouteModelBindingTest.php index b67fc052..9ad92e17 100644 --- a/tests/Unit/RouteModelBindingTest.php +++ b/tests/Unit/RouteModelBindingTest.php @@ -38,15 +38,12 @@ protected function setUp(): void $router->get('replies/{reply}', function (Reply $reply) { return ''; })->name('replies'); - - if ($this->laravelVersion(7)) { - $router->get('blog/{category}/{post:slug}', function (PostCategory $category, Post $post) { - return ''; - })->name('posts'); - $router->get('blog/{category}/{post:slug}/{tag:slug}', function (PostCategory $category, Post $post, Tag $tag) { - return ''; - })->name('posts.tags'); - } + $router->get('blog/{category}/{post:slug}', function (PostCategory $category, Post $post) { + return ''; + })->name('posts'); + $router->get('blog/{category}/{post:slug}/{tag:slug}', function (PostCategory $category, Post $post, Tag $tag) { + return ''; + })->name('posts.tags'); $router->getRoutes()->refreshNameLookups(); } @@ -128,10 +125,6 @@ public function can_handle_bound_and_unbound_parameters_in_the_same_route() /** @test */ public function can_handle_multiple_scoped_bindings() { - if (! $this->laravelVersion(7)) { - $this->markTestSkipped('Requires Laravel >=7'); - } - $this->assertSame([ 'posts' => [ 'uri' => 'blog/{category}/{post}', @@ -158,10 +151,6 @@ public function can_handle_multiple_scoped_bindings() /** @test */ public function can_merge_implicit_and_scoped_bindings() { - if (! $this->laravelVersion(7)) { - $this->markTestSkipped('Requires Laravel >=7'); - } - $this->assertSame([ 'users' => [ 'uri' => 'users/{user}', @@ -245,10 +234,6 @@ public function can_merge_implicit_and_scoped_bindings() /** @test */ public function can_include_bindings_in_json() { - if (! $this->laravelVersion(7)) { - $this->markTestSkipped('Requires Laravel >=7'); - } - $json = '{"url":"http:\/\/ziggy.dev","port":null,"defaults":{},"routes":{"users":{"uri":"users\/{user}","methods":["GET","HEAD"],"parameters":["user"],"bindings":{"user":"uuid"}},"admins":{"uri":"admins\/{admin}","methods":["GET","HEAD"],"parameters":["admin"],"bindings":{"admin":"uuid"}},"tags":{"uri":"tags\/{tag}","methods":["GET","HEAD"],"parameters":["tag"],"bindings":{"tag":"id"}},"tokens":{"uri":"tokens\/{token}","methods":["GET","HEAD"],"parameters":["token"]},"users.numbers":{"uri":"users\/{user}\/{number}","methods":["GET","HEAD"],"parameters":["user","number"],"bindings":{"user":"uuid"}},"users.store":{"uri":"users","methods":["POST"]},"comments":{"uri":"comments\/{comment}","methods":["GET","HEAD"],"parameters":["comment"],"bindings":{"comment":"uuid"}},"replies":{"uri":"replies\/{reply}","methods":["GET","HEAD"],"parameters":["reply"],"bindings":{"reply":"uuid"}},"posts":{"uri":"blog\/{category}\/{post}","methods":["GET","HEAD"],"parameters":["category","post"],"bindings":{"category":"id","post":"slug"}},"posts.tags":{"uri":"blog\/{category}\/{post}\/{tag}","methods":["GET","HEAD"],"parameters":["category","post","tag"],"bindings":{"category":"id","post":"slug","tag":"slug"}}}}'; $this->assertSame($json, (new Ziggy)->toJson()); diff --git a/tests/Unit/ZiggyTest.php b/tests/Unit/ZiggyTest.php index f05ddba5..597ff4c9 100644 --- a/tests/Unit/ZiggyTest.php +++ b/tests/Unit/ZiggyTest.php @@ -19,31 +19,11 @@ protected function setUp(): void $router->get('posts/{post}/comments', $this->noop())->name('postComments.index'); $router->post('posts', $this->noop())->middleware(['auth', 'role:admin'])->name('posts.store'); $router->get('admin/users', $this->noop())->middleware(['role:admin'])->name('admin.users.index'); - - if ($this->laravelVersion(7)) { - $router->get('/posts/{post}/comments/{comment:uuid}', $this->noop())->name('postComments.show'); - } + $router->get('/posts/{post}/comments/{comment:uuid}', $this->noop())->name('postComments.show'); $router->getRoutes()->refreshNameLookups(); } - /** - * If running Laravel 7 or higher, add the 'postComments.show' route. - */ - protected function addPostCommentsRouteWithBindings(array &$routes): void - { - if ($this->laravelVersion(7)) { - $routes['postComments.show'] = [ - 'uri' => 'posts/{post}/comments/{comment}', - 'methods' => ['GET', 'HEAD'], - 'parameters' => ['post', 'comment'], - 'bindings' => [ - 'comment' => 'uuid', - ], - ]; - } - } - /** @test */ public function can_filter_to_only_include_routes_matching_a_pattern() { @@ -85,10 +65,16 @@ public function can_filter_to_exclude_routes_matching_a_pattern() 'methods' => ['GET', 'HEAD'], 'parameters' => ['post'], ], + 'postComments.show' => [ + 'uri' => 'posts/{post}/comments/{comment}', + 'methods' => ['GET', 'HEAD'], + 'parameters' => ['post', 'comment'], + 'bindings' => [ + 'comment' => 'uuid', + ], + ], ]; - $this->addPostCommentsRouteWithBindings($expected); - $this->assertSame($expected, $routes->toArray()['routes']); } @@ -133,10 +119,16 @@ public function can_set_excluded_routes_using_except_config() 'methods' => ['GET', 'HEAD'], 'parameters' => ['post'], ], + 'postComments.show' => [ + 'uri' => 'posts/{post}/comments/{comment}', + 'methods' => ['GET', 'HEAD'], + 'parameters' => ['post', 'comment'], + 'bindings' => [ + 'comment' => 'uuid', + ], + ], ]; - $this->addPostCommentsRouteWithBindings($expected); - $this->assertSame($expected, $routes); } @@ -176,10 +168,16 @@ public function returns_unfiltered_routes_when_both_only_and_except_configs_set( 'uri' => 'admin/users', 'methods' => ['GET', 'HEAD'], ], + 'postComments.show' => [ + 'uri' => 'posts/{post}/comments/{comment}', + 'methods' => ['GET', 'HEAD'], + 'parameters' => ['post', 'comment'], + 'bindings' => [ + 'comment' => 'uuid', + ], + ], ]; - $this->addPostCommentsRouteWithBindings($expected); - $this->assertSame($expected, $routes); } @@ -294,10 +292,16 @@ public function can_filter_routes_from_multiple_groups_using_negative_patterns() 'uri' => 'admin/users', 'methods' => ['GET', 'HEAD'], ], + 'postComments.show' => [ + 'uri' => 'posts/{post}/comments/{comment}', + 'methods' => ['GET', 'HEAD'], + 'parameters' => ['post', 'comment'], + 'bindings' => [ + 'comment' => 'uuid', + ], + ], ]; - $this->addPostCommentsRouteWithBindings($expected); - $this->assertSame($expected, $routes); } @@ -334,10 +338,16 @@ public function can_ignore_passed_group_not_set_in_config() 'uri' => 'admin/users', 'methods' => ['GET', 'HEAD'], ], + 'postComments.show' => [ + 'uri' => 'posts/{post}/comments/{comment}', + 'methods' => ['GET', 'HEAD'], + 'parameters' => ['post', 'comment'], + 'bindings' => [ + 'comment' => 'uuid', + ], + ], ]; - $this->addPostCommentsRouteWithBindings($expected); - $this->assertSame($expected, $routes); } @@ -376,10 +386,16 @@ public function can_include_middleware() 'methods' => ['GET', 'HEAD'], 'middleware' => ['role:admin'], ], + 'postComments.show' => [ + 'uri' => 'posts/{post}/comments/{comment}', + 'methods' => ['GET', 'HEAD'], + 'parameters' => ['post', 'comment'], + 'bindings' => [ + 'comment' => 'uuid', + ], + ], ]; - $this->addPostCommentsRouteWithBindings($expected); - $this->assertEquals($expected, $routes); } @@ -467,10 +483,16 @@ public function can_include_only_middleware_set_in_config() 'uri' => 'admin/users', 'methods' => ['GET', 'HEAD'], ], + 'postComments.show' => [ + 'uri' => 'posts/{post}/comments/{comment}', + 'methods' => ['GET', 'HEAD'], + 'parameters' => ['post', 'comment'], + 'bindings' => [ + 'comment' => 'uuid', + ], + ], ]; - $this->addPostCommentsRouteWithBindings($expected); - $this->assertEquals($expected, $routes); } @@ -510,22 +532,26 @@ public function can_order_fallback_routes_last() 'uri' => 'admin/users', 'methods' => ['GET', 'HEAD'], ], - ]; - - $this->addPostCommentsRouteWithBindings($expected); - - $expected['users.index'] = [ - 'uri' => 'users', - 'methods' => ['GET', 'HEAD'], - ]; - - $expected['fallback'] = [ - 'uri' => '{fallbackPlaceholder}', - 'methods' => ['GET', 'HEAD'], - 'wheres' => [ - 'fallbackPlaceholder' => '.*', + 'postComments.show' => [ + 'uri' => 'posts/{post}/comments/{comment}', + 'methods' => ['GET', 'HEAD'], + 'parameters' => ['post', 'comment'], + 'bindings' => [ + 'comment' => 'uuid', + ], + ], + 'users.index' => [ + 'uri' => 'users', + 'methods' => ['GET', 'HEAD'], + ], + 'fallback' => [ + 'uri' => '{fallbackPlaceholder}', + 'methods' => ['GET', 'HEAD'], + 'wheres' => [ + 'fallbackPlaceholder' => '.*', + ], + 'parameters' => ['fallbackPlaceholder'], ], - 'parameters' => ['fallbackPlaceholder'], ]; $this->assertSame($expected, $routes); @@ -567,11 +593,17 @@ public function route_payload_can_array_itself() 'uri' => 'admin/users', 'methods' => ['GET', 'HEAD'], ], + 'postComments.show' => [ + 'uri' => 'posts/{post}/comments/{comment}', + 'methods' => ['GET', 'HEAD'], + 'parameters' => ['post', 'comment'], + 'bindings' => [ + 'comment' => 'uuid', + ], + ], ], ]; - $this->addPostCommentsRouteWithBindings($expected['routes']); - $this->assertSame($expected, $ziggy->toArray()); } @@ -590,20 +622,18 @@ public function route_payload_can_json_itself() 'methods' => ['GET', 'HEAD'], 'parameters' => ['post'], ], + 'postComments.show' => [ + 'uri' => 'posts/{post}/comments/{comment}', + 'methods' => ['GET', 'HEAD'], + 'parameters' => ['post', 'comment'], + 'bindings' => [ + 'comment' => 'uuid', + ], + ], ], ]; - $this->addPostCommentsRouteWithBindings($expected['routes']); - - $json = '{"url":"http:\/\/ziggy.dev","port":null,"defaults":{},"routes":{"postComments.index":{"uri":"posts\/{post}\/comments","methods":["GET","HEAD"],"parameters":["post"]}}}'; - - if ($this->laravelVersion(7)) { - $json = str_replace( - '}}}', - '},"postComments.show":{"uri":"posts\/{post}\/comments\/{comment}","methods":["GET","HEAD"],"parameters":["post","comment"],"bindings":{"comment":"uuid"}}}}', - $json, - ); - } + $json = '{"url":"http:\/\/ziggy.dev","port":null,"defaults":{},"routes":{"postComments.index":{"uri":"posts\/{post}\/comments","methods":["GET","HEAD"],"parameters":["post"]},"postComments.show":{"uri":"posts\/{post}\/comments\/{comment}","methods":["GET","HEAD"],"parameters":["post","comment"],"bindings":{"comment":"uuid"}}}}'; $this->assertSame($expected, json_decode(json_encode(new Ziggy), true)); $this->assertSame($json, json_encode(new Ziggy));