blob: ee056aed354a1c3603b3e4f95d6a44ea279823c6 [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átce108db2021-01-25 10:05:40 +010013#include "pretty_printers.hpp"
Václav Kubernátbddbb172018-06-13 16:27:39 +020014#include "static_schema.hpp"
Václav Kubernátd6662962018-03-22 17:41:33 +010015
16TEST_CASE("cd")
17{
Václav Kubernátbddbb172018-06-13 16:27:39 +020018 auto schema = std::make_shared<StaticSchema>();
Václav Kubernát744f57f2018-06-29 22:46:26 +020019 schema->addModule("example");
20 schema->addModule("second");
Václav Kubernátefcac932020-01-10 15:26:32 +010021 schema->addContainer("/", "example:a");
22 schema->addContainer("/", "second:a");
23 schema->addContainer("/", "example:b");
24 schema->addContainer("/example:a", "example:a2");
25 schema->addContainer("/example:b", "example:b2");
26 schema->addContainer("/example:a/example:a2", "example:a3");
27 schema->addContainer("/example:b/example:b2", "example:b3");
28 schema->addList("/", "example:list", {"number"});
Václav Kubernát3a99f002020-03-31 02:27:41 +020029 schema->addLeaf("/example:list", "example:number", yang::Int32{});
Václav Kubernátefcac932020-01-10 15:26:32 +010030 schema->addContainer("/example:list", "example:contInList");
31 schema->addList("/", "example:twoKeyList", {"number", "name"});
Václav Kubernát3a99f002020-03-31 02:27:41 +020032 schema->addLeaf("/example:twoKeyList", "example:number", yang::Int32{});
33 schema->addLeaf("/example:twoKeyList", "example:name", yang::String{});
Václav Kubernáte7248b22020-06-26 15:38:59 +020034 schema->addRpc("/", "example:launch-nukes");
Václav Kubernát0af72572020-07-22 15:15:59 +020035 schema->addList("/", "example:ports", {"name"});
36 schema->addLeaf("/example:ports", "example:name", createEnum({"A", "B", "C"}));
Václav Kubernát0d47e5e2020-11-17 12:27:05 +010037 schema->addLeaf("/", "example:myLeaf", yang::Int32{});
Václav Kubernát48fc3832018-05-28 14:21:22 +020038 Parser parser(schema);
Václav Kubernátd6662962018-03-22 17:41:33 +010039 std::string input;
Václav Kubernát2315c732018-05-16 20:25:55 +020040 std::ostringstream errorStream;
Václav Kubernátd6662962018-03-22 17:41:33 +010041
Václav Kubernát744f57f2018-06-29 22:46:26 +020042
Václav Kubernátb96eef72018-05-04 19:10:22 +020043 SECTION("valid input")
Václav Kubernátd6662962018-03-22 17:41:33 +010044 {
Václav Kubernátb96eef72018-05-04 19:10:22 +020045 cd_ expected;
46
47 SECTION("container")
Václav Kubernátd6662962018-03-22 17:41:33 +010048 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020049 SECTION("example:a")
Václav Kubernátb96eef72018-05-04 19:10:22 +020050 {
Václav Kubernátd6fd2492018-11-19 15:11:16 +010051 SECTION("trailing slash")
52 {
53 input = "cd example:a/";
54 expected.m_path.m_trailingSlash = TrailingSlash::Present;
55 }
56 SECTION("no trailing slash")
57 {
58 input = "cd example:a";
59 }
Václav Kubernátfaacd022020-07-08 16:44:38 +020060 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
Václav Kubernátb96eef72018-05-04 19:10:22 +020061 }
62
Václav Kubernát744f57f2018-06-29 22:46:26 +020063 SECTION("second:a")
Václav Kubernátb96eef72018-05-04 19:10:22 +020064 {
Václav Kubernátd6fd2492018-11-19 15:11:16 +010065 SECTION("trailing slash")
66 {
67 input = "cd second:a/";
68 expected.m_path.m_trailingSlash = TrailingSlash::Present;
69 }
70 SECTION("no trailing slash")
71 {
72 input = "cd second:a";
73 }
Václav Kubernátfaacd022020-07-08 16:44:38 +020074 expected.m_path.m_nodes.emplace_back(module_{"second"}, container_("a"));
Václav Kubernátb96eef72018-05-04 19:10:22 +020075 }
76
Václav Kubernát744f57f2018-06-29 22:46:26 +020077 SECTION("example:b")
Václav Kubernátb96eef72018-05-04 19:10:22 +020078 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020079 input = "cd example:b";
Václav Kubernátfaacd022020-07-08 16:44:38 +020080 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("b"));
Václav Kubernátb96eef72018-05-04 19:10:22 +020081 }
82
Václav Kubernát744f57f2018-06-29 22:46:26 +020083 SECTION("example:a/a2")
Václav Kubernátb96eef72018-05-04 19:10:22 +020084 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020085 input = "cd example:a/a2";
Václav Kubernátfaacd022020-07-08 16:44:38 +020086 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
87 expected.m_path.m_nodes.emplace_back(container_("a2"));
Václav Kubernát744f57f2018-06-29 22:46:26 +020088 }
89
90 SECTION("example:a/example:a2")
91 {
92 input = "cd example:a/example:a2";
Václav Kubernátfaacd022020-07-08 16:44:38 +020093 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
94 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a2"));
Václav Kubernát744f57f2018-06-29 22:46:26 +020095 }
96
97 SECTION("example:b/b2")
98 {
99 input = "cd example:b/b2";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200100 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("b"));
101 expected.m_path.m_nodes.emplace_back(container_("b2"));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200102 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100103 }
104
Václav Kubernátb96eef72018-05-04 19:10:22 +0200105 SECTION("list elements")
Václav Kubernátd6662962018-03-22 17:41:33 +0100106 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200107 SECTION("example:list[number=1]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200108 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200109 input = "cd example:list[number=1]";
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100110 auto keys = ListInstance{
Václav Kubernát7707cae2020-01-16 12:04:53 +0100111 {"number", int32_t{1}}};
Václav Kubernátfaacd022020-07-08 16:44:38 +0200112 expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("list", keys));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200113 }
114
Václav Kubernát744f57f2018-06-29 22:46:26 +0200115 SECTION("example:list[number=1]/contInList")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200116 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200117 input = "cd example:list[number=1]/contInList";
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100118 auto keys = ListInstance{
Václav Kubernát7707cae2020-01-16 12:04:53 +0100119 {"number", int32_t{1}}};
Václav Kubernátfaacd022020-07-08 16:44:38 +0200120 expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("list", keys));
121 expected.m_path.m_nodes.emplace_back(container_("contInList"));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200122 }
123
Václav Kubernát89728d82018-09-13 16:28:28 +0200124 SECTION("example:twoKeyList[number=4][name='abcd']")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200125 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200126 input = "cd example:twoKeyList[number=4][name='abcd']";
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100127 auto keys = ListInstance{
Václav Kubernát7707cae2020-01-16 12:04:53 +0100128 {"number", int32_t{4}},
129 {"name", std::string{"abcd"}}};
Václav Kubernátfaacd022020-07-08 16:44:38 +0200130 expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("twoKeyList", keys));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200131 }
Václav Kubernát0af72572020-07-22 15:15:59 +0200132
133 SECTION("enum key type")
134 {
135 input = "cd example:ports[name=A]";
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100136 auto keys = ListInstance{
Václav Kubernát0af72572020-07-22 15:15:59 +0200137 {"name", enum_{"A"}}};
138 expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("ports", keys));
139 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100140 }
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200141
142 SECTION("whitespace handling")
143 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200144 SECTION(" cd example:a ")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200145 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200146 input = " cd example:a ";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200147 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200148 }
149 }
150
Václav Kubernát60d6f292018-05-25 09:45:32 +0200151 SECTION("moving up")
152 {
Václav Kubernátc2bfe492020-06-15 13:19:07 +0200153 SECTION("moving up when already in root")
154 {
155 input = "cd ..";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200156 expected.m_path.m_nodes.emplace_back(nodeup_());
Václav Kubernátc2bfe492020-06-15 13:19:07 +0200157 }
158
159 SECTION("moving up TWICE when already in root")
160 {
161 input = "cd ../..";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200162 expected.m_path.m_nodes.emplace_back(nodeup_());
163 expected.m_path.m_nodes.emplace_back(nodeup_());
Václav Kubernátc2bfe492020-06-15 13:19:07 +0200164 }
165
Václav Kubernát744f57f2018-06-29 22:46:26 +0200166 SECTION("example:a/..")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200167 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200168 input = "cd example:a/..";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200169 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
170 expected.m_path.m_nodes.emplace_back(nodeup_());
Václav Kubernát60d6f292018-05-25 09:45:32 +0200171 }
172
Václav Kubernát744f57f2018-06-29 22:46:26 +0200173 SECTION("example:a/../example:a")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200174 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200175 input = "cd example:a/../example:a";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200176 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
177 expected.m_path.m_nodes.emplace_back(nodeup_());
178 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
Václav Kubernát60d6f292018-05-25 09:45:32 +0200179 }
180
Václav Kubernát744f57f2018-06-29 22:46:26 +0200181 SECTION("example:a/../example:a/a2")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200182 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200183 input = "cd example:a/../example:a/a2";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200184 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
185 expected.m_path.m_nodes.emplace_back(nodeup_());
186 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
187 expected.m_path.m_nodes.emplace_back(container_("a2"));
Václav Kubernát60d6f292018-05-25 09:45:32 +0200188 }
189 }
190
Václav Kubernátb61336d2018-05-28 17:35:03 +0200191 command_ command = parser.parseCommand(input, errorStream);
192 REQUIRE(command.type() == typeid(cd_));
193 REQUIRE(boost::get<cd_>(command) == expected);
Václav Kubernátd6662962018-03-22 17:41:33 +0100194 }
Václav Kubernátb96eef72018-05-04 19:10:22 +0200195 SECTION("invalid input")
Václav Kubernátd6662962018-03-22 17:41:33 +0100196 {
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200197 SECTION("missing space between a command and its arguments")
198 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200199 SECTION("cdexample:a")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200200 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200201 input = "cdexample:a";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200202 }
203 }
Václav Kubernát744f57f2018-06-29 22:46:26 +0200204
205 SECTION("whitespace between module and nodename")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200206 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200207 SECTION("cd example: a")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200208 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200209 input = "cd example: a";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200210 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100211
Václav Kubernát744f57f2018-06-29 22:46:26 +0200212 SECTION("cd example : a")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200213 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200214 input = "cd example : a";
215 }
216
217 SECTION("cd example :a")
218 {
219 input = "cd example :a";
220 }
221 }
222
223 SECTION("entering modules")
224 {
225 SECTION("cd example")
226 {
227 input = "cd example";
228 }
229
230 SECTION("cd example:")
231 {
232 input = "cd example:";
233 }
234 }
235
236 SECTION("garbage arguments handling")
237 {
238 SECTION("cd example:a garbage")
239 {
240 input = "cd example:a garbage";
241 }
242 SECTION("cd example:a/a2 garbage")
243 {
244 input = "cd example:a/a2 garbage";
245 }
246 }
247
248 SECTION("invalid node identifiers")
249 {
250 SECTION("example:nonexistent")
251 {
252 input = "cd example:nonexistent";
253 }
254
255 SECTION("example:nonexistent/lol")
256 {
257 input = "cd example:nonexistent/lol";
258 }
259 }
260
261 SECTION("invalid module identifiers")
262 {
263 SECTION("elpmaxe:nonexistent")
264 {
265 input = "cd elpmaxe:nonexistent";
266 }
267
268 SECTION("elpmaxe:nonexistent/example:lol")
269 {
270 input = "cd elpmaxe:nonexistent/example:lol";
271 }
272 }
273
274 SECTION("no top-level module")
275 {
276 SECTION("cd a")
277 {
278 input = "cd a";
279 }
280
281 SECTION("cd example:a/../a")
282 {
283 input = "cd example:a/../a";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200284 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100285 }
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200286
Václav Kubernátb96eef72018-05-04 19:10:22 +0200287 SECTION("invalid list key identifiers")
288 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200289 SECTION("example:list")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200290 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200291 input = "cd example:list";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200292 }
293
Václav Kubernát744f57f2018-06-29 22:46:26 +0200294 SECTION("example:list[]")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200295 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200296 input = "cd example:list[]";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200297 }
298
Václav Kubernát89728d82018-09-13 16:28:28 +0200299 SECTION("example:twoKeyList[invalidKey='4']")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200300 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200301 input = "cd example:twoKeyList[invalidKey='4']";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200302 }
303
Václav Kubernát89728d82018-09-13 16:28:28 +0200304 SECTION("example:twoKeyList[number=4][number=5]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200305 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200306 input = "cd example:twoKeyList[number=4][number=5]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200307 }
308
Václav Kubernát89728d82018-09-13 16:28:28 +0200309 SECTION("example:twoKeyList[number=4][name='lol'][number=7]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200310 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200311 input = "cd example:twoKeyList[number=4][name='lol'][number=7]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200312 }
313
Václav Kubernát744f57f2018-06-29 22:46:26 +0200314 SECTION("example:twoKeyList[number=4]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200315 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200316 input = "cd example:twoKeyList[number=4]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200317 }
Václav Kubernát89728d82018-09-13 16:28:28 +0200318
319 SECTION("strings must be quoted")
320 {
321 input = "cd example:twoKeyList[number=4][name=abcd]";
322 }
Václav Kubernátb96eef72018-05-04 19:10:22 +0200323 }
Václav Kubernát9fa5dca2020-06-01 03:56:41 +0200324
325 SECTION("no space between list prefix and suffix")
326 {
327 input = "cd example:list [number=10]";
328 }
329
Václav Kubernáte7248b22020-06-26 15:38:59 +0200330 SECTION("cd into rpc")
331 {
332 input = "cd example:launch-nukes";
333 }
334
Václav Kubernát0d47e5e2020-11-17 12:27:05 +0100335 SECTION("cd into a leaf")
336 {
337 input = "cd example:myLeaf";
338 }
339
Jan Kundrátc381e632019-03-14 13:39:11 +0100340 REQUIRE_THROWS_AS(parser.parseCommand(input, errorStream), InvalidCommandException);
Václav Kubernátd6662962018-03-22 17:41:33 +0100341 }
342}