Integrate DataQuery
Change-Id: I439374afe485baf08a4d5a1a02fd70d908bec9e1
diff --git a/tests/keyvalue_completion.cpp b/tests/keyvalue_completion.cpp
new file mode 100644
index 0000000..56c7841
--- /dev/null
+++ b/tests/keyvalue_completion.cpp
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2020 CESNET, https://photonics.cesnet.cz/
+ *
+ * Written by Václav Kubernát <kubervac@fit.cvut.cz>
+ *
+*/
+
+#include <experimental/iterator>
+#include <iostream>
+#include "trompeloeil_doctest.h"
+#include "ast_commands.hpp"
+#include "datastoreaccess_mock.hpp"
+#include "parser.hpp"
+#include "static_schema.hpp"
+
+namespace std {
+std::ostream& operator<<(std::ostream& s, const std::set<std::string> set)
+{
+ s << std::endl << "{";
+ std::copy(set.begin(), set.end(), std::experimental::make_ostream_joiner(s, ", "));
+ s << "}" << std::endl;
+ return s;
+}
+}
+
+TEST_CASE("keyvalue_completion")
+{
+ auto schema = std::make_shared<StaticSchema>();
+ schema->addModule("example");
+ schema->addContainer("/", "example:a");
+ schema->addContainer("/", "example:b");
+ schema->addList("/", "example:list", {"number"});
+ schema->addLeaf("/example:list", "example:number", yang::LeafDataTypes::Int32);
+ schema->addList("/", "example:twoKeyList", {"number", "name"});
+ schema->addLeaf("/example:twoKeyList", "example:number", yang::LeafDataTypes::Int32);
+ schema->addLeaf("/example:twoKeyList", "example:name", yang::LeafDataTypes::String);
+ auto mockDatastore = std::make_shared<MockDatastoreAccess>();
+
+ // DataQuery gets the schema from DatastoreAccess once
+ auto expectation = NAMED_REQUIRE_CALL(*mockDatastore, schema())
+ .RETURN(schema);
+ auto dataQuery = std::make_shared<DataQuery>(*mockDatastore);
+ expectation.reset();
+ Parser parser(schema, dataQuery);
+ std::string input;
+ std::ostringstream errorStream;
+
+ std::set<std::string> expected;
+ std::vector<std::shared_ptr<trompeloeil::expectation>> queryExpectations;
+ std::vector<ListInstance> queryReturn;
+
+ SECTION("get example:list[number=")
+ {
+ input = "get example:list[number=";
+ queryReturn = {
+ {{"number", 1}},
+ {{"number", 7}},
+ {{"number", 9}},
+ {{"number", 42}}
+ };
+ expected = {
+ "1",
+ "7",
+ "9",
+ "42"
+ };
+ queryExpectations.push_back(NAMED_REQUIRE_CALL(*mockDatastore, listInstances("/example:list"))
+ .RETURN(queryReturn));
+ }
+
+ SECTION("get example:twoKeyList[number=")
+ {
+ queryReturn = {
+ {{"number", 1}, {"name", std::string{"Petr"}}},
+ {{"number", 7}, {"name", std::string{"Petr"}}},
+ {{"number", 10}, {"name", std::string{"Petr"}}},
+ {{"number", 10}, {"name", std::string{"Honza"}}},
+ {{"number", 100}, {"name", std::string{"Honza"}}},
+ };
+ input = "get example:twoKeyList[";
+ SECTION("no keys set")
+ {
+ SECTION("number")
+ {
+ input += "number=";
+ expected = { "1", "7", "10", "100" };
+ }
+ SECTION("name")
+ {
+ input += "name=";
+ expected = { "'Petr'", "'Honza'"};
+ }
+ queryExpectations.push_back(NAMED_REQUIRE_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
+ .RETURN(queryReturn));
+ }
+
+ SECTION("name is set")
+ {
+ input += "name=";
+ SECTION("Petr")
+ {
+ input += "'Petr'";
+ expected = { "1", "7", "10"};
+ }
+ SECTION("Honza")
+ {
+ input += "'Honza'";
+ expected = { "10", "100" };
+ }
+ input += "][number=";
+ queryExpectations.push_back(NAMED_REQUIRE_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
+ .TIMES(2)
+ .RETURN(queryReturn));
+ }
+
+ SECTION("number is set")
+ {
+ input += "number=";
+ SECTION("1")
+ {
+ input += "1";
+ expected = { "'Petr'" };
+ }
+ SECTION("7")
+ {
+ input += "7";
+ expected = { "'Petr'" };
+ }
+ SECTION("10")
+ {
+ input += "10";
+ expected = { "'Honza'", "'Petr'" };
+ }
+ SECTION("100")
+ {
+ input += "100";
+ expected = { "'Honza'" };
+ }
+ input += "][name=";
+ queryExpectations.push_back(NAMED_REQUIRE_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
+ .TIMES(2)
+ .RETURN(queryReturn));
+ }
+
+ SECTION("both keys are set")
+ {
+ SECTION("get example:twoKeyList[number=123][name='Petr'")
+ {
+ input = "get example:twoKeyList[number=123][name='Petr'";
+ expected = {"]/"};
+ }
+ SECTION("get example:twoKeyList[number=123][name='Petr']")
+ {
+ input = "get example:twoKeyList[number=123][name='Petr']";
+ expected = {"]/"};
+ }
+ SECTION("get example:twoKeyList[number=123][name='Petr'][")
+ {
+ input = "get example:twoKeyList[number=123][name='Petr'][";
+ }
+ // I use ALLOW_CALL here, all this stuff calls it different number of times
+ queryExpectations.push_back(NAMED_ALLOW_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
+ .RETURN(queryReturn));
+ }
+
+ }
+
+ REQUIRE(parser.completeCommand(input, errorStream).m_completions == expected);
+ for (auto& it : queryExpectations) {
+ it.reset();
+ }
+}