blob: 85df37623ac031413ba0f03f0e9d2d56ac65aaf2 [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átb4e5b182020-11-16 19:55:09 +01009#include "trompeloeil_doctest.hpp"
Václav Kubernát47a3f672019-11-08 15:42:43 +010010#include <experimental/iterator>
Václav Kubernát3a99f002020-03-31 02:27:41 +020011#include "leaf_data_helpers.hpp"
Václav Kubernát1e09bd62020-02-17 15:13:38 +010012#include "pretty_printers.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
Václav Kubernát82d74632020-05-11 15:59:53 +020040const char* included_submodule = R"(
41submodule sub-module {
42 yang-version 1.1;
43
44 belongs-to example-schema {
45 prefix sub;
46 }
47
48 leaf subLeaf {
49 type string;
50 }
51}
52)";
53
Václav Kubernát4f77a252019-02-19 16:51:30 +010054const char* example_schema = R"(
Václav Kubernát0d4db442018-07-18 17:18:43 +020055module example-schema {
Václav Kubernát6a713d62018-10-03 18:47:34 +020056 yang-version 1.1;
Václav Kubernát0d4db442018-07-18 17:18:43 +020057 namespace "http://example.com/example-sports";
58 prefix coze;
59
Václav Kubernát82d74632020-05-11 15:59:53 +020060 include sub-module;
61
Václav Kubernáteeb38842019-03-20 19:46:05 +010062 identity drink {
63 }
64
65 identity voda {
66 base "drink";
67 }
68
69 identity food {
70 }
71
72 identity fruit {
73 base "food";
74 }
75
76 identity pizza {
77 base "food";
78 }
79
80 identity hawaii {
81 base "pizza";
82 }
83
Václav Kubernátfa36c822021-01-25 07:51:02 +010084 typedef foodTypedef {
85 type identityref {
86 base food;
87 }
88 }
89
90 leaf leafFoodTypedef {
91 type foodTypedef;
92 }
93
Václav Kubernát0d4db442018-07-18 17:18:43 +020094 container a {
95 container a2 {
96 container a3 {
97 presence true;
98 }
99 }
100
101 leaf leafa {
102 type string;
103 }
104 }
105
106 container b {
107 container b2 {
108 presence true;
109 container b3 {
110 }
111 }
112 }
113
114 leaf leafString {
115 type string;
116 }
117
118 leaf leafDecimal {
119 type decimal64 {
120 fraction-digits 5;
121 }
122 }
123
124 leaf leafBool {
125 type boolean;
126 }
127
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200128 leaf leafInt8 {
129 type int8;
130 }
131
132 leaf leafUint8 {
133 type uint8;
134 }
135
136 leaf leafInt16 {
137 type int16;
138 }
139
140 leaf leafUint16 {
141 type uint16;
142 }
143
144 leaf leafInt32 {
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100145 description "A 32-bit integer leaf.";
Václav Kubernát0d4db442018-07-18 17:18:43 +0200146 type int32;
147 }
148
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200149 leaf leafUint32 {
Václav Kubernát0d4db442018-07-18 17:18:43 +0200150 type uint32;
151 }
152
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200153 leaf leafInt64 {
154 type int64;
155 }
156
157 leaf leafUint64 {
158 type uint64;
Václav Kubernátb1a75c62020-04-21 15:20:16 +0200159 default 9001;
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200160 }
161
Václav Kubernát0d4db442018-07-18 17:18:43 +0200162 leaf leafEnum {
163 type enumeration {
164 enum lol;
165 enum data;
166 enum coze;
167 }
168 }
169
Václav Kubernát6a713d62018-10-03 18:47:34 +0200170 typedef enumTypedef {
171 type enumeration {
172 enum lol;
173 enum data;
174 enum coze;
175 }
Václav Kubernátb1a75c62020-04-21 15:20:16 +0200176 default data;
Václav Kubernát6a713d62018-10-03 18:47:34 +0200177 }
178
179 typedef enumTypedefRestricted {
180 type enumTypedef {
181 enum lol;
182 enum data;
183 }
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100184 description "This is a restricted enum typedef.";
Václav Kubernát6a713d62018-10-03 18:47:34 +0200185 }
186
187 leaf leafEnumTypedef {
188 type enumTypedef;
189 }
190
191 leaf leafEnumTypedefRestricted {
192 type enumTypedef {
193 enum data;
194 enum coze;
195 }
196 }
197
198 leaf leafEnumTypedefRestricted2 {
199 type enumTypedefRestricted;
200 }
201
Václav Kubernáteeb38842019-03-20 19:46:05 +0100202 leaf foodIdentLeaf {
203 type identityref {
204 base "food";
205 }
206 }
207
208 leaf pizzaIdentLeaf {
209 type identityref {
210 base "pizza";
211 }
212 }
213
214 leaf foodDrinkIdentLeaf {
215 type identityref {
216 base "food";
217 base "drink";
218 }
219 }
220
Václav Kubernát0d4db442018-07-18 17:18:43 +0200221 list _list {
222 key number;
223
224 leaf number {
225 type int32;
226 }
227
228 container contInList {
229 presence true;
230 }
231 }
232
233 list twoKeyList {
234 key "name number";
235
236 leaf number {
237 type int32;
238 }
239
240 leaf name {
241 type string;
242 }
243 }
Václav Kubernát7d82da72019-04-11 15:16:38 +0200244
245 grouping arithmeticFlags {
246 leaf carry {
247 type boolean;
248 }
249 leaf zero {
250 type boolean;
251 }
252 }
253
254 grouping flags {
255 leaf direction {
256 type boolean;
257 }
258 leaf interrupt {
259 type boolean;
260 }
261
262 uses arithmeticFlags;
263 }
264
265 uses flags;
Václav Kubernát280df4a2019-11-01 14:46:34 +0100266
267 choice interface {
268 case caseLoopback {
269 container loopback {
270 leaf ip {
271 type string;
272 }
273 }
274 }
275
276 case caseEthernet {
277 container ethernet {
278 leaf ip {
279 type string;
280 }
281 }
282 }
283 }
284
Václav Kubernáta38d4172019-11-04 12:36:39 +0100285 feature bigPizzas;
286
287 leaf pizzaSize {
288 type enumeration {
289 enum large {
290 if-feature "bigPizzas";
291 }
292 enum medium;
293 enum small;
294 }
295 }
296
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100297 leaf length {
298 type int32;
299 units "m";
300 }
301
302 leaf wavelength {
303 type decimal64 {
304 fraction-digits 10;
305 }
306 units "nm";
307 }
308
309 typedef seconds {
310 type int32;
311 units "s";
312 }
313
314 leaf duration {
315 type seconds;
316 }
317
318 leaf another-duration {
319 type seconds;
320 units "vt";
321 }
322
Václav Kubernátbd5e3c22020-02-19 15:22:00 +0100323 leaf activeNumber {
324 type leafref {
325 path "/_list/number";
326 }
327 }
328
Václav Kubernátfa81c8c2020-02-13 17:22:46 +0100329 rpc myRpc {}
330
Václav Kubernátd8408e02020-12-02 05:13:27 +0100331 rpc rpcOneOutput {
332 output {
333 leaf ahoj {
334 type string;
335 }
336 }
337 }
338
339 rpc rpcOneInput {
340 input {
341 leaf ahoj {
342 type string;
343 }
344 }
345 }
346
Václav Kubernát2984f442020-02-20 17:43:35 +0100347 leaf numberOrString {
348 type union {
349 type int32;
350 type string;
351 }
352 description "Can be an int32 or a string.";
353 }
354
355 list portSettings {
356 key "port";
357 leaf port {
358 type enumeration {
359 enum eth0;
360 enum eth1;
361 enum eth2;
362 }
363 }
Václav Kubernáta8789602020-07-20 15:18:19 +0200364 action shutdown {
365 output {
366 leaf success {
367 type boolean;
368 }
369 }
370 }
Václav Kubernát2984f442020-02-20 17:43:35 +0100371 }
372
373 feature weirdPortNames;
374
375 list portMapping {
376 key "port";
377 leaf port {
378 type enumeration {
379 enum WEIRD {
380 if-feature "weirdPortNames";
381 }
382 enum utf2;
383 enum utf3;
384 }
385 }
386 }
387
388 leaf activeMappedPort {
389 type leafref {
390 path "../portMapping/port";
391 }
392 }
393
394 leaf activePort {
395 type union {
396 type enumeration {
397 enum wlan0;
398 enum wlan1;
399 }
400 type leafref {
401 path "../portSettings/port";
402 }
403 type leafref {
404 path "../activeMappedPort";
405 }
Jan Kundrát379bb572020-05-07 03:23:13 +0200406 type empty;
Václav Kubernát2984f442020-02-20 17:43:35 +0100407 }
408 }
409
Jan Kundrát379bb572020-05-07 03:23:13 +0200410 leaf dummyLeaf {
411 type empty;
412 }
413
Václav Kubernát0599e9f2020-04-21 09:51:33 +0200414 leaf clockSpeed {
415 type int64;
416 config false;
417 }
418
419 container systemStats {
420 config false;
421 leaf upTime {
422 type uint64;
423 }
424 }
425
Václav Kubernáta1c4c9e2020-04-22 00:37:52 +0200426 leaf obsoleteLeaf {
427 type int32;
428 status obsolete;
429 }
430
431 leaf deprecatedLeaf {
432 type int32;
433 status deprecated;
434 }
435
436 typedef deprecatedType {
437 type int32;
438 status deprecated;
439 }
440
441 leaf obsoleteLeafWithDeprecatedType {
442 type deprecatedType;
443 status obsolete;
444 }
445
446 typedef obsoleteType {
447 type int32;
448 status obsolete;
449 }
450
451 leaf obsoleteLeafWithObsoleteType {
452 type deprecatedType;
453 status obsolete;
454 }
455
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200456 leaf-list addresses {
457 type string;
458 }
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100459
460 leaf flagBits {
461 type bits {
462 bit carry;
463 bit sign;
464 bit overflow;
465 }
466 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200467})";
468
469TEST_CASE("yangschema")
470{
Václav Kubernát82d74632020-05-11 15:59:53 +0200471 using namespace std::string_literals;
Václav Kubernát4f77a252019-02-19 16:51:30 +0100472 using namespace std::string_view_literals;
Václav Kubernát0d4db442018-07-18 17:18:43 +0200473 YangSchema ys;
Václav Kubernát82d74632020-05-11 15:59:53 +0200474 ys.registerModuleCallback([]([[maybe_unused]] auto modName, auto, auto subModule, auto) {
475 if (modName != "example-schema"sv) {
476 throw std::logic_error("unrecognized module "s + modName);
477 }
478 if (subModule == nullptr) {
479 return example_schema;
480 }
481 if (subModule == "sub-module"sv) {
482 return included_submodule;
483 }
484
485 throw std::logic_error("unrecognized submodule "s + subModule);
Václav Kubernát4f77a252019-02-19 16:51:30 +0100486 });
487 ys.addSchemaString(second_schema);
Václav Kubernát4841f132022-01-12 00:52:30 +0100488 ys.addSchemaString(R"(
489module schema-with-revision {
490 yang-version 1.1;
491 namespace "http://example.com/lol";
492 prefix oof;
493
494 revision "2022-01-12";
495}
496 )");
Václav Kubernát4f77a252019-02-19 16:51:30 +0100497
Václav Kubernátefcac932020-01-10 15:26:32 +0100498 schemaPath_ path{Scope::Absolute, {}};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200499 ModuleNodePair node;
500
501 SECTION("positive")
502 {
Václav Kubernát0d4db442018-07-18 17:18:43 +0200503 SECTION("isModule")
504 {
Václav Kubernát75877de2019-11-20 17:43:02 +0100505 REQUIRE(ys.isModule("example-schema"));
Václav Kubernát4841f132022-01-12 00:52:30 +0100506 REQUIRE(ys.isModule("schema-with-revision"));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200507 }
Václav Kubernáteeb38842019-03-20 19:46:05 +0100508
Václav Kubernát0d4db442018-07-18 17:18:43 +0200509 SECTION("listHasKey")
510 {
511 std::string key;
512
513 SECTION("_list")
514 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200515 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"_list"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200516 SECTION("number")
Václav Kubernát912b9492020-05-29 02:03:40 +0200517 {
518 key = "number";
519 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200520 }
521
522 SECTION("twoKeyList")
523 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200524 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"twoKeyList"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200525 SECTION("number")
Václav Kubernát912b9492020-05-29 02:03:40 +0200526 {
527 key = "number";
528 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200529 SECTION("name")
Václav Kubernát912b9492020-05-29 02:03:40 +0200530 {
531 key = "name";
532 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200533 }
534
Václav Kubernát912b9492020-05-29 02:03:40 +0200535 REQUIRE(ys.listHasKey(path, key));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200536 }
537 SECTION("listKeys")
538 {
539 std::set<std::string> set;
540
541 SECTION("_list")
542 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200543 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"_list"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200544 set = {"number"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200545 }
546
547 SECTION("twoKeyList")
548 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200549 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"twoKeyList"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200550 set = {"number", "name"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200551 }
552
Václav Kubernát912b9492020-05-29 02:03:40 +0200553 REQUIRE(ys.listKeys(path) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200554 }
555 SECTION("leafType")
556 {
Václav Kubernát3a99f002020-03-31 02:27:41 +0200557 yang::LeafDataType type;
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100558 std::optional<std::string> expectedDescription;
Václav Kubernát0d4db442018-07-18 17:18:43 +0200559
560 SECTION("leafString")
561 {
562 node.first = "example-schema";
563 node.second = "leafString";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200564 type = yang::String{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200565 }
566
567 SECTION("leafDecimal")
568 {
569 node.first = "example-schema";
570 node.second = "leafDecimal";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200571 type = yang::Decimal{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200572 }
573
574 SECTION("leafBool")
575 {
576 node.first = "example-schema";
577 node.second = "leafBool";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200578 type = yang::Bool{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200579 }
580
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200581 SECTION("leafInt8")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200582 {
583 node.first = "example-schema";
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200584 node.second = "leafInt8";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200585 type = yang::Int8{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200586 }
587
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200588 SECTION("leafUint8")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200589 {
590 node.first = "example-schema";
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200591 node.second = "leafUint8";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200592 type = yang::Uint8{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200593 }
594
Václav Kubernátb6d02752020-04-03 00:25:10 +0200595 SECTION("leafInt16")
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200596 {
597 node.first = "example-schema";
598 node.second = "leafInt16";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200599 type = yang::Int16{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200600 }
601
602 SECTION("leafUint16")
603 {
604 node.first = "example-schema";
605 node.second = "leafUint16";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200606 type = yang::Uint16{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200607 }
608
609 SECTION("leafInt32")
610 {
611 node.first = "example-schema";
612 node.second = "leafInt32";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200613 type = yang::Int32{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200614 }
615
616 SECTION("leafUint32")
617 {
618 node.first = "example-schema";
619 node.second = "leafUint32";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200620 type = yang::Uint32{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200621 }
622
623 SECTION("leafInt64")
624 {
625 node.first = "example-schema";
626 node.second = "leafInt64";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200627 type = yang::Int64{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200628 }
629
630 SECTION("leafUint64")
631 {
632 node.first = "example-schema";
633 node.second = "leafUint64";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200634 type = yang::Uint64{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200635 }
636
637 SECTION("leafEnum")
638 {
639 node.first = "example-schema";
640 node.second = "leafEnum";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200641 type = createEnum({"lol", "data", "coze"});
642 }
643
644 SECTION("leafEnumTypedef")
645 {
646 node.first = "example-schema";
647 node.second = "leafEnumTypedef";
648 type = createEnum({"lol", "data", "coze"});
649 }
650
651 SECTION("leafEnumTypedefRestricted")
652 {
653 node.first = "example-schema";
654 node.second = "leafEnumTypedefRestricted";
655 type = createEnum({"data", "coze"});
656 }
657
658 SECTION("leafEnumTypedefRestricted2")
659 {
660 node.first = "example-schema";
661 node.second = "leafEnumTypedefRestricted2";
662 type = createEnum({"lol", "data"});
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100663 expectedDescription = "This is a restricted enum typedef.";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200664 }
665
666 SECTION("pizzaSize")
667 {
668 node.first = "example-schema";
669 node.second = "pizzaSize";
670
671 SECTION("bigPizzas disabled")
672 {
673 type = createEnum({"small", "medium"});
674 }
675 SECTION("bigPizzas enabled")
676 {
677 ys.enableFeature("example-schema", "bigPizzas");
678 type = createEnum({"small", "medium", "large"});
679 }
680 }
681
682 SECTION("foodIdentLeaf")
683 {
684 node.first = "example-schema";
685 node.second = "foodIdentLeaf";
686 type = yang::IdentityRef{{{"second-schema", "pineapple"},
Václav Kubernát3a99f002020-03-31 02:27:41 +0200687 {"example-schema", "pizza"},
688 {"example-schema", "hawaii"},
689 {"example-schema", "fruit"}}};
690 }
691
692 SECTION("pizzaIdentLeaf")
693 {
694 node.first = "example-schema";
695 node.second = "pizzaIdentLeaf";
696
697 type = yang::IdentityRef{{
Václav Kubernát3a99f002020-03-31 02:27:41 +0200698 {"example-schema", "hawaii"},
699 }};
700 }
701
702 SECTION("foodDrinkIdentLeaf")
703 {
704 node.first = "example-schema";
705 node.second = "foodDrinkIdentLeaf";
706
707 type = yang::IdentityRef{{
Václav Kubernát3a99f002020-03-31 02:27:41 +0200708 {"example-schema", "fruit"},
709 {"example-schema", "hawaii"},
710 {"example-schema", "pizza"},
711 {"example-schema", "voda"},
712 {"second-schema", "pineapple"},
713 }};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200714 }
715
Václav Kubernátb6d02752020-04-03 00:25:10 +0200716 SECTION("activeNumber")
717 {
718 node.first = "example-schema";
719 node.second = "activeNumber";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200720 type.emplace<yang::LeafRef>(
721 "/example-schema:_list/number",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200722 std::make_unique<yang::TypeInfo>(ys.leafType("/example-schema:_list/number"))
Václav Kubernát3a99f002020-03-31 02:27:41 +0200723 );
Václav Kubernátb6d02752020-04-03 00:25:10 +0200724 }
725
Václav Kubernát2984f442020-02-20 17:43:35 +0100726 SECTION("activePort")
727 {
728 node.first = "example-schema";
729 node.second = "activePort";
730
Václav Kubernát1dc9e3e2020-06-09 15:22:39 +0200731 yang::Enum enums({});
732 SECTION("weird ports disabled")
733 {
734 enums = createEnum({"utf2", "utf3"});
735 }
736 SECTION("weird ports enabled")
737 {
738 ys.enableFeature("example-schema", "weirdPortNames");
739 enums = createEnum({"WEIRD", "utf2", "utf3"});
740 }
Václav Kubernát2984f442020-02-20 17:43:35 +0100741
742 type = yang::Union{{
Václav Kubernát13b23d72020-04-16 21:49:51 +0200743 yang::TypeInfo{createEnum({"wlan0", "wlan1"})},
744 yang::TypeInfo{yang::LeafRef{
Václav Kubernát2984f442020-02-20 17:43:35 +0100745 "/example-schema:portSettings/port",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200746 std::make_unique<yang::TypeInfo>(createEnum({"eth0", "eth1", "eth2"}))
747 }},
748 yang::TypeInfo{yang::LeafRef{
Václav Kubernát2984f442020-02-20 17:43:35 +0100749 "/example-schema:activeMappedPort",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200750 std::make_unique<yang::TypeInfo>(yang::LeafRef{
Václav Kubernát2984f442020-02-20 17:43:35 +0100751 "/example-schema:portMapping/port",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200752 std::make_unique<yang::TypeInfo>(enums)
753 })
754 }},
Jan Kundrát379bb572020-05-07 03:23:13 +0200755 yang::TypeInfo{yang::Empty{}},
Václav Kubernát2984f442020-02-20 17:43:35 +0100756 }};
757 }
758
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200759 SECTION("addresses")
760 {
761 node.first = "example-schema";
762 node.second = "addresses";
763 type.emplace<yang::String>();
764 }
765
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100766 SECTION("flagBits")
767 {
768 node.first = "example-schema";
769 node.second = "flagBits";
770 type = yang::Bits{{"carry", "sign", "overflow"}};
771 }
772
Václav Kubernátfa36c822021-01-25 07:51:02 +0100773 SECTION("foodTypedef")
774 {
775 node.first = "example-schema";
776 node.second = "leafFoodTypedef";
777 type = yang::IdentityRef{{
Václav Kubernátfa36c822021-01-25 07:51:02 +0100778 {"example-schema", "fruit"},
779 {"example-schema", "hawaii"},
780 {"example-schema", "pizza"},
781 {"second-schema", "pineapple"},
782 }};
783 }
784
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200785
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100786 REQUIRE(ys.leafType(path, node) == yang::TypeInfo(type, std::nullopt, expectedDescription));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200787 }
Václav Kubernát3a823f42020-04-29 23:40:21 +0200788 SECTION("availableNodes")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200789 {
Václav Kubernát3a823f42020-04-29 23:40:21 +0200790 // TODO: merge "path" and "module" sections and add recursive versions to the path section
791 SECTION("paths")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200792 {
Václav Kubernát95b08872020-04-28 01:04:17 +0200793 std::set<ModuleNodePair> set;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200794
Václav Kubernát95b08872020-04-28 01:04:17 +0200795 using namespace std::string_literals;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200796 SECTION("<root>")
797 {
Václav Kubernát95b08872020-04-28 01:04:17 +0200798 set = {{"example-schema"s, "a"}, {"example-schema"s, "b"}, {"example-schema"s, "leafString"},
799 {"example-schema"s, "leafDecimal"}, {"example-schema"s, "leafBool"},
800 {"example-schema"s, "leafInt8"}, {"example-schema"s, "leafUint8"},
801 {"example-schema"s, "leafInt16"}, {"example-schema"s, "leafUint16"},
802 {"example-schema"s, "leafInt32"}, {"example-schema"s, "leafUint32"},
803 {"example-schema"s, "leafInt64"}, {"example-schema"s, "leafUint64"},
804 {"example-schema"s, "leafEnum"}, {"example-schema"s, "leafEnumTypedef"},
805 {"example-schema"s, "leafEnumTypedefRestricted"}, {"example-schema"s, "leafEnumTypedefRestricted2"},
806 {"example-schema"s, "foodIdentLeaf"}, {"example-schema"s, "pizzaIdentLeaf"}, {"example-schema"s, "foodDrinkIdentLeaf"},
807 {"example-schema"s, "_list"}, {"example-schema"s, "twoKeyList"}, {"second-schema"s, "bla"},
808 {"example-schema"s, "carry"}, {"example-schema"s, "zero"}, {"example-schema"s, "direction"},
809 {"example-schema"s, "interrupt"},
810 {"example-schema"s, "ethernet"}, {"example-schema"s, "loopback"},
811 {"example-schema"s, "pizzaSize"},
812 {"example-schema"s, "length"}, {"example-schema"s, "wavelength"},
813 {"example-schema"s, "duration"}, {"example-schema"s, "another-duration"},
814 {"example-schema"s, "activeNumber"},
815 {"example-schema"s, "numberOrString"},
816 {"example-schema"s, "portSettings"},
817 {"example-schema"s, "portMapping"},
818 {"example-schema"s, "activeMappedPort"},
819 {"example-schema"s, "activePort"},
820 {"example-schema"s, "clockSpeed"},
821 {"example-schema"s, "deprecatedLeaf"},
822 {"example-schema"s, "obsoleteLeaf"},
823 {"example-schema"s, "obsoleteLeafWithDeprecatedType"},
824 {"example-schema"s, "obsoleteLeafWithObsoleteType"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200825 {"example-schema"s, "myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100826 {"example-schema"s, "rpcOneOutput"},
827 {"example-schema"s, "rpcOneInput"},
Václav Kubernát82d74632020-05-11 15:59:53 +0200828 {"example-schema"s, "systemStats"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200829 {"example-schema"s, "dummyLeaf"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200830 {"example-schema"s, "addresses"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100831 {"example-schema"s, "subLeaf"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100832 {"example-schema"s, "flagBits"},
833 {"example-schema"s, "leafFoodTypedef"}};
Václav Kubernát3a823f42020-04-29 23:40:21 +0200834 }
835
836 SECTION("example-schema:a")
837 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200838 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200839 set = {
840 {boost::none, "a2"},
841 {boost::none, "leafa"},
842 {"second-schema"s, "augmentedContainer"}
843 };
Václav Kubernát3a823f42020-04-29 23:40:21 +0200844 }
845
846 SECTION("example-schema:ethernet")
847 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200848 path.m_nodes.emplace_back(module_{"example-schema"}, container_("ethernet"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200849 set = {{boost::none, "ip"}};
850 }
851
852 SECTION("second-schema:bla")
853 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200854 path.m_nodes.emplace_back(module_{"second-schema"}, container_("bla"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200855 set = {{boost::none, "bla2"}};
Václav Kubernát3a823f42020-04-29 23:40:21 +0200856 }
857
858 REQUIRE(ys.availableNodes(path, Recursion::NonRecursive) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200859 }
860
Václav Kubernát3a823f42020-04-29 23:40:21 +0200861 SECTION("modules")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200862 {
Václav Kubernát3a823f42020-04-29 23:40:21 +0200863 std::string module;
Václav Kubernát95b08872020-04-28 01:04:17 +0200864 std::set<ModuleNodePair> expectedNonRecursive;
865 std::set<ModuleNodePair> expectedRecursive;
866 using namespace std::string_literals;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200867 SECTION("example-schema")
868 {
869 module = "example-schema";
870 expectedNonRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +0200871 {"example-schema"s, "_list"},
872 {"example-schema"s, "a"},
873 {"example-schema"s, "activeMappedPort"},
874 {"example-schema"s, "activeNumber"},
875 {"example-schema"s, "activePort"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200876 {"example-schema"s, "addresses"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200877 {"example-schema"s, "another-duration"},
878 {"example-schema"s, "b"},
879 {"example-schema"s, "carry"},
880 {"example-schema"s, "clockSpeed"},
881 {"example-schema"s, "deprecatedLeaf"},
882 {"example-schema"s, "direction"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200883 {"example-schema"s, "dummyLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200884 {"example-schema"s, "duration"},
885 {"example-schema"s, "ethernet"},
886 {"example-schema"s, "foodDrinkIdentLeaf"},
887 {"example-schema"s, "foodIdentLeaf"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100888 {"example-schema"s, "flagBits"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200889 {"example-schema"s, "interrupt"},
890 {"example-schema"s, "leafBool"},
891 {"example-schema"s, "leafDecimal"},
892 {"example-schema"s, "leafEnum"},
893 {"example-schema"s, "leafEnumTypedef"},
894 {"example-schema"s, "leafEnumTypedefRestricted"},
895 {"example-schema"s, "leafEnumTypedefRestricted2"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100896 {"example-schema"s, "leafFoodTypedef"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200897 {"example-schema"s, "leafInt16"},
898 {"example-schema"s, "leafInt32"},
899 {"example-schema"s, "leafInt64"},
900 {"example-schema"s, "leafInt8"},
901 {"example-schema"s, "leafString"},
902 {"example-schema"s, "leafUint16"},
903 {"example-schema"s, "leafUint32"},
904 {"example-schema"s, "leafUint64"},
905 {"example-schema"s, "leafUint8"},
906 {"example-schema"s, "length"},
907 {"example-schema"s, "loopback"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200908 {"example-schema"s, "myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100909 {"example-schema"s, "rpcOneOutput"},
910 {"example-schema"s, "rpcOneInput"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200911 {"example-schema"s, "numberOrString"},
912 {"example-schema"s, "obsoleteLeaf"},
913 {"example-schema"s, "obsoleteLeafWithDeprecatedType"},
914 {"example-schema"s, "obsoleteLeafWithObsoleteType"},
915 {"example-schema"s, "pizzaIdentLeaf"},
916 {"example-schema"s, "pizzaSize"},
917 {"example-schema"s, "portMapping"},
918 {"example-schema"s, "portSettings"},
919 {"example-schema"s, "systemStats"},
920 {"example-schema"s, "twoKeyList"},
921 {"example-schema"s, "wavelength"},
Václav Kubernát82d74632020-05-11 15:59:53 +0200922 {"example-schema"s, "zero"},
923 {"example-schema"s, "subLeaf"}
Václav Kubernát3a823f42020-04-29 23:40:21 +0200924 };
925 expectedRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +0200926 {boost::none, "/example-schema:_list"},
927 {boost::none, "/example-schema:_list/contInList"},
928 {boost::none, "/example-schema:_list/number"},
929 {boost::none, "/example-schema:a"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200930 {boost::none, "/example-schema:addresses"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200931 {boost::none, "/example-schema:a/a2"},
932 {boost::none, "/example-schema:a/a2/a3"},
933 {boost::none, "/example-schema:a/leafa"},
934 {boost::none, "/example-schema:a/second-schema:augmentedContainer"},
935 {boost::none, "/example-schema:activeMappedPort"},
936 {boost::none, "/example-schema:activeNumber"},
937 {boost::none, "/example-schema:activePort"},
938 {boost::none, "/example-schema:another-duration"},
939 {boost::none, "/example-schema:b"},
940 {boost::none, "/example-schema:b/b2"},
941 {boost::none, "/example-schema:b/b2/b3"},
942 {boost::none, "/example-schema:carry"},
943 {boost::none, "/example-schema:clockSpeed"},
944 {boost::none, "/example-schema:deprecatedLeaf"},
945 {boost::none, "/example-schema:direction"},
946 {boost::none, "/example-schema:duration"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200947 {boost::none, "/example-schema:dummyLeaf"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100948 {boost::none, "/example-schema:flagBits"},
949 {boost::none, "/example-schema:foodDrinkIdentLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200950 {boost::none, "/example-schema:foodDrinkIdentLeaf"},
951 {boost::none, "/example-schema:foodIdentLeaf"},
952 {boost::none, "/example-schema:interface/caseEthernet/ethernet"},
953 {boost::none, "/example-schema:interface/caseEthernet/ethernet/ip"},
954 {boost::none, "/example-schema:interface/caseLoopback/loopback"},
955 {boost::none, "/example-schema:interface/caseLoopback/loopback/ip"},
956 {boost::none, "/example-schema:interrupt"},
957 {boost::none, "/example-schema:leafBool"},
958 {boost::none, "/example-schema:leafDecimal"},
959 {boost::none, "/example-schema:leafEnum"},
960 {boost::none, "/example-schema:leafEnumTypedef"},
961 {boost::none, "/example-schema:leafEnumTypedefRestricted"},
962 {boost::none, "/example-schema:leafEnumTypedefRestricted2"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100963 {boost::none, "/example-schema:leafFoodTypedef"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200964 {boost::none, "/example-schema:leafInt16"},
965 {boost::none, "/example-schema:leafInt32"},
966 {boost::none, "/example-schema:leafInt64"},
967 {boost::none, "/example-schema:leafInt8"},
968 {boost::none, "/example-schema:leafString"},
969 {boost::none, "/example-schema:leafUint16"},
970 {boost::none, "/example-schema:leafUint32"},
971 {boost::none, "/example-schema:leafUint64"},
972 {boost::none, "/example-schema:leafUint8"},
973 {boost::none, "/example-schema:length"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200974 {boost::none, "/example-schema:myRpc"},
975 {boost::none, "/example-schema:myRpc/input"},
976 {boost::none, "/example-schema:myRpc/output"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100977 {boost::none, "/example-schema:rpcOneOutput"},
978 {boost::none, "/example-schema:rpcOneOutput/input"},
979 {boost::none, "/example-schema:rpcOneOutput/output"},
980 {boost::none, "/example-schema:rpcOneOutput/output/ahoj"},
981 {boost::none, "/example-schema:rpcOneInput"},
982 {boost::none, "/example-schema:rpcOneInput/input"},
983 {boost::none, "/example-schema:rpcOneInput/input/ahoj"},
984 {boost::none, "/example-schema:rpcOneInput/output"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200985 {boost::none, "/example-schema:numberOrString"},
986 {boost::none, "/example-schema:obsoleteLeaf"},
987 {boost::none, "/example-schema:obsoleteLeafWithDeprecatedType"},
988 {boost::none, "/example-schema:obsoleteLeafWithObsoleteType"},
989 {boost::none, "/example-schema:pizzaIdentLeaf"},
990 {boost::none, "/example-schema:pizzaSize"},
991 {boost::none, "/example-schema:portMapping"},
992 {boost::none, "/example-schema:portMapping/port"},
993 {boost::none, "/example-schema:portSettings"},
994 {boost::none, "/example-schema:portSettings/port"},
Václav Kubernáta8789602020-07-20 15:18:19 +0200995 {boost::none, "/example-schema:portSettings/shutdown"},
996 {boost::none, "/example-schema:portSettings/shutdown/input"},
997 {boost::none, "/example-schema:portSettings/shutdown/output"},
998 {boost::none, "/example-schema:portSettings/shutdown/output/success"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200999 {boost::none, "/example-schema:systemStats"},
1000 {boost::none, "/example-schema:systemStats/upTime"},
Václav Kubernát82d74632020-05-11 15:59:53 +02001001 {boost::none, "/example-schema:subLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +02001002 {boost::none, "/example-schema:twoKeyList"},
1003 {boost::none, "/example-schema:twoKeyList/name"},
1004 {boost::none, "/example-schema:twoKeyList/number"},
1005 {boost::none, "/example-schema:wavelength"},
1006 {boost::none, "/example-schema:zero"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001007 };
1008 }
Václav Kubernát3a823f42020-04-29 23:40:21 +02001009 SECTION("second-schema")
1010 {
1011 module = "second-schema";
1012 expectedNonRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +02001013 {"second-schema"s, "bla"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001014 };
1015 expectedRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +02001016 {boost::none, "/second-schema:bla"},
1017 {boost::none, "/second-schema:bla/bla2"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001018 };
1019 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001020
Václav Kubernát3a823f42020-04-29 23:40:21 +02001021 REQUIRE(ys.availableNodes(module_{module}, Recursion::NonRecursive) == expectedNonRecursive);
1022 REQUIRE(ys.availableNodes(module_{module}, Recursion::Recursive) == expectedRecursive);
Václav Kubernát47a3f672019-11-08 15:42:43 +01001023 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001024 }
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001025 SECTION("nodeType")
1026 {
1027 yang::NodeTypes expected;
1028 SECTION("leafInt32")
1029 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001030 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001031 expected = yang::NodeTypes::Leaf;
1032 }
1033
1034 SECTION("a")
1035 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001036 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001037 expected = yang::NodeTypes::Container;
1038 }
1039
1040 SECTION("a/a2/a3")
1041 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001042 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1043 path.m_nodes.emplace_back(container_("a2"));
1044 path.m_nodes.emplace_back(container_("a3"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001045 expected = yang::NodeTypes::PresenceContainer;
1046 }
1047
1048 SECTION("_list")
1049 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001050 path.m_nodes.emplace_back(module_{"example-schema"}, list_("_list"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001051 expected = yang::NodeTypes::List;
1052 }
1053
Václav Kubernát82d74632020-05-11 15:59:53 +02001054 SECTION("subLeaf")
1055 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001056 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("subLeaf"));
Václav Kubernát82d74632020-05-11 15:59:53 +02001057 expected = yang::NodeTypes::Leaf;
1058 }
1059
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001060 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1061 }
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001062
1063 SECTION("description")
1064 {
1065 std::optional<std::string> expected;
1066 SECTION("leafInt32")
1067 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001068 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001069 expected = "A 32-bit integer leaf.";
1070 }
1071
1072 SECTION("leafString")
1073 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001074 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafString"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001075 }
1076
Václav Kubernát2984f442020-02-20 17:43:35 +01001077 SECTION("numberOrString")
1078 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001079 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("numberOrString"));
Václav Kubernát2984f442020-02-20 17:43:35 +01001080 expected = "Can be an int32 or a string.";
1081 }
1082
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001083 REQUIRE(ys.description(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1084 }
1085
Václav Kubernáta1c4c9e2020-04-22 00:37:52 +02001086 SECTION("status")
1087 {
1088 REQUIRE(ys.status("/example-schema:leafUint64") == yang::Status::Current);
1089 REQUIRE(ys.status("/example-schema:obsoleteLeaf") == yang::Status::Obsolete);
1090 REQUIRE(ys.status("/example-schema:deprecatedLeaf") == yang::Status::Deprecated);
1091 REQUIRE(ys.status("/example-schema:obsoleteLeafWithDeprecatedType") == yang::Status::Obsolete);
1092 REQUIRE(ys.status("/example-schema:obsoleteLeafWithObsoleteType") == yang::Status::Obsolete);
1093 }
1094
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001095 SECTION("units")
1096 {
Václav Kubernát13b23d72020-04-16 21:49:51 +02001097 yang::LeafDataType expectedType;
1098 std::optional<std::string> expectedUnits;
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001099 SECTION("length")
1100 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001101 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("length"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001102 expectedType.emplace<yang::Int32>();
1103 expectedUnits = "m";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001104 }
1105
1106 SECTION("wavelength")
1107 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001108 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("wavelength"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001109 expectedType.emplace<yang::Decimal>();
1110 expectedUnits = "nm";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001111 }
1112
1113 SECTION("leafInt32")
1114 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001115 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001116 expectedType.emplace<yang::Int32>();
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001117 }
1118
1119 SECTION("duration")
1120 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001121 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("duration"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001122 expectedType.emplace<yang::Int32>();
1123 expectedUnits = "s";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001124 }
1125
1126 SECTION("another-duration")
1127 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001128 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("another-duration"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001129 expectedType.emplace<yang::Int32>();
1130 expectedUnits = "vt";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001131 }
Václav Kubernát5b8a8f32020-05-20 00:57:22 +02001132 auto nodeType = ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded));
1133 REQUIRE((nodeType == yang::NodeTypes::Leaf || nodeType == yang::NodeTypes::LeafList));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001134 REQUIRE(ys.leafType(pathToSchemaString(path, Prefixes::WhenNeeded)) == yang::TypeInfo{expectedType, expectedUnits});
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001135 }
1136
Václav Kubernát1ae24f42020-12-01 02:32:04 +01001137 SECTION("type description")
1138 {
1139 yang::LeafDataType expectedType = createEnum({"lol", "data"});
1140 std::optional<std::string> expectedDescription;
1141
1142 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafEnumTypedefRestricted2"));
1143 expectedDescription = "This is a restricted enum typedef.";
1144 REQUIRE(ys.leafType(pathToSchemaString(path, Prefixes::WhenNeeded)) == yang::TypeInfo{expectedType, std::nullopt, expectedDescription});
1145 }
1146
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001147 SECTION("nodeType")
1148 {
1149 yang::NodeTypes expected;
1150 SECTION("leafInt32")
1151 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001152 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001153 expected = yang::NodeTypes::Leaf;
1154 }
1155
1156 SECTION("a")
1157 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001158 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001159 expected = yang::NodeTypes::Container;
1160 }
1161
1162 SECTION("a/a2/a3")
1163 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001164 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1165 path.m_nodes.emplace_back(container_("a2"));
1166 path.m_nodes.emplace_back(container_("a3"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001167 expected = yang::NodeTypes::PresenceContainer;
1168 }
1169
1170 SECTION("_list")
1171 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001172 path.m_nodes.emplace_back(module_{"example-schema"}, list_("_list"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001173 expected = yang::NodeTypes::List;
1174 }
1175
1176 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1177 }
Václav Kubernátbd5e3c22020-02-19 15:22:00 +01001178
1179 SECTION("leafrefPath")
1180 {
1181 REQUIRE(ys.leafrefPath("/example-schema:activeNumber") == "/example-schema:_list/number");
1182 }
Václav Kubernát0599e9f2020-04-21 09:51:33 +02001183
1184 SECTION("isConfig")
1185 {
1186 REQUIRE(ys.isConfig("/example-schema:leafInt32"));
1187 REQUIRE_FALSE(ys.isConfig("/example-schema:clockSpeed"));
1188 REQUIRE_FALSE(ys.isConfig("/example-schema:systemStats"));
1189 REQUIRE_FALSE(ys.isConfig("/example-schema:systemStats/upTime"));
1190 }
Václav Kubernátbd0d5c82020-04-21 10:22:03 +02001191
Václav Kubernátb1a75c62020-04-21 15:20:16 +02001192 SECTION("defaultValue")
1193 {
1194 REQUIRE(ys.defaultValue("/example-schema:leafUint64") == "9001");
1195 REQUIRE(ys.defaultValue("/example-schema:leafEnumTypedefRestricted") == "data");
1196 REQUIRE(ys.defaultValue("/example-schema:leafInt32") == std::nullopt);
1197 }
1198
Václav Kubernát76ba4ec2020-05-18 13:26:56 +02001199 SECTION("leafTypeName")
1200 {
1201 REQUIRE(ys.leafTypeName("/example-schema:leafEnumTypedefRestricted") == "enumTypedef");
1202 REQUIRE(ys.leafTypeName("/example-schema:leafInt32") == std::nullopt);
1203 }
Václav Kubernáta8789602020-07-20 15:18:19 +02001204
1205 SECTION("dataPathToSchemaPath")
1206 {
1207 REQUIRE(ys.dataPathToSchemaPath("/example-schema:portSettings[port='eth0']") == "/example-schema:portSettings");
1208 REQUIRE(ys.dataPathToSchemaPath("/example-schema:portSettings[port='eth0']/shutdown") == "/example-schema:portSettings/shutdown");
1209 }
Václav Kubernátd8408e02020-12-02 05:13:27 +01001210
1211 SECTION("has input nodes")
1212 {
1213 bool expected;
1214 SECTION("example-schema:myRpc")
1215 {
1216 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"myRpc"});
1217 expected = false;
1218 }
1219
1220 SECTION("example-schema:rpcOneInput")
1221 {
1222 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"rpcOneInput"});
1223 expected = true;
1224 }
1225
1226 SECTION("example-schema:rpcOneOutput")
1227 {
1228 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"rpcOneOutput"});
1229 expected = false;
1230 }
1231
1232 REQUIRE(ys.hasInputNodes(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1233 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001234 }
1235
1236 SECTION("negative")
1237 {
1238 SECTION("nonexistent nodes")
1239 {
1240 SECTION("example-schema:coze")
1241 {
1242 node.first = "example-schema";
1243 node.second = "coze";
1244 }
1245
1246 SECTION("example-schema:a/nevim")
1247 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001248 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001249 node.second = "nevim";
1250 }
1251
1252 SECTION("modul:a/nevim")
1253 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001254 path.m_nodes.emplace_back(module_{"modul"}, container_("a"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001255 node.second = "nevim";
1256 }
1257
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001258 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001259 }
1260
1261 SECTION("nodetype-specific methods called with different nodetypes")
1262 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001263 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1264 path.m_nodes.emplace_back(container_("a2"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001265
Václav Kubernát912b9492020-05-29 02:03:40 +02001266 REQUIRE(!ys.listHasKey(path, "chacha"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001267 }
1268
1269 SECTION("nonexistent module")
1270 {
Václav Kubernát75877de2019-11-20 17:43:02 +01001271 REQUIRE(!ys.isModule("notAModule"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001272 }
Václav Kubernáteeb38842019-03-20 19:46:05 +01001273
Václav Kubernát7d82da72019-04-11 15:16:38 +02001274 SECTION("grouping is not a node")
1275 {
1276 SECTION("example-schema:arithmeticFlags")
1277 {
1278 node.first = "example-schema";
1279 node.second = "arithmeticFlags";
1280 }
1281
1282 SECTION("example-schema:flags")
1283 {
1284 node.first = "example-schema";
1285 node.second = "startAndStop";
1286 }
1287
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001288 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát7d82da72019-04-11 15:16:38 +02001289 }
Václav Kubernát280df4a2019-11-01 14:46:34 +01001290
1291 SECTION("choice is not a node")
1292 {
1293 SECTION("example-schema:interface")
1294 {
1295 node.first = "example-schema";
1296 node.second = "interface";
1297 }
1298
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001299 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát280df4a2019-11-01 14:46:34 +01001300 }
1301
1302 SECTION("case is not a node")
1303 {
1304 SECTION("example-schema:caseLoopback")
1305 {
1306 node.first = "example-schema";
1307 node.second = "caseLoopback";
1308 }
1309
1310 SECTION("example-schema:caseEthernet")
1311 {
1312 node.first = "example-schema";
1313 node.second = "caseEthernet";
1314 }
1315
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001316 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát280df4a2019-11-01 14:46:34 +01001317 }
Václav Kubernátf44bdda2020-06-22 15:58:41 +02001318
1319 SECTION("enableFeature - non existing module")
1320 {
1321 REQUIRE_THROWS_AS(ys.enableFeature("non-existing", "just-no"), std::runtime_error);
1322 }
Václav Kubernát7aaf6dc2020-06-26 18:03:57 +02001323
1324 SECTION("enableFeature - non existing feature")
1325 {
1326 REQUIRE_THROWS_AS(ys.enableFeature("example-schema", "just-no"), std::runtime_error);
1327 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001328 }
1329}