Skip to content

Commit

Permalink
respect inline level when dumping objects as maps
Browse files Browse the repository at this point in the history
  • Loading branch information
xabbuh committed Apr 13, 2017
1 parent 4f5c149 commit 3cca48c
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 27 deletions.
21 changes: 16 additions & 5 deletions src/Symfony/Component/Yaml/Dumper.php
Expand Up @@ -81,15 +81,20 @@ public function dump($input, $inline = 0, $indent = 0, $flags = 0)

$output = '';
$prefix = $indent ? str_repeat(' ', $indent) : '';
$dumpObjectAsInlineMap = true;

if ($inline <= 0 || !is_array($input) || empty($input)) {
if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($input instanceof \ArrayObject || $input instanceof \stdClass)) {
$dumpObjectAsInlineMap = empty((array) $input);
}

if ($inline <= 0 || (!is_array($input) && $dumpObjectAsInlineMap) || empty($input)) {
$output .= $prefix.Inline::dump($input, $flags);
} else {
$isAHash = Inline::isHash($input);
$dumpAsMap = Inline::isHash($input);

foreach ($input as $key => $value) {
if ($inline >= 1 && Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && is_string($value) && false !== strpos($value, "\n")) {
$output .= sprintf("%s%s%s |\n", $prefix, $isAHash ? Inline::dump($key, $flags).':' : '-', '');
$output .= sprintf("%s%s%s |\n", $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', '');

foreach (preg_split('/\n|\r\n/', $value) as $row) {
$output .= sprintf("%s%s%s\n", $prefix, str_repeat(' ', $this->indentation), $row);
Expand All @@ -98,11 +103,17 @@ public function dump($input, $inline = 0, $indent = 0, $flags = 0)
continue;
}

$willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value);
$dumpObjectAsInlineMap = true;

if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) {
$dumpObjectAsInlineMap = empty((array) $value);
}

$willBeInlined = $inline - 1 <= 0 || !is_array($value) && $dumpObjectAsInlineMap || empty($value);

$output .= sprintf('%s%s%s%s',
$prefix,
$isAHash ? Inline::dump($key, $flags).':' : '-',
$dumpAsMap ? Inline::dump($key, $flags).':' : '-',
$willBeInlined ? ' ' : "\n",
$this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $flags)
).($willBeInlined ? "\n" : '');
Expand Down
10 changes: 7 additions & 3 deletions src/Symfony/Component/Yaml/Inline.php
Expand Up @@ -164,7 +164,7 @@ public static function dump($value, $flags = 0)
}

if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \stdClass || $value instanceof \ArrayObject)) {
return self::dumpArray((array) $value, $flags);
return self::dumpArray($value, $flags);
}

if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) {
Expand Down Expand Up @@ -224,12 +224,16 @@ public static function dump($value, $flags = 0)
*
* @internal
*
* @param array $value The PHP array to check
* @param array|\ArrayObject|\stdClass $value The PHP array or array-like object to check
*
* @return bool true if value is hash array, false otherwise
*/
public static function isHash(array $value)
public static function isHash($value)
{
if ($value instanceof \stdClass || $value instanceof \ArrayObject) {
return true;
}

$expectedKey = 0;

foreach ($value as $key => $val) {
Expand Down
106 changes: 87 additions & 19 deletions src/Symfony/Component/Yaml/Tests/DumperTest.php
Expand Up @@ -206,25 +206,6 @@ public function testInlineLevel()
$this->assertEquals($expected, $this->dumper->dump($this->array, 10), '->dump() takes an inline level argument');
}

public function testArrayObjectAsMapNotInLined()
{
$deep = new \ArrayObject(array('deep1' => 'd', 'deep2' => 'e'));
$inner = new \ArrayObject(array('inner1' => 'b', 'inner2' => 'c', 'inner3' => $deep));
$outer = new \ArrayObject(array('outer1' => 'a', 'outer1' => $inner));

$yaml = $this->dumper->dump($outer, 2, 0, Yaml::DUMP_OBJECT_AS_MAP);

$expected = <<<YAML
outer1: a
outer2:
inner1: b
inner2: c
inner3: { deep1: d, deep2: e }
YAML;
$this->assertEquals($expected, $yaml);
}

public function testObjectSupportEnabled()
{
$dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, Yaml::DUMP_OBJECT);
Expand Down Expand Up @@ -352,6 +333,93 @@ public function objectAsMapProvider()
return $tests;
}

public function testDumpingArrayObjectInstancesRespectsInlineLevel()
{
$deep = new \ArrayObject(array('deep1' => 'd', 'deep2' => 'e'));
$inner = new \ArrayObject(array('inner1' => 'b', 'inner2' => 'c', 'inner3' => $deep));
$outer = new \ArrayObject(array('outer1' => 'a', 'outer2' => $inner));

$yaml = $this->dumper->dump($outer, 2, 0, Yaml::DUMP_OBJECT_AS_MAP);

$expected = <<<YAML
outer1: a
outer2:
inner1: b
inner2: c
inner3: { deep1: d, deep2: e }
YAML;
$this->assertSame($expected, $yaml);
}

public function testDumpingArrayObjectInstancesWithNumericKeysInlined()
{
$deep = new \ArrayObject(array('d', 'e'));
$inner = new \ArrayObject(array('b', 'c', $deep));
$outer = new \ArrayObject(array('a', $inner));

$yaml = $this->dumper->dump($outer, 0, 0, Yaml::DUMP_OBJECT_AS_MAP);
$expected = <<<YAML
{ 0: a, 1: { 0: b, 1: c, 2: { 0: d, 1: e } } }
YAML;
$this->assertSame($expected, $yaml);
}

public function testDumpingArrayObjectInstancesWithNumericKeysRespectsInlineLevel()
{
$deep = new \ArrayObject(array('d', 'e'));
$inner = new \ArrayObject(array('b', 'c', $deep));
$outer = new \ArrayObject(array('a', $inner));
$yaml = $this->dumper->dump($outer, 2, 0, Yaml::DUMP_OBJECT_AS_MAP);
$expected = <<<YAML
0: a
1:
0: b
1: c
2: { 0: d, 1: e }
YAML;
$this->assertEquals($expected, $yaml);
}

public function testDumpEmptyArrayObjectInstanceAsMap()
{
$this->assertSame('{ }', $this->dumper->dump(new \ArrayObject(), 2, 0, Yaml::DUMP_OBJECT_AS_MAP));
}

public function testDumpEmptyStdClassInstanceAsMap()
{
$this->assertSame('{ }', $this->dumper->dump(new \stdClass(), 2, 0, Yaml::DUMP_OBJECT_AS_MAP));
}

public function testDumpingStdClassInstancesRespectsInlineLevel()
{
$deep = new \stdClass();
$deep->deep1 = 'd';
$deep->deep2 = 'e';

$inner = new \stdClass();
$inner->inner1 = 'b';
$inner->inner2 = 'c';
$inner->inner3 = $deep;

$outer = new \stdClass();
$outer->outer1 = 'a';
$outer->outer2 = $inner;

$yaml = $this->dumper->dump($outer, 2, 0, Yaml::DUMP_OBJECT_AS_MAP);

$expected = <<<YAML
outer1: a
outer2:
inner1: b
inner2: c
inner3: { deep1: d, deep2: e }
YAML;
$this->assertSame($expected, $yaml);
}

public function testDumpMultiLineStringAsScalarBlock()
{
$data = array(
Expand Down

0 comments on commit 3cca48c

Please sign in to comment.