blob: 249dc8cc8aeb9eb0eae4eba901c894cb798c17a7 [file] [log] [blame]
Václav Kubernát4108e0d2018-10-29 13:32:22 +01001/*
2 * Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
3 * Copyright (C) 2018 FIT CVUT, https://fit.cvut.cz/
4 *
5 * Written by Václav Kubernát <kubervac@fit.cvut.cz>
6 *
7*/
8
Václav Kubernát26b56082020-02-03 18:28:56 +01009#include "trompeloeil_doctest.hpp"
Václav Kubernát43908fb2020-01-02 19:05:51 +010010#include "datastoreaccess_mock.hpp"
Václav Kubernát4108e0d2018-10-29 13:32:22 +010011#include "parser.hpp"
Václav Kubernát1ed4aa32020-01-23 13:13:28 +010012#include "pretty_printers.hpp"
Václav Kubernát4108e0d2018-10-29 13:32:22 +010013#include "static_schema.hpp"
14
15TEST_CASE("path_completion")
16{
17 auto schema = std::make_shared<StaticSchema>();
18 schema->addModule("example");
19 schema->addModule("second");
Václav Kubernátefcac932020-01-10 15:26:32 +010020 schema->addContainer("/", "example:ano");
21 schema->addContainer("/", "example:anoda");
22 schema->addList("/example:ano", "example:listInCont", {"number"});
23 schema->addContainer("/", "second:amelie");
24 schema->addContainer("/", "example:bota");
25 schema->addContainer("/example:ano", "example:a2");
26 schema->addContainer("/example:bota", "example:b2");
27 schema->addContainer("/example:ano/example:a2", "example:a3");
28 schema->addContainer("/example:bota/example:b2", "example:b3");
29 schema->addList("/", "example:list", {"number"});
Václav Kubernát3a99f002020-03-31 02:27:41 +020030 schema->addLeaf("/example:list", "example:number", yang::Int32{});
Václav Kubernátefcac932020-01-10 15:26:32 +010031 schema->addContainer("/example:list", "example:contInList");
Václav Kubernát7707cae2020-01-16 12:04:53 +010032 schema->addList("/", "example:ovoce", {"name"});
Václav Kubernát3a99f002020-03-31 02:27:41 +020033 schema->addLeaf("/example:ovoce", "example:name", yang::String{});
Václav Kubernát7707cae2020-01-16 12:04:53 +010034 schema->addList("/", "example:ovocezelenina", {"name"});
Václav Kubernát3a99f002020-03-31 02:27:41 +020035 schema->addLeaf("/example:ovocezelenina", "example:name", yang::String{});
Václav Kubernátefcac932020-01-10 15:26:32 +010036 schema->addList("/", "example:twoKeyList", {"number", "name"});
Václav Kubernát3a99f002020-03-31 02:27:41 +020037 schema->addLeaf("/example:twoKeyList", "example:name", yang::String{});
38 schema->addLeaf("/example:twoKeyList", "example:number", yang::Int32{});
39 schema->addLeaf("/", "example:leafInt", yang::Int32{});
Václav Kubernátabf52802020-05-19 01:31:17 +020040 schema->addLeaf("/", "example:readonly", yang::Int32{}, yang::AccessType::ReadOnly);
Václav Kubernát743d9eb2020-05-18 13:42:36 +020041 schema->addLeafList("/", "example:addresses", yang::String{});
Václav Kubernát43908fb2020-01-02 19:05:51 +010042 auto mockDatastore = std::make_shared<MockDatastoreAccess>();
43
44 // The parser will use DataQuery for key value completion, but I'm not testing that here, so I don't return anything.
45 ALLOW_CALL(*mockDatastore, listInstances("/example:list"))
46 .RETURN(std::vector<ListInstance>{});
47 ALLOW_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
48 .RETURN(std::vector<ListInstance>{});
49
50 // DataQuery gets the schema from DatastoreAccess once
51 auto expectation = NAMED_REQUIRE_CALL(*mockDatastore, schema())
52 .RETURN(schema);
53 auto dataQuery = std::make_shared<DataQuery>(*mockDatastore);
54 expectation.reset();
Václav Kubernát28cf3362020-06-29 17:52:51 +020055 Parser parser(schema, WritableOps::No, dataQuery);
Václav Kubernát4108e0d2018-10-29 13:32:22 +010056 std::string input;
57 std::ostringstream errorStream;
Václav Kubernát1ed4aa32020-01-23 13:13:28 +010058
59 std::set<std::string> expectedCompletions;
60 // GCC complains here with -Wmaybe-uninitialized if I don't assign
61 // something here. I suspect it's because of nested SECTIONs. -1 is an
62 // invalid value (as in, I'll never expect expectedContextLength to be -1),
63 // so let's go with that.
64 int expectedContextLength = -1;
Václav Kubernát4108e0d2018-10-29 13:32:22 +010065
Václav Kubernát329c6c32019-02-06 16:41:53 +010066 SECTION("node name completion")
Václav Kubernát4108e0d2018-10-29 13:32:22 +010067 {
Václav Kubernát329c6c32019-02-06 16:41:53 +010068 SECTION("ls ")
69 {
70 input = "ls ";
Václav Kubernát743d9eb2020-05-18 13:42:36 +020071 expectedCompletions = {"example:addresses/", "example:ano/", "example:anoda/", "example:bota/", "example:leafInt ", "example:list/", "example:ovoce/", "example:readonly ", "example:ovocezelenina/", "example:twoKeyList/", "second:amelie/"};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +010072 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +010073 }
74
75 SECTION("ls e")
76 {
77 input = "ls e";
Václav Kubernát743d9eb2020-05-18 13:42:36 +020078 expectedCompletions = {"example:addresses/", "example:ano/", "example:anoda/", "example:bota/", "example:leafInt ", "example:list/", "example:ovoce/", "example:readonly ", "example:ovocezelenina/", "example:twoKeyList/"};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +010079 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +010080 }
81
82 SECTION("ls example:ano")
83 {
84 input = "ls example:ano";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +010085 expectedCompletions = {"example:ano/", "example:anoda/"};
86 expectedContextLength = 11;
Václav Kubernát329c6c32019-02-06 16:41:53 +010087 }
88
Václav Kubernáte2d629f2020-04-28 11:01:54 +020089 SECTION("ls example:ano/a")
Václav Kubernát329c6c32019-02-06 16:41:53 +010090 {
Václav Kubernáte2d629f2020-04-28 11:01:54 +020091 input = "ls example:ano/a";
92 expectedCompletions = {"a2/"};
93 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +010094 }
95
96 SECTION("ls x")
97 {
98 input = "ls x";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +010099 expectedCompletions = {};
100 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100101 }
102
103 SECTION("ls /")
104 {
105 input = "ls /";
Václav Kubernát743d9eb2020-05-18 13:42:36 +0200106 expectedCompletions = {"example:addresses/", "example:ano/", "example:anoda/", "example:bota/", "example:leafInt ", "example:list/", "example:ovoce/", "example:readonly ", "example:ovocezelenina/", "example:twoKeyList/", "second:amelie/"};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100107 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100108 }
109
110 SECTION("ls /e")
111 {
112 input = "ls /e";
Václav Kubernát743d9eb2020-05-18 13:42:36 +0200113 expectedCompletions = {"example:addresses/", "example:ano/", "example:anoda/", "example:bota/", "example:leafInt ", "example:list/", "example:ovoce/", "example:readonly ", "example:ovocezelenina/", "example:twoKeyList/"};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100114 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100115 }
116
Václav Kubernáte69133a2019-11-01 19:01:34 +0100117 SECTION("ls example:bota")
118 {
119 input = "ls example:bota";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100120 expectedCompletions = {"example:bota/"};
121 expectedContextLength = 12;
Václav Kubernáte69133a2019-11-01 19:01:34 +0100122 }
123
124 SECTION("ls /example:bota")
125 {
126 input = "ls /example:bota";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100127 expectedCompletions = {"example:bota/"};
128 expectedContextLength = 12;
Václav Kubernáte69133a2019-11-01 19:01:34 +0100129 }
130
Václav Kubernát329c6c32019-02-06 16:41:53 +0100131 SECTION("ls /s")
132 {
133 input = "ls /s";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100134 expectedCompletions = {"second:amelie/"};
135 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100136 }
137
Václav Kubernát743d9eb2020-05-18 13:42:36 +0200138 SECTION("ls /example:list")
139 {
140 input = "ls /example:list";
141 expectedCompletions = {"example:list/"};
142 expectedContextLength = 12;
143 }
144
Václav Kubernát26be33a2020-02-13 13:30:14 +0100145 SECTION("ls /example:list/")
146 {
147 input = "ls /example:list/";
Václav Kubernáte2d629f2020-04-28 11:01:54 +0200148 expectedCompletions = {"contInList/", "number "};
Václav Kubernát26be33a2020-02-13 13:30:14 +0100149 expectedContextLength = 0;
150 }
151
Václav Kubernát329c6c32019-02-06 16:41:53 +0100152 SECTION("ls /example:list[number=3]/")
153 {
154 input = "ls /example:list[number=3]/";
Václav Kubernáte2d629f2020-04-28 11:01:54 +0200155 expectedCompletions = {"contInList/", "number "};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100156 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100157 }
158
159 SECTION("ls /example:list[number=3]/c")
160 {
Václav Kubernáte2d629f2020-04-28 11:01:54 +0200161 input = "ls /example:list[number=3]/c";
162 expectedCompletions = {"contInList/"};
163 expectedContextLength = 1;
164 }
165
166 SECTION("ls /example:list[number=3]/n")
167 {
168 input = "ls /example:list[number=3]/n";
169 expectedCompletions = {"number "};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100170 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100171 }
172
173 SECTION("ls /example:list[number=3]/a")
174 {
175 input = "ls /example:list[number=3]/a";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100176 expectedCompletions = {};
177 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100178 }
Václav Kubernát26be33a2020-02-13 13:30:14 +0100179
Václav Kubernáte2d629f2020-04-28 11:01:54 +0200180 SECTION("ls /example:list/contInList/")
Václav Kubernát26be33a2020-02-13 13:30:14 +0100181 {
Václav Kubernáte2d629f2020-04-28 11:01:54 +0200182 input = "ls /example:list/contInList/";
Václav Kubernát26be33a2020-02-13 13:30:14 +0100183 expectedCompletions = {};
184 expectedContextLength = 0;
185 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100186 }
187
Václav Kubernát329c6c32019-02-06 16:41:53 +0100188 SECTION("list keys completion")
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100189 {
Václav Kubernát329c6c32019-02-06 16:41:53 +0100190 SECTION("cd example:lis")
191 {
192 input = "cd example:lis";
Václav Kubernátcb3af402020-02-12 16:49:17 +0100193 expectedCompletions = {"example:list"};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100194 expectedContextLength = 11;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100195 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100196
Václav Kubernát51853b22019-04-16 21:53:44 +0200197 SECTION("set example:list")
198 {
199 input = "set example:list";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100200 expectedCompletions = {"example:list["};
201 expectedContextLength = 12;
Václav Kubernát4c325482019-04-11 17:51:55 +0200202 }
203
204 SECTION("cd example:list")
205 {
206 input = "cd example:list";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100207 expectedCompletions = {"example:list["};
208 expectedContextLength = 12;
Václav Kubernát51853b22019-04-16 21:53:44 +0200209 }
210
Václav Kubernát329c6c32019-02-06 16:41:53 +0100211 SECTION("cd example:list[")
212 {
213 input = "cd example:list[";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100214 expectedCompletions = {"number="};
215 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100216 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100217
Václav Kubernát329c6c32019-02-06 16:41:53 +0100218 SECTION("cd example:list[numb")
219 {
220 input = "cd example:list[numb";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100221 expectedCompletions = {"number="};
222 expectedContextLength = 4;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100223 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100224
Václav Kubernát329c6c32019-02-06 16:41:53 +0100225 SECTION("cd example:list[number")
226 {
227 input = "cd example:list[number";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100228 expectedCompletions = {"number="};
229 expectedContextLength = 6;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100230 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100231
Václav Kubernát117f7b52020-01-23 16:10:55 +0100232 SECTION("cd example:list[number=")
233 {
234 input = "cd example:list[number=";
Václav Kubernát43908fb2020-01-02 19:05:51 +0100235 expectedCompletions = {};
236 expectedContextLength = 0;
Václav Kubernát117f7b52020-01-23 16:10:55 +0100237 }
238
Václav Kubernát329c6c32019-02-06 16:41:53 +0100239 SECTION("cd example:list[number=12")
240 {
241 input = "cd example:list[number=12";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100242 expectedCompletions = {"]/"};
243 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100244 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100245
Václav Kubernát329c6c32019-02-06 16:41:53 +0100246 SECTION("cd example:list[number=12]")
247 {
248 input = "cd example:list[number=12]";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100249 expectedCompletions = {"]/"};
250 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100251 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100252
Václav Kubernát329c6c32019-02-06 16:41:53 +0100253 SECTION("cd example:twoKeyList[")
254 {
255 input = "cd example:twoKeyList[";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100256 expectedCompletions = {"name=", "number="};
257 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100258 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100259
Václav Kubernát4c325482019-04-11 17:51:55 +0200260 SECTION("cd example:twoKeyList[name=\"AHOJ\"")
261 {
262 input = "cd example:twoKeyList[name=\"AHOJ\"";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100263 expectedCompletions = {"]["};
264 expectedContextLength = 0;
Václav Kubernát4c325482019-04-11 17:51:55 +0200265 }
266
267 SECTION("cd example:twoKeyList[name=\"AHOJ\"]")
268 {
269 input = "cd example:twoKeyList[name=\"AHOJ\"]";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100270 expectedCompletions = {"]["};
271 expectedContextLength = 1;
Václav Kubernát4c325482019-04-11 17:51:55 +0200272 }
273
Václav Kubernát329c6c32019-02-06 16:41:53 +0100274 SECTION("cd example:twoKeyList[name=\"AHOJ\"][")
275 {
276 input = "cd example:twoKeyList[name=\"AHOJ\"][";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100277 expectedCompletions = {"number="};
278 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100279 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100280
Václav Kubernát329c6c32019-02-06 16:41:53 +0100281 SECTION("cd example:twoKeyList[number=42][")
282 {
283 input = "cd example:twoKeyList[number=42][";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100284 expectedCompletions = {"name="};
285 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100286 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100287
Václav Kubernát329c6c32019-02-06 16:41:53 +0100288 SECTION("cd example:twoKeyList[name=\"AHOJ\"][number=123")
289 {
290 input = "cd example:twoKeyList[name=\"AHOJ\"][number=123";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100291 expectedCompletions = {"]/"};
292 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100293 }
294
295 SECTION("cd example:twoKeyList[name=\"AHOJ\"][number=123]")
296 {
297 input = "cd example:twoKeyList[name=\"AHOJ\"][number=123]";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100298 expectedCompletions = {"]/"};
299 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100300 }
Václav Kubernát4c325482019-04-11 17:51:55 +0200301
302 SECTION("cd example:ovoce")
303 {
304 input = "cd example:ovoce";
Václav Kubernátcb3af402020-02-12 16:49:17 +0100305 expectedCompletions = {"example:ovoce", "example:ovocezelenina"};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100306 expectedContextLength = 13;
Václav Kubernát4c325482019-04-11 17:51:55 +0200307 }
Václav Kubernátcb3af402020-02-12 16:49:17 +0100308
309 SECTION("cd example:ovoceze")
310 {
311 input = "cd example:ovoceze";
312 expectedCompletions = {"example:ovocezelenina"};
313 expectedContextLength = 15;
314 }
315
316 SECTION("cd example:ovocezelenina")
317 {
318 input = "cd example:ovocezelenina";
319 expectedCompletions = {"example:ovocezelenina["};
320 expectedContextLength = 21;
321 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100322 }
323
Václav Kubernátabf52802020-05-19 01:31:17 +0200324 SECTION("no readonly data leafs in set")
325 {
326 input = "set example:read";
327 expectedContextLength = 12;
328 }
329
Václav Kubernát8028f942019-09-25 16:03:23 +0200330 SECTION("clear completions when no longer inputting path")
331 {
332 input = "set example:leafInt ";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100333 expectedCompletions = {};
334 expectedContextLength = 0;
Václav Kubernát8028f942019-09-25 16:03:23 +0200335 }
336
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100337 REQUIRE(parser.completeCommand(input, errorStream) == (Completions{expectedCompletions, expectedContextLength}));
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100338}