CLI: Allow deleting leaf nodes

This is allowed for YANG datastores; the semantics is that a default
value appears there if defined, otherwise the node just doesn't return
any data when requested.

Change-Id: I9e39ade3e08720b116a674650a02399cbffd854e
diff --git a/src/grammars.hpp b/src/grammars.hpp
index 9f0baf2..3cc74f2 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -57,7 +57,7 @@
     create_::name >> space_separator > (presenceContainerPath | listInstancePath | leafListElementPath);
 
 auto const delete_rule_def =
-    delete_::name >> space_separator > (presenceContainerPath | listInstancePath | leafListElementPath);
+    delete_::name >> space_separator > (presenceContainerPath | listInstancePath | leafListElementPath | writableLeafPath);
 
 auto const get_def =
     get_::name >> -(space_separator >> ((dataPathListEnd | dataPath) | (module >> "*")));
diff --git a/tests/interpreter.cpp b/tests/interpreter.cpp
index 15a268e..d1e6d26 100644
--- a/tests/interpreter.cpp
+++ b/tests/interpreter.cpp
@@ -361,6 +361,14 @@
         toInterpret.push_back(deleteCmd);
     }
 
+    SECTION("delete a leaf")
+    {
+        expectations.push_back(NAMED_REQUIRE_CALL(datastore, deleteItem("/mod:someLeaf")));
+        delete_ deleteCmd;
+        deleteCmd.m_path = {Scope::Absolute, {dataNode_{{"mod"}, leaf_{"someLeaf"}}, }};
+        toInterpret.push_back(deleteCmd);
+    }
+
     SECTION("commit")
     {
         expectations.push_back(NAMED_REQUIRE_CALL(datastore, commitChanges()));
diff --git a/tests/leaf_editing.cpp b/tests/leaf_editing.cpp
index 1a55fa1..35e2ddc 100644
--- a/tests/leaf_editing.cpp
+++ b/tests/leaf_editing.cpp
@@ -617,4 +617,15 @@
         REQUIRE_THROWS_AS(parser.parseCommand(input, errorStream), InvalidCommandException);
         REQUIRE(errorStream.str().find(expectedError) != std::string::npos);
     }
+
+    SECTION("deleting a leaf")
+    {
+        delete_ expected;
+        input = "delete mod:leafString";
+        expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafString")});
+
+        command_ command = parser.parseCommand(input, errorStream);
+        REQUIRE(command.type() == typeid(delete_));
+        REQUIRE(boost::get<delete_>(command) == expected);
+    }
 }