blob: 3e29d5a054470981b48db71681523ffda280accd [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át0d47e5e2020-11-17 12:27:05 +010036 schema->addLeaf("/", "example:myLeaf", yang::Int32{});
Václav Kubernát48fc3832018-05-28 14:21:22 +020037 Parser parser(schema);
Václav Kubernátd6662962018-03-22 17:41:33 +010038 std::string input;
Václav Kubernát2315c732018-05-16 20:25:55 +020039 std::ostringstream errorStream;
Václav Kubernátd6662962018-03-22 17:41:33 +010040
Václav Kubernát744f57f2018-06-29 22:46:26 +020041
Václav Kubernátb96eef72018-05-04 19:10:22 +020042 SECTION("valid input")
Václav Kubernátd6662962018-03-22 17:41:33 +010043 {
Václav Kubernátb96eef72018-05-04 19:10:22 +020044 cd_ expected;
45
46 SECTION("container")
Václav Kubernátd6662962018-03-22 17:41:33 +010047 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020048 SECTION("example:a")
Václav Kubernátb96eef72018-05-04 19:10:22 +020049 {
Václav Kubernátd6fd2492018-11-19 15:11:16 +010050 SECTION("trailing slash")
51 {
52 input = "cd example:a/";
53 expected.m_path.m_trailingSlash = TrailingSlash::Present;
54 }
55 SECTION("no trailing slash")
56 {
57 input = "cd example:a";
58 }
Václav Kubernátfaacd022020-07-08 16:44:38 +020059 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
Václav Kubernátb96eef72018-05-04 19:10:22 +020060 }
61
Václav Kubernát744f57f2018-06-29 22:46:26 +020062 SECTION("second:a")
Václav Kubernátb96eef72018-05-04 19:10:22 +020063 {
Václav Kubernátd6fd2492018-11-19 15:11:16 +010064 SECTION("trailing slash")
65 {
66 input = "cd second:a/";
67 expected.m_path.m_trailingSlash = TrailingSlash::Present;
68 }
69 SECTION("no trailing slash")
70 {
71 input = "cd second:a";
72 }
Václav Kubernátfaacd022020-07-08 16:44:38 +020073 expected.m_path.m_nodes.emplace_back(module_{"second"}, container_("a"));
Václav Kubernátb96eef72018-05-04 19:10:22 +020074 }
75
Václav Kubernát744f57f2018-06-29 22:46:26 +020076 SECTION("example:b")
Václav Kubernátb96eef72018-05-04 19:10:22 +020077 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020078 input = "cd example:b";
Václav Kubernátfaacd022020-07-08 16:44:38 +020079 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("b"));
Václav Kubernátb96eef72018-05-04 19:10:22 +020080 }
81
Václav Kubernát744f57f2018-06-29 22:46:26 +020082 SECTION("example:a/a2")
Václav Kubernátb96eef72018-05-04 19:10:22 +020083 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020084 input = "cd example:a/a2";
Václav Kubernátfaacd022020-07-08 16:44:38 +020085 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
86 expected.m_path.m_nodes.emplace_back(container_("a2"));
Václav Kubernát744f57f2018-06-29 22:46:26 +020087 }
88
89 SECTION("example:a/example:a2")
90 {
91 input = "cd example:a/example:a2";
Václav Kubernátfaacd022020-07-08 16:44:38 +020092 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
93 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a2"));
Václav Kubernát744f57f2018-06-29 22:46:26 +020094 }
95
96 SECTION("example:b/b2")
97 {
98 input = "cd example:b/b2";
Václav Kubernátfaacd022020-07-08 16:44:38 +020099 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("b"));
100 expected.m_path.m_nodes.emplace_back(container_("b2"));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200101 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100102 }
103
Václav Kubernátb96eef72018-05-04 19:10:22 +0200104 SECTION("list elements")
Václav Kubernátd6662962018-03-22 17:41:33 +0100105 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200106 SECTION("example:list[number=1]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200107 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200108 input = "cd example:list[number=1]";
Václav Kubernátc15fe822020-06-04 11:28:39 +0200109 auto keys = ListInstance {
Václav Kubernát7707cae2020-01-16 12:04:53 +0100110 {"number", int32_t{1}}};
Václav Kubernátfaacd022020-07-08 16:44:38 +0200111 expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("list", keys));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200112 }
113
Václav Kubernát744f57f2018-06-29 22:46:26 +0200114 SECTION("example:list[number=1]/contInList")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200115 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200116 input = "cd example:list[number=1]/contInList";
Václav Kubernátc15fe822020-06-04 11:28:39 +0200117 auto keys = ListInstance {
Václav Kubernát7707cae2020-01-16 12:04:53 +0100118 {"number", int32_t{1}}};
Václav Kubernátfaacd022020-07-08 16:44:38 +0200119 expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("list", keys));
120 expected.m_path.m_nodes.emplace_back(container_("contInList"));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200121 }
122
Václav Kubernát89728d82018-09-13 16:28:28 +0200123 SECTION("example:twoKeyList[number=4][name='abcd']")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200124 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200125 input = "cd example:twoKeyList[number=4][name='abcd']";
Václav Kubernátc15fe822020-06-04 11:28:39 +0200126 auto keys = ListInstance {
Václav Kubernát7707cae2020-01-16 12:04:53 +0100127 {"number", int32_t{4}},
128 {"name", std::string{"abcd"}}};
Václav Kubernátfaacd022020-07-08 16:44:38 +0200129 expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("twoKeyList", keys));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200130 }
Václav Kubernát0af72572020-07-22 15:15:59 +0200131
132 SECTION("enum key type")
133 {
134 input = "cd example:ports[name=A]";
135 auto keys = ListInstance {
136 {"name", enum_{"A"}}};
137 expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("ports", keys));
138 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100139 }
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200140
141 SECTION("whitespace handling")
142 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200143 SECTION(" cd example:a ")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200144 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200145 input = " cd example:a ";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200146 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200147 }
148 }
149
Václav Kubernát60d6f292018-05-25 09:45:32 +0200150 SECTION("moving up")
151 {
Václav Kubernátc2bfe492020-06-15 13:19:07 +0200152 SECTION("moving up when already in root")
153 {
154 input = "cd ..";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200155 expected.m_path.m_nodes.emplace_back(nodeup_());
Václav Kubernátc2bfe492020-06-15 13:19:07 +0200156 }
157
158 SECTION("moving up TWICE when already in root")
159 {
160 input = "cd ../..";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200161 expected.m_path.m_nodes.emplace_back(nodeup_());
162 expected.m_path.m_nodes.emplace_back(nodeup_());
Václav Kubernátc2bfe492020-06-15 13:19:07 +0200163 }
164
Václav Kubernát744f57f2018-06-29 22:46:26 +0200165 SECTION("example:a/..")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200166 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200167 input = "cd example:a/..";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200168 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
169 expected.m_path.m_nodes.emplace_back(nodeup_());
Václav Kubernát60d6f292018-05-25 09:45:32 +0200170 }
171
Václav Kubernát744f57f2018-06-29 22:46:26 +0200172 SECTION("example:a/../example:a")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200173 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200174 input = "cd example:a/../example:a";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200175 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
176 expected.m_path.m_nodes.emplace_back(nodeup_());
177 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
Václav Kubernát60d6f292018-05-25 09:45:32 +0200178 }
179
Václav Kubernát744f57f2018-06-29 22:46:26 +0200180 SECTION("example:a/../example:a/a2")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200181 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200182 input = "cd example:a/../example:a/a2";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200183 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
184 expected.m_path.m_nodes.emplace_back(nodeup_());
185 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
186 expected.m_path.m_nodes.emplace_back(container_("a2"));
Václav Kubernát60d6f292018-05-25 09:45:32 +0200187 }
188 }
189
Václav Kubernátb61336d2018-05-28 17:35:03 +0200190 command_ command = parser.parseCommand(input, errorStream);
191 REQUIRE(command.type() == typeid(cd_));
192 REQUIRE(boost::get<cd_>(command) == expected);
Václav Kubernátd6662962018-03-22 17:41:33 +0100193 }
Václav Kubernátb96eef72018-05-04 19:10:22 +0200194 SECTION("invalid input")
Václav Kubernátd6662962018-03-22 17:41:33 +0100195 {
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200196 SECTION("missing space between a command and its arguments")
197 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200198 SECTION("cdexample:a")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200199 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200200 input = "cdexample:a";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200201 }
202 }
Václav Kubernát744f57f2018-06-29 22:46:26 +0200203
204 SECTION("whitespace between module and nodename")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200205 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200206 SECTION("cd example: a")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200207 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200208 input = "cd example: a";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200209 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100210
Václav Kubernát744f57f2018-06-29 22:46:26 +0200211 SECTION("cd example : a")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200212 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200213 input = "cd example : a";
214 }
215
216 SECTION("cd example :a")
217 {
218 input = "cd example :a";
219 }
220 }
221
222 SECTION("entering modules")
223 {
224 SECTION("cd example")
225 {
226 input = "cd example";
227 }
228
229 SECTION("cd example:")
230 {
231 input = "cd example:";
232 }
233 }
234
235 SECTION("garbage arguments handling")
236 {
237 SECTION("cd example:a garbage")
238 {
239 input = "cd example:a garbage";
240 }
241 SECTION("cd example:a/a2 garbage")
242 {
243 input = "cd example:a/a2 garbage";
244 }
245 }
246
247 SECTION("invalid node identifiers")
248 {
249 SECTION("example:nonexistent")
250 {
251 input = "cd example:nonexistent";
252 }
253
254 SECTION("example:nonexistent/lol")
255 {
256 input = "cd example:nonexistent/lol";
257 }
258 }
259
260 SECTION("invalid module identifiers")
261 {
262 SECTION("elpmaxe:nonexistent")
263 {
264 input = "cd elpmaxe:nonexistent";
265 }
266
267 SECTION("elpmaxe:nonexistent/example:lol")
268 {
269 input = "cd elpmaxe:nonexistent/example:lol";
270 }
271 }
272
273 SECTION("no top-level module")
274 {
275 SECTION("cd a")
276 {
277 input = "cd a";
278 }
279
280 SECTION("cd example:a/../a")
281 {
282 input = "cd example:a/../a";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200283 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100284 }
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200285
Václav Kubernátb96eef72018-05-04 19:10:22 +0200286 SECTION("invalid list key identifiers")
287 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200288 SECTION("example:list")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200289 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200290 input = "cd example:list";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200291 }
292
Václav Kubernát744f57f2018-06-29 22:46:26 +0200293 SECTION("example:list[]")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200294 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200295 input = "cd example:list[]";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200296 }
297
Václav Kubernát89728d82018-09-13 16:28:28 +0200298 SECTION("example:twoKeyList[invalidKey='4']")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200299 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200300 input = "cd example:twoKeyList[invalidKey='4']";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200301 }
302
Václav Kubernát89728d82018-09-13 16:28:28 +0200303 SECTION("example:twoKeyList[number=4][number=5]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200304 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200305 input = "cd example:twoKeyList[number=4][number=5]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200306 }
307
Václav Kubernát89728d82018-09-13 16:28:28 +0200308 SECTION("example:twoKeyList[number=4][name='lol'][number=7]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200309 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200310 input = "cd example:twoKeyList[number=4][name='lol'][number=7]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200311 }
312
Václav Kubernát744f57f2018-06-29 22:46:26 +0200313 SECTION("example:twoKeyList[number=4]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200314 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200315 input = "cd example:twoKeyList[number=4]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200316 }
Václav Kubernát89728d82018-09-13 16:28:28 +0200317
318 SECTION("strings must be quoted")
319 {
320 input = "cd example:twoKeyList[number=4][name=abcd]";
321 }
Václav Kubernátb96eef72018-05-04 19:10:22 +0200322 }
Václav Kubernát9fa5dca2020-06-01 03:56:41 +0200323
324 SECTION("no space between list prefix and suffix")
325 {
326 input = "cd example:list [number=10]";
327 }
328
Václav Kubernáte7248b22020-06-26 15:38:59 +0200329 SECTION("cd into rpc")
330 {
331 input = "cd example:launch-nukes";
332 }
333
Václav Kubernát0d47e5e2020-11-17 12:27:05 +0100334 SECTION("cd into a leaf")
335 {
336 input = "cd example:myLeaf";
337 }
338
Jan Kundrátc381e632019-03-14 13:39:11 +0100339 REQUIRE_THROWS_AS(parser.parseCommand(input, errorStream), InvalidCommandException);
Václav Kubernátd6662962018-03-22 17:41:33 +0100340 }
341}