|
30 | 30 | use PHPUnit\Framework\Attributes\Group; |
31 | 31 | use ReflectionException; |
32 | 32 | use stdClass; |
| 33 | +use Tests\Support\Entity\ArrayObjectWithToArray; |
33 | 34 | use Tests\Support\Entity\Cast\CastBase64; |
34 | 35 | use Tests\Support\Entity\Cast\CastPassParameters; |
35 | 36 | use Tests\Support\Entity\Cast\NotExtendsBaseCast; |
36 | 37 | use Tests\Support\Enum\ColorEnum; |
| 38 | +use Tests\Support\Enum\JsonSerializableStateUnitEnum; |
37 | 39 | use Tests\Support\Enum\RoleEnum; |
| 40 | +use Tests\Support\Enum\StateEnum; |
| 41 | +use Tests\Support\Enum\StateUnitEnum; |
38 | 42 | use Tests\Support\Enum\StatusEnum; |
39 | 43 | use Tests\Support\SomeEntity; |
40 | 44 |
|
@@ -1045,6 +1049,45 @@ public function testCastEnumSetWithUnitEnumObject(): void |
1045 | 1049 | $this->assertSame(ColorEnum::RED, $entity->color); |
1046 | 1050 | } |
1047 | 1051 |
|
| 1052 | + /** |
| 1053 | + * @see https://github.com/codeigniter4/CodeIgniter4/issues/10136 |
| 1054 | + */ |
| 1055 | + public function testInjectRawDataWithBackedEnumThatHasToArrayMethod(): void |
| 1056 | + { |
| 1057 | + $entity = new class () extends Entity {}; |
| 1058 | + |
| 1059 | + $entity->injectRawData(['state' => StateEnum::DRAFT]); |
| 1060 | + |
| 1061 | + $this->assertSame(StateEnum::DRAFT, $entity->toRawArray()['state']); |
| 1062 | + $this->assertFalse($entity->hasChanged('state')); |
| 1063 | + } |
| 1064 | + |
| 1065 | + /** |
| 1066 | + * @see https://github.com/codeigniter4/CodeIgniter4/issues/10136 |
| 1067 | + */ |
| 1068 | + public function testInjectRawDataWithUnitEnumThatHasToArrayMethod(): void |
| 1069 | + { |
| 1070 | + $entity = new class () extends Entity {}; |
| 1071 | + |
| 1072 | + $entity->injectRawData(['state' => StateUnitEnum::DRAFT]); |
| 1073 | + |
| 1074 | + $this->assertSame(StateUnitEnum::DRAFT, $entity->toRawArray()['state']); |
| 1075 | + $this->assertFalse($entity->hasChanged('state')); |
| 1076 | + } |
| 1077 | + |
| 1078 | + /** |
| 1079 | + * @see https://github.com/codeigniter4/CodeIgniter4/issues/10136 |
| 1080 | + */ |
| 1081 | + public function testInjectRawDataWithUnitEnumThatImplementsJsonSerializable(): void |
| 1082 | + { |
| 1083 | + $entity = new class () extends Entity {}; |
| 1084 | + |
| 1085 | + $entity->injectRawData(['state' => JsonSerializableStateUnitEnum::DRAFT]); |
| 1086 | + |
| 1087 | + $this->assertSame(JsonSerializableStateUnitEnum::DRAFT, $entity->toRawArray()['state']); |
| 1088 | + $this->assertFalse($entity->hasChanged('state')); |
| 1089 | + } |
| 1090 | + |
1048 | 1091 | public function testAsArray(): void |
1049 | 1092 | { |
1050 | 1093 | $entity = $this->getEntity(); |
@@ -1975,6 +2018,46 @@ public function jsonSerialize(): mixed |
1975 | 2018 | $this->assertTrue($entity->hasChanged('data')); |
1976 | 2019 | } |
1977 | 2020 |
|
| 2021 | + public function testHasChangedPrefersJsonSerializableOverToArray(): void |
| 2022 | + { |
| 2023 | + $entity = new class () extends Entity { |
| 2024 | + protected $attributes = [ |
| 2025 | + 'data' => null, |
| 2026 | + ]; |
| 2027 | + }; |
| 2028 | + |
| 2029 | + $data = new class ('original') implements JsonSerializable { |
| 2030 | + public function __construct(private string $value) |
| 2031 | + { |
| 2032 | + } |
| 2033 | + |
| 2034 | + public function jsonSerialize(): mixed |
| 2035 | + { |
| 2036 | + return ['json' => $this->value]; |
| 2037 | + } |
| 2038 | + |
| 2039 | + public function setValue(string $value): void |
| 2040 | + { |
| 2041 | + $this->value = $value; |
| 2042 | + } |
| 2043 | + |
| 2044 | + /** |
| 2045 | + * @return array<string, string> |
| 2046 | + */ |
| 2047 | + public function toArray(): array |
| 2048 | + { |
| 2049 | + return ['array' => 'same']; |
| 2050 | + } |
| 2051 | + }; |
| 2052 | + |
| 2053 | + $entity->data = $data; |
| 2054 | + $entity->syncOriginal(); |
| 2055 | + |
| 2056 | + $data->setValue('modified'); |
| 2057 | + |
| 2058 | + $this->assertTrue($entity->hasChanged('data')); |
| 2059 | + } |
| 2060 | + |
1978 | 2061 | public function testHasChangedDoesNotDetectUnchangedObject(): void |
1979 | 2062 | { |
1980 | 2063 | $entity = new class () extends Entity { |
@@ -2278,6 +2361,50 @@ public function toArray(): array |
2278 | 2361 | $this->assertTrue($entity->hasChanged('custom')); |
2279 | 2362 | } |
2280 | 2363 |
|
| 2364 | + public function testHasChangedPrefersToArrayOverTraversable(): void |
| 2365 | + { |
| 2366 | + $entity = new class () extends Entity { |
| 2367 | + protected $attributes = [ |
| 2368 | + 'items' => null, |
| 2369 | + ]; |
| 2370 | + }; |
| 2371 | + |
| 2372 | + $items = new ArrayObjectWithToArray(['iterator' => 'original']); |
| 2373 | + |
| 2374 | + $entity->items = $items; |
| 2375 | + $entity->syncOriginal(); |
| 2376 | + |
| 2377 | + $items->exchangeArray(['iterator' => 'modified']); |
| 2378 | + |
| 2379 | + $this->assertFalse($entity->hasChanged('items')); |
| 2380 | + } |
| 2381 | + |
| 2382 | + public function testHasChangedPrefersToArrayOverDateTimeInterface(): void |
| 2383 | + { |
| 2384 | + $entity = new class () extends Entity { |
| 2385 | + protected $attributes = [ |
| 2386 | + 'date' => null, |
| 2387 | + ]; |
| 2388 | + }; |
| 2389 | + |
| 2390 | + $date = new class ('2024-01-01 00:00:00') extends DateTime { |
| 2391 | + /** |
| 2392 | + * @return array<string, string> |
| 2393 | + */ |
| 2394 | + public function toArray(): array |
| 2395 | + { |
| 2396 | + return ['date' => 'same']; |
| 2397 | + } |
| 2398 | + }; |
| 2399 | + |
| 2400 | + $entity->date = $date; |
| 2401 | + $entity->syncOriginal(); |
| 2402 | + |
| 2403 | + $date->modify('+1 day'); |
| 2404 | + |
| 2405 | + $this->assertFalse($entity->hasChanged('date')); |
| 2406 | + } |
| 2407 | + |
2281 | 2408 | public function testHasChangedScalarOptimizationWithNullValues(): void |
2282 | 2409 | { |
2283 | 2410 | $entity = new class () extends Entity { |
|
0 commit comments