Repository: hotmeteor/spectator (php)

Issue:
Route not found when parameters are of type not string. Problematic for router model binding
[route_not_found_when_parameters_are_of_type_not_string_problematic_for_router_mode_binding.patch](https://github.com/user-attachments/files/20522930/route_not_found_when_parameters_are_of_type_not_string_problematic_for_router_mode_binding.patch)

Hi, thanks for the awesome tool!

I'm facing a big problem, I'm probably doing something wrong.
Problem is, spectator does not find routes on the schema file when path parameter have different name on laravel route definition, and this is almost always true when using router model binding.

Could you please take a look at it?

Thanks

Pull request:
Fix route matching where route declares regular expression constraints
When route is declared with regular expression constraints, the regex failed to match the route when route parameters are different between Laravel and the OpenApi definition.

This PR fixes this

fixes #210 

Patch:
diff --git a/src/Middleware.php b/src/Middleware.php
index c734e77..36334eb 100644
--- a/src/Middleware.php
+++ b/src/Middleware.php
@@ -128,6 +128,9 @@ class Middleware
         $pathMatches = false;
         $partialMatch = null;
 
+        $route->wheres = [];
+        $pathMatchRegex = $route->toSymfonyRoute()->compile()->getRegex();
+
         foreach ($openapi->paths as $path => $pathItem) {
             $resolvedPath = $this->resolvePath($path);
             $methods = array_keys($pathItem->getOperations());
@@ -140,7 +143,7 @@ class Middleware
                 }
             }
 
-            if (Str::match($route->getCompiled()->getRegex(), $resolvedPath) !== '') {
+            if (Str::match($pathMatchRegex, $resolvedPath) !== '') {
                 $pathMatches = true;
                 $requestUrlPath = '/'.ltrim($requestUrlPath, '/');
                 $regExPattern = preg_replace('/\{[^}]+\}/', '.+', $resolvedPath);
diff --git a/src/Validation/RequestValidator.php b/src/Validation/RequestValidator.php
index fc8350b..d09fcf6 100644
--- a/src/Validation/RequestValidator.php
+++ b/src/Validation/RequestValidator.php
@@ -128,7 +128,10 @@ class RequestValidator extends AbstractValidator
         /** @var \Illuminate\Routing\Route $route */
         $route = $this->request->route();
 
-        preg_match($route->getCompiled()->getRegex(), $this->specPath, $matches);
+        $route->wheres = [];
+        $regex = $route->toSymfonyRoute()->compile()->getRegex();
+
+        preg_match($regex, $this->specPath, $matches);
 
         return Collection::make($matches)
             ->filter(fn (string $value, int|string $key) => is_string($key))


Test patch:
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 00ceef5..fd92346 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -16,7 +16,7 @@ jobs:
       fail-fast: true
       matrix:
         laravel: ['10.*', '11.*', '12.*']
-        php: [8.1, 8.2, 8.3]
+        php: [8.1, 8.2, 8.3, 8.4]
         phpunit: [ '10.*', '11.*']
         include:
           - laravel: 10.*
@@ -28,6 +28,8 @@ jobs:
         exclude:
           - laravel: 10.*
             phpunit: 11.*
+          - laravel: 10.*
+            php: 8.4
           - laravel: 11.*
             php: 8.1
           - laravel: 12.*
diff --git a/tests/Fixtures/ParametersNameMismatch.v1.yml b/tests/Fixtures/ParametersNameMismatch.v1.yml
new file mode 100644
index 0000000..50232cc
--- /dev/null
+++ b/tests/Fixtures/ParametersNameMismatch.v1.yml
@@ -0,0 +1,34 @@
+openapi: 3.0.0
+info:
+  title: Global.v1
+  version: '1.0'
+servers:
+  - url: 'https://api.protect.earth/v1'
+    description: Production
+paths:
+  /testing/{id}:
+    get:
+      summary: Get org by int id
+      tags: [ ]
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                type: object
+                properties:
+                  id:
+                    type: integer
+                  name:
+                    type: string
+      operationId: get-something
+      parameters:
+        - schema:
+            type: integer
+            format: int64
+          name: id
+          in: path
+          required: true
+components:
+  schemas: {}
diff --git a/tests/RequestValidatorTest.php b/tests/RequestValidatorTest.php
index b8ba3ec..c088ebe 100644
--- a/tests/RequestValidatorTest.php
+++ b/tests/RequestValidatorTest.php
@@ -1005,6 +1005,24 @@ class RequestValidatorTest extends TestCase
         $this->patchJson('/cars/ice', ['refill' => true])
             ->assertValidRequest();
     }
+
+    public function test_route_with_parameters_on_name_mismatch_non_string(): void
+    {
+        Config::set('spectator.path_prefix', 'v1');
+
+        Spectator::using('ParametersNameMismatch.v1.yml');
+
+        Route::get('/v1/testing/{idx}', function (int $idx) {
+            return [
+                'id' => $idx,
+                'name' => 'Testing',
+            ];
+        })->whereNumber('idx')->middleware(Middleware::class);
+
+        $this->getJson('/v1/testing/100')
+            ->assertValidRequest()
+            ->assertValidResponse(200);
+    }
 }
 
 class TestUser extends Model