Skip to content

Commit

Permalink
Merge pull request #55 from MauricioFauth/enum-fix
Browse files Browse the repository at this point in the history
Fix error when unserializing enums
  • Loading branch information
jrbasso authored Sep 25, 2023
2 parents 8e72a3f + 3a0927d commit 9378616
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/JsonSerializer/JsonSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,9 @@ protected function unserializeObject($value)
}

if (is_subclass_of($className, \UnitEnum::class)) {
return constant("$className::{$value['name']}");
$obj = constant("$className::{$value['name']}");
$this->objectMapping[$this->objectMappingIndex++] = $obj;
return $obj;
}

if (!$this->isSplList($className)) {
Expand Down
58 changes: 58 additions & 0 deletions tests/JsonSerializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,33 @@ public function testSerializeEnums()
$backedEnum = SupportEnums\MyBackedEnum::Hearts;
$expected = '{"@type":"Zumba\\\\JsonSerializer\\\\Test\\\\SupportEnums\\\\MyBackedEnum","name":"Hearts","value":"H"}';
$this->assertSame($expected, $this->serializer->serialize($backedEnum));

$intBackedEnum = SupportEnums\MyIntBackedEnum::One;
$expected = '{"@type":"Zumba\\\\JsonSerializer\\\\Test\\\\SupportEnums\\\\MyIntBackedEnum","name":"One","value":1}';
$this->assertSame($expected, $this->serializer->serialize($intBackedEnum));
}

/**
* Test serialization of multiple Enums
*
* @return void
*/
public function testSerializeMultipleEnums()
{
if (PHP_VERSION_ID < 80100) {
$this->markTestSkipped("Enums are only available since PHP 8.1");
}

$obj = new stdClass();
$obj->enum1 = SupportEnums\MyUnitEnum::Hearts;
$obj->enum2 = SupportEnums\MyBackedEnum::Hearts;
$obj->enum3 = SupportEnums\MyIntBackedEnum::One;
$obj->enum4 = SupportEnums\MyUnitEnum::Hearts;
$obj->enum5 = SupportEnums\MyBackedEnum::Hearts;
$obj->enum6 = SupportEnums\MyIntBackedEnum::One;

$expected = '{"@type":"stdClass","enum1":{"@type":"Zumba\\\\JsonSerializer\\\\Test\\\\SupportEnums\\\\MyUnitEnum","name":"Hearts"},"enum2":{"@type":"Zumba\\\\JsonSerializer\\\\Test\\\\SupportEnums\\\\MyBackedEnum","name":"Hearts","value":"H"},"enum3":{"@type":"Zumba\\\\JsonSerializer\\\\Test\\\\SupportEnums\\\\MyIntBackedEnum","name":"One","value":1},"enum4":{"@type":"@1"},"enum5":{"@type":"@2"},"enum6":{"@type":"@3"}}';
$this->assertSame($expected, $this->serializer->serialize($obj));
}

/**
Expand All @@ -279,6 +306,12 @@ public function testUnserializeEnums()
$this->assertInstanceOf('Zumba\JsonSerializer\Test\SupportEnums\MyBackedEnum', $obj);
$this->assertSame(SupportEnums\MyBackedEnum::Hearts, $obj);

$serialized = '{"@type":"Zumba\\\\JsonSerializer\\\\Test\\\\SupportEnums\\\\MyIntBackedEnum","name":"Two","value":2}';
$obj = $this->serializer->unserialize($serialized);
$this->assertInstanceOf('Zumba\JsonSerializer\Test\SupportEnums\MyIntBackedEnum', $obj);
$this->assertSame(SupportEnums\MyIntBackedEnum::Two, $obj);
$this->assertSame(SupportEnums\MyIntBackedEnum::Two->value, $obj->value);

// wrong value of BackedEnum is ignored
$serialized = '{"@type":"Zumba\\\\JsonSerializer\\\\Test\\\\SupportEnums\\\\MyBackedEnum","name":"Hearts","value":"S"}';
$obj = $this->serializer->unserialize($serialized);
Expand All @@ -287,6 +320,31 @@ public function testUnserializeEnums()
$this->assertSame(SupportEnums\MyBackedEnum::Hearts->value, $obj->value);
}

/**
* Test unserialization of multiple Enums
*
* @return void
*/
public function testUnserializeMultipleEnums()
{
if (PHP_VERSION_ID < 80100) {
$this->markTestSkipped("Enums are only available since PHP 8.1");
}

$obj = new stdClass();
$obj->enum1 = SupportEnums\MyUnitEnum::Hearts;
$obj->enum2 = SupportEnums\MyBackedEnum::Hearts;
$obj->enum3 = SupportEnums\MyIntBackedEnum::One;
$obj->enum4 = SupportEnums\MyUnitEnum::Hearts;
$obj->enum5 = SupportEnums\MyBackedEnum::Hearts;
$obj->enum6 = SupportEnums\MyIntBackedEnum::One;

$serialized = '{"@type":"stdClass","enum1":{"@type":"Zumba\\\\JsonSerializer\\\\Test\\\\SupportEnums\\\\MyUnitEnum","name":"Hearts"},"enum2":{"@type":"Zumba\\\\JsonSerializer\\\\Test\\\\SupportEnums\\\\MyBackedEnum","name":"Hearts","value":"H"},"enum3":{"@type":"Zumba\\\\JsonSerializer\\\\Test\\\\SupportEnums\\\\MyIntBackedEnum","name":"One","value":1},"enum4":{"@type":"@1"},"enum5":{"@type":"@2"},"enum6":{"@type":"@3"}}';
$actualObj = $this->serializer->unserialize($serialized);
$this->assertInstanceOf('stdClass', $actualObj);
$this->assertEquals($obj, $actualObj);
}

/**
* Test unserialization of wrong UnitEnum
*
Expand Down
9 changes: 9 additions & 0 deletions tests/SupportEnums/MyIntBackedEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace Zumba\JsonSerializer\Test\SupportEnums;

enum MyIntBackedEnum: int
{
case One = 1;
case Two = 2;
}

0 comments on commit 9378616

Please sign in to comment.