blob: a9fb65e2d09451f4d4b1bec36afb20f2421302d9 [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át2984f442020-02-20 17:43:35 +0100302 leaf numberOrString {
303 type union {
304 type int32;
305 type string;
306 }
307 description "Can be an int32 or a string.";
308 }
309
310 list portSettings {
311 key "port";
312 leaf port {
313 type enumeration {
314 enum eth0;
315 enum eth1;
316 enum eth2;
317 }
318 }
319 }
320
321 feature weirdPortNames;
322
323 list portMapping {
324 key "port";
325 leaf port {
326 type enumeration {
327 enum WEIRD {
328 if-feature "weirdPortNames";
329 }
330 enum utf2;
331 enum utf3;
332 }
333 }
334 }
335
336 leaf activeMappedPort {
337 type leafref {
338 path "../portMapping/port";
339 }
340 }
341
342 leaf activePort {
343 type union {
344 type enumeration {
345 enum wlan0;
346 enum wlan1;
347 }
348 type leafref {
349 path "../portSettings/port";
350 }
351 type leafref {
352 path "../activeMappedPort";
353 }
354 }
355 }
356
Václav Kubernát0d4db442018-07-18 17:18:43 +0200357})";
358
Václav Kubernát47a3f672019-11-08 15:42:43 +0100359namespace std {
360std::ostream& operator<<(std::ostream& s, const std::set<std::string> set)
361{
362 s << std::endl << "{";
363 std::copy(set.begin(), set.end(), std::experimental::make_ostream_joiner(s, ", "));
364 s << "}" << std::endl;
365 return s;
366}
367}
368
Václav Kubernát0d4db442018-07-18 17:18:43 +0200369TEST_CASE("yangschema")
370{
Václav Kubernát4f77a252019-02-19 16:51:30 +0100371 using namespace std::string_view_literals;
Václav Kubernát0d4db442018-07-18 17:18:43 +0200372 YangSchema ys;
Václav Kubernátb52dc252019-12-04 13:03:39 +0100373 ys.registerModuleCallback([]([[maybe_unused]] auto modName, auto, auto, auto) {
Václav Kubernát4f77a252019-02-19 16:51:30 +0100374 assert("example-schema"sv == modName);
375 return example_schema;
376 });
377 ys.addSchemaString(second_schema);
378
Václav Kubernátefcac932020-01-10 15:26:32 +0100379 schemaPath_ path{Scope::Absolute, {}};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200380 ModuleNodePair node;
381
382 SECTION("positive")
383 {
384 SECTION("isContainer")
385 {
386 SECTION("example-schema:a")
387 {
388 node.first = "example-schema";
389 node.second = "a";
390 }
391
392 SECTION("example-schema:a/a2")
393 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200394 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200395 node.second = "a2";
396 }
397
Václav Kubernát280df4a2019-11-01 14:46:34 +0100398 SECTION("example-schema:ethernet")
399 {
400 node.first = "example-schema";
401 node.second = "ethernet";
402 }
403
404 SECTION("example-schema:loopback")
405 {
406 node.first = "example-schema";
407 node.second = "loopback";
408 }
409
Václav Kubernát0d4db442018-07-18 17:18:43 +0200410 REQUIRE(ys.isContainer(path, node));
411 }
412 SECTION("isLeaf")
413 {
414 SECTION("example-schema:leafString")
415 {
416 node.first = "example-schema";
417 node.second = "leafString";
418 }
419
420 SECTION("example-schema:a/leafa")
421 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200422 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200423 node.first = "example-schema";
424 node.second = "leafa";
425 }
426
Václav Kubernát7d82da72019-04-11 15:16:38 +0200427 SECTION("example-schema:carry")
428 {
429 node.first = "example-schema";
430 node.second = "carry";
431 }
432
433 SECTION("example-schema:zero")
434 {
435 node.first = "example-schema";
436 node.second = "zero";
437 }
438
439 SECTION("example-schema:direction")
440 {
441 node.first = "example-schema";
442 node.second = "direction";
443 }
444
445 SECTION("example-schema:interrupt")
446 {
447 node.first = "example-schema";
448 node.second = "interrupt";
449 }
450
Václav Kubernát0d4db442018-07-18 17:18:43 +0200451 REQUIRE(ys.isLeaf(path, node));
452 }
453 SECTION("isModule")
454 {
Václav Kubernát75877de2019-11-20 17:43:02 +0100455 REQUIRE(ys.isModule("example-schema"));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200456 }
457 SECTION("isList")
458 {
459 SECTION("example-schema:_list")
460 {
461 node.first = "example-schema";
462 node.second = "_list";
463 }
464
465 SECTION("example-schema:twoKeyList")
466 {
467 node.first = "example-schema";
468 node.second = "twoKeyList";
469 }
470
471 REQUIRE(ys.isList(path, node));
472 }
473 SECTION("isPresenceContainer")
474 {
475 SECTION("example-schema:a/a2/a3")
476 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200477 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
478 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a2")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200479 node.second = "a3";
480 }
481
482 REQUIRE(ys.isPresenceContainer(path, node));
483 }
Václav Kubernáteeb38842019-03-20 19:46:05 +0100484
Václav Kubernát0d4db442018-07-18 17:18:43 +0200485 SECTION("listHasKey")
486 {
487 std::string key;
488
489 SECTION("_list")
490 {
491 node.first = "example-schema";
492 node.second = "_list";
493 SECTION("number")
494 key = "number";
495 }
496
497 SECTION("twoKeyList")
498 {
499 node.first = "example-schema";
500 node.second = "twoKeyList";
501 SECTION("number")
502 key = "number";
503 SECTION("name")
504 key = "name";
505 }
506
507 REQUIRE(ys.listHasKey(path, node, key));
508 }
509 SECTION("listKeys")
510 {
511 std::set<std::string> set;
512
513 SECTION("_list")
514 {
515 set = {"number"};
516 node.first = "example-schema";
517 node.second = "_list";
518 }
519
520 SECTION("twoKeyList")
521 {
522 set = {"number", "name"};
523 node.first = "example-schema";
524 node.second = "twoKeyList";
525 }
526
527 REQUIRE(ys.listKeys(path, node) == set);
528 }
529 SECTION("leafType")
530 {
Václav Kubernát3a99f002020-03-31 02:27:41 +0200531 yang::LeafDataType type;
Václav Kubernát0d4db442018-07-18 17:18:43 +0200532
533 SECTION("leafString")
534 {
535 node.first = "example-schema";
536 node.second = "leafString";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200537 type = yang::String{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200538 }
539
540 SECTION("leafDecimal")
541 {
542 node.first = "example-schema";
543 node.second = "leafDecimal";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200544 type = yang::Decimal{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200545 }
546
547 SECTION("leafBool")
548 {
549 node.first = "example-schema";
550 node.second = "leafBool";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200551 type = yang::Bool{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200552 }
553
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200554 SECTION("leafInt8")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200555 {
556 node.first = "example-schema";
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200557 node.second = "leafInt8";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200558 type = yang::Int8{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200559 }
560
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200561 SECTION("leafUint8")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200562 {
563 node.first = "example-schema";
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200564 node.second = "leafUint8";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200565 type = yang::Uint8{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200566 }
567
Václav Kubernátb6d02752020-04-03 00:25:10 +0200568 SECTION("leafInt16")
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200569 {
570 node.first = "example-schema";
571 node.second = "leafInt16";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200572 type = yang::Int16{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200573 }
574
575 SECTION("leafUint16")
576 {
577 node.first = "example-schema";
578 node.second = "leafUint16";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200579 type = yang::Uint16{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200580 }
581
582 SECTION("leafInt32")
583 {
584 node.first = "example-schema";
585 node.second = "leafInt32";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200586 type = yang::Int32{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200587 }
588
589 SECTION("leafUint32")
590 {
591 node.first = "example-schema";
592 node.second = "leafUint32";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200593 type = yang::Uint32{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200594 }
595
596 SECTION("leafInt64")
597 {
598 node.first = "example-schema";
599 node.second = "leafInt64";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200600 type = yang::Int64{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200601 }
602
603 SECTION("leafUint64")
604 {
605 node.first = "example-schema";
606 node.second = "leafUint64";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200607 type = yang::Uint64{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200608 }
609
610 SECTION("leafEnum")
611 {
612 node.first = "example-schema";
613 node.second = "leafEnum";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200614 type = createEnum({"lol", "data", "coze"});
615 }
616
617 SECTION("leafEnumTypedef")
618 {
619 node.first = "example-schema";
620 node.second = "leafEnumTypedef";
621 type = createEnum({"lol", "data", "coze"});
622 }
623
624 SECTION("leafEnumTypedefRestricted")
625 {
626 node.first = "example-schema";
627 node.second = "leafEnumTypedefRestricted";
628 type = createEnum({"data", "coze"});
629 }
630
631 SECTION("leafEnumTypedefRestricted2")
632 {
633 node.first = "example-schema";
634 node.second = "leafEnumTypedefRestricted2";
635 type = createEnum({"lol", "data"});
636 }
637
638 SECTION("pizzaSize")
639 {
640 node.first = "example-schema";
641 node.second = "pizzaSize";
642
643 SECTION("bigPizzas disabled")
644 {
645 type = createEnum({"small", "medium"});
646 }
647 SECTION("bigPizzas enabled")
648 {
649 ys.enableFeature("example-schema", "bigPizzas");
650 type = createEnum({"small", "medium", "large"});
651 }
652 }
653
654 SECTION("foodIdentLeaf")
655 {
656 node.first = "example-schema";
657 node.second = "foodIdentLeaf";
658 type = yang::IdentityRef{{{"second-schema", "pineapple"},
659 {"example-schema", "food"},
660 {"example-schema", "pizza"},
661 {"example-schema", "hawaii"},
662 {"example-schema", "fruit"}}};
663 }
664
665 SECTION("pizzaIdentLeaf")
666 {
667 node.first = "example-schema";
668 node.second = "pizzaIdentLeaf";
669
670 type = yang::IdentityRef{{
671 {"example-schema", "pizza"},
672 {"example-schema", "hawaii"},
673 }};
674 }
675
676 SECTION("foodDrinkIdentLeaf")
677 {
678 node.first = "example-schema";
679 node.second = "foodDrinkIdentLeaf";
680
681 type = yang::IdentityRef{{
682 {"example-schema", "food"},
683 {"example-schema", "drink"},
684 {"example-schema", "fruit"},
685 {"example-schema", "hawaii"},
686 {"example-schema", "pizza"},
687 {"example-schema", "voda"},
688 {"second-schema", "pineapple"},
689 }};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200690 }
691
Václav Kubernátb6d02752020-04-03 00:25:10 +0200692 SECTION("activeNumber")
693 {
694 node.first = "example-schema";
695 node.second = "activeNumber";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200696 type.emplace<yang::LeafRef>(
697 "/example-schema:_list/number",
698 std::make_unique<yang::LeafDataType>(ys.leafType("/example-schema:_list/number"))
699 );
Václav Kubernátb6d02752020-04-03 00:25:10 +0200700 }
701
Václav Kubernát2984f442020-02-20 17:43:35 +0100702 SECTION("activePort")
703 {
704 node.first = "example-schema";
705 node.second = "activePort";
706
707 yang::Enum enums = [&ys]() {
708 SECTION("weird ports disabled")
709 {
710 return createEnum({"utf2", "utf3"});
711 }
712 SECTION("weird ports enabled")
713 {
714 ys.enableFeature("example-schema", "weirdPortNames");
715 return createEnum({"WEIRD", "utf2", "utf3"});
716 }
717 __builtin_unreachable();
718 }();
719
720 type = yang::Union{{
721 createEnum({"wlan0", "wlan1"}),
722 yang::LeafRef{
723 "/example-schema:portSettings/port",
724 std::make_unique<yang::LeafDataType>(createEnum({"eth0", "eth1", "eth2"}))
725 },
726 yang::LeafRef{
727 "/example-schema:activeMappedPort",
728 std::make_unique<yang::LeafDataType>(yang::LeafRef{
729 "/example-schema:portMapping/port",
730 std::make_unique<yang::LeafDataType>(enums)
731 })},
732 }};
733 }
734
Václav Kubernát0d4db442018-07-18 17:18:43 +0200735 REQUIRE(ys.leafType(path, node) == type);
736 }
737 SECTION("childNodes")
738 {
739 std::set<std::string> set;
740
741 SECTION("<root>")
742 {
743 set = {"example-schema:a", "example-schema:b", "example-schema:leafString",
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200744 "example-schema:leafDecimal", "example-schema:leafBool",
745 "example-schema:leafInt8", "example-schema:leafUint8",
746 "example-schema:leafInt16", "example-schema:leafUint16",
747 "example-schema:leafInt32", "example-schema:leafUint32",
748 "example-schema:leafInt64", "example-schema:leafUint64",
749 "example-schema:leafEnum", "example-schema:leafEnumTypedef",
Václav Kubernát6a713d62018-10-03 18:47:34 +0200750 "example-schema:leafEnumTypedefRestricted", "example-schema:leafEnumTypedefRestricted2",
Václav Kubernáteeb38842019-03-20 19:46:05 +0100751 "example-schema:foodIdentLeaf", "example-schema:pizzaIdentLeaf", "example-schema:foodDrinkIdentLeaf",
Václav Kubernát7d82da72019-04-11 15:16:38 +0200752 "example-schema:_list", "example-schema:twoKeyList", "second-schema:bla",
753 "example-schema:carry", "example-schema:zero", "example-schema:direction",
Václav Kubernát280df4a2019-11-01 14:46:34 +0100754 "example-schema:interrupt",
Václav Kubernáta38d4172019-11-04 12:36:39 +0100755 "example-schema:ethernet", "example-schema:loopback",
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100756 "example-schema:pizzaSize",
757 "example-schema:length", "example-schema:wavelength",
Václav Kubernátbd5e3c22020-02-19 15:22:00 +0100758 "example-schema:duration", "example-schema:another-duration",
Václav Kubernát2984f442020-02-20 17:43:35 +0100759 "example-schema:activeNumber",
760 "example-schema:numberOrString",
761 "example-schema:portSettings",
762 "example-schema:portMapping",
763 "example-schema:activeMappedPort",
764 "example-schema:activePort"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200765 }
766
Václav Kubernát4f77a252019-02-19 16:51:30 +0100767 SECTION("example-schema:a")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200768 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200769 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát4f77a252019-02-19 16:51:30 +0100770 set = {"a2", "leafa", "second-schema:augmentedContainer"};
771 }
772
773 SECTION("second-schema:bla")
774 {
775 path.m_nodes.push_back(schemaNode_(module_{"second-schema"}, container_("bla")));
776 set = {"bla2"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200777 }
778
Václav Kubernát47a3f672019-11-08 15:42:43 +0100779 SECTION("example-schema:ethernet")
780 {
781 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("ethernet")));
782 set = {"ip"};
783 }
784
Václav Kubernáte7d4aea2018-09-11 18:15:48 +0200785 REQUIRE(ys.childNodes(path, Recursion::NonRecursive) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200786 }
Václav Kubernát34ee85a2020-02-18 17:12:12 +0100787 SECTION("nodeType")
788 {
789 yang::NodeTypes expected;
790 SECTION("leafInt32")
791 {
792 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
793 expected = yang::NodeTypes::Leaf;
794 }
795
796 SECTION("a")
797 {
798 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
799 expected = yang::NodeTypes::Container;
800 }
801
802 SECTION("a/a2/a3")
803 {
804 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
805 path.m_nodes.push_back(schemaNode_(container_("a2")));
806 path.m_nodes.push_back(schemaNode_(container_("a3")));
807 expected = yang::NodeTypes::PresenceContainer;
808 }
809
810 SECTION("_list")
811 {
812 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, list_("_list")));
813 expected = yang::NodeTypes::List;
814 }
815
816 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
817 }
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100818
819 SECTION("description")
820 {
821 std::optional<std::string> expected;
822 SECTION("leafInt32")
823 {
824 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
825 expected = "A 32-bit integer leaf.";
826 }
827
828 SECTION("leafString")
829 {
830 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafString")));
831 }
832
Václav Kubernát2984f442020-02-20 17:43:35 +0100833 SECTION("numberOrString")
834 {
835 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("numberOrString")));
836 expected = "Can be an int32 or a string.";
837 }
838
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100839 REQUIRE(ys.description(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
840 }
841
842 SECTION("units")
843 {
844 std::optional<std::string> expected;
845 SECTION("length")
846 {
847 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("length")));
848 expected = "m";
849 }
850
851 SECTION("wavelength")
852 {
853 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("wavelength")));
854 expected = "nm";
855 }
856
857 SECTION("leafInt32")
858 {
859 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
860 }
861
862 SECTION("duration")
863 {
864 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("duration")));
865 expected = "s";
866 }
867
868 SECTION("another-duration")
869 {
870 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("another-duration")));
871 expected = "vt";
872 }
873
874 REQUIRE(ys.units(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
875 }
876
877 SECTION("nodeType")
878 {
879 yang::NodeTypes expected;
880 SECTION("leafInt32")
881 {
882 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
883 expected = yang::NodeTypes::Leaf;
884 }
885
886 SECTION("a")
887 {
888 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
889 expected = yang::NodeTypes::Container;
890 }
891
892 SECTION("a/a2/a3")
893 {
894 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
895 path.m_nodes.push_back(schemaNode_(container_("a2")));
896 path.m_nodes.push_back(schemaNode_(container_("a3")));
897 expected = yang::NodeTypes::PresenceContainer;
898 }
899
900 SECTION("_list")
901 {
902 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, list_("_list")));
903 expected = yang::NodeTypes::List;
904 }
905
906 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
907 }
Václav Kubernátbd5e3c22020-02-19 15:22:00 +0100908
909 SECTION("leafrefPath")
910 {
911 REQUIRE(ys.leafrefPath("/example-schema:activeNumber") == "/example-schema:_list/number");
912 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200913 }
914
915 SECTION("negative")
916 {
917 SECTION("nonexistent nodes")
918 {
919 SECTION("example-schema:coze")
920 {
921 node.first = "example-schema";
922 node.second = "coze";
923 }
924
925 SECTION("example-schema:a/nevim")
926 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200927 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200928 node.second = "nevim";
929 }
930
931 SECTION("modul:a/nevim")
932 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200933 path.m_nodes.push_back(schemaNode_(module_{"modul"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200934 node.second = "nevim";
935 }
936
937 REQUIRE(!ys.isPresenceContainer(path, node));
938 REQUIRE(!ys.isList(path, node));
939 REQUIRE(!ys.isLeaf(path, node));
940 REQUIRE(!ys.isContainer(path, node));
941 }
942
943 SECTION("\"is\" methods return false for existing nodes for different nodetypes")
944 {
945 SECTION("example-schema:a")
946 {
947 node.first = "example-schema";
948 node.second = "a";
949 }
950
951 SECTION("example-schema:a/a2")
952 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200953 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200954 node.second = "a2";
955 }
956
957 REQUIRE(!ys.isPresenceContainer(path, node));
958 REQUIRE(!ys.isList(path, node));
959 REQUIRE(!ys.isLeaf(path, node));
960 }
961
962 SECTION("nodetype-specific methods called with different nodetypes")
963 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200964 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200965 node.second = "a2";
966
Václav Kubernát0d4db442018-07-18 17:18:43 +0200967 REQUIRE(!ys.listHasKey(path, node, "chacha"));
968 }
969
970 SECTION("nonexistent module")
971 {
Václav Kubernát75877de2019-11-20 17:43:02 +0100972 REQUIRE(!ys.isModule("notAModule"));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200973 }
Václav Kubernáteeb38842019-03-20 19:46:05 +0100974
Václav Kubernát7d82da72019-04-11 15:16:38 +0200975 SECTION("grouping is not a node")
976 {
977 SECTION("example-schema:arithmeticFlags")
978 {
979 node.first = "example-schema";
980 node.second = "arithmeticFlags";
981 }
982
983 SECTION("example-schema:flags")
984 {
985 node.first = "example-schema";
986 node.second = "startAndStop";
987 }
988
989 REQUIRE(!ys.isPresenceContainer(path, node));
990 REQUIRE(!ys.isList(path, node));
991 REQUIRE(!ys.isLeaf(path, node));
992 REQUIRE(!ys.isContainer(path, node));
993 }
Václav Kubernát280df4a2019-11-01 14:46:34 +0100994
995 SECTION("choice is not a node")
996 {
997 SECTION("example-schema:interface")
998 {
999 node.first = "example-schema";
1000 node.second = "interface";
1001 }
1002
1003 REQUIRE(!ys.isPresenceContainer(path, node));
1004 REQUIRE(!ys.isList(path, node));
1005 REQUIRE(!ys.isLeaf(path, node));
1006 REQUIRE(!ys.isContainer(path, node));
1007 }
1008
1009 SECTION("case is not a node")
1010 {
1011 SECTION("example-schema:caseLoopback")
1012 {
1013 node.first = "example-schema";
1014 node.second = "caseLoopback";
1015 }
1016
1017 SECTION("example-schema:caseEthernet")
1018 {
1019 node.first = "example-schema";
1020 node.second = "caseEthernet";
1021 }
1022
1023 REQUIRE(!ys.isPresenceContainer(path, node));
1024 REQUIRE(!ys.isList(path, node));
1025 REQUIRE(!ys.isLeaf(path, node));
1026 REQUIRE(!ys.isContainer(path, node));
1027 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001028 }
1029}