Repository: decorators-squad/eo-yaml
Pull request #523 (2022-11-10 13:16:53)

Do not fail with an indention error if there are emtpy block scalars
The current implementation fails with an indention error if a YAML contains empty block scalars. This PR fixes this.


Patch:
diff --git a/src/main/java/com/amihaiemil/eoyaml/WellIndented.java b/src/main/java/com/amihaiemil/eoyaml/WellIndented.java
index 42d89bf..89562b6 100644
--- a/src/main/java/com/amihaiemil/eoyaml/WellIndented.java
+++ b/src/main/java/com/amihaiemil/eoyaml/WellIndented.java
@@ -124,17 +124,21 @@ final class WellIndented implements YamlLines {
                     int lineIndent = line.indentation();
                     if(previous.requireNestedIndentation()) {
                         if(lineIndent != prevIndent + 2) {
-                            if(this.guessIndentation) {
-                                line = new Indented(line, prevIndent + 2);
-                            } else {
-                                throw new YamlIndentationException(
-                                    "Indentation of line " + (line.number() + 1)
-                                  + " [" + line.trimmed() + "]"
-                                  + " is not ok. It should be greater than the one"
-                                  + " of line " + (previous.number() + 1)
-                                  + " [" + previous.trimmed() + "]"
-                                  + " by 2 spaces."
-                                );
+                            final CharSequence prevLineLastChar =
+                                    previous.trimmed().substring(previous.trimmed().length() - 1);
+                            if (!(">|".contains(prevLineLastChar) && lineIndent == prevIndent)) {
+                                if (this.guessIndentation) {
+                                    line = new Indented(line, prevIndent + 2);
+                                } else {
+                                    throw new YamlIndentationException(
+                                            "Indentation of line " + (line.number() + 1)
+                                            + " [" + line.trimmed() + "]"
+                                            + " is not ok. It should be greater than the one"
+                                            + " of line " + (previous.number() + 1)
+                                            + " [" + previous.trimmed() + "]"
+                                            + " by 2 spaces."
+                                    );
+                                }
                             }
                         }
                     } else {


Test patch:
diff --git a/src/test/java/com/amihaiemil/eoyaml/RtYamlInputTest.java b/src/test/java/com/amihaiemil/eoyaml/RtYamlInputTest.java
index 1569e60..eb0214e 100644
--- a/src/test/java/com/amihaiemil/eoyaml/RtYamlInputTest.java
+++ b/src/test/java/com/amihaiemil/eoyaml/RtYamlInputTest.java
@@ -1020,6 +1020,53 @@ public final class RtYamlInputTest {
                                  Matchers.equalTo("value:with-colon"));
     }
 
+    /**
+     * Unit test to ensure empty block scalars are read properly.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void shouldReadEmptyBlockScalarProperly() throws IOException {
+        final String filename = "emptyLiteralScalar.yml";
+
+        final YamlMapping read = new RtYamlInput(
+                new FileInputStream("src/test/resources/" + filename)
+        ).readYamlMapping();
+
+        MatcherAssert.assertThat(read.type(), Matchers.equalTo(Node.MAPPING));
+        MatcherAssert.assertThat(
+                read.asMapping().keys(),
+                Matchers.hasSize(3));
+
+        final YamlNode emptyLiteralScalar = read.asMapping().value("empty_literal_scalar");
+        MatcherAssert.assertThat(
+                emptyLiteralScalar.type(),
+                Matchers.equalTo(Node.SCALAR));
+        MatcherAssert.assertThat(
+                emptyLiteralScalar.asScalar().value(),
+                Matchers.equalTo(""));
+
+        final YamlNode emptyFoldedScalar = read.asMapping().value("empty_folded_scalar");
+        MatcherAssert.assertThat(
+                emptyFoldedScalar.type(),
+                Matchers.equalTo(Node.SCALAR));
+        MatcherAssert.assertThat(
+                emptyFoldedScalar.asScalar().value(),
+                Matchers.equalTo(""));
+
+        YamlNode topLevelSequence = read.asMapping().value("a_sequence");
+        MatcherAssert.assertThat(
+                topLevelSequence.type(),
+                Matchers.equalTo(Node.SEQUENCE));
+        MatcherAssert.assertThat(topLevelSequence.asSequence().values(),
+                                 Matchers.hasSize(1));
+        YamlNode sequenceItem = topLevelSequence.asSequence().values()
+                                                .iterator().next();
+        MatcherAssert.assertThat(sequenceItem.type(),
+                                 Matchers.equalTo(Node.SCALAR));
+        MatcherAssert.assertThat(sequenceItem.asScalar().value(),
+                                 Matchers.equalTo("test"));
+    }
+
     /**
      * Read a test resource file's contents.
      * @param fileName File to read.
diff --git a/src/test/resources/emptyLiteralScalar.yml b/src/test/resources/emptyLiteralScalar.yml
new file mode 100644
index 0000000..56f129d
--- /dev/null
+++ b/src/test/resources/emptyLiteralScalar.yml
@@ -0,0 +1,5 @@
+empty_literal_scalar: |
+empty_folded_scalar: >
+
+a_sequence:
+  - test