Add move command for moving (leaf)list instances

Change-Id: I0bff25209f74601a450c12a810200b3c124d65f2
diff --git a/tests/list_manipulation.cpp b/tests/list_manipulation.cpp
index 35cd019..c646e13 100644
--- a/tests/list_manipulation.cpp
+++ b/tests/list_manipulation.cpp
@@ -26,6 +26,7 @@
     schema->addLeaf("/mod:company", "mod:department", schema->validIdentities("other", "deptypes"));
     schema->addList("/mod:company", "mod:inventory", {"id"});
     schema->addLeaf("/mod:company/mod:inventory", "mod:id", yang::Int32{});
+    schema->addContainer("/", "mod:cont");
     Parser parser(schema);
     std::string input;
     std::ostringstream errorStream;
@@ -83,4 +84,89 @@
         REQUIRE(commandGet.type() == typeid(get_));
         REQUIRE(boost::get<get_>(commandGet) == expectedGet);
     }
+
+    SECTION("moving (leaf)list instances")
+    {
+        move_ expected;
+        SECTION("begin")
+        {
+            SECTION("cwd: /")
+            {
+                input = "move mod:addresses['1.2.3.4'] begin";
+                expected.m_source.m_nodes.push_back(dataNode_{module_{"mod"}, leafListElement_{"addresses", "1.2.3.4"s}});
+            }
+
+            SECTION("cwd: /mod:cont")
+            {
+                parser.changeNode(dataPath_{Scope::Absolute, {dataNode_{module_{"mod"}, container_{"cont"}}}});
+                SECTION("relative")
+                {
+                    input = "move ../mod:addresses['1.2.3.4'] begin";
+                    expected.m_source.m_nodes.push_back(dataNode_{nodeup_{}});
+                    expected.m_source.m_nodes.push_back(dataNode_{module_{"mod"}, leafListElement_{"addresses", "1.2.3.4"s}});
+                }
+
+                SECTION("absolute")
+                {
+                    input = "move /mod:addresses['1.2.3.4'] begin";
+                    expected.m_source.m_scope = Scope::Absolute;
+                    expected.m_source.m_nodes.push_back(dataNode_{module_{"mod"}, leafListElement_{"addresses", "1.2.3.4"s}});
+                }
+            }
+
+            expected.m_destination = yang::move::Absolute::Begin;
+        }
+
+        SECTION("end")
+        {
+            input = "move mod:addresses['1.2.3.4'] end";
+            expected.m_source.m_nodes.push_back(dataNode_{module_{"mod"}, leafListElement_{"addresses", "1.2.3.4"s}});
+            expected.m_destination = yang::move::Absolute::End;
+        }
+
+        SECTION("after")
+        {
+            input = "move mod:addresses['1.2.3.4'] after '0.0.0.0'";
+            expected.m_source.m_nodes.push_back(dataNode_{module_{"mod"}, leafListElement_{"addresses", "1.2.3.4"s}});
+            expected.m_destination = yang::move::Relative {
+                yang::move::Relative::Position::After,
+                {{".", "0.0.0.0"s}}
+            };
+        }
+
+        SECTION("before")
+        {
+            input = "move mod:addresses['1.2.3.4'] before '0.0.0.0'";
+            expected.m_source.m_nodes.push_back(dataNode_{module_{"mod"}, leafListElement_{"addresses", "1.2.3.4"s}});
+            expected.m_destination = yang::move::Relative {
+                yang::move::Relative::Position::Before,
+                {{".", "0.0.0.0"s}}
+            };
+        }
+
+        SECTION("list instance with destination")
+        {
+            input = "move mod:list[number=12] before [number=15]";
+            auto keys = std::map<std::string, leaf_data_>{
+                {"number", int32_t{12}}};
+            expected.m_source.m_nodes.push_back(dataNode_{module_{"mod"}, listElement_("list", keys)});
+            expected.m_destination = yang::move::Relative {
+                yang::move::Relative::Position::Before,
+                ListInstance{{"number", int32_t{15}}}
+            };
+        }
+
+        SECTION("list instance without destination")
+        {
+            input = "move mod:list[number=3] begin";
+            auto keys = std::map<std::string, leaf_data_>{
+                {"number", int32_t{3}}};
+            expected.m_source.m_nodes.push_back(dataNode_{module_{"mod"}, listElement_("list", keys)});
+            expected.m_destination = yang::move::Absolute::Begin;
+        }
+
+        command_ commandMove = parser.parseCommand(input, errorStream);
+        REQUIRE(commandMove.type() == typeid(move_));
+        REQUIRE(boost::get<move_>(commandMove) == expected);
+    }
 }