blob: 174ffd03a2fda59df6c46c76d325fca7217e50ae [file] [log] [blame]
Václav Kubernátd6662962018-03-22 17:41:33 +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át24df80e2018-06-06 15:18:03 +020010#include "ast_commands.hpp"
Václav Kubernát0af72572020-07-22 15:15:59 +020011#include "leaf_data_helpers.hpp"
Václav Kubernát48fc3832018-05-28 14:21:22 +020012#include "parser.hpp"
Václav Kubernátbddbb172018-06-13 16:27:39 +020013#include "static_schema.hpp"
Václav Kubernátd6662962018-03-22 17:41:33 +010014
15TEST_CASE("cd")
16{
Václav Kubernátbddbb172018-06-13 16:27:39 +020017 auto schema = std::make_shared<StaticSchema>();
Václav Kubernát744f57f2018-06-29 22:46:26 +020018 schema->addModule("example");
19 schema->addModule("second");
Václav Kubernátefcac932020-01-10 15:26:32 +010020 schema->addContainer("/", "example:a");
21 schema->addContainer("/", "second:a");
22 schema->addContainer("/", "example:b");
23 schema->addContainer("/example:a", "example:a2");
24 schema->addContainer("/example:b", "example:b2");
25 schema->addContainer("/example:a/example:a2", "example:a3");
26 schema->addContainer("/example:b/example:b2", "example:b3");
27 schema->addList("/", "example:list", {"number"});
Václav Kubernát3a99f002020-03-31 02:27:41 +020028 schema->addLeaf("/example:list", "example:number", yang::Int32{});
Václav Kubernátefcac932020-01-10 15:26:32 +010029 schema->addContainer("/example:list", "example:contInList");
30 schema->addList("/", "example:twoKeyList", {"number", "name"});
Václav Kubernát3a99f002020-03-31 02:27:41 +020031 schema->addLeaf("/example:twoKeyList", "example:number", yang::Int32{});
32 schema->addLeaf("/example:twoKeyList", "example:name", yang::String{});
Václav Kubernáte7248b22020-06-26 15:38:59 +020033 schema->addRpc("/", "example:launch-nukes");
Václav Kubernát0af72572020-07-22 15:15:59 +020034 schema->addList("/", "example:ports", {"name"});
35 schema->addLeaf("/example:ports", "example:name", createEnum({"A", "B", "C"}));
Václav Kubernát48fc3832018-05-28 14:21:22 +020036 Parser parser(schema);
Václav Kubernátd6662962018-03-22 17:41:33 +010037 std::string input;
Václav Kubernát2315c732018-05-16 20:25:55 +020038 std::ostringstream errorStream;
Václav Kubernátd6662962018-03-22 17:41:33 +010039
Václav Kubernát744f57f2018-06-29 22:46:26 +020040
Václav Kubernátb96eef72018-05-04 19:10:22 +020041 SECTION("valid input")
Václav Kubernátd6662962018-03-22 17:41:33 +010042 {
Václav Kubernátb96eef72018-05-04 19:10:22 +020043 cd_ expected;
44
45 SECTION("container")
Václav Kubernátd6662962018-03-22 17:41:33 +010046 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020047 SECTION("example:a")
Václav Kubernátb96eef72018-05-04 19:10:22 +020048 {
Václav Kubernátd6fd2492018-11-19 15:11:16 +010049 SECTION("trailing slash")
50 {
51 input = "cd example:a/";
52 expected.m_path.m_trailingSlash = TrailingSlash::Present;
53 }
54 SECTION("no trailing slash")
55 {
56 input = "cd example:a";
57 }
Václav Kubernátfaacd022020-07-08 16:44:38 +020058 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
Václav Kubernátb96eef72018-05-04 19:10:22 +020059 }
60
Václav Kubernát744f57f2018-06-29 22:46:26 +020061 SECTION("second:a")
Václav Kubernátb96eef72018-05-04 19:10:22 +020062 {
Václav Kubernátd6fd2492018-11-19 15:11:16 +010063 SECTION("trailing slash")
64 {
65 input = "cd second:a/";
66 expected.m_path.m_trailingSlash = TrailingSlash::Present;
67 }
68 SECTION("no trailing slash")
69 {
70 input = "cd second:a";
71 }
Václav Kubernátfaacd022020-07-08 16:44:38 +020072 expected.m_path.m_nodes.emplace_back(module_{"second"}, container_("a"));
Václav Kubernátb96eef72018-05-04 19:10:22 +020073 }
74
Václav Kubernát744f57f2018-06-29 22:46:26 +020075 SECTION("example:b")
Václav Kubernátb96eef72018-05-04 19:10:22 +020076 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020077 input = "cd example:b";
Václav Kubernátfaacd022020-07-08 16:44:38 +020078 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("b"));
Václav Kubernátb96eef72018-05-04 19:10:22 +020079 }
80
Václav Kubernát744f57f2018-06-29 22:46:26 +020081 SECTION("example:a/a2")
Václav Kubernátb96eef72018-05-04 19:10:22 +020082 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020083 input = "cd example:a/a2";
Václav Kubernátfaacd022020-07-08 16:44:38 +020084 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
85 expected.m_path.m_nodes.emplace_back(container_("a2"));
Václav Kubernát744f57f2018-06-29 22:46:26 +020086 }
87
88 SECTION("example:a/example:a2")
89 {
90 input = "cd example:a/example:a2";
Václav Kubernátfaacd022020-07-08 16:44:38 +020091 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
92 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a2"));
Václav Kubernát744f57f2018-06-29 22:46:26 +020093 }
94
95 SECTION("example:b/b2")
96 {
97 input = "cd example:b/b2";
Václav Kubernátfaacd022020-07-08 16:44:38 +020098 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("b"));
99 expected.m_path.m_nodes.emplace_back(container_("b2"));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200100 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100101 }
102
Václav Kubernátb96eef72018-05-04 19:10:22 +0200103 SECTION("list elements")
Václav Kubernátd6662962018-03-22 17:41:33 +0100104 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200105 SECTION("example:list[number=1]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200106 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200107 input = "cd example:list[number=1]";
Václav Kubernátc15fe822020-06-04 11:28:39 +0200108 auto keys = ListInstance {
Václav Kubernát7707cae2020-01-16 12:04:53 +0100109 {"number", int32_t{1}}};
Václav Kubernátfaacd022020-07-08 16:44:38 +0200110 expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("list", keys));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200111 }
112
Václav Kubernát744f57f2018-06-29 22:46:26 +0200113 SECTION("example:list[number=1]/contInList")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200114 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200115 input = "cd example:list[number=1]/contInList";
Václav Kubernátc15fe822020-06-04 11:28:39 +0200116 auto keys = ListInstance {
Václav Kubernát7707cae2020-01-16 12:04:53 +0100117 {"number", int32_t{1}}};
Václav Kubernátfaacd022020-07-08 16:44:38 +0200118 expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("list", keys));
119 expected.m_path.m_nodes.emplace_back(container_("contInList"));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200120 }
121
Václav Kubernát89728d82018-09-13 16:28:28 +0200122 SECTION("example:twoKeyList[number=4][name='abcd']")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200123 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200124 input = "cd example:twoKeyList[number=4][name='abcd']";
Václav Kubernátc15fe822020-06-04 11:28:39 +0200125 auto keys = ListInstance {
Václav Kubernát7707cae2020-01-16 12:04:53 +0100126 {"number", int32_t{4}},
127 {"name", std::string{"abcd"}}};
Václav Kubernátfaacd022020-07-08 16:44:38 +0200128 expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("twoKeyList", keys));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200129 }
Václav Kubernát0af72572020-07-22 15:15:59 +0200130
131 SECTION("enum key type")
132 {
133 input = "cd example:ports[name=A]";
134 auto keys = ListInstance {
135 {"name", enum_{"A"}}};
136 expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("ports", keys));
137 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100138 }
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200139
140 SECTION("whitespace handling")
141 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200142 SECTION(" cd example:a ")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200143 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200144 input = " cd example:a ";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200145 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200146 }
147 }
148
Václav Kubernát60d6f292018-05-25 09:45:32 +0200149 SECTION("moving up")
150 {
Václav Kubernátc2bfe492020-06-15 13:19:07 +0200151 SECTION("moving up when already in root")
152 {
153 input = "cd ..";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200154 expected.m_path.m_nodes.emplace_back(nodeup_());
Václav Kubernátc2bfe492020-06-15 13:19:07 +0200155 }
156
157 SECTION("moving up TWICE when already in root")
158 {
159 input = "cd ../..";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200160 expected.m_path.m_nodes.emplace_back(nodeup_());
161 expected.m_path.m_nodes.emplace_back(nodeup_());
Václav Kubernátc2bfe492020-06-15 13:19:07 +0200162 }
163
Václav Kubernát744f57f2018-06-29 22:46:26 +0200164 SECTION("example:a/..")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200165 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200166 input = "cd example:a/..";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200167 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
168 expected.m_path.m_nodes.emplace_back(nodeup_());
Václav Kubernát60d6f292018-05-25 09:45:32 +0200169 }
170
Václav Kubernát744f57f2018-06-29 22:46:26 +0200171 SECTION("example:a/../example:a")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200172 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200173 input = "cd example:a/../example:a";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200174 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
175 expected.m_path.m_nodes.emplace_back(nodeup_());
176 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
Václav Kubernát60d6f292018-05-25 09:45:32 +0200177 }
178
Václav Kubernát744f57f2018-06-29 22:46:26 +0200179 SECTION("example:a/../example:a/a2")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200180 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200181 input = "cd example:a/../example:a/a2";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200182 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
183 expected.m_path.m_nodes.emplace_back(nodeup_());
184 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
185 expected.m_path.m_nodes.emplace_back(container_("a2"));
Václav Kubernát60d6f292018-05-25 09:45:32 +0200186 }
187 }
188
Václav Kubernátb61336d2018-05-28 17:35:03 +0200189 command_ command = parser.parseCommand(input, errorStream);
190 REQUIRE(command.type() == typeid(cd_));
191 REQUIRE(boost::get<cd_>(command) == expected);
Václav Kubernátd6662962018-03-22 17:41:33 +0100192 }
Václav Kubernátb96eef72018-05-04 19:10:22 +0200193 SECTION("invalid input")
Václav Kubernátd6662962018-03-22 17:41:33 +0100194 {
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200195 SECTION("missing space between a command and its arguments")
196 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200197 SECTION("cdexample:a")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200198 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200199 input = "cdexample:a";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200200 }
201 }
Václav Kubernát744f57f2018-06-29 22:46:26 +0200202
203 SECTION("whitespace between module and nodename")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200204 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200205 SECTION("cd example: a")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200206 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200207 input = "cd example: a";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200208 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100209
Václav Kubernát744f57f2018-06-29 22:46:26 +0200210 SECTION("cd example : a")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200211 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200212 input = "cd example : a";
213 }
214
215 SECTION("cd example :a")
216 {
217 input = "cd example :a";
218 }
219 }
220
221 SECTION("entering modules")
222 {
223 SECTION("cd example")
224 {
225 input = "cd example";
226 }
227
228 SECTION("cd example:")
229 {
230 input = "cd example:";
231 }
232 }
233
234 SECTION("garbage arguments handling")
235 {
236 SECTION("cd example:a garbage")
237 {
238 input = "cd example:a garbage";
239 }
240 SECTION("cd example:a/a2 garbage")
241 {
242 input = "cd example:a/a2 garbage";
243 }
244 }
245
246 SECTION("invalid node identifiers")
247 {
248 SECTION("example:nonexistent")
249 {
250 input = "cd example:nonexistent";
251 }
252
253 SECTION("example:nonexistent/lol")
254 {
255 input = "cd example:nonexistent/lol";
256 }
257 }
258
259 SECTION("invalid module identifiers")
260 {
261 SECTION("elpmaxe:nonexistent")
262 {
263 input = "cd elpmaxe:nonexistent";
264 }
265
266 SECTION("elpmaxe:nonexistent/example:lol")
267 {
268 input = "cd elpmaxe:nonexistent/example:lol";
269 }
270 }
271
272 SECTION("no top-level module")
273 {
274 SECTION("cd a")
275 {
276 input = "cd a";
277 }
278
279 SECTION("cd example:a/../a")
280 {
281 input = "cd example:a/../a";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200282 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100283 }
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200284
Václav Kubernátb96eef72018-05-04 19:10:22 +0200285 SECTION("invalid list key identifiers")
286 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200287 SECTION("example:list")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200288 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200289 input = "cd example:list";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200290 }
291
Václav Kubernát744f57f2018-06-29 22:46:26 +0200292 SECTION("example:list[]")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200293 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200294 input = "cd example:list[]";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200295 }
296
Václav Kubernát89728d82018-09-13 16:28:28 +0200297 SECTION("example:twoKeyList[invalidKey='4']")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200298 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200299 input = "cd example:twoKeyList[invalidKey='4']";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200300 }
301
Václav Kubernát89728d82018-09-13 16:28:28 +0200302 SECTION("example:twoKeyList[number=4][number=5]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200303 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200304 input = "cd example:twoKeyList[number=4][number=5]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200305 }
306
Václav Kubernát89728d82018-09-13 16:28:28 +0200307 SECTION("example:twoKeyList[number=4][name='lol'][number=7]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200308 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200309 input = "cd example:twoKeyList[number=4][name='lol'][number=7]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200310 }
311
Václav Kubernát744f57f2018-06-29 22:46:26 +0200312 SECTION("example:twoKeyList[number=4]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200313 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200314 input = "cd example:twoKeyList[number=4]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200315 }
Václav Kubernát89728d82018-09-13 16:28:28 +0200316
317 SECTION("strings must be quoted")
318 {
319 input = "cd example:twoKeyList[number=4][name=abcd]";
320 }
Václav Kubernátb96eef72018-05-04 19:10:22 +0200321 }
Václav Kubernát9fa5dca2020-06-01 03:56:41 +0200322
323 SECTION("no space between list prefix and suffix")
324 {
325 input = "cd example:list [number=10]";
326 }
327
Václav Kubernáte7248b22020-06-26 15:38:59 +0200328 SECTION("cd into rpc")
329 {
330 input = "cd example:launch-nukes";
331 }
332
Jan Kundrátc381e632019-03-14 13:39:11 +0100333 REQUIRE_THROWS_AS(parser.parseCommand(input, errorStream), InvalidCommandException);
Václav Kubernátd6662962018-03-22 17:41:33 +0100334 }
335}