Skip to content

Commit 9bf8be2

Browse files
feat: Serialize Enum variants with the variant name
With enum types it's almost always useful to know exactly which variant is being logged. But the current serializers don't differentiate between enums and objects. This changes the serializers to add the variant name of the enum that is being serialized.
1 parent 5fc99eb commit 9bf8be2

5 files changed

Lines changed: 124 additions & 0 deletions

File tree

phpunit.xml.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<testsuites>
1515
<testsuite name="unit">
1616
<directory>tests</directory>
17+
<directory phpVersion="8.1">tests/Php81</directory>
1718
<directory suffix=".phpt">tests/phpt</directory>
1819
</testsuite>
1920

src/Serializer/AbstractSerializer.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,12 @@ protected function serializeValue($value)
241241
return $value;
242242
}
243243

244+
if ($value instanceof \UnitEnum) {
245+
$reflection = new \ReflectionObject($value);
246+
247+
return 'Enum ' . $reflection->getName() . '::' . $value->name;
248+
}
249+
244250
if (\is_object($value)) {
245251
$reflection = new \ReflectionObject($value);
246252

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sentry\Tests\Php81\Serializer;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use Sentry\Serializer\AbstractSerializer;
9+
use Sentry\Serializer\RepresentationSerializerInterface;
10+
use Sentry\Serializer\SerializerInterface;
11+
12+
abstract class AbstractSerializerTest extends TestCase
13+
{
14+
abstract protected function createSerializer(): AbstractSerializer;
15+
16+
/**
17+
* This method is only existed because of testSerializeCallable.
18+
*/
19+
public static function setUpBeforeClass(): void
20+
{
21+
}
22+
23+
public static function serializeAllObjectsDataProvider(): array
24+
{
25+
return [
26+
['serializeAllObjects' => false],
27+
['serializeAllObjects' => true],
28+
];
29+
}
30+
31+
public function testEnumsAreNames(): void
32+
{
33+
$serializer = $this->createSerializer();
34+
$input = SerializerTestEnum::CASE_NAME;
35+
$result = $this->invokeSerialization($serializer, $input);
36+
37+
$this->assertSame('Enum Sentry\Tests\Php81\Serializer\SerializerTestEnum::CASE_NAME', $result);
38+
}
39+
40+
public function testEnumInArray(): void
41+
{
42+
$serializer = $this->createSerializer();
43+
$input = ['foo' => SerializerTestEnum::CASE_NAME];
44+
45+
$result = $this->invokeSerialization($serializer, $input);
46+
47+
$this->assertSame(['foo' => 'Enum ' . SerializerTestEnum::class . '::' . SerializerTestEnum::CASE_NAME->name], $result);
48+
}
49+
50+
public static function serializationForBadStringsDataProvider(): array
51+
{
52+
$utf8String = 'äöü';
53+
54+
return [
55+
[mb_convert_encoding($utf8String, 'ISO-8859-1', 'UTF-8'), $utf8String, 'ISO-8859-1, ASCII, UTF-8'],
56+
["\xC2\xA2\xC2", "\xC2\xA2\x3F"], // ill-formed 2-byte character U+00A2 (CENT SIGN)
57+
];
58+
}
59+
60+
protected function invokeSerialization(AbstractSerializer $serializer, $input)
61+
{
62+
if ($serializer instanceof SerializerInterface) {
63+
return $serializer->serialize($input);
64+
}
65+
66+
if ($serializer instanceof RepresentationSerializerInterface) {
67+
return $serializer->representationSerialize($input);
68+
}
69+
70+
throw new \InvalidArgumentException('Unrecognized AbstractSerializer: ' . \get_class($serializer));
71+
}
72+
}
73+
74+
enum SerializerTestEnum
75+
{
76+
case CASE_NAME;
77+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sentry\Tests\Php81\Serializer;
6+
7+
use Sentry\Options;
8+
use Sentry\Serializer\AbstractSerializer;
9+
use Sentry\Serializer\RepresentationSerializer;
10+
11+
final class RepresentationSerializerTest extends AbstractSerializerTest
12+
{
13+
/**
14+
* @return RepresentationSerializer
15+
*/
16+
protected function createSerializer(): AbstractSerializer
17+
{
18+
return new RepresentationSerializer(new Options());
19+
}
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sentry\Tests\Php81\Serializer;
6+
7+
use Sentry\Options;
8+
use Sentry\Serializer\AbstractSerializer;
9+
use Sentry\Serializer\Serializer;
10+
11+
final class SerializerTest extends AbstractSerializerTest
12+
{
13+
/**
14+
* @return Serializer
15+
*/
16+
protected function createSerializer(?Options $options = null): AbstractSerializer
17+
{
18+
return new Serializer($options ?? new Options());
19+
}
20+
}

0 commit comments

Comments
 (0)