From 038bcc33f45abc6b4eb6d1fa32182103e237ce88 Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Fri, 31 May 2024 15:59:59 +0300 Subject: [PATCH] Upgrade to Symfony 7.1 + new features (#240) --- .github/workflows/ci.yaml | 6 +- Command/EnumDropCommentCommand.php | 25 ++++-- DBAL/Types/AbstractEnumType.php | 8 +- README.md | 6 +- Resources/docs/usage_example.md | 12 +-- Tests/Command/EnumDropCommentCommandTest.php | 75 +++++++++------- Tests/DBAL/Types/AbstractEnumTypeTest.php | 86 +++++++++++-------- .../Compiler/RegisterEnumTypePassTest.php | 7 +- .../FreshDoctrineEnumExtensionTest.php | 4 +- .../InvalidArgumentExceptionTest.php | 4 +- Tests/Exception/LogicExceptionTest.php | 4 +- Tests/Exception/RuntimeExceptionTest.php | 4 +- .../UnexpectedValueExceptionTest.php | 4 +- Tests/Form/EnumTypeGuesserTest.php | 19 ++-- Tests/FreshDoctrineEnumBundleTest.php | 4 +- .../EnumConstantTwigExtensionTest.php | 28 +++--- .../EnumValuesAsArrayTwigExtensionTest.php | 19 ++-- .../ReadableEnumValueTwigExtensionTest.php | 28 +++--- Tests/Validator/EnumTypeTest.php | 13 ++- Tests/Validator/EnumTypeValidatorTest.php | 10 ++- composer.json | 14 +-- 21 files changed, 230 insertions(+), 150 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 899d81f..1b6235b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -105,6 +105,7 @@ jobs: - '8.2' symfony-version: - '7.0' + - '7.1' steps: - name: 'Checkout Code' uses: actions/checkout@v4 @@ -152,14 +153,15 @@ jobs: run: ./vendor/bin/phpunit -c phpunit.xml.dist --coverage-clover=coverage.xml - name: 'Download Coverage Files' - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: path: reports - name: 'Upload to Codecov' - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: files: ./coverage.xml fail_ci_if_error: true flags: unittests verbose: true + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/Command/EnumDropCommentCommand.php b/Command/EnumDropCommentCommand.php index 6d5f940..0c35ddd 100644 --- a/Command/EnumDropCommentCommand.php +++ b/Command/EnumDropCommentCommand.php @@ -12,13 +12,11 @@ namespace Fresh\DoctrineEnumBundle\Command; -use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\ORM\EntityManagerInterface; use Doctrine\Persistence\ManagerRegistry; use Fresh\DoctrineEnumBundle\DBAL\Types\AbstractEnumType; use Fresh\DoctrineEnumBundle\Exception\EnumType\EnumTypeIsRegisteredButClassDoesNotExistException; use Fresh\DoctrineEnumBundle\Exception\InvalidArgumentException; -use Fresh\DoctrineEnumBundle\Exception\RuntimeException; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -75,6 +73,16 @@ public function __construct(private readonly ManagerRegistry $registry, array $r } } + /** + * @return \Closure + */ + public function getEnumTypesForAutocompletion(): \Closure + { + return function () { + return \array_keys($this->registeredEnumTypes); + }; + } + /** * {@inheritdoc} */ @@ -83,7 +91,7 @@ protected function configure(): void $this ->setDefinition( new InputDefinition([ - new InputArgument('enumType', InputArgument::REQUIRED, 'Registered ENUM type'), + new InputArgument('enumType', InputArgument::REQUIRED, 'Registered ENUM type', null, $this->getEnumTypesForAutocompletion()), new InputOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command'), ]) ) @@ -143,9 +151,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $connection = $this->em->getConnection(); $platform = $connection->getDatabasePlatform(); - if (!$platform instanceof AbstractPlatform) { - throw new RuntimeException('Missing database platform for connection.', 3); - } $io->title(\sprintf('Dropping comments for %s type...', $this->enumType)); @@ -157,13 +162,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int foreach ($allMetadata as $metadata) { $entityName = $metadata->getName(); - $tableName = $metadata->getTableName(); + if (!empty($metadata->getSchemaName())) { + $tableName = $metadata->getSchemaName().'.'.$metadata->getTableName(); + } else { + $tableName = $metadata->getTableName(); + } foreach ($metadata->getFieldNames() as $fieldName) { if ($metadata->getTypeOfField($fieldName) === $this->enumType) { /** @var array{columnName: string} $fieldMappingDetails */ $fieldMappingDetails = $metadata->getFieldMapping($fieldName); - $sql = $platform->getCommentOnColumnSQL($tableName, $fieldMappingDetails['columnName'], null); + $sql = $platform->getCommentOnColumnSQL($tableName, $fieldMappingDetails['columnName'], 'NULL'); $connection->executeQuery($sql); $io->text(\sprintf(' * %s::$%s Dropped ✔', $entityName, $fieldName)); diff --git a/DBAL/Types/AbstractEnumType.php b/DBAL/Types/AbstractEnumType.php index ea6cf01..87b25ce 100644 --- a/DBAL/Types/AbstractEnumType.php +++ b/DBAL/Types/AbstractEnumType.php @@ -15,7 +15,7 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\MySQLPlatform; use Doctrine\DBAL\Platforms\PostgreSQLPlatform; -use Doctrine\DBAL\Platforms\SqlitePlatform; +use Doctrine\DBAL\Platforms\SQLitePlatform; use Doctrine\DBAL\Platforms\SQLServerPlatform; use Doctrine\DBAL\Types\Type; use Fresh\DoctrineEnumBundle\Exception\InvalidArgumentException; @@ -51,7 +51,7 @@ abstract class AbstractEnumType extends Type * * @return TValue|int|string */ - public function convertToDatabaseValue($value, AbstractPlatform $platform) + public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): mixed { if (null !== $value && !isset(static::$choices[$value])) { throw new InvalidArgumentException(\sprintf('Invalid value "%s" for ENUM "%s".', $value, $this->getName())); @@ -66,7 +66,7 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform) * * @return TValue */ - public function convertToPHPValue($value, AbstractPlatform $platform) + public function convertToPHPValue($value, AbstractPlatform $platform): mixed { if (!isset(static::$choices[$value])) { return $value; @@ -104,7 +104,7 @@ static function (int|string $value) { ); $sqlDeclaration = match (true) { - $platform instanceof SqlitePlatform => \sprintf('TEXT CHECK(%s IN (%s))', $column['name'], $values), + $platform instanceof SQLitePlatform => \sprintf('TEXT CHECK(%s IN (%s))', $column['name'], $values), $platform instanceof PostgreSQLPlatform, $platform instanceof SQLServerPlatform => \sprintf( 'VARCHAR(255) CHECK(%s IN (%s))', $column['name'], diff --git a/README.md b/README.md index 1206188..b34cccb 100644 --- a/README.md +++ b/README.md @@ -22,10 +22,10 @@ ##### Choose the version you need -| Bundle Version (X.Y.Z) | PHP | Symfony | Doctrine Bundle | Comment | +| Bundle Version (X.Y.Z) | PHP | Symfony | Doctrine Bundle | Comment | |:----------------------:|:--------:|:----------:|:---------------:|:--------------------| -| `10.1.*` | `>= 8.2` | `>= 7.0` | `>= 2.11` | **Current version** | -| `9.2.*` | `>= 8.1` | `>= 6.1` | `>= 2.9` | Previous version | +| `11.0.*` | `>= 8.2` | `>= 7.0` | `>= 2.11` | **Current version** | +| `10.1.*` | `>= 8.2` | `>= 7.0` | `>= 2.11` | Previous | #### Check the `config/bundles.php` file diff --git a/Resources/docs/usage_example.md b/Resources/docs/usage_example.md index 3ed49e1..14c74d2 100644 --- a/Resources/docs/usage_example.md +++ b/Resources/docs/usage_example.md @@ -41,9 +41,9 @@ Register `BasketballPositionType` for Doctrine in config.yaml: ```yaml doctrine: - dbal: - types: - BasketballPositionType: App\DBAL\Types\BasketballPositionType + dbal: + types: + BasketballPositionType: App\DBAL\Types\BasketballPositionType ``` Create a `Player` entity that has a `position` field: @@ -60,9 +60,9 @@ use Fresh\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert; #[ORM\Table(name: 'players')] class Player { - #[ORM\Id] - #[ORM\Column(type: 'integer', name: 'id')] - #[ORM\GeneratedValue(strategy: 'AUTO')] + #[ORM\Id] + #[ORM\Column(type: 'integer', name: 'id')] + #[ORM\GeneratedValue(strategy: 'AUTO')] private $id; // Note, that type of field should be same as you set in Doctrine config (in this case it is BasketballPositionType) diff --git a/Tests/Command/EnumDropCommentCommandTest.php b/Tests/Command/EnumDropCommentCommandTest.php index d1c35f7..6605560 100644 --- a/Tests/Command/EnumDropCommentCommandTest.php +++ b/Tests/Command/EnumDropCommentCommandTest.php @@ -23,6 +23,8 @@ use Fresh\DoctrineEnumBundle\Exception\EnumType\EnumTypeIsRegisteredButClassDoesNotExistException; use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\BasketballPositionType; use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\TaskStatusType; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Application; @@ -94,7 +96,8 @@ protected function tearDown(): void ); } - public function testExceptionInConstructor(): void + #[Test] + public function exceptionInConstructor(): void { $this->expectException(EnumTypeIsRegisteredButClassDoesNotExistException::class); $this->expectExceptionMessage('ENUM type "CustomType" is registered as "Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\CustomType", but that class does not exist'); @@ -110,7 +113,8 @@ public function testExceptionInConstructor(): void $this->commandTester->getDisplay(); } - public function testExceptionOnExecution(): void + #[Test] + public function exceptionOnExecution(): void { $this->em ->expects(self::once()) @@ -130,7 +134,8 @@ public function testExceptionOnExecution(): void self::assertStringContainsString('test', $output); } - public function testInvalidEnumTypeArgument(): void + #[Test] + public function invalidEnumTypeArgument(): void { $result = $this->commandTester->execute( [ @@ -144,7 +149,8 @@ public function testInvalidEnumTypeArgument(): void self::assertStringContainsString('Argument "enumType" is not a string.', $output); } - public function testExceptionNotRegisteredEnumType(): void + #[Test] + public function exceptionNotRegisteredEnumType(): void { $result = $this->commandTester->execute( [ @@ -158,27 +164,8 @@ public function testExceptionNotRegisteredEnumType(): void self::assertStringContainsString('Argument "enumType" is not a registered ENUM type.', $output); } - public function testMissingDatabasePlatformForConnection(): void - { - $this->connection - ->expects(self::once()) - ->method('getDatabasePlatform') - ->willReturn(null) - ; - - $result = $this->commandTester->execute( - [ - 'command' => $this->command->getName(), - 'enumType' => 'TaskStatusType', - ] - ); - self::assertSame(3, $result); - - $output = $this->commandTester->getDisplay(); - self::assertStringContainsString('Missing database platform for connection.', $output); - } - - public function testExecutionWithCaughtException(): void + #[Test] + public function executionWithCaughtException(): void { $this->connection ->expects(self::once()) @@ -198,7 +185,8 @@ public function testExecutionWithCaughtException(): void self::assertStringContainsString('test', $output); } - public function testSuccessfulExecutionWithNoMetadata(): void + #[Test] + public function successfulExecutionWithNoMetadata(): void { $this->connection ->expects(self::once()) @@ -226,7 +214,9 @@ public function testSuccessfulExecutionWithNoMetadata(): void self::assertStringContainsString('NO METADATA FOUND', $output); } - public function testSuccessfulExecutionWithMetadata(): void + #[Test] + #[DataProvider('dataProviderForMetadataTest')] + public function successfulExecutionWithMetadata(?string $schemaName, string $sqlColumnComment): void { $this->connection ->expects(self::once()) @@ -242,12 +232,15 @@ public function testSuccessfulExecutionWithMetadata(): void ; $metadata->expects(self::once())->method('getName')->willReturn('Task'); + $metadata->expects(self::atLeast(1))->method('getSchemaName')->willReturn($schemaName); $metadata->expects(self::once())->method('getTableName')->willReturn('tasks'); $metadata->expects(self::once())->method('getFieldNames')->willReturn(['status']); $metadata->expects(self::once())->method('getTypeOfField')->with('status')->willReturn('TaskStatusType'); - $metadata->expects(self::once())->method('getFieldMapping')->with('status')->willReturn(FieldMapping::fromMappingArray(['type'=> 'string', 'columnName' => 'task_column_name', 'fieldName' => 'test'])); + $metadata->expects(self::once())->method('getFieldMapping')->with('status')->willReturn( + FieldMapping::fromMappingArray(['type'=> 'string', 'columnName' => 'task_column_name', 'fieldName' => 'test']) + ); - $this->platform->expects(self::once())->method('getCommentOnColumnSQL')->with('tasks', 'task_column_name', null)->willReturn('test SQL'); + $this->platform->expects(self::once())->method('getCommentOnColumnSQL')->with($sqlColumnComment, 'task_column_name', 'NULL')->willReturn('test SQL'); $this->connection->expects(self::once())->method('executeQuery')->with('test SQL'); @@ -266,4 +259,28 @@ public function testSuccessfulExecutionWithMetadata(): void self::assertStringContainsString('TOTAL: 1', $output); self::assertStringContainsString('DONE', $output); } + + public static function dataProviderForMetadataTest(): iterable + { + yield 'no schema' => [ + 'schemaName' => null, + 'sqlColumnComment' => 'tasks', + ]; + yield 'public schema' => [ + 'schemaName' => 'public', + 'sqlColumnComment' => 'public.tasks', + ]; + yield 'custom schema' => [ + 'schemaName' => 'custom', + 'sqlColumnComment' => 'custom.tasks', + ]; + } + + #[Test] + public function autocomplete(): void + { + $enumTypes = $this->command->getEnumTypesForAutocompletion()(); + + self::assertSame(['BasketballPositionType', 'TaskStatusType'], $enumTypes); + } } diff --git a/Tests/DBAL/Types/AbstractEnumTypeTest.php b/Tests/DBAL/Types/AbstractEnumTypeTest.php index 8fb65b5..0709505 100644 --- a/Tests/DBAL/Types/AbstractEnumTypeTest.php +++ b/Tests/DBAL/Types/AbstractEnumTypeTest.php @@ -15,7 +15,7 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\MySQLPlatform; use Doctrine\DBAL\Platforms\PostgreSQLPlatform; -use Doctrine\DBAL\Platforms\SqlitePlatform; +use Doctrine\DBAL\Platforms\SQLitePlatform; use Doctrine\DBAL\Platforms\SQLServerPlatform; use Doctrine\DBAL\Types\Type; use Fresh\DoctrineEnumBundle\DBAL\Types\AbstractEnumType; @@ -26,6 +26,8 @@ use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\NumericType; use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\StubType; use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\TaskStatusType; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; /** @@ -57,14 +59,9 @@ protected function tearDown(): void unset($this->type); } - /** - * @dataProvider platformProviderForGetSqlDeclarationWithoutDefaultValue - * - * @param array $fieldDeclaration - * @param AbstractPlatform $platform - * @param string $expected - */ - public function testGetSqlDeclarationWithoutDefaultValue(array $fieldDeclaration, AbstractPlatform $platform, string $expected): void + #[Test] + #[DataProvider('platformProviderForGetSqlDeclarationWithoutDefaultValue')] + public function GetSqlDeclarationWithoutDefaultValue(array $fieldDeclaration, AbstractPlatform $platform, string $expected): void { self::assertEquals($expected, $this->type->getSqlDeclaration($fieldDeclaration, $platform)); } @@ -78,7 +75,7 @@ public static function platformProviderForGetSqlDeclarationWithoutDefaultValue() ]; yield 'sqlite' => [ ['name' => 'position'], - new SqlitePlatform(), + new SQLitePlatform(), "TEXT CHECK(position IN ('PG', 'SG', 'SF', 'PF', 'C'))", ]; yield 'postgresql' => [ @@ -93,14 +90,9 @@ public static function platformProviderForGetSqlDeclarationWithoutDefaultValue() ]; } - /** - * @dataProvider platformProviderForGetSqlDeclarationWithDefaultValue - * - * @param array $fieldDeclaration - * @param AbstractPlatform $platform - * @param string $expected - */ - public function testGetSqlDeclarationWithDefaultValue(array $fieldDeclaration, AbstractPlatform $platform, string $expected): void + #[Test] + #[DataProvider('platformProviderForGetSqlDeclarationWithDefaultValue')] + public function getSqlDeclarationWithDefaultValue(array $fieldDeclaration, AbstractPlatform $platform, string $expected): void { $type = Type::getType('TaskStatusType'); self::assertEquals($expected, $type->getSqlDeclaration($fieldDeclaration, $platform)); @@ -115,7 +107,7 @@ public static function platformProviderForGetSqlDeclarationWithDefaultValue(): i ]; yield 'sqlite' => [ ['name' => 'position'], - new SqlitePlatform(), + new SQLitePlatform(), "TEXT CHECK(position IN ('pending', 'done', 'failed')) DEFAULT 'pending'", ]; yield 'postgresql' => [ @@ -130,30 +122,35 @@ public static function platformProviderForGetSqlDeclarationWithDefaultValue(): i ]; } - public function testGetName(): void + #[Test] + public function getName(): void { self::assertEquals('BasketballPositionType', $this->type->getName()); self::assertEquals('StubType', Type::getType('StubType')->getName()); } - public function testRequiresSQLCommentHint(): void + #[Test] + public function requiresSQLCommentHint(): void { self::assertTrue($this->type->requiresSQLCommentHint(new MySqlPlatform())); } - public function testConvertToDatabaseValue(): void + #[Test] + public function convertToDatabaseValue(): void { self::assertNull($this->type->convertToDatabaseValue(null, new MySqlPlatform())); self::assertEquals('SF', $this->type->convertToDatabaseValue('SF', new MySqlPlatform())); } - public function testInvalidArgumentExceptionInConvertToDatabaseValue(): void + #[Test] + public function invalidArgumentExceptionInConvertToDatabaseValue(): void { $this->expectException(InvalidArgumentException::class); $this->type->convertToDatabaseValue('YO', new MySqlPlatform()); } - public function testGetRandomValue(): void + #[Test] + public function getRandomValue(): void { $values = $this->type::getValues(); @@ -162,7 +159,8 @@ public function testGetRandomValue(): void self::assertContains($this->type::getRandomValue(), $values); } - public function testGetRandomValueWithException(): void + #[Test] + public function getRandomValueWithException(): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('There is no value in Enum type'); @@ -170,7 +168,8 @@ public function testGetRandomValueWithException(): void NoValueType::getRandomValue(); } - public function testGetReadableValues(): void + #[Test] + public function getReadableValues(): void { $choices = [ 'PG' => 'Point Guard', @@ -182,12 +181,14 @@ public function testGetReadableValues(): void self::assertEquals($choices, $this->type::getReadableValues()); } - public function testAssertValidChoiceString(): void + #[Test] + public function assertValidChoiceString(): void { self::assertNull($this->type::assertValidChoice(BasketballPositionType::SMALL_FORWARD)); } - public function testAssertValidChoiceNumeric(): void + #[Test] + public function assertValidChoiceNumeric(): void { $this->type = Type::getType('NumericType'); self::assertNull($this->type::assertValidChoice(NumericType::TWO)); @@ -198,13 +199,15 @@ public function testAssertValidChoiceNumeric(): void $this->type = Type::getType('BasketballPositionType'); } - public function testInvalidArgumentExceptionInAssertValidChoice(): void + #[Test] + public function invalidArgumentExceptionInAssertValidChoice(): void { $this->expectException(InvalidArgumentException::class); $this->type::assertValidChoice('YO'); } - public function testGetReadableValueString(): void + #[Test] + public function getReadableValueString(): void { $this->type = Type::getType('HTTPStatusCodeType'); self::assertEquals('Not Found', $this->type::getReadableValue(HTTPStatusCodeType::HTTP_NOT_FOUND)); @@ -213,14 +216,16 @@ public function testGetReadableValueString(): void self::assertEquals('Small Forward', $this->type::getReadableValue(BasketballPositionType::SMALL_FORWARD)); } - public function testGetReadableValueNumeric(): void + #[Test] + public function getReadableValueNumeric(): void { $this->type = Type::getType('NumericType'); self::assertEquals(2, $this->type::getReadableValue(NumericType::TWO)); $this->type = Type::getType('BasketballPositionType'); } - public function testGetDefaultValue(): void + #[Test] + public function getDefaultValue(): void { self::assertNull($this->type::getDefaultValue()); self::assertEquals('pending', Type::getType('TaskStatusType')::getDefaultValue()); @@ -228,13 +233,15 @@ public function testGetDefaultValue(): void self::assertEquals(200, Type::getType('HTTPStatusCodeType')::getDefaultValue()); } - public function testInvalidArgumentExceptionInGetReadableValue(): void + #[Test] + public function invalidArgumentExceptionInGetReadableValue(): void { $this->expectException(InvalidArgumentException::class); $this->type::getReadableValue('YO'); } - public function testGetChoices(): void + #[Test] + public function getChoices(): void { $choices = [ 'Point Guard' => 'PG', @@ -247,16 +254,18 @@ public function testGetChoices(): void self::assertEquals($choices, $this->type::getChoices()); } - public function testMappedDatabaseTypesContainEnumOnMySQL(): void + #[Test] + public function mappedDatabaseTypesContainEnumOnMySQL(): void { $actual = $this->type->getMappedDatabaseTypes(new MySQLPlatform()); self::assertContains('enum', $actual); } - public function testMappedDatabaseTypesDoesNotContainEnumOnNonMySQL(): void + #[Test] + public function mappedDatabaseTypesDoesNotContainEnumOnNonMySQL(): void { $testProviders = [ - new SqlitePlatform(), + new SQLitePlatform(), new PostgreSQLPlatform(), new SQLServerPlatform(), ]; @@ -267,7 +276,8 @@ public function testMappedDatabaseTypesDoesNotContainEnumOnNonMySQL(): void } } - public function testConvertToPHPValue(): void + #[Test] + public function convertToPHPValue(): void { self::assertNull($this->type->convertToPHPValue(null, new MySQLPlatform())); self::assertSame('SF', $this->type->convertToPHPValue('SF', new MySQLPlatform())); diff --git a/Tests/DependencyInjection/Compiler/RegisterEnumTypePassTest.php b/Tests/DependencyInjection/Compiler/RegisterEnumTypePassTest.php index 959501d..46f9f76 100755 --- a/Tests/DependencyInjection/Compiler/RegisterEnumTypePassTest.php +++ b/Tests/DependencyInjection/Compiler/RegisterEnumTypePassTest.php @@ -15,6 +15,7 @@ use Doctrine\Persistence\ManagerRegistry; use Fresh\DoctrineEnumBundle\DependencyInjection\Compiler\RegisterEnumTypePass; use Fresh\DoctrineEnumBundle\Exception\InvalidArgumentException; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -52,7 +53,8 @@ protected function tearDown(): void ); } - public function testProcessSuccessful(): void + #[Test] + public function processSuccessful(): void { $this->containerBuilder ->expects(self::once()) @@ -123,7 +125,8 @@ public function testProcessSuccessful(): void $this->registerEnumTypePass->process($this->containerBuilder); } - public function testMissingDoctrine(): void + #[Test] + public function missingDoctrine(): void { $this->containerBuilder ->expects(self::once()) diff --git a/Tests/DependencyInjection/FreshDoctrineEnumExtensionTest.php b/Tests/DependencyInjection/FreshDoctrineEnumExtensionTest.php index e3351bb..01392af 100644 --- a/Tests/DependencyInjection/FreshDoctrineEnumExtensionTest.php +++ b/Tests/DependencyInjection/FreshDoctrineEnumExtensionTest.php @@ -17,6 +17,7 @@ use Fresh\DoctrineEnumBundle\Form\EnumTypeGuesser; use Fresh\DoctrineEnumBundle\Twig\Extension\EnumConstantTwigExtension; use Fresh\DoctrineEnumBundle\Twig\Extension\ReadableEnumValueTwigExtension; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; @@ -47,7 +48,8 @@ protected function tearDown(): void ); } - public function testLoadExtension(): void + #[Test] + public function loadExtension(): void { $this->container->setParameter('doctrine.dbal.connection_factory.types', []); // Just add a dummy required parameter $this->container->loadFromExtension($this->extension->getAlias()); diff --git a/Tests/Exception/InvalidArgumentExceptionTest.php b/Tests/Exception/InvalidArgumentExceptionTest.php index d8e1481..9a96e20 100644 --- a/Tests/Exception/InvalidArgumentExceptionTest.php +++ b/Tests/Exception/InvalidArgumentExceptionTest.php @@ -14,6 +14,7 @@ use Fresh\DoctrineEnumBundle\Exception\ExceptionInterface; use Fresh\DoctrineEnumBundle\Exception\InvalidArgumentException; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; /** @@ -23,7 +24,8 @@ */ final class InvalidArgumentExceptionTest extends TestCase { - public function testConstructor(): void + #[Test] + public function validCreation(): void { $exception = new InvalidArgumentException(); diff --git a/Tests/Exception/LogicExceptionTest.php b/Tests/Exception/LogicExceptionTest.php index e8b2e37..7320957 100644 --- a/Tests/Exception/LogicExceptionTest.php +++ b/Tests/Exception/LogicExceptionTest.php @@ -14,6 +14,7 @@ use Fresh\DoctrineEnumBundle\Exception\ExceptionInterface; use Fresh\DoctrineEnumBundle\Exception\LogicException; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; /** @@ -23,7 +24,8 @@ */ final class LogicExceptionTest extends TestCase { - public function testConstructor(): void + #[Test] + public function validCreation(): void { $exception = new LogicException(); diff --git a/Tests/Exception/RuntimeExceptionTest.php b/Tests/Exception/RuntimeExceptionTest.php index 167cf7f..02fef30 100644 --- a/Tests/Exception/RuntimeExceptionTest.php +++ b/Tests/Exception/RuntimeExceptionTest.php @@ -14,6 +14,7 @@ use Fresh\DoctrineEnumBundle\Exception\ExceptionInterface; use Fresh\DoctrineEnumBundle\Exception\RuntimeException; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; /** @@ -23,7 +24,8 @@ */ final class RuntimeExceptionTest extends TestCase { - public function testConstructor(): void + #[Test] + public function validCreation(): void { $exception = new RuntimeException(); diff --git a/Tests/Exception/UnexpectedValueExceptionTest.php b/Tests/Exception/UnexpectedValueExceptionTest.php index 8ef0dab..94399d9 100644 --- a/Tests/Exception/UnexpectedValueExceptionTest.php +++ b/Tests/Exception/UnexpectedValueExceptionTest.php @@ -14,6 +14,7 @@ use Fresh\DoctrineEnumBundle\Exception\ExceptionInterface; use Fresh\DoctrineEnumBundle\Exception\UnexpectedValueException; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; /** @@ -23,7 +24,8 @@ */ final class UnexpectedValueExceptionTest extends TestCase { - public function testConstructor(): void + #[Test] + public function validCreation(): void { $exception = new UnexpectedValueException(); diff --git a/Tests/Form/EnumTypeGuesserTest.php b/Tests/Form/EnumTypeGuesserTest.php index 63e6d72..43468c2 100644 --- a/Tests/Form/EnumTypeGuesserTest.php +++ b/Tests/Form/EnumTypeGuesserTest.php @@ -20,6 +20,7 @@ use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\BasketballPositionType; use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\InheritedType; use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\NotAChildType; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; @@ -33,7 +34,8 @@ */ final class EnumTypeGuesserTest extends TestCase { - public function testNullResultWhenClassMetadataNotFound(): void + #[Test] + public function nullResultWhenClassMetadataNotFound(): void { /** @var EnumTypeGuesser|MockObject $enumTypeGuesser */ $enumTypeGuesser = $this @@ -52,7 +54,8 @@ public function testNullResultWhenClassMetadataNotFound(): void self::assertNull($enumTypeGuesser->guessType(\stdClass::class, 'position')); } - public function testNullResultWhenEnumTypeNotRegistered(): void + #[Test] + public function nullResultWhenEnumTypeNotRegistered(): void { /** @var EnumTypeGuesser|MockObject $enumTypeGuesser */ $enumTypeGuesser = $this @@ -91,7 +94,8 @@ public function testNullResultWhenEnumTypeNotRegistered(): void self::assertNull($enumTypeGuesser->guessType(\stdClass::class, 'position')); } - public function testExceptionWhenClassDoesNotExist(): void + #[Test] + public function exceptionWhenClassDoesNotExist(): void { $registry = $this->createMock(ManagerRegistry::class); @@ -140,7 +144,8 @@ public function testExceptionWhenClassDoesNotExist(): void self::assertNull($enumTypeGuesser->guessType(\stdClass::class, 'position')); } - public function testNullResultWhenIsNotChildOfAbstractEnumType(): void + #[Test] + public function nullResultWhenIsNotChildOfAbstractEnumType(): void { $registry = $this->createMock(ManagerRegistry::class); @@ -186,7 +191,8 @@ public function testNullResultWhenIsNotChildOfAbstractEnumType(): void self::assertNull($enumTypeGuesser->guessType(\stdClass::class, 'position')); } - public function testSuccessfulTypeGuessingWithAncestor(): void + #[Test] + public function successfulTypeGuessingWithAncestor(): void { $registry = $this->createMock(ManagerRegistry::class); @@ -246,7 +252,8 @@ public function testSuccessfulTypeGuessingWithAncestor(): void self::assertEquals($typeGuess, $enumTypeGuesser->guessType(\stdClass::class, 'position')); } - public function testSuccessfulTypeGuessing(): void + #[Test] + public function successfulTypeGuessing(): void { $registry = $this->createMock(ManagerRegistry::class); diff --git a/Tests/FreshDoctrineEnumBundleTest.php b/Tests/FreshDoctrineEnumBundleTest.php index dd130b9..7b19dfc 100644 --- a/Tests/FreshDoctrineEnumBundleTest.php +++ b/Tests/FreshDoctrineEnumBundleTest.php @@ -14,6 +14,7 @@ use Fresh\DoctrineEnumBundle\DependencyInjection\Compiler\RegisterEnumTypePass; use Fresh\DoctrineEnumBundle\FreshDoctrineEnumBundle; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -24,7 +25,8 @@ */ final class FreshDoctrineEnumBundleTest extends TestCase { - public function testBuild(): void + #[Test] + public function build(): void { $containerBuilder = $this->createMock(ContainerBuilder::class); $containerBuilder diff --git a/Tests/Twig/Extension/EnumConstantTwigExtensionTest.php b/Tests/Twig/Extension/EnumConstantTwigExtensionTest.php index 14c374c..fb124c8 100644 --- a/Tests/Twig/Extension/EnumConstantTwigExtensionTest.php +++ b/Tests/Twig/Extension/EnumConstantTwigExtensionTest.php @@ -21,6 +21,8 @@ use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\MapLocationType; use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\NumericType; use Fresh\DoctrineEnumBundle\Twig\Extension\EnumConstantTwigExtension; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Twig\TwigFilter; @@ -48,7 +50,8 @@ protected function tearDown(): void unset($this->enumConstantTwigExtension); } - public function testGetFilters(): void + #[Test] + public function getFilters(): void { self::assertEquals( [new TwigFilter('enum_constant', [$this->enumConstantTwigExtension, 'getEnumConstant'])], @@ -56,14 +59,9 @@ public function testGetFilters(): void ); } - /** - * @dataProvider dataProviderForGetEnumConstantTest - * - * @param string $expectedValueOfConstant - * @param string $enumConstant - * @param string|null $enumType - */ - public function testGetEnumConstant(string $expectedValueOfConstant, string $enumConstant, ?string $enumType): void + #[Test] + #[DataProvider('dataProviderForGetEnumConstantTest')] + public function GetEnumConstant(string $expectedValueOfConstant, string $enumConstant, ?string $enumType): void { self::assertEquals( $expectedValueOfConstant, @@ -81,25 +79,29 @@ public static function dataProviderForGetEnumConstantTest(): iterable yield ['200', 'HTTP_OK', 'HTTPStatusCodeType']; } - public function testEnumTypeIsNotRegisteredException(): void + #[Test] + public function enumTypeIsNotRegisteredException(): void { $this->expectException(EnumTypeIsNotRegisteredException::class); $this->enumConstantTwigExtension->getEnumConstant('Pitcher', 'BaseballPositionType'); } - public function testConstantIsFoundInFewRegisteredEnumTypesException(): void + #[Test] + public function constantIsFoundInFewRegisteredEnumTypesException(): void { $this->expectException(ConstantIsFoundInFewRegisteredEnumTypesException::class); $this->enumConstantTwigExtension->getEnumConstant('CENTER'); } - public function testConstantIsNotFoundInAnyRegisteredEnumTypeException(): void + #[Test] + public function constantIsNotFoundInAnyRegisteredEnumTypeException(): void { $this->expectException(ConstantIsNotFoundInAnyRegisteredEnumTypeException::class); $this->enumConstantTwigExtension->getEnumConstant('Pitcher'); } - public function testNoRegisteredEnumTypesException(): void + #[Test] + public function noRegisteredEnumTypesException(): void { $this->expectException(NoRegisteredEnumTypesException::class); (new EnumConstantTwigExtension([]))->getEnumConstant(BasketballPositionType::POINT_GUARD, 'BasketballPositionType'); diff --git a/Tests/Twig/Extension/EnumValuesAsArrayTwigExtensionTest.php b/Tests/Twig/Extension/EnumValuesAsArrayTwigExtensionTest.php index a6c1b59..dc9e112 100644 --- a/Tests/Twig/Extension/EnumValuesAsArrayTwigExtensionTest.php +++ b/Tests/Twig/Extension/EnumValuesAsArrayTwigExtensionTest.php @@ -17,6 +17,7 @@ use Fresh\DoctrineEnumBundle\Exception\LogicException; use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\BasketballPositionType; use Fresh\DoctrineEnumBundle\Twig\Extension\EnumValuesAsArrayTwigExtension; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Twig\TwigFunction; @@ -41,7 +42,8 @@ protected function tearDown(): void unset($this->enumValuesAsArrayTwigExtension); } - public function testGetFunctions(): void + #[Test] + public function getFunctions(): void { self::assertEquals( [ @@ -52,7 +54,8 @@ public function testGetFunctions(): void ); } - public function testGetEnumValuesAsArray(): void + #[Test] + public function getEnumValuesAsArray(): void { self::assertEquals( ['PG', 'SG', 'SF', 'PF', 'C'], @@ -60,7 +63,8 @@ public function testGetEnumValuesAsArray(): void ); } - public function testGetReadableEnumValuesAsArray(): void + #[Test] + public function getReadableEnumValuesAsArray(): void { self::assertEquals( [ @@ -74,19 +78,22 @@ public function testGetReadableEnumValuesAsArray(): void ); } - public function testEnumTypeIsNotRegisteredException(): void + #[Test] + public function enumTypeIsNotRegisteredException(): void { $this->expectException(EnumTypeIsNotRegisteredException::class); $this->enumValuesAsArrayTwigExtension->getEnumValuesAsArray('MapLocationType'); } - public function testNoRegisteredEnumTypesException(): void + #[Test] + public function noRegisteredEnumTypesException(): void { $this->expectException(NoRegisteredEnumTypesException::class); (new EnumValuesAsArrayTwigExtension([]))->getEnumValuesAsArray('MapLocationType'); } - public function testInvalidCallable(): void + #[Test] + public function invalidCallable(): void { $extension = new EnumValuesAsArrayTwigExtension([]); diff --git a/Tests/Twig/Extension/ReadableEnumValueTwigExtensionTest.php b/Tests/Twig/Extension/ReadableEnumValueTwigExtensionTest.php index 27d5932..15fb0f5 100644 --- a/Tests/Twig/Extension/ReadableEnumValueTwigExtensionTest.php +++ b/Tests/Twig/Extension/ReadableEnumValueTwigExtensionTest.php @@ -21,6 +21,8 @@ use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\MapLocationType; use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\NumericType; use Fresh\DoctrineEnumBundle\Twig\Extension\ReadableEnumValueTwigExtension; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Twig\TwigFilter; @@ -48,7 +50,8 @@ protected function tearDown(): void unset($this->readableEnumValueTwigExtension); } - public function testGetFilters(): void + #[Test] + public function getFilters(): void { self::assertEquals( [new TwigFilter('readable_enum', [$this->readableEnumValueTwigExtension, 'getReadableEnumValue'])], @@ -56,14 +59,9 @@ public function testGetFilters(): void ); } - /** - * @dataProvider dataProviderForGetReadableEnumValueTest - * - * @param int|string|null $expectedReadableValue - * @param int|string|null $enumValue - * @param string|null $enumType - */ - public function testGetReadableEnumValue(int|string|null $expectedReadableValue, int|string|null $enumValue, ?string $enumType): void + #[Test] + #[DataProvider('dataProviderForGetReadableEnumValueTest')] + public function getReadableEnumValue(int|string|null $expectedReadableValue, int|string|null $enumValue, ?string $enumType): void { self::assertEquals( $expectedReadableValue, @@ -83,25 +81,29 @@ public static function dataProviderForGetReadableEnumValueTest(): iterable yield ['Not Found', HTTPStatusCodeType::HTTP_NOT_FOUND, 'HTTPStatusCodeType']; } - public function testEnumTypeIsNotRegisteredException(): void + #[Test] + public function enumTypeIsNotRegisteredException(): void { $this->expectException(EnumTypeIsNotRegisteredException::class); $this->readableEnumValueTwigExtension->getReadableEnumValue('Pitcher', 'BaseballPositionType'); } - public function testValueIsFoundInFewRegisteredEnumTypesException(): void + #[Test] + public function valueIsFoundInFewRegisteredEnumTypesException(): void { $this->expectException(ValueIsFoundInFewRegisteredEnumTypesException::class); $this->readableEnumValueTwigExtension->getReadableEnumValue(BasketballPositionType::CENTER); } - public function testValueIsNotFoundInAnyRegisteredEnumTypeException(): void + #[Test] + public function valueIsNotFoundInAnyRegisteredEnumTypeException(): void { $this->expectException(ValueIsNotFoundInAnyRegisteredEnumTypeException::class); $this->readableEnumValueTwigExtension->getReadableEnumValue('Pitcher'); } - public function testNoRegisteredEnumTypesException(): void + #[Test] + public function noRegisteredEnumTypesException(): void { $this->expectException(NoRegisteredEnumTypesException::class); (new ReadableEnumValueTwigExtension([]))->getReadableEnumValue(BasketballPositionType::POINT_GUARD, 'BasketballPositionType'); diff --git a/Tests/Validator/EnumTypeTest.php b/Tests/Validator/EnumTypeTest.php index 89e1ef5..90ed588 100644 --- a/Tests/Validator/EnumTypeTest.php +++ b/Tests/Validator/EnumTypeTest.php @@ -15,6 +15,7 @@ use Fresh\DoctrineEnumBundle\Exception\InvalidArgumentException; use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\BasketballPositionType; use Fresh\DoctrineEnumBundle\Validator\Constraints\EnumType; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; /** @@ -24,7 +25,8 @@ */ final class EnumTypeTest extends TestCase { - public function testConstructorWithRequiredArguments(): void + #[Test] + public function constructorWithRequiredArguments(): void { $constraint = new EnumType(entity: BasketballPositionType::class); @@ -32,7 +34,8 @@ public function testConstructorWithRequiredArguments(): void self::assertTrue($constraint->strict); } - public function testConstructorWithAllArguments(): void + #[Test] + public function constructorWithAllArguments(): void { $constraint = new EnumType(entity: BasketballPositionType::class, message: 'test', groups: ['foo'], payload: ['bar' => 'baz']); @@ -48,7 +51,8 @@ public function testConstructorWithAllArguments(): void self::assertNull($constraint->max); } - public function testNotEnumType(): void + #[Test] + public function notEnumType(): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('stdClass is not instance of Fresh\DoctrineEnumBundle\DBAL\Types\AbstractEnumType'); @@ -56,7 +60,8 @@ public function testNotEnumType(): void new EnumType(entity: \stdClass::class); } - public function testGetDefaultOption(): void + #[Test] + public function getDefaultOption(): void { $constraint = new EnumType(entity: BasketballPositionType::class); diff --git a/Tests/Validator/EnumTypeValidatorTest.php b/Tests/Validator/EnumTypeValidatorTest.php index 90de86e..26a94c7 100644 --- a/Tests/Validator/EnumTypeValidatorTest.php +++ b/Tests/Validator/EnumTypeValidatorTest.php @@ -16,6 +16,7 @@ use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\BasketballPositionType; use Fresh\DoctrineEnumBundle\Validator\Constraints\EnumType; use Fresh\DoctrineEnumBundle\Validator\Constraints\EnumTypeValidator; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Validator\Context\ExecutionContext; @@ -47,7 +48,8 @@ protected function tearDown(): void ); } - public function testValidateIncorrectConstraintClass(): void + #[Test] + public function validateIncorrectConstraintClass(): void { $this->expectException(RuntimeException::class); $this->expectExceptionMessageMatches('/^Object of class .* is not instance of .*$/'); @@ -55,7 +57,8 @@ public function testValidateIncorrectConstraintClass(): void $this->enumValidator->validate(BasketballPositionType::POINT_GUARD, new DummyConstraint()); } - public function testValidBasketballPositionType(): void + #[Test] + public function validBasketballPositionType(): void { $constraint = new EnumType(entity: BasketballPositionType::class); @@ -68,7 +71,8 @@ public function testValidBasketballPositionType(): void $this->enumValidator->validate(BasketballPositionType::SMALL_FORWARD, $constraint); } - public function testInvalidBasketballPositionType(): void + #[Test] + public function invalidBasketballPositionType(): void { $constraint = new EnumType(entity: BasketballPositionType::class); $constraintValidationBuilder = $this->createMock(ConstraintViolationBuilder::class); diff --git a/composer.json b/composer.json index a361e13..0c2624a 100644 --- a/composer.json +++ b/composer.json @@ -24,16 +24,16 @@ "require": { "php": ">=8.1", "doctrine/common": "^3.4", - "doctrine/dbal": "^3.7", - "doctrine/doctrine-bundle": "^2.11", - "doctrine/orm": "^2.16|^3.0", + "doctrine/dbal": "^4.0", + "doctrine/doctrine-bundle": "^2.12", + "doctrine/orm": "^3.1", "symfony/config": "^7.0", "symfony/dependency-injection": "^7.0", "symfony/doctrine-bridge": "^7.0", "symfony/framework-bundle": "^7.0", "symfony/http-kernel": "^7.0", "symfony/validator": "^7.0", - "twig/twig": "^3.8" + "twig/twig": "^3.9" }, "require-dev": { "escapestudios/symfony2-coding-standard": "^3.13", @@ -42,9 +42,9 @@ "phpstan/phpstan-doctrine": "^1.3", "phpstan/phpstan-phpunit": "^1.3", "phpstan/phpstan-symfony": "^1.3", - "phpunit/phpunit": "^10.5", - "slam/phpstan-extensions": "^6.1", - "symfony/form": "^6.1" + "phpunit/phpunit": "^11.1", + "slam/phpstan-extensions": "^6.3", + "symfony/form": "^7.0" }, "autoload": { "psr-4": {