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

Issue:
Move indentation validation (WellIndentedLine) at YamlLines level
This check should be done at YamlLines level, rather than at the single-line level.

Pull request:
validation of indentation at YamlLines level
Fixes #194

Patch:
diff --git a/src/main/java/com/amihaiemil/eoyaml/AllYamlLines.java b/src/main/java/com/amihaiemil/eoyaml/AllYamlLines.java
index c670eb6..631899c 100644
--- a/src/main/java/com/amihaiemil/eoyaml/AllYamlLines.java
+++ b/src/main/java/com/amihaiemil/eoyaml/AllYamlLines.java
@@ -69,11 +69,6 @@ final class AllYamlLines implements YamlLines {
         return this.lines;
     }
     
-    @Override
-    public int count() {
-        return this.lines.size();
-    }
-
     @Override
     public YamlNode toYamlNode(final YamlLine prev) {
         final String trimmed = prev.trimmed();
diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadYamlMapping.java b/src/main/java/com/amihaiemil/eoyaml/ReadYamlMapping.java
index 858dc32..147ee9e 100644
--- a/src/main/java/com/amihaiemil/eoyaml/ReadYamlMapping.java
+++ b/src/main/java/com/amihaiemil/eoyaml/ReadYamlMapping.java
@@ -47,7 +47,9 @@ final class ReadYamlMapping extends ComparableYamlMapping {
      * @param lines Given lines.
      */
     ReadYamlMapping(final AllYamlLines lines) {
-        this.lines = new SameIndentationLevel((AllYamlLines) lines);
+        this.lines = new SameIndentationLevel(
+            new WellIndented(lines)
+        );
     }
 
     @Override
@@ -201,7 +203,7 @@ final class ReadYamlMapping extends ComparableYamlMapping {
                 final YamlNode keyNode = keyLines.toYamlNode(line);
                 if(keyNode.equals(key)) {
                     final YamlLine colonLine = this.lines.line(
-                        line.number() + keyLines.count() + 1
+                        line.number() + keyLines.lines().size() + 1
                     );
                     if(":".equals(colonLine.trimmed())) {
                         value = this.lines.nested(colonLine.number())
diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadYamlSequence.java b/src/main/java/com/amihaiemil/eoyaml/ReadYamlSequence.java
index 09b8555..09e4c49 100644
--- a/src/main/java/com/amihaiemil/eoyaml/ReadYamlSequence.java
+++ b/src/main/java/com/amihaiemil/eoyaml/ReadYamlSequence.java
@@ -50,7 +50,9 @@ final class ReadYamlSequence extends ComparableYamlSequence {
      * @param lines Given lines.
      */
     ReadYamlSequence(final AllYamlLines lines) {
-        this.lines = new SameIndentationLevel((AllYamlLines) lines);
+        this.lines = new SameIndentationLevel(
+            new WellIndented(lines)
+        );
     }
 
     @Override
diff --git a/src/main/java/com/amihaiemil/eoyaml/RtYamlInput.java b/src/main/java/com/amihaiemil/eoyaml/RtYamlInput.java
index 29bd9c9..63923dd 100644
--- a/src/main/java/com/amihaiemil/eoyaml/RtYamlInput.java
+++ b/src/main/java/com/amihaiemil/eoyaml/RtYamlInput.java
@@ -79,23 +79,14 @@ final class RtYamlInput implements YamlInput {
         ) {
             String line;
             int number = 0;
-            YamlLine previous = new YamlLine.NullYamlLine();
             while ((line = reader.readLine()) != null) {
                 final YamlLine current = new NoCommentsYamlLine(
                     new RtYamlLine(line, number)
                 );
                 if(!current.trimmed().isEmpty()) {
-                    lines.add(
-                        new CachedYamlLine(
-                            new WellIndentedLine(
-                                previous,
-                                current
-                            )
-                        )
-                    );
-                    number++;
-                    previous = current;
+                    lines.add(new CachedYamlLine(current));
                 }
+                number++;
             }
         }
         return new AllYamlLines(lines);
diff --git a/src/main/java/com/amihaiemil/eoyaml/SameIndentationLevel.java b/src/main/java/com/amihaiemil/eoyaml/SameIndentationLevel.java
index f296c09..80955a6 100644
--- a/src/main/java/com/amihaiemil/eoyaml/SameIndentationLevel.java
+++ b/src/main/java/com/amihaiemil/eoyaml/SameIndentationLevel.java
@@ -33,7 +33,7 @@ import java.util.Iterator;
 import java.util.List;
 
 /**
- * SameIndentationLevel. Decorates "all" the YamlLines
+ * SameIndentationLevel. Decorates some YamlLines
  * and iterates only over those which are at the same
  * indentation level with the first one.
  * @author Mihai Andronache (amihaiemil@gmail.com)
@@ -43,16 +43,16 @@ import java.util.List;
 final class SameIndentationLevel implements YamlLines {
 
     /**
-     * All YamlLines, unaltered.
+     * YamlLines.
      */
-    private final AllYamlLines all;
+    private final YamlLines yamlLines;
 
     /**
      * Ctor.
-     * @param all All the Yaml lines.
+     * @param yamlLines The Yaml lines.
      */
-    SameIndentationLevel(final AllYamlLines all) {
-        this.all = all;
+    SameIndentationLevel(final YamlLines yamlLines) {
+        this.yamlLines = yamlLines;
     }
 
     /**
@@ -63,7 +63,7 @@ final class SameIndentationLevel implements YamlLines {
      */
     @Override
     public Iterator<YamlLine> iterator() {
-        Iterator<YamlLine> iterator = this.all.iterator();
+        Iterator<YamlLine> iterator = this.yamlLines.iterator();
         if (iterator.hasNext()) {
             final List<YamlLine> sameIndentation = new ArrayList<>();
             final YamlLine first = iterator.next();
@@ -81,17 +81,12 @@ final class SameIndentationLevel implements YamlLines {
 
     @Override
     public Collection<YamlLine> lines() {
-        return this.all.lines();
-    }
-
-    @Override
-    public int count() {
-        return this.lines().size();
+        return this.yamlLines.lines();
     }
 
     @Override
     public YamlNode toYamlNode(final YamlLine prev) {
-        return this.all.toYamlNode(prev);
+        return this.yamlLines.toYamlNode(prev);
     }
 
 }
diff --git a/src/main/java/com/amihaiemil/eoyaml/WellIndented.java b/src/main/java/com/amihaiemil/eoyaml/WellIndented.java
new file mode 100644
index 0000000..f7d19f7
--- /dev/null
+++ b/src/main/java/com/amihaiemil/eoyaml/WellIndented.java
@@ -0,0 +1,137 @@
+/**
+ * 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.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * YamlLines decorator which iterates over them and verifies
+ * that their indentation is correct.<br><br>
+ * Initially, we used to do this validation at line level, right when each
+ * line is being read (in {@link RtYamlInput}). However, we decided
+ * to do it at YamlLines level, as a decorator, because
+ * in some cases, we need to eliminate some of them first (markers,
+ * directives etc). <br><br>
+ * 
+ * This class can be used as follows:
+ * 
+ * <pre>
+ * 
+ * YamlLines wellIndented = new SameIndentationLevel(
+ *     new WellIndented(lines)
+ * );//Iterate over the lines which are at the same indentation level
+ * </pre>
+ * or
+ * <pre>
+ * 
+ * YamlLines wellIndented = new SameIndentationLevel(
+ *     new WellIndented(
+ *         new NoMarkersOrDirectives(
+ *             lines
+ *         )//ignore markers or directives
+ *     )
+ * );//Iterate over the lines which are at the same indentation level
+ * </pre>
+ * 
+ * @author Mihai Andronache (amihaiemil@gmail.com)
+ * @version $Id$
+ * @since 3.1.2
+ *
+ */
+final class WellIndented implements YamlLines {
+
+    /**
+     * YamlLines.
+     */
+    private final YamlLines yamlLines;
+
+    /**
+     * Ctor.
+     * @param yamlLines The Yaml lines.
+     */
+    WellIndented(final YamlLines yamlLines) {
+        this.yamlLines = yamlLines;
+    }
+    
+    /**
+     * Returns an iterator over these Yaml lines.
+     * It will verify that each line is properly indented in relation
+     * to the previous one and will complain if the indentation is not
+     * correct.
+     * @return Iterator over these yaml lines.
+     */
+    @Override
+    public Iterator<YamlLine> iterator() {
+        final Iterator<YamlLine> iterator = this.yamlLines.iterator();
+        final List<YamlLine> wellIndented = new ArrayList<>();
+        YamlLine previous;
+        if(iterator.hasNext()) {
+            previous = iterator.next();
+            wellIndented.add(previous);
+            while(iterator.hasNext()) {
+                YamlLine line = iterator.next();
+                int prevIndent = previous.indentation();
+                int lineIndent = line.indentation();
+                if(previous.hasNestedNode()) {
+                    if(lineIndent != prevIndent+2) {
+                        throw new IllegalStateException(
+                            "Indentation of line " + line.number()
+                             + " is not ok. It should be greater than the"
+                             + " previous line's by 2"
+                        );
+                    }
+                } else {
+                    if(lineIndent > prevIndent) {
+                        throw new IllegalStateException(
+                            "Indentation of line " + line.number() + " is "
+                            + "greater than the previous one's. "
+                            + "It should be less or equal."
+                        );
+                    }
+                }
+                previous = line;
+                wellIndented.add(line);
+            }
+        }
+        return wellIndented.iterator();
+    }
+    
+    @Override
+    public Collection<YamlLine> lines() {
+        return this.yamlLines.lines();
+    }
+
+    @Override
+    public YamlNode toYamlNode(final YamlLine prev) {
+        return this.yamlLines.toYamlNode(prev);
+    }
+
+}
diff --git a/src/main/java/com/amihaiemil/eoyaml/WellIndentedLine.java b/src/main/java/com/amihaiemil/eoyaml/WellIndentedLine.java
deleted file mode 100644
index 8ca8924..0000000
--- a/src/main/java/com/amihaiemil/eoyaml/WellIndentedLine.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- * 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;
-
-/**
- * Decorator for YamlLine to check if the line is well indented relative to the
- * previous one.
- * @author Sherif Waly (sherifwaly95@gmail.com)
- * @version $Id$
- * @since 1.0.0
- *
- */
-final class WellIndentedLine implements YamlLine {
-
-    /**
-     * Content line.
-     */
-    private YamlLine line;
-
-    /**
-     * Previous line.
-     */
-    private YamlLine previousLine;
-
-    /**
-     * Ctor.
-     * @param previous YamlLine
-     * @param current YamlLine
-     */
-    WellIndentedLine(final YamlLine previous, final YamlLine current) {
-        this.previousLine = previous;
-        this.line = current;
-    }
-
-    @Override
-    public String trimmed() {
-        return this.line.trimmed();
-    }
-
-    @Override
-    public int number() {
-        return this.line.number();
-    }
-
-    @Override
-    public int indentation() {
-        final int lineIndent = this.line.indentation();
-        final int previousLineIndent = this.previousLine.indentation();
-        if(this.previousLine.hasNestedNode()) {
-            if(lineIndent != previousLineIndent+2) {
-                throw new IllegalStateException(
-                    "Indentation of line " + this.line.number() + " isn't ok. "
-                     + " It should be greater than the previous line's by 2"
-                );
-            }
-        } else {
-            if(lineIndent > previousLineIndent) {
-                throw new IllegalStateException(
-                    "Indentation of line " + this.line.number() + " is "
-                    + "greater than the previous one's"
-                );
-            }
-        }
-        return lineIndent;
-    }
-
-    @Override
-    public String toString() {
-        return this.line.toString();
-    }
-
-    @Override
-    public int compareTo(final YamlLine other) {
-        return this.line.compareTo(other);
-    }
-
-    @Override
-    public boolean hasNestedNode() {
-        return this.line.hasNestedNode();
-    }
-}
diff --git a/src/main/java/com/amihaiemil/eoyaml/YamlLines.java b/src/main/java/com/amihaiemil/eoyaml/YamlLines.java
index 666ba09..eabf71b 100644
--- a/src/main/java/com/amihaiemil/eoyaml/YamlLines.java
+++ b/src/main/java/com/amihaiemil/eoyaml/YamlLines.java
@@ -41,16 +41,12 @@ import java.util.List;
 interface YamlLines extends Iterable<YamlLine> {
 
     /**
-     * All the YAML lines, as a collection.
+     * All the YAML lines, as a collection.<br>
+     * This method should always return all the lines
+     * there are, irrespective of iteration logic!
      * @return These YamlLines as a Collection.
      */
     Collection<YamlLine> lines();
-    
-    /**
-     * Number of lines.
-     * @return Integer.
-     */
-    int count();
 
     /**
      * Turn these lines into a YamlNode.


Test patch:
diff --git a/src/test/java/com/amihaiemil/eoyaml/ReadYamlMappingTest.java b/src/test/java/com/amihaiemil/eoyaml/ReadYamlMappingTest.java
index 017c76d..5a3bdd5 100644
--- a/src/test/java/com/amihaiemil/eoyaml/ReadYamlMappingTest.java
+++ b/src/test/java/com/amihaiemil/eoyaml/ReadYamlMappingTest.java
@@ -177,7 +177,7 @@ public final class ReadYamlMappingTest {
         
         final YamlMapping map = new ReadYamlMapping(new AllYamlLines(lines));
         System.out.print(map);
-        final Collection<YamlNode> children = map.children();
+        final Collection<YamlNode> children = map.values();
         MatcherAssert.assertThat(
             children, Matchers.iterableWithSize(5)
         );
@@ -477,8 +477,8 @@ public final class ReadYamlMappingTest {
         lines.add(new RtYamlLine("  complex1: mapping1", 2));
         lines.add(new RtYamlLine("  complex2: mapping2", 3));
         lines.add(new RtYamlLine(":", 4));
-        lines.add(new RtYamlLine(" - some", 5));
-        lines.add(new RtYamlLine(" - sequence", 6));
+        lines.add(new RtYamlLine("  - some", 5));
+        lines.add(new RtYamlLine("  - sequence", 6));
         lines.add(new RtYamlLine("second: something", 7));
         final YamlMapping map = new ReadYamlMapping(new AllYamlLines(lines));
         System.out.print(map);
@@ -502,8 +502,8 @@ public final class ReadYamlMappingTest {
         lines.add(new RtYamlLine("  - sequence", 2));
         lines.add(new RtYamlLine("  - key", 3));
         lines.add(new RtYamlLine(":", 4));
-        lines.add(new RtYamlLine(" - some", 5));
-        lines.add(new RtYamlLine(" - sequence", 6));
+        lines.add(new RtYamlLine("  - some", 5));
+        lines.add(new RtYamlLine("  - sequence", 6));
         lines.add(new RtYamlLine("second: something", 7));
         final YamlMapping map = new ReadYamlMapping(new AllYamlLines(lines));
         
diff --git a/src/test/java/com/amihaiemil/eoyaml/SameIndentationLevelTestCase.java b/src/test/java/com/amihaiemil/eoyaml/SameIndentationLevelTestCase.java
index 2748b12..287fec6 100644
--- a/src/test/java/com/amihaiemil/eoyaml/SameIndentationLevelTestCase.java
+++ b/src/test/java/com/amihaiemil/eoyaml/SameIndentationLevelTestCase.java
@@ -64,27 +64,6 @@ public final class SameIndentationLevelTestCase {
         );
     }
     
-    /**
-     * SameIndentationLevel should return its line count, the number
-     * of all the lines that it encapsulates.
-     */
-    @Test
-    public void fetchesCount() {
-        final List<YamlLine> lines = new ArrayList<>();
-        lines.add(new RtYamlLine("first: somethingElse", 0));
-        lines.add(new RtYamlLine("second: ", 1));
-        lines.add(new RtYamlLine("  fourth: some", 2));
-        lines.add(new RtYamlLine("  fifth: values", 3));
-        lines.add(new RtYamlLine("third: something", 4));
-        final YamlLines yaml = new SameIndentationLevel(
-            new AllYamlLines(lines)
-        );
-        MatcherAssert.assertThat(
-            yaml.count(),
-            Matchers.equalTo(lines.size())
-        );
-    }
-    
     /**
      * SameIndentationLevel should iterate only over the lines,
      * which have the same level of indentation.
diff --git a/src/test/java/com/amihaiemil/eoyaml/WellIndentedLineTest.java b/src/test/java/com/amihaiemil/eoyaml/WellIndentedLineTest.java
deleted file mode 100644
index 06dd011..0000000
--- a/src/test/java/com/amihaiemil/eoyaml/WellIndentedLineTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * 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 org.hamcrest.MatcherAssert;
-import org.hamcrest.Matchers;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link WellIndentedLine}.
- * @author Mihai Andronache (amihaiemil@gmail.com)
- * @version $Id$
- * @since 1.0.0
- *
- */
-public final class WellIndentedLineTest {
-
-    /**
-     * WellIndentedLine knows its number.
-     */
-    @Test
-    public void knowsNumber() {
-        YamlLine line = new WellIndentedLine(
-            new RtYamlLine("previus", 11),
-            new RtYamlLine("this line", 12)
-        );
-        MatcherAssert.assertThat(line.number(), Matchers.is(12));
-    }
-
-    /**
-     * WellIndentedLine can trim itself.
-     */
-    @Test
-    public void trimmsItself() {
-        YamlLine line = new WellIndentedLine(
-            new RtYamlLine("previusline", 9),
-            new RtYamlLine("   this: line   ", 10)
-        );
-        MatcherAssert.assertThat(
-            line.trimmed(), Matchers.equalTo("this: line")
-        );
-    }
-
-    /**
-     * WellIndentedLine returns its, indentation if it's right.
-     */
-    @Test
-    public void isWellIndented() {
-        YamlLine line = new WellIndentedLine(
-            new RtYamlLine("previusline: ", 9),
-            new RtYamlLine("  this: line", 10)
-        );
-        MatcherAssert.assertThat(
-            line.indentation(), Matchers.is(2)
-        );
-    }
-
-    /**
-     * WellIndentedLine throws ISE when the indentation
-     * is not correct (not greater than 2 relative to the previous line).
-     */
-    @Test (expected = IllegalStateException.class)
-    public void exceptionWhenTooLittleIndentation() {
-        YamlLine line = new WellIndentedLine(
-            new RtYamlLine("previusline: |- ", 9),
-            new RtYamlLine(" test", 10)
-        );
-        line.indentation();
-    }
-
-    /**
-     * WellIndentedLine throws ISE when the indentation
-     * is not correct (if the previous line doesn't end with a
-     * special character, then the line's indentation must be the same).
-     */
-    @Test (expected = IllegalStateException.class)
-    public void exceptionWhenTooMuchIndentation() {
-        YamlLine line = new WellIndentedLine(
-            new RtYamlLine("- previusline", 9),
-            new RtYamlLine("  - right ", 10)
-        );
-        line.indentation();
-    }
-
-}
diff --git a/src/test/java/com/amihaiemil/eoyaml/WellIndentedTest.java b/src/test/java/com/amihaiemil/eoyaml/WellIndentedTest.java
new file mode 100644
index 0000000..d0e4584
--- /dev/null
+++ b/src/test/java/com/amihaiemil/eoyaml/WellIndentedTest.java
@@ -0,0 +1,169 @@
+/**
+ * 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.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.hamcrest.MatcherAssert;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import org.junit.Assert;
+
+/**
+ * Unit tests for {@link WellIndented}.
+ * @author Mihai Andronache
+ * @version $Id$
+ * @since 3.1.2
+ */
+public final class WellIndentedTest {
+
+    /**
+     * WellIndented can return the encapsulated lines.
+     */
+    @Test
+    @SuppressWarnings("unchecked")
+    public void returnsLines() {
+        final YamlLines lines = Mockito.mock(YamlLines.class);
+        final Collection<YamlLine> collection = Mockito.mock(Collection.class);
+        Mockito.when(lines.lines()).thenReturn(collection);
+        MatcherAssert.assertThat(
+            new WellIndented(lines).lines(),
+            Matchers.is(collection)
+        );
+    }
+    
+    /**
+     * WellIndented can turn itself into YamlNode.
+     */
+    @Test
+    public void turnsIntoYamlNode() {
+        final YamlLines lines = Mockito.mock(YamlLines.class);
+        final YamlLine prev = Mockito.mock(YamlLine.class);
+        final YamlNode result = Mockito.mock(YamlNode.class);
+        Mockito.when(lines.toYamlNode(prev)).thenReturn(result);
+        MatcherAssert.assertThat(
+            new WellIndented(lines).toYamlNode(prev),
+            Matchers.is(result)
+        );
+    }
+    
+    /**
+     * WellIndented validates correctly-indented lines.
+     */
+    @Test
+    public void validatesProperLines() {
+        final List<YamlLine> lines = new ArrayList<>();
+        lines.add(new RtYamlLine("first: somethingElse", 0));
+        lines.add(new RtYamlLine("second: ", 1));
+        lines.add(new RtYamlLine("  fourth: some", 2));
+        lines.add(new RtYamlLine("  fifth: values", 3));
+        lines.add(new RtYamlLine("third:", 4));
+        lines.add(new RtYamlLine("  - seq", 5));
+        final YamlLines wiLines = new WellIndented(new AllYamlLines(lines));
+        MatcherAssert.assertThat(
+            wiLines,
+            Matchers.iterableWithSize(6)
+        );
+    }
+    
+    /**
+     * WellIndented complains on badly indented nested mapping.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void complainsOnBadlyIndentedNestedMapping() {
+        final List<YamlLine> lines = new ArrayList<>();
+        lines.add(new RtYamlLine("first: somethingElse", 0));
+        lines.add(new RtYamlLine("second: ", 1));
+        lines.add(new RtYamlLine(" fourth: some", 2));
+        lines.add(new RtYamlLine("  notok: values", 3));
+        lines.add(new RtYamlLine("third: something", 4));
+        final YamlLines wiLines = new WellIndented(new AllYamlLines(lines));
+        MatcherAssert.assertThat(
+            wiLines,
+            Matchers.iterableWithSize(5)
+        );
+        Assert.fail("IllegalStateException was expected!");
+    }
+    
+    /**
+     * WellIndented complains on badly indented nested sequence.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void complainsOnBadlyIndentedNestedSequence() {
+        final List<YamlLine> lines = new ArrayList<>();
+        lines.add(new RtYamlLine("first: somethingElse", 0));
+        lines.add(new RtYamlLine("second: ", 1));
+        lines.add(new RtYamlLine("  - ok", 2));
+        lines.add(new RtYamlLine("   - notok", 3));
+        lines.add(new RtYamlLine("third: something", 4));
+        final YamlLines wiLines = new WellIndented(new AllYamlLines(lines));
+        MatcherAssert.assertThat(
+            wiLines,
+            Matchers.iterableWithSize(5)
+        );
+        Assert.fail("IllegalStateException was expected!");
+    }
+    
+    /**
+     * WellIndented complains on badly indented sequence.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void complainsOnBadlyIndentedSequence() {
+        final List<YamlLine> lines = new ArrayList<>();
+        lines.add(new RtYamlLine("- first", 0));
+        lines.add(new RtYamlLine("- second", 1));
+        lines.add(new RtYamlLine(" - third_not_ok", 2));
+        final YamlLines wiLines = new WellIndented(new AllYamlLines(lines));
+        MatcherAssert.assertThat(
+            wiLines,
+            Matchers.iterableWithSize(3)
+        );
+        Assert.fail("IllegalStateException was expected!");
+    }
+    
+    /**
+     * WellIndented complains on badly indented mapping.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void complainsOnBadlyIndentedMapping() {
+        final List<YamlLine> lines = new ArrayList<>();
+        lines.add(new RtYamlLine("first: somethingElse", 0));
+        lines.add(new RtYamlLine("  second_not_ok: value ", 1));
+        lines.add(new RtYamlLine("third: something", 2));
+        final YamlLines wiLines = new WellIndented(new AllYamlLines(lines));
+        MatcherAssert.assertThat(
+            wiLines,
+            Matchers.iterableWithSize(3)
+        );
+        Assert.fail("IllegalStateException was expected!");
+    }
+}