Skip to content
This repository has been archived by the owner on Dec 12, 2021. It is now read-only.

Commit

Permalink
Magic method added to catch http request methods
Browse files Browse the repository at this point in the history
- defined routes removed from constructor which breaks BC
- __call magic method added to let router set http request methods using method call
- More exceptions defined
- Tests added/changed for changes
  • Loading branch information
mkorkmaz committed Jan 3, 2017
1 parent a10276c commit 87baef0
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 25 deletions.
64 changes: 46 additions & 18 deletions src/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
*
* @license https://github.com/selamiphp/router/blob/master/LICENSE (MIT License)
* @link https://github.com/selamiphp/router
* @package router
* @category library
*/

declare(strict_types = 1);
Expand All @@ -13,6 +15,7 @@

use FastRoute;
use InvalidArgumentException;
use UnexpectedValueException;

/**
* Router
Expand Down Expand Up @@ -93,6 +96,7 @@ final class Router
/**
* Valid Request Methods array.
* Make sures about return type.
* Index 0 is also default value.
* @var array
*/
private static $validReturnTypes = [
Expand All @@ -107,12 +111,11 @@ final class Router
* Router constructor.
* Create new router.
*
* @param array $routes
* @param string $defaultReturnType
* @param string $method
* @param string $requestedPath
* @param string $folder
* @throws InvalidArgumentException
* @throws UnexpectedValueException
*/
public function __construct(
string $defaultReturnType,
Expand All @@ -121,12 +124,12 @@ public function __construct(
string $folder = ''
) {
if (!in_array($method, self::$validRequestMethods, true)) {
$message = sprintf('%s is nat valid Http request method.', $method);
throw new InvalidArgumentException($message);
$message = sprintf('%s is not valid Http request method.', $method);
throw new UnexpectedValueException($message);
}
$this->method = $method;
$this->requestedPath = $this->extractFolder($requestedPath, $folder);
$this->defaultReturnType = self::$translations[$defaultReturnType] ?? self::$defaultReturnType[0];
$this->defaultReturnType = self::$translations[$defaultReturnType] ?? self::$validReturnTypes[0];
}

/**
Expand All @@ -153,39 +156,64 @@ private function extractFolder(string $requestPath, string $folder)
* @param string $action
* @param string $returnType
* @param string $alias
* @return string
* @throws InvalidArgumentException
* @throws UnexpectedValueException
*/
public function add($requestMethods, string $route, string $action, string $returnType=null, string $alias=null)
{
$requestMethodParameterType = gettype($requestMethods);
if (!in_array($requestMethodParameterType, ['array', 'string'], true)) {
$message = sprintf(
'Request method must be either string or array but %s given.',
$requestMethodParameterType);
throw new InvalidArgumentException($message);
}
$requestMethodsGiven = is_array($requestMethods) ? (array) $requestMethods : [0 => $requestMethods];
$returnType = $returnType === null ? $this->defaultReturnType: self::$validReturnTypes[$returnType]?? $this->defaultReturnType;
$returnType = $returnType === null ? $this->defaultReturnType : self::$validReturnTypes[$returnType] ?? $this->defaultReturnType;
foreach ($requestMethodsGiven as $requestMethod) {
$requestMethodParameterType = gettype($requestMethod);
if (!in_array($requestMethodParameterType, ['array', 'string'], true)) {
$message = sprintf(
'Request method must be string or array but %s given.',
$requestMethodParameterType);
throw new InvalidArgumentException($message);
}
if (!in_array(strtoupper($requestMethod), self::$validRequestMethods, true)) {
$message = sprintf('%s is not valid Http request method.', $requestMethod);
throw new UnexpectedValueException($message);
}
if ($alias !== null) {
$this->aliases[$alias] = $route;
}
$this->routes[] = [strtoupper($requestMethod), $route, $action, $returnType];
}
}

/**
* @param string $method
* @param array $args
* @throws UnexpectedValueException
*/
public function __call(string $method, array $args)
{
if (!in_array(strtoupper($method), self::$validRequestMethods, true)) {
$message = sprintf('%s is not valid Http request method.', $method);
throw new UnexpectedValueException($message);
}
$defaults = [
null,
null,
$this->defaultReturnType,
null
];
list($route, $action, $returnType, $alias) = array_merge($args, $defaults);
$this->add($method, $route, $action, $returnType, $alias);
}

/**
* Dispatch against the provided HTTP method verb and URI.
* @return array
*/
private function dispatcher()
{
$options = [
'routeParser' => 'FastRoute\\RouteParser\\Std',
'dataGenerator' => 'FastRoute\\DataGenerator\\GroupCountBased',
'dispatcher' => 'FastRoute\\Dispatcher\\GroupCountBased',
'routeCollector' => 'FastRoute\\RouteCollector',
'routeParser' => FastRoute\RouteParser\Std::class,
'dataGenerator' => FastRoute\DataGenerator\GroupCountBased::class,
'dispatcher' => FastRoute\Dispatcher\GroupCountBased::class,
'routeCollector' => FastRoute\RouteCollector::class,
];
/** @var RouteCollector $routeCollector */
$routeCollector = new $options['routeCollector'](
Expand Down
82 changes: 75 additions & 7 deletions test/RouterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
use Selami;
use Zend\Diactoros\ServerRequestFactory;
use ReflectionObject;
use UnexpectedValueException;
use InvalidArgumentException;

class MyRouterClass extends \PHPUnit_Framework_TestCase
{
Expand Down Expand Up @@ -95,7 +97,12 @@ public function shouldCorrectlyInstantiateRouter()
$router->add('post', '/json', 'app/redirect', 'redirect');
$router->add('get', '/alias', 'app/alias', null, 'alias');
$this->assertInstanceOf('Selami\Router', $router);
$this->assertAttributeContains('GET', 'method', $router, "Router didn't correctly return method as GET.");
$this->assertAttributeContains(
'GET',
'method',
$router,
"Router didn't correctly return method as GET."
);
}

/**
Expand All @@ -104,16 +111,17 @@ public function shouldCorrectlyInstantiateRouter()
public function shouldCorrectlyReturnRouteAndRouteAliases()
{
$router = new Selami\Router(
$this->config['default_return_type'],
'json',
$this->request->getMethod(),
$this->request->getUri()->getPath(),
$this->config['folder']
);

$router->add('get', '/', 'app/main',null, 'home');
$router->add('get', '/json', 'app/json', 'json');
$router->add('post', '/json', 'app/redirect', 'redirect');
$router->add('get', '/alias', 'app/alias', null, 'alias');
$router->get('/', 'app/main', null, 'home');
$router->get('/json', 'app/json', 'json');
$router->get('/html', 'app/json');
$router->post('/json', 'app/redirect', 'redirect');
$router->get('/alias', 'app/alias', null, 'alias');
$routeInfo = $router->getRoute();
$this->assertArrayHasKey('aliases', $routeInfo, "Router didn't correctly return route data");

Expand All @@ -123,9 +131,69 @@ public function shouldCorrectlyReturnRouteAndRouteAliases()
$this->assertEquals('/alias', $routeInfo['aliases']['alias'], "Router didn't correctly return aliases");
$this->assertArrayHasKey('controller', $routeInfo['route'], "Router didn't correctly return route data");
$this->assertEquals('app/alias', $routeInfo['route']['controller'], "Router didn't correctly return router data");
$this->assertEquals('html', $routeInfo['route']['returnType'], "Router didn't correctly return router data");
$this->assertEquals('json', $routeInfo['route']['returnType'], "Router didn't correctly return router data");
}

/**
* @test
* @expectedException UnexpectedValueException
*/
public function shouldThrowUnexpectedValueExceptionFor__callMethod()
{
$router = new Selami\Router(
$this->config['default_return_type'],
$this->request->getMethod(),
$this->request->getUri()->getPath(),
$this->config['folder']
);
$router->nonAvalibleHTTPMethod('/', 'app/main',null, 'home');
}

/**
* @test
* @expectedException UnexpectedValueException
*/
public function shouldThrowUnexpectedValueExceptionFor__constructorMethod()
{
$router = new Selami\Router(
$this->config['default_return_type'],
'UNEXPECTEDVALUE',
$this->request->getUri()->getPath(),
$this->config['folder']
);
}

/**
* @test
* @expectedException UnexpectedValueException
*/
public function shouldThrowUnexpectedValueExceptionForAddMethod()
{
$router = new Selami\Router(
$this->config['default_return_type'],
$this->request->getMethod(),
$this->request->getUri()->getPath(),
$this->config['folder']
);
$router->add('nonAvailableHTTPMethod','/', 'app/main',null, 'home');
}

/**
* @test
* @expectedException InvalidArgumentException
*/
public function shouldThrowInvalidArgumentExceptionForAddMethodIfREquestMEthotIsNotStringOrArray()
{
$router = new Selami\Router(
$this->config['default_return_type'],
$this->request->getMethod(),
$this->request->getUri()->getPath(),
$this->config['folder']
);
$router->add(200,'/', 'app/main',null, 'home');
}


/**
* @test
*/
Expand Down

0 comments on commit 87baef0

Please sign in to comment.