Skip to content

Commit

Permalink
[FrameworkBundle] Simplify "invokable" controllers as services
Browse files Browse the repository at this point in the history
  • Loading branch information
kbond authored and fabpot committed Jun 26, 2014
1 parent ce15db5 commit e712e89
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 12 deletions.
Expand Up @@ -63,6 +63,10 @@ protected function createController($controller)
list($service, $method) = explode(':', $controller, 2);

return array($this->container->get($service), $method);
} elseif ($this->container->has($controller) &&
method_exists($service = $this->container->get($controller), '__invoke')
) {
return $service;
} else {
throw new \LogicException(sprintf('Unable to parse the controller name "%s".', $controller));
}
Expand Down
@@ -0,0 +1,155 @@
<?php

namespace Symfony\Bundle\FrameworkBundle\Tests\Controller;

use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
use Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest as BaseControllerResolverTest;

class ControllerResolverTest extends BaseControllerResolverTest
{
public function testGetControllerOnContainerAware()
{
$resolver = $this->createControllerResolver();
$request = Request::create('/');
$request->attributes->set('_controller', 'Symfony\Bundle\FrameworkBundle\Tests\Controller\ContainerAwareController::testAction');

$controller = $resolver->getController($request);

$this->assertInstanceOf('Symfony\Component\DependencyInjection\ContainerInterface', $controller[0]->getContainer());
$this->assertSame('testAction', $controller[1]);
}

public function testGetControllerWithBundleNotation()
{
$shortName = 'FooBundle:Default:test';
$parser = $this->createMockParser();
$parser->expects($this->once())
->method('parse')
->with($shortName)
->will($this->returnValue('Symfony\Bundle\FrameworkBundle\Tests\Controller\ContainerAwareController::testAction'))
;

$resolver = $this->createControllerResolver(null, $parser);
$request = Request::create('/');
$request->attributes->set('_controller', $shortName);

$controller = $resolver->getController($request);

$this->assertInstanceOf('Symfony\Bundle\FrameworkBundle\Tests\Controller\ContainerAwareController', $controller[0]);
$this->assertInstanceOf('Symfony\Component\DependencyInjection\ContainerInterface', $controller[0]->getContainer());
$this->assertSame('testAction', $controller[1]);
}

public function testGetControllerService()
{
$container = $this->createMockContainer();
$container->expects($this->once())
->method('get')
->with('foo')
->will($this->returnValue($this))
;

$resolver = $this->createControllerResolver(null, null, $container);
$request = Request::create('/');
$request->attributes->set('_controller', 'foo:controllerMethod1');

$controller = $resolver->getController($request);

$this->assertInstanceOf(get_class($this), $controller[0]);
$this->assertSame('controllerMethod1', $controller[1]);
}

public function testGetControllerInvokableService()
{
$container = $this->createMockContainer();
$container->expects($this->once())
->method('has')
->with('foo')
->will($this->returnValue(true))
;
$container->expects($this->once())
->method('get')
->with('foo')
->will($this->returnValue($this))
;

$resolver = $this->createControllerResolver(null, null, $container);
$request = Request::create('/');
$request->attributes->set('_controller', 'foo');

$controller = $resolver->getController($request);

$this->assertInstanceOf(get_class($this), $controller);
}

/**
* @dataProvider getUndefinedControllers
*/
public function testGetControllerOnNonUndefinedFunction($controller, $exceptionName = null, $exceptionMessage = null)
{
$this->setExpectedException($exceptionName, $exceptionMessage);

parent::testGetControllerOnNonUndefinedFunction($controller);
}

public function getUndefinedControllers()
{
return array(
array('foo', '\LogicException', 'Unable to parse the controller name "foo".'),
array('foo::bar', '\InvalidArgumentException', 'Class "foo" does not exist.'),
array('stdClass', '\LogicException', 'Unable to parse the controller name "stdClass".'),
array(
'Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest::bar',
'\InvalidArgumentException',
'Controller "Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest::bar" for URI "/" is not callable.'
)
);
}

protected function createControllerResolver(LoggerInterface $logger = null, ControllerNameParser $parser = null, ContainerInterface $container = null)
{
if (!$parser) {
$parser = $this->createMockParser();
}

if (!$container) {
$container = $this->createMockContainer();
}

return new ControllerResolver($container, $parser, $logger);
}

protected function createMockParser()
{
return $this->getMock('Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser', array(), array(), '', false);
}

protected function createMockContainer()
{
return $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
}
}

class ContainerAwareController implements ContainerAwareInterface
{
private $container;

public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}

public function getContainer()
{
return $this->container;
}

public function testAction()
{
}
}
Expand Up @@ -11,8 +11,8 @@

namespace Symfony\Component\HttpKernel\Tests\Controller;

use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
use Symfony\Component\HttpKernel\Tests\Logger;
use Symfony\Component\HttpFoundation\Request;

class ControllerResolverTest extends \PHPUnit_Framework_TestCase
Expand All @@ -21,15 +21,15 @@ public function testGetControllerWithoutControllerParameter()
{
$logger = $this->getMock('Psr\Log\LoggerInterface');
$logger->expects($this->once())->method('warning')->with('Unable to look for the controller as the "_controller" parameter is missing');
$resolver = new ControllerResolver($logger);
$resolver = $this->createControllerResolver($logger);

$request = Request::create('/');
$this->assertFalse($resolver->getController($request), '->getController() returns false when the request has no _controller attribute');
}

public function testGetControllerWithLambda()
{
$resolver = new ControllerResolver();
$resolver = $this->createControllerResolver();

$request = Request::create('/');
$request->attributes->set('_controller', $lambda = function () {});
Expand All @@ -39,7 +39,7 @@ public function testGetControllerWithLambda()

public function testGetControllerWithObjectAndInvokeMethod()
{
$resolver = new ControllerResolver();
$resolver = $this->createControllerResolver();

$request = Request::create('/');
$request->attributes->set('_controller', $this);
Expand All @@ -49,7 +49,7 @@ public function testGetControllerWithObjectAndInvokeMethod()

public function testGetControllerWithObjectAndMethod()
{
$resolver = new ControllerResolver();
$resolver = $this->createControllerResolver();

$request = Request::create('/');
$request->attributes->set('_controller', array($this, 'controllerMethod1'));
Expand All @@ -59,7 +59,7 @@ public function testGetControllerWithObjectAndMethod()

public function testGetControllerWithClassAndMethod()
{
$resolver = new ControllerResolver();
$resolver = $this->createControllerResolver();

$request = Request::create('/');
$request->attributes->set('_controller', array('Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest', 'controllerMethod4'));
Expand All @@ -69,7 +69,7 @@ public function testGetControllerWithClassAndMethod()

public function testGetControllerWithObjectAndMethodAsString()
{
$resolver = new ControllerResolver();
$resolver = $this->createControllerResolver();

$request = Request::create('/');
$request->attributes->set('_controller', 'Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest::controllerMethod1');
Expand All @@ -79,7 +79,7 @@ public function testGetControllerWithObjectAndMethodAsString()

public function testGetControllerWithClassAndInvokeMethod()
{
$resolver = new ControllerResolver();
$resolver = $this->createControllerResolver();

$request = Request::create('/');
$request->attributes->set('_controller', 'Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest');
Expand All @@ -92,7 +92,7 @@ public function testGetControllerWithClassAndInvokeMethod()
*/
public function testGetControllerOnObjectWithoutInvokeMethod()
{
$resolver = new ControllerResolver();
$resolver = $this->createControllerResolver();

$request = Request::create('/');
$request->attributes->set('_controller', new \stdClass());
Expand All @@ -101,7 +101,7 @@ public function testGetControllerOnObjectWithoutInvokeMethod()

public function testGetControllerWithFunction()
{
$resolver = new ControllerResolver();
$resolver = $this->createControllerResolver();

$request = Request::create('/');
$request->attributes->set('_controller', 'Symfony\Component\HttpKernel\Tests\Controller\some_controller_function');
Expand All @@ -115,7 +115,7 @@ public function testGetControllerWithFunction()
*/
public function testGetControllerOnNonUndefinedFunction($controller)
{
$resolver = new ControllerResolver();
$resolver = $this->createControllerResolver();

$request = Request::create('/');
$request->attributes->set('_controller', $controller);
Expand All @@ -134,7 +134,7 @@ public function getUndefinedControllers()

public function testGetArguments()
{
$resolver = new ControllerResolver();
$resolver = $this->createControllerResolver();

$request = Request::create('/');
$controller = array(new self(), 'testGetArguments');
Expand Down Expand Up @@ -207,6 +207,11 @@ public function testCreateControllerCanReturnAnyCallable()
$mock->getController($request);
}

protected function createControllerResolver(LoggerInterface $logger = null)
{
return new ControllerResolver($logger);
}

public function __invoke($foo, $bar = null)
{
}
Expand Down

0 comments on commit e712e89

Please sign in to comment.