Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure the application via a container #2793

Merged
merged 8 commits into from Aug 11, 2019
22 changes: 22 additions & 0 deletions Slim/Factory/AppFactory.php
Expand Up @@ -89,6 +89,28 @@ public static function create(
);
}

/**
* @param ContainerInterface $container
* @return App
*/
public static function createFromContainer(ContainerInterface $container): App
{
$responseFactory = $container->has(ResponseFactoryInterface::class)
? $container->get(ResponseFactoryInterface::class)
: self::determineResponseFactory();
$callableResolver = $container->has(CallableResolverInterface::class)
? $container->get(CallableResolverInterface::class)
: null;
$routeCollector = $container->has(RouteCollectorInterface::class)
? $container->get(RouteCollectorInterface::class)
: null;
$routeResolver = $container->has(RouteResolverInterface::class)
? $container->get(RouteResolverInterface::class)
: null;

return new App($responseFactory, $container, $callableResolver, $routeCollector, $routeResolver);
}

/**
* @return ResponseFactoryInterface
* @throws RuntimeException
Expand Down
37 changes: 37 additions & 0 deletions tests/Factory/AppFactoryTest.php
Expand Up @@ -31,6 +31,7 @@
use Slim\Interfaces\RouteResolverInterface;
use Slim\Psr7\Factory\ResponseFactory as SlimResponseFactory;
use Slim\Routing\RouteCollector;
use Slim\Tests\Mocks\MockContainer;
use Slim\Tests\Mocks\MockPsr17FactoryWithoutStreamFactory;
use Slim\Tests\TestCase;
use Zend\Diactoros\ResponseFactory as ZendDiactorosResponseFactory;
Expand Down Expand Up @@ -228,4 +229,40 @@ public function testResponseAndStreamFactoryIsBeingInjectedInDecoratedResponseFa

$this->assertSame($streamFactoryProphecy->reveal(), $streamFactoryProperty->getValue($response));
}

public function testCreateAppWithEmptyContainer()
{
$container = new MockContainer([]);

$app = AppFactory::createFromContainer($container);

$this->assertSame($container, $app->getContainer());
}

public function testCreateAppWithContainerThatProvidesAllImplementations()
l0gicgate marked this conversation as resolved.
Show resolved Hide resolved
{
$responseFactory = $this->createMock(ResponseFactoryInterface::class);
$callableResolver = $this->createMock(CallableResolverInterface::class);
$routeParser = $this->createMock(RouteParserInterface::class);
$routeCollector = $this->createConfiguredMock(RouteCollectorInterface::class, [
'getRouteParser' => $routeParser
]);
$routeResolver = $this->createMock(RouteResolverInterface::class);

$container = new MockContainer([
ResponseFactoryInterface::class => $responseFactory,
CallableResolverInterface::class => $callableResolver,
RouteCollectorInterface::class => $routeCollector,
RouteParserInterface::class => $routeParser,
RouteResolverInterface::class => $routeResolver,
]);

$app = AppFactory::createFromContainer($container);

$this->assertSame($responseFactory, $app->getResponseFactory());
$this->assertSame($container, $app->getContainer());
$this->assertSame($callableResolver, $app->getCallableResolver());
$this->assertSame($routeCollector, $app->getRouteCollector());
$this->assertSame($routeResolver, $app->getRouteResolver());
}
}
26 changes: 26 additions & 0 deletions tests/Mocks/MockContainer.php
@@ -0,0 +1,26 @@
<?php declare(strict_types=1);

namespace Slim\Tests\Mocks;

use Psr\Container\ContainerInterface;

class MockContainer implements ContainerInterface
l0gicgate marked this conversation as resolved.
Show resolved Hide resolved
{
/** @var array */
private $entries;

public function __construct(array $entries)
{
$this->entries = $entries;
}

public function get($id)
{
return $this->entries[$id];
}

public function has($id)
{
return array_key_exists($id, $this->entries);
}
}