Skip to content

Commit b2f1eff

Browse files
committed
Change how to stringify JsonSerializable objects
We can only convert those objects into JSON via the `jsonSerialize()` method. Being more descriptive that the JSON we see is the result of that method will make it more straightforward. Besides that, it's better to directly use a stringifier that converts data to JSON instead of calling the whole stringifier cluster to stringify the result of `jsonSerialize()`. Signed-off-by: Henrique Moody <[email protected]>
1 parent 71187af commit b2f1eff

File tree

8 files changed

+73
-87
lines changed

8 files changed

+73
-87
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
},
3434
"autoload-dev": {
3535
"psr-4": {
36+
"": "tests/fixtures/",
3637
"Respect\\Stringifier\\Test\\": "tests/src/",
3738
"Respect\\Stringifier\\Test\\Unit\\": "tests/unit"
3839
},

phpcs.xml.dist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,8 @@
1313
<file>tests/</file>
1414

1515
<rule ref="Respect" />
16+
17+
<rule ref="PSR1.Classes.ClassDeclaration.MissingNamespace">
18+
<exclude-pattern>tests/fixtures/</exclude-pattern>
19+
</rule>
1620
</ruleset>

src/Stringifiers/ClusterStringifier.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,23 @@ public static function createDefault(): self
3737
$quoter = new CodeQuoter();
3838

3939
$stringifier = new self();
40+
41+
$jsonParsableStringifier = new JsonParsableStringifier();
42+
4043
$stringifier->setStringifiers([
4144
new TraversableStringifier($stringifier, $quoter),
4245
new DateTimeStringifier($quoter, DateTimeInterface::ATOM),
4346
new ThrowableStringifier($stringifier, $quoter),
4447
new StringableObjectStringifier($stringifier),
45-
new JsonSerializableStringifier($stringifier, $quoter),
48+
new JsonSerializableObjectStringifier($jsonParsableStringifier, $quoter),
4649
new ObjectStringifier($stringifier, $quoter),
4750
new ArrayStringifier($stringifier, $quoter, self::MAXIMUM_DEPTH, self::MAXIMUM_NUMBER_OF_ITEMS),
4851
new InfiniteStringifier($quoter),
4952
new NanStringifier($quoter),
5053
new ResourceStringifier($quoter),
5154
new BoolStringifier($quoter),
5255
new NullStringifier($quoter),
53-
new JsonParsableStringifier(),
56+
$jsonParsableStringifier,
5457
]);
5558

5659
return $stringifier;

src/Stringifiers/JsonSerializableStringifier.php renamed to src/Stringifiers/JsonSerializableObjectStringifier.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
use function sprintf;
1818

19-
final class JsonSerializableStringifier implements Stringifier
19+
final class JsonSerializableObjectStringifier implements Stringifier
2020
{
2121
public function __construct(
2222
private readonly Stringifier $stringifier,
@@ -32,7 +32,7 @@ public function stringify(mixed $raw, int $depth): ?string
3232

3333
return $this->quoter->quote(
3434
sprintf(
35-
'[json-serializable] (%s: %s)',
35+
'%s { jsonSerialize() => %s }',
3636
$raw::class,
3737
$this->stringifier->stringify($raw->jsonSerialize(), $depth + 1)
3838
),

tests/src/MyJsonSerializable.php renamed to tests/fixtures/ConcreteJsonSerializable.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,12 @@
88

99
declare(strict_types=1);
1010

11-
namespace Respect\Stringifier\Test;
12-
13-
use JsonSerializable;
14-
15-
final class MyJsonSerializable implements JsonSerializable
11+
final class ConcreteJsonSerializable implements JsonSerializable
1612
{
17-
public const JSON_VALUE = [1, 2, 3];
13+
public const JSON_VALUE = [1, 2, 3, 'foo' => true];
1814

1915
/**
20-
* @return int[]
16+
* @return array<mixed, mixed>
2117
*/
2218
public function jsonSerialize(): array
2319
{

tests/integration/stringify-object-jsonSerializable.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ declare(strict_types=1);
55

66
require 'vendor/autoload.php';
77

8-
output(new Respect\Stringifier\Test\MyJsonSerializable());
8+
output(new ConcreteJsonSerializable());
99
?>
1010
--EXPECT--
11-
`[json-serializable] (Respect\Stringifier\Test\MyJsonSerializable: [1, 2, 3])`
11+
`ConcreteJsonSerializable { jsonSerialize() => {"0":1,"1":2,"2":3,"foo":true} }`
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
/*
4+
* This file is part of Respect/Stringifier.
5+
* Copyright (c) Henrique Moody <[email protected]>
6+
* SPDX-License-Identifier: MIT
7+
*/
8+
9+
declare(strict_types=1);
10+
11+
namespace Respect\Stringifier\Test\Unit\Stringifiers;
12+
13+
use ConcreteJsonSerializable;
14+
use PHPUnit\Framework\Attributes\CoversClass;
15+
use PHPUnit\Framework\Attributes\Test;
16+
use PHPUnit\Framework\TestCase;
17+
use Respect\Stringifier\Stringifiers\JsonSerializableObjectStringifier;
18+
use Respect\Stringifier\Test\Double\FakeQuoter;
19+
use Respect\Stringifier\Test\Double\FakeStringifier;
20+
use stdClass;
21+
22+
use function sprintf;
23+
24+
#[CoversClass(JsonSerializableObjectStringifier::class)]
25+
final class JsonSerializableObjectStringifierTest extends TestCase
26+
{
27+
private const DEPTH = 0;
28+
29+
#[Test]
30+
public function itShouldNotStringifyRawValueWhenItIsNotAnInstanceOfJsonSerializable(): void
31+
{
32+
$sut = new JsonSerializableObjectStringifier(new FakeStringifier(), new FakeQuoter());
33+
34+
self::assertNull($sut->stringify(new stdClass(), self::DEPTH));
35+
}
36+
37+
#[Test]
38+
public function itShouldStringifyRawValueWhenItIsAnInstanceOfJsonSerializable(): void
39+
{
40+
$raw = new ConcreteJsonSerializable();
41+
42+
$stringifier = new FakeStringifier();
43+
$quoter = new FakeQuoter();
44+
45+
$jsonString = $stringifier->stringify($raw->jsonSerialize(), self::DEPTH + 1);
46+
47+
$sut = new JsonSerializableObjectStringifier($stringifier, $quoter);
48+
$actual = $sut->stringify($raw, self::DEPTH);
49+
$expected = $quoter->quote(
50+
sprintf('%s { jsonSerialize() => %s }', ConcreteJsonSerializable::class, $jsonString),
51+
self::DEPTH
52+
);
53+
54+
self::assertSame($expected, $actual);
55+
}
56+
}

tests/unit/Stringifiers/JsonSerializableStringifierTest.php

Lines changed: 0 additions & 74 deletions
This file was deleted.

0 commit comments

Comments
 (0)