blob: 941586decf959f75c18b09f6c2183c16050af62c [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",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200698 std::make_unique<yang::TypeInfo>(ys.leafType("/example-schema:_list/number"))
Václav Kubernát3a99f002020-03-31 02:27:41 +0200699 );
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{{
Václav Kubernát13b23d72020-04-16 21:49:51 +0200721 yang::TypeInfo{createEnum({"wlan0", "wlan1"})},
722 yang::TypeInfo{yang::LeafRef{
Václav Kubernát2984f442020-02-20 17:43:35 +0100723 "/example-schema:portSettings/port",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200724 std::make_unique<yang::TypeInfo>(createEnum({"eth0", "eth1", "eth2"}))
725 }},
726 yang::TypeInfo{yang::LeafRef{
Václav Kubernát2984f442020-02-20 17:43:35 +0100727 "/example-schema:activeMappedPort",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200728 std::make_unique<yang::TypeInfo>(yang::LeafRef{
Václav Kubernát2984f442020-02-20 17:43:35 +0100729 "/example-schema:portMapping/port",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200730 std::make_unique<yang::TypeInfo>(enums)
731 })
732 }},
Václav Kubernát2984f442020-02-20 17:43:35 +0100733 }};
734 }
735
Václav Kubernát0d4db442018-07-18 17:18:43 +0200736 REQUIRE(ys.leafType(path, node) == type);
737 }
738 SECTION("childNodes")
739 {
740 std::set<std::string> set;
741
742 SECTION("<root>")
743 {
744 set = {"example-schema:a", "example-schema:b", "example-schema:leafString",
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200745 "example-schema:leafDecimal", "example-schema:leafBool",
746 "example-schema:leafInt8", "example-schema:leafUint8",
747 "example-schema:leafInt16", "example-schema:leafUint16",
748 "example-schema:leafInt32", "example-schema:leafUint32",
749 "example-schema:leafInt64", "example-schema:leafUint64",
750 "example-schema:leafEnum", "example-schema:leafEnumTypedef",
Václav Kubernát6a713d62018-10-03 18:47:34 +0200751 "example-schema:leafEnumTypedefRestricted", "example-schema:leafEnumTypedefRestricted2",
Václav Kubernáteeb38842019-03-20 19:46:05 +0100752 "example-schema:foodIdentLeaf", "example-schema:pizzaIdentLeaf", "example-schema:foodDrinkIdentLeaf",
Václav Kubernát7d82da72019-04-11 15:16:38 +0200753 "example-schema:_list", "example-schema:twoKeyList", "second-schema:bla",
754 "example-schema:carry", "example-schema:zero", "example-schema:direction",
Václav Kubernát280df4a2019-11-01 14:46:34 +0100755 "example-schema:interrupt",
Václav Kubernáta38d4172019-11-04 12:36:39 +0100756 "example-schema:ethernet", "example-schema:loopback",
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100757 "example-schema:pizzaSize",
758 "example-schema:length", "example-schema:wavelength",
Václav Kubernátbd5e3c22020-02-19 15:22:00 +0100759 "example-schema:duration", "example-schema:another-duration",
Václav Kubernát2984f442020-02-20 17:43:35 +0100760 "example-schema:activeNumber",
761 "example-schema:numberOrString",
762 "example-schema:portSettings",
763 "example-schema:portMapping",
764 "example-schema:activeMappedPort",
765 "example-schema:activePort"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200766 }
767
Václav Kubernát4f77a252019-02-19 16:51:30 +0100768 SECTION("example-schema:a")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200769 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200770 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát4f77a252019-02-19 16:51:30 +0100771 set = {"a2", "leafa", "second-schema:augmentedContainer"};
772 }
773
774 SECTION("second-schema:bla")
775 {
776 path.m_nodes.push_back(schemaNode_(module_{"second-schema"}, container_("bla")));
777 set = {"bla2"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200778 }
779
Václav Kubernát47a3f672019-11-08 15:42:43 +0100780 SECTION("example-schema:ethernet")
781 {
782 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("ethernet")));
783 set = {"ip"};
784 }
785
Václav Kubernáte7d4aea2018-09-11 18:15:48 +0200786 REQUIRE(ys.childNodes(path, Recursion::NonRecursive) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200787 }
Václav Kubernát34ee85a2020-02-18 17:12:12 +0100788 SECTION("nodeType")
789 {
790 yang::NodeTypes expected;
791 SECTION("leafInt32")
792 {
793 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
794 expected = yang::NodeTypes::Leaf;
795 }
796
797 SECTION("a")
798 {
799 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
800 expected = yang::NodeTypes::Container;
801 }
802
803 SECTION("a/a2/a3")
804 {
805 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
806 path.m_nodes.push_back(schemaNode_(container_("a2")));
807 path.m_nodes.push_back(schemaNode_(container_("a3")));
808 expected = yang::NodeTypes::PresenceContainer;
809 }
810
811 SECTION("_list")
812 {
813 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, list_("_list")));
814 expected = yang::NodeTypes::List;
815 }
816
817 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
818 }
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100819
820 SECTION("description")
821 {
822 std::optional<std::string> expected;
823 SECTION("leafInt32")
824 {
825 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
826 expected = "A 32-bit integer leaf.";
827 }
828
829 SECTION("leafString")
830 {
831 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafString")));
832 }
833
Václav Kubernát2984f442020-02-20 17:43:35 +0100834 SECTION("numberOrString")
835 {
836 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("numberOrString")));
837 expected = "Can be an int32 or a string.";
838 }
839
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100840 REQUIRE(ys.description(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
841 }
842
843 SECTION("units")
844 {
Václav Kubernát13b23d72020-04-16 21:49:51 +0200845 yang::LeafDataType expectedType;
846 std::optional<std::string> expectedUnits;
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100847 SECTION("length")
848 {
849 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("length")));
Václav Kubernát13b23d72020-04-16 21:49:51 +0200850 expectedType.emplace<yang::Int32>();
851 expectedUnits = "m";
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100852 }
853
854 SECTION("wavelength")
855 {
856 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("wavelength")));
Václav Kubernát13b23d72020-04-16 21:49:51 +0200857 expectedType.emplace<yang::Decimal>();
858 expectedUnits = "nm";
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100859 }
860
861 SECTION("leafInt32")
862 {
863 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
Václav Kubernát13b23d72020-04-16 21:49:51 +0200864 expectedType.emplace<yang::Int32>();
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100865 }
866
867 SECTION("duration")
868 {
869 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("duration")));
Václav Kubernát13b23d72020-04-16 21:49:51 +0200870 expectedType.emplace<yang::Int32>();
871 expectedUnits = "s";
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100872 }
873
874 SECTION("another-duration")
875 {
876 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("another-duration")));
Václav Kubernát13b23d72020-04-16 21:49:51 +0200877 expectedType.emplace<yang::Int32>();
878 expectedUnits = "vt";
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100879 }
Václav Kubernát13b23d72020-04-16 21:49:51 +0200880 REQUIRE(ys.leafType(pathToSchemaString(path, Prefixes::WhenNeeded)) == yang::TypeInfo{expectedType, expectedUnits});
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100881 }
882
883 SECTION("nodeType")
884 {
885 yang::NodeTypes expected;
886 SECTION("leafInt32")
887 {
888 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
889 expected = yang::NodeTypes::Leaf;
890 }
891
892 SECTION("a")
893 {
894 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
895 expected = yang::NodeTypes::Container;
896 }
897
898 SECTION("a/a2/a3")
899 {
900 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
901 path.m_nodes.push_back(schemaNode_(container_("a2")));
902 path.m_nodes.push_back(schemaNode_(container_("a3")));
903 expected = yang::NodeTypes::PresenceContainer;
904 }
905
906 SECTION("_list")
907 {
908 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, list_("_list")));
909 expected = yang::NodeTypes::List;
910 }
911
912 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
913 }
Václav Kubernátbd5e3c22020-02-19 15:22:00 +0100914
915 SECTION("leafrefPath")
916 {
917 REQUIRE(ys.leafrefPath("/example-schema:activeNumber") == "/example-schema:_list/number");
918 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200919 }
920
921 SECTION("negative")
922 {
923 SECTION("nonexistent nodes")
924 {
925 SECTION("example-schema:coze")
926 {
927 node.first = "example-schema";
928 node.second = "coze";
929 }
930
931 SECTION("example-schema:a/nevim")
932 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200933 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200934 node.second = "nevim";
935 }
936
937 SECTION("modul:a/nevim")
938 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200939 path.m_nodes.push_back(schemaNode_(module_{"modul"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200940 node.second = "nevim";
941 }
942
943 REQUIRE(!ys.isPresenceContainer(path, node));
944 REQUIRE(!ys.isList(path, node));
945 REQUIRE(!ys.isLeaf(path, node));
946 REQUIRE(!ys.isContainer(path, node));
947 }
948
949 SECTION("\"is\" methods return false for existing nodes for different nodetypes")
950 {
951 SECTION("example-schema:a")
952 {
953 node.first = "example-schema";
954 node.second = "a";
955 }
956
957 SECTION("example-schema:a/a2")
958 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200959 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200960 node.second = "a2";
961 }
962
963 REQUIRE(!ys.isPresenceContainer(path, node));
964 REQUIRE(!ys.isList(path, node));
965 REQUIRE(!ys.isLeaf(path, node));
966 }
967
968 SECTION("nodetype-specific methods called with different nodetypes")
969 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200970 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200971 node.second = "a2";
972
Václav Kubernát0d4db442018-07-18 17:18:43 +0200973 REQUIRE(!ys.listHasKey(path, node, "chacha"));
974 }
975
976 SECTION("nonexistent module")
977 {
Václav Kubernát75877de2019-11-20 17:43:02 +0100978 REQUIRE(!ys.isModule("notAModule"));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200979 }
Václav Kubernáteeb38842019-03-20 19:46:05 +0100980
Václav Kubernát7d82da72019-04-11 15:16:38 +0200981 SECTION("grouping is not a node")
982 {
983 SECTION("example-schema:arithmeticFlags")
984 {
985 node.first = "example-schema";
986 node.second = "arithmeticFlags";
987 }
988
989 SECTION("example-schema:flags")
990 {
991 node.first = "example-schema";
992 node.second = "startAndStop";
993 }
994
995 REQUIRE(!ys.isPresenceContainer(path, node));
996 REQUIRE(!ys.isList(path, node));
997 REQUIRE(!ys.isLeaf(path, node));
998 REQUIRE(!ys.isContainer(path, node));
999 }
Václav Kubernát280df4a2019-11-01 14:46:34 +01001000
1001 SECTION("choice is not a node")
1002 {
1003 SECTION("example-schema:interface")
1004 {
1005 node.first = "example-schema";
1006 node.second = "interface";
1007 }
1008
1009 REQUIRE(!ys.isPresenceContainer(path, node));
1010 REQUIRE(!ys.isList(path, node));
1011 REQUIRE(!ys.isLeaf(path, node));
1012 REQUIRE(!ys.isContainer(path, node));
1013 }
1014
1015 SECTION("case is not a node")
1016 {
1017 SECTION("example-schema:caseLoopback")
1018 {
1019 node.first = "example-schema";
1020 node.second = "caseLoopback";
1021 }
1022
1023 SECTION("example-schema:caseEthernet")
1024 {
1025 node.first = "example-schema";
1026 node.second = "caseEthernet";
1027 }
1028
1029 REQUIRE(!ys.isPresenceContainer(path, node));
1030 REQUIRE(!ys.isList(path, node));
1031 REQUIRE(!ys.isLeaf(path, node));
1032 REQUIRE(!ys.isContainer(path, node));
1033 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001034 }
1035}