blob: e0d62937af593fbb4b18af8d427e30621df029a0 [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át48fc3832018-05-28 14:21:22 +020032 Parser parser(schema);
Václav Kubernátd6662962018-03-22 17:41:33 +010033 std::string input;
Václav Kubernát2315c732018-05-16 20:25:55 +020034 std::ostringstream errorStream;
Václav Kubernátd6662962018-03-22 17:41:33 +010035
Václav Kubernát744f57f2018-06-29 22:46:26 +020036
Václav Kubernátb96eef72018-05-04 19:10:22 +020037 SECTION("valid input")
Václav Kubernátd6662962018-03-22 17:41:33 +010038 {
Václav Kubernátb96eef72018-05-04 19:10:22 +020039 cd_ expected;
40
41 SECTION("container")
Václav Kubernátd6662962018-03-22 17:41:33 +010042 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020043 SECTION("example:a")
Václav Kubernátb96eef72018-05-04 19:10:22 +020044 {
Václav Kubernátd6fd2492018-11-19 15:11:16 +010045 SECTION("trailing slash")
46 {
47 input = "cd example:a/";
48 expected.m_path.m_trailingSlash = TrailingSlash::Present;
49 }
50 SECTION("no trailing slash")
51 {
52 input = "cd example:a";
53 }
Václav Kubernát2eaceb82018-10-08 19:56:30 +020054 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
Václav Kubernátb96eef72018-05-04 19:10:22 +020055 }
56
Václav Kubernát744f57f2018-06-29 22:46:26 +020057 SECTION("second:a")
Václav Kubernátb96eef72018-05-04 19:10:22 +020058 {
Václav Kubernátd6fd2492018-11-19 15:11:16 +010059 SECTION("trailing slash")
60 {
61 input = "cd second:a/";
62 expected.m_path.m_trailingSlash = TrailingSlash::Present;
63 }
64 SECTION("no trailing slash")
65 {
66 input = "cd second:a";
67 }
Václav Kubernát2eaceb82018-10-08 19:56:30 +020068 expected.m_path.m_nodes.push_back(dataNode_(module_{"second"}, container_("a")));
Václav Kubernátb96eef72018-05-04 19:10:22 +020069 }
70
Václav Kubernát744f57f2018-06-29 22:46:26 +020071 SECTION("example:b")
Václav Kubernátb96eef72018-05-04 19:10:22 +020072 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020073 input = "cd example:b";
Václav Kubernát2eaceb82018-10-08 19:56:30 +020074 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("b")));
Václav Kubernátb96eef72018-05-04 19:10:22 +020075 }
76
Václav Kubernát744f57f2018-06-29 22:46:26 +020077 SECTION("example:a/a2")
Václav Kubernátb96eef72018-05-04 19:10:22 +020078 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020079 input = "cd example:a/a2";
Václav Kubernát2eaceb82018-10-08 19:56:30 +020080 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
81 expected.m_path.m_nodes.push_back(dataNode_(container_("a2")));
Václav Kubernát744f57f2018-06-29 22:46:26 +020082 }
83
84 SECTION("example:a/example:a2")
85 {
86 input = "cd example:a/example:a2";
Václav Kubernát2eaceb82018-10-08 19:56:30 +020087 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
88 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a2")));
Václav Kubernát744f57f2018-06-29 22:46:26 +020089 }
90
91 SECTION("example:b/b2")
92 {
93 input = "cd example:b/b2";
Václav Kubernát2eaceb82018-10-08 19:56:30 +020094 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("b")));
95 expected.m_path.m_nodes.push_back(dataNode_(container_("b2")));
Václav Kubernátb96eef72018-05-04 19:10:22 +020096 }
Václav Kubernátd6662962018-03-22 17:41:33 +010097 }
98
Václav Kubernátb96eef72018-05-04 19:10:22 +020099 SECTION("list elements")
Václav Kubernátd6662962018-03-22 17:41:33 +0100100 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200101 SECTION("example:list[number=1]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200102 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200103 input = "cd example:list[number=1]";
Václav Kubernátc15fe822020-06-04 11:28:39 +0200104 auto keys = ListInstance {
Václav Kubernát7707cae2020-01-16 12:04:53 +0100105 {"number", int32_t{1}}};
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200106 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, listElement_("list", keys)));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200107 }
108
Václav Kubernát744f57f2018-06-29 22:46:26 +0200109 SECTION("example:list[number=1]/contInList")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200110 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200111 input = "cd example:list[number=1]/contInList";
Václav Kubernátc15fe822020-06-04 11:28:39 +0200112 auto keys = ListInstance {
Václav Kubernát7707cae2020-01-16 12:04:53 +0100113 {"number", int32_t{1}}};
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200114 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, listElement_("list", keys)));
115 expected.m_path.m_nodes.push_back(dataNode_(container_("contInList")));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200116 }
117
Václav Kubernát89728d82018-09-13 16:28:28 +0200118 SECTION("example:twoKeyList[number=4][name='abcd']")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200119 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200120 input = "cd example:twoKeyList[number=4][name='abcd']";
Václav Kubernátc15fe822020-06-04 11:28:39 +0200121 auto keys = ListInstance {
Václav Kubernát7707cae2020-01-16 12:04:53 +0100122 {"number", int32_t{4}},
123 {"name", std::string{"abcd"}}};
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200124 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, listElement_("twoKeyList", keys)));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200125 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100126 }
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200127
128 SECTION("whitespace handling")
129 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200130 SECTION(" cd example:a ")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200131 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200132 input = " cd example:a ";
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200133 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200134 }
135 }
136
Václav Kubernát60d6f292018-05-25 09:45:32 +0200137 SECTION("moving up")
138 {
Václav Kubernátc2bfe492020-06-15 13:19:07 +0200139 SECTION("moving up when already in root")
140 {
141 input = "cd ..";
142 expected.m_path.m_nodes.push_back(dataNode_(nodeup_()));
143 }
144
145 SECTION("moving up TWICE when already in root")
146 {
147 input = "cd ../..";
148 expected.m_path.m_nodes.push_back(dataNode_(nodeup_()));
149 expected.m_path.m_nodes.push_back(dataNode_(nodeup_()));
150 }
151
Václav Kubernát744f57f2018-06-29 22:46:26 +0200152 SECTION("example:a/..")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200153 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200154 input = "cd example:a/..";
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200155 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
156 expected.m_path.m_nodes.push_back(dataNode_(nodeup_()));
Václav Kubernát60d6f292018-05-25 09:45:32 +0200157 }
158
Václav Kubernát744f57f2018-06-29 22:46:26 +0200159 SECTION("example:a/../example:a")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200160 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200161 input = "cd example:a/../example:a";
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200162 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
163 expected.m_path.m_nodes.push_back(dataNode_(nodeup_()));
164 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
Václav Kubernát60d6f292018-05-25 09:45:32 +0200165 }
166
Václav Kubernát744f57f2018-06-29 22:46:26 +0200167 SECTION("example:a/../example:a/a2")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200168 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200169 input = "cd example:a/../example:a/a2";
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200170 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
171 expected.m_path.m_nodes.push_back(dataNode_(nodeup_()));
172 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
173 expected.m_path.m_nodes.push_back(dataNode_(container_("a2")));
Václav Kubernát60d6f292018-05-25 09:45:32 +0200174 }
175 }
176
Václav Kubernátb61336d2018-05-28 17:35:03 +0200177 command_ command = parser.parseCommand(input, errorStream);
178 REQUIRE(command.type() == typeid(cd_));
179 REQUIRE(boost::get<cd_>(command) == expected);
Václav Kubernátd6662962018-03-22 17:41:33 +0100180 }
Václav Kubernátb96eef72018-05-04 19:10:22 +0200181 SECTION("invalid input")
Václav Kubernátd6662962018-03-22 17:41:33 +0100182 {
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200183 SECTION("missing space between a command and its arguments")
184 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200185 SECTION("cdexample:a")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200186 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200187 input = "cdexample:a";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200188 }
189 }
Václav Kubernát744f57f2018-06-29 22:46:26 +0200190
191 SECTION("whitespace between module and nodename")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200192 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200193 SECTION("cd example: a")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200194 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200195 input = "cd example: a";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200196 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100197
Václav Kubernát744f57f2018-06-29 22:46:26 +0200198 SECTION("cd example : a")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200199 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200200 input = "cd example : a";
201 }
202
203 SECTION("cd example :a")
204 {
205 input = "cd example :a";
206 }
207 }
208
209 SECTION("entering modules")
210 {
211 SECTION("cd example")
212 {
213 input = "cd example";
214 }
215
216 SECTION("cd example:")
217 {
218 input = "cd example:";
219 }
220 }
221
222 SECTION("garbage arguments handling")
223 {
224 SECTION("cd example:a garbage")
225 {
226 input = "cd example:a garbage";
227 }
228 SECTION("cd example:a/a2 garbage")
229 {
230 input = "cd example:a/a2 garbage";
231 }
232 }
233
234 SECTION("invalid node identifiers")
235 {
236 SECTION("example:nonexistent")
237 {
238 input = "cd example:nonexistent";
239 }
240
241 SECTION("example:nonexistent/lol")
242 {
243 input = "cd example:nonexistent/lol";
244 }
245 }
246
247 SECTION("invalid module identifiers")
248 {
249 SECTION("elpmaxe:nonexistent")
250 {
251 input = "cd elpmaxe:nonexistent";
252 }
253
254 SECTION("elpmaxe:nonexistent/example:lol")
255 {
256 input = "cd elpmaxe:nonexistent/example:lol";
257 }
258 }
259
260 SECTION("no top-level module")
261 {
262 SECTION("cd a")
263 {
264 input = "cd a";
265 }
266
267 SECTION("cd example:a/../a")
268 {
269 input = "cd example:a/../a";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200270 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100271 }
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200272
Václav Kubernátb96eef72018-05-04 19:10:22 +0200273 SECTION("invalid list key identifiers")
274 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200275 SECTION("example:list")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200276 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200277 input = "cd example:list";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200278 }
279
Václav Kubernát744f57f2018-06-29 22:46:26 +0200280 SECTION("example:list[]")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200281 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200282 input = "cd example:list[]";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200283 }
284
Václav Kubernát89728d82018-09-13 16:28:28 +0200285 SECTION("example:twoKeyList[invalidKey='4']")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200286 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200287 input = "cd example:twoKeyList[invalidKey='4']";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200288 }
289
Václav Kubernát89728d82018-09-13 16:28:28 +0200290 SECTION("example:twoKeyList[number=4][number=5]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200291 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200292 input = "cd example:twoKeyList[number=4][number=5]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200293 }
294
Václav Kubernát89728d82018-09-13 16:28:28 +0200295 SECTION("example:twoKeyList[number=4][name='lol'][number=7]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200296 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200297 input = "cd example:twoKeyList[number=4][name='lol'][number=7]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200298 }
299
Václav Kubernát744f57f2018-06-29 22:46:26 +0200300 SECTION("example:twoKeyList[number=4]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200301 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200302 input = "cd example:twoKeyList[number=4]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200303 }
Václav Kubernát89728d82018-09-13 16:28:28 +0200304
305 SECTION("strings must be quoted")
306 {
307 input = "cd example:twoKeyList[number=4][name=abcd]";
308 }
Václav Kubernátb96eef72018-05-04 19:10:22 +0200309 }
Václav Kubernát9fa5dca2020-06-01 03:56:41 +0200310
311 SECTION("no space between list prefix and suffix")
312 {
313 input = "cd example:list [number=10]";
314 }
315
Jan Kundrátc381e632019-03-14 13:39:11 +0100316 REQUIRE_THROWS_AS(parser.parseCommand(input, errorStream), InvalidCommandException);
Václav Kubernátd6662962018-03-22 17:41:33 +0100317 }
318}