From 2119c40bbd1f3d6ec030befaafdd97e418cbc6e0 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Wed, 10 Nov 2021 10:43:47 +0000 Subject: [PATCH 1/2] Fixes serialize enum objects --- src/Serializers/Native.php | 7 +++ tests/ReflectionClosurePhp81Test.php | 49 ++++++++++++--- tests/SerializerPhp81Test.php | 89 +++++++++++++++++++++++++--- 3 files changed, 131 insertions(+), 14 deletions(-) diff --git a/src/Serializers/Native.php b/src/Serializers/Native.php index 95916681..cd69f0af 100644 --- a/src/Serializers/Native.php +++ b/src/Serializers/Native.php @@ -458,6 +458,13 @@ protected function mapByReference(&$data) } $instance = $data; + + if (function_exists('enum_exists') && enum_exists(get_class($data))) { + $this->scope[$instance] = $data; + + return; + } + $reflection = new ReflectionObject($data); if (! $reflection->isUserDefined()) { diff --git a/tests/ReflectionClosurePhp81Test.php b/tests/ReflectionClosurePhp81Test.php index cebb0c1c..8ed3dd07 100644 --- a/tests/ReflectionClosurePhp81Test.php +++ b/tests/ReflectionClosurePhp81Test.php @@ -3,35 +3,70 @@ use Foo\Baz\Qux\Forest; use Some\ClassName as ClassAlias; -enum GlobalEnum: string { +enum GlobalEnum { + case Admin; + case Guest; + case Moderator; +} + +test('enums', function () { + $f = function (GlobalEnum $role) { + return $role; + }; + + $e = 'function (\GlobalEnum $role) { + return $role; + }'; + + expect($f)->toBeCode($e); + + enum ScopedEnum { + case Admin; + case Guest; + case Moderator; + } + + $f = function (ScopedEnum $role) { + return $role; + }; + + $e = 'function (\ScopedEnum $role) { + return $role; + }'; + + expect($f)->toBeCode($e); +}); + + +enum GlobalBackedEnum: string { case Admin = 'Administrator'; case Guest = 'Guest'; case Moderator = 'Moderator'; } -test('enums', function () { +test('backed enums', function () { - $f = function (GlobalEnum $role) { + $f = function (GlobalBackedEnum $role) { return $role; }; - $e = 'function (\GlobalEnum $role) { + $e = 'function (\GlobalBackedEnum $role) { return $role; }'; expect($f)->toBeCode($e); - enum ScopedEnum: string { + enum ScopedBackedEnum: string { case Admin = 'Administrator'; case Guest = 'Guest'; case Moderator = 'Moderator'; } - $f = function (ScopedEnum $role) { + $f = function (ScopedBackedEnum $role) { return $role; }; - $e = 'function (\ScopedEnum $role) { + $e = 'function (\ScopedBackedEnum $role) { return $role; }'; diff --git a/tests/SerializerPhp81Test.php b/tests/SerializerPhp81Test.php index ec3bb6b1..77cd17a1 100644 --- a/tests/SerializerPhp81Test.php +++ b/tests/SerializerPhp81Test.php @@ -1,9 +1,9 @@ toBe(SerializerGlobalEnum::Admin); + if (! enum_exists(SerializerScopedEnum::class)) { - enum SerializerScopedEnum: string { + enum SerializerScopedEnum { + case Admin; + case Guest; + case Moderator; + } + } + + $f = function () { + return SerializerScopedEnum::Admin; + }; + + $f = s($f); + + expect($f()->name)->toBe('Admin'); + + $role = SerializerScopedEnum::Admin; + + $f = function () use ($role) { + return $role; + }; + + $f = s($f); + + expect($f())->toBe(SerializerScopedEnum::Admin); +})->with('serializers'); + +enum SerializerGlobalBackedEnum: string { + case Admin = 'Administrator'; + case Guest = 'Guest'; + case Moderator = 'Moderator'; +} + +test('backed enums', function () { + $f = function (SerializerGlobalBackedEnum $role) { + return $role; + }; + + $f = s($f); + + expect($f(SerializerGlobalBackedEnum::Guest))->toBe( + SerializerGlobalBackedEnum::Guest + ); + + $role = SerializerGlobalBackedEnum::Admin; + + $f = function () use ($role) { + return $role; + }; + + $f = s($f); + + expect($f())->toBe(SerializerGlobalBackedEnum::Admin); + + if (! enum_exists(SerializerScopedBackedEnum::class)) { + enum SerializerScopedBackedEnum: string { case Admin = 'Administrator'; case Guest = 'Guest'; case Moderator = 'Moderator'; @@ -26,12 +90,23 @@ enum SerializerScopedEnum: string { } $f = function () { - return SerializerScopedEnum::Admin; + return SerializerScopedBackedEnum::Admin; + }; + + $f = s($f); + + expect($f())->name->toBe('Admin') + ->value->toBe('Administrator'); + + $role = SerializerScopedBackedEnum::Admin; + + $f = function () use ($role) { + return $role; }; $f = s($f); - expect($f()->value)->toBe('Administrator'); + expect($f())->toBe(SerializerScopedBackedEnum::Admin); })->with('serializers'); test('array unpacking', function () { From 8c1c235233ae105fdfce4d23157d430841b5f815 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Wed, 10 Nov 2021 12:33:52 +0000 Subject: [PATCH 2/2] Improves enum checker --- src/Serializers/Native.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Serializers/Native.php b/src/Serializers/Native.php index cd69f0af..169c56d2 100644 --- a/src/Serializers/Native.php +++ b/src/Serializers/Native.php @@ -10,6 +10,7 @@ use Laravel\SerializableClosure\Support\ReflectionClosure; use Laravel\SerializableClosure\Support\SelfReference; use ReflectionObject; +use UnitEnum; class Native implements Serializable { @@ -459,7 +460,7 @@ protected function mapByReference(&$data) $instance = $data; - if (function_exists('enum_exists') && enum_exists(get_class($data))) { + if ($data instanceof UnitEnum) { $this->scope[$instance] = $data; return;