summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Enums/PathSegmentType.php15
-rw-r--r--src/PathSegment.php13
-rw-r--r--src/PathSegmentTypeMatch.php13
-rw-r--r--src/Router.php3
-rw-r--r--tests/Unit/Enums/PathSegmentTypeTest.php14
-rw-r--r--tests/Unit/PathSegmentTest.php14
-rw-r--r--tests/Unit/PathSegmentTypeMatchTest.php14
-rw-r--r--tests/Unit/RouterTest.php32
8 files changed, 90 insertions, 28 deletions
diff --git a/src/Enums/PathSegmentType.php b/src/Enums/PathSegmentType.php
index 43113e6..7cb1a51 100644
--- a/src/Enums/PathSegmentType.php
+++ b/src/Enums/PathSegmentType.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Lightscale\Router\Enums;
+use Lightscale\Router\PathSegmentTypeMatch;
+
enum PathSegmentType
{
case Raw;
@@ -17,4 +19,17 @@ enum PathSegmentType
default => null,
};
}
+
+ public static function matchRouteString(string $value): PathSegmentTypeMatch
+ {
+ $type = PathSegmentType::Parameter;
+ $regex = $type->routeMatchRegex();
+ if (preg_match($regex, $value, $matches) === 1) {
+ $value = $matches[1];
+ }
+ else {
+ $type = PathSegmentType::Raw;
+ }
+ return new PathSegmentTypeMatch( $type, $value);
+ }
}
diff --git a/src/PathSegment.php b/src/PathSegment.php
index d55102f..2fc4cbb 100644
--- a/src/PathSegment.php
+++ b/src/PathSegment.php
@@ -29,19 +29,6 @@ class PathSegment
}
}
- public static function makeFromRouteString(string $value): static
- {
- $type = PathSegmentType::Parameter;
- $regex = $type->routeMatchRegex();
- if (preg_match($regex, $value, $matches) === 1) {
- $value = $matches[1];
- }
- else {
- $type = PathSegmentType::Raw;
- }
- return new static($value, $type);
- }
-
public function getContent(): string
{
return match ($this->type) {
diff --git a/src/PathSegmentTypeMatch.php b/src/PathSegmentTypeMatch.php
new file mode 100644
index 0000000..4e32bdb
--- /dev/null
+++ b/src/PathSegmentTypeMatch.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Lightscale\Router;
+
+use Lightscale\Router\Enums\PathSegmentType;
+
+readonly class PathSegmentTypeMatch
+{
+ final public function __construct(
+ public PathSegmentType $type,
+ public string $value,
+ ) {}
+}
diff --git a/src/Router.php b/src/Router.php
index 4463150..1c5e087 100644
--- a/src/Router.php
+++ b/src/Router.php
@@ -126,7 +126,8 @@ class Router
$seg = $this->root();
while (($v = array_shift($pathSplit)) !== null) {
- $seg = $seg->child($v);
+ $typeMatch = PathSegmentType::matchRouteString($v);
+ $seg = $seg->child($typeMatch->value, $typeMatch->type);
}
$route = new Route($method, $handler);
diff --git a/tests/Unit/Enums/PathSegmentTypeTest.php b/tests/Unit/Enums/PathSegmentTypeTest.php
index f2fda0a..a0a638d 100644
--- a/tests/Unit/Enums/PathSegmentTypeTest.php
+++ b/tests/Unit/Enums/PathSegmentTypeTest.php
@@ -15,3 +15,17 @@ it('has no routeMatchRegex for Root')
it('has routeMatchRegex for Parameter')
->expect(fn () => PathSegmentType::Parameter->routeMatchRegex())
->toBeString();
+
+it('matches from route string :dataset', function (string $v, PathSegmentType $type) {
+ $match = PathSegmentType::matchRouteString($v);
+ expect($match->type)->toBe($type);
+})->with([
+ $v = '{test-test}' => [$v, PathSegmentType::Parameter],
+ $v = '{test_test}' => [$v, PathSegmentType::Parameter],
+ $v = '{testTest}' => [$v, PathSegmentType::Parameter],
+ $v = '{TestTest}' => [$v, PathSegmentType::Parameter],
+ $v = '{testTest912}' => [$v, PathSegmentType::Parameter],
+ $v = 'hello-hello' => [$v, PathSegmentType::Raw],
+ $v = 'hellohello123' => [$v, PathSegmentType::Raw],
+ $v = 'hello_hello' => [$v, PathSegmentType::Raw],
+]);
diff --git a/tests/Unit/PathSegmentTest.php b/tests/Unit/PathSegmentTest.php
index 62c6ec9..ffad95f 100644
--- a/tests/Unit/PathSegmentTest.php
+++ b/tests/Unit/PathSegmentTest.php
@@ -57,20 +57,6 @@ it('gets type :dataset', function (PathSegmentType $type) {
}
});
-it('is made from route string :dataset', function (string $v, PathSegmentType $type) {
- $seg = PathSegment::makeFromRouteString($v);
- expect($seg->getType())->toBe($type);
-})->with([
- $v = '{test-test}' => [$v, PathSegmentType::Parameter],
- $v = '{test_test}' => [$v, PathSegmentType::Parameter],
- $v = '{testTest}' => [$v, PathSegmentType::Parameter],
- $v = '{TestTest}' => [$v, PathSegmentType::Parameter],
- $v = '{testTest912}' => [$v, PathSegmentType::Parameter],
- $v = 'hello-hello' => [$v, PathSegmentType::Raw],
- $v = 'hellohello123' => [$v, PathSegmentType::Raw],
- $v = 'hello_hello' => [$v, PathSegmentType::Raw],
-]);
-
it('defaults type to Raw')
->expect(fn () => (new PathSegment('testing'))->getType())
->toBe(PathSegmentType::Raw);
diff --git a/tests/Unit/PathSegmentTypeMatchTest.php b/tests/Unit/PathSegmentTypeMatchTest.php
new file mode 100644
index 0000000..8a4e70d
--- /dev/null
+++ b/tests/Unit/PathSegmentTypeMatchTest.php
@@ -0,0 +1,14 @@
+<?php
+
+declare(strict_types=1);
+
+use Lightscale\Router\Enums\PathSegmentType;
+use Lightscale\Router\PathSegmentTypeMatch;
+
+it('initializes with data')
+ ->expect(fn () => new PathSegmentTypeMatch(
+ PathSegmentType::Raw,
+ 'hello'
+ ))
+ ->type->toBe(PathSegmentType::Raw)
+ ->value->toBe('hello');
diff --git a/tests/Unit/RouterTest.php b/tests/Unit/RouterTest.php
index d55fbd2..497772d 100644
--- a/tests/Unit/RouterTest.php
+++ b/tests/Unit/RouterTest.php
@@ -6,6 +6,7 @@ use Lightscale\Router\BasicStrategy;
use Lightscale\Router\Contracts\Strategy;
use Lightscale\Router\Enums\HttpMethod;
use Lightscale\Router\Enums\PathSegmentType;
+use Lightscale\Router\Exceptions\MissingParameterException;
use Lightscale\Router\PathSegment;
use Lightscale\Router\Route;
use Lightscale\Router\RouteCall;
@@ -208,6 +209,15 @@ it('make a route', function () {
->toBeInstanceOf(RouteMatch::class);
});
+it('make a route with parameter', function() {
+ $router = new Router();
+ $router->make(HttpMethod::Get, '/test/{test1}/hello', fn() => null);
+
+ expect($router->findSegment('/test/hello'))
+ ->not->toBeNull()
+ ->parameters->toBe(['test1' => 'hello']);
+});
+
it('makes a get route', function () {
$router = new Router();
$router->get('/test1/test2', fn () => null);
@@ -278,3 +288,25 @@ it('generates route from name', function() {
expect($router->route('test'))->toBe('/test');
});
+it('generates route with parameters from name', function() {
+ $router = new Router();
+ $router->get('/test/{test1}/hello', fn() => null)->name('test');
+
+ expect($router->route('test', [
+ 'test1' => 'world'
+ ]))->toBe('/test/world/hello');
+});
+
+it('throws when generating route with missing parameter from name', function() {
+ $router = new Router();
+ $router->get('/test/{test1}/hello', fn() => null)->name('test');
+
+ $router->route('test', []);
+})->throws(MissingParameterException::class);
+
+it('throws when generating route with non string parameter from name', function() {
+ $router = new Router();
+ $router->get('/test/{test1}/hello', fn() => null)->name('test');
+
+ $router->route('test', ['test1' => 123]);
+})->throws(InvalidArgumentException::class);