blob: fb8521038bbcdb915088ecc9eedb4371f2df52cb [file] [log] [blame]
Václav Kubernát4108e0d2018-10-29 13:32:22 +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átcb3af402020-02-12 16:49:17 +010010#include "completion.hpp"
Václav Kubernát2984f442020-02-20 17:43:35 +010011#include "leaf_data_helpers.hpp"
Václav Kubernát2e4cafe2020-11-05 01:53:21 +010012#include "libyang_utils.hpp"
13#include "pretty_printers.hpp"
Václav Kubernát4108e0d2018-10-29 13:32:22 +010014#include "utils.hpp"
15
16TEST_CASE("utils")
17{
Václav Kubernáta395d332019-02-13 16:49:20 +010018 SECTION("filterByPrefix")
Václav Kubernát4108e0d2018-10-29 13:32:22 +010019 {
Václav Kubernátcb3af402020-02-12 16:49:17 +010020 std::set<Completion> set{{"ahoj"}, {"coze"}, {"copak"}, {"aha"}, {"polivka"}};
Václav Kubernát4108e0d2018-10-29 13:32:22 +010021
Václav Kubernátcb3af402020-02-12 16:49:17 +010022 REQUIRE((filterByPrefix(set, "a") == std::set<Completion>{{"ahoj"}, {"aha"}}));
23 REQUIRE((filterByPrefix(set, "ah") == std::set<Completion>{{"ahoj"}, {"aha"}}));
24 REQUIRE((filterByPrefix(set, "aho") == std::set<Completion>{{"ahoj"}}));
25 REQUIRE((filterByPrefix(set, "polivka") == std::set<Completion>{{"polivka"}}));
26 REQUIRE((filterByPrefix(set, "polivkax") == std::set<Completion>{}));
27 REQUIRE((filterByPrefix(set, "co") == std::set<Completion>{{"copak"}, {"coze"}}));
Václav Kubernát4108e0d2018-10-29 13:32:22 +010028 }
Václav Kubernáta44bdf22020-01-24 12:15:31 +010029
30 SECTION("joinPaths") {
31 std::string prefix, suffix, result;
32
33 SECTION("regular") {
34 prefix = "/example:a";
35 suffix = "leaf";
36 result = "/example:a/leaf";
37 }
38
39 SECTION("no prefix - absolute path") {
40 suffix = "/example:a/leaf";
41 result = "/example:a/leaf";
42 }
43
44 SECTION("no prefix - relative path") {
45 suffix = "example:a/leaf";
46 result = "example:a/leaf";
47 }
48
49 SECTION("no suffix") {
50 prefix = "/example:a/leaf";
51 result = "/example:a/leaf";
52 }
53
54 SECTION("at root") {
55 prefix = "/";
56 suffix = "example:a";
57 result = "/example:a";
58 }
59
60 SECTION("trailing slash") {
61 prefix = "/example:a";
62 suffix = "/";
63 result = "/example:a/";
64 }
65
66 SECTION("prefix ends with slash") {
67 prefix = "/example:a/";
68 suffix = "leaf";
69 result = "/example:a/leaf";
70 }
71
72 SECTION("suffix starts with slash") {
73 prefix = "/example:a";
74 suffix = "/leaf";
75 result = "/example:a/leaf";
76 }
77
78 SECTION("slashes all the way to eleven") {
79 prefix = "/example:a/";
80 suffix = "/leaf";
81 result = "/example:a/leaf";
82 }
83
84 REQUIRE(joinPaths(prefix, suffix) == result);
85 }
Václav Kubernát2984f442020-02-20 17:43:35 +010086
87 SECTION("leafDataTypeToString")
88 {
89 yang::LeafDataType type;
90 std::string expected;
91 SECTION("union")
92 {
93 type = yang::Union{{
Václav Kubernát13b23d72020-04-16 21:49:51 +020094 yang::TypeInfo{yang::String{}},
95 yang::TypeInfo{createEnum({"foo", "bar"})},
96 yang::TypeInfo{yang::Int8{}},
97 yang::TypeInfo{yang::Int64{}},
Václav Kubernát2984f442020-02-20 17:43:35 +010098 }};
99 expected = "a string, an enum, an 8-bit integer, a 64-bit integer";
100 }
101
102 REQUIRE(leafDataTypeToString(type) == expected);
103
104 }
105
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100106}
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100107
108const auto schema = R"(
109module test-schema {
110 namespace "http://example.com/ayyyy";
111 prefix AHOJ;
112
113 leaf int8 {
114 type int8;
115 }
116 leaf int16 {
117 type int16;
118 }
119 leaf int32 {
120 type int32;
121 }
122 leaf int64 {
123 type int64;
124 }
125 leaf uint8 {
126 type uint8;
127 }
128 leaf uint16 {
129 type uint16;
130 }
131 leaf uint32 {
132 type uint32;
133 }
134 leaf uint64 {
135 type uint64;
136 }
137 leaf boolean {
138 type boolean;
139 }
140 leaf string {
141 type string;
142 }
143 leaf enum {
144 type enumeration {
145 enum A;
146 enum B;
147 enum C;
148 }
149 }
150 identity food;
151 identity apple {
152 base "food";
153 }
154 leaf identityRef {
155 type identityref {
156 base "food";
157 }
158 }
159 leaf binary {
160 type binary;
161 }
162 leaf empty {
163 type empty;
164 }
165 leaf bits {
166 type bits {
167 bit a;
168 bit b;
169 bit AHOJ;
170 }
171 }
Václav Kubernátd4800e52020-11-09 10:58:12 +0100172 typedef capabilitiesType {
173 type bits {
174 bit router;
175 bit switch;
176 bit hub;
177 }
178 }
179 leaf capabilities {
180 type capabilitiesType;
181 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100182 leaf dec64 {
183 type decimal64 {
184 fraction-digits 5;
185 }
186 }
187
188 list stuff {
189 key "name";
190 leaf name {
191 type string;
192 }
193 }
194
195 leaf leafRefPresent {
196 type leafref {
197 path ../stuff/name;
198 }
199 }
200
201 leaf leafRefNonPresent {
202 type leafref {
203 path ../stuff/name;
204 }
205 }
Václav Kubernát61d92d72020-11-06 03:14:18 +0100206
207 container users {
208 config false;
209 list userList {
210 leaf name {
211 type string;
212 }
213 }
214 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100215}
216)";
217
218const auto data = R"(
219{
220 "test-schema:int8": 8,
221 "test-schema:int16": 300,
222 "test-schema:int32": -300,
223 "test-schema:int64": -999999999999999,
224 "test-schema:uint8": 8,
225 "test-schema:uint16": 300,
226 "test-schema:uint32": 300,
227 "test-schema:uint64": 999999999999999,
228 "test-schema:boolean": true,
229 "test-schema:string": "AHOJ",
230 "test-schema:enum": "A",
231 "test-schema:identityRef": "apple",
232 "test-schema:binary": "QUhPSgo=",
233 "test-schema:empty": "",
234 "test-schema:bits": "a AHOJ",
Václav Kubernátd4800e52020-11-09 10:58:12 +0100235 "test-schema:capabilities": "switch hub",
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100236 "test-schema:dec64": "43242.43260",
237 "test-schema:stuff": [
238 {
239 "name": "Xaver"
240 }
241 ],
242 "test-schema:leafRefPresent": "Xaver",
Václav Kubernát61d92d72020-11-06 03:14:18 +0100243 "test-schema:leafRefNonPresent": "Lucas",
244 "test-schema:users": {
245 "userList": [
246 {
247 "name": "John"
248 },
249 {
250 "name": "Aneta"
251 },
252 {
253 "name": "Aneta"
254 }
255 ]
256 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100257}
258)";
259
260
261TEST_CASE("libyang_utils")
262{
263 auto ctx = std::make_shared<libyang::Context>();
264 ctx->parse_module_mem(schema, LYS_IN_YANG);
Václav Kubernát61d92d72020-11-06 03:14:18 +0100265 auto dataNode = ctx->parse_data_mem(data, LYD_JSON, LYD_OPT_DATA_NO_YANGLIB | LYD_OPT_NOEXTDEPS | LYD_OPT_STRICT);
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100266
Václav Kubernát61d92d72020-11-06 03:14:18 +0100267 SECTION("leafValueFromNode") {
268 std::string path;
269 leaf_data_ expectedLeafData;
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100270
Václav Kubernát61d92d72020-11-06 03:14:18 +0100271 SECTION("test-schema:int8") {
272 path = "test-schema:int8";
273 expectedLeafData = int8_t{8};
274 }
275 SECTION("test-schema:int16") {
276 path = "test-schema:int16";
277 expectedLeafData = int16_t{300};
278 }
279 SECTION("test-schema:int32") {
280 path = "test-schema:int32";
281 expectedLeafData = int32_t{-300};
282 }
283 SECTION("test-schema:int64") {
284 path = "test-schema:int64";
285 expectedLeafData = int64_t{-999999999999999};
286 }
287 SECTION("test-schema:uint8") {
288 path = "test-schema:uint8";
289 expectedLeafData = uint8_t{8};
290 }
291 SECTION("test-schema:uint16") {
292 path = "test-schema:uint16";
293 expectedLeafData = uint16_t{300};
294 }
295 SECTION("test-schema:uint32") {
296 path = "test-schema:uint32";
297 expectedLeafData = uint32_t{300};
298 }
299 SECTION("test-schema:uint64") {
300 path = "test-schema:uint64";
301 expectedLeafData = uint64_t{999999999999999};
302 }
303 SECTION("test-schema:boolean") {
304 path = "test-schema:boolean";
305 expectedLeafData = true;
306 }
307 SECTION("test-schema:string") {
308 path = "test-schema:string";
309 expectedLeafData = std::string{"AHOJ"};
310 }
311 SECTION("test-schema:enum") {
312 path = "test-schema:enum";
313 expectedLeafData = enum_{"A"};
314 }
315 SECTION("test-schema:identityRef") {
316 path = "test-schema:identityRef";
317 expectedLeafData = identityRef_{"test-schema", "apple"};
318 }
319 SECTION("test-schema:binary") {
320 path = "test-schema:binary";
321 expectedLeafData = binary_{"QUhPSgo="};
322 }
323 SECTION("test-schema:empty") {
324 path = "test-schema:empty";
325 expectedLeafData = empty_{};
326 }
327 SECTION("test-schema:bits") {
328 path = "test-schema:bits";
329 expectedLeafData = bits_{{"a", "AHOJ"}};
330 }
331 SECTION("test-schema:dec64") {
332 path = "test-schema:dec64";
333 expectedLeafData = 43242.43260;
334 }
335 SECTION("test-schema:leafRefPresent") {
336 path = "test-schema:leafRefPresent";
337 expectedLeafData = std::string{"Xaver"};
338 }
339 SECTION("test-schema:leafRefNonPresent") {
340 path = "test-schema:leafRefNonPresent";
341 expectedLeafData = std::string{"Lucas"};
342 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100343
Václav Kubernát61d92d72020-11-06 03:14:18 +0100344 auto leaf = dataNode->find_path(("/" + path).c_str());
345 REQUIRE(leaf->number() == 1);
346 auto firstLeaf = std::make_shared<libyang::Data_Node_Leaf_List>(leaf->data().front());
347 REQUIRE(leafValueFromNode(firstLeaf) == expectedLeafData);
348
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100349 }
350
Václav Kubernát61d92d72020-11-06 03:14:18 +0100351 SECTION("lyNodesToTree") {
352 DatastoreAccess::Tree expected {
353 {"/test-schema:int8", int8_t{8}},
354 {"/test-schema:int16", int16_t{300}},
355 {"/test-schema:int32", int32_t{-300}},
356 {"/test-schema:int64", int64_t{-999999999999999}},
357 {"/test-schema:uint8", uint8_t{8}},
358 {"/test-schema:uint16", uint16_t{300}},
359 {"/test-schema:uint32", uint32_t{300}},
360 {"/test-schema:uint64", uint64_t{999999999999999}},
361 {"/test-schema:boolean", true},
362 {"/test-schema:string", std::string{"AHOJ"}},
363 {"/test-schema:enum", enum_{"A"}},
364 {"/test-schema:identityRef", identityRef_{"test-schema", "apple"}},
365 {"/test-schema:binary", binary_{"QUhPSgo="}},
366 {"/test-schema:empty", empty_{}},
367 {"/test-schema:bits", bits_{{"a", "AHOJ"}}},
Václav Kubernátd4800e52020-11-09 10:58:12 +0100368 {"/test-schema:capabilities", bits_{{"switch", "hub"}}},
Václav Kubernát61d92d72020-11-06 03:14:18 +0100369 {"/test-schema:dec64", 43242.432600},
370 {"/test-schema:stuff[name='Xaver']", special_{SpecialValue::List}},
371 {"/test-schema:stuff[name='Xaver']/name", std::string{"Xaver"}},
372 {"/test-schema:leafRefPresent", std::string{"Xaver"}},
373 {"/test-schema:leafRefNonPresent", std::string{"Lucas"}},
374 {"/test-schema:users/userList[1]", special_{SpecialValue::List}},
375 {"/test-schema:users/userList[1]/name", std::string{"John"}},
376 {"/test-schema:users/userList[2]", special_{SpecialValue::List}},
377 {"/test-schema:users/userList[2]/name", std::string{"Aneta"}},
378 {"/test-schema:users/userList[3]", special_{SpecialValue::List}},
379 {"/test-schema:users/userList[3]/name", std::string{"Aneta"}},
380 };
381
382 DatastoreAccess::Tree tree;
383 lyNodesToTree(tree, {dataNode->tree_for()});
384 REQUIRE(tree == expected);
385 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100386}