3434use Tests \Support \Entity \Cast \CastPassParameters ;
3535use Tests \Support \Entity \Cast \NotExtendsBaseCast ;
3636use Tests \Support \Enum \ColorEnum ;
37+ use Tests \Support \Enum \JsonSerializableStateUnitEnum ;
3738use Tests \Support \Enum \RoleEnum ;
3839use Tests \Support \Enum \StateEnum ;
40+ use Tests \Support \Enum \StateUnitEnum ;
3941use Tests \Support \Enum \StatusEnum ;
4042use Tests \Support \SomeEntity ;
4143
@@ -1049,7 +1051,7 @@ public function testCastEnumSetWithUnitEnumObject(): void
10491051 /**
10501052 * @see https://github.com/codeigniter4/CodeIgniter4/issues/10136
10511053 */
1052- public function testInjectRawDataWithEnumThatHasToArrayMethod (): void
1054+ public function testInjectRawDataWithBackedEnumThatHasToArrayMethod (): void
10531055 {
10541056 $ entity = new class () extends Entity {};
10551057
@@ -1059,6 +1061,32 @@ public function testInjectRawDataWithEnumThatHasToArrayMethod(): void
10591061 $ this ->assertFalse ($ entity ->hasChanged ('state ' ));
10601062 }
10611063
1064+ /**
1065+ * @see https://github.com/codeigniter4/CodeIgniter4/issues/10136
1066+ */
1067+ public function testInjectRawDataWithUnitEnumThatHasToArrayMethod (): void
1068+ {
1069+ $ entity = new class () extends Entity {};
1070+
1071+ $ entity ->injectRawData (['state ' => StateUnitEnum::DRAFT ]);
1072+
1073+ $ this ->assertSame (StateUnitEnum::DRAFT , $ entity ->toRawArray ()['state ' ]);
1074+ $ this ->assertFalse ($ entity ->hasChanged ('state ' ));
1075+ }
1076+
1077+ /**
1078+ * @see https://github.com/codeigniter4/CodeIgniter4/issues/10136
1079+ */
1080+ public function testInjectRawDataWithUnitEnumThatImplementsJsonSerializable (): void
1081+ {
1082+ $ entity = new class () extends Entity {};
1083+
1084+ $ entity ->injectRawData (['state ' => JsonSerializableStateUnitEnum::DRAFT ]);
1085+
1086+ $ this ->assertSame (JsonSerializableStateUnitEnum::DRAFT , $ entity ->toRawArray ()['state ' ]);
1087+ $ this ->assertFalse ($ entity ->hasChanged ('state ' ));
1088+ }
1089+
10621090 public function testAsArray (): void
10631091 {
10641092 $ entity = $ this ->getEntity ();
@@ -1989,6 +2017,41 @@ public function jsonSerialize(): mixed
19892017 $ this ->assertTrue ($ entity ->hasChanged ('data ' ));
19902018 }
19912019
2020+ public function testHasChangedPrefersJsonSerializableOverToArray (): void
2021+ {
2022+ $ entity = new class () extends Entity {
2023+ protected $ attributes = [
2024+ 'data ' => null ,
2025+ ];
2026+ };
2027+
2028+ $ entity ->data = new class ('original ' ) implements JsonSerializable {
2029+ public function __construct (private string $ value )
2030+ {
2031+ }
2032+
2033+ public function jsonSerialize (): mixed
2034+ {
2035+ return ['json ' => $ this ->value ];
2036+ }
2037+
2038+ public function setValue (string $ value ): void
2039+ {
2040+ $ this ->value = $ value ;
2041+ }
2042+
2043+ public function toArray (): array
2044+ {
2045+ return ['array ' => 'same ' ];
2046+ }
2047+ };
2048+ $ entity ->syncOriginal ();
2049+
2050+ $ entity ->data ->setValue ('modified ' );
2051+
2052+ $ this ->assertTrue ($ entity ->hasChanged ('data ' ));
2053+ }
2054+
19922055 public function testHasChangedDoesNotDetectUnchangedObject (): void
19932056 {
19942057 $ entity = new class () extends Entity {
@@ -2292,6 +2355,48 @@ public function toArray(): array
22922355 $ this ->assertTrue ($ entity ->hasChanged ('custom ' ));
22932356 }
22942357
2358+ public function testHasChangedPrefersToArrayOverTraversable (): void
2359+ {
2360+ $ entity = new class () extends Entity {
2361+ protected $ attributes = [
2362+ 'items ' => null ,
2363+ ];
2364+ };
2365+
2366+ $ entity ->items = new class (['iterator ' => 'original ' ]) extends ArrayObject {
2367+ public function toArray (): array
2368+ {
2369+ return ['array ' => 'same ' ];
2370+ }
2371+ };
2372+ $ entity ->syncOriginal ();
2373+
2374+ $ entity ->items ->exchangeArray (['iterator ' => 'modified ' ]);
2375+
2376+ $ this ->assertFalse ($ entity ->hasChanged ('items ' ));
2377+ }
2378+
2379+ public function testHasChangedPrefersToArrayOverDateTimeInterface (): void
2380+ {
2381+ $ entity = new class () extends Entity {
2382+ protected $ attributes = [
2383+ 'date ' => null ,
2384+ ];
2385+ };
2386+
2387+ $ entity ->date = new class ('2024-01-01 00:00:00 ' ) extends DateTime {
2388+ public function toArray (): array
2389+ {
2390+ return ['date ' => 'same ' ];
2391+ }
2392+ };
2393+ $ entity ->syncOriginal ();
2394+
2395+ $ entity ->date ->modify ('+1 day ' );
2396+
2397+ $ this ->assertFalse ($ entity ->hasChanged ('date ' ));
2398+ }
2399+
22952400 public function testHasChangedScalarOptimizationWithNullValues (): void
22962401 {
22972402 $ entity = new class () extends Entity {
0 commit comments