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

Issue:
Plain Scalar's Comment Only On Self Line
Scalars should look for comments only on their own line, like this:

```yaml
# this atm is seen as a comment for the 'value' scalar bellow
key: value # but this is actually the comment of the scalar, above is the comment of the mapping
```

Pull request:
Read Scalar Comment from Own Line
fixes #302 
In the case of plain scalars, we read only the comment which is on the same line, right after it. Otherwise, the comment's ownership gets messy when we are in the context of a map or a sequence. 

Patch:
diff --git a/src/main/java/com/amihaiemil/eoyaml/AllYamlLines.java b/src/main/java/com/amihaiemil/eoyaml/AllYamlLines.java
index adc256e..9aa2eab 100644
--- a/src/main/java/com/amihaiemil/eoyaml/AllYamlLines.java
+++ b/src/main/java/com/amihaiemil/eoyaml/AllYamlLines.java
@@ -117,6 +117,7 @@ final class AllYamlLines implements YamlLines {
         } else if(this.original().size() == 1) {
             node = new ReadPlainScalar(this, first);
         } else {
+            System.out.println("LINE IS: [" + first.trimmed() + "]");
             throw new YamlReadingException(
                 "Could not parse YAML starting at line " + (first.number() + 1)
                 + " . It should be a sequence (line should start with '-'), "
diff --git a/src/main/java/com/amihaiemil/eoyaml/BaseScalar.java b/src/main/java/com/amihaiemil/eoyaml/BaseScalar.java
index a90180a..25ab5c5 100644
--- a/src/main/java/com/amihaiemil/eoyaml/BaseScalar.java
+++ b/src/main/java/com/amihaiemil/eoyaml/BaseScalar.java
@@ -127,7 +127,11 @@ abstract class BaseScalar extends BaseYamlNode implements Scalar {
             printed.append(" ");
             spaces--;
         }
-        return printed.append(this.value()).toString();
+        printed.append(this.value());
+        if(!this.comment().value().isEmpty()) {
+            printed.append(" # ").append(this.comment().value());
+        }
+        return printed.toString();
     }
 
 }
diff --git a/src/main/java/com/amihaiemil/eoyaml/BaseYamlMapping.java b/src/main/java/com/amihaiemil/eoyaml/BaseYamlMapping.java
index 07eee29..82e2bf9 100644
--- a/src/main/java/com/amihaiemil/eoyaml/BaseYamlMapping.java
+++ b/src/main/java/com/amihaiemil/eoyaml/BaseYamlMapping.java
@@ -169,22 +169,15 @@ public abstract class BaseYamlMapping
             print.append(alignment);
             final BaseYamlNode indKey = (BaseYamlNode) key;
             final BaseYamlNode value = (BaseYamlNode) this.value(key);
-            this.printPossibleComment(
-                value.comment(), print, alignment.toString()
-            );
+            if(!(value instanceof Scalar)) {
+                this.printPossibleComment(
+                        value.comment(), print, alignment.toString()
+                );
+            }
             if(indKey instanceof Scalar) {
                 print
                     .append(indKey.indent(0))
                     .append(":");
-                if (value instanceof Scalar) {
-                    print.append(" ");
-                    this.printScalar((Scalar) value, print, indentation);
-                } else  {
-                    print
-                        .append(newLine)
-                        .append(value.indent(indentation + 2))
-                        .append(newLine);
-                }
             } else {
                 print
                     .append("?")
@@ -193,15 +186,15 @@ public abstract class BaseYamlMapping
                     .append(newLine)
                     .append(alignment)
                     .append(":");
-                if(value instanceof Scalar) {
-                    print.append(" ");
-                    this.printScalar((Scalar) value, print, indentation);
-                } else {
-                    print
-                        .append(newLine)
-                        .append(value.indent(indentation + 2))
-                        .append(newLine);
-                }
+            }
+            if (value instanceof Scalar) {
+                print.append(" ");
+                this.printScalar((Scalar) value, print, indentation);
+            } else  {
+                print
+                    .append(newLine)
+                    .append(value.indent(indentation + 2))
+                    .append(newLine);
             }
         }
         String printed = print.toString();
diff --git a/src/main/java/com/amihaiemil/eoyaml/BaseYamlSequence.java b/src/main/java/com/amihaiemil/eoyaml/BaseYamlSequence.java
index 5157930..c2485a1 100644
--- a/src/main/java/com/amihaiemil/eoyaml/BaseYamlSequence.java
+++ b/src/main/java/com/amihaiemil/eoyaml/BaseYamlSequence.java
@@ -149,14 +149,16 @@ public abstract class BaseYamlSequence
             spaces--;
         }
         for (final YamlNode node : this.values()) {
-            this.printPossibleComment(node.comment(), print, alignment.toString());
-            print
-                .append(alignment)
-                .append("-");
             if (node instanceof Scalar) {
+                print
+                    .append(alignment)
+                    .append("-");
                 this.printScalar((Scalar) node, print, indentation);
             } else  {
+                this.printPossibleComment(node.comment(), print, alignment.toString());
                 print
+                    .append(alignment)
+                    .append("-")
                     .append(newLine)
                     .append(((BaseYamlNode) node).indent(indentation + 2))
                     .append(newLine);
diff --git a/src/main/java/com/amihaiemil/eoyaml/CachedYamlLine.java b/src/main/java/com/amihaiemil/eoyaml/CachedYamlLine.java
index 35ed3be..0c17524 100644
--- a/src/main/java/com/amihaiemil/eoyaml/CachedYamlLine.java
+++ b/src/main/java/com/amihaiemil/eoyaml/CachedYamlLine.java
@@ -78,6 +78,11 @@ final class CachedYamlLine implements YamlLine {
         return this.trimmed;
     }
 
+    @Override
+    public String comment() {
+        return this.line.comment();
+    }
+
     @Override
     public int number() {
         return this.line.number();
diff --git a/src/main/java/com/amihaiemil/eoyaml/FirstCommentFound.java b/src/main/java/com/amihaiemil/eoyaml/FirstCommentFound.java
index 4621df1..a315780 100644
--- a/src/main/java/com/amihaiemil/eoyaml/FirstCommentFound.java
+++ b/src/main/java/com/amihaiemil/eoyaml/FirstCommentFound.java
@@ -66,7 +66,7 @@ final class FirstCommentFound implements YamlLines {
             final List<YamlLine> comment = new ArrayList<>();
             while (iterator.hasNext()) {
                 YamlLine line = iterator.next();
-                if(line.trimmed().startsWith("#")) {
+                if(!line.comment().isEmpty()) {
                     comment.add(line);
                 } else {
                     break;
diff --git a/src/main/java/com/amihaiemil/eoyaml/NoCommentsYamlLine.java b/src/main/java/com/amihaiemil/eoyaml/NoCommentsYamlLine.java
index c0136ae..60c1a54 100644
--- a/src/main/java/com/amihaiemil/eoyaml/NoCommentsYamlLine.java
+++ b/src/main/java/com/amihaiemil/eoyaml/NoCommentsYamlLine.java
@@ -82,6 +82,11 @@ final class NoCommentsYamlLine implements YamlLine {
         return trimmed.trim();
     }
 
+    @Override
+    public String comment() {
+        return "";
+    }
+
     @Override
     public int number() {
         return this.line.number();
diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadComment.java b/src/main/java/com/amihaiemil/eoyaml/ReadComment.java
index 789ef69..b9d6aaf 100644
--- a/src/main/java/com/amihaiemil/eoyaml/ReadComment.java
+++ b/src/main/java/com/amihaiemil/eoyaml/ReadComment.java
@@ -65,7 +65,7 @@ final class ReadComment implements Comment {
         final StringBuilder comment = new StringBuilder();
         for(final YamlLine line : this.lines) {
             comment
-                .append(line.trimmed().substring(1).trim())
+                .append(line.comment().trim())
                 .append(System.lineSeparator());
         }
         return comment.toString().trim();
diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadPlainScalar.java b/src/main/java/com/amihaiemil/eoyaml/ReadPlainScalar.java
index 55459f8..8807f27 100644
--- a/src/main/java/com/amihaiemil/eoyaml/ReadPlainScalar.java
+++ b/src/main/java/com/amihaiemil/eoyaml/ReadPlainScalar.java
@@ -81,15 +81,9 @@ final class ReadPlainScalar extends BaseScalar {
         } else {
             comment = new ReadComment(
                 new FirstCommentFound(
-                    new Backwards(
-                        new Skip(
-                            this.all,
-                            line -> line.number() >= this.scalar.number(),
-                            line -> line.trimmed().startsWith("---"),
-                            line -> line.trimmed().startsWith("..."),
-                            line -> line.trimmed().startsWith("%"),
-                            line -> line.trimmed().startsWith("!!")
-                        )
+                    new Skip(
+                        this.all,
+                        line -> line.number() != this.scalar.number()
                     )
                 ),
                 this
diff --git a/src/main/java/com/amihaiemil/eoyaml/RtYamlLine.java b/src/main/java/com/amihaiemil/eoyaml/RtYamlLine.java
index b83603e..c6f1584 100644
--- a/src/main/java/com/amihaiemil/eoyaml/RtYamlLine.java
+++ b/src/main/java/com/amihaiemil/eoyaml/RtYamlLine.java
@@ -83,6 +83,31 @@ final class RtYamlLine implements YamlLine {
         return trimmed.trim();
     }
 
+    @Override
+    public String comment() {
+        String comment = "";
+        String trimmed = this.value.trim();
+        int i = 0;
+        while(i < trimmed.length()) {
+            if(trimmed.charAt(i) == '#') {
+                comment = trimmed.substring(i + 1);
+                break;
+            } else if(trimmed.charAt(i) == '"') {
+                i++;
+                while(i < trimmed.length() && trimmed.charAt(i) != '"') {
+                    i++;
+                }
+            } else if(trimmed.charAt(i) == '\'') {
+                i++;
+                while(i < trimmed.length() && trimmed.charAt(i) != '\'') {
+                    i++;
+                }
+            }
+            i++;
+        }
+        return comment.trim();
+    }
+
     @Override
     public int number() {
         return this.number;
diff --git a/src/main/java/com/amihaiemil/eoyaml/YamlLine.java b/src/main/java/com/amihaiemil/eoyaml/YamlLine.java
index 08f0ca0..d4ef4af 100644
--- a/src/main/java/com/amihaiemil/eoyaml/YamlLine.java
+++ b/src/main/java/com/amihaiemil/eoyaml/YamlLine.java
@@ -36,11 +36,17 @@ package com.amihaiemil.eoyaml;
 interface YamlLine extends Comparable<YamlLine> {
 
     /**
-     * The line's trimmed contents.
+     * The line's trimmed contents with comments, aliases etc removed.
      * @return String contents.
      */
     String trimmed();
 
+    /**
+     * Return the comment, if any, from this line.
+     * @return Comment of empty string.
+     */
+    String comment();
+
     /**
      * Number of the line (count start from 0).
      * @return Integer.
@@ -71,6 +77,11 @@ interface YamlLine extends Comparable<YamlLine> {
             return "";
         }
 
+        @Override
+        public String comment() {
+            return "";
+        }
+
         @Override
         public int number() {
             return -1;


Test patch:
diff --git a/src/test/java/com/amihaiemil/eoyaml/FirstCommentFoundTest.java b/src/test/java/com/amihaiemil/eoyaml/FirstCommentFoundTest.java
index ba0b175..22d57c4 100644
--- a/src/test/java/com/amihaiemil/eoyaml/FirstCommentFoundTest.java
+++ b/src/test/java/com/amihaiemil/eoyaml/FirstCommentFoundTest.java
@@ -106,12 +106,12 @@ public final class FirstCommentFoundTest {
         MatcherAssert.assertThat(comment, Matchers.iterableWithSize(2));
         final Iterator<YamlLine> commIt = comment.iterator();
         MatcherAssert.assertThat(
-            commIt.next().trimmed(),
-            Matchers.equalTo("# YAML document for")
+            commIt.next().comment(),
+            Matchers.equalTo("YAML document for")
         );
         MatcherAssert.assertThat(
-            commIt.next().trimmed(),
-            Matchers.equalTo("# test purposes:")
+            commIt.next().comment(),
+            Matchers.equalTo("test purposes:")
         );
     }
 
diff --git a/src/test/java/com/amihaiemil/eoyaml/ReadPlainScalarTest.java b/src/test/java/com/amihaiemil/eoyaml/ReadPlainScalarTest.java
index 5320e1b..619875e 100644
--- a/src/test/java/com/amihaiemil/eoyaml/ReadPlainScalarTest.java
+++ b/src/test/java/com/amihaiemil/eoyaml/ReadPlainScalarTest.java
@@ -74,16 +74,15 @@ public final class ReadPlainScalarTest {
     public void returnsCommentFromSequenceLine() {
         final List<YamlLine> lines = new ArrayList<>();
         lines.add(new RtYamlLine("- value1", 0));
-        lines.add(new RtYamlLine("# Comment about value 2", 1));
-        lines.add(new RtYamlLine("- value2", 2));
-        lines.add(new RtYamlLine("- value3", 3));
+        lines.add(new RtYamlLine("- value2 # Comment here", 1));
+        lines.add(new RtYamlLine("- value3", 2));
         final Scalar scalar = new ReadPlainScalar(
-            new AllYamlLines(lines), lines.get(2)
+            new AllYamlLines(lines), lines.get(1)
         );
         final Comment comment = scalar.comment();
         MatcherAssert.assertThat(
             comment.value(),
-            Matchers.equalTo("Comment about value 2")
+            Matchers.equalTo("Comment here")
         );
         MatcherAssert.assertThat(comment.yamlNode(), Matchers.is(scalar));
     }
@@ -96,16 +95,15 @@ public final class ReadPlainScalarTest {
     public void returnsCommentFromMappingLine() {
         final List<YamlLine> lines = new ArrayList<>();
         lines.add(new RtYamlLine("key1: value1", 0));
-        lines.add(new RtYamlLine("# Comment about value 2", 1));
-        lines.add(new RtYamlLine("key2: value2", 2));
-        lines.add(new RtYamlLine("key3: value3", 3));
+        lines.add(new RtYamlLine("key2: value2 # Comment here", 1));
+        lines.add(new RtYamlLine("key3: value3", 2));
         final Scalar scalar = new ReadPlainScalar(
-            new AllYamlLines(lines), lines.get(2)
+            new AllYamlLines(lines), lines.get(1)
         );
         final Comment comment = scalar.comment();
         MatcherAssert.assertThat(
             comment.value(),
-            Matchers.equalTo("Comment about value 2")
+            Matchers.equalTo("Comment here")
         );
         MatcherAssert.assertThat(comment.yamlNode(), Matchers.is(scalar));
     }
diff --git a/src/test/java/com/amihaiemil/eoyaml/RtYamlLineTest.java b/src/test/java/com/amihaiemil/eoyaml/RtYamlLineTest.java
index 1847bb4..76a7bf7 100644
--- a/src/test/java/com/amihaiemil/eoyaml/RtYamlLineTest.java
+++ b/src/test/java/com/amihaiemil/eoyaml/RtYamlLineTest.java
@@ -76,13 +76,109 @@ public final class RtYamlLineTest {
      * RtYamlLine can trim itself.
      */
     @Test
-    public void trimmsItself() {
+    public void trimsItself() {
         YamlLine line = new RtYamlLine("   this: line   ", 10);
         MatcherAssert.assertThat(
             line.trimmed(), Matchers.equalTo("this: line")
         );
     }
 
+    /**
+     * RtYamlLine can trim off the comments.
+     */
+    @Test
+    public void trimsCommentsOff() {
+        YamlLine line = new RtYamlLine("this: line  #has a comment ", 0);
+        MatcherAssert.assertThat(
+            line.trimmed(), Matchers.equalTo("this: line")
+        );
+    }
+
+    /**
+     * RtYamlLine will not trim the '#' because it is escaped and part
+     * of a value.
+     */
+    @Test
+    public void doesNotTrimEscapedHash() {
+        YamlLine line = new RtYamlLine("color: '#404040' # comment here", 0);
+        MatcherAssert.assertThat(
+                line.trimmed(), Matchers.equalTo("color: '#404040'")
+        );
+    }
+
+    /**
+     * RtYamlLine returns the contained comment.
+     */
+    @Test
+    public void returnsComment() {
+        YamlLine line = new RtYamlLine("color: '#404040' # comment here", 0);
+        MatcherAssert.assertThat(
+            line.comment(), Matchers.equalTo("comment here")
+        );
+    }
+
+    /**
+     * RtYamlLine returns the comment which is the whole line.
+     */
+    @Test
+    public void returnsCommentWholeLine() {
+        YamlLine line = new RtYamlLine(
+            "# line containing only a comment", 0
+        );
+        MatcherAssert.assertThat(
+            line.comment(),
+            Matchers.equalTo("line containing only a comment")
+        );
+    }
+
+    /**
+     * RtYamlLine returns an empty comment as the line is only a hash.
+     */
+    @Test
+    public void returnsEmptyLineComment() {
+        YamlLine line = new RtYamlLine("#", 0);
+        MatcherAssert.assertThat(
+            line.comment(),
+            Matchers.isEmptyString()
+        );
+    }
+
+    /**
+     * RtYamlLine returns an empty comment.
+     */
+    @Test
+    public void returnsEmptyComment() {
+        YamlLine line = new RtYamlLine("test: value #", 0);
+        MatcherAssert.assertThat(
+            line.comment(),
+            Matchers.isEmptyString()
+        );
+    }
+
+    /**
+     * RtYamlLine returns an empty comment from an empty line.
+     */
+    @Test
+    public void returnsEmptyCommentFromEmptyLine() {
+        YamlLine line = new RtYamlLine("", 0);
+        MatcherAssert.assertThat(
+            line.comment(),
+            Matchers.isEmptyString()
+        );
+    }
+
+
+    /**
+     * RtYamlLine can trim off the anchors.
+     */
+    @Test
+    public void trimsAnchorOff() {
+        YamlLine line = new RtYamlLine("this: line  &anc ", 0);
+        MatcherAssert.assertThat(
+                line.trimmed(), Matchers.equalTo("this: line")
+        );
+    }
+
     /**
      * RtYamlLine returns indentation.
      */
diff --git a/src/test/java/com/amihaiemil/eoyaml/YamlMappingCommentsPrintTest.java b/src/test/java/com/amihaiemil/eoyaml/YamlMappingCommentsPrintTest.java
index 38d6127..7adb066 100644
--- a/src/test/java/com/amihaiemil/eoyaml/YamlMappingCommentsPrintTest.java
+++ b/src/test/java/com/amihaiemil/eoyaml/YamlMappingCommentsPrintTest.java
@@ -30,7 +30,7 @@ package com.amihaiemil.eoyaml;
 import org.apache.commons.io.IOUtils;
 import org.hamcrest.MatcherAssert;
 import org.hamcrest.Matchers;
-import org.junit.Ignore;
+
 import org.junit.Test;
 
 import java.io.File;
@@ -85,7 +85,6 @@ public final class YamlMappingCommentsPrintTest {
      * @throws Exception If something goes wrong.
      */
     @Test
-    @Ignore
     public void printsReadYamlMappingWithComments() throws Exception {
         final YamlMapping read = Yaml.createYamlInput(
             new File("src/test/resources/commentedMapping.yml")
diff --git a/src/test/resources/commentedMapping.yml b/src/test/resources/commentedMapping.yml
index 49020e3..a0e1172 100644
--- a/src/test/resources/commentedMapping.yml
+++ b/src/test/resources/commentedMapping.yml
@@ -5,5 +5,4 @@ developers:
   - rultor
   - salikjan
   - sherif
-# name of the project
-name: eo-yaml
\ No newline at end of file
+name: eo-yaml # name of the project
\ No newline at end of file
diff --git a/src/test/resources/commentedSequence.yml b/src/test/resources/commentedSequence.yml
index fb707c9..0a60d20 100644
--- a/src/test/resources/commentedSequence.yml
+++ b/src/test/resources/commentedSequence.yml
@@ -1,7 +1,6 @@
 # a sequence with comments
 - element1
-# a plain scalar string in a sequence
-- element2
+- element2 # a plain scalar string in a sequence
 - element3
 # a mapping as an element of a sequence
 -