Lots more unit testing for group based routing

pull/506/head
Austin Collier 1 year ago
parent a3555b019f
commit 65b3d5445f

@ -313,17 +313,24 @@ You can even nest groups of groups:
```php
Flight::group('/api', function () {
Flight::group('/v1', function () {
Flight::route('/users', function () {
// Matches /api/v1/users
// Flight::get() gets variables, it doesn't set a route! See object context below
Flight::route('GET /users', function () {
// Matches GET /api/v1/users
});
Flight::route('/posts', function () {
// Matches /api/v1/posts
Flight::post('/posts', function () {
// Matches POST /api/v1/posts
});
Flight::put('/posts/1', function () {
// Matches PUT /api/v1/posts
});
});
Flight::group('/v2', function () {
Flight::route('/users', function () {
// Matches /api/v2/users
// Flight::get() gets variables, it doesn't set a route! See object context below
Flight::route('GET /users', function () {
// Matches GET /api/v2/users
});
});
});
@ -336,12 +343,12 @@ You can still use route grouping with the `Engine` object in the following way:
```php
$app = new \flight\Engine();
$app->group('/api/v1', function (Router $router) {
$router->map('/users', function () {
// Matches /api/v1/users
$router->get('/users', function () {
// Matches GET /api/v1/users
});
$router->map('/posts', function () {
// Matches /api/v1/posts
$router->post('/posts', function () {
// Matches POST /api/v1/posts
});
});
```

@ -34,7 +34,6 @@ use Throwable;
* Routing
* @method void route(string $pattern, callable $callback, bool $pass_route = false) Routes a URL to a callback function.
* @method void group(string $pattern, callable $callback) Groups a set of routes together under a common prefix.
* @method void get(string $pattern, callable $callback, bool $pass_route = false) Routes a GET URL to a callback function.
* @method void post(string $pattern, callable $callback, bool $pass_route = false) Routes a POST URL to a callback function.
* @method void put(string $pattern, callable $callback, bool $pass_route = false) Routes a PUT URL to a callback function.
* @method void patch(string $pattern, callable $callback, bool $pass_route = false) Routes a PATCH URL to a callback function.

@ -25,6 +25,10 @@ use flight\template\View;
*
* @method static void route(string $pattern, callable $callback, bool $pass_route = false) Maps a URL pattern to a callback.
* @method static void group(string $pattern, callable $callback) Groups a set of routes together under a common prefix.
* @method void post(string $pattern, callable $callback, bool $pass_route = false) Routes a POST URL to a callback function.
* @method void put(string $pattern, callable $callback, bool $pass_route = false) Routes a PUT URL to a callback function.
* @method void patch(string $pattern, callable $callback, bool $pass_route = false) Routes a PATCH URL to a callback function.
* @method void delete(string $pattern, callable $callback, bool $pass_route = false) Routes a DELETE URL to a callback function.
* @method static Router router() Returns Router instance.
*
* @method static void map(string $name, callable $callback) Creates a custom framework method.
@ -124,11 +128,22 @@ class Flight
if (!$initialized) {
require_once __DIR__ . '/autoload.php';
self::$engine = new Engine();
self::setEngine(new Engine());
$initialized = true;
}
return self::$engine;
}
/**
* Set the engine instance
*
* @param Engine $engine Vroom vroom!
* @return void
*/
public static function setEngine(Engine $engine): void
{
self::$engine = $engine;
}
}

@ -63,10 +63,11 @@ class Router
* @param string $pattern URL pattern to match
* @param callable $callback Callback function
* @param bool $pass_route Pass the matching route object to the callback
* @return void
*/
public function map(string $pattern, callable $callback, bool $pass_route = false): void
{
$url = $this->group_prefix.trim($pattern);
$url = trim($pattern);
$methods = ['*'];
if (false !== strpos($url, ' ')) {
@ -75,9 +76,69 @@ class Router
$methods = explode('|', $method);
}
$this->routes[] = new Route($url, $callback, $methods, $pass_route);
$this->routes[] = new Route($this->group_prefix.$url, $callback, $methods, $pass_route);
}
/**
* Creates a GET based route
*
* @param string $pattern URL pattern to match
* @param callable $callback Callback function
* @param bool $pass_route Pass the matching route object to the callback
* @return void
*/
public function get(string $pattern, callable $callback, bool $pass_route = false): void {
$this->map('GET ' . $pattern, $callback, $pass_route);
}
/**
* Creates a POST based route
*
* @param string $pattern URL pattern to match
* @param callable $callback Callback function
* @param bool $pass_route Pass the matching route object to the callback
* @return void
*/
public function post(string $pattern, callable $callback, bool $pass_route = false): void {
$this->map('POST ' . $pattern, $callback, $pass_route);
}
/**
* Creates a PUT based route
*
* @param string $pattern URL pattern to match
* @param callable $callback Callback function
* @param bool $pass_route Pass the matching route object to the callback
* @return void
*/
public function put(string $pattern, callable $callback, bool $pass_route = false): void {
$this->map('PUT ' . $pattern, $callback, $pass_route);
}
/**
* Creates a PATCH based route
*
* @param string $pattern URL pattern to match
* @param callable $callback Callback function
* @param bool $pass_route Pass the matching route object to the callback
* @return void
*/
public function patch(string $pattern, callable $callback, bool $pass_route = false): void {
$this->map('PATCH ' . $pattern, $callback, $pass_route);
}
/**
* Creates a DELETE based route
*
* @param string $pattern URL pattern to match
* @param callable $callback Callback function
* @param bool $pass_route Pass the matching route object to the callback
* @return void
*/
public function delete(string $pattern, callable $callback, bool $pass_route = false): void {
$this->map('DELETE ' . $pattern, $callback, $pass_route);
}
/**
* Group together a set of routes
*

@ -1,5 +1,6 @@
<?php
use flight\Engine;
use flight\net\Request;
use flight\net\Response;
use flight\net\Router;
@ -18,11 +19,13 @@ class FlightTest extends PHPUnit\Framework\TestCase
$_SERVER = [];
$_REQUEST = [];
Flight::init();
Flight::setEngine(new Engine());
}
protected function tearDown(): void {
unset($_REQUEST);
unset($_SERVER);
Flight::clear();
}
// Checks that default components are loaded
@ -102,10 +105,9 @@ class FlightTest extends PHPUnit\Framework\TestCase
echo 'test';
});
Flight::request()->url = '/test';
$this->expectOutputString('test');
Flight::start();
}
public function testStaticRouteGroup() {
@ -118,6 +120,71 @@ class FlightTest extends PHPUnit\Framework\TestCase
$this->expectOutputString('test');
Flight::start();
}
public function testStaticRouteGet() {
// can't actually get "get" because that gets a variable
Flight::route('GET /test', function() {
echo 'test get';
});
$_SERVER['REQUEST_METHOD'] = 'GET';
Flight::request()->url = '/test';
$this->expectOutputString('test get');
Flight::start();
}
public function testStaticRoutePost() {
Flight::post('/test', function() {
echo 'test post';
});
$_SERVER['REQUEST_METHOD'] = 'POST';
Flight::request()->url = '/test';
$this->expectOutputString('test post');
Flight::start();
}
public function testStaticRoutePut() {
Flight::put('/test', function() {
echo 'test put';
});
$_SERVER['REQUEST_METHOD'] = 'PUT';
Flight::request()->url = '/test';
$this->expectOutputString('test put');
Flight::start();
}
public function testStaticRoutePatch() {
Flight::patch('/test', function() {
echo 'test patch';
});
$_SERVER['REQUEST_METHOD'] = 'PATCH';
Flight::request()->url = '/test';
$this->expectOutputString('test patch');
Flight::start();
}
public function testStaticRouteDelete() {
Flight::delete('/test', function() {
echo 'test delete';
});
$_SERVER['REQUEST_METHOD'] = 'DELETE';
Flight::request()->url = '/test';
$this->expectOutputString('test delete');
Flight::start();
}
}

@ -106,7 +106,6 @@ class RouterTest extends PHPUnit\Framework\TestCase
}
// Simple path with trailing slash
// Simple path
public function testPathRouteTrailingSlash()
{
$this->router->map('/path/', [$this, 'ok']);
@ -115,6 +114,15 @@ class RouterTest extends PHPUnit\Framework\TestCase
$this->check('OK');
}
public function testGetRouteShortcut()
{
$this->router->get('/path', [$this, 'ok']);
$this->request->url = '/path';
$this->request->method = 'GET';
$this->check('OK');
}
// POST route
public function testPostRoute()
{
@ -125,6 +133,15 @@ class RouterTest extends PHPUnit\Framework\TestCase
$this->check('OK');
}
public function testPostRouteShortcut()
{
$this->router->post('/path', [$this, 'ok']);
$this->request->url = '/path';
$this->request->method = 'POST';
$this->check('OK');
}
// Either GET or POST route
public function testGetPostRoute()
{
@ -135,6 +152,30 @@ class RouterTest extends PHPUnit\Framework\TestCase
$this->check('OK');
}
public function testPutRouteShortcut() {
$this->router->put('/path', [$this, 'ok']);
$this->request->url = '/path';
$this->request->method = 'PUT';
$this->check('OK');
}
public function testPatchRouteShortcut() {
$this->router->patch('/path', [$this, 'ok']);
$this->request->url = '/path';
$this->request->method = 'PATCH';
$this->check('OK');
}
public function testDeleteRouteShortcut() {
$this->router->delete('/path', [$this, 'ok']);
$this->request->url = '/path';
$this->request->method = 'DELETE';
$this->check('OK');
}
// Test regular expression matching
public function testRegEx()
{
@ -403,4 +444,21 @@ class RouterTest extends PHPUnit\Framework\TestCase
$this->request->url = '/client/user/123/abc';
$this->check('123abc');
}
public function testGroupNestedRoutesWithCustomMethods()
{
$this->router->group('/client', function(Router $router) {
$router->group('/user', function(Router $router) {
$router->get('/@id', function ($id) {
echo $id;
});
$router->post('/@id/@name', function ($id, $name) {
echo $id . $name;
});
});
});
$this->request->url = '/client/user/123/abc';
$this->request->method = 'POST';
$this->check('123abc');
}
}

Loading…
Cancel
Save