Repository: decorators-squad/eo-yaml (java)

Issue:
Unable to read empty sequences or map
You said in a previous closed issue that you didn't planned to parse json-like yaml. But, there is no other way of writing empty sequences or mappings … Is it possible to add support to this ? For example making [] and {} nodes converted to empty sequences and mappings ?

Or do i have to code this node-checking myself ?

Thanks for reading

Pull request description:
Handle empty mappings and sequences.
This is another blocker. Was getting:
- foo
  - {}

Turned into:
- foo
  - "{}"

Fixes #383 

Patch:
diff --git a/src/main/java/com/amihaiemil/eoyaml/EmptyYamlMapping.java b/src/main/java/com/amihaiemil/eoyaml/EmptyYamlMapping.java
new file mode 100644
index 0000000..a59c837
--- /dev/null
+++ b/src/main/java/com/amihaiemil/eoyaml/EmptyYamlMapping.java
@@ -0,0 +1,42 @@
+package com.amihaiemil.eoyaml;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * Representation of an empty YAML Mapping (or "{}").  A decorator around
+ * {@link YamlMapping} with no keys.
+ * @author Andrew Newman
+ * @version $Id$
+ * @since 5.1.17
+ */
+public class EmptyYamlMapping extends BaseYamlMapping {
+
+    /**
+     * Decorated object - used for getting comments.
+     */
+    private final YamlMapping mapping;
+
+    /**
+     * Wrap an existing mapping - expects comments() to be implemented.
+     * @param mapping The mapping to wrap.
+     */
+    public EmptyYamlMapping(final YamlMapping mapping) {
+        this.mapping = mapping;
+    }
+
+    @Override
+    public final Set<YamlNode> keys() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public final YamlNode value(final YamlNode key) {
+        return null;
+    }
+
+    @Override
+    public final Comment comment() {
+        return this.mapping.comment();
+    }
+}
diff --git a/src/main/java/com/amihaiemil/eoyaml/EmptyYamlSequence.java b/src/main/java/com/amihaiemil/eoyaml/EmptyYamlSequence.java
new file mode 100644
index 0000000..6d7cc7d
--- /dev/null
+++ b/src/main/java/com/amihaiemil/eoyaml/EmptyYamlSequence.java
@@ -0,0 +1,37 @@
+package com.amihaiemil.eoyaml;
+
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * Representation of an empty YAML Sequence (or "[]").  A decorator around
+ * {@link YamlSequence} with no values.
+ * @author Andrew Newman
+ * @version $Id$
+ * @since 5.1.17
+ */
+public class EmptyYamlSequence extends BaseYamlSequence {
+
+    /**
+     * Decorated object - used for getting comments.
+     */
+    private final YamlSequence sequence;
+
+    /**
+     * Wrap an existing sequence - expects comments() to be implemented.
+     * @param sequence The sequence to wrap.
+     */
+    public EmptyYamlSequence(final YamlSequence sequence) {
+        this.sequence = sequence;
+    }
+
+    @Override
+    public final Collection<YamlNode> values() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public final Comment comment() {
+        return sequence.comment();
+    }
+}
diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadYamlMapping.java b/src/main/java/com/amihaiemil/eoyaml/ReadYamlMapping.java
index 45cfb58..9b08d00 100644
--- a/src/main/java/com/amihaiemil/eoyaml/ReadYamlMapping.java
+++ b/src/main/java/com/amihaiemil/eoyaml/ReadYamlMapping.java
@@ -245,12 +245,25 @@ final class ReadYamlMapping extends BaseYamlMapping {
                     value = this.significant.toYamlNode(
                         line, this.guessIndentation
                     );
+                } else if (trimmed.matches(tryKey + ":[ ]*\\{}")) {
+                    value = new EmptyYamlMapping(new ReadYamlMapping(
+                            this.all.line(line.number()),
+                            this.all,
+                            this.guessIndentation
+                    ));
+                } else if (trimmed.matches(tryKey + ":[ ]*\\[]")) {
+                    value = new EmptyYamlSequence(new ReadYamlSequence(
+                            this.all.line(line.number()),
+                            this.all,
+                            this.guessIndentation
+                    ));
                 } else if((trimmed.startsWith(tryKey + ":")
-                    || trimmed.startsWith("- " + tryKey + ":"))
-                    && trimmed.length() > 1
+                        || trimmed.startsWith("- " + tryKey + ":"))
+                        && trimmed.length() > 1
                 ) {
                     value = new ReadPlainScalar(this.all, line);
                 }
+
                 if(value != null) {
                     return value;
                 }
diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadYamlSequence.java b/src/main/java/com/amihaiemil/eoyaml/ReadYamlSequence.java
index d25574f..8e3f67f 100644
--- a/src/main/java/com/amihaiemil/eoyaml/ReadYamlSequence.java
+++ b/src/main/java/com/amihaiemil/eoyaml/ReadYamlSequence.java
@@ -27,7 +27,9 @@
  */
 package com.amihaiemil.eoyaml;
 
-import java.util.*;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
 
 /**
  * YamlSequence read from somewhere.
@@ -145,10 +147,22 @@ final class ReadYamlSequence extends BaseYamlSequence {
                     || trimmed.endsWith(">")
                 ) {
                     kids.add(
-                        this.significant.toYamlNode(
-                            line, this.guessIndentation
-                        )
+                            this.significant.toYamlNode(
+                                    line, this.guessIndentation
+                            )
                     );
+                } else if (trimmed.matches("^-[ ]*\\{}")) {
+                    kids.add(new EmptyYamlMapping(new ReadYamlMapping(
+                            this.all.line(line.number()),
+                            this.all,
+                            this.guessIndentation
+                    )));
+                } else if (trimmed.matches("^-[ ]*\\[]")) {
+                    kids.add(new EmptyYamlSequence(new ReadYamlSequence(
+                            this.all.line(line.number()),
+                            this.all,
+                            this.guessIndentation
+                    )));
                 } else {
                     if(this.mappingStartsAtDash(line)) {
                         kids.add(
diff --git a/src/main/java/com/amihaiemil/eoyaml/RtYamlMappingBuilder.java b/src/main/java/com/amihaiemil/eoyaml/RtYamlMappingBuilder.java
index 30539bb..d98247d 100644
--- a/src/main/java/com/amihaiemil/eoyaml/RtYamlMappingBuilder.java
+++ b/src/main/java/com/amihaiemil/eoyaml/RtYamlMappingBuilder.java
@@ -93,7 +93,11 @@ final class RtYamlMappingBuilder implements YamlMappingBuilder {
 
     @Override
     public YamlMapping build(final String comment) {
-        return new RtYamlMapping(this.pairs, comment);
+        YamlMapping mapping = new RtYamlMapping(this.pairs, comment);
+        if (pairs.isEmpty()) {
+            mapping = new EmptyYamlMapping(mapping);
+        }
+        return mapping;
     }
 
 }
diff --git a/src/main/java/com/amihaiemil/eoyaml/RtYamlPrinter.java b/src/main/java/com/amihaiemil/eoyaml/RtYamlPrinter.java
index 8fc834e..df6cc57 100644
--- a/src/main/java/com/amihaiemil/eoyaml/RtYamlPrinter.java
+++ b/src/main/java/com/amihaiemil/eoyaml/RtYamlPrinter.java
@@ -268,8 +268,14 @@ final class RtYamlPrinter implements YamlPrinter {
         final boolean onNewLine,
         final int indentation
     ) throws IOException {
-        if(node == null || ((BaseYamlNode) node).isEmpty()) {
-            this.writer.append(" ").append("null");
+        if (node == null || ((BaseYamlNode) node).isEmpty()) {
+            if (node instanceof EmptyYamlSequence) {
+                this.writer.append(" ").append("[]");
+            } else if (node instanceof EmptyYamlMapping) {
+                this.writer.append(" ").append("{}");
+            } else {
+                this.writer.append(" ").append("null");
+            }
         } else {
             if (onNewLine) {
                 this.writer.append(System.lineSeparator());
diff --git a/src/main/java/com/amihaiemil/eoyaml/RtYamlSequenceBuilder.java b/src/main/java/com/amihaiemil/eoyaml/RtYamlSequenceBuilder.java
index 79ce93c..b50de00 100644
--- a/src/main/java/com/amihaiemil/eoyaml/RtYamlSequenceBuilder.java
+++ b/src/main/java/com/amihaiemil/eoyaml/RtYamlSequenceBuilder.java
@@ -73,6 +73,10 @@ final class RtYamlSequenceBuilder implements YamlSequenceBuilder {
 
     @Override
     public YamlSequence build(final String comment) {
-        return new RtYamlSequence(this.nodes, comment);
+        YamlSequence sequence = new RtYamlSequence(this.nodes, comment);
+        if (this.nodes.isEmpty()) {
+            sequence = new EmptyYamlSequence(sequence);
+        }
+        return sequence;
     }
 }


Test patch:
diff --git a/src/test/java/com/amihaiemil/eoyaml/EmptyYamlMappingTest.java b/src/test/java/com/amihaiemil/eoyaml/EmptyYamlMappingTest.java
new file mode 100644
index 0000000..2186dc1
--- /dev/null
+++ b/src/test/java/com/amihaiemil/eoyaml/EmptyYamlMappingTest.java
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2016-2020, Mihai Emil Andronache
+ * All rights reserved.
+ * <p>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+package com.amihaiemil.eoyaml;
+
+import java.util.UUID;
+
+import org.hamcrest.MatcherAssert;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ * Unit tests for {@link EmptyYamlMapping}.
+ *
+ * @author Andrew Newman
+ * @version $Id$
+ * @since 5.1.17
+ */
+public final class EmptyYamlMappingTest {
+
+    /**
+     * Random comment.
+     */
+    public static final String ANY_COMMENT = UUID.randomUUID().toString();
+
+    /**
+     * Random key.
+     */
+    public static final String ANY_KEY = UUID.randomUUID().toString();
+
+    /**
+     * Able to get comment.
+     */
+    @Test
+    public void returnsCommentFromDecoratedObject() {
+        final YamlMapping mapping = Mockito.mock(YamlMapping.class);
+        final YamlNode node = Mockito.mock(YamlNode.class);
+        final Comment comment = new BuiltComment(node, ANY_COMMENT);
+        Mockito.when(mapping.comment()).thenReturn(comment);
+        YamlMapping emptyMapping = new EmptyYamlMapping(mapping);
+        MatcherAssert.assertThat(
+                emptyMapping.comment().value(),
+                Matchers.equalTo(ANY_COMMENT)
+        );
+    }
+
+    /**
+     * Has no elements in the mapping - no keys.
+     */
+    @Test
+    public void hasEmptyKeys() {
+        final YamlMapping mapping = Mockito.mock(YamlMapping.class);
+        YamlMapping emptyMapping = new EmptyYamlMapping(mapping);
+        MatcherAssert.assertThat(
+                emptyMapping.keys().size(),
+                Matchers.is(0)
+        );
+    }
+
+    /**
+     * Has no elements in the mapping - no values.
+     */
+    @Test
+    public void hasNoValues() {
+        final YamlMapping mapping = Mockito.mock(YamlMapping.class);
+        YamlMapping emptyMapping = new EmptyYamlMapping(mapping);
+        MatcherAssert.assertThat(
+                emptyMapping.value(ANY_KEY),
+                Matchers.is(Matchers.nullValue())
+        );
+    }
+}
diff --git a/src/test/java/com/amihaiemil/eoyaml/EmptyYamlSequenceTest.java b/src/test/java/com/amihaiemil/eoyaml/EmptyYamlSequenceTest.java
new file mode 100644
index 0000000..439a165
--- /dev/null
+++ b/src/test/java/com/amihaiemil/eoyaml/EmptyYamlSequenceTest.java
@@ -0,0 +1,78 @@
+/**
+ * Copyright (c) 2016-2020, Mihai Emil Andronache
+ * All rights reserved.
+ * <p>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+package com.amihaiemil.eoyaml;
+
+import java.util.UUID;
+
+import org.hamcrest.MatcherAssert;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ * Unit tests for {@link EmptyYamlSequence}.
+ * @author Andrew Newman
+ * @version $Id$
+ * @since 5.1.17
+ */
+public final class EmptyYamlSequenceTest {
+
+    /**
+     * Random comment.
+     */
+    public static final String ANY_COMMENT = UUID.randomUUID().toString();
+
+    /**
+     * Able to get comment.
+     */
+    @Test
+    public void returnsCommentFromDecoratedObject() {
+        final YamlSequence sequence = Mockito.mock(YamlSequence.class);
+        final YamlNode node = Mockito.mock(YamlNode.class);
+        final Comment comment = new BuiltComment(node, ANY_COMMENT);
+        Mockito.when(sequence.comment()).thenReturn(comment);
+        YamlSequence emptyMapping = new EmptyYamlSequence(sequence);
+        MatcherAssert.assertThat(
+            emptyMapping.comment().value(),
+            Matchers.equalTo(ANY_COMMENT)
+        );
+    }
+
+    /**
+     * Has no elements in the sequence.
+     */
+    @Test
+    public void hasEmptyValues() {
+        final YamlSequence sequence = Mockito.mock(YamlSequence.class);
+        YamlSequence emptySequence = new EmptyYamlSequence(sequence);
+        MatcherAssert.assertThat(
+                emptySequence.values().isEmpty(),
+                Matchers.is(Boolean.TRUE)
+        );
+    }
+}
diff --git a/src/test/java/com/amihaiemil/eoyaml/ReadYamlMappingTest.java b/src/test/java/com/amihaiemil/eoyaml/ReadYamlMappingTest.java
index 280b6db..a5ea47a 100644
--- a/src/test/java/com/amihaiemil/eoyaml/ReadYamlMappingTest.java
+++ b/src/test/java/com/amihaiemil/eoyaml/ReadYamlMappingTest.java
@@ -1093,8 +1093,8 @@ public final class ReadYamlMappingTest {
         lines.add(new RtYamlLine("  x: 2", 3));
         final YamlMapping map = new ReadYamlMapping(new AllYamlLines(lines));
         MatcherAssert.assertThat(
-            map.value("a").asMapping().string("x"),
-            Matchers.equalTo("2")
+                map.value("a").asMapping().string("x"),
+                Matchers.equalTo("2")
         );
     }
 
@@ -1117,4 +1117,37 @@ public final class ReadYamlMappingTest {
                 Matchers.equalTo("1")
         );
     }
+
+    /**
+     * ReadYamlMapping returns the correct value for empty maps and sequences.
+     */
+    @Test
+    public void dontTurnEmptyMapsAndArraysIntoStrings() {
+        final List<YamlLine> lines = new ArrayList<>();
+        lines.add(new RtYamlLine("# A", 0));
+        lines.add(new RtYamlLine("def: {}", 1));
+        lines.add(new RtYamlLine("# B", 2));
+        lines.add(new RtYamlLine("ghi: []", 3));
+        final YamlMapping map = new ReadYamlMapping(new AllYamlLines(lines));
+        YamlMapping actualMap = map.value("def").asMapping();
+        YamlMapping expectedMap = Yaml.createYamlMappingBuilder().build("A");
+        MatcherAssert.assertThat(
+                actualMap,
+                Matchers.equalTo(expectedMap)
+        );
+        MatcherAssert.assertThat(
+                actualMap.comment().value(),
+                Matchers.equalTo(expectedMap.comment().value())
+        );
+        YamlSequence actualSeq = map.value("ghi").asSequence();
+        YamlSequence expectedSeq = Yaml.createYamlSequenceBuilder().build("B");
+        MatcherAssert.assertThat(
+                actualSeq,
+                Matchers.equalTo(expectedSeq)
+        );
+        MatcherAssert.assertThat(
+                actualSeq.comment().value(),
+                Matchers.equalTo(expectedSeq.comment().value())
+        );
+    }
 }
diff --git a/src/test/java/com/amihaiemil/eoyaml/ReadYamlSequenceTest.java b/src/test/java/com/amihaiemil/eoyaml/ReadYamlSequenceTest.java
index 9ccb89a..1f25179 100644
--- a/src/test/java/com/amihaiemil/eoyaml/ReadYamlSequenceTest.java
+++ b/src/test/java/com/amihaiemil/eoyaml/ReadYamlSequenceTest.java
@@ -374,6 +374,40 @@ public final class ReadYamlSequenceTest {
         );
     }
 
+    /**
+     * ReadYamlSequence returns the correct value for empty maps and sequences.
+     */
+    @Test
+    public void dontTurnEmptyMapsAndArraysIntoStrings() {
+        final List<YamlLine> lines = new ArrayList<>();
+        lines.add(new RtYamlLine("# A", 0));
+        lines.add(new RtYamlLine("- {}", 1));
+        lines.add(new RtYamlLine("# B", 2));
+        lines.add(new RtYamlLine("- []", 3));
+        final YamlSequence seq = new ReadYamlSequence(new AllYamlLines(lines));
+        Iterator<YamlNode> iterator = seq.values().iterator();
+        YamlMapping actualMap = iterator.next().asMapping();
+        YamlMapping expectedMap = Yaml.createYamlMappingBuilder().build("A");
+        MatcherAssert.assertThat(
+                actualMap,
+                Matchers.equalTo(expectedMap)
+        );
+        MatcherAssert.assertThat(
+                actualMap.comment().value(),
+                Matchers.equalTo(expectedMap.comment().value())
+        );
+        YamlSequence actualSeq = iterator.next().asSequence();
+        YamlSequence expectedSeq = Yaml.createYamlSequenceBuilder().build("B");
+        MatcherAssert.assertThat(
+                actualSeq,
+                Matchers.equalTo(expectedSeq)
+        );
+        MatcherAssert.assertThat(
+                actualSeq.comment().value(),
+                Matchers.equalTo(expectedSeq.comment().value())
+        );
+    }
+
     /**
      * An empty ReadYamlSequence can be printed.
      * @throws Exception if something goes wrong
diff --git a/src/test/java/com/amihaiemil/eoyaml/YamlMappingPrintTest.java b/src/test/java/com/amihaiemil/eoyaml/YamlMappingPrintTest.java
index 35f9f8b..c295d2b 100644
--- a/src/test/java/com/amihaiemil/eoyaml/YamlMappingPrintTest.java
+++ b/src/test/java/com/amihaiemil/eoyaml/YamlMappingPrintTest.java
@@ -126,6 +126,16 @@ public final class YamlMappingPrintTest {
                     .add("as value")
                     .build()
             )
+            .add(
+                "key6",
+                Yaml.createYamlMappingBuilder()
+                    .build()
+            )
+            .add(
+                "key7",
+                Yaml.createYamlSequenceBuilder()
+                    .build()
+            )
             .add(
                 Yaml.createYamlSequenceBuilder()
                     .add("Atlanta Braves")
@@ -153,7 +163,7 @@ public final class YamlMappingPrintTest {
     }
 
     /**
-     * An empty YamlSequence value is printed as null.
+     * An empty YamlSequence value is printed as empty sequence ([]).
      */
     @Test
     public void printsEmptySequenceAsNull() {
@@ -165,7 +175,7 @@ public final class YamlMappingPrintTest {
         final StringBuilder expected = new StringBuilder();
         expected
             .append("key: value1").append(System.lineSeparator())
-            .append("seq: null").append(System.lineSeparator())
+            .append("seq: []").append(System.lineSeparator())
             .append("anotherKey: value2");
         MatcherAssert.assertThat(
             map.toString(),
@@ -196,7 +206,7 @@ public final class YamlMappingPrintTest {
     }
 
     /**
-     * An empty YamlMapping value is printed as null.
+     * An empty YamlMapping value is printed as empty mapping ({}).
      */
     @Test
     public void printsEmptyMappingAsNull() {
@@ -208,7 +218,7 @@ public final class YamlMappingPrintTest {
         final StringBuilder expected = new StringBuilder();
         expected
             .append("key: value1").append(System.lineSeparator())
-            .append("map: null").append(System.lineSeparator())
+            .append("map: {}").append(System.lineSeparator())
             .append("anotherKey: value2");
         MatcherAssert.assertThat(
             map.toString(),
diff --git a/src/test/java/com/amihaiemil/eoyaml/YamlSequencePrintTest.java b/src/test/java/com/amihaiemil/eoyaml/YamlSequencePrintTest.java
index 35d69bb..265dbb4 100644
--- a/src/test/java/com/amihaiemil/eoyaml/YamlSequencePrintTest.java
+++ b/src/test/java/com/amihaiemil/eoyaml/YamlSequencePrintTest.java
@@ -105,6 +105,8 @@ public final class YamlSequencePrintTest {
                     .add("as child")
                     .build()
             )
+            .add(Yaml.createYamlSequenceBuilder().build())
+            .add(Yaml.createYamlMappingBuilder().build())
             .build();
         MatcherAssert.assertThat(
             built.toString(),
@@ -115,7 +117,7 @@ public final class YamlSequencePrintTest {
     }
 
     /**
-     * An empty YamlSequence value is printed as null.
+     * An empty YamlSequence value is printed as empty sequence ([]).
      */
     @Test
     public void printsEmptySequenceAsNull() {
@@ -127,7 +129,7 @@ public final class YamlSequencePrintTest {
         final StringBuilder expected = new StringBuilder();
         expected
             .append("- value1").append(System.lineSeparator())
-            .append("- null").append(System.lineSeparator())
+            .append("- []").append(System.lineSeparator())
             .append("- value2");
         MatcherAssert.assertThat(
             sequence.toString(),
@@ -158,7 +160,7 @@ public final class YamlSequencePrintTest {
     }
 
     /**
-     * An empty YamlMapping value is printed as null.
+     * An empty YamlMapping value is printed as empty mapping ({}).
      */
     @Test
     public void printsEmptyMappingAsNull() {
@@ -170,7 +172,7 @@ public final class YamlSequencePrintTest {
         final StringBuilder expected = new StringBuilder();
         expected
             .append("- value1").append(System.lineSeparator())
-            .append("- null").append(System.lineSeparator())
+            .append("- {}").append(System.lineSeparator())
             .append("- value2");
         MatcherAssert.assertThat(
             sequence.toString(),
diff --git a/src/test/resources/printing_tests/yamlMappingAllNodes.txt b/src/test/resources/printing_tests/yamlMappingAllNodes.txt
index a364329..3456b3c 100644
--- a/src/test/resources/printing_tests/yamlMappingAllNodes.txt
+++ b/src/test/resources/printing_tests/yamlMappingAllNodes.txt
@@ -13,6 +13,8 @@ key5:
   - a sequence
   - of plain scalars
   - as value
+key6: {}
+key7: []
 ?
   - Atlanta Braves
   - New York Yankees
diff --git a/src/test/resources/printing_tests/yamlSequenceAllNodes.txt b/src/test/resources/printing_tests/yamlSequenceAllNodes.txt
index bf8e5d5..c4c544f 100644
--- a/src/test/resources/printing_tests/yamlSequenceAllNodes.txt
+++ b/src/test/resources/printing_tests/yamlSequenceAllNodes.txt
@@ -12,4 +12,6 @@
 -
   - a sequence
   - of plain scalars
-  - as child
\ No newline at end of file
+  - as child
+- []
+- {}
\ No newline at end of file