-
-
Notifications
You must be signed in to change notification settings - Fork 2
Issue 16 Refactor Routing #336
Changes from all commits
35b0ea1
e74caa5
7a32f98
670f058
182978d
52a6f5f
362398a
f85a692
dc16244
ac762be
91d2421
cd173e3
df45b96
e82fcf4
7d1cda0
a64168e
8356efb
afd1e05
b247d7a
b05559e
5acb592
59a4058
32aebd7
299740d
d4f8145
4c364b2
63bab5e
7c5cab8
a677e60
dee7c14
1d8abad
10c51d6
16bfc95
db9c7b5
781aca4
8695267
12015b1
e246d32
e6d6baa
3371e87
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?php | ||
declare(strict_types=1); | ||
namespace Narrowspark\Routing; | ||
|
||
use Benchmark; | ||
|
||
class RouteParserBench implements Benchmark | ||
{ | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"bootstrap": "vendor/autoload.php", | ||
"path": "benchmarks", | ||
"progress": "dots" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,20 +2,27 @@ | |
declare(strict_types=1); | ||
namespace Viserio\Console; | ||
|
||
use Closure; | ||
use Interop\Container\ContainerInterface as ContainerContract; | ||
use Invoker\Exception\InvocationException; | ||
use RuntimeException; | ||
use Symfony\Component\Console\Application as SymfonyConsole; | ||
use Symfony\Component\Console\Command\Command as SymfonyCommand; | ||
use Symfony\Component\Console\Input\InputDefinition; | ||
use Symfony\Component\Console\Input\InputInterface; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
use Viserio\Console\Command\Command as ViserioCommand; | ||
use Viserio\Console\Command\ExpressionParser as Parser; | ||
use Viserio\Console\Input\InputOption; | ||
use Viserio\Contracts\Console\Application as ApplicationContract; | ||
use Symfony\Component\Console\{ | ||
Application as SymfonyConsole, | ||
Command\Command as SymfonyCommand, | ||
Input\InputDefinition, | ||
Input\InputInterface, | ||
Output\OutputInterface | ||
}; | ||
use Viserio\Console\{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There must be one USE keyword per declaration |
||
Command\Command as ViserioCommand, | ||
Command\ExpressionParser as Parser, | ||
Input\InputOption | ||
}; | ||
use Viserio\Contracts\{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There must be one USE keyword per declaration |
||
Console\Application as ApplicationContract, | ||
Container\Traits\ContainerAwareTrait | ||
}; | ||
use Viserio\Support\Invoker; | ||
use Viserio\Support\Traits\ContainerAwareTrait; | ||
|
||
class Application extends SymfonyConsole implements ApplicationContract | ||
{ | ||
|
@@ -59,9 +66,9 @@ class Application extends SymfonyConsole implements ApplicationContract | |
/** | ||
* Create a new Cerebro console application. | ||
* | ||
* @param ContainerContract $container | ||
* @param string $version | ||
* @param string $name | ||
* @param \Interop\Container\ContainerInterface $container | ||
* @param string $version | ||
* @param string $name | ||
*/ | ||
public function __construct( | ||
ContainerContract $container, | ||
|
@@ -70,23 +77,22 @@ public function __construct( | |
) { | ||
$this->name = $name; | ||
$this->version = $version; | ||
|
||
$this->setContainer($container); | ||
$this->container = $container; | ||
$this->expressionParser = new Parser(); | ||
$this->initInvoker(); | ||
|
||
$this->initInvoker(); | ||
$this->setAutoExit(false); | ||
$this->setCatchExceptions(false); | ||
|
||
parent::__construct($this->getName(), $this->getVersion()); | ||
parent::__construct($name, $version); | ||
} | ||
|
||
/** | ||
* Add a command to the console. | ||
* | ||
* @param \Symfony\Component\Console\Command\Command $command | ||
* | ||
* @return SymfonyCommand|null | ||
* @return null|\Symfony\Component\Console\Command\Command | ||
*/ | ||
public function add(SymfonyCommand $command) | ||
{ | ||
|
@@ -105,10 +111,11 @@ public function add(SymfonyCommand $command) | |
* @param callable|string|array $callable Called when the command is called. | ||
* When using a container, this can be a "pseudo-callable" | ||
* i.e. the name of the container entry to invoke. | ||
* @param array $aliases An array of aliases for the command. | ||
* | ||
* @return SymfonyCommand | ||
* @return \Symfony\Component\Console\Command\Command | ||
*/ | ||
public function command(string $expression, $callable): SymfonyCommand | ||
public function command(string $expression, $callable, array $aliases = []): SymfonyCommand | ||
{ | ||
$commandFunction = function (InputInterface $input, OutputInterface $output) use ($callable) { | ||
$parameters = array_merge( | ||
|
@@ -120,18 +127,23 @@ public function command(string $expression, $callable): SymfonyCommand | |
$input->getOptions() | ||
); | ||
|
||
if ($callable instanceof Closure) { | ||
$callable = $callable->bindTo($this, $this); | ||
} | ||
|
||
try { | ||
$this->getInvoker()->call($callable, $parameters); | ||
} catch (InvocationException $e) { | ||
} catch (InvocationException $exception) { | ||
throw new RuntimeException(sprintf( | ||
"Impossible to call the '%s' command: %s", | ||
$input->getFirstArgument(), | ||
$e->getMessage() | ||
), 0, $e); | ||
$exception->getMessage() | ||
), 0, $exception); | ||
} | ||
}; | ||
|
||
$command = $this->createCommand($expression, $commandFunction); | ||
$command->setAliases($aliases); | ||
|
||
$this->add($command); | ||
|
||
|
@@ -208,7 +220,7 @@ protected function getEnvironmentOption(): InputOption | |
* @param string $expression | ||
* @param callable $callable | ||
* | ||
* @return SymfonyCommand | ||
* @return \Symfony\Component\Console\Command\Command | ||
*/ | ||
protected function createCommand(string $expression, callable $callable): SymfonyCommand | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,11 +18,11 @@ | |
Question\Question | ||
}; | ||
use Viserio\Console\Style\NarrowsparkStyle; | ||
use Viserio\Contracts\Support\Arrayable; | ||
use Viserio\Support\{ | ||
Invoker, | ||
Traits\ContainerAwareTrait | ||
use Viserio\Contracts\{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There must be one USE keyword per declaration |
||
Support\Arrayable, | ||
Container\Traits\ContainerAwareTrait | ||
}; | ||
use Viserio\Support\Invoker; | ||
|
||
abstract class Command extends BaseCommand implements CompletionAwareInterface | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,9 +2,11 @@ | |
declare(strict_types=1); | ||
namespace Viserio\Console\Command; | ||
|
||
use Viserio\Console\Input\InputArgument; | ||
use Viserio\Console\Input\InputOption; | ||
use Viserio\Contracts\Console\InvalidCommandExpression; | ||
use Viserio\Console\Input\{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There must be one USE keyword per declaration |
||
InputArgument, | ||
InputOption | ||
}; | ||
use Viserio\Contracts\Console\Exceptions\InvalidCommandExpression; | ||
use Viserio\Support\Str; | ||
|
||
class ExpressionParser | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,12 +4,16 @@ | |
|
||
use Mockery as Mock; | ||
use Narrowspark\TestingHelper\ArrayContainer; | ||
use stdClass; | ||
use Symfony\Component\Console\Input\StringInput; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
use Viserio\Console\Application; | ||
use Viserio\Console\Tests\Fixture\SpyOutput; | ||
use Viserio\Console\Tests\Fixture\ViserioCommand; | ||
use StdClass; | ||
use Symfony\Component\Console\{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There must be one USE keyword per declaration |
||
Input\StringInput, | ||
Output\OutputInterface | ||
}; | ||
use Viserio\Console\{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There must be one USE keyword per declaration |
||
Application, | ||
Tests\Fixture\SpyOutput, | ||
Tests\Fixture\ViserioCommand | ||
}; | ||
|
||
class ApplicationTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
|
@@ -20,9 +24,9 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase | |
|
||
public function setUp() | ||
{ | ||
$stdClass = new stdClass(); | ||
$stdClass = new StdClass(); | ||
$stdClass->foo = 'hello'; | ||
$stdClass2 = new stdClass(); | ||
$stdClass2 = new StdClass(); | ||
$stdClass2->foo = 'nope!'; | ||
|
||
$container = new ArrayContainer([ | ||
|
@@ -139,7 +143,7 @@ public function testItShouldRunACommandWitMultipleOptions() | |
|
||
public function testItShouldInjectTypeHintInPriority() | ||
{ | ||
$this->application->command('greet', function (OutputInterface $output, stdClass $param) { | ||
$this->application->command('greet', function (OutputInterface $output, StdClass $param) { | ||
$output->write($param->foo); | ||
}); | ||
|
||
|
@@ -149,20 +153,23 @@ public function testItShouldInjectTypeHintInPriority() | |
public function testItCanResolveCallableStringFromContainer() | ||
{ | ||
$this->application->command('greet', 'command.greet'); | ||
|
||
$this->assertOutputIs('greet', 'hello'); | ||
} | ||
|
||
public function testItCanResolveCallableArrayFromContainer() | ||
{ | ||
$this->application->command('greet', 'command.arr.greet'); | ||
|
||
$this->assertOutputIs('greet', 'hello'); | ||
} | ||
|
||
public function testItcanInjectUsingTypeHints() | ||
{ | ||
$this->application->command('greet', function (OutputInterface $output, stdClass $stdClass) { | ||
$this->application->command('greet', function (OutputInterface $output, StdClass $stdClass) { | ||
$output->write($stdClass->foo); | ||
}); | ||
|
||
$this->assertOutputIs('greet', 'hello'); | ||
} | ||
|
||
|
@@ -171,6 +178,7 @@ public function testItCanInjectUsingParameterNames() | |
$this->application->command('greet', function (OutputInterface $output, $stdClass) { | ||
$output->write($stdClass->foo); | ||
}); | ||
|
||
$this->assertOutputIs('greet', 'hello'); | ||
} | ||
|
||
|
@@ -182,9 +190,31 @@ public function testItShouldThrowIfAParameterCannotBeResolved() | |
{ | ||
$this->application->command('greet', function ($fbo) { | ||
}); | ||
|
||
$this->assertOutputIs('greet', ''); | ||
} | ||
|
||
public function testRunsACommandViaItsAliasAndReturnsExitCode() | ||
{ | ||
$this->application->command('foo', function ($output) { | ||
$output->write(1); | ||
}, ['bar']); | ||
|
||
$this->assertOutputIs('bar', 1); | ||
} | ||
|
||
public function testitShouldRunACommandInTheScopeOfTheApplication() | ||
{ | ||
$whatIsThis = null; | ||
|
||
$this->application->command('foo', function () use (&$whatIsThis) { | ||
$whatIsThis = $this; | ||
}); | ||
|
||
$this->assertOutputIs('foo', ''); | ||
$this->assertSame($this->application, $whatIsThis); | ||
} | ||
|
||
/** | ||
* Fixture method. | ||
* | ||
|
@@ -204,6 +234,7 @@ private function assertOutputIs($command, $expected) | |
$output = new SpyOutput(); | ||
|
||
$this->application->run(new StringInput($command), $output); | ||
|
||
$this->assertEquals($expected, $output->output); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There must be one USE keyword per declaration