blob: 37b473da28c203a14b7a35642b9bd26f5b7aa53e [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);
488
Václav Kubernátefcac932020-01-10 15:26:32 +0100489 schemaPath_ path{Scope::Absolute, {}};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200490 ModuleNodePair node;
491
492 SECTION("positive")
493 {
Václav Kubernát0d4db442018-07-18 17:18:43 +0200494 SECTION("isModule")
495 {
Václav Kubernát75877de2019-11-20 17:43:02 +0100496 REQUIRE(ys.isModule("example-schema"));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200497 }
Václav Kubernáteeb38842019-03-20 19:46:05 +0100498
Václav Kubernát0d4db442018-07-18 17:18:43 +0200499 SECTION("listHasKey")
500 {
501 std::string key;
502
503 SECTION("_list")
504 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200505 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"_list"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200506 SECTION("number")
Václav Kubernát912b9492020-05-29 02:03:40 +0200507 {
508 key = "number";
509 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200510 }
511
512 SECTION("twoKeyList")
513 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200514 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"twoKeyList"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200515 SECTION("number")
Václav Kubernát912b9492020-05-29 02:03:40 +0200516 {
517 key = "number";
518 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200519 SECTION("name")
Václav Kubernát912b9492020-05-29 02:03:40 +0200520 {
521 key = "name";
522 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200523 }
524
Václav Kubernát912b9492020-05-29 02:03:40 +0200525 REQUIRE(ys.listHasKey(path, key));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200526 }
527 SECTION("listKeys")
528 {
529 std::set<std::string> set;
530
531 SECTION("_list")
532 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200533 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"_list"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200534 set = {"number"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200535 }
536
537 SECTION("twoKeyList")
538 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200539 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"twoKeyList"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200540 set = {"number", "name"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200541 }
542
Václav Kubernát912b9492020-05-29 02:03:40 +0200543 REQUIRE(ys.listKeys(path) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200544 }
545 SECTION("leafType")
546 {
Václav Kubernát3a99f002020-03-31 02:27:41 +0200547 yang::LeafDataType type;
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100548 std::optional<std::string> expectedDescription;
Václav Kubernát0d4db442018-07-18 17:18:43 +0200549
550 SECTION("leafString")
551 {
552 node.first = "example-schema";
553 node.second = "leafString";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200554 type = yang::String{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200555 }
556
557 SECTION("leafDecimal")
558 {
559 node.first = "example-schema";
560 node.second = "leafDecimal";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200561 type = yang::Decimal{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200562 }
563
564 SECTION("leafBool")
565 {
566 node.first = "example-schema";
567 node.second = "leafBool";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200568 type = yang::Bool{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200569 }
570
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200571 SECTION("leafInt8")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200572 {
573 node.first = "example-schema";
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200574 node.second = "leafInt8";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200575 type = yang::Int8{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200576 }
577
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200578 SECTION("leafUint8")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200579 {
580 node.first = "example-schema";
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200581 node.second = "leafUint8";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200582 type = yang::Uint8{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200583 }
584
Václav Kubernátb6d02752020-04-03 00:25:10 +0200585 SECTION("leafInt16")
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200586 {
587 node.first = "example-schema";
588 node.second = "leafInt16";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200589 type = yang::Int16{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200590 }
591
592 SECTION("leafUint16")
593 {
594 node.first = "example-schema";
595 node.second = "leafUint16";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200596 type = yang::Uint16{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200597 }
598
599 SECTION("leafInt32")
600 {
601 node.first = "example-schema";
602 node.second = "leafInt32";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200603 type = yang::Int32{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200604 }
605
606 SECTION("leafUint32")
607 {
608 node.first = "example-schema";
609 node.second = "leafUint32";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200610 type = yang::Uint32{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200611 }
612
613 SECTION("leafInt64")
614 {
615 node.first = "example-schema";
616 node.second = "leafInt64";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200617 type = yang::Int64{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200618 }
619
620 SECTION("leafUint64")
621 {
622 node.first = "example-schema";
623 node.second = "leafUint64";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200624 type = yang::Uint64{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200625 }
626
627 SECTION("leafEnum")
628 {
629 node.first = "example-schema";
630 node.second = "leafEnum";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200631 type = createEnum({"lol", "data", "coze"});
632 }
633
634 SECTION("leafEnumTypedef")
635 {
636 node.first = "example-schema";
637 node.second = "leafEnumTypedef";
638 type = createEnum({"lol", "data", "coze"});
639 }
640
641 SECTION("leafEnumTypedefRestricted")
642 {
643 node.first = "example-schema";
644 node.second = "leafEnumTypedefRestricted";
645 type = createEnum({"data", "coze"});
646 }
647
648 SECTION("leafEnumTypedefRestricted2")
649 {
650 node.first = "example-schema";
651 node.second = "leafEnumTypedefRestricted2";
652 type = createEnum({"lol", "data"});
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100653 expectedDescription = "This is a restricted enum typedef.";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200654 }
655
656 SECTION("pizzaSize")
657 {
658 node.first = "example-schema";
659 node.second = "pizzaSize";
660
661 SECTION("bigPizzas disabled")
662 {
663 type = createEnum({"small", "medium"});
664 }
665 SECTION("bigPizzas enabled")
666 {
667 ys.enableFeature("example-schema", "bigPizzas");
668 type = createEnum({"small", "medium", "large"});
669 }
670 }
671
672 SECTION("foodIdentLeaf")
673 {
674 node.first = "example-schema";
675 node.second = "foodIdentLeaf";
676 type = yang::IdentityRef{{{"second-schema", "pineapple"},
677 {"example-schema", "food"},
678 {"example-schema", "pizza"},
679 {"example-schema", "hawaii"},
680 {"example-schema", "fruit"}}};
681 }
682
683 SECTION("pizzaIdentLeaf")
684 {
685 node.first = "example-schema";
686 node.second = "pizzaIdentLeaf";
687
688 type = yang::IdentityRef{{
689 {"example-schema", "pizza"},
690 {"example-schema", "hawaii"},
691 }};
692 }
693
694 SECTION("foodDrinkIdentLeaf")
695 {
696 node.first = "example-schema";
697 node.second = "foodDrinkIdentLeaf";
698
699 type = yang::IdentityRef{{
700 {"example-schema", "food"},
701 {"example-schema", "drink"},
702 {"example-schema", "fruit"},
703 {"example-schema", "hawaii"},
704 {"example-schema", "pizza"},
705 {"example-schema", "voda"},
706 {"second-schema", "pineapple"},
707 }};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200708 }
709
Václav Kubernátb6d02752020-04-03 00:25:10 +0200710 SECTION("activeNumber")
711 {
712 node.first = "example-schema";
713 node.second = "activeNumber";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200714 type.emplace<yang::LeafRef>(
715 "/example-schema:_list/number",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200716 std::make_unique<yang::TypeInfo>(ys.leafType("/example-schema:_list/number"))
Václav Kubernát3a99f002020-03-31 02:27:41 +0200717 );
Václav Kubernátb6d02752020-04-03 00:25:10 +0200718 }
719
Václav Kubernát2984f442020-02-20 17:43:35 +0100720 SECTION("activePort")
721 {
722 node.first = "example-schema";
723 node.second = "activePort";
724
Václav Kubernát1dc9e3e2020-06-09 15:22:39 +0200725 yang::Enum enums({});
726 SECTION("weird ports disabled")
727 {
728 enums = createEnum({"utf2", "utf3"});
729 }
730 SECTION("weird ports enabled")
731 {
732 ys.enableFeature("example-schema", "weirdPortNames");
733 enums = createEnum({"WEIRD", "utf2", "utf3"});
734 }
Václav Kubernát2984f442020-02-20 17:43:35 +0100735
736 type = yang::Union{{
Václav Kubernát13b23d72020-04-16 21:49:51 +0200737 yang::TypeInfo{createEnum({"wlan0", "wlan1"})},
738 yang::TypeInfo{yang::LeafRef{
Václav Kubernát2984f442020-02-20 17:43:35 +0100739 "/example-schema:portSettings/port",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200740 std::make_unique<yang::TypeInfo>(createEnum({"eth0", "eth1", "eth2"}))
741 }},
742 yang::TypeInfo{yang::LeafRef{
Václav Kubernát2984f442020-02-20 17:43:35 +0100743 "/example-schema:activeMappedPort",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200744 std::make_unique<yang::TypeInfo>(yang::LeafRef{
Václav Kubernát2984f442020-02-20 17:43:35 +0100745 "/example-schema:portMapping/port",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200746 std::make_unique<yang::TypeInfo>(enums)
747 })
748 }},
Jan Kundrát379bb572020-05-07 03:23:13 +0200749 yang::TypeInfo{yang::Empty{}},
Václav Kubernát2984f442020-02-20 17:43:35 +0100750 }};
751 }
752
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200753 SECTION("addresses")
754 {
755 node.first = "example-schema";
756 node.second = "addresses";
757 type.emplace<yang::String>();
758 }
759
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100760 SECTION("flagBits")
761 {
762 node.first = "example-schema";
763 node.second = "flagBits";
764 type = yang::Bits{{"carry", "sign", "overflow"}};
765 }
766
Václav Kubernátfa36c822021-01-25 07:51:02 +0100767 SECTION("foodTypedef")
768 {
769 node.first = "example-schema";
770 node.second = "leafFoodTypedef";
771 type = yang::IdentityRef{{
772 {"example-schema", "food"},
773 {"example-schema", "fruit"},
774 {"example-schema", "hawaii"},
775 {"example-schema", "pizza"},
776 {"second-schema", "pineapple"},
777 }};
778 }
779
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200780
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100781 REQUIRE(ys.leafType(path, node) == yang::TypeInfo(type, std::nullopt, expectedDescription));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200782 }
Václav Kubernát3a823f42020-04-29 23:40:21 +0200783 SECTION("availableNodes")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200784 {
Václav Kubernát3a823f42020-04-29 23:40:21 +0200785 // TODO: merge "path" and "module" sections and add recursive versions to the path section
786 SECTION("paths")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200787 {
Václav Kubernát95b08872020-04-28 01:04:17 +0200788 std::set<ModuleNodePair> set;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200789
Václav Kubernát95b08872020-04-28 01:04:17 +0200790 using namespace std::string_literals;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200791 SECTION("<root>")
792 {
Václav Kubernát95b08872020-04-28 01:04:17 +0200793 set = {{"example-schema"s, "a"}, {"example-schema"s, "b"}, {"example-schema"s, "leafString"},
794 {"example-schema"s, "leafDecimal"}, {"example-schema"s, "leafBool"},
795 {"example-schema"s, "leafInt8"}, {"example-schema"s, "leafUint8"},
796 {"example-schema"s, "leafInt16"}, {"example-schema"s, "leafUint16"},
797 {"example-schema"s, "leafInt32"}, {"example-schema"s, "leafUint32"},
798 {"example-schema"s, "leafInt64"}, {"example-schema"s, "leafUint64"},
799 {"example-schema"s, "leafEnum"}, {"example-schema"s, "leafEnumTypedef"},
800 {"example-schema"s, "leafEnumTypedefRestricted"}, {"example-schema"s, "leafEnumTypedefRestricted2"},
801 {"example-schema"s, "foodIdentLeaf"}, {"example-schema"s, "pizzaIdentLeaf"}, {"example-schema"s, "foodDrinkIdentLeaf"},
802 {"example-schema"s, "_list"}, {"example-schema"s, "twoKeyList"}, {"second-schema"s, "bla"},
803 {"example-schema"s, "carry"}, {"example-schema"s, "zero"}, {"example-schema"s, "direction"},
804 {"example-schema"s, "interrupt"},
805 {"example-schema"s, "ethernet"}, {"example-schema"s, "loopback"},
806 {"example-schema"s, "pizzaSize"},
807 {"example-schema"s, "length"}, {"example-schema"s, "wavelength"},
808 {"example-schema"s, "duration"}, {"example-schema"s, "another-duration"},
809 {"example-schema"s, "activeNumber"},
810 {"example-schema"s, "numberOrString"},
811 {"example-schema"s, "portSettings"},
812 {"example-schema"s, "portMapping"},
813 {"example-schema"s, "activeMappedPort"},
814 {"example-schema"s, "activePort"},
815 {"example-schema"s, "clockSpeed"},
816 {"example-schema"s, "deprecatedLeaf"},
817 {"example-schema"s, "obsoleteLeaf"},
818 {"example-schema"s, "obsoleteLeafWithDeprecatedType"},
819 {"example-schema"s, "obsoleteLeafWithObsoleteType"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200820 {"example-schema"s, "myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100821 {"example-schema"s, "rpcOneOutput"},
822 {"example-schema"s, "rpcOneInput"},
Václav Kubernát82d74632020-05-11 15:59:53 +0200823 {"example-schema"s, "systemStats"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200824 {"example-schema"s, "dummyLeaf"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200825 {"example-schema"s, "addresses"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100826 {"example-schema"s, "subLeaf"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100827 {"example-schema"s, "flagBits"},
828 {"example-schema"s, "leafFoodTypedef"}};
Václav Kubernát3a823f42020-04-29 23:40:21 +0200829 }
830
831 SECTION("example-schema:a")
832 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200833 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200834 set = {
835 {boost::none, "a2"},
836 {boost::none, "leafa"},
837 {"second-schema"s, "augmentedContainer"}
838 };
Václav Kubernát3a823f42020-04-29 23:40:21 +0200839 }
840
841 SECTION("example-schema:ethernet")
842 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200843 path.m_nodes.emplace_back(module_{"example-schema"}, container_("ethernet"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200844 set = {{boost::none, "ip"}};
845 }
846
847 SECTION("second-schema:bla")
848 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200849 path.m_nodes.emplace_back(module_{"second-schema"}, container_("bla"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200850 set = {{boost::none, "bla2"}};
Václav Kubernát3a823f42020-04-29 23:40:21 +0200851 }
852
853 REQUIRE(ys.availableNodes(path, Recursion::NonRecursive) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200854 }
855
Václav Kubernát3a823f42020-04-29 23:40:21 +0200856 SECTION("modules")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200857 {
Václav Kubernát3a823f42020-04-29 23:40:21 +0200858 std::string module;
Václav Kubernát95b08872020-04-28 01:04:17 +0200859 std::set<ModuleNodePair> expectedNonRecursive;
860 std::set<ModuleNodePair> expectedRecursive;
861 using namespace std::string_literals;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200862 SECTION("example-schema")
863 {
864 module = "example-schema";
865 expectedNonRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +0200866 {"example-schema"s, "_list"},
867 {"example-schema"s, "a"},
868 {"example-schema"s, "activeMappedPort"},
869 {"example-schema"s, "activeNumber"},
870 {"example-schema"s, "activePort"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200871 {"example-schema"s, "addresses"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200872 {"example-schema"s, "another-duration"},
873 {"example-schema"s, "b"},
874 {"example-schema"s, "carry"},
875 {"example-schema"s, "clockSpeed"},
876 {"example-schema"s, "deprecatedLeaf"},
877 {"example-schema"s, "direction"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200878 {"example-schema"s, "dummyLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200879 {"example-schema"s, "duration"},
880 {"example-schema"s, "ethernet"},
881 {"example-schema"s, "foodDrinkIdentLeaf"},
882 {"example-schema"s, "foodIdentLeaf"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100883 {"example-schema"s, "flagBits"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200884 {"example-schema"s, "interrupt"},
885 {"example-schema"s, "leafBool"},
886 {"example-schema"s, "leafDecimal"},
887 {"example-schema"s, "leafEnum"},
888 {"example-schema"s, "leafEnumTypedef"},
889 {"example-schema"s, "leafEnumTypedefRestricted"},
890 {"example-schema"s, "leafEnumTypedefRestricted2"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100891 {"example-schema"s, "leafFoodTypedef"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200892 {"example-schema"s, "leafInt16"},
893 {"example-schema"s, "leafInt32"},
894 {"example-schema"s, "leafInt64"},
895 {"example-schema"s, "leafInt8"},
896 {"example-schema"s, "leafString"},
897 {"example-schema"s, "leafUint16"},
898 {"example-schema"s, "leafUint32"},
899 {"example-schema"s, "leafUint64"},
900 {"example-schema"s, "leafUint8"},
901 {"example-schema"s, "length"},
902 {"example-schema"s, "loopback"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200903 {"example-schema"s, "myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100904 {"example-schema"s, "rpcOneOutput"},
905 {"example-schema"s, "rpcOneInput"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200906 {"example-schema"s, "numberOrString"},
907 {"example-schema"s, "obsoleteLeaf"},
908 {"example-schema"s, "obsoleteLeafWithDeprecatedType"},
909 {"example-schema"s, "obsoleteLeafWithObsoleteType"},
910 {"example-schema"s, "pizzaIdentLeaf"},
911 {"example-schema"s, "pizzaSize"},
912 {"example-schema"s, "portMapping"},
913 {"example-schema"s, "portSettings"},
914 {"example-schema"s, "systemStats"},
915 {"example-schema"s, "twoKeyList"},
916 {"example-schema"s, "wavelength"},
Václav Kubernát82d74632020-05-11 15:59:53 +0200917 {"example-schema"s, "zero"},
918 {"example-schema"s, "subLeaf"}
Václav Kubernát3a823f42020-04-29 23:40:21 +0200919 };
920 expectedRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +0200921 {boost::none, "/example-schema:_list"},
922 {boost::none, "/example-schema:_list/contInList"},
923 {boost::none, "/example-schema:_list/number"},
924 {boost::none, "/example-schema:a"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200925 {boost::none, "/example-schema:addresses"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200926 {boost::none, "/example-schema:a/a2"},
927 {boost::none, "/example-schema:a/a2/a3"},
928 {boost::none, "/example-schema:a/leafa"},
929 {boost::none, "/example-schema:a/second-schema:augmentedContainer"},
930 {boost::none, "/example-schema:activeMappedPort"},
931 {boost::none, "/example-schema:activeNumber"},
932 {boost::none, "/example-schema:activePort"},
933 {boost::none, "/example-schema:another-duration"},
934 {boost::none, "/example-schema:b"},
935 {boost::none, "/example-schema:b/b2"},
936 {boost::none, "/example-schema:b/b2/b3"},
937 {boost::none, "/example-schema:carry"},
938 {boost::none, "/example-schema:clockSpeed"},
939 {boost::none, "/example-schema:deprecatedLeaf"},
940 {boost::none, "/example-schema:direction"},
941 {boost::none, "/example-schema:duration"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200942 {boost::none, "/example-schema:dummyLeaf"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100943 {boost::none, "/example-schema:flagBits"},
944 {boost::none, "/example-schema:foodDrinkIdentLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200945 {boost::none, "/example-schema:foodDrinkIdentLeaf"},
946 {boost::none, "/example-schema:foodIdentLeaf"},
947 {boost::none, "/example-schema:interface/caseEthernet/ethernet"},
948 {boost::none, "/example-schema:interface/caseEthernet/ethernet/ip"},
949 {boost::none, "/example-schema:interface/caseLoopback/loopback"},
950 {boost::none, "/example-schema:interface/caseLoopback/loopback/ip"},
951 {boost::none, "/example-schema:interrupt"},
952 {boost::none, "/example-schema:leafBool"},
953 {boost::none, "/example-schema:leafDecimal"},
954 {boost::none, "/example-schema:leafEnum"},
955 {boost::none, "/example-schema:leafEnumTypedef"},
956 {boost::none, "/example-schema:leafEnumTypedefRestricted"},
957 {boost::none, "/example-schema:leafEnumTypedefRestricted2"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100958 {boost::none, "/example-schema:leafFoodTypedef"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200959 {boost::none, "/example-schema:leafInt16"},
960 {boost::none, "/example-schema:leafInt32"},
961 {boost::none, "/example-schema:leafInt64"},
962 {boost::none, "/example-schema:leafInt8"},
963 {boost::none, "/example-schema:leafString"},
964 {boost::none, "/example-schema:leafUint16"},
965 {boost::none, "/example-schema:leafUint32"},
966 {boost::none, "/example-schema:leafUint64"},
967 {boost::none, "/example-schema:leafUint8"},
968 {boost::none, "/example-schema:length"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200969 {boost::none, "/example-schema:myRpc"},
970 {boost::none, "/example-schema:myRpc/input"},
971 {boost::none, "/example-schema:myRpc/output"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100972 {boost::none, "/example-schema:rpcOneOutput"},
973 {boost::none, "/example-schema:rpcOneOutput/input"},
974 {boost::none, "/example-schema:rpcOneOutput/output"},
975 {boost::none, "/example-schema:rpcOneOutput/output/ahoj"},
976 {boost::none, "/example-schema:rpcOneInput"},
977 {boost::none, "/example-schema:rpcOneInput/input"},
978 {boost::none, "/example-schema:rpcOneInput/input/ahoj"},
979 {boost::none, "/example-schema:rpcOneInput/output"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200980 {boost::none, "/example-schema:numberOrString"},
981 {boost::none, "/example-schema:obsoleteLeaf"},
982 {boost::none, "/example-schema:obsoleteLeafWithDeprecatedType"},
983 {boost::none, "/example-schema:obsoleteLeafWithObsoleteType"},
984 {boost::none, "/example-schema:pizzaIdentLeaf"},
985 {boost::none, "/example-schema:pizzaSize"},
986 {boost::none, "/example-schema:portMapping"},
987 {boost::none, "/example-schema:portMapping/port"},
988 {boost::none, "/example-schema:portSettings"},
989 {boost::none, "/example-schema:portSettings/port"},
Václav Kubernáta8789602020-07-20 15:18:19 +0200990 {boost::none, "/example-schema:portSettings/shutdown"},
991 {boost::none, "/example-schema:portSettings/shutdown/input"},
992 {boost::none, "/example-schema:portSettings/shutdown/output"},
993 {boost::none, "/example-schema:portSettings/shutdown/output/success"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200994 {boost::none, "/example-schema:systemStats"},
995 {boost::none, "/example-schema:systemStats/upTime"},
Václav Kubernát82d74632020-05-11 15:59:53 +0200996 {boost::none, "/example-schema:subLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200997 {boost::none, "/example-schema:twoKeyList"},
998 {boost::none, "/example-schema:twoKeyList/name"},
999 {boost::none, "/example-schema:twoKeyList/number"},
1000 {boost::none, "/example-schema:wavelength"},
1001 {boost::none, "/example-schema:zero"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001002 };
1003 }
Václav Kubernát3a823f42020-04-29 23:40:21 +02001004 SECTION("second-schema")
1005 {
1006 module = "second-schema";
1007 expectedNonRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +02001008 {"second-schema"s, "bla"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001009 };
1010 expectedRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +02001011 {boost::none, "/second-schema:bla"},
1012 {boost::none, "/second-schema:bla/bla2"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001013 };
1014 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001015
Václav Kubernát3a823f42020-04-29 23:40:21 +02001016 REQUIRE(ys.availableNodes(module_{module}, Recursion::NonRecursive) == expectedNonRecursive);
1017 REQUIRE(ys.availableNodes(module_{module}, Recursion::Recursive) == expectedRecursive);
Václav Kubernát47a3f672019-11-08 15:42:43 +01001018 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001019 }
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001020 SECTION("nodeType")
1021 {
1022 yang::NodeTypes expected;
1023 SECTION("leafInt32")
1024 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001025 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001026 expected = yang::NodeTypes::Leaf;
1027 }
1028
1029 SECTION("a")
1030 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001031 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001032 expected = yang::NodeTypes::Container;
1033 }
1034
1035 SECTION("a/a2/a3")
1036 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001037 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1038 path.m_nodes.emplace_back(container_("a2"));
1039 path.m_nodes.emplace_back(container_("a3"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001040 expected = yang::NodeTypes::PresenceContainer;
1041 }
1042
1043 SECTION("_list")
1044 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001045 path.m_nodes.emplace_back(module_{"example-schema"}, list_("_list"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001046 expected = yang::NodeTypes::List;
1047 }
1048
Václav Kubernát82d74632020-05-11 15:59:53 +02001049 SECTION("subLeaf")
1050 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001051 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("subLeaf"));
Václav Kubernát82d74632020-05-11 15:59:53 +02001052 expected = yang::NodeTypes::Leaf;
1053 }
1054
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001055 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1056 }
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001057
1058 SECTION("description")
1059 {
1060 std::optional<std::string> expected;
1061 SECTION("leafInt32")
1062 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001063 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001064 expected = "A 32-bit integer leaf.";
1065 }
1066
1067 SECTION("leafString")
1068 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001069 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafString"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001070 }
1071
Václav Kubernát2984f442020-02-20 17:43:35 +01001072 SECTION("numberOrString")
1073 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001074 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("numberOrString"));
Václav Kubernát2984f442020-02-20 17:43:35 +01001075 expected = "Can be an int32 or a string.";
1076 }
1077
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001078 REQUIRE(ys.description(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1079 }
1080
Václav Kubernáta1c4c9e2020-04-22 00:37:52 +02001081 SECTION("status")
1082 {
1083 REQUIRE(ys.status("/example-schema:leafUint64") == yang::Status::Current);
1084 REQUIRE(ys.status("/example-schema:obsoleteLeaf") == yang::Status::Obsolete);
1085 REQUIRE(ys.status("/example-schema:deprecatedLeaf") == yang::Status::Deprecated);
1086 REQUIRE(ys.status("/example-schema:obsoleteLeafWithDeprecatedType") == yang::Status::Obsolete);
1087 REQUIRE(ys.status("/example-schema:obsoleteLeafWithObsoleteType") == yang::Status::Obsolete);
1088 }
1089
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001090 SECTION("units")
1091 {
Václav Kubernát13b23d72020-04-16 21:49:51 +02001092 yang::LeafDataType expectedType;
1093 std::optional<std::string> expectedUnits;
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001094 SECTION("length")
1095 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001096 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("length"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001097 expectedType.emplace<yang::Int32>();
1098 expectedUnits = "m";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001099 }
1100
1101 SECTION("wavelength")
1102 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001103 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("wavelength"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001104 expectedType.emplace<yang::Decimal>();
1105 expectedUnits = "nm";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001106 }
1107
1108 SECTION("leafInt32")
1109 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001110 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001111 expectedType.emplace<yang::Int32>();
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001112 }
1113
1114 SECTION("duration")
1115 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001116 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("duration"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001117 expectedType.emplace<yang::Int32>();
1118 expectedUnits = "s";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001119 }
1120
1121 SECTION("another-duration")
1122 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001123 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("another-duration"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001124 expectedType.emplace<yang::Int32>();
1125 expectedUnits = "vt";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001126 }
Václav Kubernát5b8a8f32020-05-20 00:57:22 +02001127 auto nodeType = ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded));
1128 REQUIRE((nodeType == yang::NodeTypes::Leaf || nodeType == yang::NodeTypes::LeafList));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001129 REQUIRE(ys.leafType(pathToSchemaString(path, Prefixes::WhenNeeded)) == yang::TypeInfo{expectedType, expectedUnits});
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001130 }
1131
Václav Kubernát1ae24f42020-12-01 02:32:04 +01001132 SECTION("type description")
1133 {
1134 yang::LeafDataType expectedType = createEnum({"lol", "data"});
1135 std::optional<std::string> expectedDescription;
1136
1137 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafEnumTypedefRestricted2"));
1138 expectedDescription = "This is a restricted enum typedef.";
1139 REQUIRE(ys.leafType(pathToSchemaString(path, Prefixes::WhenNeeded)) == yang::TypeInfo{expectedType, std::nullopt, expectedDescription});
1140 }
1141
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001142 SECTION("nodeType")
1143 {
1144 yang::NodeTypes expected;
1145 SECTION("leafInt32")
1146 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001147 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001148 expected = yang::NodeTypes::Leaf;
1149 }
1150
1151 SECTION("a")
1152 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001153 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001154 expected = yang::NodeTypes::Container;
1155 }
1156
1157 SECTION("a/a2/a3")
1158 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001159 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1160 path.m_nodes.emplace_back(container_("a2"));
1161 path.m_nodes.emplace_back(container_("a3"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001162 expected = yang::NodeTypes::PresenceContainer;
1163 }
1164
1165 SECTION("_list")
1166 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001167 path.m_nodes.emplace_back(module_{"example-schema"}, list_("_list"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001168 expected = yang::NodeTypes::List;
1169 }
1170
1171 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1172 }
Václav Kubernátbd5e3c22020-02-19 15:22:00 +01001173
1174 SECTION("leafrefPath")
1175 {
1176 REQUIRE(ys.leafrefPath("/example-schema:activeNumber") == "/example-schema:_list/number");
1177 }
Václav Kubernát0599e9f2020-04-21 09:51:33 +02001178
1179 SECTION("isConfig")
1180 {
1181 REQUIRE(ys.isConfig("/example-schema:leafInt32"));
1182 REQUIRE_FALSE(ys.isConfig("/example-schema:clockSpeed"));
1183 REQUIRE_FALSE(ys.isConfig("/example-schema:systemStats"));
1184 REQUIRE_FALSE(ys.isConfig("/example-schema:systemStats/upTime"));
1185 }
Václav Kubernátbd0d5c82020-04-21 10:22:03 +02001186
Václav Kubernátb1a75c62020-04-21 15:20:16 +02001187 SECTION("defaultValue")
1188 {
1189 REQUIRE(ys.defaultValue("/example-schema:leafUint64") == "9001");
1190 REQUIRE(ys.defaultValue("/example-schema:leafEnumTypedefRestricted") == "data");
1191 REQUIRE(ys.defaultValue("/example-schema:leafInt32") == std::nullopt);
1192 }
1193
Václav Kubernát76ba4ec2020-05-18 13:26:56 +02001194 SECTION("leafTypeName")
1195 {
1196 REQUIRE(ys.leafTypeName("/example-schema:leafEnumTypedefRestricted") == "enumTypedef");
1197 REQUIRE(ys.leafTypeName("/example-schema:leafInt32") == std::nullopt);
1198 }
Václav Kubernáta8789602020-07-20 15:18:19 +02001199
1200 SECTION("dataPathToSchemaPath")
1201 {
1202 REQUIRE(ys.dataPathToSchemaPath("/example-schema:portSettings[port='eth0']") == "/example-schema:portSettings");
1203 REQUIRE(ys.dataPathToSchemaPath("/example-schema:portSettings[port='eth0']/shutdown") == "/example-schema:portSettings/shutdown");
1204 }
Václav Kubernátd8408e02020-12-02 05:13:27 +01001205
1206 SECTION("has input nodes")
1207 {
1208 bool expected;
1209 SECTION("example-schema:myRpc")
1210 {
1211 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"myRpc"});
1212 expected = false;
1213 }
1214
1215 SECTION("example-schema:rpcOneInput")
1216 {
1217 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"rpcOneInput"});
1218 expected = true;
1219 }
1220
1221 SECTION("example-schema:rpcOneOutput")
1222 {
1223 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"rpcOneOutput"});
1224 expected = false;
1225 }
1226
1227 REQUIRE(ys.hasInputNodes(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1228 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001229 }
1230
1231 SECTION("negative")
1232 {
1233 SECTION("nonexistent nodes")
1234 {
1235 SECTION("example-schema:coze")
1236 {
1237 node.first = "example-schema";
1238 node.second = "coze";
1239 }
1240
1241 SECTION("example-schema:a/nevim")
1242 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001243 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001244 node.second = "nevim";
1245 }
1246
1247 SECTION("modul:a/nevim")
1248 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001249 path.m_nodes.emplace_back(module_{"modul"}, container_("a"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001250 node.second = "nevim";
1251 }
1252
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001253 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001254 }
1255
1256 SECTION("nodetype-specific methods called with different nodetypes")
1257 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001258 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1259 path.m_nodes.emplace_back(container_("a2"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001260
Václav Kubernát912b9492020-05-29 02:03:40 +02001261 REQUIRE(!ys.listHasKey(path, "chacha"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001262 }
1263
1264 SECTION("nonexistent module")
1265 {
Václav Kubernát75877de2019-11-20 17:43:02 +01001266 REQUIRE(!ys.isModule("notAModule"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001267 }
Václav Kubernáteeb38842019-03-20 19:46:05 +01001268
Václav Kubernát7d82da72019-04-11 15:16:38 +02001269 SECTION("grouping is not a node")
1270 {
1271 SECTION("example-schema:arithmeticFlags")
1272 {
1273 node.first = "example-schema";
1274 node.second = "arithmeticFlags";
1275 }
1276
1277 SECTION("example-schema:flags")
1278 {
1279 node.first = "example-schema";
1280 node.second = "startAndStop";
1281 }
1282
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001283 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát7d82da72019-04-11 15:16:38 +02001284 }
Václav Kubernát280df4a2019-11-01 14:46:34 +01001285
1286 SECTION("choice is not a node")
1287 {
1288 SECTION("example-schema:interface")
1289 {
1290 node.first = "example-schema";
1291 node.second = "interface";
1292 }
1293
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001294 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát280df4a2019-11-01 14:46:34 +01001295 }
1296
1297 SECTION("case is not a node")
1298 {
1299 SECTION("example-schema:caseLoopback")
1300 {
1301 node.first = "example-schema";
1302 node.second = "caseLoopback";
1303 }
1304
1305 SECTION("example-schema:caseEthernet")
1306 {
1307 node.first = "example-schema";
1308 node.second = "caseEthernet";
1309 }
1310
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001311 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát280df4a2019-11-01 14:46:34 +01001312 }
Václav Kubernátf44bdda2020-06-22 15:58:41 +02001313
1314 SECTION("enableFeature - non existing module")
1315 {
1316 REQUIRE_THROWS_AS(ys.enableFeature("non-existing", "just-no"), std::runtime_error);
1317 }
Václav Kubernát7aaf6dc2020-06-26 18:03:57 +02001318
1319 SECTION("enableFeature - non existing feature")
1320 {
1321 REQUIRE_THROWS_AS(ys.enableFeature("example-schema", "just-no"), std::runtime_error);
1322 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001323 }
1324}