blob: 4905166b91ed14532de459e8d22a414f0be68a7d [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"},
Václav Kubernát3a99f002020-03-31 02:27:41 +0200677 {"example-schema", "pizza"},
678 {"example-schema", "hawaii"},
679 {"example-schema", "fruit"}}};
680 }
681
682 SECTION("pizzaIdentLeaf")
683 {
684 node.first = "example-schema";
685 node.second = "pizzaIdentLeaf";
686
687 type = yang::IdentityRef{{
Václav Kubernát3a99f002020-03-31 02:27:41 +0200688 {"example-schema", "hawaii"},
689 }};
690 }
691
692 SECTION("foodDrinkIdentLeaf")
693 {
694 node.first = "example-schema";
695 node.second = "foodDrinkIdentLeaf";
696
697 type = yang::IdentityRef{{
Václav Kubernát3a99f002020-03-31 02:27:41 +0200698 {"example-schema", "fruit"},
699 {"example-schema", "hawaii"},
700 {"example-schema", "pizza"},
701 {"example-schema", "voda"},
702 {"second-schema", "pineapple"},
703 }};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200704 }
705
Václav Kubernátb6d02752020-04-03 00:25:10 +0200706 SECTION("activeNumber")
707 {
708 node.first = "example-schema";
709 node.second = "activeNumber";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200710 type.emplace<yang::LeafRef>(
711 "/example-schema:_list/number",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200712 std::make_unique<yang::TypeInfo>(ys.leafType("/example-schema:_list/number"))
Václav Kubernát3a99f002020-03-31 02:27:41 +0200713 );
Václav Kubernátb6d02752020-04-03 00:25:10 +0200714 }
715
Václav Kubernát2984f442020-02-20 17:43:35 +0100716 SECTION("activePort")
717 {
718 node.first = "example-schema";
719 node.second = "activePort";
720
Václav Kubernát1dc9e3e2020-06-09 15:22:39 +0200721 yang::Enum enums({});
722 SECTION("weird ports disabled")
723 {
724 enums = createEnum({"utf2", "utf3"});
725 }
726 SECTION("weird ports enabled")
727 {
728 ys.enableFeature("example-schema", "weirdPortNames");
729 enums = createEnum({"WEIRD", "utf2", "utf3"});
730 }
Václav Kubernát2984f442020-02-20 17:43:35 +0100731
732 type = yang::Union{{
Václav Kubernát13b23d72020-04-16 21:49:51 +0200733 yang::TypeInfo{createEnum({"wlan0", "wlan1"})},
734 yang::TypeInfo{yang::LeafRef{
Václav Kubernát2984f442020-02-20 17:43:35 +0100735 "/example-schema:portSettings/port",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200736 std::make_unique<yang::TypeInfo>(createEnum({"eth0", "eth1", "eth2"}))
737 }},
738 yang::TypeInfo{yang::LeafRef{
Václav Kubernát2984f442020-02-20 17:43:35 +0100739 "/example-schema:activeMappedPort",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200740 std::make_unique<yang::TypeInfo>(yang::LeafRef{
Václav Kubernát2984f442020-02-20 17:43:35 +0100741 "/example-schema:portMapping/port",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200742 std::make_unique<yang::TypeInfo>(enums)
743 })
744 }},
Jan Kundrát379bb572020-05-07 03:23:13 +0200745 yang::TypeInfo{yang::Empty{}},
Václav Kubernát2984f442020-02-20 17:43:35 +0100746 }};
747 }
748
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200749 SECTION("addresses")
750 {
751 node.first = "example-schema";
752 node.second = "addresses";
753 type.emplace<yang::String>();
754 }
755
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100756 SECTION("flagBits")
757 {
758 node.first = "example-schema";
759 node.second = "flagBits";
760 type = yang::Bits{{"carry", "sign", "overflow"}};
761 }
762
Václav Kubernátfa36c822021-01-25 07:51:02 +0100763 SECTION("foodTypedef")
764 {
765 node.first = "example-schema";
766 node.second = "leafFoodTypedef";
767 type = yang::IdentityRef{{
Václav Kubernátfa36c822021-01-25 07:51:02 +0100768 {"example-schema", "fruit"},
769 {"example-schema", "hawaii"},
770 {"example-schema", "pizza"},
771 {"second-schema", "pineapple"},
772 }};
773 }
774
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200775
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100776 REQUIRE(ys.leafType(path, node) == yang::TypeInfo(type, std::nullopt, expectedDescription));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200777 }
Václav Kubernát3a823f42020-04-29 23:40:21 +0200778 SECTION("availableNodes")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200779 {
Václav Kubernát3a823f42020-04-29 23:40:21 +0200780 // TODO: merge "path" and "module" sections and add recursive versions to the path section
781 SECTION("paths")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200782 {
Václav Kubernát95b08872020-04-28 01:04:17 +0200783 std::set<ModuleNodePair> set;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200784
Václav Kubernát95b08872020-04-28 01:04:17 +0200785 using namespace std::string_literals;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200786 SECTION("<root>")
787 {
Václav Kubernát95b08872020-04-28 01:04:17 +0200788 set = {{"example-schema"s, "a"}, {"example-schema"s, "b"}, {"example-schema"s, "leafString"},
789 {"example-schema"s, "leafDecimal"}, {"example-schema"s, "leafBool"},
790 {"example-schema"s, "leafInt8"}, {"example-schema"s, "leafUint8"},
791 {"example-schema"s, "leafInt16"}, {"example-schema"s, "leafUint16"},
792 {"example-schema"s, "leafInt32"}, {"example-schema"s, "leafUint32"},
793 {"example-schema"s, "leafInt64"}, {"example-schema"s, "leafUint64"},
794 {"example-schema"s, "leafEnum"}, {"example-schema"s, "leafEnumTypedef"},
795 {"example-schema"s, "leafEnumTypedefRestricted"}, {"example-schema"s, "leafEnumTypedefRestricted2"},
796 {"example-schema"s, "foodIdentLeaf"}, {"example-schema"s, "pizzaIdentLeaf"}, {"example-schema"s, "foodDrinkIdentLeaf"},
797 {"example-schema"s, "_list"}, {"example-schema"s, "twoKeyList"}, {"second-schema"s, "bla"},
798 {"example-schema"s, "carry"}, {"example-schema"s, "zero"}, {"example-schema"s, "direction"},
799 {"example-schema"s, "interrupt"},
800 {"example-schema"s, "ethernet"}, {"example-schema"s, "loopback"},
801 {"example-schema"s, "pizzaSize"},
802 {"example-schema"s, "length"}, {"example-schema"s, "wavelength"},
803 {"example-schema"s, "duration"}, {"example-schema"s, "another-duration"},
804 {"example-schema"s, "activeNumber"},
805 {"example-schema"s, "numberOrString"},
806 {"example-schema"s, "portSettings"},
807 {"example-schema"s, "portMapping"},
808 {"example-schema"s, "activeMappedPort"},
809 {"example-schema"s, "activePort"},
810 {"example-schema"s, "clockSpeed"},
811 {"example-schema"s, "deprecatedLeaf"},
812 {"example-schema"s, "obsoleteLeaf"},
813 {"example-schema"s, "obsoleteLeafWithDeprecatedType"},
814 {"example-schema"s, "obsoleteLeafWithObsoleteType"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200815 {"example-schema"s, "myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100816 {"example-schema"s, "rpcOneOutput"},
817 {"example-schema"s, "rpcOneInput"},
Václav Kubernát82d74632020-05-11 15:59:53 +0200818 {"example-schema"s, "systemStats"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200819 {"example-schema"s, "dummyLeaf"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200820 {"example-schema"s, "addresses"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100821 {"example-schema"s, "subLeaf"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100822 {"example-schema"s, "flagBits"},
823 {"example-schema"s, "leafFoodTypedef"}};
Václav Kubernát3a823f42020-04-29 23:40:21 +0200824 }
825
826 SECTION("example-schema:a")
827 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200828 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200829 set = {
830 {boost::none, "a2"},
831 {boost::none, "leafa"},
832 {"second-schema"s, "augmentedContainer"}
833 };
Václav Kubernát3a823f42020-04-29 23:40:21 +0200834 }
835
836 SECTION("example-schema:ethernet")
837 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200838 path.m_nodes.emplace_back(module_{"example-schema"}, container_("ethernet"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200839 set = {{boost::none, "ip"}};
840 }
841
842 SECTION("second-schema:bla")
843 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200844 path.m_nodes.emplace_back(module_{"second-schema"}, container_("bla"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200845 set = {{boost::none, "bla2"}};
Václav Kubernát3a823f42020-04-29 23:40:21 +0200846 }
847
848 REQUIRE(ys.availableNodes(path, Recursion::NonRecursive) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200849 }
850
Václav Kubernát3a823f42020-04-29 23:40:21 +0200851 SECTION("modules")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200852 {
Václav Kubernát3a823f42020-04-29 23:40:21 +0200853 std::string module;
Václav Kubernát95b08872020-04-28 01:04:17 +0200854 std::set<ModuleNodePair> expectedNonRecursive;
855 std::set<ModuleNodePair> expectedRecursive;
856 using namespace std::string_literals;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200857 SECTION("example-schema")
858 {
859 module = "example-schema";
860 expectedNonRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +0200861 {"example-schema"s, "_list"},
862 {"example-schema"s, "a"},
863 {"example-schema"s, "activeMappedPort"},
864 {"example-schema"s, "activeNumber"},
865 {"example-schema"s, "activePort"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200866 {"example-schema"s, "addresses"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200867 {"example-schema"s, "another-duration"},
868 {"example-schema"s, "b"},
869 {"example-schema"s, "carry"},
870 {"example-schema"s, "clockSpeed"},
871 {"example-schema"s, "deprecatedLeaf"},
872 {"example-schema"s, "direction"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200873 {"example-schema"s, "dummyLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200874 {"example-schema"s, "duration"},
875 {"example-schema"s, "ethernet"},
876 {"example-schema"s, "foodDrinkIdentLeaf"},
877 {"example-schema"s, "foodIdentLeaf"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100878 {"example-schema"s, "flagBits"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200879 {"example-schema"s, "interrupt"},
880 {"example-schema"s, "leafBool"},
881 {"example-schema"s, "leafDecimal"},
882 {"example-schema"s, "leafEnum"},
883 {"example-schema"s, "leafEnumTypedef"},
884 {"example-schema"s, "leafEnumTypedefRestricted"},
885 {"example-schema"s, "leafEnumTypedefRestricted2"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100886 {"example-schema"s, "leafFoodTypedef"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200887 {"example-schema"s, "leafInt16"},
888 {"example-schema"s, "leafInt32"},
889 {"example-schema"s, "leafInt64"},
890 {"example-schema"s, "leafInt8"},
891 {"example-schema"s, "leafString"},
892 {"example-schema"s, "leafUint16"},
893 {"example-schema"s, "leafUint32"},
894 {"example-schema"s, "leafUint64"},
895 {"example-schema"s, "leafUint8"},
896 {"example-schema"s, "length"},
897 {"example-schema"s, "loopback"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200898 {"example-schema"s, "myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100899 {"example-schema"s, "rpcOneOutput"},
900 {"example-schema"s, "rpcOneInput"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200901 {"example-schema"s, "numberOrString"},
902 {"example-schema"s, "obsoleteLeaf"},
903 {"example-schema"s, "obsoleteLeafWithDeprecatedType"},
904 {"example-schema"s, "obsoleteLeafWithObsoleteType"},
905 {"example-schema"s, "pizzaIdentLeaf"},
906 {"example-schema"s, "pizzaSize"},
907 {"example-schema"s, "portMapping"},
908 {"example-schema"s, "portSettings"},
909 {"example-schema"s, "systemStats"},
910 {"example-schema"s, "twoKeyList"},
911 {"example-schema"s, "wavelength"},
Václav Kubernát82d74632020-05-11 15:59:53 +0200912 {"example-schema"s, "zero"},
913 {"example-schema"s, "subLeaf"}
Václav Kubernát3a823f42020-04-29 23:40:21 +0200914 };
915 expectedRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +0200916 {boost::none, "/example-schema:_list"},
917 {boost::none, "/example-schema:_list/contInList"},
918 {boost::none, "/example-schema:_list/number"},
919 {boost::none, "/example-schema:a"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200920 {boost::none, "/example-schema:addresses"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200921 {boost::none, "/example-schema:a/a2"},
922 {boost::none, "/example-schema:a/a2/a3"},
923 {boost::none, "/example-schema:a/leafa"},
924 {boost::none, "/example-schema:a/second-schema:augmentedContainer"},
925 {boost::none, "/example-schema:activeMappedPort"},
926 {boost::none, "/example-schema:activeNumber"},
927 {boost::none, "/example-schema:activePort"},
928 {boost::none, "/example-schema:another-duration"},
929 {boost::none, "/example-schema:b"},
930 {boost::none, "/example-schema:b/b2"},
931 {boost::none, "/example-schema:b/b2/b3"},
932 {boost::none, "/example-schema:carry"},
933 {boost::none, "/example-schema:clockSpeed"},
934 {boost::none, "/example-schema:deprecatedLeaf"},
935 {boost::none, "/example-schema:direction"},
936 {boost::none, "/example-schema:duration"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200937 {boost::none, "/example-schema:dummyLeaf"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100938 {boost::none, "/example-schema:flagBits"},
939 {boost::none, "/example-schema:foodDrinkIdentLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200940 {boost::none, "/example-schema:foodDrinkIdentLeaf"},
941 {boost::none, "/example-schema:foodIdentLeaf"},
942 {boost::none, "/example-schema:interface/caseEthernet/ethernet"},
943 {boost::none, "/example-schema:interface/caseEthernet/ethernet/ip"},
944 {boost::none, "/example-schema:interface/caseLoopback/loopback"},
945 {boost::none, "/example-schema:interface/caseLoopback/loopback/ip"},
946 {boost::none, "/example-schema:interrupt"},
947 {boost::none, "/example-schema:leafBool"},
948 {boost::none, "/example-schema:leafDecimal"},
949 {boost::none, "/example-schema:leafEnum"},
950 {boost::none, "/example-schema:leafEnumTypedef"},
951 {boost::none, "/example-schema:leafEnumTypedefRestricted"},
952 {boost::none, "/example-schema:leafEnumTypedefRestricted2"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100953 {boost::none, "/example-schema:leafFoodTypedef"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200954 {boost::none, "/example-schema:leafInt16"},
955 {boost::none, "/example-schema:leafInt32"},
956 {boost::none, "/example-schema:leafInt64"},
957 {boost::none, "/example-schema:leafInt8"},
958 {boost::none, "/example-schema:leafString"},
959 {boost::none, "/example-schema:leafUint16"},
960 {boost::none, "/example-schema:leafUint32"},
961 {boost::none, "/example-schema:leafUint64"},
962 {boost::none, "/example-schema:leafUint8"},
963 {boost::none, "/example-schema:length"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200964 {boost::none, "/example-schema:myRpc"},
965 {boost::none, "/example-schema:myRpc/input"},
966 {boost::none, "/example-schema:myRpc/output"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100967 {boost::none, "/example-schema:rpcOneOutput"},
968 {boost::none, "/example-schema:rpcOneOutput/input"},
969 {boost::none, "/example-schema:rpcOneOutput/output"},
970 {boost::none, "/example-schema:rpcOneOutput/output/ahoj"},
971 {boost::none, "/example-schema:rpcOneInput"},
972 {boost::none, "/example-schema:rpcOneInput/input"},
973 {boost::none, "/example-schema:rpcOneInput/input/ahoj"},
974 {boost::none, "/example-schema:rpcOneInput/output"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200975 {boost::none, "/example-schema:numberOrString"},
976 {boost::none, "/example-schema:obsoleteLeaf"},
977 {boost::none, "/example-schema:obsoleteLeafWithDeprecatedType"},
978 {boost::none, "/example-schema:obsoleteLeafWithObsoleteType"},
979 {boost::none, "/example-schema:pizzaIdentLeaf"},
980 {boost::none, "/example-schema:pizzaSize"},
981 {boost::none, "/example-schema:portMapping"},
982 {boost::none, "/example-schema:portMapping/port"},
983 {boost::none, "/example-schema:portSettings"},
984 {boost::none, "/example-schema:portSettings/port"},
Václav Kubernáta8789602020-07-20 15:18:19 +0200985 {boost::none, "/example-schema:portSettings/shutdown"},
986 {boost::none, "/example-schema:portSettings/shutdown/input"},
987 {boost::none, "/example-schema:portSettings/shutdown/output"},
988 {boost::none, "/example-schema:portSettings/shutdown/output/success"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200989 {boost::none, "/example-schema:systemStats"},
990 {boost::none, "/example-schema:systemStats/upTime"},
Václav Kubernát82d74632020-05-11 15:59:53 +0200991 {boost::none, "/example-schema:subLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200992 {boost::none, "/example-schema:twoKeyList"},
993 {boost::none, "/example-schema:twoKeyList/name"},
994 {boost::none, "/example-schema:twoKeyList/number"},
995 {boost::none, "/example-schema:wavelength"},
996 {boost::none, "/example-schema:zero"}
Václav Kubernát3a823f42020-04-29 23:40:21 +0200997 };
998 }
Václav Kubernát3a823f42020-04-29 23:40:21 +0200999 SECTION("second-schema")
1000 {
1001 module = "second-schema";
1002 expectedNonRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +02001003 {"second-schema"s, "bla"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001004 };
1005 expectedRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +02001006 {boost::none, "/second-schema:bla"},
1007 {boost::none, "/second-schema:bla/bla2"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001008 };
1009 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001010
Václav Kubernát3a823f42020-04-29 23:40:21 +02001011 REQUIRE(ys.availableNodes(module_{module}, Recursion::NonRecursive) == expectedNonRecursive);
1012 REQUIRE(ys.availableNodes(module_{module}, Recursion::Recursive) == expectedRecursive);
Václav Kubernát47a3f672019-11-08 15:42:43 +01001013 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001014 }
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001015 SECTION("nodeType")
1016 {
1017 yang::NodeTypes expected;
1018 SECTION("leafInt32")
1019 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001020 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001021 expected = yang::NodeTypes::Leaf;
1022 }
1023
1024 SECTION("a")
1025 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001026 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001027 expected = yang::NodeTypes::Container;
1028 }
1029
1030 SECTION("a/a2/a3")
1031 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001032 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1033 path.m_nodes.emplace_back(container_("a2"));
1034 path.m_nodes.emplace_back(container_("a3"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001035 expected = yang::NodeTypes::PresenceContainer;
1036 }
1037
1038 SECTION("_list")
1039 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001040 path.m_nodes.emplace_back(module_{"example-schema"}, list_("_list"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001041 expected = yang::NodeTypes::List;
1042 }
1043
Václav Kubernát82d74632020-05-11 15:59:53 +02001044 SECTION("subLeaf")
1045 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001046 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("subLeaf"));
Václav Kubernát82d74632020-05-11 15:59:53 +02001047 expected = yang::NodeTypes::Leaf;
1048 }
1049
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001050 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1051 }
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001052
1053 SECTION("description")
1054 {
1055 std::optional<std::string> expected;
1056 SECTION("leafInt32")
1057 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001058 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001059 expected = "A 32-bit integer leaf.";
1060 }
1061
1062 SECTION("leafString")
1063 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001064 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafString"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001065 }
1066
Václav Kubernát2984f442020-02-20 17:43:35 +01001067 SECTION("numberOrString")
1068 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001069 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("numberOrString"));
Václav Kubernát2984f442020-02-20 17:43:35 +01001070 expected = "Can be an int32 or a string.";
1071 }
1072
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001073 REQUIRE(ys.description(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1074 }
1075
Václav Kubernáta1c4c9e2020-04-22 00:37:52 +02001076 SECTION("status")
1077 {
1078 REQUIRE(ys.status("/example-schema:leafUint64") == yang::Status::Current);
1079 REQUIRE(ys.status("/example-schema:obsoleteLeaf") == yang::Status::Obsolete);
1080 REQUIRE(ys.status("/example-schema:deprecatedLeaf") == yang::Status::Deprecated);
1081 REQUIRE(ys.status("/example-schema:obsoleteLeafWithDeprecatedType") == yang::Status::Obsolete);
1082 REQUIRE(ys.status("/example-schema:obsoleteLeafWithObsoleteType") == yang::Status::Obsolete);
1083 }
1084
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001085 SECTION("units")
1086 {
Václav Kubernát13b23d72020-04-16 21:49:51 +02001087 yang::LeafDataType expectedType;
1088 std::optional<std::string> expectedUnits;
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001089 SECTION("length")
1090 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001091 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("length"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001092 expectedType.emplace<yang::Int32>();
1093 expectedUnits = "m";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001094 }
1095
1096 SECTION("wavelength")
1097 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001098 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("wavelength"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001099 expectedType.emplace<yang::Decimal>();
1100 expectedUnits = "nm";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001101 }
1102
1103 SECTION("leafInt32")
1104 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001105 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001106 expectedType.emplace<yang::Int32>();
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001107 }
1108
1109 SECTION("duration")
1110 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001111 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("duration"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001112 expectedType.emplace<yang::Int32>();
1113 expectedUnits = "s";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001114 }
1115
1116 SECTION("another-duration")
1117 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001118 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("another-duration"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001119 expectedType.emplace<yang::Int32>();
1120 expectedUnits = "vt";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001121 }
Václav Kubernát5b8a8f32020-05-20 00:57:22 +02001122 auto nodeType = ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded));
1123 REQUIRE((nodeType == yang::NodeTypes::Leaf || nodeType == yang::NodeTypes::LeafList));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001124 REQUIRE(ys.leafType(pathToSchemaString(path, Prefixes::WhenNeeded)) == yang::TypeInfo{expectedType, expectedUnits});
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001125 }
1126
Václav Kubernát1ae24f42020-12-01 02:32:04 +01001127 SECTION("type description")
1128 {
1129 yang::LeafDataType expectedType = createEnum({"lol", "data"});
1130 std::optional<std::string> expectedDescription;
1131
1132 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafEnumTypedefRestricted2"));
1133 expectedDescription = "This is a restricted enum typedef.";
1134 REQUIRE(ys.leafType(pathToSchemaString(path, Prefixes::WhenNeeded)) == yang::TypeInfo{expectedType, std::nullopt, expectedDescription});
1135 }
1136
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001137 SECTION("nodeType")
1138 {
1139 yang::NodeTypes expected;
1140 SECTION("leafInt32")
1141 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001142 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001143 expected = yang::NodeTypes::Leaf;
1144 }
1145
1146 SECTION("a")
1147 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001148 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001149 expected = yang::NodeTypes::Container;
1150 }
1151
1152 SECTION("a/a2/a3")
1153 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001154 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1155 path.m_nodes.emplace_back(container_("a2"));
1156 path.m_nodes.emplace_back(container_("a3"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001157 expected = yang::NodeTypes::PresenceContainer;
1158 }
1159
1160 SECTION("_list")
1161 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001162 path.m_nodes.emplace_back(module_{"example-schema"}, list_("_list"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001163 expected = yang::NodeTypes::List;
1164 }
1165
1166 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1167 }
Václav Kubernátbd5e3c22020-02-19 15:22:00 +01001168
1169 SECTION("leafrefPath")
1170 {
1171 REQUIRE(ys.leafrefPath("/example-schema:activeNumber") == "/example-schema:_list/number");
1172 }
Václav Kubernát0599e9f2020-04-21 09:51:33 +02001173
1174 SECTION("isConfig")
1175 {
1176 REQUIRE(ys.isConfig("/example-schema:leafInt32"));
1177 REQUIRE_FALSE(ys.isConfig("/example-schema:clockSpeed"));
1178 REQUIRE_FALSE(ys.isConfig("/example-schema:systemStats"));
1179 REQUIRE_FALSE(ys.isConfig("/example-schema:systemStats/upTime"));
1180 }
Václav Kubernátbd0d5c82020-04-21 10:22:03 +02001181
Václav Kubernátb1a75c62020-04-21 15:20:16 +02001182 SECTION("defaultValue")
1183 {
1184 REQUIRE(ys.defaultValue("/example-schema:leafUint64") == "9001");
1185 REQUIRE(ys.defaultValue("/example-schema:leafEnumTypedefRestricted") == "data");
1186 REQUIRE(ys.defaultValue("/example-schema:leafInt32") == std::nullopt);
1187 }
1188
Václav Kubernát76ba4ec2020-05-18 13:26:56 +02001189 SECTION("leafTypeName")
1190 {
1191 REQUIRE(ys.leafTypeName("/example-schema:leafEnumTypedefRestricted") == "enumTypedef");
1192 REQUIRE(ys.leafTypeName("/example-schema:leafInt32") == std::nullopt);
1193 }
Václav Kubernáta8789602020-07-20 15:18:19 +02001194
1195 SECTION("dataPathToSchemaPath")
1196 {
1197 REQUIRE(ys.dataPathToSchemaPath("/example-schema:portSettings[port='eth0']") == "/example-schema:portSettings");
1198 REQUIRE(ys.dataPathToSchemaPath("/example-schema:portSettings[port='eth0']/shutdown") == "/example-schema:portSettings/shutdown");
1199 }
Václav Kubernátd8408e02020-12-02 05:13:27 +01001200
1201 SECTION("has input nodes")
1202 {
1203 bool expected;
1204 SECTION("example-schema:myRpc")
1205 {
1206 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"myRpc"});
1207 expected = false;
1208 }
1209
1210 SECTION("example-schema:rpcOneInput")
1211 {
1212 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"rpcOneInput"});
1213 expected = true;
1214 }
1215
1216 SECTION("example-schema:rpcOneOutput")
1217 {
1218 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"rpcOneOutput"});
1219 expected = false;
1220 }
1221
1222 REQUIRE(ys.hasInputNodes(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1223 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001224 }
1225
1226 SECTION("negative")
1227 {
1228 SECTION("nonexistent nodes")
1229 {
1230 SECTION("example-schema:coze")
1231 {
1232 node.first = "example-schema";
1233 node.second = "coze";
1234 }
1235
1236 SECTION("example-schema:a/nevim")
1237 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001238 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001239 node.second = "nevim";
1240 }
1241
1242 SECTION("modul:a/nevim")
1243 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001244 path.m_nodes.emplace_back(module_{"modul"}, container_("a"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001245 node.second = "nevim";
1246 }
1247
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001248 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001249 }
1250
1251 SECTION("nodetype-specific methods called with different nodetypes")
1252 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001253 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1254 path.m_nodes.emplace_back(container_("a2"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001255
Václav Kubernát912b9492020-05-29 02:03:40 +02001256 REQUIRE(!ys.listHasKey(path, "chacha"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001257 }
1258
1259 SECTION("nonexistent module")
1260 {
Václav Kubernát75877de2019-11-20 17:43:02 +01001261 REQUIRE(!ys.isModule("notAModule"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001262 }
Václav Kubernáteeb38842019-03-20 19:46:05 +01001263
Václav Kubernát7d82da72019-04-11 15:16:38 +02001264 SECTION("grouping is not a node")
1265 {
1266 SECTION("example-schema:arithmeticFlags")
1267 {
1268 node.first = "example-schema";
1269 node.second = "arithmeticFlags";
1270 }
1271
1272 SECTION("example-schema:flags")
1273 {
1274 node.first = "example-schema";
1275 node.second = "startAndStop";
1276 }
1277
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001278 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát7d82da72019-04-11 15:16:38 +02001279 }
Václav Kubernát280df4a2019-11-01 14:46:34 +01001280
1281 SECTION("choice is not a node")
1282 {
1283 SECTION("example-schema:interface")
1284 {
1285 node.first = "example-schema";
1286 node.second = "interface";
1287 }
1288
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001289 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát280df4a2019-11-01 14:46:34 +01001290 }
1291
1292 SECTION("case is not a node")
1293 {
1294 SECTION("example-schema:caseLoopback")
1295 {
1296 node.first = "example-schema";
1297 node.second = "caseLoopback";
1298 }
1299
1300 SECTION("example-schema:caseEthernet")
1301 {
1302 node.first = "example-schema";
1303 node.second = "caseEthernet";
1304 }
1305
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001306 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát280df4a2019-11-01 14:46:34 +01001307 }
Václav Kubernátf44bdda2020-06-22 15:58:41 +02001308
1309 SECTION("enableFeature - non existing module")
1310 {
1311 REQUIRE_THROWS_AS(ys.enableFeature("non-existing", "just-no"), std::runtime_error);
1312 }
Václav Kubernát7aaf6dc2020-06-26 18:03:57 +02001313
1314 SECTION("enableFeature - non existing feature")
1315 {
1316 REQUIRE_THROWS_AS(ys.enableFeature("example-schema", "just-no"), std::runtime_error);
1317 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001318 }
1319}