Repository: decorators-squad/eo-yaml
Pull request #188 (2020-03-12 08:12:57)

Implement Building of Yaml Streams
PR for #90 

* Implemented building of YamlStream. YamlStream also implements the Java 8 Stream!


Patch:
diff --git a/README.md b/README.md
index 452e565..740e515 100644
--- a/README.md
+++ b/README.md
@@ -29,10 +29,12 @@ or download the <a href="https://oss.sonatype.org/service/local/repositories/rel
 
 The API of this library is clean, intuitive and generally close to the ``javax.json`` API that most developers are used to:
 
-## Features
+## Features (ongoing work!)
 
 Since the library is quite young, it doesn't support all the features of YAML yet. For now, it only supports creating/parsing [Block Style](http://yaml.org/spec/1.2/spec.html#Block) YAML, so use it if you have to read/create configuration files and such stuff. It doesn't yet implement features such as **flow** or **recursive** representation, **aliases & anchors** or document streams (more YAMLs separated by ``---``).
 
+Have a look under [src/test/resources](https://github.com/decorators-squad/eo-yaml/tree/master/src/test/resources) to see the kinds of YAML it supports so far.
+
 However, keep in mind that the library is based on interfaces and OOP best practices, so you can probably extend/decorate the objects in order to create the functionality you need! 
 
 If you have some time and like the library, please consider contributing. 
@@ -113,12 +115,11 @@ You can also parse maps (``Map<Object, Object>``) and collections (``Collection<
 
 ## Contribute
 
-Contributors are [welcome](http://www.amihaiemil.com/2016/12/30/becoming-a-contributor.html)
+Contributors are welcome!
 
 1. Open an issue regarding an improvement you thought of, or a bug you noticed, or ask to be assigned to an existing one.
 2. If the issue is confirmed, fork the repository, do the changes on a separate branch and make a Pull Request.
 3. After review and acceptance, the PR is merged and closed.
-4. You are automatically listed as a contributor on the repo and the project's site (to follow)
 
 Make sure the maven build
 
diff --git a/pom.xml b/pom.xml
index b2138ad..09e77ea 100644
--- a/pom.xml
+++ b/pom.xml
@@ -138,6 +138,11 @@
                                 </goals>
                             </execution>
                         </executions>
+                        <configuration>
+                            <excludes>
+                                <exclude>**/*RtYamlStreamBuilder$*.*</exclude>
+                            </excludes>
+                        </configuration>
                     </plugin>
                     <plugin>
                         <groupId>org.eluder.coveralls</groupId>
diff --git a/src/main/java/com/amihaiemil/eoyaml/ComparableYamlSequence.java b/src/main/java/com/amihaiemil/eoyaml/ComparableYamlSequence.java
index a856fdd..0d5f9eb 100644
--- a/src/main/java/com/amihaiemil/eoyaml/ComparableYamlSequence.java
+++ b/src/main/java/com/amihaiemil/eoyaml/ComparableYamlSequence.java
@@ -77,18 +77,18 @@ abstract class ComparableYamlSequence implements YamlSequence {
      * A Sequence is always considered greater than a Scalar and less than
      * a Mapping.<br>
      *
-     * If o is a Sequence, their integer lengths are compared - the one with
+     * If other is a Sequence, their integer lengths are compared - the one with
      * the greater length is considered greater. If the lengths are equal,
      * then the 2 Sequences are equal if all elements are equal. If the
      * elements are not identical, the comparison of the first unequal
      * elements is returned.
      *
-     * @param other The other AbstractNode.
+     * @param other The other YamlNode.
      * @checkstyle NestedIfDepth (100 lines)
      * @return
-     *   a value &lt; 0 if this &lt; o <br>
-     *   0 if this == o or <br>
-     *   a value &gt; 0 if this &gt; o
+     *   a value &lt; 0 if this &lt; other <br>
+     *   0 if this == other or <br>
+     *   a value &gt; 0 if this &gt; other
      */
     @Override
     public int compareTo(final YamlNode other) {
@@ -99,7 +99,6 @@ abstract class ComparableYamlSequence implements YamlSequence {
             result = -1;
         } else if (this != other) {
             final Collection<YamlNode> nodes = this.values();
-            nodes.hashCode();
             final Collection<YamlNode> others = other.values();
             if(nodes.size() > others.size()) {
                 result = 1;
diff --git a/src/main/java/com/amihaiemil/eoyaml/ComparableYamlStream.java b/src/main/java/com/amihaiemil/eoyaml/ComparableYamlStream.java
new file mode 100644
index 0000000..f075c8a
--- /dev/null
+++ b/src/main/java/com/amihaiemil/eoyaml/ComparableYamlStream.java
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2016-2020, Mihai Emil Andronache
+ * All rights reserved.
+ *
+ * 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.Collection;
+import java.util.Iterator;
+
+/**
+ * Comparable YamlStream implementing equals, hashcode and compareTo methods.
+ * <br><br>
+ * These methods should be default methods on the interface,
+ * but we are not allowed to have default implementations of java.lang.Object
+ * methods.
+ *
+ * @author Mihai Andronache (amihaiemil@gmail.com)
+ * @version $Id$
+ * @since 3.1.1
+ */
+abstract class ComparableYamlStream implements YamlStream {
+
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        for(final YamlNode node : this.values()) {
+            hash += node.hashCode();
+        }
+        return hash;
+    }
+
+    /**
+     * Equals method for YamlStream. It returns true if the compareTo(...)
+     * method returns 0.
+     * @param other The YamlStream to which this is compared.
+     * @return True or false
+     */
+    @Override
+    public boolean equals(final Object other) {
+        final boolean result;
+        if (other == null || !(other instanceof YamlStream)) {
+            result = false;
+        } else if (this == other) {
+            result = true;
+        } else {
+            result = this.compareTo((YamlStream) other) == 0;
+        }
+        return result;
+    }
+
+    /**
+     * Compare this Sequence to another node.<br><br>
+     *
+     * A YamlStream is always considered greater than a Scalar,
+     * a YamlSequence or a YamlMapping.
+     *
+     * If other is a YamlStream, their integer lengths are compared - the one
+     * with the greater length is considered greater. If the lengths are equal,
+     * then the 2 YamlStreams are equal if all elements are equal. If the
+     * elements are not identical, the comparison of the first unequal
+     * elements is returned.
+     *
+     * @param other The other YamlNode.
+     * @checkstyle NestedIfDepth (100 lines)
+     * @return
+     *   a value &lt; 0 if this &lt; other <br>
+     *   0 if this == other or <br>
+     *   a value &gt; 0 if this &gt; other
+     */
+    @Override
+    public int compareTo(final YamlNode other) {
+        int result = 0;
+        if (other == null || other instanceof Scalar) {
+            result = 1;
+        } else if (other instanceof YamlSequence) {
+            result = 1;
+        } else if (other instanceof YamlMapping) {
+            result = 1;
+        } else if (this != other) {
+            final Collection<YamlNode> nodes = this.values();
+            final Collection<YamlNode> others = other.values();
+            if(nodes.size() > others.size()) {
+                result = 1;
+            } else if (nodes.size() < others.size()) {
+                result = -1;
+            } else {
+                final Iterator<YamlNode> iterator = others.iterator();
+                final Iterator<YamlNode> here = nodes.iterator();
+                while(iterator.hasNext()) {
+                    result = here.next().compareTo(iterator.next());
+                    if(result != 0) {
+                        break;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+}
diff --git a/src/main/java/com/amihaiemil/eoyaml/RtYamlStreamBuilder.java b/src/main/java/com/amihaiemil/eoyaml/RtYamlStreamBuilder.java
new file mode 100644
index 0000000..cd3f05c
--- /dev/null
+++ b/src/main/java/com/amihaiemil/eoyaml/RtYamlStreamBuilder.java
@@ -0,0 +1,296 @@
+/**
+ * Copyright (c) 2016-2020, Mihai Emil Andronache
+ * All rights reserved.
+ *
+ * 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.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+import java.util.Spliterator;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.BinaryOperator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.IntFunction;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+import java.util.stream.Collector;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.Stream;
+
+/**
+ * YamlStreamBuilder implementation.
+ * This class is immutable and thread-safe.
+ * @author Mihai Andronache (amihaiemil@gmail.com)
+ * @version $Id$
+ * @since 3.1.1
+ */
+final class RtYamlStreamBuilder implements YamlStreamBuilder {
+
+    /**
+     * Added nodes.
+     */
+    private final List<YamlNode> documents;
+
+    /**
+     * Default ctor.
+     */
+    RtYamlStreamBuilder() {
+        this(new LinkedList<YamlNode>());
+    }
+
+    /**
+     * Constructor.
+     * @param documents YAML documents used in building the YamlStream.
+     */
+    RtYamlStreamBuilder(final List<YamlNode> documents) {
+        this.documents = documents;
+    }
+
+    @Override
+    public YamlStreamBuilder add(final YamlNode document) {
+        final List<YamlNode> list = new LinkedList<>();
+        list.addAll(this.documents);
+        list.add(document);
+        return new RtYamlStreamBuilder(list);
+    }
+
+    @Override
+    public YamlStream build() {
+        return new BuiltYamlStream(this.documents);
+    }
+    
+    /**
+     * Built YamlStream.
+     * @checkstyle FinalParameters (200 lines)
+     * @checkstyle JavadocMethod (200 lines)
+     * @checkstyle LineLength (200 lines)
+     * @checkstyle ParameterName (200 lines)
+     * @checkstyle FinalParameters (200 lines)
+     * @author Mihai Andronache (amihaiemil@gmail.com)
+     * @version $Id$
+     * @since 3.1.1
+     */
+    static class BuiltYamlStream extends ComparableYamlStream {
+
+        /**
+         * Documents as a List.
+         */
+        private Collection<YamlNode> documents;
+        
+        /**
+         * The Stream of YAML Documents.
+         */
+        private Stream<YamlNode> documentStream;
+        
+        BuiltYamlStream(final Collection<YamlNode> documents) {
+            this.documents = documents;
+            this.documentStream = documents.stream();
+        }
+        
+        public Iterator<YamlNode> iterator() {
+            return this.documentStream.iterator();
+        }
+
+        public Spliterator<YamlNode> spliterator() {
+            return this.documentStream.spliterator();
+        }
+
+        public boolean isParallel() {
+            return this.documentStream.isParallel();
+        }
+
+        public Stream<YamlNode> sequential() {
+            return this.documentStream.sequential();
+        }
+
+        public Stream<YamlNode> parallel() {
+            return this.documentStream.parallel();
+        }
+
+        public Stream<YamlNode> unordered() {
+            return this.documentStream.unordered();
+        }
+
+        public Stream<YamlNode> onClose(Runnable closeHandler) {
+            return this.documentStream.onClose(closeHandler);
+        }
+
+        public void close() {
+            this.documentStream.close();
+        }
+
+        public Stream<YamlNode> filter(Predicate<? super YamlNode> predicate) {
+            return this.documentStream.filter(predicate);
+        }
+
+        public <R> Stream<R> map(Function<? super YamlNode, ? extends R> mapper) {
+            return this.documentStream.map(mapper);
+        }
+
+        public IntStream mapToInt(ToIntFunction<? super YamlNode> mapper) {
+            return this.documentStream.mapToInt(mapper);
+        }
+
+        public LongStream mapToLong(ToLongFunction<? super YamlNode> mapper) {
+            return this.documentStream.mapToLong(mapper);
+        }
+
+        public DoubleStream mapToDouble(ToDoubleFunction<? super YamlNode> mapper) {
+            return this.documentStream.mapToDouble(mapper);
+        }
+
+        public <R> Stream<R> flatMap(Function<? super YamlNode, ? extends Stream<? extends R>> mapper) {
+            return this.documentStream.flatMap(mapper);
+        }
+
+        public IntStream flatMapToInt(Function<? super YamlNode, ? extends IntStream> mapper) {
+            return this.documentStream.flatMapToInt(mapper);
+        }
+
+        public LongStream flatMapToLong(Function<? super YamlNode, ? extends LongStream> mapper) {
+            return this.documentStream.flatMapToLong(mapper);
+        }
+
+        public DoubleStream flatMapToDouble(Function<? super YamlNode, ? extends DoubleStream> mapper) {
+            return this.documentStream.flatMapToDouble(mapper);
+        }
+
+        public Stream<YamlNode> distinct() {
+            return this.documentStream.distinct();
+        }
+
+        public Stream<YamlNode> sorted() {
+            return this.documentStream.sorted();
+        }
+
+        public Stream<YamlNode> sorted(Comparator<? super YamlNode> comparator) {
+            return this.documentStream.sorted(comparator);
+        }
+
+        public Stream<YamlNode> peek(Consumer<? super YamlNode> action) {
+            return this.documentStream.peek(action);
+        }
+
+        public Stream<YamlNode> limit(long maxSize) {
+            return this.documentStream.limit(maxSize);
+        }
+
+        public Stream<YamlNode> skip(long n) {
+            return this.documentStream.skip(n);
+        }
+
+        public void forEach(Consumer<? super YamlNode> action) {
+            this.documentStream.forEach(action);
+        }
+
+        public void forEachOrdered(Consumer<? super YamlNode> action) {
+            this.documentStream.forEachOrdered(action);
+        }
+
+        public Object[] toArray() {
+            return this.documentStream.toArray();
+        }
+
+        public <A> A[] toArray(IntFunction<A[]> generator) {
+            return this.documentStream.toArray(generator);
+        }
+
+        public YamlNode reduce(YamlNode identity, BinaryOperator<YamlNode> accumulator) {
+            return this.documentStream.reduce(identity, accumulator);
+        }
+
+        public Optional<YamlNode> reduce(BinaryOperator<YamlNode> accumulator) {
+            return this.documentStream.reduce(accumulator);
+        }
+
+        public <U> U reduce(U identity, BiFunction<U, ? super YamlNode, U> accumulator, BinaryOperator<U> combiner) {
+            return this.documentStream.reduce(identity, accumulator, combiner);
+        }
+
+        public <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super YamlNode> accumulator,
+                BiConsumer<R, R> combiner) {
+            return this.documentStream.collect(supplier, accumulator, combiner);
+        }
+
+        public <R, A> R collect(Collector<? super YamlNode, A, R> collector) {
+            return this.documentStream.collect(collector);
+        }
+
+        public Optional<YamlNode> min(Comparator<? super YamlNode> comparator) {
+            return this.documentStream.min(comparator);
+        }
+
+        public Optional<YamlNode> max(Comparator<? super YamlNode> comparator) {
+            return this.documentStream.max(comparator);
+        }
+
+        public long count() {
+            return this.documentStream.count();
+        }
+
+        public boolean anyMatch(Predicate<? super YamlNode> predicate) {
+            return this.documentStream.anyMatch(predicate);
+        }
+
+        public boolean allMatch(Predicate<? super YamlNode> predicate) {
+            return this.documentStream.allMatch(predicate);
+        }
+
+        public boolean noneMatch(Predicate<? super YamlNode> predicate) {
+            return this.documentStream.noneMatch(predicate);
+        }
+
+        public Optional<YamlNode> findFirst() {
+            return this.documentStream.findFirst();
+        }
+
+        public Optional<YamlNode> findAny() {
+            return this.documentStream.findAny();
+        }
+
+        @Override
+        public Collection<YamlNode> values() {
+            return this.documents;
+        }
+
+        @Override
+        public String toString() {
+            return this.indent(0);
+        }
+    }
+    
+}
diff --git a/src/main/java/com/amihaiemil/eoyaml/Yaml.java b/src/main/java/com/amihaiemil/eoyaml/Yaml.java
index 2d0ccc1..7038342 100644
--- a/src/main/java/com/amihaiemil/eoyaml/Yaml.java
+++ b/src/main/java/com/amihaiemil/eoyaml/Yaml.java
@@ -62,6 +62,14 @@ public final class Yaml {
     public static YamlSequenceBuilder createYamlSequenceBuilder() {
         return new RtYamlSequenceBuilder();
     }
+    
+    /**
+     * Create a {@link YamlStreamBuilder}.
+     * @return Builder of YamlStream.
+     */
+    public static YamlStreamBuilder createYamlStreamBuilder() {
+        return new RtYamlStreamBuilder();
+    }
 
     /**
      * Create a {@link YamlInput} from a File.
diff --git a/src/main/java/com/amihaiemil/eoyaml/YamlInput.java b/src/main/java/com/amihaiemil/eoyaml/YamlInput.java
index 319d6d3..9487b1a 100644
--- a/src/main/java/com/amihaiemil/eoyaml/YamlInput.java
+++ b/src/main/java/com/amihaiemil/eoyaml/YamlInput.java
@@ -50,5 +50,18 @@ public interface YamlInput {
      * @throws IOException if the input cannot be read for some reason
      */
     YamlSequence readYamlSequence() throws IOException;
+    
+    /**
+     * Read the given input as a Yaml stream.
+     * @return Read YamlStream.
+     * @throws IOException if the input cannot be read for some reason
+     */
+    default YamlStream readYamlStream() throws IOException {
+        throw new UnsupportedOperationException(
+            "Not yet implemented. You can follow the development here "
+          + "https://github.com/decorators-squad/eo-yaml/issues/90. " 
+          + "You may also contribute if you have the time!" 
+        );
+    }
 
 }
diff --git a/src/main/java/com/amihaiemil/eoyaml/YamlStream.java b/src/main/java/com/amihaiemil/eoyaml/YamlStream.java
new file mode 100644
index 0000000..c6fb390
--- /dev/null
+++ b/src/main/java/com/amihaiemil/eoyaml/YamlStream.java
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2016-2020, Mihai Emil Andronache
+ * All rights reserved.
+ *
+ * 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.Collection;
+import java.util.stream.Stream;
+
+/**
+ * A YAML Stream of documents. Documents are separated by 3 dashes (---).
+ * @author Mihai Andronache (amihaiemil@gmail.com)
+ * @version $Id$
+ * @since 3.1.1
+ */
+public interface YamlStream extends YamlNode, Stream<YamlNode> {
+
+    /**
+     * Indent this YamlStream. It will take all elements and separate
+     * them with "---". It also starts with "---".
+     * If the YamlStream is empty, it will just print: 
+     * <pre>
+     * ---
+     * ...
+     * </pre>
+     * 
+     * Here is an example of printed YamlStream:
+     * <pre>
+     * ---
+     *   architect: amihaiemil
+     *   developers: 
+     *     - amihaiemil
+     *     - salikjan
+     * ---
+     *   architect: yegor256
+     *   developers: 
+     *     - paolo
+     *     - mario
+     * </pre>
+     * @param indentation Integer specifying the root indentation level.
+     *  Usually 0, but it may be greater than 0 if this YamlNode should
+     *  be nested within a bigger YAML.
+     * @return String.
+     */
+    default String indent(final int indentation) {
+        if(indentation < 0) {
+            throw new IllegalArgumentException(
+                "Indentation level has to be >=0"
+            );
+        }
+        final StringBuilder print = new StringBuilder();
+        int spaces = indentation;
+        final StringBuilder indent = new StringBuilder();
+        while (spaces > 0) {
+            indent.append(" ");
+            spaces--;
+        }
+        final Collection<YamlNode> values = this.values();
+        String printed;
+        if(values.size() == 0) {
+            print
+                .append(indent).append("---\n")
+                .append(indent).append("...");
+            printed = print.toString();
+        } else {
+            for (final YamlNode node : values) {
+                print.append(indent)
+                     .append("---\n");
+                print.append(node.indent(indentation + 2));
+                print.append("\n");
+            }
+            printed = print.toString();
+            if(printed.length() > 0) {
+                printed = printed.substring(0, printed.length() - 1);
+            }
+        }
+        return printed;
+    }
+    
+}
diff --git a/src/main/java/com/amihaiemil/eoyaml/YamlStreamBuilder.java b/src/main/java/com/amihaiemil/eoyaml/YamlStreamBuilder.java
new file mode 100644
index 0000000..e0fe348
--- /dev/null
+++ b/src/main/java/com/amihaiemil/eoyaml/YamlStreamBuilder.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2016-2020, Mihai Emil Andronache
+ * All rights reserved.
+ *
+ * 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;
+
+/**
+ * Builder of YamlStream. Implementations should be immutable and thread-safe.
+ * @author Mihai Andronache (amihaiemil@gmail.com)
+ * @version $Id$
+ * @since 3.1.1
+ */
+public interface YamlStreamBuilder {
+    
+    /**
+     * Add a YAML to the Stream.
+     * @param document YamlNode
+     * @return This builder
+     */
+    YamlStreamBuilder add(final YamlNode document);
+
+    /**
+     * Build the YamlStream.
+     * @return Built YamlStream.
+     */
+    YamlStream build();
+    
+}


Test patch:
diff --git a/src/test/java/com/amihaiemil/eoyaml/BuiltYamlStreamTest.java b/src/test/java/com/amihaiemil/eoyaml/BuiltYamlStreamTest.java
new file mode 100644
index 0000000..34d0e05
--- /dev/null
+++ b/src/test/java/com/amihaiemil/eoyaml/BuiltYamlStreamTest.java
@@ -0,0 +1,403 @@
+/**
+ * Copyright (c) 2016-2020, Mihai Emil Andronache
+ * All rights reserved.
+ *
+ * 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.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.stream.Stream;
+import org.apache.commons.io.IOUtils;
+import org.hamcrest.MatcherAssert;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ * Unit tests for {@link RtYamlStreamBuilder.BuiltYamlStream}.
+ * @author Mihai Andronache (amihaiemil@gmail.com)
+ * @version $Id$
+ * @since 3.1.1
+ *
+ */
+public final class BuiltYamlStreamTest {
+
+    /**
+     * BuiltYamlStreams can hold a stream of mappings.
+     * @throws Exception If something goes wrong.
+     */
+    @Test
+    public void builtStreamOfMappings() throws Exception {
+        final YamlStream mappings = Yaml.createYamlStreamBuilder()
+            .add(
+                Yaml.createYamlMappingBuilder()
+                    .add("architect", "mihai")
+                    .add(
+                        "developers",
+                        Yaml.createYamlSequenceBuilder()
+                            .add("rultor")
+                            .add("salikjan")
+                            .add("sherif")
+                            .build()
+                    )
+                    .add("name", "eo-yaml")
+                    .build()
+            )
+            .add(
+                Yaml.createYamlMappingBuilder()
+                    .add("architect", "vlad")
+                    .add(
+                        "developers",
+                        Yaml.createYamlSequenceBuilder()
+                            .add("andrei")
+                            .build()
+                    )
+                    .add("name", "eo-json-impl")
+                    .build()
+            )
+            .add(
+                Yaml.createYamlMappingBuilder()
+                    .add("architect", "felicia")
+                    .add(
+                        "developer", "sara"
+                    )
+                    .add("name", "docker-java-api")
+                    .build()
+            )
+            .build();
+        MatcherAssert.assertThat(mappings, Matchers.notNullValue());
+        MatcherAssert.assertThat(mappings, Matchers.instanceOf(Stream.class));
+        MatcherAssert.assertThat(
+            mappings.values(), Matchers.iterableWithSize(3)
+        );
+        MatcherAssert.assertThat(
+            mappings.toString(),
+            Matchers.equalTo(this.readTestResource("streamOfMappings.yml"))
+        );
+    }
+    
+    /**
+     * BuiltYamlStreams can hold a stream of sequences.
+     * @throws Exception If something goes wrong.
+     */
+    @Test
+    public void builtStreamOfSequences() throws Exception {
+        final YamlStream sequences = Yaml.createYamlStreamBuilder()
+            .add(
+                Yaml.createYamlSequenceBuilder()
+                    .add("rultor")
+                    .add("salikjan")
+                    .add("sherif")
+                    .build()
+            )
+            .add(
+                Yaml.createYamlSequenceBuilder()
+                    .add("andrei")
+                    .build()
+            )
+            .add(
+                Yaml.createYamlSequenceBuilder()
+                    .add("yegor")
+                    .add("paolo")
+                    .add("cesar")
+                    .build()
+            )
+            .build();
+        MatcherAssert.assertThat(sequences, Matchers.notNullValue());
+        MatcherAssert.assertThat(sequences, Matchers.instanceOf(Stream.class));
+        MatcherAssert.assertThat(
+            sequences.values(), Matchers.iterableWithSize(3)
+        );
+        MatcherAssert.assertThat(
+            sequences.toString(),
+            Matchers.equalTo(this.readTestResource("streamOfSequences.yml"))
+        );
+    }
+    
+    /**
+     * BuiltYamlStreams can hold a stream of mixed nodes.
+     * @throws Exception If something goes wrong.
+     */
+    @Test
+    public void builtStreamOfMixed() throws Exception {
+        final YamlStream mixed = Yaml.createYamlStreamBuilder()
+                .add(
+                    Yaml.createYamlMappingBuilder()
+                        .add("architect", "mihai")
+                        .add(
+                            "developers",
+                            Yaml.createYamlSequenceBuilder()
+                                .add("rultor")
+                                .add("salikjan")
+                                .add("sherif")
+                                .build()
+                        )
+                        .add("name", "eo-yaml")
+                        .build()
+                )
+                .add(
+                    Yaml.createYamlSequenceBuilder()
+                        .add("yegor")
+                        .add("paolo")
+                        .add("cesar")
+                        .build()
+                )
+                .add(
+                    Yaml.createYamlMappingBuilder()
+                        .add("architect", "felicia")
+                        .add(
+                            "developer", "sara"
+                        )
+                        .add("name", "docker-java-api")
+                        .build()
+                )
+                .build();
+        MatcherAssert.assertThat(mixed, Matchers.notNullValue());
+        MatcherAssert.assertThat(mixed, Matchers.instanceOf(Stream.class));
+        MatcherAssert.assertThat(
+            mixed.values(), Matchers.iterableWithSize(3)
+        );
+        MatcherAssert.assertThat(
+            mixed.toString(),
+            Matchers.equalTo(this.readTestResource("streamMixed.yml"))
+        );
+    }
+    
+    /**
+     * According to the comparison rules, any YamlStream is always considered
+     * "greater than" a scalar.
+     */
+    @Test
+    public void greaterThanAScalar() {
+        final YamlStream stream = Yaml.createYamlStreamBuilder().build();
+        MatcherAssert.assertThat(
+            stream.compareTo(new Scalar("test")),
+            Matchers.greaterThan(0)
+        );
+    }
+    
+    /**
+     * According to the comparison rules, any YamlStream is always considered
+     * "greater than" a mapping.
+     */
+    @Test
+    public void greaterThanAMapping() {
+        final YamlStream stream = Yaml.createYamlStreamBuilder().build();
+        MatcherAssert.assertThat(
+            stream.compareTo(Mockito.mock(YamlMapping.class)),
+            Matchers.greaterThan(0)
+        );
+    }
+    
+    /**
+     * According to the comparison rules, any YamlStream is always considered
+     * "greater than" a sequence.
+     */
+    @Test
+    public void greaterThanASequence() {
+        final YamlStream stream = Yaml.createYamlStreamBuilder().build();
+        MatcherAssert.assertThat(
+            stream.compareTo(Mockito.mock(YamlSequence.class)),
+            Matchers.greaterThan(0)
+        );
+    }
+    
+    /**
+     * Two YamlStreams which are empty should be equal.
+     */
+    @Test
+    public void emptyStreamsAreEqual() {
+        final YamlStream first = Yaml.createYamlStreamBuilder().build();
+        final YamlStream second = Yaml.createYamlStreamBuilder().build();
+        MatcherAssert.assertThat(
+            first.compareTo(second),
+            Matchers.equalTo(0)
+        );
+        MatcherAssert.assertThat(
+            second.compareTo(first),
+            Matchers.equalTo(0)
+        );
+        MatcherAssert.assertThat(
+            first.equals(second),
+            Matchers.is(Boolean.TRUE)
+        );
+        MatcherAssert.assertThat(
+            second.equals(first),
+            Matchers.is(Boolean.TRUE)
+        );
+    }
+    
+    /**
+     * Two identical YamlStreams are equal.
+     */
+    @Test
+    public void streamsAreEqual() {
+        final YamlStream first = Yaml.createYamlStreamBuilder()
+            .add(
+                Yaml.createYamlSequenceBuilder()
+                    .add("rultor")
+                    .add("salikjan")
+                    .add("sherif")
+                    .build()
+            )
+            .add(
+                Yaml.createYamlSequenceBuilder()
+                    .add("andrei")
+                    .build()
+            )
+            .add(
+                Yaml.createYamlSequenceBuilder()
+                    .add("yegor")
+                    .add("paolo")
+                    .add("cesar")
+                    .build()
+            )
+            .build();
+        final YamlStream second = Yaml.createYamlStreamBuilder()
+            .add(
+                Yaml.createYamlSequenceBuilder()
+                    .add("rultor")
+                    .add("salikjan")
+                    .add("sherif")
+                    .build()
+            )
+            .add(
+                Yaml.createYamlSequenceBuilder()
+                    .add("andrei")
+                    .build()
+            )
+            .add(
+                Yaml.createYamlSequenceBuilder()
+                    .add("yegor")
+                    .add("paolo")
+                    .add("cesar")
+                    .build()
+            )
+            .build();
+        MatcherAssert.assertThat(
+            second.equals(first),
+            Matchers.is(Boolean.TRUE)
+        );
+        MatcherAssert.assertThat(
+            first.equals(second),
+            Matchers.is(Boolean.TRUE)
+        );
+        MatcherAssert.assertThat(
+            first.equals(first),
+            Matchers.is(Boolean.TRUE)
+        );
+        MatcherAssert.assertThat(
+            second.equals(second),
+            Matchers.is(Boolean.TRUE)
+        );
+    }
+    
+    /**
+     * Two different YamlStreams are equal.
+     */
+    @Test
+    public void differentStreamsAreNotEqual() {
+        final YamlStream first = Yaml.createYamlStreamBuilder()
+            .add(
+                Yaml.createYamlSequenceBuilder()
+                    .add("rultor")
+                    .add("salikjan")
+                    .add("sherif")
+                    .build()
+            )
+            .add(
+                Yaml.createYamlSequenceBuilder()
+                    .add("andrei")
+                    .build()
+            )
+            .add(
+                Yaml.createYamlSequenceBuilder()
+                    .add("yegor")
+                    .add("paolo")
+                    .add("cesar")
+                    .build()
+            )
+            .build();
+        final YamlStream second = Yaml.createYamlStreamBuilder()
+            .add(
+                Yaml.createYamlMappingBuilder()
+                    .add("architect", "felicia")
+                    .add(
+                        "developer", "sara"
+                    )
+                    .add("name", "docker-java-api")
+                    .build()
+            )
+            .build();
+        MatcherAssert.assertThat(
+            second.equals(first),
+            Matchers.is(Boolean.FALSE)
+        );
+        MatcherAssert.assertThat(
+            first.equals(second),
+            Matchers.is(Boolean.FALSE)
+        );
+    }
+    
+    /**
+     * BuiltYamlStreams can hold an empty stream.
+     * @throws Exception If something goes wrong.
+     */
+    @Test
+    public void builtEmptyStream() throws Exception {
+        final YamlStream mappings = Yaml.createYamlStreamBuilder().build();
+        MatcherAssert.assertThat(mappings, Matchers.notNullValue());
+        MatcherAssert.assertThat(mappings, Matchers.instanceOf(Stream.class));
+        MatcherAssert.assertThat(
+            mappings.values(), Matchers.iterableWithSize(0)
+        );
+        MatcherAssert.assertThat(
+            mappings.toString(),
+            Matchers.equalTo("---\n...")
+        );
+    }
+    
+    /**
+     * Read a test resource file's contents.
+     * @param fileName File to read.
+     * @return File's contents as String.
+     * @throws FileNotFoundException If somethig is wrong.
+     * @throws IOException If somethig is wrong.
+     */
+    private String readTestResource(final String fileName)
+        throws FileNotFoundException, IOException {
+        return new String(
+            IOUtils.toByteArray(
+                new FileInputStream(
+                    new File("src/test/resources/" + fileName)
+                )
+            )
+        );
+    }
+    
+}
diff --git a/src/test/java/com/amihaiemil/eoyaml/RtYamlInputTest.java b/src/test/java/com/amihaiemil/eoyaml/RtYamlInputTest.java
index 06d1cf8..ad53e86 100644
--- a/src/test/java/com/amihaiemil/eoyaml/RtYamlInputTest.java
+++ b/src/test/java/com/amihaiemil/eoyaml/RtYamlInputTest.java
@@ -186,5 +186,16 @@ public final class RtYamlInputTest {
 
         MatcherAssert.assertThat(read, Matchers.equalTo(expected));
     }
+    
+    /**
+     * Reading of YamlStream is not yet implemented, an exception should
+     * be thrown.
+     * @throws Exception If something goes wrong.
+     */
+    @Test (expected = UnsupportedOperationException.class)
+    public void readingYamlStreamNotImplemented() throws Exception {
+        final YamlInput input = Yaml.createYamlInput("");
+        input.readYamlStream();
+    }
 
 }
diff --git a/src/test/java/com/amihaiemil/eoyaml/RtYamlMappingBuilderTest.java b/src/test/java/com/amihaiemil/eoyaml/RtYamlMappingBuilderTest.java
index 984cab0..fe7ee71 100644
--- a/src/test/java/com/amihaiemil/eoyaml/RtYamlMappingBuilderTest.java
+++ b/src/test/java/com/amihaiemil/eoyaml/RtYamlMappingBuilderTest.java
@@ -28,9 +28,7 @@
 package com.amihaiemil.eoyaml;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import org.hamcrest.MatcherAssert;
 import org.hamcrest.Matchers;
@@ -55,10 +53,6 @@ public final class RtYamlMappingBuilderTest {
         MatcherAssert.assertThat(
             mappingBuilder, Matchers.not(Matchers.is(withAdded))
         );
-        Map<String, String> test = new HashMap<>();
-        test.put("1", "2");
-        test.put("2", "5");
-        test.put("3", "6");
     }
 
     /**
diff --git a/src/test/java/com/amihaiemil/eoyaml/RtYamlStreamBuilderTest.java b/src/test/java/com/amihaiemil/eoyaml/RtYamlStreamBuilderTest.java
new file mode 100644
index 0000000..e7626e3
--- /dev/null
+++ b/src/test/java/com/amihaiemil/eoyaml/RtYamlStreamBuilderTest.java
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2016-2020, Mihai Emil Andronache
+ * All rights reserved.
+ *
+ * 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.stream.Stream;
+
+import org.hamcrest.MatcherAssert;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ * Unit tests for {@link RtYamlStreamBuilder}.
+ * @author Mihai Andronache (amihaiemil@gmail.com)
+ * @version $Id$
+ * @since 3.1.1
+ */
+public final class RtYamlStreamBuilderTest {
+    
+    /**
+     * RtYamlStreamBuilder can add a YamlSequence.
+     */
+    @Test
+    public void addsYamlSequence() {
+        YamlStreamBuilder streamBuilder = new RtYamlStreamBuilder();
+        YamlStreamBuilder withAdded = streamBuilder.add(
+            Mockito.mock(YamlSequence.class)              
+        );
+        MatcherAssert.assertThat(withAdded, Matchers.notNullValue());
+        MatcherAssert.assertThat(
+            streamBuilder, Matchers.not(Matchers.is(withAdded))
+        );
+    }
+    
+    /**
+     * RtYamlStreamBuilder can add a YamlMapping.
+     */
+    @Test
+    public void addsYamlMapping() {
+        YamlStreamBuilder streamBuilder = new RtYamlStreamBuilder();
+        YamlStreamBuilder withAdded = streamBuilder.add(
+            Mockito.mock(YamlMapping.class)              
+        );
+        MatcherAssert.assertThat(withAdded, Matchers.notNullValue());
+        MatcherAssert.assertThat(
+            streamBuilder, Matchers.not(Matchers.is(withAdded))
+        );
+    }
+    
+    /**
+     * RtYamlStreamBuilder can add a Scalar.
+     */
+    @Test
+    public void addsScalar() {
+        YamlStreamBuilder streamBuilder = new RtYamlStreamBuilder();
+        YamlStreamBuilder withAdded = streamBuilder.add(
+            new Scalar("test")            
+        );
+        MatcherAssert.assertThat(withAdded, Matchers.notNullValue());
+        MatcherAssert.assertThat(
+            streamBuilder, Matchers.not(Matchers.is(withAdded))
+        );
+    }
+    
+    /**
+     * RtYamlStreamBuilder can add a YamlNode.
+     */
+    @Test
+    public void addsYamlNode() {
+        YamlStreamBuilder streamBuilder = new RtYamlStreamBuilder();
+        YamlStreamBuilder withAdded = streamBuilder.add(
+            Mockito.mock(YamlNode.class)              
+        );
+        MatcherAssert.assertThat(withAdded, Matchers.notNullValue());
+        MatcherAssert.assertThat(
+            streamBuilder, Matchers.not(Matchers.is(withAdded))
+        );
+    }
+    
+    /**
+     * RtYamlStreamBuilder can build the YamlStream.
+     */
+    @Test
+    public void buildsYamlStream() {
+        final YamlStream stream = new RtYamlStreamBuilder()
+            .add(Mockito.mock(YamlMapping.class))
+            .add(Mockito.mock(YamlSequence.class))
+            .add(Mockito.mock(YamlNode.class))
+            .build();
+        
+        MatcherAssert.assertThat(stream, Matchers.notNullValue());
+        MatcherAssert.assertThat(stream, Matchers.instanceOf(Stream.class));
+        MatcherAssert.assertThat(
+              stream.values(), Matchers.iterableWithSize(3)
+        );
+    }
+    
+}
diff --git a/src/test/java/com/amihaiemil/eoyaml/YamlTest.java b/src/test/java/com/amihaiemil/eoyaml/YamlTest.java
index 2300153..128c8a3 100644
--- a/src/test/java/com/amihaiemil/eoyaml/YamlTest.java
+++ b/src/test/java/com/amihaiemil/eoyaml/YamlTest.java
@@ -62,6 +62,16 @@ public final class YamlTest {
         );
     }
 
+    /**
+     * Yaml can create a YamlStreamBuilder.
+     */
+    @Test
+    public void createsYamlStreamBuilder() {
+        MatcherAssert.assertThat(
+            Yaml.createYamlStreamBuilder(), Matchers.notNullValue()
+        );
+    }
+
     /**
      * Yaml can create a YamlInput from a File.
      * @throws Exception if something goes wrong
diff --git a/src/test/resources/streamMixed.yml b/src/test/resources/streamMixed.yml
new file mode 100644
index 0000000..56cb45b
--- /dev/null
+++ b/src/test/resources/streamMixed.yml
@@ -0,0 +1,15 @@
+---
+  architect: mihai
+  developers: 
+    - rultor
+    - salikjan
+    - sherif
+  name: eo-yaml
+---
+  - yegor
+  - paolo
+  - cesar
+---
+  architect: felicia
+  developer: sara
+  name: docker-java-api
\ No newline at end of file
diff --git a/src/test/resources/streamOfMappings.yml b/src/test/resources/streamOfMappings.yml
new file mode 100644
index 0000000..bafc1e5
--- /dev/null
+++ b/src/test/resources/streamOfMappings.yml
@@ -0,0 +1,16 @@
+---
+  architect: mihai
+  developers: 
+    - rultor
+    - salikjan
+    - sherif
+  name: eo-yaml
+---
+  architect: vlad
+  developers: 
+    - andrei
+  name: eo-json-impl
+---
+  architect: felicia
+  developer: sara
+  name: docker-java-api
\ No newline at end of file
diff --git a/src/test/resources/streamOfSequences.yml b/src/test/resources/streamOfSequences.yml
new file mode 100644
index 0000000..a17aeba
--- /dev/null
+++ b/src/test/resources/streamOfSequences.yml
@@ -0,0 +1,10 @@
+---
+  - rultor
+  - salikjan
+  - sherif
+---
+  - andrei
+---
+  - yegor
+  - paolo
+  - cesar
\ No newline at end of file