blob: c5f6fa4f2288f94eb9f5e7b738b646551af3e8c4 [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át1e09bd62020-02-17 15:13:38 +010010#include "pretty_printers.hpp"
Václav Kubernát26b56082020-02-03 18:28:56 +010011#include "trompeloeil_doctest.hpp"
Václav Kubernát0d4db442018-07-18 17:18:43 +020012#include "yang_schema.hpp"
13
Václav Kubernát4f77a252019-02-19 16:51:30 +010014const char* second_schema = R"(
15module second-schema {
16 namespace "http://example.com/nevim";
17 prefix second;
18
19 import example-schema {
20 prefix "example";
21 }
22
Václav Kubernáteeb38842019-03-20 19:46:05 +010023 identity pineapple {
24 base "example:fruit";
25 }
26
Václav Kubernát4f77a252019-02-19 16:51:30 +010027 augment /example:a {
28 container augmentedContainer {
29 }
30 }
31
32 container bla {
33 container bla2 {
34 }
35 }
36}
37)";
38
39const char* example_schema = R"(
Václav Kubernát0d4db442018-07-18 17:18:43 +020040module example-schema {
Václav Kubernát6a713d62018-10-03 18:47:34 +020041 yang-version 1.1;
Václav Kubernát0d4db442018-07-18 17:18:43 +020042 namespace "http://example.com/example-sports";
43 prefix coze;
44
Václav Kubernáteeb38842019-03-20 19:46:05 +010045 identity drink {
46 }
47
48 identity voda {
49 base "drink";
50 }
51
52 identity food {
53 }
54
55 identity fruit {
56 base "food";
57 }
58
59 identity pizza {
60 base "food";
61 }
62
63 identity hawaii {
64 base "pizza";
65 }
66
Václav Kubernát0d4db442018-07-18 17:18:43 +020067 container a {
68 container a2 {
69 container a3 {
70 presence true;
71 }
72 }
73
74 leaf leafa {
75 type string;
76 }
77 }
78
79 container b {
80 container b2 {
81 presence true;
82 container b3 {
83 }
84 }
85 }
86
87 leaf leafString {
88 type string;
89 }
90
91 leaf leafDecimal {
92 type decimal64 {
93 fraction-digits 5;
94 }
95 }
96
97 leaf leafBool {
98 type boolean;
99 }
100
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200101 leaf leafInt8 {
102 type int8;
103 }
104
105 leaf leafUint8 {
106 type uint8;
107 }
108
109 leaf leafInt16 {
110 type int16;
111 }
112
113 leaf leafUint16 {
114 type uint16;
115 }
116
117 leaf leafInt32 {
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100118 description "A 32-bit integer leaf.";
Václav Kubernát0d4db442018-07-18 17:18:43 +0200119 type int32;
120 }
121
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200122 leaf leafUint32 {
Václav Kubernát0d4db442018-07-18 17:18:43 +0200123 type uint32;
124 }
125
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200126 leaf leafInt64 {
127 type int64;
128 }
129
130 leaf leafUint64 {
131 type uint64;
132 }
133
Václav Kubernát0d4db442018-07-18 17:18:43 +0200134 leaf leafEnum {
135 type enumeration {
136 enum lol;
137 enum data;
138 enum coze;
139 }
140 }
141
Václav Kubernát6a713d62018-10-03 18:47:34 +0200142 typedef enumTypedef {
143 type enumeration {
144 enum lol;
145 enum data;
146 enum coze;
147 }
148 }
149
150 typedef enumTypedefRestricted {
151 type enumTypedef {
152 enum lol;
153 enum data;
154 }
155 }
156
157 leaf leafEnumTypedef {
158 type enumTypedef;
159 }
160
161 leaf leafEnumTypedefRestricted {
162 type enumTypedef {
163 enum data;
164 enum coze;
165 }
166 }
167
168 leaf leafEnumTypedefRestricted2 {
169 type enumTypedefRestricted;
170 }
171
Václav Kubernáteeb38842019-03-20 19:46:05 +0100172 leaf foodIdentLeaf {
173 type identityref {
174 base "food";
175 }
176 }
177
178 leaf pizzaIdentLeaf {
179 type identityref {
180 base "pizza";
181 }
182 }
183
184 leaf foodDrinkIdentLeaf {
185 type identityref {
186 base "food";
187 base "drink";
188 }
189 }
190
Václav Kubernát0d4db442018-07-18 17:18:43 +0200191 list _list {
192 key number;
193
194 leaf number {
195 type int32;
196 }
197
198 container contInList {
199 presence true;
200 }
201 }
202
203 list twoKeyList {
204 key "name number";
205
206 leaf number {
207 type int32;
208 }
209
210 leaf name {
211 type string;
212 }
213 }
Václav Kubernát7d82da72019-04-11 15:16:38 +0200214
215 grouping arithmeticFlags {
216 leaf carry {
217 type boolean;
218 }
219 leaf zero {
220 type boolean;
221 }
222 }
223
224 grouping flags {
225 leaf direction {
226 type boolean;
227 }
228 leaf interrupt {
229 type boolean;
230 }
231
232 uses arithmeticFlags;
233 }
234
235 uses flags;
Václav Kubernát280df4a2019-11-01 14:46:34 +0100236
237 choice interface {
238 case caseLoopback {
239 container loopback {
240 leaf ip {
241 type string;
242 }
243 }
244 }
245
246 case caseEthernet {
247 container ethernet {
248 leaf ip {
249 type string;
250 }
251 }
252 }
253 }
254
Václav Kubernáta38d4172019-11-04 12:36:39 +0100255 feature bigPizzas;
256
257 leaf pizzaSize {
258 type enumeration {
259 enum large {
260 if-feature "bigPizzas";
261 }
262 enum medium;
263 enum small;
264 }
265 }
266
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100267 leaf length {
268 type int32;
269 units "m";
270 }
271
272 leaf wavelength {
273 type decimal64 {
274 fraction-digits 10;
275 }
276 units "nm";
277 }
278
279 typedef seconds {
280 type int32;
281 units "s";
282 }
283
284 leaf duration {
285 type seconds;
286 }
287
288 leaf another-duration {
289 type seconds;
290 units "vt";
291 }
292
Václav Kubernátbd5e3c22020-02-19 15:22:00 +0100293 leaf activeNumber {
294 type leafref {
295 path "/_list/number";
296 }
297 }
298
Václav Kubernát0d4db442018-07-18 17:18:43 +0200299})";
300
Václav Kubernát47a3f672019-11-08 15:42:43 +0100301namespace std {
302std::ostream& operator<<(std::ostream& s, const std::set<std::string> set)
303{
304 s << std::endl << "{";
305 std::copy(set.begin(), set.end(), std::experimental::make_ostream_joiner(s, ", "));
306 s << "}" << std::endl;
307 return s;
308}
309}
310
Václav Kubernát0d4db442018-07-18 17:18:43 +0200311TEST_CASE("yangschema")
312{
Václav Kubernát4f77a252019-02-19 16:51:30 +0100313 using namespace std::string_view_literals;
Václav Kubernát0d4db442018-07-18 17:18:43 +0200314 YangSchema ys;
Václav Kubernátb52dc252019-12-04 13:03:39 +0100315 ys.registerModuleCallback([]([[maybe_unused]] auto modName, auto, auto, auto) {
Václav Kubernát4f77a252019-02-19 16:51:30 +0100316 assert("example-schema"sv == modName);
317 return example_schema;
318 });
319 ys.addSchemaString(second_schema);
320
Václav Kubernátefcac932020-01-10 15:26:32 +0100321 schemaPath_ path{Scope::Absolute, {}};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200322 ModuleNodePair node;
323
324 SECTION("positive")
325 {
326 SECTION("isContainer")
327 {
328 SECTION("example-schema:a")
329 {
330 node.first = "example-schema";
331 node.second = "a";
332 }
333
334 SECTION("example-schema:a/a2")
335 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200336 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200337 node.second = "a2";
338 }
339
Václav Kubernát280df4a2019-11-01 14:46:34 +0100340 SECTION("example-schema:ethernet")
341 {
342 node.first = "example-schema";
343 node.second = "ethernet";
344 }
345
346 SECTION("example-schema:loopback")
347 {
348 node.first = "example-schema";
349 node.second = "loopback";
350 }
351
Václav Kubernát0d4db442018-07-18 17:18:43 +0200352 REQUIRE(ys.isContainer(path, node));
353 }
354 SECTION("isLeaf")
355 {
356 SECTION("example-schema:leafString")
357 {
358 node.first = "example-schema";
359 node.second = "leafString";
360 }
361
362 SECTION("example-schema:a/leafa")
363 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200364 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200365 node.first = "example-schema";
366 node.second = "leafa";
367 }
368
Václav Kubernát7d82da72019-04-11 15:16:38 +0200369 SECTION("example-schema:carry")
370 {
371 node.first = "example-schema";
372 node.second = "carry";
373 }
374
375 SECTION("example-schema:zero")
376 {
377 node.first = "example-schema";
378 node.second = "zero";
379 }
380
381 SECTION("example-schema:direction")
382 {
383 node.first = "example-schema";
384 node.second = "direction";
385 }
386
387 SECTION("example-schema:interrupt")
388 {
389 node.first = "example-schema";
390 node.second = "interrupt";
391 }
392
Václav Kubernát0d4db442018-07-18 17:18:43 +0200393 REQUIRE(ys.isLeaf(path, node));
394 }
395 SECTION("isModule")
396 {
Václav Kubernát75877de2019-11-20 17:43:02 +0100397 REQUIRE(ys.isModule("example-schema"));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200398 }
399 SECTION("isList")
400 {
401 SECTION("example-schema:_list")
402 {
403 node.first = "example-schema";
404 node.second = "_list";
405 }
406
407 SECTION("example-schema:twoKeyList")
408 {
409 node.first = "example-schema";
410 node.second = "twoKeyList";
411 }
412
413 REQUIRE(ys.isList(path, node));
414 }
415 SECTION("isPresenceContainer")
416 {
417 SECTION("example-schema:a/a2/a3")
418 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200419 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
420 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a2")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200421 node.second = "a3";
422 }
423
424 REQUIRE(ys.isPresenceContainer(path, node));
425 }
426 SECTION("leafEnumHasValue")
427 {
Václav Kubernát0d4db442018-07-18 17:18:43 +0200428 std::string value;
Václav Kubernát6a713d62018-10-03 18:47:34 +0200429 SECTION("leafEnum")
430 {
431 node.first = "example-schema";
432 node.second = "leafEnum";
Václav Kubernát0d4db442018-07-18 17:18:43 +0200433
Václav Kubernát6a713d62018-10-03 18:47:34 +0200434 SECTION("lol")
435 value = "lol";
Václav Kubernát0d4db442018-07-18 17:18:43 +0200436
Václav Kubernát6a713d62018-10-03 18:47:34 +0200437 SECTION("data")
438 value = "data";
Václav Kubernát0d4db442018-07-18 17:18:43 +0200439
Václav Kubernát6a713d62018-10-03 18:47:34 +0200440 SECTION("coze")
441 value = "coze";
442 }
443
444 SECTION("leafEnumTypedef")
445 {
446 node.first = "example-schema";
447 node.second = "leafEnumTypedef";
448
449 SECTION("lol")
450 value = "lol";
451
452 SECTION("data")
453 value = "data";
454
455 SECTION("coze")
456 value = "coze";
457 }
458
459 SECTION("leafEnumTypedefRestricted")
460 {
461 node.first = "example-schema";
462 node.second = "leafEnumTypedefRestricted";
463
464 SECTION("data")
465 value = "data";
466
467 SECTION("coze")
468 value = "coze";
469 }
470
471 SECTION("leafEnumTypedefRestricted2")
472 {
473 node.first = "example-schema";
474 node.second = "leafEnumTypedefRestricted2";
475
476 SECTION("lol")
477 value = "lol";
478
479 SECTION("data")
480 value = "data";
481 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200482
Václav Kubernáta38d4172019-11-04 12:36:39 +0100483 SECTION("pizzaSize")
484 {
485 node.first = "example-schema";
486 node.second = "pizzaSize";
487
488 SECTION("small")
489 {
490 value = "small";
Václav Kubernáta38d4172019-11-04 12:36:39 +0100491 }
492 SECTION("medium")
493 {
494 value = "medium";
495 }
496
497 SECTION("large")
498 {
499 ys.enableFeature("example-schema", "bigPizzas");
500 value = "large";
501 }
502 }
503
Václav Kubernát0d4db442018-07-18 17:18:43 +0200504 REQUIRE(ys.leafEnumHasValue(path, node, value));
505 }
Václav Kubernáteeb38842019-03-20 19:46:05 +0100506 SECTION("leafIdentityIsValid")
507 {
508 ModuleValuePair value;
509
510 SECTION("foodIdentLeaf")
511 {
512 node.first = "example-schema";
513 node.second = "foodIdentLeaf";
514
515 SECTION("food")
516 {
517 value.second = "food";
518 }
519 SECTION("example-schema:food")
520 {
521 value.first = "example-schema";
522 value.second = "food";
523 }
524 SECTION("pizza")
525 {
526 value.second = "pizza";
527 }
528 SECTION("example-schema:pizza")
529 {
530 value.first = "example-schema";
531 value.second = "pizza";
532 }
533 SECTION("hawaii")
534 {
535 value.second = "hawaii";
536 }
537 SECTION("example-schema:hawaii")
538 {
539 value.first = "example-schema";
540 value.second = "hawaii";
541 }
542 SECTION("fruit")
543 {
544 value.second = "fruit";
545 }
546 SECTION("example-schema:fruit")
547 {
548 value.first = "example-schema";
549 value.second = "fruit";
550 }
551 SECTION("second-schema:pineapple")
552 {
553 value.first = "second-schema";
554 value.second = "pineapple";
555 }
556 }
557
558 SECTION("pizzaIdentLeaf")
559 {
560 node.first = "example-schema";
561 node.second = "pizzaIdentLeaf";
562
563 SECTION("pizza")
564 {
565 value.second = "pizza";
566 }
567 SECTION("example-schema:pizza")
568 {
569 value.first = "example-schema";
570 value.second = "pizza";
571 }
572 SECTION("hawaii")
573 {
574 value.second = "hawaii";
575 }
576 SECTION("example-schema:hawaii")
577 {
578 value.first = "example-schema";
579 value.second = "hawaii";
580 }
581 }
582
583 SECTION("foodDrinkIdentLeaf")
584 {
585 node.first = "example-schema";
586 node.second = "foodDrinkIdentLeaf";
587
588 SECTION("food")
589 {
590 value.second = "food";
591 }
592 SECTION("example-schema:food")
593 {
594 value.first = "example-schema";
595 value.second = "food";
596 }
597 SECTION("drink")
598 {
599 value.second = "drink";
600 }
601 SECTION("example-schema:drink")
602 {
603 value.first = "example-schema";
604 value.second = "drink";
605 }
606 }
607 REQUIRE(ys.leafIdentityIsValid(path, node, value));
608 }
609
Václav Kubernát0d4db442018-07-18 17:18:43 +0200610 SECTION("listHasKey")
611 {
612 std::string key;
613
614 SECTION("_list")
615 {
616 node.first = "example-schema";
617 node.second = "_list";
618 SECTION("number")
619 key = "number";
620 }
621
622 SECTION("twoKeyList")
623 {
624 node.first = "example-schema";
625 node.second = "twoKeyList";
626 SECTION("number")
627 key = "number";
628 SECTION("name")
629 key = "name";
630 }
631
632 REQUIRE(ys.listHasKey(path, node, key));
633 }
634 SECTION("listKeys")
635 {
636 std::set<std::string> set;
637
638 SECTION("_list")
639 {
640 set = {"number"};
641 node.first = "example-schema";
642 node.second = "_list";
643 }
644
645 SECTION("twoKeyList")
646 {
647 set = {"number", "name"};
648 node.first = "example-schema";
649 node.second = "twoKeyList";
650 }
651
652 REQUIRE(ys.listKeys(path, node) == set);
653 }
654 SECTION("leafType")
655 {
656 yang::LeafDataTypes type;
657
658 SECTION("leafString")
659 {
660 node.first = "example-schema";
661 node.second = "leafString";
662 type = yang::LeafDataTypes::String;
663 }
664
665 SECTION("leafDecimal")
666 {
667 node.first = "example-schema";
668 node.second = "leafDecimal";
669 type = yang::LeafDataTypes::Decimal;
670 }
671
672 SECTION("leafBool")
673 {
674 node.first = "example-schema";
675 node.second = "leafBool";
676 type = yang::LeafDataTypes::Bool;
677 }
678
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200679 SECTION("leafInt8")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200680 {
681 node.first = "example-schema";
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200682 node.second = "leafInt8";
683 type = yang::LeafDataTypes::Int8;
Václav Kubernát0d4db442018-07-18 17:18:43 +0200684 }
685
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200686 SECTION("leafUint8")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200687 {
688 node.first = "example-schema";
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200689 node.second = "leafUint8";
690 type = yang::LeafDataTypes::Uint8;
691 }
692
693 SECTION("leafInt15")
694 {
695 node.first = "example-schema";
696 node.second = "leafInt16";
697 type = yang::LeafDataTypes::Int16;
698 }
699
700 SECTION("leafUint16")
701 {
702 node.first = "example-schema";
703 node.second = "leafUint16";
704 type = yang::LeafDataTypes::Uint16;
705 }
706
707 SECTION("leafInt32")
708 {
709 node.first = "example-schema";
710 node.second = "leafInt32";
711 type = yang::LeafDataTypes::Int32;
712 }
713
714 SECTION("leafUint32")
715 {
716 node.first = "example-schema";
717 node.second = "leafUint32";
718 type = yang::LeafDataTypes::Uint32;
719 }
720
721 SECTION("leafInt64")
722 {
723 node.first = "example-schema";
724 node.second = "leafInt64";
725 type = yang::LeafDataTypes::Int64;
726 }
727
728 SECTION("leafUint64")
729 {
730 node.first = "example-schema";
731 node.second = "leafUint64";
732 type = yang::LeafDataTypes::Uint64;
Václav Kubernát0d4db442018-07-18 17:18:43 +0200733 }
734
735 SECTION("leafEnum")
736 {
737 node.first = "example-schema";
738 node.second = "leafEnum";
739 type = yang::LeafDataTypes::Enum;
740 }
741
742 REQUIRE(ys.leafType(path, node) == type);
743 }
744 SECTION("childNodes")
745 {
746 std::set<std::string> set;
747
748 SECTION("<root>")
749 {
750 set = {"example-schema:a", "example-schema:b", "example-schema:leafString",
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200751 "example-schema:leafDecimal", "example-schema:leafBool",
752 "example-schema:leafInt8", "example-schema:leafUint8",
753 "example-schema:leafInt16", "example-schema:leafUint16",
754 "example-schema:leafInt32", "example-schema:leafUint32",
755 "example-schema:leafInt64", "example-schema:leafUint64",
756 "example-schema:leafEnum", "example-schema:leafEnumTypedef",
Václav Kubernát6a713d62018-10-03 18:47:34 +0200757 "example-schema:leafEnumTypedefRestricted", "example-schema:leafEnumTypedefRestricted2",
Václav Kubernáteeb38842019-03-20 19:46:05 +0100758 "example-schema:foodIdentLeaf", "example-schema:pizzaIdentLeaf", "example-schema:foodDrinkIdentLeaf",
Václav Kubernát7d82da72019-04-11 15:16:38 +0200759 "example-schema:_list", "example-schema:twoKeyList", "second-schema:bla",
760 "example-schema:carry", "example-schema:zero", "example-schema:direction",
Václav Kubernát280df4a2019-11-01 14:46:34 +0100761 "example-schema:interrupt",
Václav Kubernáta38d4172019-11-04 12:36:39 +0100762 "example-schema:ethernet", "example-schema:loopback",
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100763 "example-schema:pizzaSize",
764 "example-schema:length", "example-schema:wavelength",
Václav Kubernátbd5e3c22020-02-19 15:22:00 +0100765 "example-schema:duration", "example-schema:another-duration",
766 "example-schema:activeNumber"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200767 }
768
Václav Kubernát4f77a252019-02-19 16:51:30 +0100769 SECTION("example-schema:a")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200770 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200771 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát4f77a252019-02-19 16:51:30 +0100772 set = {"a2", "leafa", "second-schema:augmentedContainer"};
773 }
774
775 SECTION("second-schema:bla")
776 {
777 path.m_nodes.push_back(schemaNode_(module_{"second-schema"}, container_("bla")));
778 set = {"bla2"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200779 }
780
Václav Kubernát47a3f672019-11-08 15:42:43 +0100781 SECTION("example-schema:ethernet")
782 {
783 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("ethernet")));
784 set = {"ip"};
785 }
786
Václav Kubernáte7d4aea2018-09-11 18:15:48 +0200787 REQUIRE(ys.childNodes(path, Recursion::NonRecursive) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200788 }
Václav Kubernát34ee85a2020-02-18 17:12:12 +0100789 SECTION("nodeType")
790 {
791 yang::NodeTypes expected;
792 SECTION("leafInt32")
793 {
794 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
795 expected = yang::NodeTypes::Leaf;
796 }
797
798 SECTION("a")
799 {
800 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
801 expected = yang::NodeTypes::Container;
802 }
803
804 SECTION("a/a2/a3")
805 {
806 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
807 path.m_nodes.push_back(schemaNode_(container_("a2")));
808 path.m_nodes.push_back(schemaNode_(container_("a3")));
809 expected = yang::NodeTypes::PresenceContainer;
810 }
811
812 SECTION("_list")
813 {
814 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, list_("_list")));
815 expected = yang::NodeTypes::List;
816 }
817
818 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
819 }
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100820
821 SECTION("description")
822 {
823 std::optional<std::string> expected;
824 SECTION("leafInt32")
825 {
826 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
827 expected = "A 32-bit integer leaf.";
828 }
829
830 SECTION("leafString")
831 {
832 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafString")));
833 }
834
835 REQUIRE(ys.description(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
836 }
837
838 SECTION("units")
839 {
840 std::optional<std::string> expected;
841 SECTION("length")
842 {
843 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("length")));
844 expected = "m";
845 }
846
847 SECTION("wavelength")
848 {
849 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("wavelength")));
850 expected = "nm";
851 }
852
853 SECTION("leafInt32")
854 {
855 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
856 }
857
858 SECTION("duration")
859 {
860 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("duration")));
861 expected = "s";
862 }
863
864 SECTION("another-duration")
865 {
866 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("another-duration")));
867 expected = "vt";
868 }
869
870 REQUIRE(ys.units(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
871 }
872
873 SECTION("nodeType")
874 {
875 yang::NodeTypes expected;
876 SECTION("leafInt32")
877 {
878 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
879 expected = yang::NodeTypes::Leaf;
880 }
881
882 SECTION("a")
883 {
884 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
885 expected = yang::NodeTypes::Container;
886 }
887
888 SECTION("a/a2/a3")
889 {
890 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
891 path.m_nodes.push_back(schemaNode_(container_("a2")));
892 path.m_nodes.push_back(schemaNode_(container_("a3")));
893 expected = yang::NodeTypes::PresenceContainer;
894 }
895
896 SECTION("_list")
897 {
898 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, list_("_list")));
899 expected = yang::NodeTypes::List;
900 }
901
902 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
903 }
Václav Kubernátbd5e3c22020-02-19 15:22:00 +0100904
905 SECTION("leafrefPath")
906 {
907 REQUIRE(ys.leafrefPath("/example-schema:activeNumber") == "/example-schema:_list/number");
908 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200909 }
910
911 SECTION("negative")
912 {
913 SECTION("nonexistent nodes")
914 {
915 SECTION("example-schema:coze")
916 {
917 node.first = "example-schema";
918 node.second = "coze";
919 }
920
921 SECTION("example-schema:a/nevim")
922 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200923 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200924 node.second = "nevim";
925 }
926
927 SECTION("modul:a/nevim")
928 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200929 path.m_nodes.push_back(schemaNode_(module_{"modul"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200930 node.second = "nevim";
931 }
932
933 REQUIRE(!ys.isPresenceContainer(path, node));
934 REQUIRE(!ys.isList(path, node));
935 REQUIRE(!ys.isLeaf(path, node));
936 REQUIRE(!ys.isContainer(path, node));
937 }
938
939 SECTION("\"is\" methods return false for existing nodes for different nodetypes")
940 {
941 SECTION("example-schema:a")
942 {
943 node.first = "example-schema";
944 node.second = "a";
945 }
946
947 SECTION("example-schema:a/a2")
948 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200949 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200950 node.second = "a2";
951 }
952
953 REQUIRE(!ys.isPresenceContainer(path, node));
954 REQUIRE(!ys.isList(path, node));
955 REQUIRE(!ys.isLeaf(path, node));
956 }
957
958 SECTION("nodetype-specific methods called with different nodetypes")
959 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200960 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200961 node.second = "a2";
962
963 REQUIRE(!ys.leafEnumHasValue(path, node, "haha"));
964 REQUIRE(!ys.listHasKey(path, node, "chacha"));
965 }
966
967 SECTION("nonexistent module")
968 {
Václav Kubernát75877de2019-11-20 17:43:02 +0100969 REQUIRE(!ys.isModule("notAModule"));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200970 }
Václav Kubernáteeb38842019-03-20 19:46:05 +0100971
972 SECTION("leafIdentityIsValid")
973 {
974 ModuleValuePair value;
975 SECTION("pizzaIdentLeaf")
976 {
977 node.first = "example-schema";
978 node.second = "pizzaIdentLeaf";
979
980 SECTION("wrong base ident")
981 {
982 SECTION("food")
983 {
984 value.second = "food";
985 }
986 SECTION("fruit")
987 {
988 value.second = "fruit";
989 }
990 }
991 SECTION("non-existent identity")
992 {
993 value.second = "nonexistent";
994 }
995 SECTION("weird module")
996 {
997 value.first = "ahahaha";
998 value.second = "pizza";
999 }
1000 }
1001 SECTION("different module identity, but withotu prefix")
1002 {
1003 node.first = "example-schema";
1004 node.second = "foodIdentLeaf";
1005 value.second = "pineapple";
1006 }
1007 REQUIRE_FALSE(ys.leafIdentityIsValid(path, node, value));
1008 }
Václav Kubernát7d82da72019-04-11 15:16:38 +02001009
1010 SECTION("grouping is not a node")
1011 {
1012 SECTION("example-schema:arithmeticFlags")
1013 {
1014 node.first = "example-schema";
1015 node.second = "arithmeticFlags";
1016 }
1017
1018 SECTION("example-schema:flags")
1019 {
1020 node.first = "example-schema";
1021 node.second = "startAndStop";
1022 }
1023
1024 REQUIRE(!ys.isPresenceContainer(path, node));
1025 REQUIRE(!ys.isList(path, node));
1026 REQUIRE(!ys.isLeaf(path, node));
1027 REQUIRE(!ys.isContainer(path, node));
1028 }
Václav Kubernát280df4a2019-11-01 14:46:34 +01001029
1030 SECTION("choice is not a node")
1031 {
1032 SECTION("example-schema:interface")
1033 {
1034 node.first = "example-schema";
1035 node.second = "interface";
1036 }
1037
1038 REQUIRE(!ys.isPresenceContainer(path, node));
1039 REQUIRE(!ys.isList(path, node));
1040 REQUIRE(!ys.isLeaf(path, node));
1041 REQUIRE(!ys.isContainer(path, node));
1042 }
1043
1044 SECTION("case is not a node")
1045 {
1046 SECTION("example-schema:caseLoopback")
1047 {
1048 node.first = "example-schema";
1049 node.second = "caseLoopback";
1050 }
1051
1052 SECTION("example-schema:caseEthernet")
1053 {
1054 node.first = "example-schema";
1055 node.second = "caseEthernet";
1056 }
1057
1058 REQUIRE(!ys.isPresenceContainer(path, node));
1059 REQUIRE(!ys.isList(path, node));
1060 REQUIRE(!ys.isLeaf(path, node));
1061 REQUIRE(!ys.isContainer(path, node));
1062 }
Václav Kubernáta38d4172019-11-04 12:36:39 +01001063
1064 SECTION("enum is disabled by if-feature if feature is not enabled")
1065 {
1066 node.first = "example-schema";
1067 node.second = "pizzaSize";
1068
1069 std::string value = "large";
1070
1071 REQUIRE(!ys.leafEnumHasValue(path, node, value));
1072 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001073 }
1074}