From 5029085bd9e2304bf259c1990ed92bf3bb351f24 Mon Sep 17 00:00:00 2001 From: amihaiemil Date: Tue, 14 Jul 2020 16:31:55 +0300 Subject: [PATCH] #382 fixed small bug regarding escaped scalars --- .../amihaiemil/eoyaml/ReadPlainScalar.java | 24 ++++++++++-- .../amihaiemil/eoyaml/ReadYamlMapping.java | 1 + .../amihaiemil/eoyaml/ReadYamlSequence.java | 14 ++++++- .../com/amihaiemil/eoyaml/RtYamlPrinter.java | 2 +- .../eoyaml/SameIndentationLevel.java | 15 +++++++- .../amihaiemil/eoyaml/RtYamlInputTest.java | 37 +++++++++++++++++++ .../resources/escapedScalarsInSequence.yml | 5 +++ 7 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 src/test/resources/escapedScalarsInSequence.yml diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadPlainScalar.java b/src/main/java/com/amihaiemil/eoyaml/ReadPlainScalar.java index 255238e9..b63bda55 100644 --- a/src/main/java/com/amihaiemil/eoyaml/ReadPlainScalar.java +++ b/src/main/java/com/amihaiemil/eoyaml/ReadPlainScalar.java @@ -70,12 +70,16 @@ final class ReadPlainScalar extends BaseScalar { public String value() { final String value; final String trimmed = this.scalar.trimmed(); - if(trimmed.contains(":") && !trimmed.endsWith(":")) { - value = trimmed.substring(trimmed.indexOf(":") + 1).trim(); - } else if(trimmed.startsWith("-") && trimmed.length() > 1) { + if(this.escapedSequenceScalar(this.scalar)) { value = trimmed.substring(trimmed.indexOf('-')+1).trim(); } else { - value = trimmed; + if (trimmed.contains(":") && !trimmed.endsWith(":")) { + value = trimmed.substring(trimmed.indexOf(":") + 1).trim(); + } else if (trimmed.startsWith("-") && trimmed.length() > 1) { + value = trimmed.substring(trimmed.indexOf('-') + 1).trim(); + } else { + value = trimmed; + } } if("null".equals(value)) { return null; @@ -125,4 +129,16 @@ private String unescape(final String value) { } return unescaped; } + + /** + * Returns true if there's a YamlMapping starting right after the + * dash, on the same line. + * @param dashLine Line. + * @return True of false. + */ + private boolean escapedSequenceScalar(final YamlLine dashLine) { + final String trimmed = dashLine.trimmed(); + return trimmed.matches("^[ ]*\\-[ ]*\".*\"$") + || trimmed.matches("^[ ]*\\-[ ]*\'.*\'$"); + } } diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadYamlMapping.java b/src/main/java/com/amihaiemil/eoyaml/ReadYamlMapping.java index ad271f65..41c690a3 100644 --- a/src/main/java/com/amihaiemil/eoyaml/ReadYamlMapping.java +++ b/src/main/java/com/amihaiemil/eoyaml/ReadYamlMapping.java @@ -225,6 +225,7 @@ public Comment comment() { * @param key String key. * @return YamlNode. * @checkstyle ReturnCount (50 lines) + * @checkstyle LineLength (30 lines) */ private YamlNode valueOfStringKey(final String key) { YamlNode value = null; diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadYamlSequence.java b/src/main/java/com/amihaiemil/eoyaml/ReadYamlSequence.java index 9a0c9470..3953cd56 100644 --- a/src/main/java/com/amihaiemil/eoyaml/ReadYamlSequence.java +++ b/src/main/java/com/amihaiemil/eoyaml/ReadYamlSequence.java @@ -150,7 +150,7 @@ public Collection values() { ) ); } else { - if(trimmed.matches("^.*\\-.*\\:.*$")) { + if(this.mappingStartsAtDash(line)) { kids.add( new ReadYamlMapping( new RtYamlLine("", line.number()-1), @@ -202,4 +202,16 @@ public Comment comment() { ); } + /** + * Returns true if there's a YamlMapping starting right after the + * dash, on the same line. + * @param dashLine Line. + * @return True of false. + */ + private boolean mappingStartsAtDash(final YamlLine dashLine) { + final String trimmed = dashLine.trimmed(); + final boolean escapedScalar = trimmed.matches("^[ ]*\\-[ ]*\".*\"$") + || trimmed.matches("^[ ]*\\-[ ]*\'.*\'$"); + return trimmed.matches("^.*\\-.*\\:.*$") && !escapedScalar; + } } diff --git a/src/main/java/com/amihaiemil/eoyaml/RtYamlPrinter.java b/src/main/java/com/amihaiemil/eoyaml/RtYamlPrinter.java index a7e57d35..04f0c60b 100644 --- a/src/main/java/com/amihaiemil/eoyaml/RtYamlPrinter.java +++ b/src/main/java/com/amihaiemil/eoyaml/RtYamlPrinter.java @@ -346,7 +346,7 @@ static class Escaped extends BaseScalar { /** * Special chars that need escaping. */ - private final String RESERVED = "#:->|$%&"; + private final String RESERVED = "#:->|$%&{}[]"; /** * Original unescaped scalar. diff --git a/src/main/java/com/amihaiemil/eoyaml/SameIndentationLevel.java b/src/main/java/com/amihaiemil/eoyaml/SameIndentationLevel.java index 7b3abca9..c0a5ecd5 100644 --- a/src/main/java/com/amihaiemil/eoyaml/SameIndentationLevel.java +++ b/src/main/java/com/amihaiemil/eoyaml/SameIndentationLevel.java @@ -77,7 +77,7 @@ public Iterator iterator() { final YamlLine first = iterator.next(); sameIndentation.add(first); int firstIndentation = first.indentation(); - if(first.trimmed().matches("^[ ]*\\-.*\\:.+$")) { + if(this.mappingStartsAtDash(first)) { firstIndentation += 2; } while (iterator.hasNext()) { @@ -106,4 +106,17 @@ public YamlNode toYamlNode( return this.yamlLines.toYamlNode(prev, guessIndentation); } + /** + * Returns true if there's a YamlMapping starting right after the + * dash, on the same line. + * @param dashLine Line. + * @return True of false. + */ + private boolean mappingStartsAtDash(final YamlLine dashLine) { + final String trimmed = dashLine.trimmed(); + final boolean escapedScalar = trimmed.matches("^[ ]*\\-[ ]*\".*\"$") + || trimmed.matches("^[ ]*\\-[ ]*\'.*\'$"); + return trimmed.matches("^[ ]*\\-.*\\:.+$") && !escapedScalar; + } + } diff --git a/src/test/java/com/amihaiemil/eoyaml/RtYamlInputTest.java b/src/test/java/com/amihaiemil/eoyaml/RtYamlInputTest.java index 6a455ef4..4b34c5cf 100644 --- a/src/test/java/com/amihaiemil/eoyaml/RtYamlInputTest.java +++ b/src/test/java/com/amihaiemil/eoyaml/RtYamlInputTest.java @@ -647,6 +647,43 @@ public void readsSequenceWithDashMappings() throws Exception { ); } + /** + * Some escaped scalars can be read from a sequence. + * @throws Exception If something goes wrong. + */ + @Test + public void readsEscapedScalarsFromSequence() throws Exception { + final YamlMapping map = Yaml.createYamlInput( + this.readTestResource("escapedScalarsInSequence.yml") + ).readYamlMapping(); + System.out.println(map); + final YamlSequence scalars = map.yamlSequence("scalars"); + MatcherAssert.assertThat( + scalars.string(0), + Matchers.equalTo( + "escaped: scalar, looks like mapping" + ) + ); + MatcherAssert.assertThat( + scalars.string(1), + Matchers.equalTo( + "{escaped: scalar, like: flow}" + ) + ); + MatcherAssert.assertThat( + scalars.string(2), + Matchers.equalTo( + "- escapedScalar3" + ) + ); + MatcherAssert.assertThat( + scalars.string(3), + Matchers.equalTo( + "[scalar, like, flow, sequence]" + ) + ); + } + /** * Read a test resource file's contents. * @param fileName File to read. diff --git a/src/test/resources/escapedScalarsInSequence.yml b/src/test/resources/escapedScalarsInSequence.yml new file mode 100644 index 00000000..9ba44f6b --- /dev/null +++ b/src/test/resources/escapedScalarsInSequence.yml @@ -0,0 +1,5 @@ +scalars: + - "escaped: scalar, looks like mapping" + - "{escaped: scalar, like: flow}" + - "- escapedScalar3" + - "[scalar, like, flow, sequence]" \ No newline at end of file