blob: dcf4354014ce1b4941a95bb49be5c4e3c2d602e7 [file] [log] [blame]
Václav Kubernát0d4db442018-07-18 17:18:43 +02001/*
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át47a3f672019-11-08 15:42:43 +01009#include <experimental/iterator>
Václav Kubernát3a99f002020-03-31 02:27:41 +020010#include "leaf_data_helpers.hpp"
Václav Kubernát1e09bd62020-02-17 15:13:38 +010011#include "pretty_printers.hpp"
Václav Kubernát26b56082020-02-03 18:28:56 +010012#include "trompeloeil_doctest.hpp"
Václav Kubernát0d4db442018-07-18 17:18:43 +020013#include "yang_schema.hpp"
14
Václav Kubernát4f77a252019-02-19 16:51:30 +010015const char* second_schema = R"(
16module second-schema {
17 namespace "http://example.com/nevim";
18 prefix second;
19
20 import example-schema {
21 prefix "example";
22 }
23
Václav Kubernáteeb38842019-03-20 19:46:05 +010024 identity pineapple {
25 base "example:fruit";
26 }
27
Václav Kubernát4f77a252019-02-19 16:51:30 +010028 augment /example:a {
29 container augmentedContainer {
30 }
31 }
32
33 container bla {
34 container bla2 {
35 }
36 }
37}
38)";
39
40const char* example_schema = R"(
Václav Kubernát0d4db442018-07-18 17:18:43 +020041module example-schema {
Václav Kubernát6a713d62018-10-03 18:47:34 +020042 yang-version 1.1;
Václav Kubernát0d4db442018-07-18 17:18:43 +020043 namespace "http://example.com/example-sports";
44 prefix coze;
45
Václav Kubernáteeb38842019-03-20 19:46:05 +010046 identity drink {
47 }
48
49 identity voda {
50 base "drink";
51 }
52
53 identity food {
54 }
55
56 identity fruit {
57 base "food";
58 }
59
60 identity pizza {
61 base "food";
62 }
63
64 identity hawaii {
65 base "pizza";
66 }
67
Václav Kubernát0d4db442018-07-18 17:18:43 +020068 container a {
69 container a2 {
70 container a3 {
71 presence true;
72 }
73 }
74
75 leaf leafa {
76 type string;
77 }
78 }
79
80 container b {
81 container b2 {
82 presence true;
83 container b3 {
84 }
85 }
86 }
87
88 leaf leafString {
89 type string;
90 }
91
92 leaf leafDecimal {
93 type decimal64 {
94 fraction-digits 5;
95 }
96 }
97
98 leaf leafBool {
99 type boolean;
100 }
101
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200102 leaf leafInt8 {
103 type int8;
104 }
105
106 leaf leafUint8 {
107 type uint8;
108 }
109
110 leaf leafInt16 {
111 type int16;
112 }
113
114 leaf leafUint16 {
115 type uint16;
116 }
117
118 leaf leafInt32 {
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100119 description "A 32-bit integer leaf.";
Václav Kubernát0d4db442018-07-18 17:18:43 +0200120 type int32;
121 }
122
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200123 leaf leafUint32 {
Václav Kubernát0d4db442018-07-18 17:18:43 +0200124 type uint32;
125 }
126
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200127 leaf leafInt64 {
128 type int64;
129 }
130
131 leaf leafUint64 {
132 type uint64;
133 }
134
Václav Kubernát0d4db442018-07-18 17:18:43 +0200135 leaf leafEnum {
136 type enumeration {
137 enum lol;
138 enum data;
139 enum coze;
140 }
141 }
142
Václav Kubernát6a713d62018-10-03 18:47:34 +0200143 typedef enumTypedef {
144 type enumeration {
145 enum lol;
146 enum data;
147 enum coze;
148 }
149 }
150
151 typedef enumTypedefRestricted {
152 type enumTypedef {
153 enum lol;
154 enum data;
155 }
156 }
157
158 leaf leafEnumTypedef {
159 type enumTypedef;
160 }
161
162 leaf leafEnumTypedefRestricted {
163 type enumTypedef {
164 enum data;
165 enum coze;
166 }
167 }
168
169 leaf leafEnumTypedefRestricted2 {
170 type enumTypedefRestricted;
171 }
172
Václav Kubernáteeb38842019-03-20 19:46:05 +0100173 leaf foodIdentLeaf {
174 type identityref {
175 base "food";
176 }
177 }
178
179 leaf pizzaIdentLeaf {
180 type identityref {
181 base "pizza";
182 }
183 }
184
185 leaf foodDrinkIdentLeaf {
186 type identityref {
187 base "food";
188 base "drink";
189 }
190 }
191
Václav Kubernát0d4db442018-07-18 17:18:43 +0200192 list _list {
193 key number;
194
195 leaf number {
196 type int32;
197 }
198
199 container contInList {
200 presence true;
201 }
202 }
203
204 list twoKeyList {
205 key "name number";
206
207 leaf number {
208 type int32;
209 }
210
211 leaf name {
212 type string;
213 }
214 }
Václav Kubernát7d82da72019-04-11 15:16:38 +0200215
216 grouping arithmeticFlags {
217 leaf carry {
218 type boolean;
219 }
220 leaf zero {
221 type boolean;
222 }
223 }
224
225 grouping flags {
226 leaf direction {
227 type boolean;
228 }
229 leaf interrupt {
230 type boolean;
231 }
232
233 uses arithmeticFlags;
234 }
235
236 uses flags;
Václav Kubernát280df4a2019-11-01 14:46:34 +0100237
238 choice interface {
239 case caseLoopback {
240 container loopback {
241 leaf ip {
242 type string;
243 }
244 }
245 }
246
247 case caseEthernet {
248 container ethernet {
249 leaf ip {
250 type string;
251 }
252 }
253 }
254 }
255
Václav Kubernáta38d4172019-11-04 12:36:39 +0100256 feature bigPizzas;
257
258 leaf pizzaSize {
259 type enumeration {
260 enum large {
261 if-feature "bigPizzas";
262 }
263 enum medium;
264 enum small;
265 }
266 }
267
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100268 leaf length {
269 type int32;
270 units "m";
271 }
272
273 leaf wavelength {
274 type decimal64 {
275 fraction-digits 10;
276 }
277 units "nm";
278 }
279
280 typedef seconds {
281 type int32;
282 units "s";
283 }
284
285 leaf duration {
286 type seconds;
287 }
288
289 leaf another-duration {
290 type seconds;
291 units "vt";
292 }
293
Václav Kubernátbd5e3c22020-02-19 15:22:00 +0100294 leaf activeNumber {
295 type leafref {
296 path "/_list/number";
297 }
298 }
299
Václav Kubernátfa81c8c2020-02-13 17:22:46 +0100300 rpc myRpc {}
301
Václav Kubernát0d4db442018-07-18 17:18:43 +0200302})";
303
Václav Kubernát47a3f672019-11-08 15:42:43 +0100304namespace std {
305std::ostream& operator<<(std::ostream& s, const std::set<std::string> set)
306{
307 s << std::endl << "{";
308 std::copy(set.begin(), set.end(), std::experimental::make_ostream_joiner(s, ", "));
309 s << "}" << std::endl;
310 return s;
311}
312}
313
Václav Kubernát0d4db442018-07-18 17:18:43 +0200314TEST_CASE("yangschema")
315{
Václav Kubernát4f77a252019-02-19 16:51:30 +0100316 using namespace std::string_view_literals;
Václav Kubernát0d4db442018-07-18 17:18:43 +0200317 YangSchema ys;
Václav Kubernátb52dc252019-12-04 13:03:39 +0100318 ys.registerModuleCallback([]([[maybe_unused]] auto modName, auto, auto, auto) {
Václav Kubernát4f77a252019-02-19 16:51:30 +0100319 assert("example-schema"sv == modName);
320 return example_schema;
321 });
322 ys.addSchemaString(second_schema);
323
Václav Kubernátefcac932020-01-10 15:26:32 +0100324 schemaPath_ path{Scope::Absolute, {}};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200325 ModuleNodePair node;
326
327 SECTION("positive")
328 {
329 SECTION("isContainer")
330 {
331 SECTION("example-schema:a")
332 {
333 node.first = "example-schema";
334 node.second = "a";
335 }
336
337 SECTION("example-schema:a/a2")
338 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200339 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200340 node.second = "a2";
341 }
342
Václav Kubernát280df4a2019-11-01 14:46:34 +0100343 SECTION("example-schema:ethernet")
344 {
345 node.first = "example-schema";
346 node.second = "ethernet";
347 }
348
349 SECTION("example-schema:loopback")
350 {
351 node.first = "example-schema";
352 node.second = "loopback";
353 }
354
Václav Kubernát0d4db442018-07-18 17:18:43 +0200355 REQUIRE(ys.isContainer(path, node));
356 }
357 SECTION("isLeaf")
358 {
359 SECTION("example-schema:leafString")
360 {
361 node.first = "example-schema";
362 node.second = "leafString";
363 }
364
365 SECTION("example-schema:a/leafa")
366 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200367 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200368 node.first = "example-schema";
369 node.second = "leafa";
370 }
371
Václav Kubernát7d82da72019-04-11 15:16:38 +0200372 SECTION("example-schema:carry")
373 {
374 node.first = "example-schema";
375 node.second = "carry";
376 }
377
378 SECTION("example-schema:zero")
379 {
380 node.first = "example-schema";
381 node.second = "zero";
382 }
383
384 SECTION("example-schema:direction")
385 {
386 node.first = "example-schema";
387 node.second = "direction";
388 }
389
390 SECTION("example-schema:interrupt")
391 {
392 node.first = "example-schema";
393 node.second = "interrupt";
394 }
395
Václav Kubernát0d4db442018-07-18 17:18:43 +0200396 REQUIRE(ys.isLeaf(path, node));
397 }
398 SECTION("isModule")
399 {
Václav Kubernát75877de2019-11-20 17:43:02 +0100400 REQUIRE(ys.isModule("example-schema"));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200401 }
402 SECTION("isList")
403 {
404 SECTION("example-schema:_list")
405 {
406 node.first = "example-schema";
407 node.second = "_list";
408 }
409
410 SECTION("example-schema:twoKeyList")
411 {
412 node.first = "example-schema";
413 node.second = "twoKeyList";
414 }
415
416 REQUIRE(ys.isList(path, node));
417 }
418 SECTION("isPresenceContainer")
419 {
420 SECTION("example-schema:a/a2/a3")
421 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200422 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
423 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a2")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200424 node.second = "a3";
425 }
426
427 REQUIRE(ys.isPresenceContainer(path, node));
428 }
Václav Kubernáteeb38842019-03-20 19:46:05 +0100429
Václav Kubernát0d4db442018-07-18 17:18:43 +0200430 SECTION("listHasKey")
431 {
432 std::string key;
433
434 SECTION("_list")
435 {
436 node.first = "example-schema";
437 node.second = "_list";
438 SECTION("number")
439 key = "number";
440 }
441
442 SECTION("twoKeyList")
443 {
444 node.first = "example-schema";
445 node.second = "twoKeyList";
446 SECTION("number")
447 key = "number";
448 SECTION("name")
449 key = "name";
450 }
451
452 REQUIRE(ys.listHasKey(path, node, key));
453 }
454 SECTION("listKeys")
455 {
456 std::set<std::string> set;
457
458 SECTION("_list")
459 {
460 set = {"number"};
461 node.first = "example-schema";
462 node.second = "_list";
463 }
464
465 SECTION("twoKeyList")
466 {
467 set = {"number", "name"};
468 node.first = "example-schema";
469 node.second = "twoKeyList";
470 }
471
472 REQUIRE(ys.listKeys(path, node) == set);
473 }
474 SECTION("leafType")
475 {
Václav Kubernát3a99f002020-03-31 02:27:41 +0200476 yang::LeafDataType type;
Václav Kubernát0d4db442018-07-18 17:18:43 +0200477
478 SECTION("leafString")
479 {
480 node.first = "example-schema";
481 node.second = "leafString";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200482 type = yang::String{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200483 }
484
485 SECTION("leafDecimal")
486 {
487 node.first = "example-schema";
488 node.second = "leafDecimal";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200489 type = yang::Decimal{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200490 }
491
492 SECTION("leafBool")
493 {
494 node.first = "example-schema";
495 node.second = "leafBool";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200496 type = yang::Bool{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200497 }
498
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200499 SECTION("leafInt8")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200500 {
501 node.first = "example-schema";
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200502 node.second = "leafInt8";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200503 type = yang::Int8{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200504 }
505
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200506 SECTION("leafUint8")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200507 {
508 node.first = "example-schema";
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200509 node.second = "leafUint8";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200510 type = yang::Uint8{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200511 }
512
Václav Kubernátb6d02752020-04-03 00:25:10 +0200513 SECTION("leafInt16")
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200514 {
515 node.first = "example-schema";
516 node.second = "leafInt16";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200517 type = yang::Int16{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200518 }
519
520 SECTION("leafUint16")
521 {
522 node.first = "example-schema";
523 node.second = "leafUint16";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200524 type = yang::Uint16{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200525 }
526
527 SECTION("leafInt32")
528 {
529 node.first = "example-schema";
530 node.second = "leafInt32";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200531 type = yang::Int32{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200532 }
533
534 SECTION("leafUint32")
535 {
536 node.first = "example-schema";
537 node.second = "leafUint32";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200538 type = yang::Uint32{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200539 }
540
541 SECTION("leafInt64")
542 {
543 node.first = "example-schema";
544 node.second = "leafInt64";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200545 type = yang::Int64{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200546 }
547
548 SECTION("leafUint64")
549 {
550 node.first = "example-schema";
551 node.second = "leafUint64";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200552 type = yang::Uint64{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200553 }
554
555 SECTION("leafEnum")
556 {
557 node.first = "example-schema";
558 node.second = "leafEnum";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200559 type = createEnum({"lol", "data", "coze"});
560 }
561
562 SECTION("leafEnumTypedef")
563 {
564 node.first = "example-schema";
565 node.second = "leafEnumTypedef";
566 type = createEnum({"lol", "data", "coze"});
567 }
568
569 SECTION("leafEnumTypedefRestricted")
570 {
571 node.first = "example-schema";
572 node.second = "leafEnumTypedefRestricted";
573 type = createEnum({"data", "coze"});
574 }
575
576 SECTION("leafEnumTypedefRestricted2")
577 {
578 node.first = "example-schema";
579 node.second = "leafEnumTypedefRestricted2";
580 type = createEnum({"lol", "data"});
581 }
582
583 SECTION("pizzaSize")
584 {
585 node.first = "example-schema";
586 node.second = "pizzaSize";
587
588 SECTION("bigPizzas disabled")
589 {
590 type = createEnum({"small", "medium"});
591 }
592 SECTION("bigPizzas enabled")
593 {
594 ys.enableFeature("example-schema", "bigPizzas");
595 type = createEnum({"small", "medium", "large"});
596 }
597 }
598
599 SECTION("foodIdentLeaf")
600 {
601 node.first = "example-schema";
602 node.second = "foodIdentLeaf";
603 type = yang::IdentityRef{{{"second-schema", "pineapple"},
604 {"example-schema", "food"},
605 {"example-schema", "pizza"},
606 {"example-schema", "hawaii"},
607 {"example-schema", "fruit"}}};
608 }
609
610 SECTION("pizzaIdentLeaf")
611 {
612 node.first = "example-schema";
613 node.second = "pizzaIdentLeaf";
614
615 type = yang::IdentityRef{{
616 {"example-schema", "pizza"},
617 {"example-schema", "hawaii"},
618 }};
619 }
620
621 SECTION("foodDrinkIdentLeaf")
622 {
623 node.first = "example-schema";
624 node.second = "foodDrinkIdentLeaf";
625
626 type = yang::IdentityRef{{
627 {"example-schema", "food"},
628 {"example-schema", "drink"},
629 {"example-schema", "fruit"},
630 {"example-schema", "hawaii"},
631 {"example-schema", "pizza"},
632 {"example-schema", "voda"},
633 {"second-schema", "pineapple"},
634 }};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200635 }
636
Václav Kubernátb6d02752020-04-03 00:25:10 +0200637 SECTION("activeNumber")
638 {
639 node.first = "example-schema";
640 node.second = "activeNumber";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200641 type.emplace<yang::LeafRef>(
642 "/example-schema:_list/number",
643 std::make_unique<yang::LeafDataType>(ys.leafType("/example-schema:_list/number"))
644 );
Václav Kubernátb6d02752020-04-03 00:25:10 +0200645 }
646
Václav Kubernát0d4db442018-07-18 17:18:43 +0200647 REQUIRE(ys.leafType(path, node) == type);
648 }
649 SECTION("childNodes")
650 {
651 std::set<std::string> set;
652
653 SECTION("<root>")
654 {
655 set = {"example-schema:a", "example-schema:b", "example-schema:leafString",
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200656 "example-schema:leafDecimal", "example-schema:leafBool",
657 "example-schema:leafInt8", "example-schema:leafUint8",
658 "example-schema:leafInt16", "example-schema:leafUint16",
659 "example-schema:leafInt32", "example-schema:leafUint32",
660 "example-schema:leafInt64", "example-schema:leafUint64",
661 "example-schema:leafEnum", "example-schema:leafEnumTypedef",
Václav Kubernát6a713d62018-10-03 18:47:34 +0200662 "example-schema:leafEnumTypedefRestricted", "example-schema:leafEnumTypedefRestricted2",
Václav Kubernáteeb38842019-03-20 19:46:05 +0100663 "example-schema:foodIdentLeaf", "example-schema:pizzaIdentLeaf", "example-schema:foodDrinkIdentLeaf",
Václav Kubernát7d82da72019-04-11 15:16:38 +0200664 "example-schema:_list", "example-schema:twoKeyList", "second-schema:bla",
665 "example-schema:carry", "example-schema:zero", "example-schema:direction",
Václav Kubernát280df4a2019-11-01 14:46:34 +0100666 "example-schema:interrupt",
Václav Kubernáta38d4172019-11-04 12:36:39 +0100667 "example-schema:ethernet", "example-schema:loopback",
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100668 "example-schema:pizzaSize",
669 "example-schema:length", "example-schema:wavelength",
Václav Kubernátbd5e3c22020-02-19 15:22:00 +0100670 "example-schema:duration", "example-schema:another-duration",
671 "example-schema:activeNumber"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200672 }
673
Václav Kubernát4f77a252019-02-19 16:51:30 +0100674 SECTION("example-schema:a")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200675 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200676 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát4f77a252019-02-19 16:51:30 +0100677 set = {"a2", "leafa", "second-schema:augmentedContainer"};
678 }
679
680 SECTION("second-schema:bla")
681 {
682 path.m_nodes.push_back(schemaNode_(module_{"second-schema"}, container_("bla")));
683 set = {"bla2"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200684 }
685
Václav Kubernát47a3f672019-11-08 15:42:43 +0100686 SECTION("example-schema:ethernet")
687 {
688 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("ethernet")));
689 set = {"ip"};
690 }
691
Václav Kubernáte7d4aea2018-09-11 18:15:48 +0200692 REQUIRE(ys.childNodes(path, Recursion::NonRecursive) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200693 }
Václav Kubernát34ee85a2020-02-18 17:12:12 +0100694 SECTION("nodeType")
695 {
696 yang::NodeTypes expected;
697 SECTION("leafInt32")
698 {
699 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
700 expected = yang::NodeTypes::Leaf;
701 }
702
703 SECTION("a")
704 {
705 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
706 expected = yang::NodeTypes::Container;
707 }
708
709 SECTION("a/a2/a3")
710 {
711 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
712 path.m_nodes.push_back(schemaNode_(container_("a2")));
713 path.m_nodes.push_back(schemaNode_(container_("a3")));
714 expected = yang::NodeTypes::PresenceContainer;
715 }
716
717 SECTION("_list")
718 {
719 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, list_("_list")));
720 expected = yang::NodeTypes::List;
721 }
722
723 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
724 }
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100725
726 SECTION("description")
727 {
728 std::optional<std::string> expected;
729 SECTION("leafInt32")
730 {
731 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
732 expected = "A 32-bit integer leaf.";
733 }
734
735 SECTION("leafString")
736 {
737 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafString")));
738 }
739
740 REQUIRE(ys.description(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
741 }
742
743 SECTION("units")
744 {
745 std::optional<std::string> expected;
746 SECTION("length")
747 {
748 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("length")));
749 expected = "m";
750 }
751
752 SECTION("wavelength")
753 {
754 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("wavelength")));
755 expected = "nm";
756 }
757
758 SECTION("leafInt32")
759 {
760 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
761 }
762
763 SECTION("duration")
764 {
765 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("duration")));
766 expected = "s";
767 }
768
769 SECTION("another-duration")
770 {
771 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("another-duration")));
772 expected = "vt";
773 }
774
775 REQUIRE(ys.units(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
776 }
777
778 SECTION("nodeType")
779 {
780 yang::NodeTypes expected;
781 SECTION("leafInt32")
782 {
783 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
784 expected = yang::NodeTypes::Leaf;
785 }
786
787 SECTION("a")
788 {
789 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
790 expected = yang::NodeTypes::Container;
791 }
792
793 SECTION("a/a2/a3")
794 {
795 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
796 path.m_nodes.push_back(schemaNode_(container_("a2")));
797 path.m_nodes.push_back(schemaNode_(container_("a3")));
798 expected = yang::NodeTypes::PresenceContainer;
799 }
800
801 SECTION("_list")
802 {
803 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, list_("_list")));
804 expected = yang::NodeTypes::List;
805 }
806
807 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
808 }
Václav Kubernátbd5e3c22020-02-19 15:22:00 +0100809
810 SECTION("leafrefPath")
811 {
812 REQUIRE(ys.leafrefPath("/example-schema:activeNumber") == "/example-schema:_list/number");
813 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200814 }
815
816 SECTION("negative")
817 {
818 SECTION("nonexistent nodes")
819 {
820 SECTION("example-schema:coze")
821 {
822 node.first = "example-schema";
823 node.second = "coze";
824 }
825
826 SECTION("example-schema:a/nevim")
827 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200828 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200829 node.second = "nevim";
830 }
831
832 SECTION("modul:a/nevim")
833 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200834 path.m_nodes.push_back(schemaNode_(module_{"modul"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200835 node.second = "nevim";
836 }
837
838 REQUIRE(!ys.isPresenceContainer(path, node));
839 REQUIRE(!ys.isList(path, node));
840 REQUIRE(!ys.isLeaf(path, node));
841 REQUIRE(!ys.isContainer(path, node));
842 }
843
844 SECTION("\"is\" methods return false for existing nodes for different nodetypes")
845 {
846 SECTION("example-schema:a")
847 {
848 node.first = "example-schema";
849 node.second = "a";
850 }
851
852 SECTION("example-schema:a/a2")
853 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200854 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200855 node.second = "a2";
856 }
857
858 REQUIRE(!ys.isPresenceContainer(path, node));
859 REQUIRE(!ys.isList(path, node));
860 REQUIRE(!ys.isLeaf(path, node));
861 }
862
863 SECTION("nodetype-specific methods called with different nodetypes")
864 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200865 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200866 node.second = "a2";
867
Václav Kubernát0d4db442018-07-18 17:18:43 +0200868 REQUIRE(!ys.listHasKey(path, node, "chacha"));
869 }
870
871 SECTION("nonexistent module")
872 {
Václav Kubernát75877de2019-11-20 17:43:02 +0100873 REQUIRE(!ys.isModule("notAModule"));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200874 }
Václav Kubernáteeb38842019-03-20 19:46:05 +0100875
Václav Kubernát7d82da72019-04-11 15:16:38 +0200876 SECTION("grouping is not a node")
877 {
878 SECTION("example-schema:arithmeticFlags")
879 {
880 node.first = "example-schema";
881 node.second = "arithmeticFlags";
882 }
883
884 SECTION("example-schema:flags")
885 {
886 node.first = "example-schema";
887 node.second = "startAndStop";
888 }
889
890 REQUIRE(!ys.isPresenceContainer(path, node));
891 REQUIRE(!ys.isList(path, node));
892 REQUIRE(!ys.isLeaf(path, node));
893 REQUIRE(!ys.isContainer(path, node));
894 }
Václav Kubernát280df4a2019-11-01 14:46:34 +0100895
896 SECTION("choice is not a node")
897 {
898 SECTION("example-schema:interface")
899 {
900 node.first = "example-schema";
901 node.second = "interface";
902 }
903
904 REQUIRE(!ys.isPresenceContainer(path, node));
905 REQUIRE(!ys.isList(path, node));
906 REQUIRE(!ys.isLeaf(path, node));
907 REQUIRE(!ys.isContainer(path, node));
908 }
909
910 SECTION("case is not a node")
911 {
912 SECTION("example-schema:caseLoopback")
913 {
914 node.first = "example-schema";
915 node.second = "caseLoopback";
916 }
917
918 SECTION("example-schema:caseEthernet")
919 {
920 node.first = "example-schema";
921 node.second = "caseEthernet";
922 }
923
924 REQUIRE(!ys.isPresenceContainer(path, node));
925 REQUIRE(!ys.isList(path, node));
926 REQUIRE(!ys.isLeaf(path, node));
927 REQUIRE(!ys.isContainer(path, node));
928 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200929 }
930}