blob: 71fc9175a6333ddf41794989490726ef78db3a02 [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át43908fb2020-01-02 19:05:51 +010041 auto mockDatastore = std::make_shared<MockDatastoreAccess>();
42
43 // The parser will use DataQuery for key value completion, but I'm not testing that here, so I don't return anything.
44 ALLOW_CALL(*mockDatastore, listInstances("/example:list"))
45 .RETURN(std::vector<ListInstance>{});
46 ALLOW_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
47 .RETURN(std::vector<ListInstance>{});
48
49 // DataQuery gets the schema from DatastoreAccess once
50 auto expectation = NAMED_REQUIRE_CALL(*mockDatastore, schema())
51 .RETURN(schema);
52 auto dataQuery = std::make_shared<DataQuery>(*mockDatastore);
53 expectation.reset();
54 Parser parser(schema, dataQuery);
Václav Kubernát4108e0d2018-10-29 13:32:22 +010055 std::string input;
56 std::ostringstream errorStream;
Václav Kubernát1ed4aa32020-01-23 13:13:28 +010057
58 std::set<std::string> expectedCompletions;
59 // GCC complains here with -Wmaybe-uninitialized if I don't assign
60 // something here. I suspect it's because of nested SECTIONs. -1 is an
61 // invalid value (as in, I'll never expect expectedContextLength to be -1),
62 // so let's go with that.
63 int expectedContextLength = -1;
Václav Kubernát4108e0d2018-10-29 13:32:22 +010064
Václav Kubernát329c6c32019-02-06 16:41:53 +010065 SECTION("node name completion")
Václav Kubernát4108e0d2018-10-29 13:32:22 +010066 {
Václav Kubernát329c6c32019-02-06 16:41:53 +010067 SECTION("ls ")
68 {
69 input = "ls ";
Václav Kubernátabf52802020-05-19 01:31:17 +020070 expectedCompletions = {"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 +010071 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +010072 }
73
74 SECTION("ls e")
75 {
76 input = "ls e";
Václav Kubernátabf52802020-05-19 01:31:17 +020077 expectedCompletions = {"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 +010078 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +010079 }
80
81 SECTION("ls example:ano")
82 {
83 input = "ls example:ano";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +010084 expectedCompletions = {"example:ano/", "example:anoda/"};
85 expectedContextLength = 11;
Václav Kubernát329c6c32019-02-06 16:41:53 +010086 }
87
Václav Kubernáte2d629f2020-04-28 11:01:54 +020088 SECTION("ls example:ano/a")
Václav Kubernát329c6c32019-02-06 16:41:53 +010089 {
Václav Kubernáte2d629f2020-04-28 11:01:54 +020090 input = "ls example:ano/a";
91 expectedCompletions = {"a2/"};
92 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +010093 }
94
95 SECTION("ls x")
96 {
97 input = "ls x";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +010098 expectedCompletions = {};
99 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100100 }
101
102 SECTION("ls /")
103 {
104 input = "ls /";
Václav Kubernátabf52802020-05-19 01:31:17 +0200105 expectedCompletions = {"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 +0100106 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100107 }
108
109 SECTION("ls /e")
110 {
111 input = "ls /e";
Václav Kubernátabf52802020-05-19 01:31:17 +0200112 expectedCompletions = {"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 +0100113 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100114 }
115
Václav Kubernáte69133a2019-11-01 19:01:34 +0100116 SECTION("ls example:bota")
117 {
118 input = "ls example:bota";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100119 expectedCompletions = {"example:bota/"};
120 expectedContextLength = 12;
Václav Kubernáte69133a2019-11-01 19:01:34 +0100121 }
122
123 SECTION("ls /example:bota")
124 {
125 input = "ls /example:bota";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100126 expectedCompletions = {"example:bota/"};
127 expectedContextLength = 12;
Václav Kubernáte69133a2019-11-01 19:01:34 +0100128 }
129
Václav Kubernát329c6c32019-02-06 16:41:53 +0100130 SECTION("ls /s")
131 {
132 input = "ls /s";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100133 expectedCompletions = {"second:amelie/"};
134 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100135 }
136
Václav Kubernát26be33a2020-02-13 13:30:14 +0100137 SECTION("ls /example:list/")
138 {
139 input = "ls /example:list/";
Václav Kubernáte2d629f2020-04-28 11:01:54 +0200140 expectedCompletions = {"contInList/", "number "};
Václav Kubernát26be33a2020-02-13 13:30:14 +0100141 expectedContextLength = 0;
142 }
143
Václav Kubernát329c6c32019-02-06 16:41:53 +0100144 SECTION("ls /example:list[number=3]/")
145 {
146 input = "ls /example:list[number=3]/";
Václav Kubernáte2d629f2020-04-28 11:01:54 +0200147 expectedCompletions = {"contInList/", "number "};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100148 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100149 }
150
151 SECTION("ls /example:list[number=3]/c")
152 {
Václav Kubernáte2d629f2020-04-28 11:01:54 +0200153 input = "ls /example:list[number=3]/c";
154 expectedCompletions = {"contInList/"};
155 expectedContextLength = 1;
156 }
157
158 SECTION("ls /example:list[number=3]/n")
159 {
160 input = "ls /example:list[number=3]/n";
161 expectedCompletions = {"number "};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100162 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100163 }
164
165 SECTION("ls /example:list[number=3]/a")
166 {
167 input = "ls /example:list[number=3]/a";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100168 expectedCompletions = {};
169 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100170 }
Václav Kubernát26be33a2020-02-13 13:30:14 +0100171
Václav Kubernáte2d629f2020-04-28 11:01:54 +0200172 SECTION("ls /example:list/contInList/")
Václav Kubernát26be33a2020-02-13 13:30:14 +0100173 {
Václav Kubernáte2d629f2020-04-28 11:01:54 +0200174 input = "ls /example:list/contInList/";
Václav Kubernát26be33a2020-02-13 13:30:14 +0100175 expectedCompletions = {};
176 expectedContextLength = 0;
177 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100178 }
179
Václav Kubernát329c6c32019-02-06 16:41:53 +0100180 SECTION("list keys completion")
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100181 {
Václav Kubernát329c6c32019-02-06 16:41:53 +0100182 SECTION("cd example:lis")
183 {
184 input = "cd example:lis";
Václav Kubernátcb3af402020-02-12 16:49:17 +0100185 expectedCompletions = {"example:list"};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100186 expectedContextLength = 11;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100187 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100188
Václav Kubernát51853b22019-04-16 21:53:44 +0200189 SECTION("set example:list")
190 {
191 input = "set example:list";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100192 expectedCompletions = {"example:list["};
193 expectedContextLength = 12;
Václav Kubernát4c325482019-04-11 17:51:55 +0200194 }
195
196 SECTION("cd example:list")
197 {
198 input = "cd example:list";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100199 expectedCompletions = {"example:list["};
200 expectedContextLength = 12;
Václav Kubernát51853b22019-04-16 21:53:44 +0200201 }
202
Václav Kubernát329c6c32019-02-06 16:41:53 +0100203 SECTION("cd example:list[")
204 {
205 input = "cd example:list[";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100206 expectedCompletions = {"number="};
207 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100208 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100209
Václav Kubernát329c6c32019-02-06 16:41:53 +0100210 SECTION("cd example:list[numb")
211 {
212 input = "cd example:list[numb";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100213 expectedCompletions = {"number="};
214 expectedContextLength = 4;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100215 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100216
Václav Kubernát329c6c32019-02-06 16:41:53 +0100217 SECTION("cd example:list[number")
218 {
219 input = "cd example:list[number";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100220 expectedCompletions = {"number="};
221 expectedContextLength = 6;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100222 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100223
Václav Kubernát117f7b52020-01-23 16:10:55 +0100224 SECTION("cd example:list[number=")
225 {
226 input = "cd example:list[number=";
Václav Kubernát43908fb2020-01-02 19:05:51 +0100227 expectedCompletions = {};
228 expectedContextLength = 0;
Václav Kubernát117f7b52020-01-23 16:10:55 +0100229 }
230
Václav Kubernát329c6c32019-02-06 16:41:53 +0100231 SECTION("cd example:list[number=12")
232 {
233 input = "cd example:list[number=12";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100234 expectedCompletions = {"]/"};
235 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100236 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100237
Václav Kubernát329c6c32019-02-06 16:41:53 +0100238 SECTION("cd example:list[number=12]")
239 {
240 input = "cd example:list[number=12]";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100241 expectedCompletions = {"]/"};
242 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100243 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100244
Václav Kubernát329c6c32019-02-06 16:41:53 +0100245 SECTION("cd example:twoKeyList[")
246 {
247 input = "cd example:twoKeyList[";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100248 expectedCompletions = {"name=", "number="};
249 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100250 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100251
Václav Kubernát4c325482019-04-11 17:51:55 +0200252 SECTION("cd example:twoKeyList[name=\"AHOJ\"")
253 {
254 input = "cd example:twoKeyList[name=\"AHOJ\"";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100255 expectedCompletions = {"]["};
256 expectedContextLength = 0;
Václav Kubernát4c325482019-04-11 17:51:55 +0200257 }
258
259 SECTION("cd example:twoKeyList[name=\"AHOJ\"]")
260 {
261 input = "cd example:twoKeyList[name=\"AHOJ\"]";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100262 expectedCompletions = {"]["};
263 expectedContextLength = 1;
Václav Kubernát4c325482019-04-11 17:51:55 +0200264 }
265
Václav Kubernát329c6c32019-02-06 16:41:53 +0100266 SECTION("cd example:twoKeyList[name=\"AHOJ\"][")
267 {
268 input = "cd example:twoKeyList[name=\"AHOJ\"][";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100269 expectedCompletions = {"number="};
270 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100271 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100272
Václav Kubernát329c6c32019-02-06 16:41:53 +0100273 SECTION("cd example:twoKeyList[number=42][")
274 {
275 input = "cd example:twoKeyList[number=42][";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100276 expectedCompletions = {"name="};
277 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100278 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100279
Václav Kubernát329c6c32019-02-06 16:41:53 +0100280 SECTION("cd example:twoKeyList[name=\"AHOJ\"][number=123")
281 {
282 input = "cd example:twoKeyList[name=\"AHOJ\"][number=123";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100283 expectedCompletions = {"]/"};
284 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100285 }
286
287 SECTION("cd example:twoKeyList[name=\"AHOJ\"][number=123]")
288 {
289 input = "cd example:twoKeyList[name=\"AHOJ\"][number=123]";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100290 expectedCompletions = {"]/"};
291 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100292 }
Václav Kubernát4c325482019-04-11 17:51:55 +0200293
294 SECTION("cd example:ovoce")
295 {
296 input = "cd example:ovoce";
Václav Kubernátcb3af402020-02-12 16:49:17 +0100297 expectedCompletions = {"example:ovoce", "example:ovocezelenina"};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100298 expectedContextLength = 13;
Václav Kubernát4c325482019-04-11 17:51:55 +0200299 }
Václav Kubernátcb3af402020-02-12 16:49:17 +0100300
301 SECTION("cd example:ovoceze")
302 {
303 input = "cd example:ovoceze";
304 expectedCompletions = {"example:ovocezelenina"};
305 expectedContextLength = 15;
306 }
307
308 SECTION("cd example:ovocezelenina")
309 {
310 input = "cd example:ovocezelenina";
311 expectedCompletions = {"example:ovocezelenina["};
312 expectedContextLength = 21;
313 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100314 }
315
Václav Kubernátabf52802020-05-19 01:31:17 +0200316 SECTION("no readonly data leafs in set")
317 {
318 input = "set example:read";
319 expectedContextLength = 12;
320 }
321
Václav Kubernát8028f942019-09-25 16:03:23 +0200322 SECTION("clear completions when no longer inputting path")
323 {
324 input = "set example:leafInt ";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100325 expectedCompletions = {};
326 expectedContextLength = 0;
Václav Kubernát8028f942019-09-25 16:03:23 +0200327 }
328
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100329 REQUIRE(parser.completeCommand(input, errorStream) == (Completions{expectedCompletions, expectedContextLength}));
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100330}