Repository: decorators-squad/eo-yaml
Pull request #310 (2020-04-11 07:24:34)

#134 empty values improvement: complain on empty/null key
PR for #134 
Better support for null/empty values. Handling null or empty keys when building maps.


Patch:
diff --git a/src/main/java/com/amihaiemil/eoyaml/BaseScalar.java b/src/main/java/com/amihaiemil/eoyaml/BaseScalar.java
index 25ab5c5..2d06eae 100644
--- a/src/main/java/com/amihaiemil/eoyaml/BaseScalar.java
+++ b/src/main/java/com/amihaiemil/eoyaml/BaseScalar.java
@@ -134,4 +134,8 @@ abstract class BaseScalar extends BaseYamlNode implements Scalar {
         return printed.toString();
     }
 
+    @Override
+    final boolean isEmpty() {
+        return this.value() == null || this.value().trim().isEmpty();
+    }
 }
diff --git a/src/main/java/com/amihaiemil/eoyaml/BaseYamlMapping.java b/src/main/java/com/amihaiemil/eoyaml/BaseYamlMapping.java
index 82e2bf9..4043e14 100644
--- a/src/main/java/com/amihaiemil/eoyaml/BaseYamlMapping.java
+++ b/src/main/java/com/amihaiemil/eoyaml/BaseYamlMapping.java
@@ -283,4 +283,9 @@ public abstract class BaseYamlMapping
         print.append(this.indent(0));
         return print.toString();
     }
+
+    @Override
+    final boolean isEmpty() {
+        return this.keys().isEmpty();
+    }
 }
diff --git a/src/main/java/com/amihaiemil/eoyaml/BaseYamlNode.java b/src/main/java/com/amihaiemil/eoyaml/BaseYamlNode.java
index f7425c9..4c7f3d6 100644
--- a/src/main/java/com/amihaiemil/eoyaml/BaseYamlNode.java
+++ b/src/main/java/com/amihaiemil/eoyaml/BaseYamlNode.java
@@ -41,6 +41,12 @@ package com.amihaiemil.eoyaml;
  */
 abstract class BaseYamlNode implements YamlNode {
 
+    /**
+     * Is this YamlNode empty?
+     * @return True or false.
+     */
+    abstract boolean isEmpty();
+
     /**
      * Print this YAML node with the given indentation.
      * When implementing this method, make sure to only use
diff --git a/src/main/java/com/amihaiemil/eoyaml/BaseYamlSequence.java b/src/main/java/com/amihaiemil/eoyaml/BaseYamlSequence.java
index c2485a1..e2089a6 100644
--- a/src/main/java/com/amihaiemil/eoyaml/BaseYamlSequence.java
+++ b/src/main/java/com/amihaiemil/eoyaml/BaseYamlSequence.java
@@ -253,4 +253,9 @@ public abstract class BaseYamlSequence
         print.append(this.indent(0));
         return print.toString();
     }
+
+    @Override
+    final boolean isEmpty() {
+        return this.values().isEmpty();
+    }
 }
diff --git a/src/main/java/com/amihaiemil/eoyaml/BaseYamlStream.java b/src/main/java/com/amihaiemil/eoyaml/BaseYamlStream.java
index 12a9c21..5e00633 100644
--- a/src/main/java/com/amihaiemil/eoyaml/BaseYamlStream.java
+++ b/src/main/java/com/amihaiemil/eoyaml/BaseYamlStream.java
@@ -201,4 +201,9 @@ abstract class BaseYamlStream extends BaseYamlNode implements YamlStream {
     public final String toString() {
         return this.indent(0);
     }
+
+    @Override
+    final boolean isEmpty() {
+        return this.values().isEmpty();
+    }
 }
diff --git a/src/main/java/com/amihaiemil/eoyaml/RtYamlMappingBuilder.java b/src/main/java/com/amihaiemil/eoyaml/RtYamlMappingBuilder.java
index c7f5f19..30539bb 100644
--- a/src/main/java/com/amihaiemil/eoyaml/RtYamlMappingBuilder.java
+++ b/src/main/java/com/amihaiemil/eoyaml/RtYamlMappingBuilder.java
@@ -80,10 +80,15 @@ final class RtYamlMappingBuilder implements YamlMappingBuilder {
 
     @Override
     public YamlMappingBuilder add(final YamlNode key, final YamlNode value) {
-        final Map<YamlNode, YamlNode> withAddedPair = new LinkedHashMap<>();
-        withAddedPair.putAll(this.pairs);
-        withAddedPair.put(key, value);
-        return new RtYamlMappingBuilder(withAddedPair);
+        if(key == null || ((BaseYamlNode) key).isEmpty()) {
+            throw new IllegalArgumentException(
+                "The key in YamlMapping cannot be null or empty!"
+            );
+        }
+        final Map<YamlNode, YamlNode> withAdded = new LinkedHashMap<>();
+        withAdded.putAll(this.pairs);
+        withAdded.put(key, value);
+        return new RtYamlMappingBuilder(withAdded);
     }
 
     @Override


Test patch:
diff --git a/src/test/java/com/amihaiemil/eoyaml/RtYamlMappingBuilderTest.java b/src/test/java/com/amihaiemil/eoyaml/RtYamlMappingBuilderTest.java
index 06d0f49..146a322 100644
--- a/src/test/java/com/amihaiemil/eoyaml/RtYamlMappingBuilderTest.java
+++ b/src/test/java/com/amihaiemil/eoyaml/RtYamlMappingBuilderTest.java
@@ -32,7 +32,9 @@ import java.util.List;
 
 import org.hamcrest.MatcherAssert;
 import org.hamcrest.Matchers;
+import org.junit.Assert;
 import org.junit.Test;
+import org.mockito.Mockito;
 
 /**
  * Unit tests for {@link RtYamlMappingBuilder}.
@@ -140,4 +142,48 @@ public final class RtYamlMappingBuilderTest {
             Matchers.equalTo("some test mapping")
         );
     }
+
+    /**
+     * RtYamlMappingBuilder should complain when a null key is provided.
+     */
+    @Test
+    public void complainsOnNullKey() {
+        final YamlNode key = null;
+        try {
+            final YamlMapping mapping = new RtYamlMappingBuilder()
+                .add(key, "value")
+                .build("some test mapping");
+            Assert.fail("IAE was expected!");
+        } catch (final IllegalArgumentException ex) {
+            MatcherAssert.assertThat(
+                ex.getMessage(),
+                Matchers.equalTo(
+                    "The key in YamlMapping cannot be null or empty!"
+                )
+            );
+        }
+    }
+
+    /**
+     * RtYamlMappingBuilder should complain when an empty key is provided.
+     */
+    @Test
+    public void complainsOnEmptyKey() {
+        final BaseYamlNode key = Mockito.mock(BaseYamlNode.class);
+        Mockito.when(key.isEmpty()).thenReturn(true);
+        try {
+            final YamlMapping mapping = new RtYamlMappingBuilder()
+                .add(key, "value")
+                .build("some test mapping");
+            Assert.fail("IAE was expected!");
+        } catch (final IllegalArgumentException ex) {
+            MatcherAssert.assertThat(
+                ex.getMessage(),
+                Matchers.equalTo(
+                    "The key in YamlMapping cannot be null or empty!"
+                )
+            );
+        }
+    }
+
 }