From f29b424c005c2d501467f9cd88a678194a3c8836 Mon Sep 17 00:00:00 2001 From: Funky Waddle Date: Sat, 14 Feb 2026 23:43:17 -0600 Subject: [PATCH] feat: add closure support to RouteGroup::group() --- src/Router/RouteGroup.php | 11 ++++--- tests/Unit/RouteGroupClosureTest.php | 47 ++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 tests/Unit/RouteGroupClosureTest.php diff --git a/src/Router/RouteGroup.php b/src/Router/RouteGroup.php index 0176886..b289e35 100644 --- a/src/Router/RouteGroup.php +++ b/src/Router/RouteGroup.php @@ -31,9 +31,7 @@ class RouteGroup */ public static function create(array $options, Router $router): self { - $self = new self($options); - $self->router = $router; - return $self; + return new self($options, $router); } public function get(string $path, mixed $handler, string|null $name = null): RouteDefinition @@ -174,8 +172,13 @@ class RouteGroup return $this->joinPaths($this->options['prefix'] ?? '', $path); } - public function group(array $options): RouteGroup + public function group(array|callable $options): RouteGroup { + if (is_callable($options)) { + $options($this); + return $this; + } + $prefix = $this->options['prefix'] ?? ''; $newPrefix = $this->joinPaths($prefix, $options['prefix'] ?? ''); diff --git a/tests/Unit/RouteGroupClosureTest.php b/tests/Unit/RouteGroupClosureTest.php new file mode 100644 index 0000000..105cfdd --- /dev/null +++ b/tests/Unit/RouteGroupClosureTest.php @@ -0,0 +1,47 @@ + ['/path/to/modules']]); + $this->router = new Router($config); + } + + public function testGroupSupportsClosureRegistration(): void + { + $this->router->group(['prefix' => '/api'])->group(function($group) { + $group->get('/users', 'UserHandler'); + $group->post('/users', 'UserCreateHandler'); + }); + + $routes = iterator_to_array($this->router->getRoutes()); + $this->assertCount(2, $routes); + $this->assertSame('/api/users', $routes[0]->getPath()); + $this->assertSame('GET', $routes[0]->getMethod()); + $this->assertSame('/api/users', $routes[1]->getPath()); + $this->assertSame('POST', $routes[1]->getMethod()); + } + + public function testNestedGroupClosureInheritance(): void + { + $this->router->group(['prefix' => '/api', 'middleware' => ['auth']])->group(function($group) { + $group->group(['prefix' => '/v1'])->group(function($v1) { + $v1->get('/profile', 'ProfileHandler'); + }); + }); + + $routes = iterator_to_array($this->router->getRoutes()); + $this->assertCount(1, $routes); + $this->assertSame('/api/v1/profile', $routes[0]->getPath()); + $this->assertContains('auth', $routes[0]->getMiddleware()); + } +}