Skip to content

Commit 377c613

Browse files
committed
Add tests and cover more cases
1 parent e2ff6b3 commit 377c613

File tree

4 files changed

+215
-17
lines changed

4 files changed

+215
-17
lines changed

src/Symfony/Component/Yaml/Dumper.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ public function dump(mixed $input, int $inline = 0, int $indent = 0, int $flags
5757
if ($inline <= 0 || (!\is_array($input) && !$input instanceof TaggedValue && $dumpObjectAsInlineMap) || empty($input)) {
5858
$output .= $prefix.Inline::dump($input, $flags);
5959
} else {
60+
if (Yaml::DUMP_NUMERIC_KEY_AS_STRING & $flags) {
61+
$keyFlags = $flags;
62+
$valueFlags = $flags - Yaml::DUMP_NUMERIC_KEY_AS_STRING;
63+
} else {
64+
$keyFlags = $valueFlags = $flags;
65+
}
66+
6067
$dumpAsMap = Inline::isHash($input);
6168

6269
foreach ($input as $key => $value) {
@@ -77,7 +84,7 @@ public function dump(mixed $input, int $inline = 0, int $indent = 0, int $flags
7784
$blockChompingIndicator = '-';
7885
}
7986

80-
$output .= sprintf('%s%s%s |%s%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', '', $blockIndentationIndicator, $blockChompingIndicator);
87+
$output .= sprintf('%s%s%s |%s%s', $prefix, $dumpAsMap ? Inline::dump($key, $keyFlags).':' : '-', '', $blockIndentationIndicator, $blockChompingIndicator);
8188

8289
foreach (explode("\n", $value) as $row) {
8390
if ('' === $row) {
@@ -91,7 +98,7 @@ public function dump(mixed $input, int $inline = 0, int $indent = 0, int $flags
9198
}
9299

93100
if ($value instanceof TaggedValue) {
94-
$output .= sprintf('%s%s !%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', $value->getTag());
101+
$output .= sprintf('%s%s !%s', $prefix, $dumpAsMap ? Inline::dump($key, $keyFlags).':' : '-', $value->getTag());
95102

96103
if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && str_contains($value->getValue(), "\n") && !str_contains($value->getValue(), "\r\n")) {
97104
// If the first line starts with a space character, the spec requires a blockIndicationIndicator
@@ -107,7 +114,7 @@ public function dump(mixed $input, int $inline = 0, int $indent = 0, int $flags
107114
}
108115

109116
if ($inline - 1 <= 0 || null === $value->getValue() || \is_scalar($value->getValue())) {
110-
$output .= ' '.$this->dump($value->getValue(), $inline - 1, 0, $flags)."\n";
117+
$output .= ' '.$this->dump($value->getValue(), $inline - 1, 0, \is_int($value->getValue()) ? $valueFlags : $keyFlags)."\n";
111118
} else {
112119
$output .= "\n";
113120
$output .= $this->dump($value->getValue(), $inline - 1, $dumpAsMap ? $indent + $this->indentation : $indent + 2, $flags);
@@ -126,9 +133,9 @@ public function dump(mixed $input, int $inline = 0, int $indent = 0, int $flags
126133

127134
$output .= sprintf('%s%s%s%s',
128135
$prefix,
129-
$dumpAsMap ? Inline::dump($key, $flags).':' : '-',
136+
$dumpAsMap ? Inline::dump($key, $keyFlags).':' : '-',
130137
$willBeInlined ? ' ' : "\n",
131-
$this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $flags)
138+
$this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, \is_int($value) ? $valueFlags : $keyFlags)
132139
).($willBeInlined ? "\n" : '');
133140
}
134141
}

src/Symfony/Component/Yaml/Inline.php

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,16 +114,23 @@ public static function dump(mixed $value, int $flags = 0): string
114114
case $value instanceof \UnitEnum:
115115
return sprintf('!php/const %s::%s', $value::class, $value->name);
116116
case \is_object($value):
117+
if (Yaml::DUMP_NUMERIC_KEY_AS_STRING & $flags) {
118+
$keyFlags = $flags;
119+
$valueFlags = $flags - Yaml::DUMP_NUMERIC_KEY_AS_STRING;
120+
} else {
121+
$keyFlags = $valueFlags = $flags;
122+
}
123+
117124
if ($value instanceof TaggedValue) {
118-
return '!'.$value->getTag().' '.self::dump($value->getValue(), $flags);
125+
return '!'.$value->getTag().' '.self::dump($value->getValue(), $valueFlags);
119126
}
120127

121128
if (Yaml::DUMP_OBJECT & $flags) {
122129
return '!php/object '.self::dump(serialize($value));
123130
}
124131

125132
if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \stdClass || $value instanceof \ArrayObject)) {
126-
return self::dumpHashArray($value, $flags);
133+
return self::dumpHashArray($value, $keyFlags, $valueFlags);
127134
}
128135

129136
if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) {
@@ -220,30 +227,39 @@ public static function isHash(array|\ArrayObject|\stdClass $value): bool
220227
*/
221228
private static function dumpArray(array $value, int $flags): string
222229
{
230+
$numericKeysAsString = Yaml::DUMP_NUMERIC_KEY_AS_STRING & $flags;
231+
if ($numericKeysAsString) {
232+
$keyFlags = $flags;
233+
$valueFlags = $flags - Yaml::DUMP_NUMERIC_KEY_AS_STRING;
234+
} else {
235+
$keyFlags = $valueFlags = $flags;
236+
}
237+
223238
// array
224239
if (($value || Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE & $flags) && !self::isHash($value)) {
225240
$output = [];
226241
foreach ($value as $val) {
227-
$output[] = self::dump($val, $flags);
242+
$output[] = self::dump($val, $valueFlags);
228243
}
229244

230245
return sprintf('[%s]', implode(', ', $output));
231246
}
232247

233-
return self::dumpHashArray($value, $flags);
248+
return self::dumpHashArray($value, $keyFlags, $valueFlags);
234249
}
235250

236251
/**
237252
* Dumps hash array to a YAML string.
238253
*
239-
* @param array|\ArrayObject|\stdClass $value The hash array to dump
240-
* @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string
254+
* @param array|\ArrayObject|\stdClass $value The hash array to dump
255+
* @param int $keyFlags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string
256+
* @param int $valueFlags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string
241257
*/
242-
private static function dumpHashArray(array|\ArrayObject|\stdClass $value, int $flags): string
258+
private static function dumpHashArray(array|\ArrayObject|\stdClass $value, int $keyFlags, int $valueFlags): string
243259
{
244260
$output = [];
245261
foreach ($value as $key => $val) {
246-
$output[] = sprintf('%s: %s', self::dump($key, $flags), self::dump($val, $flags));
262+
$output[] = sprintf('%s: %s', self::dump($key, $keyFlags), self::dump($val, \is_int($val) ? $valueFlags : $keyFlags));
247263
}
248264

249265
return sprintf('{ %s }', implode(', ', $output));

src/Symfony/Component/Yaml/Tests/DumperTest.php

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -804,9 +804,67 @@ public function testDumpNullAsTilde()
804804
$this->assertSame('{ foo: ~ }', $this->dumper->dump(['foo' => null], 0, 0, Yaml::DUMP_NULL_AS_TILDE));
805805
}
806806

807-
public function testDumpNumericKeyAsString()
807+
/**
808+
* @dataProvider getNumericKeyData
809+
*/
810+
public function testDumpInlineNumericKeyAsString(array $input, bool $inline, int $flags, string $expected)
811+
{
812+
$this->assertSame($expected, $this->dumper->dump($input, $inline ? 0 : 4, 0, $flags));
813+
}
814+
815+
public function getNumericKeyData()
808816
{
809-
$this->assertSame("{ '200': foo }", $this->dumper->dump([200 => 'foo'], 0, 0, Yaml::DUMP_NUMERIC_KEY_AS_STRING));
817+
yield 'Int key with flag ineline' => [
818+
[200 => 'foo'],
819+
true,
820+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
821+
"{ '200': foo }",
822+
];
823+
824+
yield 'Int key without flag ineline' => [
825+
[200 => 'foo'],
826+
true,
827+
0,
828+
'{ 200: foo }',
829+
];
830+
831+
$expected = <<<YAML
832+
'200': foo
833+
834+
YAML;
835+
836+
yield 'Int key with flag' => [
837+
[200 => 'foo'],
838+
false,
839+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
840+
$expected,
841+
];
842+
843+
$expected = <<<YAML
844+
200: foo
845+
846+
YAML;
847+
848+
yield 'Int key without flag' => [
849+
[200 => 'foo'],
850+
false,
851+
0,
852+
$expected,
853+
];
854+
855+
$expected = <<<YAML
856+
count: !number 5
857+
858+
YAML;
859+
860+
yield 'Int tagged value with flag' => [
861+
[
862+
'count' => new TaggedValue('number', 5),
863+
],
864+
false,
865+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
866+
$expected,
867+
];
810868
}
811869

812870
public function testDumpIdeographicSpaces()

src/Symfony/Component/Yaml/Tests/InlineTest.php

Lines changed: 119 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -617,9 +617,126 @@ public function testDumpDateTime($dateTime, $expected)
617617
$this->assertSame($expected, Inline::dump($dateTime));
618618
}
619619

620-
public function testDumpNumericKeyAsString()
620+
/**
621+
* @dataProvider getNumericKeyData
622+
*/
623+
public function testDumpNumericKeyAsString(array|int $input, int $flags, string $expected)
624+
{
625+
$this->assertSame($expected, Inline::dump($input, $flags));
626+
}
627+
628+
public function getNumericKeyData()
621629
{
622-
$this->assertSame("'200'", Inline::dump(200, Yaml::DUMP_NUMERIC_KEY_AS_STRING));
630+
yield 'Int with flag' => [
631+
200,
632+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
633+
"'200'",
634+
];
635+
636+
yield 'Int without flag' => [
637+
200,
638+
0,
639+
'200',
640+
];
641+
642+
yield 'Int key with flag' => [
643+
[200 => 'foo'],
644+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
645+
"{ '200': foo }",
646+
];
647+
648+
yield 'String key with flag' => [
649+
['200' => 'foo'],
650+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
651+
"{ '200': foo }",
652+
];
653+
654+
yield 'Float key with flag' => [
655+
[3.4 => 'foo'],
656+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
657+
"{ '3': foo }",
658+
];
659+
660+
yield 'Bool key with flag' => [
661+
[true => 'foo'],
662+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
663+
"{ '1': foo }",
664+
];
665+
666+
yield 'null key with flag' => [
667+
[null => 'foo'],
668+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
669+
"{ '': foo }",
670+
];
671+
672+
yield 'Int key without flag' => [
673+
[200 => 'foo'],
674+
0,
675+
'{ 200: foo }',
676+
];
677+
678+
yield 'Int value with flag' => [
679+
[200 => 200],
680+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
681+
"{ '200': 200 }",
682+
];
683+
684+
yield 'Mixed with flag' => [
685+
[42 => 'a', 'b' => 'c', 'd' => 43],
686+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
687+
"{ '42': a, b: c, d: 43 }",
688+
];
689+
690+
yield 'Auto-index with flag' => [
691+
['a', 'b', 42],
692+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
693+
'[a, b, 42]',
694+
];
695+
696+
yield 'Complex mixed array with flag' => [
697+
[
698+
42 => [
699+
'foo' => 43,
700+
44 => 'bar',
701+
],
702+
45 => 'baz',
703+
46,
704+
],
705+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
706+
"{ '42': { foo: 43, '44': bar }, '45': baz, '46': 46 }",
707+
];
708+
709+
yield 'Int tagged value with flag' => [
710+
[
711+
'count' => new TaggedValue('number', 5),
712+
],
713+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
714+
'{ count: !number 5 }',
715+
];
716+
717+
yield 'Array tagged value with flag' => [
718+
[
719+
'user' => new TaggedValue('metadata', [
720+
'john',
721+
42,
722+
]),
723+
],
724+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
725+
'{ user: !metadata [john, 42] }',
726+
];
727+
728+
$arrayObject = new \ArrayObject();
729+
$arrayObject['foo'] = 'bar';
730+
$arrayObject[42] = 'baz';
731+
$arrayObject['baz'] = 43;
732+
733+
yield 'Object value with flag' => [
734+
[
735+
'user' => $arrayObject,
736+
],
737+
Yaml::DUMP_NUMERIC_KEY_AS_STRING | Yaml::DUMP_OBJECT_AS_MAP,
738+
"{ user: { foo: bar, '42': baz, baz: 43 } }",
739+
];
623740
}
624741

625742
public function testDumpUnitEnum()

0 commit comments

Comments
 (0)