From 95f12af8278204e61ec5cbe5a99e0312b4d96850 Mon Sep 17 00:00:00 2001 From: amihaiemil Date: Sat, 13 Apr 2024 18:55:32 +0300 Subject: [PATCH 1/2] #618 ReadFlowMapping.comment() implemented --- .../amihaiemil/eoyaml/ReadFlowMapping.java | 60 ++++++++++++++++--- .../amihaiemil/eoyaml/ReadFlowSequence.java | 36 ++++++++--- .../eoyaml/ReadFlowMappingTestCase.java | 44 ++++++++++++-- .../eoyaml/ReadFlowSequenceTestCase.java | 21 +++++-- 4 files changed, 136 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadFlowMapping.java b/src/main/java/com/amihaiemil/eoyaml/ReadFlowMapping.java index 6bc75c78..b8c9195c 100644 --- a/src/main/java/com/amihaiemil/eoyaml/ReadFlowMapping.java +++ b/src/main/java/com/amihaiemil/eoyaml/ReadFlowMapping.java @@ -41,11 +41,19 @@ * @author Mihai Andronache (amihaiemil@gmail.com) * @version $Id$ * @since 8.0.0 - * @todo #615:60min Implement the comment() method properly (at the moment - * it always assumes there is no comment). */ final class ReadFlowMapping extends BaseYamlMapping { + /** + * All the lines of the YAML document. + */ + private final AllYamlLines all; + + /** + * Previous line just before the one where this flow sequence starts. + */ + private final YamlLine previous; + /** * The entries of this flow mapping as String. */ @@ -84,7 +92,9 @@ final class ReadFlowMapping extends BaseYamlMapping { ), '{', '}' - ).line(previous.number() < 0 ? 0 : previous.number() + 1) + ).line(previous.number() < 0 ? 0 : previous.number() + 1), + previous, + lines ); } @@ -92,8 +102,14 @@ final class ReadFlowMapping extends BaseYamlMapping { * Constructor. * @param folded All the YAML lines of this flow mapping, * folded into a single one. + * @param previous Line previous to where this flow mapping starts. + * @param all All the lines of the YAML document. */ - ReadFlowMapping(final YamlLine folded) { + ReadFlowMapping( + final YamlLine folded, final YamlLine previous, final AllYamlLines all + ) { + this.previous = previous; + this.all = all; this.entries = new StringEntries(folded); this.folded = folded; } @@ -123,7 +139,33 @@ public YamlNode value(final YamlNode key) { @Override public Comment comment() { - return new BuiltComment(this, ""); + boolean documentComment = this.previous.number() < 0; + //@checkstyle LineLength (50 lines) + return new ReadComment( + new Backwards( + new FirstCommentFound( + new Backwards( + new Skip( + this.all, + line -> { + final boolean skip; + if(documentComment) { + skip = line.number() >= this.folded.number(); + } else { + skip = line.number() >= this.previous.number(); + } + return skip; + }, + line -> line.trimmed().startsWith("..."), + line -> line.trimmed().startsWith("%"), + line -> line.trimmed().startsWith("!!") + ) + ), + documentComment + ) + ), + this + ); } /** @@ -135,11 +177,15 @@ private YamlNode stringToYamlNodeNode(final String node) { final YamlNode yaml; if (node.startsWith("[")) { yaml = new ReadFlowSequence( - new RtYamlLine(node, this.folded.number()) + new RtYamlLine(node, this.folded.number()), + this.previous, + this.all ); } else if (node.startsWith("{")) { yaml = new ReadFlowMapping( - new RtYamlLine(node, this.folded.number()) + new RtYamlLine(node, this.folded.number()), + this.previous, + this.all ); } else { yaml = new PlainStringScalar(node.trim()); diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadFlowSequence.java b/src/main/java/com/amihaiemil/eoyaml/ReadFlowSequence.java index 1ebec367..8a7bf783 100644 --- a/src/main/java/com/amihaiemil/eoyaml/ReadFlowSequence.java +++ b/src/main/java/com/amihaiemil/eoyaml/ReadFlowSequence.java @@ -40,6 +40,16 @@ */ final class ReadFlowSequence extends BaseYamlSequence { + /** + * All the lines of the document. + */ + private final AllYamlLines all; + + /** + * Previous line just before the one where this flow sequence starts. + */ + private final YamlLine previous; + /** * The entries of this flow sequence as String. */ @@ -61,14 +71,14 @@ final class ReadFlowSequence extends BaseYamlSequence { /** * Ctor. * @param previous Line just before the start of this flow sequence. - * @param lines All lines of the YAML document. + * @param all All lines of the YAML document. * @checkstyle AvoidInlineConditionals (30 lines) */ - ReadFlowSequence(final YamlLine previous, final AllYamlLines lines) { + ReadFlowSequence(final YamlLine previous, final AllYamlLines all) { this( new CollapsedFlowLines( new Skip( - lines, + all, line -> line.number() <= previous.number(), line -> line.trimmed().startsWith("#"), line -> line.trimmed().startsWith("---"), @@ -78,7 +88,9 @@ final class ReadFlowSequence extends BaseYamlSequence { ), '[', ']' - ).line(previous.number() < 0 ? 0 : previous.number() + 1) + ).line(previous.number() < 0 ? 0 : previous.number() + 1), + previous, + all ); } @@ -86,8 +98,14 @@ final class ReadFlowSequence extends BaseYamlSequence { * Constructor. * @param folded All the YAML lines of this flow sequence, * folded into a single one. + * @param previous Line previous to where this flow mapping starts. + * @param all All the lines of the YAML document. */ - ReadFlowSequence(final YamlLine folded) { + ReadFlowSequence( + final YamlLine folded, final YamlLine previous, final AllYamlLines all + ) { + this.previous = previous; + this.all = all; this.entries = new StringNodes(folded); this.folded = folded; } @@ -99,13 +117,17 @@ public Collection values() { if (node.startsWith("[")) { kids.add( new ReadFlowSequence( - new RtYamlLine(node, this.folded.number()) + new RtYamlLine(node, this.folded.number()), + this.previous, + this.all ) ); } else if(node.startsWith("{")) { kids.add( new ReadFlowMapping( - new RtYamlLine(node, this.folded.number()) + new RtYamlLine(node, this.folded.number()), + this.previous, + this.all ) ); } else { diff --git a/src/test/java/com/amihaiemil/eoyaml/ReadFlowMappingTestCase.java b/src/test/java/com/amihaiemil/eoyaml/ReadFlowMappingTestCase.java index f19c9fca..eedb50ea 100644 --- a/src/test/java/com/amihaiemil/eoyaml/ReadFlowMappingTestCase.java +++ b/src/test/java/com/amihaiemil/eoyaml/ReadFlowMappingTestCase.java @@ -30,8 +30,6 @@ import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.Test; -import org.mockito.Mockito; - import java.util.Arrays; import java.util.Collection; import java.util.Iterator; @@ -46,16 +44,50 @@ public final class ReadFlowMappingTestCase { /** - * YamlMapping in flow format has no comment. + * YamlMapping in flow format can return the document comment. */ @Test - public void hasNoComment() { + public void hasDocumentComment() { final YamlMapping map = new ReadFlowMapping( - Mockito.mock(YamlLine.class) + new RtYamlLine("{a: b, c: d, e: f}", 2), + new RtYamlLine("---", 1), + new AllYamlLines( + Arrays.asList( + new RtYamlLine("# this is a flow mapping document", 0), + new RtYamlLine("---", 1), + new RtYamlLine("{a: b, c: d, e: f}", 2) + ) + ) + ); + MatcherAssert.assertThat( + map.comment().value(), + Matchers.equalTo("this is a flow mapping document") + ); + MatcherAssert.assertThat( + map.comment().yamlNode(), + Matchers.is(map) + ); + } + + /** + * YamlMapping in flow format can return the comment referring to it. + */ + @Test + public void hasOwnNodeComment() { + final YamlMapping map = new ReadFlowMapping( + new RtYamlLine("{a: {i: j}, c: d, e: f}", 2), + new RtYamlLine("flow:", 1), + new AllYamlLines( + Arrays.asList( + new RtYamlLine("# this comment about the 'flow' map", 0), + new RtYamlLine("flow:", 1), + new RtYamlLine(" {a: {i: j}, c: d, e: f}", 2) + ) + ) ); MatcherAssert.assertThat( map.comment().value(), - Matchers.isEmptyString() + Matchers.equalTo("this comment about the 'flow' map") ); MatcherAssert.assertThat( map.comment().yamlNode(), diff --git a/src/test/java/com/amihaiemil/eoyaml/ReadFlowSequenceTestCase.java b/src/test/java/com/amihaiemil/eoyaml/ReadFlowSequenceTestCase.java index ca4b720b..6ce88bc2 100644 --- a/src/test/java/com/amihaiemil/eoyaml/ReadFlowSequenceTestCase.java +++ b/src/test/java/com/amihaiemil/eoyaml/ReadFlowSequenceTestCase.java @@ -32,6 +32,7 @@ import org.junit.Test; import org.mockito.Mockito; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; @@ -50,7 +51,9 @@ public final class ReadFlowSequenceTestCase { @Test public void hasNoComment() { final YamlSequence seq = new ReadFlowSequence( - Mockito.mock(YamlLine.class) + Mockito.mock(YamlLine.class), + Mockito.mock(YamlLine.class), + new AllYamlLines(new ArrayList<>()) ); MatcherAssert.assertThat( seq.comment().value(), @@ -68,7 +71,9 @@ public void hasNoComment() { @Test public void hasNoValues() { final YamlSequence seq = new ReadFlowSequence( - new RtYamlLine("[]", 0) + new RtYamlLine("[]", 0), + Mockito.mock(YamlLine.class), + new AllYamlLines(new ArrayList<>()) ); MatcherAssert.assertThat( seq.values(), @@ -82,7 +87,9 @@ public void hasNoValues() { @Test public void hasOnlyScalars() { final YamlSequence seq = new ReadFlowSequence( - new RtYamlLine("[a, b, c, d:e]", 0) + new RtYamlLine("[a, b, c, d:e]", 0), + Mockito.mock(YamlLine.class), + new AllYamlLines(new ArrayList<>()) ); final Collection values = seq.values(); MatcherAssert.assertThat(values, Matchers.iterableWithSize(4)); @@ -111,7 +118,9 @@ public void hasOnlyScalars() { @Test public void hasOnlySequences() { final YamlSequence seq = new ReadFlowSequence( - new RtYamlLine("[[a, b], [c,\"[a]\",'b]['], [d]]", 0) + new RtYamlLine("[[a, b], [c,\"[a]\",'b]['], [d]]", 0), + Mockito.mock(YamlLine.class), + new AllYamlLines(new ArrayList<>()) ); System.out.println(seq); MatcherAssert.assertThat( @@ -161,7 +170,9 @@ public void hasSequencesAndScalars() { final YamlSequence seq = new ReadFlowSequence( new RtYamlLine( "[scalar, \"u][\", 'v}{', 'escalar', [a, b], other, [d]]", 0 - ) + ), + Mockito.mock(YamlLine.class), + new AllYamlLines(new ArrayList<>()) ); System.out.println(seq); MatcherAssert.assertThat( From d4656491299b4579fde0ea08661a960c03be2e61 Mon Sep 17 00:00:00 2001 From: amihaiemil Date: Sat, 13 Apr 2024 19:19:41 +0300 Subject: [PATCH 2/2] #618 ReadFlowSequence.comment() implemented --- .../amihaiemil/eoyaml/ReadFlowSequence.java | 28 +++++++++++- .../eoyaml/ReadFlowMappingTestCase.java | 4 +- .../eoyaml/ReadFlowSequenceTestCase.java | 44 ++++++++++++++++--- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadFlowSequence.java b/src/main/java/com/amihaiemil/eoyaml/ReadFlowSequence.java index 8a7bf783..daf472e9 100644 --- a/src/main/java/com/amihaiemil/eoyaml/ReadFlowSequence.java +++ b/src/main/java/com/amihaiemil/eoyaml/ReadFlowSequence.java @@ -141,7 +141,33 @@ public Collection values() { @Override public Comment comment() { - return new BuiltComment(this, ""); + boolean documentComment = this.previous.number() < 0; + //@checkstyle LineLength (50 lines) + return new ReadComment( + new Backwards( + new FirstCommentFound( + new Backwards( + new Skip( + this.all, + line -> { + final boolean skip; + if(documentComment) { + skip = line.number() >= this.folded.number(); + } else { + skip = line.number() >= this.previous.number(); + } + return skip; + }, + line -> line.trimmed().startsWith("..."), + line -> line.trimmed().startsWith("%"), + line -> line.trimmed().startsWith("!!") + ) + ), + documentComment + ) + ), + this + ); } /** diff --git a/src/test/java/com/amihaiemil/eoyaml/ReadFlowMappingTestCase.java b/src/test/java/com/amihaiemil/eoyaml/ReadFlowMappingTestCase.java index eedb50ea..c7c9580f 100644 --- a/src/test/java/com/amihaiemil/eoyaml/ReadFlowMappingTestCase.java +++ b/src/test/java/com/amihaiemil/eoyaml/ReadFlowMappingTestCase.java @@ -44,7 +44,7 @@ public final class ReadFlowMappingTestCase { /** - * YamlMapping in flow format can return the document comment. + * ReadFlowMapping can return the document comment. */ @Test public void hasDocumentComment() { @@ -70,7 +70,7 @@ public void hasDocumentComment() { } /** - * YamlMapping in flow format can return the comment referring to it. + * ReadFlowMapping can return the comment referring to it. */ @Test public void hasOwnNodeComment() { diff --git a/src/test/java/com/amihaiemil/eoyaml/ReadFlowSequenceTestCase.java b/src/test/java/com/amihaiemil/eoyaml/ReadFlowSequenceTestCase.java index 6ce88bc2..78e32e0a 100644 --- a/src/test/java/com/amihaiemil/eoyaml/ReadFlowSequenceTestCase.java +++ b/src/test/java/com/amihaiemil/eoyaml/ReadFlowSequenceTestCase.java @@ -46,18 +46,50 @@ public final class ReadFlowSequenceTestCase { /** - * Sequences in flow/json style have no comment. + * ReadFlowSequence can return the document comment. */ @Test - public void hasNoComment() { + public void hasDocumentComment() { final YamlSequence seq = new ReadFlowSequence( - Mockito.mock(YamlLine.class), - Mockito.mock(YamlLine.class), - new AllYamlLines(new ArrayList<>()) + new RtYamlLine("[{a: b}, {c: d}, {e: f}]", 2), + new RtYamlLine("---", 1), + new AllYamlLines( + Arrays.asList( + new RtYamlLine("# this is a flow sequence document", 0), + new RtYamlLine("---", 1), + new RtYamlLine("[{a: b}, {c: d}, {e: f}]", 2) + ) + ) + ); + MatcherAssert.assertThat( + seq.comment().value(), + Matchers.equalTo("this is a flow sequence document") + ); + MatcherAssert.assertThat( + seq.comment().yamlNode(), + Matchers.is(seq) + ); + } + + /** + * ReadFlowMapping can return the comment referring to it. + */ + @Test + public void hasOwnNodeComment() { + final YamlSequence seq = new ReadFlowSequence( + new RtYamlLine("[{a: b}, {c: d}, {e: f}]", 2), + new RtYamlLine("flow_seq:", 1), + new AllYamlLines( + Arrays.asList( + new RtYamlLine("# this comment about the 'flow' seq", 0), + new RtYamlLine("flow:", 1), + new RtYamlLine(" [{a: b}, {c: d}, {e: f}]", 2) + ) + ) ); MatcherAssert.assertThat( seq.comment().value(), - Matchers.isEmptyString() + Matchers.equalTo("this comment about the 'flow' seq") ); MatcherAssert.assertThat( seq.comment().yamlNode(),