blob: 1d03e78a808f72335bbbfa62027240e64164b34a [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
Jan Kundráta33cf082019-03-28 11:55:57 +01009#include "trompeloeil_doctest.h"
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"});
27 schema->addContainer("/example:list", "example:contInList");
28 schema->addList("/", "example:twoKeyList", {"number", "name"});
Václav Kubernát48fc3832018-05-28 14:21:22 +020029 Parser parser(schema);
Václav Kubernátd6662962018-03-22 17:41:33 +010030 std::string input;
Václav Kubernát2315c732018-05-16 20:25:55 +020031 std::ostringstream errorStream;
Václav Kubernátd6662962018-03-22 17:41:33 +010032
Václav Kubernát744f57f2018-06-29 22:46:26 +020033
Václav Kubernátb96eef72018-05-04 19:10:22 +020034 SECTION("valid input")
Václav Kubernátd6662962018-03-22 17:41:33 +010035 {
Václav Kubernátb96eef72018-05-04 19:10:22 +020036 cd_ expected;
37
38 SECTION("container")
Václav Kubernátd6662962018-03-22 17:41:33 +010039 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020040 SECTION("example:a")
Václav Kubernátb96eef72018-05-04 19:10:22 +020041 {
Václav Kubernátd6fd2492018-11-19 15:11:16 +010042 SECTION("trailing slash")
43 {
44 input = "cd example:a/";
45 expected.m_path.m_trailingSlash = TrailingSlash::Present;
46 }
47 SECTION("no trailing slash")
48 {
49 input = "cd example:a";
50 }
Václav Kubernát2eaceb82018-10-08 19:56:30 +020051 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
Václav Kubernátb96eef72018-05-04 19:10:22 +020052 }
53
Václav Kubernát744f57f2018-06-29 22:46:26 +020054 SECTION("second:a")
Václav Kubernátb96eef72018-05-04 19:10:22 +020055 {
Václav Kubernátd6fd2492018-11-19 15:11:16 +010056 SECTION("trailing slash")
57 {
58 input = "cd second:a/";
59 expected.m_path.m_trailingSlash = TrailingSlash::Present;
60 }
61 SECTION("no trailing slash")
62 {
63 input = "cd second:a";
64 }
Václav Kubernát2eaceb82018-10-08 19:56:30 +020065 expected.m_path.m_nodes.push_back(dataNode_(module_{"second"}, container_("a")));
Václav Kubernátb96eef72018-05-04 19:10:22 +020066 }
67
Václav Kubernát744f57f2018-06-29 22:46:26 +020068 SECTION("example:b")
Václav Kubernátb96eef72018-05-04 19:10:22 +020069 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020070 input = "cd example:b";
Václav Kubernát2eaceb82018-10-08 19:56:30 +020071 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("b")));
Václav Kubernátb96eef72018-05-04 19:10:22 +020072 }
73
Václav Kubernát744f57f2018-06-29 22:46:26 +020074 SECTION("example:a/a2")
Václav Kubernátb96eef72018-05-04 19:10:22 +020075 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020076 input = "cd example:a/a2";
Václav Kubernát2eaceb82018-10-08 19:56:30 +020077 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
78 expected.m_path.m_nodes.push_back(dataNode_(container_("a2")));
Václav Kubernát744f57f2018-06-29 22:46:26 +020079 }
80
81 SECTION("example:a/example:a2")
82 {
83 input = "cd example:a/example:a2";
Václav Kubernát2eaceb82018-10-08 19:56:30 +020084 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
85 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a2")));
Václav Kubernát744f57f2018-06-29 22:46:26 +020086 }
87
88 SECTION("example:b/b2")
89 {
90 input = "cd example:b/b2";
Václav Kubernát2eaceb82018-10-08 19:56:30 +020091 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("b")));
92 expected.m_path.m_nodes.push_back(dataNode_(container_("b2")));
Václav Kubernátb96eef72018-05-04 19:10:22 +020093 }
Václav Kubernátd6662962018-03-22 17:41:33 +010094 }
95
Václav Kubernátb96eef72018-05-04 19:10:22 +020096 SECTION("list elements")
Václav Kubernátd6662962018-03-22 17:41:33 +010097 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020098 SECTION("example:list[number=1]")
Václav Kubernátb96eef72018-05-04 19:10:22 +020099 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200100 input = "cd example:list[number=1]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200101 auto keys = std::map<std::string, std::string>{
Václav Kubernát48fc3832018-05-28 14:21:22 +0200102 {"number", "1"}};
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200103 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, listElement_("list", keys)));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200104 }
105
Václav Kubernát744f57f2018-06-29 22:46:26 +0200106 SECTION("example:list[number=1]/contInList")
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]/contInList";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200109 auto keys = std::map<std::string, std::string>{
Václav Kubernát48fc3832018-05-28 14:21:22 +0200110 {"number", "1"}};
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200111 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, listElement_("list", keys)));
112 expected.m_path.m_nodes.push_back(dataNode_(container_("contInList")));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200113 }
114
Václav Kubernát89728d82018-09-13 16:28:28 +0200115 SECTION("example:twoKeyList[number=4][name='abcd']")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200116 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200117 input = "cd example:twoKeyList[number=4][name='abcd']";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200118 auto keys = std::map<std::string, std::string>{
Václav Kubernát48fc3832018-05-28 14:21:22 +0200119 {"number", "4"},
120 {"name", "abcd"}};
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200121 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, listElement_("twoKeyList", keys)));
Václav Kubernátb96eef72018-05-04 19:10:22 +0200122 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100123 }
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200124
125 SECTION("whitespace handling")
126 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200127 SECTION(" cd example:a ")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200128 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200129 input = " cd example:a ";
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200130 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200131 }
132 }
133
Václav Kubernát60d6f292018-05-25 09:45:32 +0200134 SECTION("moving up")
135 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200136 SECTION("example:a/..")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200137 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200138 input = "cd example:a/..";
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200139 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
140 expected.m_path.m_nodes.push_back(dataNode_(nodeup_()));
Václav Kubernát60d6f292018-05-25 09:45:32 +0200141 }
142
Václav Kubernát744f57f2018-06-29 22:46:26 +0200143 SECTION("example:a/../example:a")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200144 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200145 input = "cd example:a/../example:a";
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200146 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
147 expected.m_path.m_nodes.push_back(dataNode_(nodeup_()));
148 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
Václav Kubernát60d6f292018-05-25 09:45:32 +0200149 }
150
Václav Kubernát744f57f2018-06-29 22:46:26 +0200151 SECTION("example:a/../example:a/a2")
Václav Kubernát60d6f292018-05-25 09:45:32 +0200152 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200153 input = "cd example:a/../example:a/a2";
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200154 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
155 expected.m_path.m_nodes.push_back(dataNode_(nodeup_()));
156 expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
157 expected.m_path.m_nodes.push_back(dataNode_(container_("a2")));
Václav Kubernát60d6f292018-05-25 09:45:32 +0200158 }
159 }
160
Václav Kubernátb61336d2018-05-28 17:35:03 +0200161 command_ command = parser.parseCommand(input, errorStream);
162 REQUIRE(command.type() == typeid(cd_));
163 REQUIRE(boost::get<cd_>(command) == expected);
Václav Kubernátd6662962018-03-22 17:41:33 +0100164 }
Václav Kubernátb96eef72018-05-04 19:10:22 +0200165 SECTION("invalid input")
Václav Kubernátd6662962018-03-22 17:41:33 +0100166 {
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200167 SECTION("missing space between a command and its arguments")
168 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200169 SECTION("cdexample:a")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200170 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200171 input = "cdexample:a";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200172 }
173 }
Václav Kubernát744f57f2018-06-29 22:46:26 +0200174
175 SECTION("whitespace between module and nodename")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200176 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200177 SECTION("cd example: a")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200178 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200179 input = "cd example: a";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200180 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100181
Václav Kubernát744f57f2018-06-29 22:46:26 +0200182 SECTION("cd example : a")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200183 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200184 input = "cd example : a";
185 }
186
187 SECTION("cd example :a")
188 {
189 input = "cd example :a";
190 }
191 }
192
193 SECTION("entering modules")
194 {
195 SECTION("cd example")
196 {
197 input = "cd example";
198 }
199
200 SECTION("cd example:")
201 {
202 input = "cd example:";
203 }
204 }
205
206 SECTION("garbage arguments handling")
207 {
208 SECTION("cd example:a garbage")
209 {
210 input = "cd example:a garbage";
211 }
212 SECTION("cd example:a/a2 garbage")
213 {
214 input = "cd example:a/a2 garbage";
215 }
216 }
217
218 SECTION("invalid node identifiers")
219 {
220 SECTION("example:nonexistent")
221 {
222 input = "cd example:nonexistent";
223 }
224
225 SECTION("example:nonexistent/lol")
226 {
227 input = "cd example:nonexistent/lol";
228 }
229 }
230
231 SECTION("invalid module identifiers")
232 {
233 SECTION("elpmaxe:nonexistent")
234 {
235 input = "cd elpmaxe:nonexistent";
236 }
237
238 SECTION("elpmaxe:nonexistent/example:lol")
239 {
240 input = "cd elpmaxe:nonexistent/example:lol";
241 }
242 }
243
244 SECTION("no top-level module")
245 {
246 SECTION("cd a")
247 {
248 input = "cd a";
249 }
250
251 SECTION("cd example:a/../a")
252 {
253 input = "cd example:a/../a";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200254 }
Václav Kubernátd6662962018-03-22 17:41:33 +0100255 }
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200256
Václav Kubernátb96eef72018-05-04 19:10:22 +0200257 SECTION("invalid list key identifiers")
258 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200259 SECTION("example:list")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200260 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200261 input = "cd example:list";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200262 }
263
Václav Kubernát744f57f2018-06-29 22:46:26 +0200264 SECTION("example:list[]")
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200265 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200266 input = "cd example:list[]";
Václav Kubernát7e4e82f2018-05-14 20:04:58 +0200267 }
268
Václav Kubernát89728d82018-09-13 16:28:28 +0200269 SECTION("example:twoKeyList[invalidKey='4']")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200270 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200271 input = "cd example:twoKeyList[invalidKey='4']";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200272 }
273
Václav Kubernát89728d82018-09-13 16:28:28 +0200274 SECTION("example:twoKeyList[number=4][number=5]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200275 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200276 input = "cd example:twoKeyList[number=4][number=5]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200277 }
278
Václav Kubernát89728d82018-09-13 16:28:28 +0200279 SECTION("example:twoKeyList[number=4][name='lol'][number=7]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200280 {
Václav Kubernát89728d82018-09-13 16:28:28 +0200281 input = "cd example:twoKeyList[number=4][name='lol'][number=7]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200282 }
283
Václav Kubernát744f57f2018-06-29 22:46:26 +0200284 SECTION("example:twoKeyList[number=4]")
Václav Kubernátb96eef72018-05-04 19:10:22 +0200285 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200286 input = "cd example:twoKeyList[number=4]";
Václav Kubernátb96eef72018-05-04 19:10:22 +0200287 }
Václav Kubernát89728d82018-09-13 16:28:28 +0200288
289 SECTION("strings must be quoted")
290 {
291 input = "cd example:twoKeyList[number=4][name=abcd]";
292 }
Václav Kubernátb96eef72018-05-04 19:10:22 +0200293 }
Jan Kundrátc381e632019-03-14 13:39:11 +0100294 REQUIRE_THROWS_AS(parser.parseCommand(input, errorStream), InvalidCommandException);
Václav Kubernátd6662962018-03-22 17:41:33 +0100295 }
296}