diff --git a/.gitignore b/.gitignore index a3dbf0d..6caa4d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ /bin /vendor -/tests/temp composer.lock -composer.phar -autoload.php +.phpcs-cache +.phpunit.result.cache diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index 519951d..0000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -filter: - excluded_paths: [vendor/*, bin/*] - -checks: - php: - code_rating: true - duplication: true - -tools: - php_cpd: true - php_pdepend: - excluded_dirs: [vendor] - diff --git a/.travis.yml b/.travis.yml index e42b630..0382bb7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,8 @@ matrix: - php: 7.1 env: - COMPOSER_FLAGS='--prefer-lowest' - - php: 7.3 + - php: 7.4 + - php: 8.0 env: global: @@ -15,4 +16,7 @@ before_script: - phpenv config-rm xdebug.ini - COMPOSER_MEMORY_LIMIT=-1 composer update $COMPOSER_FLAGS -script: vendor/bin/phpunit +script: + - vendor/bin/phpcs + - vendor/bin/phpstan analyze -c phpstan.neon + - vendor/bin/phpunit diff --git a/DataSource/Extension/Symfony/Core/EventSubscriber/BindParameters.php b/DataSource/Extension/Symfony/Core/EventSubscriber/BindParameters.php index a86f278..ac9bf32 100644 --- a/DataSource/Extension/Symfony/Core/EventSubscriber/BindParameters.php +++ b/DataSource/Extension/Symfony/Core/EventSubscriber/BindParameters.php @@ -26,7 +26,7 @@ public static function getSubscribedEvents() public function preBindParameters(DataSourceEvent\ParametersEventArgs $event) { $parameters = $event->getParameters(); - if ($parameters instanceof Request) { + if (true === $parameters instanceof Request) { $event->setParameters($parameters->query->all()); } } diff --git a/DataSource/Extension/Symfony/DependencyInjection/Driver/DriverExtension.php b/DataSource/Extension/Symfony/DependencyInjection/Driver/DriverExtension.php index 820c6e2..ac81b83 100644 --- a/DataSource/Extension/Symfony/DependencyInjection/Driver/DriverExtension.php +++ b/DataSource/Extension/Symfony/DependencyInjection/Driver/DriverExtension.php @@ -73,7 +73,9 @@ public function hasFieldType($type) public function getFieldType($type) { if (false === array_key_exists($type, $this->fieldTypes)) { - throw new InvalidArgumentException(sprintf('The field type "%s" is not registered within the service container.', $type)); + throw new InvalidArgumentException( + sprintf('The field type "%s" is not registered within the service container.', $type) + ); } return $this->fieldTypes[$type]; diff --git a/DataSource/Extension/Symfony/Form/Field/FormFieldExtension.php b/DataSource/Extension/Symfony/Form/Field/FormFieldExtension.php index 6d014dc..f56cd5d 100644 --- a/DataSource/Extension/Symfony/Form/Field/FormFieldExtension.php +++ b/DataSource/Extension/Symfony/Form/Field/FormFieldExtension.php @@ -81,7 +81,7 @@ public function initOptions(FieldTypeInterface $field) 'form_filter' => true, 'form_options' => [], 'form_from_options' => [], - 'form_to_options' =>[] + 'form_to_options' => [] ]) ->setDefined([ 'form_type', @@ -337,7 +337,7 @@ private function getParameterValue(array $array, FieldTypeInterface $field) } /** - * @param array &$array + * @param array $array * @param FieldTypeInterface $field * @param mixed $value */ diff --git a/DependencyInjection/Compiler/DataSourcePass.php b/DependencyInjection/Compiler/DataSourcePass.php index 17a1550..a7ade7f 100644 --- a/DependencyInjection/Compiler/DataSourcePass.php +++ b/DependencyInjection/Compiler/DataSourcePass.php @@ -52,7 +52,8 @@ public function process(ContainerBuilder $container) $driverType = $container->getDefinition($driverExtension)->getArgument(0); $fields = []; - foreach ($container->findTaggedServiceIds('datasource.driver.'.$driverType.'.field') as $serviceId => $tag) { + $fieldTag = 'datasource.driver.' . $driverType . '.field'; + foreach ($container->findTaggedServiceIds($fieldTag) as $serviceId => $tag) { $alias = isset($tag[0]['alias']) ? $tag[0]['alias'] : $serviceId; $fields[$alias] = new Reference($serviceId); @@ -61,7 +62,8 @@ public function process(ContainerBuilder $container) $container->getDefinition($driverExtension)->replaceArgument(1, $fields); $fieldSubscribers = []; - foreach ($container->findTaggedServiceIds('datasource.driver.'.$driverType.'.field.subscriber') as $serviceId => $tag) { + $fieldSubscriberTag = 'datasource.driver.' . $driverType . '.field.subscriber'; + foreach ($container->findTaggedServiceIds($fieldSubscriberTag) as $serviceId => $tag) { $alias = isset($tag[0]['alias']) ? $tag[0]['alias'] : $serviceId; $fieldSubscribers[$alias] = new Reference($serviceId); @@ -70,7 +72,8 @@ public function process(ContainerBuilder $container) $container->getDefinition($driverExtension)->replaceArgument(2, $fieldSubscribers); $subscribers = []; - foreach ($container->findTaggedServiceIds('datasource.driver.'.$driverType.'.subscriber') as $serviceId => $tag) { + $driverSubscriberTag = 'datasource.driver.' . $driverType . '.subscriber'; + foreach ($container->findTaggedServiceIds($driverSubscriberTag) as $serviceId => $tag) { $alias = isset($tag[0]['alias']) ? $tag[0]['alias'] : $serviceId; $subscribers[$alias] = new Reference($serviceId); diff --git a/DependencyInjection/Compiler/TemplatePathPass.php b/DependencyInjection/Compiler/TemplatePathPass.php index cf13d1a..6332573 100644 --- a/DependencyInjection/Compiler/TemplatePathPass.php +++ b/DependencyInjection/Compiler/TemplatePathPass.php @@ -21,14 +21,11 @@ final class TemplatePathPass implements CompilerPassInterface public function process(ContainerBuilder $container) { $loaderDefinition = $container->getDefinition('twig.loader.filesystem'); - if (null === $loaderDefinition) { - return; - } $reflection = new ReflectionClass(DataSourceBundle::class); $loaderDefinition->addMethodCall( 'addPath', - [dirname($reflection->getFileName()).'/Resources/views'] + [dirname($reflection->getFileName()) . '/Resources/views'] ); } } diff --git a/DependencyInjection/FSIDataSourceExtension.php b/DependencyInjection/FSIDataSourceExtension.php index 7b3cb9d..64cad8d 100644 --- a/DependencyInjection/FSIDataSourceExtension.php +++ b/DependencyInjection/FSIDataSourceExtension.php @@ -32,7 +32,7 @@ public function load(array $configs, ContainerBuilder $container) $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); - $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); $loader->load('datasource.xml'); $this->registerDrivers($loader); @@ -65,8 +65,10 @@ private function registerDrivers(LoaderInterface $loader): void private function registerForAutoconfiguration(ContainerBuilder $container): void { $container->registerForAutoconfiguration(DriverFactoryInterface::class)->addTag('datasource.driver.factory'); - $container->registerForAutoconfiguration(DriverExtensionInterface::class)->addTag('datasource.driver.extension'); - $container->registerForAutoconfiguration(CollectionAbstractField::class)->addTag('datasource.driver.collection.field'); + $container->registerForAutoconfiguration(DriverExtensionInterface::class) + ->addTag('datasource.driver.extension'); + $container->registerForAutoconfiguration(CollectionAbstractField::class) + ->addTag('datasource.driver.collection.field'); $container->registerForAutoconfiguration(Collection\FieldEventSubscriberInterface::class) ->addTag('datasource.driver.collection.field.subscriber') ; diff --git a/Tests/DataSource/Extension/Configuration/EventSubscriber/ConfigurationBuilderTest.php b/Tests/DataSource/Extension/Configuration/EventSubscriber/ConfigurationBuilderTest.php index 869febc..166e9c1 100644 --- a/Tests/DataSource/Extension/Configuration/EventSubscriber/ConfigurationBuilderTest.php +++ b/Tests/DataSource/Extension/Configuration/EventSubscriber/ConfigurationBuilderTest.php @@ -23,158 +23,162 @@ class ConfigurationBuilderTest extends TestCase { /** - * @var MockObject + * @var Kernel&MockObject */ private $kernel; /** - * @var MockObject + * @var ConfigurationBuilder */ private $subscriber; - public function testSubscribedEvents() + public function testSubscribedEvents(): void { - $this->assertEquals( + self::assertEquals( ConfigurationBuilder::getSubscribedEvents(), [DataSourceEvents::PRE_BIND_PARAMETERS => ['readConfiguration', 1024]] ); } - public function testReadConfigurationFromOneBundle() + public function testReadConfigurationFromOneBundle(): void { $container = $this->createMock(ContainerInterface::class); - $container->expects($this->once()) + $container->expects(self::once()) ->method('getParameter') ->with('datasource.yaml.main_config') ->willReturn(null) ; - $this->kernel->expects($this->once())->method('getContainer')->willReturn($container); - $this->kernel->expects($this->once()) + $this->kernel->expects(self::once())->method('getContainer')->willReturn($container); + $this->kernel->expects(self::once()) ->method('getBundles') - ->will($this->returnCallback(function(): array { - $bundle = $this->createMock(BundleInterface::class, ['getPath']); - $bundle->expects($this->any()) - ->method('getPath') - ->will($this->returnValue(__DIR__ . '/../../../../Fixtures/FooBundle')); + ->willReturnCallback( + function (): array { + $bundle = $this->createMock(BundleInterface::class); + $bundle->method('getPath')->willReturn(__DIR__ . '/../../../../Fixtures/FooBundle'); - return [$bundle]; - })); + return [$bundle]; + } + ); $dataSource = $this->createMock(DataSourceInterface::class); - $dataSource->expects($this->any())->method('getName')->will($this->returnValue('news')); - $dataSource->expects($this->once())->method('addField')->with('title', 'text', 'like', ['label' => 'Title']); + $dataSource->method('getName')->willReturn('news'); + $dataSource->expects(self::once())->method('addField')->with('title', 'text', 'like', ['label' => 'Title']); $this->subscriber->readConfiguration(new ParametersEventArgs($dataSource, [])); } - public function testReadConfigurationFromManyBundles() + public function testReadConfigurationFromManyBundles(): void { $container = $this->createMock(ContainerInterface::class); - $container->expects($this->once()) + $container->expects(self::once()) ->method('getParameter') ->with('datasource.yaml.main_config') ->willReturn(null) ; - $this->kernel->expects($this->once())->method('getContainer')->willReturn($container); - $this->kernel->expects($this->once()) + $this->kernel->expects(self::once())->method('getContainer')->willReturn($container); + $this->kernel->expects(self::once()) ->method('getBundles') - ->will($this->returnCallback(function(): array { - $fooBundle = $this->createMock(BundleInterface::class); - $fooBundle->expects($this->any()) - ->method('getPath') - ->willReturn(__DIR__ . '/../../../../Fixtures/FooBundle'); + ->willReturnCallback( + function (): array { + $fooBundle = $this->createMock(BundleInterface::class); + $fooBundle->method('getPath')->willReturn(__DIR__ . '/../../../../Fixtures/FooBundle'); - $barBundle = $this->createMock(BundleInterface::class); - $barBundle->expects($this->any()) - ->method('getPath') - ->willReturn(__DIR__ . '/../../../../Fixtures/BarBundle') - ; + $barBundle = $this->createMock(BundleInterface::class); + $barBundle->method('getPath')->willReturn(__DIR__ . '/../../../../Fixtures/BarBundle'); - return [$fooBundle, $barBundle]; - })); + return [$fooBundle, $barBundle]; + } + ); $dataSource = $this->createMock(DataSourceInterface::class); - $dataSource->expects($this->any())->method('getName')->will($this->returnValue('news')); + $dataSource->method('getName')->willReturn('news'); // 0 - 1 getName() is called - $dataSource->expects($this->at(2))->method('addField')->with('title', 'text', 'like', ['label' => 'News Title']); - $dataSource->expects($this->at(3))->method('addField')->with('author', null, null, []); + $dataSource->expects(self::at(2))->method('addField')->with('title', 'text', 'like', ['label' => 'News Title']); + $dataSource->expects(self::at(3))->method('addField')->with('author', null, null, []); $this->subscriber->readConfiguration(new ParametersEventArgs($dataSource, [])); } - public function testMainConfigurationOverridesBundles() + public function testMainConfigurationOverridesBundles(): void { $container = $this->createMock(ContainerInterface::class); - $container->expects($this->once()) + $container->expects(self::once()) ->method('getParameter') ->with('datasource.yaml.main_config') ->willReturn(sprintf('%s/../../../../Resources/config/main_directory', __DIR__)) ; - $this->kernel->expects($this->once())->method('getContainer')->willReturn($container); - $this->kernel->expects($this->never())->method('getBundles'); + $this->kernel->expects(self::once())->method('getContainer')->willReturn($container); + $this->kernel->expects(self::never())->method('getBundles'); $dataSource = $this->createMock(DataSourceInterface::class); - $dataSource->expects($this->any())->method('getName')->will($this->returnValue('news')); + $dataSource->method('getName')->willReturn('news'); // 0 is when getName() is called - $dataSource->expects($this->at(1))->method('addField')->with('title_short', 'text', null, ['label' => 'Short title']); - $dataSource->expects($this->at(2))->method('addField')->with('created_at', 'date', null, ['label' => 'Created at']); + $dataSource->expects(self::at(1)) + ->method('addField') + ->with('title_short', 'text', null, ['label' => 'Short title']) + ; + + $dataSource->expects(self::at(2)) + ->method('addField') + ->with('created_at', 'date', null, ['label' => 'Created at']) + ; $this->subscriber->readConfiguration(new ParametersEventArgs($dataSource, [])); } - public function testBundleConfigUsedWhenNoFileFoundInMainDirectory() + public function testBundleConfigUsedWhenNoFileFoundInMainDirectory(): void { $container = $this->createMock(ContainerInterface::class); - $container->expects($this->once()) + $container->expects(self::once()) ->method('getParameter') ->with('datasource.yaml.main_config') ->willReturn(sprintf('%s/../../../../Resources/config/main_directory', __DIR__)) ; - $this->kernel->expects($this->once())->method('getContainer')->willReturn($container); - $this->kernel->expects($this->once()) + $this->kernel->expects(self::once())->method('getContainer')->willReturn($container); + $this->kernel->expects(self::once()) ->method('getBundles') - ->will($this->returnCallback(function() { - $bundle = $this->createMock(BundleInterface::class); - $bundle->expects($this->any()) - ->method('getPath') - ->willReturn(__DIR__ . '/../../../../Fixtures/FooBundle'); + ->willReturnCallback( + function (): array { + $bundle = $this->createMock(BundleInterface::class); + $bundle->method('getPath')->willReturn(__DIR__ . '/../../../../Fixtures/FooBundle'); - return [$bundle]; - })); + return [$bundle]; + } + ); $dataSource = $this->createMock(DataSourceInterface::class); - $dataSource->expects($this->any())->method('getName')->will($this->returnValue('user')); - $dataSource->expects($this->once())->method('addField')->with('username', 'text', null, []); + $dataSource->method('getName')->willReturn('user'); + $dataSource->expects(self::once())->method('addField')->with('username', 'text', null, []); $this->subscriber->readConfiguration(new ParametersEventArgs($dataSource, [])); } - public function testExceptionThrownWhenMainConfigPathIsNotADirectory() + public function testExceptionThrownWhenMainConfigPathIsNotADirectory(): void { $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('"non existant directory" is not a directory!'); + $this->expectExceptionMessage('"non existent directory" is not a directory!'); $container = $this->createMock(ContainerInterface::class); - $container->expects($this->once()) + $container->expects(self::once()) ->method('getParameter') ->with('datasource.yaml.main_config') - ->willReturn('non existant directory') + ->willReturn('non existent directory') ; - $this->kernel->expects($this->once())->method('getContainer')->willReturn($container); + $this->kernel->expects(self::once())->method('getContainer')->willReturn($container); $dataSource = $this->createMock(DataSourceInterface::class); - $dataSource->expects($this->any())->method('getName')->will($this->returnValue('news')); + $dataSource->method('getName')->willReturn('news'); $this->subscriber->readConfiguration(new ParametersEventArgs($dataSource, [])); } - protected function setUp() + protected function setUp(): void { $kernelMockBuilder = $this->getMockBuilder(Kernel::class)->setConstructorArgs(['dev', true]); $kernelMockBuilder->setMethods( diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php index 2975e51..dd626ec 100644 --- a/Tests/DependencyInjection/ConfigurationTest.php +++ b/Tests/DependencyInjection/ConfigurationTest.php @@ -22,7 +22,7 @@ class ConfigurationTest extends TestCase */ private $processor; - public function testDefaultOptions() + public function testDefaultOptions(): void { $defaults = [ 'yaml_configuration' => [ @@ -34,13 +34,14 @@ public function testDefaultOptions() 'template' => '@DataSource/datasource.html.twig' ] ]; - $this->assertSame( + + self::assertSame( $defaults, $this->processor->processConfiguration(new Configuration(), [[]]) ); } - public function testFoldedYamlConfigurationForTrue() + public function testFoldedYamlConfigurationForTrue(): void { $folded = [ 'yaml_configuration' => [ @@ -52,13 +53,14 @@ public function testFoldedYamlConfigurationForTrue() 'template' => '@DataSource/datasource.html.twig' ] ]; - $this->assertSame( + + self::assertSame( $folded, $this->processor->processConfiguration(new Configuration(), [['yaml_configuration' => true]]) ); } - public function testFoldedYamlConfigurationForFalse() + public function testFoldedYamlConfigurationForFalse(): void { $folded = [ 'yaml_configuration' => [ @@ -70,7 +72,8 @@ public function testFoldedYamlConfigurationForFalse() 'template' => '@DataSource/datasource.html.twig' ] ]; - $this->assertSame( + + self::assertSame( $folded, $this->processor->processConfiguration(new Configuration(), [ ['yaml_configuration' => false] @@ -78,13 +81,13 @@ public function testFoldedYamlConfigurationForFalse() ); } - public function testThemesOption() + public function testThemesOption(): void { $config = $this->processor->processConfiguration(new Configuration(), [ ['twig' => ['template' => '@DataSource/custom_datasource.html.twig']] ]); - $this->assertSame( + self::assertSame( [ 'twig' => ['template' => '@DataSource/custom_datasource.html.twig', 'enabled' => true], 'yaml_configuration' => ['enabled' => true, 'main_configuration_directory' => null] @@ -93,7 +96,7 @@ public function testThemesOption() ); } - public function testCustomMainConfigurationFilesPath() + public function testCustomMainConfigurationFilesPath(): void { $config = $this->processor->processConfiguration(new Configuration(), [ [ @@ -103,7 +106,7 @@ public function testCustomMainConfigurationFilesPath() ] ]); - $this->assertSame( + self::assertSame( [ 'yaml_configuration' => [ 'main_configuration_directory' => 'a path to main configuration directory', @@ -115,7 +118,7 @@ public function testCustomMainConfigurationFilesPath() ); } - protected function setUp() + protected function setUp(): void { $this->processor = new Processor(); } diff --git a/Tests/Extension/Symfony/CoreExtensionTest.php b/Tests/Extension/Symfony/CoreExtensionTest.php index ea21b88..d6352e9 100644 --- a/Tests/Extension/Symfony/CoreExtensionTest.php +++ b/Tests/Extension/Symfony/CoreExtensionTest.php @@ -18,10 +18,9 @@ class CoreExtensionTest extends TestCase { - public function testBindParameters() + public function testBindParameters(): void { $extension = new CoreExtension(); - $driver = $this->createMock(DriverInterface::class); $datasource = $this->createMock(DataSourceInterface::class); $data1 = ['key1' => 'value1', 'key2' => 'value2']; $data2 = $data1; @@ -32,13 +31,13 @@ public function testBindParameters() $args = new DataSourceEvent\ParametersEventArgs($datasource, $data2); $subscriber->preBindParameters($args); $data2 = $args->getParameters(); - $this->assertEquals($data1, $data2); + self::assertEquals($data1, $data2); $request = new Request($data2); $args = new DataSourceEvent\ParametersEventArgs($datasource, $request); $subscriber->preBindParameters($args); $request = $args->getParameters(); - $this->assertTrue(is_array($request)); - $this->assertEquals($data1, $request); + self::assertIsArray($request); + self::assertEquals($data1, $request); } } diff --git a/Tests/Extension/Symfony/FormExtensionEntityTest.php b/Tests/Extension/Symfony/FormExtensionEntityTest.php index eddfb0c..835556d 100644 --- a/Tests/Extension/Symfony/FormExtensionEntityTest.php +++ b/Tests/Extension/Symfony/FormExtensionEntityTest.php @@ -12,9 +12,11 @@ use Doctrine\ORM\EntityManager; use Doctrine\ORM\Tools\SchemaTool; use Doctrine\ORM\Tools\Setup; +use Doctrine\Persistence\ManagerRegistry as PersistenceManagerRegistry; use FSi\Bundle\DataSourceBundle\DataSource\Extension\Symfony\Form\Driver\DriverExtension; use FSi\Bundle\DataSourceBundle\Tests\Fixtures\News; use FSi\Bundle\DataSourceBundle\Tests\Fixtures\TestManagerRegistry; +use FSi\Bundle\DataSourceBundle\Tests\Fixtures\TestManagerRegistryNew; use FSi\Component\DataSource\DataSourceInterface; use FSi\Component\DataSource\Event\FieldEvent; use FSi\Component\DataSource\Field\FieldAbstractExtension; @@ -31,9 +33,11 @@ use Symfony\Component\Security\Csrf\CsrfTokenManager; use Symfony\Component\Translation\TranslatorInterface; +use function interface_exists; + class FormExtensionEntityTest extends TestCase { - public function testEntityField() + public function testEntityField(): void { $formFactory = $this->getFormFactory(); $translator = $this->createMock(TranslatorInterface::class); @@ -41,50 +45,51 @@ public function testEntityField() $field = $this->createMock(FieldTypeInterface::class); $datasource = $this->createMock(DataSourceInterface::class); - $datasource->expects($this->any())->method('getName')->will($this->returnValue('datasource')); - - $field->expects($this->atLeastOnce())->method('getName')->will($this->returnValue('name')); - $field->expects($this->any())->method('getDataSource')->will($this->returnValue($datasource)); - $field->expects($this->any())->method('getName')->will($this->returnValue('name')); - $field->expects($this->any())->method('getType')->will($this->returnValue('entity')); + $datasource->method('getName')->willReturn('datasource'); - $field - ->expects($this->any()) - ->method('hasOption') - ->will($this->returnCallback(function (): bool { - $args = func_get_args(); + $field->expects(self::atLeastOnce())->method('getName')->willReturn('name'); + $field->method('getDataSource')->willReturn($datasource); + $field->method('getName')->willReturn('name'); + $field->method('getType')->willReturn('entity'); - return 'form_options' === array_shift($args); - })) + $field->method('hasOption') + ->willReturnCallback( + function (string $option): bool { + return 'form_options' === $option; + } + ) ; - $field - ->expects($this->any()) - ->method('getOption') - ->will($this->returnCallback(function () { - switch (func_get_arg(0)) { - case 'form_filter': - return true; - case 'form_options': - return ['class' => News::class]; + $field->method('getOption') + ->willReturnCallback( + function (string $option) { + switch ($option) { + case 'form_filter': + return true; + case 'form_options': + return ['class' => News::class]; + } + + return null; } - })) + ) ; $extensions = $extension->getFieldTypeExtensions('entity'); $parameters = ['datasource' => [DataSourceInterface::PARAMETER_FIELDS => ['name' => 'value']]]; - //Form extension will remove 'name' => 'value' since this is not valid entity id (since we have no entities at all). + // Form extension will remove 'name' => 'value' since this is not valid entity id + // (since we have no entities at all). $parameters2 = ['datasource' => [DataSourceInterface::PARAMETER_FIELDS => []]]; $args = new FieldEvent\ParameterEventArgs($field, $parameters); foreach ($extensions as $ext) { - $this->assertTrue($ext instanceof FieldAbstractExtension); + self::assertInstanceOf(FieldAbstractExtension::class, $ext); $ext->preBindParameter($args); } $parameters = $args->getParameter(); - $this->assertEquals($parameters2, $parameters); + self::assertEquals($parameters2, $parameters); - $fieldView = $this->createMock(FieldViewInterface::class, [], [$field]); - $fieldView->expects($this->atLeastOnce())->method('setAttribute'); + $fieldView = $this->getMockBuilder(FieldViewInterface::class)->setConstructorArgs([$field])->getMock(); + $fieldView->expects(self::atLeastOnce())->method('setAttribute'); $args = new FieldEvent\ViewEventArgs($field, $fieldView); foreach ($extensions as $ext) { @@ -95,16 +100,22 @@ public function testEntityField() private function getFormFactory(): FormFactoryInterface { $typeFactory = new ResolvedFormTypeFactory(); + if (true === interface_exists(PersistenceManagerRegistry::class)) { + $managerRegistry = new TestManagerRegistryNew($this->getEntityManager()); + } else { + $managerRegistry = new TestManagerRegistry($this->getEntityManager()); + } + $registry = new FormRegistry( [ new CoreExtension(), new CsrfExtension(new CsrfTokenManager()), - new DoctrineOrmExtension(new TestManagerRegistry($this->getEntityManager())), + new DoctrineOrmExtension($managerRegistry), ], $typeFactory ); - return new FormFactory($registry, $typeFactory); + return new FormFactory($registry); } private function getEntityManager(): EntityManager diff --git a/Tests/Extension/Symfony/FormExtensionTest.php b/Tests/Extension/Symfony/FormExtensionTest.php index 6ce104c..6358c56 100644 --- a/Tests/Extension/Symfony/FormExtensionTest.php +++ b/Tests/Extension/Symfony/FormExtensionTest.php @@ -75,20 +75,20 @@ public static function fieldTypesProvider(): array /** * Checks creation of DriverExtension. */ - public function testCreateDriverExtension() + public function testCreateDriverExtension(): void { $formFactory = $this->getFormFactory(); $translator = $this->createMock(TranslatorInterface::class); $driver = new DriverExtension($formFactory, $translator); // Without an assertion the test would be marked as risky - $this->assertNotNull($driver); + self::assertNotNull($driver); } /** * Tests if driver extension has all needed fields. */ - public function testDriverExtension() + public function testDriverExtension(): void { $this->expectException(DataSourceException::class); @@ -96,13 +96,13 @@ public function testDriverExtension() $translator = $this->createMock(TranslatorInterface::class); $extension = new DriverExtension($formFactory, $translator); - $this->assertTrue($extension->hasFieldTypeExtensions('text')); - $this->assertTrue($extension->hasFieldTypeExtensions('number')); - $this->assertTrue($extension->hasFieldTypeExtensions('entity')); - $this->assertTrue($extension->hasFieldTypeExtensions('date')); - $this->assertTrue($extension->hasFieldTypeExtensions('time')); - $this->assertTrue($extension->hasFieldTypeExtensions('datetime')); - $this->assertFalse($extension->hasFieldTypeExtensions('wrong')); + self::assertTrue($extension->hasFieldTypeExtensions('text')); + self::assertTrue($extension->hasFieldTypeExtensions('number')); + self::assertTrue($extension->hasFieldTypeExtensions('entity')); + self::assertTrue($extension->hasFieldTypeExtensions('date')); + self::assertTrue($extension->hasFieldTypeExtensions('time')); + self::assertTrue($extension->hasFieldTypeExtensions('datetime')); + self::assertFalse($extension->hasFieldTypeExtensions('wrong')); $extension->getFieldTypeExtensions('text'); $extension->getFieldTypeExtensions('number'); @@ -113,7 +113,7 @@ public function testDriverExtension() $extension->getFieldTypeExtensions('wrong'); } - public function testFormOrder() + public function testFormOrder(): void { $datasource = $this->createMock(DataSourceInterface::class); $view = $this->createMock(DataSourceViewInterface::class); @@ -127,18 +127,18 @@ public function testFormOrder() unset($order); if ($i < 5) { $order = -4 + $i; - } else if ($i > 10) { + } elseif ($i > 10) { $order = $i - 10; } - $field->expects($this->any())->method('getName')->willReturn('field' . $i); - $field->expects($this->any())->method('hasOption')->willReturn(isset($order)); + $field->method('getName')->willReturn('field' . $i); + $field->method('hasOption')->willReturn(isset($order)); if (isset($order)) { - $field->expects($this->any())->method('getOption')->willReturn($order); + $field->method('getOption')->willReturn($order); } - $fieldView->expects($this->any())->method('getName')->willReturn('field' . $i); + $fieldView->method('getName')->willReturn('field' . $i); $fields['field' . $i] = $field; $fieldViews['field' . $i] = $fieldView; if (isset($order)) { @@ -149,32 +149,47 @@ public function testFormOrder() } $datasource - ->expects($this->any()) ->method('getField') - ->will($this->returnCallback(function($field) use ($fields) { - return $fields[$field]; - })) + ->willReturnCallback( + function ($field) use ($fields) { + return $fields[$field]; + } + ) ; - $view->expects($this->any())->method('getFields')->will($this->returnValue($fieldViews)); + $view->method('getFields')->willReturn($fieldViews); $view - ->expects($this->once()) + ->expects(self::once()) ->method('setFields') - ->will($this->returnCallback(function(array $fields) { - $names = []; - foreach ($fields as $field) { - $names[] = $field->getName(); + ->willReturnCallback( + function (array $fields) { + $names = []; + foreach ($fields as $field) { + $names[] = $field->getName(); + } + + $this->assertSame( + [ + 'field0', + 'field1', + 'field2', + 'field3', + 'field5', + 'field6', + 'field7', + 'field8', + 'field9', + 'field10', + 'field4', + 'field11', + 'field12', + 'field13', + 'field14' + ], + $names + ); } - - $this->assertSame( - [ - 'field0', 'field1', 'field2', 'field3', 'field5', - 'field6', 'field7', 'field8', 'field9', 'field10', 'field4', - 'field11', 'field12', 'field13', 'field14' - ], - $names - ); - })) + ) ; $event = new ViewEventArgs($datasource, $view); @@ -185,39 +200,41 @@ public function testFormOrder() /** * @dataProvider typesProvider() */ - public function testFields(string $type) + public function testFields(string $type): void { $formFactory = $this->getFormFactory(); $translator = $this->createMock(TranslatorInterface::class); $extension = new DriverExtension($formFactory, $translator); $datasource = $this->createMock(DataSourceInterface::class); - $datasource->expects($this->any())->method('getName')->willReturn('datasource'); + $datasource->method('getName')->willReturn('datasource'); $field = $this->createMock(FieldTypeInterface::class); - $field->expects($this->atLeastOnce())->method('getName')->willReturn('name'); - $field->expects($this->any())->method('getDataSource')->willReturn($datasource); - $field->expects($this->any())->method('getType')->willReturn($type); - $field->expects($this->any())->method('hasOption')->willReturn(false); + $field->expects(self::atLeastOnce())->method('getName')->willReturn('name'); + $field->method('getDataSource')->willReturn($datasource); + $field->method('getType')->willReturn($type); + $field->method('hasOption')->willReturn(false); $field - ->expects($this->any()) ->method('getOption') - ->will($this->returnCallback(function($option) use ($type) { - switch ($option) { - case 'form_filter': - return true; - case 'form_from_options': - case 'form_to_options': - return []; - case 'form_options': - return true === in_array($type, ['date', 'datetime'], true) - // By default the year range for the date select widget - // is 5 years into past. - ? ['years' => range(2012, (int) date('Y'))] - : [] - ; + ->willReturnCallback( + function (string $option) use ($type) { + switch ($option) { + case 'form_filter': + return true; + case 'form_from_options': + case 'form_to_options': + return []; + case 'form_options': + return true === in_array($type, ['date', 'datetime'], true) + // By default the year range for the date select widget + // is 5 years into past. + ? ['years' => range(2012, (int) date('Y'))] + : []; + } + + return null; } - })) + ) ; $extensions = $extension->getFieldTypeExtensions($type); @@ -250,7 +267,7 @@ public function testFields(string $type) $parameters2 = [ 'datasource' => [ DataSourceInterface::PARAMETER_FIELDS => [ - 'name' => new DateTimeImmutable(date('Y-m-d', 0).' 12:12:00') + 'name' => new DateTimeImmutable(date('Y-m-d', 0) . ' 12:12:00') ] ] ]; @@ -262,7 +279,13 @@ public function testFields(string $type) ] ] ]; - $parameters2 = ['datasource' => [DataSourceInterface::PARAMETER_FIELDS => ['name' => new DateTimeImmutable('2012-12-12')]]]; + $parameters2 = [ + 'datasource' => [ + DataSourceInterface::PARAMETER_FIELDS => [ + 'name' => new DateTimeImmutable('2012-12-12') + ] + ] + ]; } elseif ($type === 'number') { $parameters = ['datasource' => [DataSourceInterface::PARAMETER_FIELDS => ['name' => 123]]]; $parameters2 = $parameters; @@ -273,28 +296,31 @@ public function testFields(string $type) $args = new FieldEvent\ParameterEventArgs($field, $parameters); foreach ($extensions as $ext) { - $this->assertTrue($ext instanceof FieldAbstractExtension); + self::assertInstanceOf(FormFieldExtension::class, $ext); $ext->preBindParameter($args); } - $this->assertEquals($parameters2, $args->getParameter()); + self::assertEquals($parameters2, $args->getParameter()); $fieldView = $this->getMockBuilder(FieldViewInterface::class) ->setConstructorArgs([$field]) ->getMock() ; $fieldView - ->expects($this->atLeastOnce()) + ->expects(self::atLeastOnce()) ->method('setAttribute') - ->will($this->returnCallback(function ($attribute, $value) use ($type) { - if ($attribute === 'form') { - $this->assertInstanceOf(FormView::class, $value); + ->willReturnCallback( + function (string $attribute, $value): void { + if ($attribute === 'form') { + self::assertInstanceOf(FormView::class, $value); + } } - })) + ) ; $args = new FieldEvent\ViewEventArgs($field, $fieldView); foreach ($extensions as $ext) { + self::assertInstanceOf(FormFieldExtension::class, $ext); $ext->postBuildView($args); } } @@ -302,38 +328,41 @@ public function testFields(string $type) /** * @dataProvider fieldTypesProvider */ - public function testFormFields(string $type, string $comparison, $expected) + public function testFormFields(string $type, string $comparison, $expected): void { $formFactory = $this->getFormFactory(); $translator = $this->getTranslator(); $extension = new DriverExtension($formFactory, $translator); $driver = $this->createMock(DriverInterface::class); $datasource = $this->createMock(DataSourceInterface::class); - $datasource->expects($this->any())->method('getName')->willReturn('datasource'); + $datasource->method('getName')->willReturn('datasource'); $field = $this->createMock(FieldTypeInterface::class); - $field->expects($this->atLeastOnce())->method('getName')->willReturn('name'); - $field->expects($this->any())->method('getDataSource')->willReturn($datasource); - $field->expects($this->any())->method('getType')->willReturn($type); - $field->expects($this->any())->method('hasOption')->willReturn(false); - $field->expects($this->any())->method('getComparison')->willReturn($comparison); + $field->expects(self::atLeastOnce())->method('getName')->willReturn('name'); + $field->method('getDataSource')->willReturn($datasource); + $field->method('getType')->willReturn($type); + $field->method('hasOption')->willReturn(false); + $field->method('getComparison')->willReturn($comparison); $field - ->expects($this->any()) ->method('getOption') - ->will($this->returnCallback(function($option) { - switch ($option) { - case 'form_filter': - return true; - - case 'form_type': - return null; - - case 'form_from_options': - case 'form_to_options': - case 'form_options': - return []; + ->willReturnCallback( + function (string $option) { + switch ($option) { + case 'form_filter': + return true; + + case 'form_type': + return null; + + case 'form_from_options': + case 'form_to_options': + case 'form_options': + return []; + } + + return null; } - })) + ) ; $extensions = $extension->getFieldTypeExtensions($type); @@ -344,27 +373,28 @@ public function testFormFields(string $type, string $comparison, $expected) $viewEventArgs = new FieldEvent\ViewEventArgs($field, $view); foreach ($extensions as $ext) { + self::assertInstanceOf(FormFieldExtension::class, $ext); $ext->preBindParameter($args); $ext->postBuildView($viewEventArgs); } $form = $viewEventArgs->getView()->getAttribute('form'); - $this->assertEquals($expected, $form['fields']['name']->vars['block_prefixes'][1]); + self::assertEquals($expected, $form['fields']['name']->vars['block_prefixes'][1]); if ($comparison === 'isNull') { - $this->assertEquals( + self::assertEquals( 'is_null_translated', $form['fields']['name']->vars['choices'][0]->label ); - $this->assertEquals( + self::assertEquals( 'is_not_null_translated', $form['fields']['name']->vars['choices'][1]->label ); } } - public function testBuildBooleanFormWhenOptionsProvided() + public function testBuildBooleanFormWhenOptionsProvided(): void { $formFactory = $this->getFormFactory(); $translator = $this->getTranslator(); @@ -373,19 +403,21 @@ public function testBuildBooleanFormWhenOptionsProvided() $datasource = $this->createMock(DataSourceInterface::class); $field = $this->createMock(Boolean::class); - $field->expects($this->atLeastOnce())->method('getName')->willReturn('name'); - $field->expects($this->atLeastOnce())->method('getDataSource')->willReturn($datasource); - $field->expects($this->atLeastOnce())->method('getType')->willReturn('boolean'); - $field->expects($this->atLeastOnce()) + $field->expects(self::atLeastOnce())->method('getName')->willReturn('name'); + $field->expects(self::atLeastOnce())->method('getDataSource')->willReturn($datasource); + $field->expects(self::atLeastOnce())->method('getType')->willReturn('boolean'); + $field->expects(self::atLeastOnce()) ->method('getOption') - ->will($this->returnCallback(function($option) { - switch ($option) { - case 'form_filter': - return true; - case 'form_options': - return ['choices' => ['tak' => '1', 'nie' => '0']]; + ->willReturnCallback( + function ($option) { + switch ($option) { + case 'form_filter': + return true; + case 'form_options': + return ['choices' => ['tak' => '1', 'nie' => '0']]; + } } - })); + ); $parameters = ['datasource' => [DataSourceInterface::PARAMETER_FIELDS => ['name' => 'null']]]; $args = new FieldEvent\ParameterEventArgs($field, $parameters); @@ -398,13 +430,13 @@ public function testBuildBooleanFormWhenOptionsProvided() $form = $viewEventArgs->getView()->getAttribute('form'); $choices = $form['fields']['name']->vars['choices']; - $this->assertEquals($choices[0]->value, '1'); - $this->assertEquals($choices[0]->label, 'tak'); - $this->assertEquals($choices[1]->value, '0'); - $this->assertEquals($choices[1]->label, 'nie'); + self::assertEquals($choices[0]->value, '1'); + self::assertEquals($choices[0]->label, 'tak'); + self::assertEquals($choices[1]->value, '0'); + self::assertEquals($choices[1]->label, 'nie'); } - public function testBuildBooleanFormWhenOptionsNotProvided() + public function testBuildBooleanFormWhenOptionsNotProvided(): void { $formFactory = $this->getFormFactory(); $translator = $this->getTranslator(); @@ -412,19 +444,21 @@ public function testBuildBooleanFormWhenOptionsNotProvided() $datasource = $this->createMock(DataSourceInterface::class); $field = $this->createMock(Boolean::class); - $field->expects($this->atLeastOnce())->method('getName')->willReturn('name'); - $field->expects($this->atLeastOnce())->method('getDataSource')->willReturn($datasource); - $field->expects($this->atLeastOnce())->method('getType')->willReturn('boolean'); - $field->expects($this->atLeastOnce()) + $field->expects(self::atLeastOnce())->method('getName')->willReturn('name'); + $field->expects(self::atLeastOnce())->method('getDataSource')->willReturn($datasource); + $field->expects(self::atLeastOnce())->method('getType')->willReturn('boolean'); + $field->expects(self::atLeastOnce()) ->method('getOption') - ->will($this->returnCallback(function($option) { - switch ($option) { - case 'form_filter': - return true; - case 'form_options': - return []; + ->willReturnCallback( + function ($option) { + switch ($option) { + case 'form_filter': + return true; + case 'form_options': + return []; + } } - })); + ); $args = new FieldEvent\ParameterEventArgs( $field, @@ -439,27 +473,29 @@ public function testBuildBooleanFormWhenOptionsNotProvided() $form = $viewEventArgs->getView()->getAttribute('form'); $choices = $form['fields']['name']->vars['choices']; - $this->assertEquals($choices[0]->value, '1'); - $this->assertEquals($choices[0]->label, 'yes_translated'); - $this->assertEquals($choices[1]->value, '0'); - $this->assertEquals($choices[1]->label, 'no_translated'); + self::assertEquals($choices[0]->value, '1'); + self::assertEquals($choices[0]->label, 'yes_translated'); + self::assertEquals($choices[1]->value, '0'); + self::assertEquals($choices[1]->label, 'no_translated'); } /** * @dataProvider getDatasourceFieldTypes */ - public function testCreateDataSourceFieldWithCustomFormType(string $dataSourceFieldType, string $comparison = null) - { + public function testCreateDataSourceFieldWithCustomFormType( + string $dataSourceFieldType, + string $comparison = null + ): void { $formFactory = $this->getFormFactory(); $translator = $this->getTranslator(); $formFieldExtension = new FormFieldExtension($formFactory, $translator); $field = $this->createMock(FieldTypeInterface::class); $datasource = $this->createMock(DataSourceInterface::class); - $field->expects($this->atLeastOnce())->method('getName')->willReturn('name'); - $field->expects($this->atLeastOnce())->method('getDataSource')->willReturn($datasource); - $field->expects($this->atLeastOnce())->method('getType')->willReturn($dataSourceFieldType); - $field->expects($this->atLeastOnce())->method('getComparison')->willReturn($comparison); + $field->expects(self::atLeastOnce())->method('getName')->willReturn('name'); + $field->expects(self::atLeastOnce())->method('getDataSource')->willReturn($datasource); + $field->expects(self::atLeastOnce())->method('getType')->willReturn($dataSourceFieldType); + $field->expects(self::atLeastOnce())->method('getComparison')->willReturn($comparison); $options = [ 'form_filter' => true, @@ -467,17 +503,21 @@ public function testCreateDataSourceFieldWithCustomFormType(string $dataSourceFi 'form_type' => HiddenType::class ]; - $field->expects($this->atLeastOnce()) - ->method('hasOption') - ->will($this->returnCallback(function($option) use ($options) { - return isset($options[$option]); - })); + $field->expects(self::atLeastOnce()) + ->method('hasOption') + ->willReturnCallback( + function ($option) use ($options) { + return isset($options[$option]); + } + ); - $field->expects($this->atLeastOnce()) - ->method('getOption') - ->will($this->returnCallback(function($option) use ($options) { - return $options[$option]; - })); + $field->expects(self::atLeastOnce()) + ->method('getOption') + ->willReturnCallback( + function ($option) use ($options) { + return $options[$option]; + } + ); $args = new FieldEvent\ParameterEventArgs( $field, @@ -491,10 +531,10 @@ public function testCreateDataSourceFieldWithCustomFormType(string $dataSourceFi $formFieldExtension->postBuildView($viewEventArgs); $form = $viewEventArgs->getView()->getAttribute('form'); - $this->assertEquals('hidden', $form['fields']['name']->vars['block_prefixes'][1]); + self::assertEquals('hidden', $form['fields']['name']->vars['block_prefixes'][1]); } - public function getDatasourceFieldTypes() + public function getDatasourceFieldTypes(): array { return [ [ @@ -525,32 +565,36 @@ private function getFormFactory(): FormFactoryInterface $typeFactory ); - return new Form\FormFactory($registry, $typeFactory); + return new Form\FormFactory($registry); } - private function getTranslator(): MockObject + /** + * @return TranslatorInterface&MockObject + */ + private function getTranslator(): TranslatorInterface { $translator = $this->createMock(TranslatorInterface::class); - $translator->expects($this->any()) - ->method('trans') - ->will($this->returnCallback(function ($id, array $params, $translation_domain) { - if ($translation_domain !== 'DataSourceBundle') { - throw new RuntimeException(sprintf('Unknown translation domain %s', $translation_domain)); + $translator->method('trans') + ->willReturnCallback( + function ($id, array $params, $translation_domain): string { + if ($translation_domain !== 'DataSourceBundle') { + throw new RuntimeException(sprintf('Unknown translation domain %s', $translation_domain)); + } + + switch ($id) { + case 'datasource.form.choices.is_null': + return 'is_null_translated'; + case 'datasource.form.choices.is_not_null': + return 'is_not_null_translated'; + case 'datasource.form.choices.yes': + return 'yes_translated'; + case 'datasource.form.choices.no': + return 'no_translated'; + default: + throw new RuntimeException(sprintf('Unknown translation id %s', $id)); + } } - - switch ($id) { - case 'datasource.form.choices.is_null': - return 'is_null_translated'; - case 'datasource.form.choices.is_not_null': - return 'is_not_null_translated'; - case 'datasource.form.choices.yes': - return 'yes_translated'; - case 'datasource.form.choices.no': - return 'no_translated'; - default: - throw new RuntimeException(sprintf('Unknown translation id %s', $id)); - } - })); + ); return $translator; } diff --git a/Tests/Fixtures/Form/Extension/TestCore/Type/FormType.php b/Tests/Fixtures/Form/Extension/TestCore/Type/FormType.php index cf4798d..efb59a8 100644 --- a/Tests/Fixtures/Form/Extension/TestCore/Type/FormType.php +++ b/Tests/Fixtures/Form/Extension/TestCore/Type/FormType.php @@ -19,6 +19,6 @@ public function buildView(FormView $view, FormInterface $form, array $options) { parent::buildView($view, $form, $options); - $view->vars['type'] = $form->getConfig()->getType()->getName(); + $view->vars['type'] = $form->getConfig()->getType()->getInnerType()->getBlockPrefix(); } } diff --git a/Tests/Fixtures/News.php b/Tests/Fixtures/News.php index fd038df..a40c6e4 100644 --- a/Tests/Fixtures/News.php +++ b/Tests/Fixtures/News.php @@ -189,7 +189,7 @@ public function setCreateDate($createDate) * * @return \DateTime */ - public function getCreate_Date() + public function getCreateDate() { return $this->create_date; } @@ -237,7 +237,7 @@ public function getCategory() /** * Set category2. * - * @param Category $category + * @param Category $category2 */ public function setCategory2(Category $category2) { diff --git a/Tests/Fixtures/StubTranslator.php b/Tests/Fixtures/StubTranslator.php new file mode 100644 index 0000000..e1b285a --- /dev/null +++ b/Tests/Fixtures/StubTranslator.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace FSi\Bundle\DataSourceBundle\Tests\Fixtures; + +use Symfony\Component\Translation\TranslatorInterface; + +class StubTranslator implements TranslatorInterface +{ + private $locale; + + public function trans($id, array $parameters = array(), $domain = null, $locale = null) + { + return '[trans]' . $id . '[/trans]'; + } + + public function transChoice($id, $number, array $parameters = [], $domain = null, $locale = null) + { + return '[trans]' . $id . '[/trans]'; + } + + public function setLocale($locale) + { + $this->locale = $locale; + } + + public function getLocale() + { + return $this->locale; + } +} diff --git a/Tests/Fixtures/TestManagerRegistry.php b/Tests/Fixtures/TestManagerRegistry.php index 7ebb630..9c50f02 100644 --- a/Tests/Fixtures/TestManagerRegistry.php +++ b/Tests/Fixtures/TestManagerRegistry.php @@ -20,7 +20,7 @@ class TestManagerRegistry implements ManagerRegistry /** * Test managers name. */ - const NAME = 'test'; + private const NAME = 'test'; /** * @var EntityManager @@ -79,7 +79,7 @@ public function getConnectionNames() /** * {@inheritdoc} */ - function getManager($name = null) + public function getManager($name = null) { return $this->em; } @@ -87,7 +87,7 @@ function getManager($name = null) /** * {@inheritdoc} */ - function getManagers() + public function getManagers() { return [$this->em]; } @@ -95,21 +95,21 @@ function getManagers() /** * {@inheritdoc} */ - function resetManager($name = null) + public function resetManager($name = null) { } /** * {@inheritdoc} */ - function getAliasNamespace($alias) + public function getAliasNamespace($alias) { } /** * {@inheritdoc} */ - function getManagerNames() + public function getManagerNames() { return [self::NAME]; } @@ -117,7 +117,7 @@ function getManagerNames() /** * {@inheritdoc} */ - function getRepository($persistentObject, $persistentManagerName = null) + public function getRepository($persistentObject, $persistentManagerName = null) { return $this->em; } @@ -125,7 +125,7 @@ function getRepository($persistentObject, $persistentManagerName = null) /** * {@inheritdoc} */ - function getManagerForClass($class) + public function getManagerForClass($class) { return $this->em; } diff --git a/Tests/Fixtures/TestManagerRegistryNew.php b/Tests/Fixtures/TestManagerRegistryNew.php new file mode 100644 index 0000000..0ad2034 --- /dev/null +++ b/Tests/Fixtures/TestManagerRegistryNew.php @@ -0,0 +1,134 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FSi\Bundle\DataSourceBundle\Tests\Fixtures; + +use Doctrine\Persistence\ManagerRegistry; +use Doctrine\ORM\EntityManager; + +/** + * It's dumb implementation of ManagerRegistry, but it's enough for testing purposes. + */ +class TestManagerRegistryNew implements ManagerRegistry +{ + /** + * Test managers name. + */ + private const NAME = 'test'; + + /** + * @var EntityManager + */ + private $em; + + /** + * @param EntityManager $em + */ + public function __construct(EntityManager $em) + { + $this->em = $em; + } + + /** + * {@inheritdoc} + */ + public function getDefaultManagerName() + { + return self::NAME; + } + + /** + * {@inheritdoc} + */ + public function getDefaultConnectionName() + { + return self::NAME; + } + + /** + * {@inheritdoc} + */ + public function getConnection($name = null) + { + return $this->em; + } + + /** + * {@inheritdoc} + */ + public function getConnections() + { + return [$this->em]; + } + + /** + * {@inheritdoc} + */ + public function getConnectionNames() + { + return [self::NAME]; + } + + + /** + * {@inheritdoc} + */ + public function getManager($name = null) + { + return $this->em; + } + + /** + * {@inheritdoc} + */ + public function getManagers() + { + return [$this->em]; + } + + /** + * {@inheritdoc} + */ + public function resetManager($name = null) + { + return $this->em; + } + + /** + * {@inheritdoc} + */ + public function getAliasNamespace($alias) + { + return ''; + } + + /** + * {@inheritdoc} + */ + public function getManagerNames() + { + return [self::NAME]; + } + + /** + * {@inheritdoc} + */ + public function getRepository($persistentObject, $persistentManagerName = null) + { + return $this->em; + } + + /** + * {@inheritdoc} + */ + public function getManagerForClass($class) + { + return $this->em; + } +} diff --git a/Tests/Twig/Extension/DataSourceExtensionTest.php b/Tests/Twig/Extension/DataSourceExtensionTest.php index 86d16f8..614f8c9 100644 --- a/Tests/Twig/Extension/DataSourceExtensionTest.php +++ b/Tests/Twig/Extension/DataSourceExtensionTest.php @@ -9,6 +9,7 @@ namespace FSi\Bundle\DataSourceBundle\Tests\Twig\Extension; +use FSi\Bundle\DataSourceBundle\Tests\Fixtures\StubTranslator; use FSi\Bundle\DataSourceBundle\Twig\Extension\DataSourceExtension; use FSi\Component\DataSource\DataSourceViewInterface; use FSi\Component\DataSource\Field\FieldViewInterface; @@ -16,7 +17,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\Twig\Extension\FormExtension; use Symfony\Bridge\Twig\Extension\TranslationExtension; -use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubTranslator; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Routing\RouterInterface; use Twig\Environment; @@ -39,7 +39,7 @@ class DataSourceExtensionTest extends TestCase */ protected $extension; - public function testInitRuntimeShouldThrowExceptionBecauseNotExistingTheme() + public function testInitRuntimeShouldThrowExceptionBecauseNotExistingTheme(): void { $this->expectException(LoaderError::class); $this->expectExceptionMessage('Unable to find template "this_is_not_valid_path.html.twig"'); @@ -49,14 +49,14 @@ public function testInitRuntimeShouldThrowExceptionBecauseNotExistingTheme() $this->twig->loadTemplate('datasource.html.twig'); } - public function testInitRuntimeWithValidPathToTheme() + public function testInitRuntimeWithValidPathToTheme(): void { $this->twig->addExtension($this->extension); // force initRuntime() - $this->assertInstanceOf(Template::class, $this->twig->loadTemplate('datasource.html.twig')); + self::assertInstanceOf(Template::class, $this->twig->loadTemplate('datasource.html.twig')); } - public function testDataSourceFilterCount() + public function testDataSourceFilterCount(): void { $this->twig->addExtension($this->extension); // force initRuntime() @@ -64,39 +64,39 @@ public function testDataSourceFilterCount() $datasourceView = $this->getDataSourceView('datasource'); $fieldView1 = $this->createMock(FieldViewInterface::class); - $fieldView1->expects($this->atLeastOnce())->method('hasAttribute')->with('form')->willReturn(true); + $fieldView1->expects(self::atLeastOnce())->method('hasAttribute')->with('form')->willReturn(true); $fieldView2 = $this->createMock(FieldViewInterface::class); - $fieldView2->expects($this->atLeastOnce())->method('hasAttribute')->with('form')->willReturn(false); + $fieldView2->expects(self::atLeastOnce())->method('hasAttribute')->with('form')->willReturn(false); $fieldView3 = $this->createMock(FieldViewInterface::class); - $fieldView3->expects($this->atLeastOnce())->method('hasAttribute')->with('form')->willReturn(true); + $fieldView3->expects(self::atLeastOnce())->method('hasAttribute')->with('form')->willReturn(true); - $datasourceView->expects($this->atLeastOnce()) + $datasourceView->expects(self::atLeastOnce()) ->method('getFields') ->willReturn([$fieldView1, $fieldView2, $fieldView3]) ; - $this->assertEquals(2, $this->extension->datasourceFilterCount($datasourceView)); + self::assertEquals(2, $this->extension->datasourceFilterCount($datasourceView)); } - public function testDataSourceRenderBlock() + public function testDataSourceRenderBlock(): void { $this->twig->addExtension($this->extension); // force initRuntime() $this->twig->loadTemplate('datasource.html.twig'); $template = $this->getTemplateMock(); - $template->expects($this->at(0))->method('hasBlock') + $template->expects(self::at(0))->method('hasBlock') ->with('datasource_datasource_filter') ->willReturn(false) ; - $template->expects($this->at(1))->method('getParent')->with([])->willReturn(false); - $template->expects($this->at(2))->method('hasBlock')->with('datasource_filter')->willReturn(true); + $template->expects(self::at(1))->method('getParent')->with([])->willReturn(false); + $template->expects(self::at(2))->method('hasBlock')->with('datasource_filter')->willReturn(true); $datasourceView = $this->getDataSourceView('datasource'); $this->extension->setTheme($datasourceView, $template); - $template->expects($this->at(3)) + $template->expects(self::at(3)) ->method('displayBlock') ->with('datasource_filter', [ 'datasource' => $datasourceView, @@ -109,7 +109,7 @@ public function testDataSourceRenderBlock() $this->extension->datasourceFilter($datasourceView); } - public function testDataSourceRenderBlockFromParent() + public function testDataSourceRenderBlockFromParent(): void { $this->twig->addExtension($this->extension); // force initRuntime() @@ -117,21 +117,21 @@ public function testDataSourceRenderBlockFromParent() $parent = $this->getTemplateMock(); $template = $this->getTemplateMock(); - $template->expects($this->at(0)) + $template->expects(self::at(0)) ->method('hasBlock') ->with('datasource_datasource_filter') ->willReturn(false) ; - $template->expects($this->at(1))->method('getParent')->with([])->willReturn(false); - $template->expects($this->at(2))->method('hasBlock')->with('datasource_filter')->willReturn(false); - $template->expects($this->at(3))->method('getParent')->with([])->willReturn($parent); - $parent->expects($this->at(0))->method('hasBlock')->with('datasource_filter')->willReturn(true); + $template->expects(self::at(1))->method('getParent')->with([])->willReturn(false); + $template->expects(self::at(2))->method('hasBlock')->with('datasource_filter')->willReturn(false); + $template->expects(self::at(3))->method('getParent')->with([])->willReturn($parent); + $parent->expects(self::at(0))->method('hasBlock')->with('datasource_filter')->willReturn(true); $datasourceView = $this->getDataSourceView('datasource'); $this->extension->setTheme($datasourceView, $template); - $parent->expects($this->at(1)) + $parent->expects(self::at(1)) ->method('displayBlock') ->with('datasource_filter', [ 'datasource' => $datasourceView, @@ -143,7 +143,7 @@ public function testDataSourceRenderBlockFromParent() $this->extension->datasourceFilter($datasourceView); } - protected function setUp() + protected function setUp(): void { $loader = new FilesystemLoader([ __DIR__ . '/../../../vendor/symfony/twig-bridge/Resources/views/Form', @@ -162,28 +162,38 @@ protected function setUp() private function getRouter(): MockObject { $router = $this->createMock(RouterInterface::class); - $router->expects($this->any())->method('generate')->willReturn('some_route'); + $router->method('generate')->willReturn('some_route'); return $router; } - private function getContainer(): MockObject + /** + * @return ContainerInterface&MockObject + */ + private function getContainer(): ContainerInterface { $container = $this->createMock(ContainerInterface::class); - $container->expects($this->any())->method('get')->with('router')->willReturn($this->getRouter()); + $container->method('get')->with('router')->willReturn($this->getRouter()); return $container; } - private function getDataSourceView(string $name): MockObject + /** + * @param string $name + * @return DataSourceViewInterface&MockObject + */ + private function getDataSourceView(string $name): DataSourceViewInterface { $datasourceView = $this->createMock(DataSourceViewInterface::class); - $datasourceView->expects($this->any())->method('getName')->willReturn($name); + $datasourceView->method('getName')->willReturn($name); return $datasourceView; } - private function getTemplateMock(): MockObject + /** + * @return Template&MockObject + */ + private function getTemplateMock(): Template { return $this->createMock(Template::class); } diff --git a/Twig/Extension/DataSourceExtension.php b/Twig/Extension/DataSourceExtension.php index 33752d8..e691a44 100644 --- a/Twig/Extension/DataSourceExtension.php +++ b/Twig/Extension/DataSourceExtension.php @@ -53,7 +53,7 @@ class DataSourceExtension extends AbstractExtension implements InitRuntimeInterf private $additionalParameters; /** - * @var Template + * @var string */ private $baseTemplate; @@ -111,7 +111,7 @@ public function getTokenParsers() * Theme is nothing more than twig template that contains some or all of blocks required to render DataSource. * * @param DataSourceViewInterface $dataSource - * @param $theme + * @param Template|string $theme * @param array $vars */ public function setTheme(DataSourceViewInterface $dataSource, $theme, array $vars = []) @@ -126,7 +126,7 @@ public function setTheme(DataSourceViewInterface $dataSource, $theme, array $var * Set route and optionally additional parameters for specific DataSource. * * @param DataSourceViewInterface $dataSource - * @param $route + * @param string $route * @param array $additionalParameters */ public function setRoute(DataSourceViewInterface $dataSource, $route, array $additionalParameters = []) @@ -157,7 +157,7 @@ public function datasourceFilterCount(DataSourceViewInterface $view) { $fields = $view->getFields(); $count = 0; - /** @var $field FieldViewInterface */ + /** @var FieldViewInterface $field */ foreach ($fields as $field) { if ($field->hasAttribute('form')) { $count++; @@ -220,8 +220,16 @@ public function datasourceSort(FieldViewInterface $fieldView, array $options = [ ]; $options = $this->resolveSortOptions($options, $dataSourceView); - $ascendingUrl = $this->getUrl($dataSourceView, $options, $fieldView->getAttribute('parameters_sort_ascending')); - $descendingUrl = $this->getUrl($dataSourceView, $options, $fieldView->getAttribute('parameters_sort_descending')); + $ascendingUrl = $this->getUrl( + $dataSourceView, + $options, + $fieldView->getAttribute('parameters_sort_ascending') + ); + $descendingUrl = $this->getUrl( + $dataSourceView, + $options, + $fieldView->getAttribute('parameters_sort_descending') + ); $viewData = [ 'field' => $fieldView, @@ -272,8 +280,9 @@ public function datasourcePagination(DataSourceViewInterface $view, $options = [ $pagesParams = $view->getAttribute('parameters_pages'); $current = $view->getAttribute('page'); $pageCount = count($pagesParams); - if ($pageCount < 2) + if ($pageCount < 2) { return; + } if (isset($options['max_pages'])) { $delta = ceil($options['max_pages'] / 2); @@ -434,7 +443,7 @@ private function getVars(DataSourceViewInterface $dataSource) * Return additional parameters that should be passed to the URL generation for specified datasource. * * @param DataSourceViewInterface $dataSource - * @return array + * @return string */ private function getUrl(DataSourceViewInterface $dataSource, array $options = [], array $parameters = []) { @@ -444,12 +453,8 @@ private function getUrl(DataSourceViewInterface $dataSource, array $options = [] return $router->generate( $options['route'], array_merge( - isset($this->additionalParameters[$dataSource->getName()]) - ? $this->additionalParameters[$dataSource->getName()] - : [], - isset($options['additional_parameters']) - ? $options['additional_parameters'] - : [], + $this->additionalParameters[$dataSource->getName()] ?? [], + $options['additional_parameters'] ?? [], $parameters ) ); @@ -458,7 +463,7 @@ private function getUrl(DataSourceViewInterface $dataSource, array $options = [] /** * @param DataSourceViewInterface $view * @param array $contextVars - * @param $availableBlocks + * @param array $availableBlocks * @return string */ private function renderTheme( diff --git a/Twig/Node/DataSourceRouteNode.php b/Twig/Node/DataSourceRouteNode.php index 406b901..1e2c5cb 100644 --- a/Twig/Node/DataSourceRouteNode.php +++ b/Twig/Node/DataSourceRouteNode.php @@ -9,6 +9,7 @@ namespace FSi\Bundle\DataSourceBundle\Twig\Node; +use FSi\Bundle\DataSourceBundle\Twig\Extension\DataSourceExtension; use Twig\Compiler; use Twig\Node\Expression\AbstractExpression; use Twig\Node\Node; @@ -38,7 +39,7 @@ public function compile(Compiler $compiler) { $compiler ->addDebugInfo($this) - ->write('$this->env->getExtension(\'FSi\Bundle\DataSourceBundle\Twig\Extension\DataSourceExtension\')->setRoute(') + ->write(sprintf('$this->env->getExtension(\'%s\')->setRoute(', DataSourceExtension::class)) ->subcompile($this->getNode('datasource')) ->raw(', ') ->subcompile($this->getNode('route')) diff --git a/Twig/Node/DataSourceThemeNode.php b/Twig/Node/DataSourceThemeNode.php index 9e7cb4c..bc388f1 100644 --- a/Twig/Node/DataSourceThemeNode.php +++ b/Twig/Node/DataSourceThemeNode.php @@ -9,6 +9,7 @@ namespace FSi\Bundle\DataSourceBundle\Twig\Node; +use FSi\Bundle\DataSourceBundle\Twig\Extension\DataSourceExtension; use Twig\Compiler; use Twig\Node\Expression\AbstractExpression; use Twig\Node\Node; @@ -24,7 +25,7 @@ public function compile(Compiler $compiler) { $compiler ->addDebugInfo($this) - ->write('$this->env->getExtension(\'FSi\Bundle\DataSourceBundle\Twig\Extension\DataSourceExtension\')->setTheme(') + ->write(sprintf('$this->env->getExtension(\'%s\')->setTheme(', DataSourceExtension::class)) ->subcompile($this->getNode('datasource')) ->raw(', ') ->subcompile($this->getNode('theme')) diff --git a/Twig/TokenParser/DataSourceRouteTokenParser.php b/Twig/TokenParser/DataSourceRouteTokenParser.php index 6c15fc6..08b6e24 100644 --- a/Twig/TokenParser/DataSourceRouteTokenParser.php +++ b/Twig/TokenParser/DataSourceRouteTokenParser.php @@ -26,7 +26,10 @@ public function parse(Token $token) if ($this->parser->getStream()->test(Token::NAME_TYPE, 'with')) { $this->parser->getStream()->next(); - if ($this->parser->getStream()->test(Token::PUNCTUATION_TYPE) || $this->parser->getStream()->test(Token::NAME_TYPE)) { + if ( + $this->parser->getStream()->test(Token::PUNCTUATION_TYPE) + || $this->parser->getStream()->test(Token::NAME_TYPE) + ) { $additional_parameters = $this->parser->getExpressionParser()->parseExpression(); } } diff --git a/composer.json b/composer.json index a61a03c..2c1545c 100644 --- a/composer.json +++ b/composer.json @@ -11,31 +11,30 @@ } ], "require": { + "php": "^7.1|^8.0", "doctrine/orm": "^2.3", - "doctrine/collections": "^1.0", "fsi/datasource": "^2.0", - "php": ">=7.1", - "symfony/framework-bundle" : "^3.4|^4.0", - "symfony/options-resolver": "^3.4|^4.0", - "symfony/dependency-injection" : "^3.4|^4.0", - "symfony/doctrine-bridge": "^3.4|^4.0", - "symfony/security-csrf": "^3.4|^4.0", - "symfony/yaml": "^3.4|^4.0", + "symfony/framework-bundle" : "^3.4|^4.0|^5.0", + "symfony/options-resolver": "^3.4|^4.0|^5.0", + "symfony/dependency-injection" : "^3.4|^4.0|^5.0", + "symfony/doctrine-bridge": "^3.4|^4.0|^5.0", + "symfony/security-csrf": "^3.4|^4.0|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0", "symfony/translation": "^3.4|^4.0", "twig/twig": "^2.11" }, "require-dev": { + "phpstan/phpstan": "^0.12.66", + "phpstan/phpstan-phpunit": "^0.12.15", + "squizlabs/php_codesniffer": "^3.5", "symfony/form" : "^3.4|^4.0", - "symfony/phpunit-bridge": "^4.0", - "symfony/twig-bridge" : "^3.4|^4.0", - "phpunit/phpunit": "^7.5" + "symfony/phpunit-bridge": "^4.0|^5.0", + "symfony/twig-bridge" : "^3.4|^4.0|^5.0", + "phpunit/phpunit": "^7.5|^8.0" }, "autoload": { "psr-4": { "FSi\\Bundle\\DataSourceBundle\\": "" } }, - "autoload-dev": { - "psr-4": { "FSi\\Bundle\\DataSourceBundle\\Tests\\": "Tests/" } - }, "config": { "bin-dir": "vendor/bin" }, diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..86e60b1 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,17 @@ + + + + + + . + bin + vendor + + + + + + + + + diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..58df09e --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,15 @@ +includes: + - vendor/phpstan/phpstan-phpunit/extension.neon +parameters: + treatPhpDocTypesAsCertain: false + level: 3 + paths: + - . + excludePaths: + - DataSource/Extension/Symfony/DependencyInjection/Driver/DriverExtension + - DependencyInjection + - Resources + - Tests/Fixtures/TestManagerRegistry* + - Tests/Extension/Symfony/FormExtensionEntityTest + - bin + - vendor