blob: 61e90cd8094d1c848a122adff34bbead441a94b1 [file] [log] [blame]
Václav Kubernát43908fb2020-01-02 19:05:51 +01001/*
2 * Copyright (C) 2020 CESNET, https://photonics.cesnet.cz/
3 *
4 * Written by Václav Kubernát <kubervac@fit.cvut.cz>
5 *
6*/
7
8#include <experimental/iterator>
9#include <iostream>
Václav Kubernát26b56082020-02-03 18:28:56 +010010#include "trompeloeil_doctest.hpp"
Václav Kubernát43908fb2020-01-02 19:05:51 +010011#include "ast_commands.hpp"
12#include "datastoreaccess_mock.hpp"
13#include "parser.hpp"
14#include "static_schema.hpp"
15
16namespace std {
17std::ostream& operator<<(std::ostream& s, const std::set<std::string> set)
18{
19 s << std::endl << "{";
20 std::copy(set.begin(), set.end(), std::experimental::make_ostream_joiner(s, ", "));
21 s << "}" << std::endl;
22 return s;
23}
24}
25
26TEST_CASE("keyvalue_completion")
27{
28 auto schema = std::make_shared<StaticSchema>();
29 schema->addModule("example");
30 schema->addContainer("/", "example:a");
31 schema->addContainer("/", "example:b");
32 schema->addList("/", "example:list", {"number"});
Václav Kubernát3a99f002020-03-31 02:27:41 +020033 schema->addLeaf("/example:list", "example:number", yang::Int32{});
Václav Kubernát43908fb2020-01-02 19:05:51 +010034 schema->addList("/", "example:twoKeyList", {"number", "name"});
Václav Kubernát3a99f002020-03-31 02:27:41 +020035 schema->addLeaf("/example:twoKeyList", "example:number", yang::Int32{});
36 schema->addLeaf("/example:twoKeyList", "example:name", yang::String{});
Václav Kubernát43908fb2020-01-02 19:05:51 +010037 auto mockDatastore = std::make_shared<MockDatastoreAccess>();
38
39 // DataQuery gets the schema from DatastoreAccess once
40 auto expectation = NAMED_REQUIRE_CALL(*mockDatastore, schema())
41 .RETURN(schema);
42 auto dataQuery = std::make_shared<DataQuery>(*mockDatastore);
43 expectation.reset();
44 Parser parser(schema, dataQuery);
45 std::string input;
46 std::ostringstream errorStream;
47
48 std::set<std::string> expected;
49 std::vector<std::shared_ptr<trompeloeil::expectation>> queryExpectations;
50 std::vector<ListInstance> queryReturn;
51
52 SECTION("get example:list[number=")
53 {
54 input = "get example:list[number=";
55 queryReturn = {
56 {{"number", 1}},
57 {{"number", 7}},
58 {{"number", 9}},
59 {{"number", 42}}
60 };
61 expected = {
62 "1",
63 "7",
64 "9",
65 "42"
66 };
67 queryExpectations.push_back(NAMED_REQUIRE_CALL(*mockDatastore, listInstances("/example:list"))
68 .RETURN(queryReturn));
69 }
70
71 SECTION("get example:twoKeyList[number=")
72 {
73 queryReturn = {
74 {{"number", 1}, {"name", std::string{"Petr"}}},
75 {{"number", 7}, {"name", std::string{"Petr"}}},
76 {{"number", 10}, {"name", std::string{"Petr"}}},
77 {{"number", 10}, {"name", std::string{"Honza"}}},
78 {{"number", 100}, {"name", std::string{"Honza"}}},
79 };
80 input = "get example:twoKeyList[";
81 SECTION("no keys set")
82 {
83 SECTION("number")
84 {
85 input += "number=";
86 expected = { "1", "7", "10", "100" };
87 }
88 SECTION("name")
89 {
90 input += "name=";
91 expected = { "'Petr'", "'Honza'"};
92 }
93 queryExpectations.push_back(NAMED_REQUIRE_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
94 .RETURN(queryReturn));
95 }
96
97 SECTION("name is set")
98 {
99 input += "name=";
100 SECTION("Petr")
101 {
102 input += "'Petr'";
103 expected = { "1", "7", "10"};
104 }
105 SECTION("Honza")
106 {
107 input += "'Honza'";
108 expected = { "10", "100" };
109 }
110 input += "][number=";
111 queryExpectations.push_back(NAMED_REQUIRE_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
112 .TIMES(2)
113 .RETURN(queryReturn));
114 }
115
116 SECTION("number is set")
117 {
118 input += "number=";
119 SECTION("1")
120 {
121 input += "1";
122 expected = { "'Petr'" };
123 }
124 SECTION("7")
125 {
126 input += "7";
127 expected = { "'Petr'" };
128 }
129 SECTION("10")
130 {
131 input += "10";
132 expected = { "'Honza'", "'Petr'" };
133 }
134 SECTION("100")
135 {
136 input += "100";
137 expected = { "'Honza'" };
138 }
139 input += "][name=";
140 queryExpectations.push_back(NAMED_REQUIRE_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
141 .TIMES(2)
142 .RETURN(queryReturn));
143 }
144
145 SECTION("both keys are set")
146 {
147 SECTION("get example:twoKeyList[number=123][name='Petr'")
148 {
149 input = "get example:twoKeyList[number=123][name='Petr'";
150 expected = {"]/"};
151 }
152 SECTION("get example:twoKeyList[number=123][name='Petr']")
153 {
154 input = "get example:twoKeyList[number=123][name='Petr']";
155 expected = {"]/"};
156 }
157 SECTION("get example:twoKeyList[number=123][name='Petr'][")
158 {
159 input = "get example:twoKeyList[number=123][name='Petr'][";
160 }
161 // I use ALLOW_CALL here, all this stuff calls it different number of times
162 queryExpectations.push_back(NAMED_ALLOW_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
163 .RETURN(queryReturn));
164 }
165
166 }
167
168 REQUIRE(parser.completeCommand(input, errorStream).m_completions == expected);
169 for (auto& it : queryExpectations) {
170 it.reset();
171 }
172}