Skip to content

Commit

Permalink
0.5.0 (#5)
Browse files Browse the repository at this point in the history
* Changed - white space between first and second parameter is not required,
if second parameter begins with `:`, e.g. `{{id:uint}}`

* Changed preg_replace_callback to preg_match_all

* Replaced `: class` with `: self` wherever it was possible
  • Loading branch information
bkrukowski committed Mar 28, 2018
1 parent 09f7915 commit 3229e38
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 38 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog

### [0.5.0] - 2018-03-28

* Changed - white space between first and second parameter is not required,
if second parameter begins with `:`, e.g. `{{id:uint}}`
* Replaced `: class` with `: self` wherever it was possible

### [0.4.0] - 2018-03-23

* Fixed - `Awesomite\Chariot\Pattern\StdPatterns\ListPattern` should not allow for bool
Expand Down Expand Up @@ -80,6 +86,7 @@ e.g. `{{ subdomain }}.local/`

* Initial public release

[0.5.0]: https://github.com/awesomite/chariot/compare/v0.4.0...v0.5.0
[0.4.0]: https://github.com/awesomite/chariot/compare/v0.3.1...v0.4.0
[0.3.1]: https://github.com/awesomite/chariot/compare/v0.3.0...v0.3.1
[0.3.0]: https://github.com/awesomite/chariot/compare/v0.2.1...v0.3.0
Expand Down
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -60,6 +60,7 @@ Third value contains default value of parameter (used for generating links).
I believe that the best documentation are examples from the real world. The following patterns should help you to understand how does it work.

* `/page/{{ page :uint }}`
* `/page/{{page:uint}}` (white space between first and second parameter is not required, if second parameter begins with `:`)
* `/page/{{page \d+ 1}}`
* `/categories/{{ name [a-zA-Z0-9-]+ }}`
* `/categories/{{ categoryName }}/item-{{ itemId :uint }}`
Expand Down
2 changes: 1 addition & 1 deletion src/Collector/RouterCollector.php
Expand Up @@ -22,7 +22,7 @@ class RouterCollector implements RouterInterface
*/
private $routers = [];

public function addRouter(RouterInterface $router): RouterCollector
public function addRouter(RouterInterface $router): self
{
$this->routers[] = $router;

Expand Down
6 changes: 3 additions & 3 deletions src/LinkInterface.php
Expand Up @@ -15,9 +15,9 @@ interface LinkInterface
{
const ERROR_CANNOT_GENERATE_LINK = '__ERROR_CANNOT_GENERATE_LINK';

public function withParam(string $key, $value): LinkInterface;
public function withParam(string $key, $value): self;

public function withParams(array $params): LinkInterface;
public function withParams(array $params): self;

/**
* Works same as __toString() method with one exception:
Expand All @@ -40,5 +40,5 @@ public function toString(): string;
*/
public function __toString(): string;

public function withPrefix(string $prefix): LinkInterface;
public function withPrefix(string $prefix): self;
}
55 changes: 29 additions & 26 deletions src/Pattern/PatternRoute.php
Expand Up @@ -165,35 +165,30 @@ private function processTokens()
* ['{{ month :int }}', 'month', ':int', null],
* ]
*
* @return array
* @return \Generator
*/
private function getTokensStream(): array
private function getTokensStream()
{
$preProcessed = [];
\preg_replace_callback(
static::PATTERN_VAR,
function ($matches) use (&$preProcessed) {
$arr = $this->paramStrToArr($matches[0]);

if (\count($arr) > 3) {
throw new InvalidArgumentException("Invalid url pattern {$this->pattern}");
}
$matches = [];
\preg_match_all(static::PATTERN_VAR, $this->pattern, $matches);
foreach ($matches[0] ?? [] as $match) {
$arr = $this->paramStrToArr($match);

$name = $arr[0];
$pattern = $arr[1] ?? $this->patterns->getDefaultPattern();
$default = $arr[2] ?? null;
if (\count($arr) > 3) {
throw new InvalidArgumentException("Invalid url pattern {$this->pattern}");
}

$preProcessed[] = [
$matches[0],
$name,
$pattern,
$default
];
},
$this->pattern
);

return $preProcessed;
$name = $arr[0];
$pattern = $arr[1] ?? $this->patterns->getDefaultPattern();
$default = $arr[2] ?? null;

yield [
$match,
$name,
$pattern,
$default
];
}
}

/**
Expand All @@ -207,8 +202,16 @@ private function paramStrToArr(string $paramString)
$result = \array_filter(\preg_split('/\\s+/', $str), function ($a) {
return '' !== \trim($a);
});
$result = \array_values($result);

return \array_values($result);
if (!\in_array(\strpos($result[0], ':'), [0, false], true)) {
$first = \array_shift($result);
list($a, $b) = \explode(':', $first, 2);
$b = ':' . $b;
\array_unshift($result, $a, $b);
}

return $result;
}

public function match(string $path, &$params): bool
Expand Down
12 changes: 6 additions & 6 deletions src/Pattern/PatternsInterface.php
Expand Up @@ -17,30 +17,30 @@ interface PatternsInterface extends \ArrayAccess, \Serializable
* @param string $name
* @param string|PatternInterface $pattern Acceptable also stringable object (with method __toString)
*
* @return PatternsInterface
* @return self
*
* @throws InvalidArgumentException
*/
public function addPattern(string $name, $pattern): PatternsInterface;
public function addPattern(string $name, $pattern): self;

/**
* @param string $name
* @param string[] $values
*
* @return PatternsInterface
* @return self
*
* @throws InvalidArgumentException
*/
public function addEnumPattern(string $name, array $values): PatternsInterface;
public function addEnumPattern(string $name, array $values): self;

/**
* @param string|PatternInterface $pattern
*
* @return PatternsInterface
* @return self
*
* @throws InvalidArgumentException
*/
public function setDefaultPattern($pattern): PatternsInterface;
public function setDefaultPattern($pattern): self;

public function getDefaultPattern();

Expand Down
3 changes: 1 addition & 2 deletions tests/GeneralTest.php
Expand Up @@ -170,8 +170,7 @@ private function providerLinkTo()
$router->addRoute(HttpMethods::METHOD_GET, '/pl', 'home', ['lang' => 'pl']);
$router->addRoute(HttpMethods::METHOD_GET, '/category-{{ categoryId \\d+ }}', 'showCategory');
$router->addRoute(HttpMethods::METHOD_GET, '/date-{{ date :date }}', 'showDate');
$router->addRoute(HttpMethods::METHOD_GET, '/date-{{ date :date }}', 'showDate');
$router->addRoute(HttpMethods::METHOD_GET, '/user-{{ name :az }}', 'showUser');
$router->addRoute(HttpMethods::METHOD_GET, '/user-{{name:az}}', 'showUser');

yield [$router, 'home', ['lang' => 'en'], '/'];
yield [$router, 'home', ['lang' => 'pl'], '/pl'];
Expand Down
52 changes: 52 additions & 0 deletions tests/ShortNotationTest.php
@@ -0,0 +1,52 @@
<?php

/*
* This file is part of the awesomite/chariot package.
* (c) Bartłomiej Krukowski <bartlomiej@krukowski.me>
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace Awesomite\Chariot;

use Awesomite\Chariot\Exceptions\InvalidArgumentException;
use Awesomite\Chariot\Pattern\PatternRouter;

/**
* @internal
*/
class ShortNotationTest extends TestBase
{
public function testShortNotation()
{
$router = PatternRouter::createDefault();
$router->get('/category-{{id:uint}}', 'category');
$router->get('/item-{{ id:int }}', 'item');

$this->assertSame('/category-5', (string)$router->linkTo('category')->withParam('id', 5));
$this->assertSame('/item-27', (string)$router->linkTo('item')->withParam('id', 27));
}

/**
* @dataProvider providerInvalidShortNotation
*
* @param string $pattern
* @param string $expectedMsg
*/
public function testInvalidShortNotation(string $pattern, string $expectedMsg)
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage($expectedMsg);

$router = PatternRouter::createDefault();
$router->get($pattern, 'category');
}

public function providerInvalidShortNotation()
{
return [
['/category-{{id[0-9]+}}', 'Invalid param name “id[0-9]+” (source: /category-{{id[0-9]+}})'],
['/category-{{ id[0-9]+ }}', 'Invalid param name “id[0-9]+” (source: /category-{{ id[0-9]+ }})'],
];
}
}

0 comments on commit 3229e38

Please sign in to comment.