blob: bfc83d27bb257bff608458e9ab59b2410eb9a9b4 [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át43908fb2020-01-02 19:05:51 +010040 auto mockDatastore = std::make_shared<MockDatastoreAccess>();
41
42 // The parser will use DataQuery for key value completion, but I'm not testing that here, so I don't return anything.
43 ALLOW_CALL(*mockDatastore, listInstances("/example:list"))
44 .RETURN(std::vector<ListInstance>{});
45 ALLOW_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
46 .RETURN(std::vector<ListInstance>{});
47
48 // DataQuery gets the schema from DatastoreAccess once
49 auto expectation = NAMED_REQUIRE_CALL(*mockDatastore, schema())
50 .RETURN(schema);
51 auto dataQuery = std::make_shared<DataQuery>(*mockDatastore);
52 expectation.reset();
53 Parser parser(schema, dataQuery);
Václav Kubernát4108e0d2018-10-29 13:32:22 +010054 std::string input;
55 std::ostringstream errorStream;
Václav Kubernát1ed4aa32020-01-23 13:13:28 +010056
57 std::set<std::string> expectedCompletions;
58 // GCC complains here with -Wmaybe-uninitialized if I don't assign
59 // something here. I suspect it's because of nested SECTIONs. -1 is an
60 // invalid value (as in, I'll never expect expectedContextLength to be -1),
61 // so let's go with that.
62 int expectedContextLength = -1;
Václav Kubernát4108e0d2018-10-29 13:32:22 +010063
Václav Kubernát329c6c32019-02-06 16:41:53 +010064 SECTION("node name completion")
Václav Kubernát4108e0d2018-10-29 13:32:22 +010065 {
Václav Kubernát329c6c32019-02-06 16:41:53 +010066 SECTION("ls ")
67 {
68 input = "ls ";
Václav Kubernátcb3af402020-02-12 16:49:17 +010069 expectedCompletions = {"example:ano/", "example:anoda/", "example:bota/", "example:leafInt ", "example:list", "example:ovoce", "example:ovocezelenina", "example:twoKeyList", "second:amelie/"};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +010070 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +010071 }
72
73 SECTION("ls e")
74 {
75 input = "ls e";
Václav Kubernátcb3af402020-02-12 16:49:17 +010076 expectedCompletions = {"example:ano/", "example:anoda/", "example:bota/", "example:leafInt ", "example:list", "example:ovoce", "example:ovocezelenina", "example:twoKeyList"};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +010077 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +010078 }
79
80 SECTION("ls example:ano")
81 {
82 input = "ls example:ano";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +010083 expectedCompletions = {"example:ano/", "example:anoda/"};
84 expectedContextLength = 11;
Václav Kubernát329c6c32019-02-06 16:41:53 +010085 }
86
Václav Kubernáte2d629f2020-04-28 11:01:54 +020087 SECTION("ls example:ano/a")
Václav Kubernát329c6c32019-02-06 16:41:53 +010088 {
Václav Kubernáte2d629f2020-04-28 11:01:54 +020089 input = "ls example:ano/a";
90 expectedCompletions = {"a2/"};
91 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +010092 }
93
94 SECTION("ls x")
95 {
96 input = "ls x";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +010097 expectedCompletions = {};
98 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +010099 }
100
101 SECTION("ls /")
102 {
103 input = "ls /";
Václav Kubernátcb3af402020-02-12 16:49:17 +0100104 expectedCompletions = {"example:ano/", "example:anoda/", "example:bota/", "example:leafInt ", "example:list", "example:ovoce", "example:ovocezelenina", "example:twoKeyList", "second:amelie/"};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100105 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100106 }
107
108 SECTION("ls /e")
109 {
110 input = "ls /e";
Václav Kubernátcb3af402020-02-12 16:49:17 +0100111 expectedCompletions = {"example:ano/", "example:anoda/", "example:bota/", "example:leafInt ", "example:list", "example:ovoce", "example:ovocezelenina", "example:twoKeyList"};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100112 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100113 }
114
Václav Kubernáte69133a2019-11-01 19:01:34 +0100115 SECTION("ls example:bota")
116 {
117 input = "ls example:bota";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100118 expectedCompletions = {"example:bota/"};
119 expectedContextLength = 12;
Václav Kubernáte69133a2019-11-01 19:01:34 +0100120 }
121
122 SECTION("ls /example:bota")
123 {
124 input = "ls /example:bota";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100125 expectedCompletions = {"example:bota/"};
126 expectedContextLength = 12;
Václav Kubernáte69133a2019-11-01 19:01:34 +0100127 }
128
Václav Kubernát329c6c32019-02-06 16:41:53 +0100129 SECTION("ls /s")
130 {
131 input = "ls /s";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100132 expectedCompletions = {"second:amelie/"};
133 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100134 }
135
Václav Kubernát26be33a2020-02-13 13:30:14 +0100136 SECTION("ls /example:list/")
137 {
138 input = "ls /example:list/";
Václav Kubernáte2d629f2020-04-28 11:01:54 +0200139 expectedCompletions = {"contInList/", "number "};
Václav Kubernát26be33a2020-02-13 13:30:14 +0100140 expectedContextLength = 0;
141 }
142
Václav Kubernát329c6c32019-02-06 16:41:53 +0100143 SECTION("ls /example:list[number=3]/")
144 {
145 input = "ls /example:list[number=3]/";
Václav Kubernáte2d629f2020-04-28 11:01:54 +0200146 expectedCompletions = {"contInList/", "number "};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100147 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100148 }
149
150 SECTION("ls /example:list[number=3]/c")
151 {
Václav Kubernáte2d629f2020-04-28 11:01:54 +0200152 input = "ls /example:list[number=3]/c";
153 expectedCompletions = {"contInList/"};
154 expectedContextLength = 1;
155 }
156
157 SECTION("ls /example:list[number=3]/n")
158 {
159 input = "ls /example:list[number=3]/n";
160 expectedCompletions = {"number "};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100161 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100162 }
163
164 SECTION("ls /example:list[number=3]/a")
165 {
166 input = "ls /example:list[number=3]/a";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100167 expectedCompletions = {};
168 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100169 }
Václav Kubernát26be33a2020-02-13 13:30:14 +0100170
Václav Kubernáte2d629f2020-04-28 11:01:54 +0200171 SECTION("ls /example:list/contInList/")
Václav Kubernát26be33a2020-02-13 13:30:14 +0100172 {
Václav Kubernáte2d629f2020-04-28 11:01:54 +0200173 input = "ls /example:list/contInList/";
Václav Kubernát26be33a2020-02-13 13:30:14 +0100174 expectedCompletions = {};
175 expectedContextLength = 0;
176 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100177 }
178
Václav Kubernát329c6c32019-02-06 16:41:53 +0100179 SECTION("list keys completion")
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100180 {
Václav Kubernát329c6c32019-02-06 16:41:53 +0100181 SECTION("cd example:lis")
182 {
183 input = "cd example:lis";
Václav Kubernátcb3af402020-02-12 16:49:17 +0100184 expectedCompletions = {"example:list"};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100185 expectedContextLength = 11;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100186 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100187
Václav Kubernát51853b22019-04-16 21:53:44 +0200188 SECTION("set example:list")
189 {
190 input = "set example:list";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100191 expectedCompletions = {"example:list["};
192 expectedContextLength = 12;
Václav Kubernát4c325482019-04-11 17:51:55 +0200193 }
194
195 SECTION("cd example:list")
196 {
197 input = "cd example:list";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100198 expectedCompletions = {"example:list["};
199 expectedContextLength = 12;
Václav Kubernát51853b22019-04-16 21:53:44 +0200200 }
201
Václav Kubernát329c6c32019-02-06 16:41:53 +0100202 SECTION("cd example:list[")
203 {
204 input = "cd example:list[";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100205 expectedCompletions = {"number="};
206 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100207 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100208
Václav Kubernát329c6c32019-02-06 16:41:53 +0100209 SECTION("cd example:list[numb")
210 {
211 input = "cd example:list[numb";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100212 expectedCompletions = {"number="};
213 expectedContextLength = 4;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100214 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100215
Václav Kubernát329c6c32019-02-06 16:41:53 +0100216 SECTION("cd example:list[number")
217 {
218 input = "cd example:list[number";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100219 expectedCompletions = {"number="};
220 expectedContextLength = 6;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100221 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100222
Václav Kubernát117f7b52020-01-23 16:10:55 +0100223 SECTION("cd example:list[number=")
224 {
225 input = "cd example:list[number=";
Václav Kubernát43908fb2020-01-02 19:05:51 +0100226 expectedCompletions = {};
227 expectedContextLength = 0;
Václav Kubernát117f7b52020-01-23 16:10:55 +0100228 }
229
Václav Kubernát329c6c32019-02-06 16:41:53 +0100230 SECTION("cd example:list[number=12")
231 {
232 input = "cd example:list[number=12";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100233 expectedCompletions = {"]/"};
234 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100235 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100236
Václav Kubernát329c6c32019-02-06 16:41:53 +0100237 SECTION("cd example:list[number=12]")
238 {
239 input = "cd example:list[number=12]";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100240 expectedCompletions = {"]/"};
241 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100242 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100243
Václav Kubernát329c6c32019-02-06 16:41:53 +0100244 SECTION("cd example:twoKeyList[")
245 {
246 input = "cd example:twoKeyList[";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100247 expectedCompletions = {"name=", "number="};
248 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100249 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100250
Václav Kubernát4c325482019-04-11 17:51:55 +0200251 SECTION("cd example:twoKeyList[name=\"AHOJ\"")
252 {
253 input = "cd example:twoKeyList[name=\"AHOJ\"";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100254 expectedCompletions = {"]["};
255 expectedContextLength = 0;
Václav Kubernát4c325482019-04-11 17:51:55 +0200256 }
257
258 SECTION("cd example:twoKeyList[name=\"AHOJ\"]")
259 {
260 input = "cd example:twoKeyList[name=\"AHOJ\"]";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100261 expectedCompletions = {"]["};
262 expectedContextLength = 1;
Václav Kubernát4c325482019-04-11 17:51:55 +0200263 }
264
Václav Kubernát329c6c32019-02-06 16:41:53 +0100265 SECTION("cd example:twoKeyList[name=\"AHOJ\"][")
266 {
267 input = "cd example:twoKeyList[name=\"AHOJ\"][";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100268 expectedCompletions = {"number="};
269 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100270 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100271
Václav Kubernát329c6c32019-02-06 16:41:53 +0100272 SECTION("cd example:twoKeyList[number=42][")
273 {
274 input = "cd example:twoKeyList[number=42][";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100275 expectedCompletions = {"name="};
276 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100277 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100278
Václav Kubernát329c6c32019-02-06 16:41:53 +0100279 SECTION("cd example:twoKeyList[name=\"AHOJ\"][number=123")
280 {
281 input = "cd example:twoKeyList[name=\"AHOJ\"][number=123";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100282 expectedCompletions = {"]/"};
283 expectedContextLength = 0;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100284 }
285
286 SECTION("cd example:twoKeyList[name=\"AHOJ\"][number=123]")
287 {
288 input = "cd example:twoKeyList[name=\"AHOJ\"][number=123]";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100289 expectedCompletions = {"]/"};
290 expectedContextLength = 1;
Václav Kubernát329c6c32019-02-06 16:41:53 +0100291 }
Václav Kubernát4c325482019-04-11 17:51:55 +0200292
293 SECTION("cd example:ovoce")
294 {
295 input = "cd example:ovoce";
Václav Kubernátcb3af402020-02-12 16:49:17 +0100296 expectedCompletions = {"example:ovoce", "example:ovocezelenina"};
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100297 expectedContextLength = 13;
Václav Kubernát4c325482019-04-11 17:51:55 +0200298 }
Václav Kubernátcb3af402020-02-12 16:49:17 +0100299
300 SECTION("cd example:ovoceze")
301 {
302 input = "cd example:ovoceze";
303 expectedCompletions = {"example:ovocezelenina"};
304 expectedContextLength = 15;
305 }
306
307 SECTION("cd example:ovocezelenina")
308 {
309 input = "cd example:ovocezelenina";
310 expectedCompletions = {"example:ovocezelenina["};
311 expectedContextLength = 21;
312 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100313 }
314
Václav Kubernát8028f942019-09-25 16:03:23 +0200315 SECTION("clear completions when no longer inputting path")
316 {
317 input = "set example:leafInt ";
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100318 expectedCompletions = {};
319 expectedContextLength = 0;
Václav Kubernát8028f942019-09-25 16:03:23 +0200320 }
321
Václav Kubernát1ed4aa32020-01-23 13:13:28 +0100322 REQUIRE(parser.completeCommand(input, errorStream) == (Completions{expectedCompletions, expectedContextLength}));
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100323}