diff --git a/.travis.yml b/.travis.yml index 5409284..a1482cc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,8 @@ matrix: - php: 7.4 env: COVERAGE=true PHPUNIT_FLAGS="-v --coverage-text" XDEBUG_MODE=coverage - php: 8.0 + - php: 8.0 + env: VENDORS=minimal # Latest commit to master - php: 7.4 @@ -38,7 +40,7 @@ matrix: before_install: - if [[ $COVERAGE != true ]]; then phpenv config-rm xdebug.ini || true; fi - if ! [ -z "$STABILITY" ]; then composer config minimum-stability ${STABILITY}; fi; - - if ! [ -v "$DEPENDENCIES" ]; then composer require --no-update ${DEPENDENCIES}; fi; + - if ! [ $DEPENDENCIES == "minimal" ]; then composer remove --dev --no-update nyholm/psr7 laminas/laminas-diactoros; fi; install: # To be removed when this issue will be resolved: https://github.com/composer/composer/issues/5355 diff --git a/Bundle/DependencyInjection/Configuration.php b/Bundle/DependencyInjection/Configuration.php new file mode 100644 index 0000000..045819c --- /dev/null +++ b/Bundle/DependencyInjection/Configuration.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PsrHttpMessage\Bundle\DependencyInjection; + +use Laminas\Diactoros\RequestFactory; +use Laminas\Diactoros\ServerRequestFactory; +use Nyholm\Psr7\Factory\Psr17Factory; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +/** + * @author Alexander M. Turek + */ +final class Configuration implements ConfigurationInterface +{ + public function getConfigTreeBuilder(): TreeBuilder + { + $treeBuilder = new TreeBuilder('psr_http_message'); + $rootNode = $treeBuilder->getRootNode(); + + $rootNode->children() + ->arrayNode('message_factories') + ->{class_exists(Psr17Factory::class) || class_exists(ServerRequestFactory::class) ? 'canBeDisabled' : 'canBeEnabled'}() + ->children() + ->enumNode('implementation') + ->info('The PSR-7 implementation to use. By default, the bundle will configure the Nyholm implementation if it\'s available.') + ->values(['nyholm', 'diactoros']) + ->defaultValue(class_exists(Psr17Factory::class) || !class_exists(ServerRequestFactory::class) ? 'nyholm' : 'diactoros') + ->validate() + ->ifTrue(function ($value) { + return 'nyholm' === $value && !class_exists(Psr17Factory::class); + })->thenInvalid('Cannot configure Nyholm\'s PSR-7 implementation. Try running "composer require nyholm/psr7".') + ->end() + ->validate() + ->ifTrue(function ($value) { + return 'diactoros' === $value && !class_exists(RequestFactory::class); + })->thenInvalid('Cannot configure Diactoros. Try running "composer require laminas/laminas-diactoros".') + ->end() + ->end() + ->end() + ->end() + ->arrayNode('message_converters') + ->info('Converters that enable controllers to operate on PSR-7 messages') + ->canBeEnabled() + ->end() + ->integerNode('response_buffer') + ->info('The maximum output buffering size for each iteration when sending the response') + ->min(1) + ->defaultValue(16372) + ->end() + ; + + return $treeBuilder; + } +} diff --git a/Bundle/DependencyInjection/PsrHttpMessageExtension.php b/Bundle/DependencyInjection/PsrHttpMessageExtension.php new file mode 100644 index 0000000..d535f2b --- /dev/null +++ b/Bundle/DependencyInjection/PsrHttpMessageExtension.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PsrHttpMessage\Bundle\DependencyInjection; + +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\Extension; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; + +/** + * @author Alexander M. Turek + */ +final class PsrHttpMessageExtension extends Extension +{ + public function load(array $configs, ContainerBuilder $container): void + { + $loader = new PhpFileLoader($container, new FileLocator(\dirname(__DIR__).'/Resources/config')); + $loader->load('http_foundation.php'); + + $configuration = $this->getConfiguration($configs, $container); + $config = $this->processConfiguration($configuration, $configs); + + $container->setParameter('psr_http_message.response_buffer', $config['response_buffer']); + + if ($config['message_converters']['enabled']) { + $loader->load('message_converters.php'); + } + + switch ($config['message_factories']['enabled'] ? $config['message_factories']['implementation'] : 'disabled') { + case 'nyholm': + $loader->load('nyholm.php'); + $loader->load('psr_factories.php'); + break; + case 'diactoros': + $loader->load('diactoros.php'); + $loader->load('psr_factories.php'); + break; + default: + $container->removeDefinition('psr_http_message.server_request_resolver'); + break; + } + } +} diff --git a/Bundle/PsrHttpMessageBundle.php b/Bundle/PsrHttpMessageBundle.php new file mode 100644 index 0000000..5ceb82a --- /dev/null +++ b/Bundle/PsrHttpMessageBundle.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PsrHttpMessage\Bundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +/** + * @author Alexander M. Turek + */ +final class PsrHttpMessageBundle extends Bundle +{ +} diff --git a/Bundle/Resources/config/diactoros.php b/Bundle/Resources/config/diactoros.php new file mode 100644 index 0000000..d58987b --- /dev/null +++ b/Bundle/Resources/config/diactoros.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Laminas\Diactoros\RequestFactory; +use Laminas\Diactoros\ResponseFactory; +use Laminas\Diactoros\ServerRequestFactory; +use Laminas\Diactoros\StreamFactory; +use Laminas\Diactoros\UploadedFileFactory; +use Laminas\Diactoros\UriFactory; + +return static function (ContainerConfigurator $container) { + $container->services() + ->set('psr_http_message.diactoros.request_factory', RequestFactory::class) + ->set('psr_http_message.diactoros.response_factory', ResponseFactory::class) + ->set('psr_http_message.diactoros.server_request_factory', ServerRequestFactory::class) + ->set('psr_http_message.diactoros.stream_factory', StreamFactory::class) + ->set('psr_http_message.diactoros.uploaded_file_factory', UploadedFileFactory::class) + ->set('psr_http_message.diactoros.uri_factory', UriFactory::class) + + ->alias('psr_http_message.psr.request_factory', 'psr_http_message.diactoros.request_factory') + ->alias('psr_http_message.psr.response_factory', 'psr_http_message.diactoros.response_factory') + ->alias('psr_http_message.psr.server_request_factory', 'psr_http_message.diactoros.server_request_factory') + ->alias('psr_http_message.psr.stream_factory', 'psr_http_message.diactoros.stream_factory') + ->alias('psr_http_message.psr.uploaded_file_factory', 'psr_http_message.diactoros.uploaded_file_factory') + ->alias('psr_http_message.psr.uri_factory', 'psr_http_message.diactoros.uri_factory') + ; +}; diff --git a/Bundle/Resources/config/http_foundation.php b/Bundle/Resources/config/http_foundation.php new file mode 100644 index 0000000..1d711f3 --- /dev/null +++ b/Bundle/Resources/config/http_foundation.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory; +use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface; + +return static function (ContainerConfigurator $container) { + $container->services() + ->set('psr_http_message.http_foundation_factory', HttpFoundationFactory::class) + ->args(['%psr_http_message.response_buffer%']) + + ->alias(HttpFoundationFactoryInterface::class, 'psr_http_message.http_foundation_factory') + ; +}; diff --git a/Bundle/Resources/config/message_converters.php b/Bundle/Resources/config/message_converters.php new file mode 100644 index 0000000..a1d2930 --- /dev/null +++ b/Bundle/Resources/config/message_converters.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Bridge\PsrHttpMessage\ArgumentValueResolver\PsrServerRequestResolver; +use Symfony\Bridge\PsrHttpMessage\EventListener\PsrResponseListener; +use Symfony\Component\DependencyInjection\Reference; + +return static function (ContainerConfigurator $container) { + $container->services() + ->set('psr_http_message.response_listener', PsrResponseListener::class) + ->args([new Reference('psr_http_message.http_foundation_factory')]) + ->tag('kernel.event_subscriber') + + ->set('psr_http_message.server_request_resolver', PsrServerRequestResolver::class) + ->args([new Reference('psr_http_message.psr_http_factory')]) + ->tag('controller.argument_value_resolver') + ; +}; diff --git a/Bundle/Resources/config/nyholm.php b/Bundle/Resources/config/nyholm.php new file mode 100644 index 0000000..2ecd04e --- /dev/null +++ b/Bundle/Resources/config/nyholm.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Nyholm\Psr7\Factory\Psr17Factory; + +return static function (ContainerConfigurator $container) { + $container->services() + ->set('psr_http_message.nyholm.factory', Psr17Factory::class) + + ->alias('psr_http_message.psr.request_factory', 'psr_http_message.nyholm.factory') + ->alias('psr_http_message.psr.response_factory', 'psr_http_message.nyholm.factory') + ->alias('psr_http_message.psr.server_request_factory', 'psr_http_message.nyholm.factory') + ->alias('psr_http_message.psr.stream_factory', 'psr_http_message.nyholm.factory') + ->alias('psr_http_message.psr.uploaded_file_factory', 'psr_http_message.nyholm.factory') + ->alias('psr_http_message.psr.uri_factory', 'psr_http_message.nyholm.factory') + ; +}; diff --git a/Bundle/Resources/config/psr_factories.php b/Bundle/Resources/config/psr_factories.php new file mode 100644 index 0000000..0781a3a --- /dev/null +++ b/Bundle/Resources/config/psr_factories.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Psr\Http\Message\RequestFactoryInterface; +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ServerRequestFactoryInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Message\UploadedFileFactoryInterface; +use Psr\Http\Message\UriFactoryInterface; +use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory; +use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; +use Symfony\Component\DependencyInjection\Reference; + +return static function (ContainerConfigurator $container) { + $container->services() + ->set('psr_http_message.psr_http_factory', PsrHttpFactory::class) + ->args([ + new Reference('psr_http_message.psr.server_request_factory'), + new Reference('psr_http_message.psr.stream_factory'), + new Reference('psr_http_message.psr.uploaded_file_factory'), + new Reference('psr_http_message.psr.response_factory'), + ]) + + ->alias(HttpMessageFactoryInterface::class, 'psr_http_message.psr_http_factory') + + ->alias(RequestFactoryInterface::class, 'psr_http_message.psr.request_factory') + ->alias(ResponseFactoryInterface::class, 'psr_http_message.psr.response_factory') + ->alias(ServerRequestFactoryInterface::class, 'psr_http_message.psr.server_request_factory') + ->alias(StreamFactoryInterface::class, 'psr_http_message.psr.stream_factory') + ->alias(UploadedFileFactoryInterface::class, 'psr_http_message.psr.uploaded_file_factory') + ->alias(UriFactoryInterface::class, 'psr_http_message.psr.uri_factory') + ; +}; diff --git a/CHANGELOG.md b/CHANGELOG.md index d70e5a5..319afe4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ CHANGELOG ========= +# 2.2.0 (TBA) + + * Added a bundle that integrates the bridge into Symfony applications + # 2.1.0 (2021-02-17) * Added a `PsrResponseListener` to automatically convert PSR-7 responses returned by controllers diff --git a/Tests/Factory/PsrHttpFactoryTest.php b/Tests/Factory/PsrHttpFactoryTest.php index b47cefc..cf2cd30 100644 --- a/Tests/Factory/PsrHttpFactoryTest.php +++ b/Tests/Factory/PsrHttpFactoryTest.php @@ -23,6 +23,10 @@ class PsrHttpFactoryTest extends AbstractHttpMessageFactoryTest { protected function buildHttpMessageFactory(): HttpMessageFactoryInterface { + if (!class_exists(Psr17Factory::class)) { + self::markTestSkipped('This test requires nyholm/psr7.'); + } + $factory = new Psr17Factory(); return new PsrHttpFactory($factory, $factory, $factory, $factory); diff --git a/Tests/Fixtures/App/Kernel.php b/Tests/Fixtures/App/Kernel.php index aef8193..e1eb841 100644 --- a/Tests/Fixtures/App/Kernel.php +++ b/Tests/Fixtures/App/Kernel.php @@ -2,19 +2,10 @@ namespace Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\App; -use Nyholm\Psr7\Factory\Psr17Factory; -use Psr\Http\Message\ResponseFactoryInterface; -use Psr\Http\Message\ServerRequestFactoryInterface; -use Psr\Http\Message\StreamFactoryInterface; -use Psr\Http\Message\UploadedFileFactoryInterface; use Psr\Log\NullLogger; -use Symfony\Bridge\PsrHttpMessage\ArgumentValueResolver\PsrServerRequestResolver; -use Symfony\Bridge\PsrHttpMessage\EventListener\PsrResponseListener; -use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory; -use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory; -use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface; -use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; +use Symfony\Bridge\PsrHttpMessage\Bundle\PsrHttpMessageBundle; use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\App\Controller\PsrRequestController; +use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\App\Service\AllFactories; use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; @@ -25,9 +16,19 @@ class Kernel extends SymfonyKernel { use MicroKernelTrait; + private $implementation; + + public function __construct(string $implementation) + { + $this->implementation = $implementation; + + parent::__construct('test', true); + } + public function registerBundles(): iterable { yield new FrameworkBundle(); + yield new PsrHttpMessageBundle(); } public function getProjectDir(): string @@ -35,6 +36,11 @@ public function getProjectDir(): string return __DIR__; } + public function getCacheDir(): string + { + return parent::getCacheDir().'/'.$this->implementation; + } + protected function configureRoutes(RoutingConfigurator $routes): void { $routes @@ -52,25 +58,27 @@ protected function configureContainer(ContainerConfigurator $container): void 'test' => true, ]); - $container->services() - ->set('nyholm.psr_factory', Psr17Factory::class) - ->alias(ResponseFactoryInterface::class, 'nyholm.psr_factory') - ->alias(ServerRequestFactoryInterface::class, 'nyholm.psr_factory') - ->alias(StreamFactoryInterface::class, 'nyholm.psr_factory') - ->alias(UploadedFileFactoryInterface::class, 'nyholm.psr_factory') - ; + $bundleConfig = [ + 'message_converters' => ['enabled' => true], + ]; + if ('auto' !== $this->implementation && 'minimal' !== $this->implementation) { + $bundleConfig['message_factories'] = [ + 'enabled' => true, + 'implementation' => $this->implementation, + ]; + } - $container->services() - ->defaults()->autowire()->autoconfigure() - ->set(HttpFoundationFactoryInterface::class, HttpFoundationFactory::class) - ->set(HttpMessageFactoryInterface::class, PsrHttpFactory::class) - ->set(PsrResponseListener::class) - ->set(PsrServerRequestResolver::class) - ; + $container->extension('psr_http_message', $bundleConfig); $container->services() ->set('logger', NullLogger::class) - ->set(PsrRequestController::class)->public()->autowire() ; + + if ('minimal' !== $this->implementation) { + $container->services() + ->set(PsrRequestController::class)->public()->autowire() + ->set(AllFactories::class)->public()->autowire() + ; + } } } diff --git a/Tests/Fixtures/App/Kernel44.php b/Tests/Fixtures/App/Kernel44.php index e976ae2..10d5ae8 100644 --- a/Tests/Fixtures/App/Kernel44.php +++ b/Tests/Fixtures/App/Kernel44.php @@ -2,19 +2,10 @@ namespace Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\App; -use Nyholm\Psr7\Factory\Psr17Factory; -use Psr\Http\Message\ResponseFactoryInterface; -use Psr\Http\Message\ServerRequestFactoryInterface; -use Psr\Http\Message\StreamFactoryInterface; -use Psr\Http\Message\UploadedFileFactoryInterface; use Psr\Log\NullLogger; -use Symfony\Bridge\PsrHttpMessage\ArgumentValueResolver\PsrServerRequestResolver; -use Symfony\Bridge\PsrHttpMessage\EventListener\PsrResponseListener; -use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory; -use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory; -use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface; -use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; +use Symfony\Bridge\PsrHttpMessage\Bundle\PsrHttpMessageBundle; use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\App\Controller\PsrRequestController; +use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\App\Service\AllFactories; use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\Config\Loader\LoaderInterface; @@ -26,9 +17,19 @@ class Kernel44 extends SymfonyKernel { use MicroKernelTrait; + private $implementation; + + public function __construct(string $implementation) + { + $this->implementation = $implementation; + + parent::__construct('test', true); + } + public function registerBundles(): iterable { yield new FrameworkBundle(); + yield new PsrHttpMessageBundle(); } public function getProjectDir(): string @@ -36,6 +37,11 @@ public function getProjectDir(): string return __DIR__; } + public function getCacheDir(): string + { + return parent::getCacheDir().'/'.$this->implementation; + } + protected function configureRoutes(RouteCollectionBuilder $routes): void { $routes->add('/server-request', PsrRequestController::class.'::serverRequestAction')->setMethods(['GET']); @@ -50,18 +56,23 @@ protected function configureContainer(ContainerBuilder $container, LoaderInterfa 'test' => true, ]); - $container->register('nyholm.psr_factory', Psr17Factory::class); - $container->setAlias(ResponseFactoryInterface::class, 'nyholm.psr_factory'); - $container->setAlias(ServerRequestFactoryInterface::class, 'nyholm.psr_factory'); - $container->setAlias(StreamFactoryInterface::class, 'nyholm.psr_factory'); - $container->setAlias(UploadedFileFactoryInterface::class, 'nyholm.psr_factory'); + $bundleConfig = [ + 'message_converters' => ['enabled' => true], + ]; + if ('auto' !== $this->implementation && 'minimal' !== $this->implementation) { + $bundleConfig['message_factories'] = [ + 'enabled' => true, + 'implementation' => $this->implementation, + ]; + } - $container->register(HttpFoundationFactoryInterface::class, HttpFoundationFactory::class)->setAutowired(true)->setAutoconfigured(true); - $container->register(HttpMessageFactoryInterface::class, PsrHttpFactory::class)->setAutowired(true)->setAutoconfigured(true); - $container->register(PsrResponseListener::class)->setAutowired(true)->setAutoconfigured(true); - $container->register(PsrServerRequestResolver::class)->setAutowired(true)->setAutoconfigured(true); + $container->loadFromExtension('psr_http_message', $bundleConfig); $container->register('logger', NullLogger::class); - $container->register(PsrRequestController::class)->setPublic(true)->setAutowired(true); + + if ('minimal' !== $this->implementation) { + $container->register(PsrRequestController::class)->setPublic(true)->setAutowired(true); + $container->register(AllFactories::class)->setPublic(true)->setAutowired(true); + } } } diff --git a/Tests/Fixtures/App/Service/AllFactories.php b/Tests/Fixtures/App/Service/AllFactories.php new file mode 100644 index 0000000..f648f8c --- /dev/null +++ b/Tests/Fixtures/App/Service/AllFactories.php @@ -0,0 +1,85 @@ +httpFoundationFactory = $httpFoundationFactory; + $this->httpMessageFactory = $httpMessageFactory; + $this->requestFactory = $requestFactory; + $this->responseFactory = $responseFactory; + $this->serverRequestFactory = $serverRequestFactory; + $this->streamFactory = $streamFactory; + $this->uploadedFileFactory = $uploadedFileFactory; + $this->uriFactory = $uriFactory; + } + + public function getHttpFoundationFactory(): HttpFoundationFactoryInterface + { + return $this->httpFoundationFactory; + } + + public function getHttpMessageFactory(): HttpMessageFactoryInterface + { + return $this->httpMessageFactory; + } + + public function getRequestFactory(): RequestFactoryInterface + { + return $this->requestFactory; + } + + public function getResponseFactory(): ResponseFactoryInterface + { + return $this->responseFactory; + } + + public function getServerRequestFactory(): ServerRequestFactoryInterface + { + return $this->serverRequestFactory; + } + + public function getStreamFactory(): StreamFactoryInterface + { + return $this->streamFactory; + } + + public function getUploadedFileFactory(): UploadedFileFactoryInterface + { + return $this->uploadedFileFactory; + } + + public function getUriFactory(): UriFactoryInterface + { + return $this->uriFactory; + } +} diff --git a/Tests/Functional/AutoControllerTest.php b/Tests/Functional/AutoControllerTest.php new file mode 100644 index 0000000..2665513 --- /dev/null +++ b/Tests/Functional/AutoControllerTest.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PsrHttpMessage\Tests\Functional; + +use Nyholm\Psr7\Factory\Psr17Factory; +use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\App\Service\AllFactories; + +final class AutoControllerTest extends ControllerTest +{ + public function testImplementationIsNyholm() + { + self::bootKernel(); + + self::assertInstanceOf(Psr17Factory::class, self::$container->get(AllFactories::class)->getServerRequestFactory()); + } + + protected static function getImplementation(): string + { + if (!class_exists(Psr17Factory::class)) { + self::markTestSkipped('This test requires nyholm/psr7.'); + } + + return 'auto'; + } +} diff --git a/Tests/Functional/ControllerTest.php b/Tests/Functional/ControllerTest.php index 0b88405..85fa163 100644 --- a/Tests/Functional/ControllerTest.php +++ b/Tests/Functional/ControllerTest.php @@ -15,11 +15,12 @@ use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\App\Kernel44; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\HttpKernel\Kernel as SymfonyKernel; +use Symfony\Component\HttpKernel\KernelInterface; /** * @author Alexander M. Turek */ -final class ControllerTest extends WebTestCase +abstract class ControllerTest extends WebTestCase { public function testServerRequestAction() { @@ -52,4 +53,15 @@ protected static function getKernelClass(): string { return SymfonyKernel::VERSION_ID >= 50200 ? Kernel::class : Kernel44::class; } + + protected static function createKernel(array $options = []): KernelInterface + { + if (null === static::$class) { + static::$class = static::getKernelClass(); + } + + return new static::$class(static::getImplementation()); + } + + abstract protected static function getImplementation(): string; } diff --git a/Tests/Functional/CovertTest.php b/Tests/Functional/CovertTest.php index f460b0e..0d7249a 100644 --- a/Tests/Functional/CovertTest.php +++ b/Tests/Functional/CovertTest.php @@ -36,12 +36,15 @@ class CovertTest extends TestCase { private $tmpDir; - protected function setUp(): void + public static function setUpBeforeClass(): void { if (!class_exists(Psr7Request::class)) { - $this->markTestSkipped('nyholm/psr7 is not installed.'); + self::markTestSkipped('nyholm/psr7 is not installed.'); } + } + protected function setUp(): void + { $this->tmpDir = sys_get_temp_dir(); } diff --git a/Tests/Functional/DiactorosControllerTest.php b/Tests/Functional/DiactorosControllerTest.php new file mode 100644 index 0000000..9fd0776 --- /dev/null +++ b/Tests/Functional/DiactorosControllerTest.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PsrHttpMessage\Tests\Functional; + +use Laminas\Diactoros\ServerRequestFactory; +use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\App\Service\AllFactories; + +final class DiactorosControllerTest extends ControllerTest +{ + public function testImplementationIsDiactoros() + { + self::bootKernel(); + + self::assertInstanceOf(ServerRequestFactory::class, self::$container->get(AllFactories::class)->getServerRequestFactory()); + } + + protected static function getImplementation(): string + { + if (!class_exists(ServerRequestFactory::class)) { + self::markTestSkipped('This test requires nyholm/psr7.'); + } + + return 'diactoros'; + } +} diff --git a/Tests/Functional/MinimalBundleTest.php b/Tests/Functional/MinimalBundleTest.php new file mode 100644 index 0000000..976c74c --- /dev/null +++ b/Tests/Functional/MinimalBundleTest.php @@ -0,0 +1,46 @@ +has(HttpMessageFactoryInterface::class)); + self::assertInstanceOf(HttpFoundationFactory::class, self::$container->get(HttpFoundationFactoryInterface::class)); + } + + protected static function getKernelClass(): string + { + return SymfonyKernel::VERSION_ID >= 50200 ? Kernel::class : Kernel44::class; + } + + protected static function createKernel(array $options = []): KernelInterface + { + if (null === static::$class) { + static::$class = static::getKernelClass(); + } + + return new static::$class('minimal'); + } +} diff --git a/Tests/Functional/NyholmControllerTest.php b/Tests/Functional/NyholmControllerTest.php new file mode 100644 index 0000000..b869525 --- /dev/null +++ b/Tests/Functional/NyholmControllerTest.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PsrHttpMessage\Tests\Functional; + +use Nyholm\Psr7\Factory\Psr17Factory; +use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\App\Service\AllFactories; + +/** + * @author Alexander M. Turek + */ +final class NyholmControllerTest extends ControllerTest +{ + public function testImplementationIsNyholm() + { + self::bootKernel(); + + self::assertInstanceOf(Psr17Factory::class, self::$container->get(AllFactories::class)->getServerRequestFactory()); + } + + protected static function getImplementation(): string + { + if (!class_exists(Psr17Factory::class)) { + self::markTestSkipped('This test requires nyholm/psr7.'); + } + + return 'nyholm'; + } +} diff --git a/composer.json b/composer.json index 07563bc..9c14977 100644 --- a/composer.json +++ b/composer.json @@ -21,8 +21,10 @@ "symfony/http-foundation": "^4.4 || ^5.0" }, "require-dev": { + "laminas/laminas-diactoros": "^2.4", "symfony/browser-kit": "^4.4 || ^5.0", "symfony/config": "^4.4 || ^5.0", + "symfony/dependency-injection": "^4.4 || ^5.0", "symfony/event-dispatcher": "^4.4 || ^5.0", "symfony/framework-bundle": "^4.4 || ^5.0", "symfony/http-kernel": "^4.4 || ^5.0", @@ -41,7 +43,7 @@ }, "extra": { "branch-alias": { - "dev-main": "2.1-dev" + "dev-main": "2.2-dev" } } }