Skip to content

Commit f11cdff

Browse files
committed
Add support for stdClass empty and annotated object handling in Stringifier
1 parent aef989c commit f11cdff

2 files changed

Lines changed: 58 additions & 2 deletions

File tree

src/Stringifier.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ public static function stringify(mixed $value): string
2626
}
2727
return $leading . self::stringifyObject($value, 0, $annotated);
2828
}
29+
if ($value instanceof \stdClass) {
30+
return $leading . self::stringifyObject((array) $value, 0, $annotated);
31+
}
2932
if ($annotated !== null) {
3033
foreach ($annotated->danglingComments as $c) {
3134
$dangling .= "\n" . '#' . $c;
@@ -66,6 +69,9 @@ private static function doStringify(mixed $value, int $level): string
6669
}
6770
return self::stringifyObject($value, $level, $annotated);
6871
}
72+
if ($value instanceof \stdClass) {
73+
return self::stringifyObject((array) $value, $level, $annotated);
74+
}
6975
throw new \InvalidArgumentException('Unsupported value type: ' . get_debug_type($value));
7076
}
7177

@@ -100,7 +106,7 @@ private static function stringifyArray(array $arr, int $level, ?Annotated $annot
100106
}
101107
}
102108
$out .= $childIndent . self::doStringify($arr[$i], $level + 1);
103-
if ($elAnnotated !== null && $elAnnotated->trailingComment !== null && !is_array($innerValue)) {
109+
if ($elAnnotated !== null && $elAnnotated->trailingComment !== null && !is_array($innerValue) && !$innerValue instanceof \stdClass) {
104110
$out .= ' #' . $elAnnotated->trailingComment;
105111
}
106112
}
@@ -123,6 +129,9 @@ private static function stringifyObject(array $obj, int $level, ?Annotated $anno
123129
{
124130
$keys = array_keys($obj);
125131
$hasDangling = $annotated !== null && count($annotated->danglingComments) > 0;
132+
if (count($keys) === 0 && !$hasDangling) {
133+
return '{}';
134+
}
126135
$childIndent = self::getIndent($level + 1);
127136
$parentIndent = self::getIndent($level);
128137
$out = "{\n";
@@ -146,7 +155,7 @@ private static function stringifyObject(array $obj, int $level, ?Annotated $anno
146155
}
147156
}
148157
$out .= $childIndent . self::stringifyKey($key) . ': ' . self::doStringify($obj[$key], $level + 1);
149-
if ($elAnnotated !== null && $elAnnotated->trailingComment !== null && !is_array($innerValue)) {
158+
if ($elAnnotated !== null && $elAnnotated->trailingComment !== null && !is_array($innerValue) && !$innerValue instanceof \stdClass) {
150159
$out .= ' #' . $elAnnotated->trailingComment;
151160
}
152161
}

tests/StringifierTest.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,53 @@ public function testCombinedAnnotations(): void
319319
$this->assertSame($expected, Maml::stringify($data));
320320
}
321321

322+
// --- stdClass (empty object) tests ---
323+
324+
public function testEmptyStdClass(): void
325+
{
326+
$this->assertSame('{}', Maml::stringify(new \stdClass()));
327+
}
328+
329+
public function testEmptyObjectCast(): void
330+
{
331+
$this->assertSame('{}', Maml::stringify((object) []));
332+
}
333+
334+
public function testStdClassWithProperties(): void
335+
{
336+
$data = (object) ['name' => 'test', 'count' => 3];
337+
$expected = "{\n name: \"test\"\n count: 3\n}";
338+
$this->assertSame($expected, Maml::stringify($data));
339+
}
340+
341+
public function testNestedEmptyObject(): void
342+
{
343+
$data = ['config' => new \stdClass()];
344+
$expected = "{\n config: {}\n}";
345+
$this->assertSame($expected, Maml::stringify($data));
346+
}
347+
348+
public function testEmptyObjectInArray(): void
349+
{
350+
$data = [new \stdClass(), new \stdClass()];
351+
$expected = "[\n {}\n {}\n]";
352+
$this->assertSame($expected, Maml::stringify($data));
353+
}
354+
355+
public function testAnnotatedEmptyObjectWithDanglingComment(): void
356+
{
357+
$data = ['plugins' => Annotated::with(new \stdClass())->danglingComment(' Add here')];
358+
$expected = "{\n plugins: {\n # Add here\n }\n}";
359+
$this->assertSame($expected, Maml::stringify($data));
360+
}
361+
362+
public function testTrailingCommentOnStdClassIsIgnored(): void
363+
{
364+
$data = ['x' => Annotated::with(new \stdClass())->trailingComment(' ignored')];
365+
$expected = "{\n x: {}\n}";
366+
$this->assertSame($expected, Maml::stringify($data));
367+
}
368+
322369
public function testDocumentWithLeadingAndDanglingComments(): void
323370
{
324371
$data = Annotated::with([

0 commit comments

Comments
 (0)