blob: 307f287620745075a5b096417b802c4cca7fa1f1 [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át48fc3832018-05-28 14:21:22 +020011#include "parser.hpp"
Václav Kubernátbddbb172018-06-13 16:27:39 +020012#include "static_schema.hpp"
Václav Kubernátd6662962018-03-22 17:41:33 +010013
14TEST_CASE("cd")
15{
Václav Kubernátbddbb172018-06-13 16:27:39 +020016 auto schema = std::make_shared<StaticSchema>();
Václav Kubernát744f57f2018-06-29 22:46:26 +020017 schema->addModule("example");
18 schema->addModule("second");
Václav Kubernátefcac932020-01-10 15:26:32 +010019 schema->addContainer("/", "example:a");
20 schema->addContainer("/", "second:a");
21 schema->addContainer("/", "example:b");
22 schema->addContainer("/example:a", "example:a2");
23 schema->addContainer("/example:b", "example:b2");
24 schema->addContainer("/example:a/example:a2", "example:a3");
25 schema->addContainer("/example:b/example:b2", "example:b3");
26 schema->addList("/", "example:list", {"number"});
Václav Kubernát3a99f002020-03-31 02:27:41 +020027 schema->addLeaf("/example:list", "example:number", yang::Int32{});
Václav Kubernátefcac932020-01-10 15:26:32 +010028 schema->addContainer("/example:list", "example:contInList");
29 schema->addList("/", "example:twoKeyList", {"number", "name"});
Václav Kubernát3a99f002020-03-31 02:27:41 +020030 schema->addLeaf("/example:twoKeyList", "example:number", yang::Int32{});
31 schema->addLeaf("/example:twoKeyList", "example:name", yang::String{});
Václav Kubernáte7248b22020-06-26 15:38:59 +020032 schema->addRpc("/", "example:launch-nukes");
Václav Kubernát48fc3832018-05-28 14:21:22 +020033 Parser parser(schema);
Václav Kubernátd6662962018-03-22 17:41:33 +010034 std::string input;
Václav Kubernát2315c732018-05-16 20:25:55 +020035 std::ostringstream errorStream;
Václav Kubernátd6662962018-03-22 17:41:33 +010036
Václav Kubernát744f57f2018-06-29 22:46:26 +020037
Václav Kubernátb96eef72018-05-04 19:10:22 +020038 SECTION("valid input")
Václav Kubernátd6662962018-03-22 17:41:33 +010039 {
Václav Kubernátb96eef72018-05-04 19:10:22 +020040 cd_ expected;
41
42 SECTION("container")
Václav Kubernátd6662962018-03-22 17:41:33 +010043 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020044 SECTION("example:a")
Václav Kubernátb96eef72018-05-04 19:10:22 +020045 {
Václav Kubernátd6fd2492018-11-19 15:11:16 +010046 SECTION("trailing slash")
47 {
48 input = "cd example:a/";
49 expected.m_path.m_trailingSlash = TrailingSlash::Present;
50 }
51 SECTION("no trailing slash")
52 {
53 input = "cd example:a";
54 }
Václav Kubernátfaacd022020-07-08 16:44:38 +020055 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
Václav Kubernátb96eef72018-05-04 19:10:22 +020056 }
57
Václav Kubernát744f57f2018-06-29 22:46:26 +020058 SECTION("second:a")
Václav Kubernátb96eef72018-05-04 19:10:22 +020059 {
Václav Kubernátd6fd2492018-11-19 15:11:16 +010060 SECTION("trailing slash")
61 {
62 input = "cd second:a/";
63 expected.m_path.m_trailingSlash = TrailingSlash::Present;
64 }
65 SECTION("no trailing slash")
66 {
67 input = "cd second:a";
68 }
Václav Kubernátfaacd022020-07-08 16:44:38 +020069 expected.m_path.m_nodes.emplace_back(module_{"second"}, container_("a"));
Václav Kubernátb96eef72018-05-04 19:10:22 +020070 }
71
Václav Kubernát744f57f2018-06-29 22:46:26 +020072 SECTION("example:b")
Václav Kubernátb96eef72018-05-04 19:10:22 +020073 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020074 input = "cd example:b";
Václav Kubernátfaacd022020-07-08 16:44:38 +020075 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("b"));
Václav Kubernátb96eef72018-05-04 19:10:22 +020076 }
77
Václav Kubernát744f57f2018-06-29 22:46:26 +020078 SECTION("example:a/a2")
Václav Kubernátb96eef72018-05-04 19:10:22 +020079 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020080 input = "cd example:a/a2";
Václav Kubernátfaacd022020-07-08 16:44:38 +020081 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
82 expected.m_path.m_nodes.emplace_back(container_("a2"));
Václav Kubernát744f57f2018-06-29 22:46:26 +020083 }
84
85 SECTION("example:a/example:a2")
86 {
87 input = "cd example:a/example:a2";
Václav Kubernátfaacd022020-07-08 16:44:38 +020088 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
89 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a2"));
Václav Kubernát744f57f2018-06-29 22:46:26 +020090 }
91
92 SECTION("example:b/b2")
93 {
94 input = "cd example:b/b2";
Václav Kubernátfaacd022020-07-08 16:44:38 +020095 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("b"));
96 expected.m_path.m_nodes.emplace_back(container_("b2"));
Václav Kubernátb96eef72018-05-04 19:10:22 +020097 }
Václav Kubernátd6662962018-03-22 17:41:33 +010098 }
99
Václav Kubernátb96eef72018-05-04 19:10:22 +0200100 SECTION("list elements")
Václav Kubernátd6662962018-03-22 17:41:33 +0100101 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200102 SECTION("example:list[number=1]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200103 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200104 input = "cd example:list[number=1]";
Václav Kubernátc15fe822020-06-04 11:28:39 +0200105 auto keys = ListInstance {
Václav Kubernát7707cae2020-01-16 12:04:53 +0100106 {"number", int32_t{1}}};
Václav Kubernátfaacd022020-07-08 16:44:38 +0200107 expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("list", keys));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200108 }
109
Václav Kubernát744f57f2018-06-29 22:46:26 +0200110 SECTION("example:list[number=1]/contInList")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200111 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200112 input = "cd example:list[number=1]/contInList";
Václav Kubernátc15fe822020-06-04 11:28:39 +0200113 auto keys = ListInstance {
Václav Kubernát7707cae2020-01-16 12:04:53 +0100114 {"number", int32_t{1}}};
Václav Kubernátfaacd022020-07-08 16:44:38 +0200115 expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("list", keys));
116 expected.m_path.m_nodes.emplace_back(container_("contInList"));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200117 }
118
Václav Kubernát89728d82018-09-13 16:28:28 +0200119 SECTION("example:twoKeyList[number=4][name='abcd']")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200120 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200121 input = "cd example:twoKeyList[number=4][name='abcd']";
Václav Kubernátc15fe822020-06-04 11:28:39 +0200122 auto keys = ListInstance {
Václav Kubernát7707cae2020-01-16 12:04:53 +0100123 {"number", int32_t{4}},
124 {"name", std::string{"abcd"}}};
Václav Kubernátfaacd022020-07-08 16:44:38 +0200125 expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("twoKeyList", keys));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200126 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100127 }
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200128
129 SECTION("whitespace handling")
130 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200131 SECTION(" cd example:a ")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200132 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200133 input = " cd example:a ";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200134 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200135 }
136 }
137
Václav Kubernát60d6f292018-05-25 09:45:32 +0200138 SECTION("moving up")
139 {
Václav Kubernátc2bfe492020-06-15 13:19:07 +0200140 SECTION("moving up when already in root")
141 {
142 input = "cd ..";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200143 expected.m_path.m_nodes.emplace_back(nodeup_());
Václav Kubernátc2bfe492020-06-15 13:19:07 +0200144 }
145
146 SECTION("moving up TWICE when already in root")
147 {
148 input = "cd ../..";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200149 expected.m_path.m_nodes.emplace_back(nodeup_());
150 expected.m_path.m_nodes.emplace_back(nodeup_());
Václav Kubernátc2bfe492020-06-15 13:19:07 +0200151 }
152
Václav Kubernát744f57f2018-06-29 22:46:26 +0200153 SECTION("example:a/..")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200154 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200155 input = "cd example:a/..";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200156 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
157 expected.m_path.m_nodes.emplace_back(nodeup_());
Václav Kubernát60d6f292018-05-25 09:45:32 +0200158 }
159
Václav Kubernát744f57f2018-06-29 22:46:26 +0200160 SECTION("example:a/../example:a")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200161 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200162 input = "cd example:a/../example:a";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200163 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
164 expected.m_path.m_nodes.emplace_back(nodeup_());
165 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
Václav Kubernát60d6f292018-05-25 09:45:32 +0200166 }
167
Václav Kubernát744f57f2018-06-29 22:46:26 +0200168 SECTION("example:a/../example:a/a2")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200169 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200170 input = "cd example:a/../example:a/a2";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200171 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
172 expected.m_path.m_nodes.emplace_back(nodeup_());
173 expected.m_path.m_nodes.emplace_back(module_{"example"}, container_("a"));
174 expected.m_path.m_nodes.emplace_back(container_("a2"));
Václav Kubernát60d6f292018-05-25 09:45:32 +0200175 }
176 }
177
Václav Kubernátb61336d2018-05-28 17:35:03 +0200178 command_ command = parser.parseCommand(input, errorStream);
179 REQUIRE(command.type() == typeid(cd_));
180 REQUIRE(boost::get<cd_>(command) == expected);
Václav Kubernátd6662962018-03-22 17:41:33 +0100181 }
Václav Kubernátb96eef72018-05-04 19:10:22 +0200182 SECTION("invalid input")
Václav Kubernátd6662962018-03-22 17:41:33 +0100183 {
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200184 SECTION("missing space between a command and its arguments")
185 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200186 SECTION("cdexample:a")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200187 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200188 input = "cdexample:a";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200189 }
190 }
Václav Kubernát744f57f2018-06-29 22:46:26 +0200191
192 SECTION("whitespace between module and nodename")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200193 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200194 SECTION("cd example: a")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200195 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200196 input = "cd example: a";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200197 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100198
Václav Kubernát744f57f2018-06-29 22:46:26 +0200199 SECTION("cd example : a")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200200 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200201 input = "cd example : a";
202 }
203
204 SECTION("cd example :a")
205 {
206 input = "cd example :a";
207 }
208 }
209
210 SECTION("entering modules")
211 {
212 SECTION("cd example")
213 {
214 input = "cd example";
215 }
216
217 SECTION("cd example:")
218 {
219 input = "cd example:";
220 }
221 }
222
223 SECTION("garbage arguments handling")
224 {
225 SECTION("cd example:a garbage")
226 {
227 input = "cd example:a garbage";
228 }
229 SECTION("cd example:a/a2 garbage")
230 {
231 input = "cd example:a/a2 garbage";
232 }
233 }
234
235 SECTION("invalid node identifiers")
236 {
237 SECTION("example:nonexistent")
238 {
239 input = "cd example:nonexistent";
240 }
241
242 SECTION("example:nonexistent/lol")
243 {
244 input = "cd example:nonexistent/lol";
245 }
246 }
247
248 SECTION("invalid module identifiers")
249 {
250 SECTION("elpmaxe:nonexistent")
251 {
252 input = "cd elpmaxe:nonexistent";
253 }
254
255 SECTION("elpmaxe:nonexistent/example:lol")
256 {
257 input = "cd elpmaxe:nonexistent/example:lol";
258 }
259 }
260
261 SECTION("no top-level module")
262 {
263 SECTION("cd a")
264 {
265 input = "cd a";
266 }
267
268 SECTION("cd example:a/../a")
269 {
270 input = "cd example:a/../a";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200271 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100272 }
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200273
Václav Kubernátb96eef72018-05-04 19:10:22 +0200274 SECTION("invalid list key identifiers")
275 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200276 SECTION("example:list")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200277 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200278 input = "cd example:list";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200279 }
280
Václav Kubernát744f57f2018-06-29 22:46:26 +0200281 SECTION("example:list[]")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200282 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200283 input = "cd example:list[]";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200284 }
285
Václav Kubernát89728d82018-09-13 16:28:28 +0200286 SECTION("example:twoKeyList[invalidKey='4']")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200287 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200288 input = "cd example:twoKeyList[invalidKey='4']";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200289 }
290
Václav Kubernát89728d82018-09-13 16:28:28 +0200291 SECTION("example:twoKeyList[number=4][number=5]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200292 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200293 input = "cd example:twoKeyList[number=4][number=5]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200294 }
295
Václav Kubernát89728d82018-09-13 16:28:28 +0200296 SECTION("example:twoKeyList[number=4][name='lol'][number=7]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200297 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200298 input = "cd example:twoKeyList[number=4][name='lol'][number=7]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200299 }
300
Václav Kubernát744f57f2018-06-29 22:46:26 +0200301 SECTION("example:twoKeyList[number=4]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200302 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200303 input = "cd example:twoKeyList[number=4]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200304 }
Václav Kubernát89728d82018-09-13 16:28:28 +0200305
306 SECTION("strings must be quoted")
307 {
308 input = "cd example:twoKeyList[number=4][name=abcd]";
309 }
Václav Kubernátb96eef72018-05-04 19:10:22 +0200310 }
Václav Kubernát9fa5dca2020-06-01 03:56:41 +0200311
312 SECTION("no space between list prefix and suffix")
313 {
314 input = "cd example:list [number=10]";
315 }
316
Václav Kubernáte7248b22020-06-26 15:38:59 +0200317 SECTION("cd into rpc")
318 {
319 input = "cd example:launch-nukes";
320 }
321
Jan Kundrátc381e632019-03-14 13:39:11 +0100322 REQUIRE_THROWS_AS(parser.parseCommand(input, errorStream), InvalidCommandException);
Václav Kubernátd6662962018-03-22 17:41:33 +0100323 }
324}