Skip to content

Commit

Permalink
Initial testing
Browse files Browse the repository at this point in the history
  • Loading branch information
bigfoot90 committed Mar 23, 2024
1 parent ccdb800 commit cbb4017
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 36 deletions.
67 changes: 31 additions & 36 deletions src/Types/EnumType.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,100 +10,95 @@
use Doctrine\DBAL\Platforms\SQLServerPlatform;
use Doctrine\DBAL\Types\Exception\InvalidType;
use Doctrine\DBAL\Types\Exception\ValueNotConvertible;
use ReflectionClass;
use Throwable;

use function array_map;
use function class_exists;
use function implode;
use function is_string;
use function sprintf;

final class EnumType extends Type
{
public string $name = 'enum';

public ?string $enumClassname = null;

/** @var array<int, string> */
public array $members = [];

/**
* Gets an array of database types that map to this Doctrine type.
*
* @return string[]
* {@inheritDoc}
*/
public function getMappedDatabaseTypes(AbstractPlatform $platform): array
{
return [$this->name];
}

/**
* Gets the SQL declaration snippet for a field of this type.
*
* @param mixed[] $column The field declaration
* @param AbstractPlatform $platform The currently used database platform
* {@inheritDoc}
*/
public function getSqlDeclaration(array $column, AbstractPlatform $platform): string

Check failure on line 42 in src/Types/EnumType.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (8.3)

Method Doctrine\DBAL\Types\EnumType::getSqlDeclaration() does not match parent method name: Doctrine\DBAL\Types\Type::getSQLDeclaration().
{
assert($column['type'] instanceof self::class);

$values = implode(
', ',
array_map(
static fn (string $value) => "'{$value}'",
$column['members'] ?: $column['type']->members
)
static fn (string $value) => sprintf('\'%s\'', $value),
$column['members'] ?: $column['type']->members,

Check failure on line 48 in src/Types/EnumType.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (8.3)

Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.
),
);

$sqlDeclaration = match (true) {
return match (true) {
$platform instanceof SqlitePlatform => sprintf('TEXT CHECK(%s IN (%s))', $column['name'], $values),

Check failure on line 53 in src/Types/EnumType.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (8.3)

Class Doctrine\DBAL\Platforms\SQLitePlatform referenced with incorrect case: Doctrine\DBAL\Platforms\SqlitePlatform.

Check failure on line 53 in src/Types/EnumType.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (8.3)

InvalidClass

src/Types/EnumType.php:53:34: InvalidClass: Class, interface or enum Doctrine\DBAL\Platforms\SqlitePlatform has wrong casing (see https://psalm.dev/007)
$platform instanceof PostgreSqlPlatform, $platform instanceof SQLServerPlatform => sprintf('VARCHAR(255) CHECK(%s IN (%s))', $column['name'], $values),

Check warning on line 54 in src/Types/EnumType.php

View workflow job for this annotation

GitHub Actions / Coding Standards / Coding Standards (8.3)

Line exceeds 120 characters; contains 163 characters

Check failure on line 54 in src/Types/EnumType.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (8.3)

Class Doctrine\DBAL\Platforms\PostgreSQLPlatform referenced with incorrect case: Doctrine\DBAL\Platforms\PostgreSqlPlatform.

Check failure on line 54 in src/Types/EnumType.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (8.3)

InvalidClass

src/Types/EnumType.php:54:34: InvalidClass: Class, interface or enum Doctrine\DBAL\Platforms\PostgreSqlPlatform has wrong casing (see https://psalm.dev/007)
default => sprintf('ENUM(%s)', $values),
};

return $sqlDeclaration;
}

/**
* {@inheritdoc}
*
* @return mixed the database representation of the value
*
* @throws \InvalidArgumentException
* {@inheritDoc}
*/
public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string
{
if (null === $value) {
if ($value === null) {
return null;
}

return (string) $value;
}

/**

Check failure on line 71 in src/Types/EnumType.php

View workflow job for this annotation

GitHub Actions / Coding Standards / Coding Standards (8.3)

Useless documentation comment with @inheritdoc.
* {@inheritdoc}
*
* @return mixed the PHP representation of the value
* {@inheritDoc}
*/
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): mixed
{
if (null === $value) {
if ($value === null) {
return null;
}

if (!\is_string($value)) {
if (! is_string($value)) {
throw InvalidType::new($value, $this->name, ['null', 'string']);

Check warning on line 81 in src/Types/EnumType.php

View check run for this annotation

Codecov / codecov/patch

src/Types/EnumType.php#L81

Added line #L81 was not covered by tests
}

$refl = new \ReflectionClass($this->enumClassname);
if ($this->enumClassname && class_exists($this->enumClassname)) {

Check failure on line 84 in src/Types/EnumType.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (8.3)

Only booleans are allowed in &&, string|null given on the left side.

Check failure on line 84 in src/Types/EnumType.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (8.3)

RiskyTruthyFalsyComparison

src/Types/EnumType.php:84:13: RiskyTruthyFalsyComparison: Operand of type null|string contains type string, which can be falsy and truthy. This can cause possibly unexpected behavior. Use strict comparison instead. (see https://psalm.dev/356)
$refl = new ReflectionClass($this->enumClassname);

try {
return $refl->newInstance($value);
} catch (\Throwable $e) {
throw ValueNotConvertible::new($value, $this->name, $e->getMessage(), $e);
try {
return $refl->newInstance($value);
} catch (Throwable $e) {
throw ValueNotConvertible::new($value, $this->name, $e->getMessage(), $e);

Check warning on line 90 in src/Types/EnumType.php

View check run for this annotation

Codecov / codecov/patch

src/Types/EnumType.php#L89-L90

Added lines #L89 - L90 were not covered by tests
}
}

return $value;
}

/**
* {@inheritdoc}
*/
public static function addType(string $name, string $enumClassname): void

Check failure on line 97 in src/Types/EnumType.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (8.3)

ParamNameMismatch

src/Types/EnumType.php:97:57: ParamNameMismatch: Argument 2 of Doctrine\DBAL\Types\EnumType::addType has wrong name $enumClassname, expecting $className as defined by Doctrine\DBAL\Types\Type::addType (see https://psalm.dev/230)

Check warning on line 97 in src/Types/EnumType.php

View check run for this annotation

Codecov / codecov/patch

src/Types/EnumType.php#L97

Added line #L97 was not covered by tests
{
self::getTypeRegistry()->register($name, $me = new self());
$me->name = $name;
$me->name = $name;
$me->enumClassname = $enumClassname;
$me->members = $enumClassname::getAllowedValues();
$me->members = $enumClassname::getAllowedValues();

Check failure on line 102 in src/Types/EnumType.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (8.3)

Call to an undefined static method Doctrine\DBAL\Types\Type::getAllowedValues().

Check failure on line 102 in src/Types/EnumType.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (8.3)

UndefinedMethod

src/Types/EnumType.php:102:30: UndefinedMethod: Method Doctrine\DBAL\Types\Type::getallowedvalues does not exist (see https://psalm.dev/022)

Check warning on line 102 in src/Types/EnumType.php

View check run for this annotation

Codecov / codecov/patch

src/Types/EnumType.php#L99-L102

Added lines #L99 - L102 were not covered by tests
}
}
1 change: 1 addition & 0 deletions tests/Schema/ColumnTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public function testToArray(): void
'default' => 'baz',
'notnull' => false,
'length' => 200,
'members' => [],
'precision' => 5,
'scale' => 2,
'fixed' => true,
Expand Down
79 changes: 79 additions & 0 deletions tests/Types/EnumTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Tests\Types;

use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\EnumType;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

use function anonymous_class;

Check failure on line 12 in tests/Types/EnumTest.php

View workflow job for this annotation

GitHub Actions / Coding Standards / Coding Standards (8.3)

Type anonymous_class is not used in this file.

Check failure on line 12 in tests/Types/EnumTest.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (8.3)

Used function anonymous_class not found.

class EnumTest extends TestCase
{
private AbstractPlatform&MockObject $platform;
private EnumType $type;

protected function setUp(): void
{
$this->platform = $this->createMock(AbstractPlatform::class);
$this->type = new EnumType();

Check failure on line 22 in tests/Types/EnumTest.php

View workflow job for this annotation

GitHub Actions / Coding Standards / Coding Standards (8.3)

Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space
}

public function testReturnsSQLDeclaration(): void
{
self::assertEquals('ENUM(\'A\', \'B\')', $this->type->getSQLDeclaration(['members' => ['A', 'B']], $this->platform));

Check warning on line 27 in tests/Types/EnumTest.php

View workflow job for this annotation

GitHub Actions / Coding Standards / Coding Standards (8.3)

Line exceeds 120 characters; contains 125 characters

Check failure on line 27 in tests/Types/EnumTest.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (8.3)

Call to method Doctrine\DBAL\Types\EnumType::getSqlDeclaration() with incorrect case: getSQLDeclaration
}

public function testConvertToPHPValue(): void
{
self::assertIsString($this->type->convertToPHPValue('foo', $this->platform));
self::assertIsString($this->type->convertToPHPValue('', $this->platform));
self::assertNull($this->type->convertToPHPValue(null, $this->platform));
}

public function testConvertToPHPObject(): void
{
$this->type->enumClassname = get_class(self::getEnumClass());

Check failure on line 39 in tests/Types/EnumTest.php

View workflow job for this annotation

GitHub Actions / Coding Standards / Coding Standards (8.3)

Function get_class() should not be referenced via a fallback global name, but via a use statement.

self::assertInstanceOf($this->type->enumClassname, $this->type->convertToPHPValue('A', $this->platform));
self::assertEquals('A', $this->type->convertToPHPValue('A', $this->platform)->getValue());
}

public function testConvertStringToDatabaseValue(): void
{
self::assertEquals('A', $this->type->convertToDatabaseValue('A', $this->platform));
self::assertNull($this->type->convertToDatabaseValue(null, $this->platform));
}

public function testConvertObjectToDatabaseValue(): void
{
$enum = self::getEnumClass('A');

Check failure on line 53 in tests/Types/EnumTest.php

View workflow job for this annotation

GitHub Actions / Coding Standards / Coding Standards (8.3)

Equals sign not aligned with surrounding assignments; expected 22 spaces but found 1 space
$this->type->enumClassname = get_class(self::getEnumClass());

self::assertEquals('A', $this->type->convertToDatabaseValue($enum, $this->platform));
self::assertNull($this->type->convertToDatabaseValue(null, $this->platform));
}

private static function getEnumClass(mixed $value = null)

Check failure on line 60 in tests/Types/EnumTest.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (8.3)

MissingReturnType

tests/Types/EnumTest.php:60:29: MissingReturnType: Method Doctrine\DBAL\Tests\Types\EnumTest::getEnumClass does not have a return type, expecting _home_runner_work_dbal_dbal_tests_Types_EnumTest_php_62_2091 (see https://psalm.dev/050)
{
return new class ($value) implements \Stringable {
function __construct(
private ?string $value
) {
}

function getValue(): ?string
{
return $this->value;
}

function __tostring(): string

Check failure on line 73 in tests/Types/EnumTest.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (8.3)

InvalidToString

tests/Types/EnumTest.php:73:36: InvalidToString: __toString methods must return a string, null|string returned (see https://psalm.dev/055)
{
return $this->value;

Check failure on line 75 in tests/Types/EnumTest.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (8.3)

NullableReturnStatement

tests/Types/EnumTest.php:75:24: NullableReturnStatement: The declared return type 'string' for _home_runner_work_dbal_dbal_tests_Types_EnumTest_php_62_2091::__tostring is not nullable, but the function returns 'null|string' (see https://psalm.dev/139)
}
};
}
}

0 comments on commit cbb4017

Please sign in to comment.