Skip to content

Commit a3915be

Browse files
committed
Support Uuid list column
1 parent b9b0c03 commit a3915be

File tree

4 files changed

+154
-9
lines changed

4 files changed

+154
-9
lines changed

phpunit.xml

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3-
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.1/phpunit.xsd" bootstrap="vendor/autoload.php"
4-
executionOrder="depends,defects" beStrictAboutOutputDuringTests="true" failOnRisky="true" failOnWarning="true"
5-
colors="true" cacheDirectory=".phpunit.cache" requireCoverageMetadata="false"
6-
displayDetailsOnTestsThatTriggerDeprecations="true"
7-
displayDetailsOnTestsThatTriggerErrors="true"
8-
displayDetailsOnTestsThatTriggerNotices="true"
9-
displayDetailsOnTestsThatTriggerWarnings="true"
3+
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
4+
bootstrap="vendor/autoload.php"
5+
backupGlobals="false"
6+
colors="true"
7+
processIsolation="false"
8+
stopOnFailure="false"
9+
stopOnError="false"
10+
stderr="true"
11+
cacheDirectory="runtime/.phpunit.cache"
12+
backupStaticProperties="false"
13+
beStrictAboutOutputDuringTests="true"
1014
displayDetailsOnPhpunitDeprecations="true"
11-
beStrictAboutCoverageMetadata="true">
15+
failOnPhpunitDeprecation="true"
16+
failOnDeprecation="true"
17+
failOnRisky="true"
18+
failOnWarning="true"
19+
>
1220
<testsuites>
1321
<testsuite name="default">
1422
<directory>tests</directory>

src/ColumnBuilder.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,15 @@ private static function getPropertyConfig(string $propertyTypeName, array $prope
9898
$subType = null;
9999

100100
if ($columnClass === Columns\ArrayColumn::class && isset($propertyAttributes[Attributes\ListOf::class])) {
101-
$columnClass = Columns\EntityListColumn::class;
102101
/** @var Attributes\ListOf $listOfAttribute */
103102
$listOfAttribute = $propertyAttributes[Attributes\ListOf::class];
104103
$type = $listOfAttribute->class;
105104
$subType = $listOfAttribute->keyColumn;
105+
if ($type === UuidInterface::class) {
106+
$columnClass = Columns\UuidListColumn::class;
107+
} else {
108+
$columnClass = Columns\EntityListColumn::class;
109+
}
106110
} elseif (!$columnClass && class_exists($propertyTypeName)) {
107111
if (is_subclass_of($propertyTypeName, AbstractEntity::class)) {
108112
$columnClass = Columns\EntityColumn::class;

src/Columns/UuidListColumn.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Composite\Entity\Columns;
4+
5+
use Composite\Entity\Exceptions\EntityException;
6+
use Ramsey\Uuid;
7+
8+
class UuidListColumn extends AbstractColumn
9+
{
10+
/**
11+
* @return array<Uuid\UuidInterface>
12+
* @throws EntityException
13+
*/
14+
public function cast(mixed $dbValue): array
15+
{
16+
if (is_array($dbValue)) {
17+
foreach ($dbValue as $key => $value) {
18+
if (is_string($value)) {
19+
$dbValue[$key] = Uuid\Uuid::fromString($value);
20+
}
21+
}
22+
return $dbValue;
23+
}
24+
try {
25+
return array_map(
26+
fn ($value) => Uuid\Uuid::fromString((string)$value),
27+
(array)\json_decode(strval($dbValue), true, 512, JSON_THROW_ON_ERROR)
28+
);
29+
} catch (\Exception $e) {
30+
throw new EntityException($e->getMessage(), $e);
31+
}
32+
}
33+
34+
/**
35+
* @throws EntityException
36+
*/
37+
public function uncast(mixed $entityValue): string
38+
{
39+
try {
40+
return \json_encode($entityValue, JSON_THROW_ON_ERROR);
41+
} catch (\JsonException $e) {
42+
throw new EntityException($e->getMessage(), $e);
43+
}
44+
}
45+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Composite\Entity\Tests\Columns;
4+
5+
use Composite\Entity\AbstractEntity;
6+
use Composite\Entity\Attributes\ListOf;
7+
use PHPUnit\Framework\Attributes\DataProvider;
8+
use Ramsey\Uuid\Uuid;
9+
use Ramsey\Uuid\UuidInterface;
10+
11+
final class UuidListColumnTest extends \PHPUnit\Framework\TestCase
12+
{
13+
public static function cast_dataProvider(): array
14+
{
15+
$str = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
16+
$uuid = Uuid::fromString($str);
17+
return [
18+
[
19+
'value' => [],
20+
'expected' => [],
21+
],
22+
[
23+
'value' => "[\"{$str}\"]",
24+
'expected' => [$uuid],
25+
],
26+
[
27+
'value' => [$uuid],
28+
'expected' => [$uuid],
29+
],
30+
[
31+
'value' => [$str],
32+
'expected' => [$uuid],
33+
],
34+
[
35+
'value' => 'invalid_uuid',
36+
'expected' => [],
37+
],
38+
];
39+
}
40+
41+
#[DataProvider('cast_dataProvider')]
42+
public function test_cast(mixed $value, array $expected): void
43+
{
44+
$class = new class extends AbstractEntity {
45+
public function __construct(
46+
#[ListOf(UuidInterface::class)]
47+
public array $column = [],
48+
) {}
49+
};
50+
$entity = $class::fromArray(['column' => $value]);
51+
$this->assertEquals($expected, $entity->column);
52+
}
53+
54+
public static function uncast_dataProvider(): array
55+
{
56+
$str = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
57+
$uuid = Uuid::fromString($str);
58+
return [
59+
[
60+
'value' => [],
61+
'expected' => '[]',
62+
],
63+
[
64+
'value' => [$uuid],
65+
'expected' => "[\"{$str}\"]",
66+
],
67+
68+
];
69+
}
70+
71+
#[DataProvider('uncast_dataProvider')]
72+
public function test_uncast(array $value, mixed $expected): void
73+
{
74+
$entity = new class($value) extends AbstractEntity {
75+
public function __construct(
76+
#[ListOf(UuidInterface::class)]
77+
public array $column,
78+
) {}
79+
};
80+
$actual = $entity->toArray()['column'];
81+
$this->assertEquals($expected, $actual);
82+
83+
$newEntity = $entity::fromArray(['column' => $actual]);
84+
$newActual = $newEntity->toArray()['column'];
85+
$this->assertEquals($entity->column, $newEntity->column);
86+
$this->assertEquals($expected, $newActual);
87+
}
88+
}

0 commit comments

Comments
 (0)