blob: ed4da88182b8e4cf65c7415fdf1b23775207a3f1 [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át97f6b602022-01-17 23:55:51 +010062 identity identNoderived {
63 }
64
65 leaf leafNoValidIdent {
66 type identityref {
67 base "identNoderived";
68 }
69 }
70
Václav Kubernáteeb38842019-03-20 19:46:05 +010071 identity drink {
72 }
73
74 identity voda {
75 base "drink";
76 }
77
78 identity food {
79 }
80
81 identity fruit {
82 base "food";
83 }
84
85 identity pizza {
86 base "food";
87 }
88
89 identity hawaii {
90 base "pizza";
91 }
92
Václav Kubernátfa36c822021-01-25 07:51:02 +010093 typedef foodTypedef {
94 type identityref {
95 base food;
96 }
97 }
98
99 leaf leafFoodTypedef {
100 type foodTypedef;
101 }
102
Václav Kubernát0d4db442018-07-18 17:18:43 +0200103 container a {
104 container a2 {
105 container a3 {
106 presence true;
107 }
108 }
109
110 leaf leafa {
111 type string;
112 }
113 }
114
115 container b {
116 container b2 {
117 presence true;
118 container b3 {
119 }
120 }
121 }
122
123 leaf leafString {
124 type string;
125 }
126
127 leaf leafDecimal {
128 type decimal64 {
129 fraction-digits 5;
130 }
131 }
132
133 leaf leafBool {
134 type boolean;
135 }
136
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200137 leaf leafInt8 {
138 type int8;
139 }
140
141 leaf leafUint8 {
142 type uint8;
143 }
144
145 leaf leafInt16 {
146 type int16;
147 }
148
149 leaf leafUint16 {
150 type uint16;
151 }
152
153 leaf leafInt32 {
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100154 description "A 32-bit integer leaf.";
Václav Kubernát0d4db442018-07-18 17:18:43 +0200155 type int32;
156 }
157
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200158 leaf leafUint32 {
Václav Kubernát0d4db442018-07-18 17:18:43 +0200159 type uint32;
160 }
161
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200162 leaf leafInt64 {
163 type int64;
164 }
165
166 leaf leafUint64 {
167 type uint64;
Václav Kubernátb1a75c62020-04-21 15:20:16 +0200168 default 9001;
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200169 }
170
Václav Kubernát0d4db442018-07-18 17:18:43 +0200171 leaf leafEnum {
172 type enumeration {
173 enum lol;
174 enum data;
175 enum coze;
176 }
177 }
178
Václav Kubernát6a713d62018-10-03 18:47:34 +0200179 typedef enumTypedef {
180 type enumeration {
181 enum lol;
182 enum data;
183 enum coze;
184 }
Václav Kubernátb1a75c62020-04-21 15:20:16 +0200185 default data;
Václav Kubernát6a713d62018-10-03 18:47:34 +0200186 }
187
188 typedef enumTypedefRestricted {
189 type enumTypedef {
190 enum lol;
191 enum data;
192 }
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100193 description "This is a restricted enum typedef.";
Václav Kubernát6a713d62018-10-03 18:47:34 +0200194 }
195
196 leaf leafEnumTypedef {
197 type enumTypedef;
198 }
199
200 leaf leafEnumTypedefRestricted {
201 type enumTypedef {
202 enum data;
203 enum coze;
204 }
205 }
206
207 leaf leafEnumTypedefRestricted2 {
208 type enumTypedefRestricted;
209 }
210
Václav Kubernáteeb38842019-03-20 19:46:05 +0100211 leaf foodIdentLeaf {
212 type identityref {
213 base "food";
214 }
215 }
216
217 leaf pizzaIdentLeaf {
218 type identityref {
219 base "pizza";
220 }
221 }
222
223 leaf foodDrinkIdentLeaf {
224 type identityref {
225 base "food";
226 base "drink";
227 }
228 }
229
Václav Kubernát0d4db442018-07-18 17:18:43 +0200230 list _list {
231 key number;
232
233 leaf number {
234 type int32;
235 }
236
237 container contInList {
238 presence true;
239 }
240 }
241
242 list twoKeyList {
243 key "name number";
244
245 leaf number {
246 type int32;
247 }
248
249 leaf name {
250 type string;
251 }
252 }
Václav Kubernát7d82da72019-04-11 15:16:38 +0200253
254 grouping arithmeticFlags {
255 leaf carry {
256 type boolean;
257 }
258 leaf zero {
259 type boolean;
260 }
261 }
262
263 grouping flags {
264 leaf direction {
265 type boolean;
266 }
267 leaf interrupt {
268 type boolean;
269 }
270
271 uses arithmeticFlags;
272 }
273
274 uses flags;
Václav Kubernát280df4a2019-11-01 14:46:34 +0100275
276 choice interface {
277 case caseLoopback {
278 container loopback {
279 leaf ip {
280 type string;
281 }
282 }
283 }
284
285 case caseEthernet {
286 container ethernet {
287 leaf ip {
288 type string;
289 }
290 }
291 }
292 }
293
Václav Kubernáta38d4172019-11-04 12:36:39 +0100294 feature bigPizzas;
295
296 leaf pizzaSize {
297 type enumeration {
298 enum large {
299 if-feature "bigPizzas";
300 }
301 enum medium;
302 enum small;
303 }
304 }
305
Václav Kubernát1e09bd62020-02-17 15:13:38 +0100306 leaf length {
307 type int32;
308 units "m";
309 }
310
311 leaf wavelength {
312 type decimal64 {
313 fraction-digits 10;
314 }
315 units "nm";
316 }
317
318 typedef seconds {
319 type int32;
320 units "s";
321 }
322
323 leaf duration {
324 type seconds;
325 }
326
327 leaf another-duration {
328 type seconds;
329 units "vt";
330 }
331
Václav Kubernátbd5e3c22020-02-19 15:22:00 +0100332 leaf activeNumber {
333 type leafref {
334 path "/_list/number";
335 }
336 }
337
Václav Kubernátfa81c8c2020-02-13 17:22:46 +0100338 rpc myRpc {}
339
Václav Kubernátd8408e02020-12-02 05:13:27 +0100340 rpc rpcOneOutput {
341 output {
342 leaf ahoj {
343 type string;
344 }
345 }
346 }
347
348 rpc rpcOneInput {
349 input {
350 leaf ahoj {
351 type string;
352 }
353 }
354 }
355
Václav Kubernát2984f442020-02-20 17:43:35 +0100356 leaf numberOrString {
357 type union {
358 type int32;
359 type string;
360 }
361 description "Can be an int32 or a string.";
362 }
363
364 list portSettings {
365 key "port";
366 leaf port {
367 type enumeration {
368 enum eth0;
369 enum eth1;
370 enum eth2;
371 }
372 }
Václav Kubernáta8789602020-07-20 15:18:19 +0200373 action shutdown {
374 output {
375 leaf success {
376 type boolean;
377 }
378 }
379 }
Václav Kubernát2984f442020-02-20 17:43:35 +0100380 }
381
382 feature weirdPortNames;
383
384 list portMapping {
385 key "port";
386 leaf port {
387 type enumeration {
388 enum WEIRD {
389 if-feature "weirdPortNames";
390 }
391 enum utf2;
392 enum utf3;
393 }
394 }
395 }
396
397 leaf activeMappedPort {
398 type leafref {
399 path "../portMapping/port";
400 }
401 }
402
403 leaf activePort {
404 type union {
405 type enumeration {
406 enum wlan0;
407 enum wlan1;
408 }
409 type leafref {
410 path "../portSettings/port";
411 }
412 type leafref {
413 path "../activeMappedPort";
414 }
Jan Kundrát379bb572020-05-07 03:23:13 +0200415 type empty;
Václav Kubernát2984f442020-02-20 17:43:35 +0100416 }
417 }
418
Jan Kundrát379bb572020-05-07 03:23:13 +0200419 leaf dummyLeaf {
420 type empty;
421 }
422
Václav Kubernát0599e9f2020-04-21 09:51:33 +0200423 leaf clockSpeed {
424 type int64;
425 config false;
426 }
427
428 container systemStats {
429 config false;
430 leaf upTime {
431 type uint64;
432 }
433 }
434
Václav Kubernáta1c4c9e2020-04-22 00:37:52 +0200435 leaf obsoleteLeaf {
436 type int32;
437 status obsolete;
438 }
439
440 leaf deprecatedLeaf {
441 type int32;
442 status deprecated;
443 }
444
445 typedef deprecatedType {
446 type int32;
447 status deprecated;
448 }
449
450 leaf obsoleteLeafWithDeprecatedType {
451 type deprecatedType;
452 status obsolete;
453 }
454
455 typedef obsoleteType {
456 type int32;
457 status obsolete;
458 }
459
460 leaf obsoleteLeafWithObsoleteType {
461 type deprecatedType;
462 status obsolete;
463 }
464
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200465 leaf-list addresses {
466 type string;
467 }
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100468
469 leaf flagBits {
470 type bits {
471 bit carry;
472 bit sign;
473 bit overflow;
474 }
475 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200476})";
477
478TEST_CASE("yangschema")
479{
Václav Kubernát82d74632020-05-11 15:59:53 +0200480 using namespace std::string_literals;
Václav Kubernát4f77a252019-02-19 16:51:30 +0100481 using namespace std::string_view_literals;
Václav Kubernát0d4db442018-07-18 17:18:43 +0200482 YangSchema ys;
Václav Kubernát82d74632020-05-11 15:59:53 +0200483 ys.registerModuleCallback([]([[maybe_unused]] auto modName, auto, auto subModule, auto) {
484 if (modName != "example-schema"sv) {
485 throw std::logic_error("unrecognized module "s + modName);
486 }
487 if (subModule == nullptr) {
488 return example_schema;
489 }
490 if (subModule == "sub-module"sv) {
491 return included_submodule;
492 }
493
494 throw std::logic_error("unrecognized submodule "s + subModule);
Václav Kubernát4f77a252019-02-19 16:51:30 +0100495 });
496 ys.addSchemaString(second_schema);
Václav Kubernát4841f132022-01-12 00:52:30 +0100497 ys.addSchemaString(R"(
498module schema-with-revision {
499 yang-version 1.1;
500 namespace "http://example.com/lol";
501 prefix oof;
502
503 revision "2022-01-12";
504}
505 )");
Václav Kubernát4f77a252019-02-19 16:51:30 +0100506
Václav Kubernátefcac932020-01-10 15:26:32 +0100507 schemaPath_ path{Scope::Absolute, {}};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200508 ModuleNodePair node;
509
510 SECTION("positive")
511 {
Václav Kubernát0d4db442018-07-18 17:18:43 +0200512 SECTION("isModule")
513 {
Václav Kubernát75877de2019-11-20 17:43:02 +0100514 REQUIRE(ys.isModule("example-schema"));
Václav Kubernát4841f132022-01-12 00:52:30 +0100515 REQUIRE(ys.isModule("schema-with-revision"));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200516 }
Václav Kubernáteeb38842019-03-20 19:46:05 +0100517
Václav Kubernát0d4db442018-07-18 17:18:43 +0200518 SECTION("listHasKey")
519 {
520 std::string key;
521
522 SECTION("_list")
523 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200524 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"_list"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200525 SECTION("number")
Václav Kubernát912b9492020-05-29 02:03:40 +0200526 {
527 key = "number";
528 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200529 }
530
531 SECTION("twoKeyList")
532 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200533 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"twoKeyList"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200534 SECTION("number")
Václav Kubernát912b9492020-05-29 02:03:40 +0200535 {
536 key = "number";
537 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200538 SECTION("name")
Václav Kubernát912b9492020-05-29 02:03:40 +0200539 {
540 key = "name";
541 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200542 }
543
Václav Kubernát912b9492020-05-29 02:03:40 +0200544 REQUIRE(ys.listHasKey(path, key));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200545 }
546 SECTION("listKeys")
547 {
548 std::set<std::string> set;
549
550 SECTION("_list")
551 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200552 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"_list"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200553 set = {"number"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200554 }
555
556 SECTION("twoKeyList")
557 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200558 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"twoKeyList"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200559 set = {"number", "name"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200560 }
561
Václav Kubernát912b9492020-05-29 02:03:40 +0200562 REQUIRE(ys.listKeys(path) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200563 }
564 SECTION("leafType")
565 {
Václav Kubernát3a99f002020-03-31 02:27:41 +0200566 yang::LeafDataType type;
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100567 std::optional<std::string> expectedDescription;
Václav Kubernát0d4db442018-07-18 17:18:43 +0200568
569 SECTION("leafString")
570 {
571 node.first = "example-schema";
572 node.second = "leafString";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200573 type = yang::String{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200574 }
575
576 SECTION("leafDecimal")
577 {
578 node.first = "example-schema";
579 node.second = "leafDecimal";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200580 type = yang::Decimal{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200581 }
582
583 SECTION("leafBool")
584 {
585 node.first = "example-schema";
586 node.second = "leafBool";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200587 type = yang::Bool{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200588 }
589
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200590 SECTION("leafInt8")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200591 {
592 node.first = "example-schema";
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200593 node.second = "leafInt8";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200594 type = yang::Int8{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200595 }
596
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200597 SECTION("leafUint8")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200598 {
599 node.first = "example-schema";
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200600 node.second = "leafUint8";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200601 type = yang::Uint8{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200602 }
603
Václav Kubernátb6d02752020-04-03 00:25:10 +0200604 SECTION("leafInt16")
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200605 {
606 node.first = "example-schema";
607 node.second = "leafInt16";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200608 type = yang::Int16{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200609 }
610
611 SECTION("leafUint16")
612 {
613 node.first = "example-schema";
614 node.second = "leafUint16";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200615 type = yang::Uint16{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200616 }
617
618 SECTION("leafInt32")
619 {
620 node.first = "example-schema";
621 node.second = "leafInt32";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200622 type = yang::Int32{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200623 }
624
625 SECTION("leafUint32")
626 {
627 node.first = "example-schema";
628 node.second = "leafUint32";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200629 type = yang::Uint32{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200630 }
631
632 SECTION("leafInt64")
633 {
634 node.first = "example-schema";
635 node.second = "leafInt64";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200636 type = yang::Int64{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200637 }
638
639 SECTION("leafUint64")
640 {
641 node.first = "example-schema";
642 node.second = "leafUint64";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200643 type = yang::Uint64{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200644 }
645
646 SECTION("leafEnum")
647 {
648 node.first = "example-schema";
649 node.second = "leafEnum";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200650 type = createEnum({"lol", "data", "coze"});
651 }
652
653 SECTION("leafEnumTypedef")
654 {
655 node.first = "example-schema";
656 node.second = "leafEnumTypedef";
657 type = createEnum({"lol", "data", "coze"});
658 }
659
660 SECTION("leafEnumTypedefRestricted")
661 {
662 node.first = "example-schema";
663 node.second = "leafEnumTypedefRestricted";
664 type = createEnum({"data", "coze"});
665 }
666
667 SECTION("leafEnumTypedefRestricted2")
668 {
669 node.first = "example-schema";
670 node.second = "leafEnumTypedefRestricted2";
671 type = createEnum({"lol", "data"});
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100672 expectedDescription = "This is a restricted enum typedef.";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200673 }
674
675 SECTION("pizzaSize")
676 {
677 node.first = "example-schema";
678 node.second = "pizzaSize";
679
680 SECTION("bigPizzas disabled")
681 {
682 type = createEnum({"small", "medium"});
683 }
684 SECTION("bigPizzas enabled")
685 {
686 ys.enableFeature("example-schema", "bigPizzas");
687 type = createEnum({"small", "medium", "large"});
688 }
689 }
690
691 SECTION("foodIdentLeaf")
692 {
693 node.first = "example-schema";
694 node.second = "foodIdentLeaf";
695 type = yang::IdentityRef{{{"second-schema", "pineapple"},
Václav Kubernát3a99f002020-03-31 02:27:41 +0200696 {"example-schema", "pizza"},
697 {"example-schema", "hawaii"},
698 {"example-schema", "fruit"}}};
699 }
700
701 SECTION("pizzaIdentLeaf")
702 {
703 node.first = "example-schema";
704 node.second = "pizzaIdentLeaf";
705
706 type = yang::IdentityRef{{
Václav Kubernát3a99f002020-03-31 02:27:41 +0200707 {"example-schema", "hawaii"},
708 }};
709 }
710
711 SECTION("foodDrinkIdentLeaf")
712 {
713 node.first = "example-schema";
714 node.second = "foodDrinkIdentLeaf";
715
716 type = yang::IdentityRef{{
Václav Kubernát3a99f002020-03-31 02:27:41 +0200717 {"example-schema", "fruit"},
718 {"example-schema", "hawaii"},
719 {"example-schema", "pizza"},
720 {"example-schema", "voda"},
721 {"second-schema", "pineapple"},
722 }};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200723 }
724
Václav Kubernátb6d02752020-04-03 00:25:10 +0200725 SECTION("activeNumber")
726 {
727 node.first = "example-schema";
728 node.second = "activeNumber";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200729 type.emplace<yang::LeafRef>(
730 "/example-schema:_list/number",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200731 std::make_unique<yang::TypeInfo>(ys.leafType("/example-schema:_list/number"))
Václav Kubernát3a99f002020-03-31 02:27:41 +0200732 );
Václav Kubernátb6d02752020-04-03 00:25:10 +0200733 }
734
Václav Kubernát2984f442020-02-20 17:43:35 +0100735 SECTION("activePort")
736 {
737 node.first = "example-schema";
738 node.second = "activePort";
739
Václav Kubernát1dc9e3e2020-06-09 15:22:39 +0200740 yang::Enum enums({});
741 SECTION("weird ports disabled")
742 {
743 enums = createEnum({"utf2", "utf3"});
744 }
745 SECTION("weird ports enabled")
746 {
747 ys.enableFeature("example-schema", "weirdPortNames");
748 enums = createEnum({"WEIRD", "utf2", "utf3"});
749 }
Václav Kubernát2984f442020-02-20 17:43:35 +0100750
751 type = yang::Union{{
Václav Kubernát13b23d72020-04-16 21:49:51 +0200752 yang::TypeInfo{createEnum({"wlan0", "wlan1"})},
753 yang::TypeInfo{yang::LeafRef{
Václav Kubernát2984f442020-02-20 17:43:35 +0100754 "/example-schema:portSettings/port",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200755 std::make_unique<yang::TypeInfo>(createEnum({"eth0", "eth1", "eth2"}))
756 }},
757 yang::TypeInfo{yang::LeafRef{
Václav Kubernát2984f442020-02-20 17:43:35 +0100758 "/example-schema:activeMappedPort",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200759 std::make_unique<yang::TypeInfo>(yang::LeafRef{
Václav Kubernát2984f442020-02-20 17:43:35 +0100760 "/example-schema:portMapping/port",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200761 std::make_unique<yang::TypeInfo>(enums)
762 })
763 }},
Jan Kundrát379bb572020-05-07 03:23:13 +0200764 yang::TypeInfo{yang::Empty{}},
Václav Kubernát2984f442020-02-20 17:43:35 +0100765 }};
766 }
767
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200768 SECTION("addresses")
769 {
770 node.first = "example-schema";
771 node.second = "addresses";
772 type.emplace<yang::String>();
773 }
774
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100775 SECTION("flagBits")
776 {
777 node.first = "example-schema";
778 node.second = "flagBits";
779 type = yang::Bits{{"carry", "sign", "overflow"}};
780 }
781
Václav Kubernátfa36c822021-01-25 07:51:02 +0100782 SECTION("foodTypedef")
783 {
784 node.first = "example-schema";
785 node.second = "leafFoodTypedef";
786 type = yang::IdentityRef{{
Václav Kubernátfa36c822021-01-25 07:51:02 +0100787 {"example-schema", "fruit"},
788 {"example-schema", "hawaii"},
789 {"example-schema", "pizza"},
790 {"second-schema", "pineapple"},
791 }};
792 }
793
Václav Kubernát97f6b602022-01-17 23:55:51 +0100794 SECTION("leafNoValidIdent")
795 {
796 node.first = "example-schema";
797 node.second = "leafNoValidIdent";
798 type = yang::IdentityRef{{}};
799 }
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200800
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100801 REQUIRE(ys.leafType(path, node) == yang::TypeInfo(type, std::nullopt, expectedDescription));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200802 }
Václav Kubernát3a823f42020-04-29 23:40:21 +0200803 SECTION("availableNodes")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200804 {
Václav Kubernát3a823f42020-04-29 23:40:21 +0200805 // TODO: merge "path" and "module" sections and add recursive versions to the path section
806 SECTION("paths")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200807 {
Václav Kubernát95b08872020-04-28 01:04:17 +0200808 std::set<ModuleNodePair> set;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200809
Václav Kubernát95b08872020-04-28 01:04:17 +0200810 using namespace std::string_literals;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200811 SECTION("<root>")
812 {
Václav Kubernát95b08872020-04-28 01:04:17 +0200813 set = {{"example-schema"s, "a"}, {"example-schema"s, "b"}, {"example-schema"s, "leafString"},
814 {"example-schema"s, "leafDecimal"}, {"example-schema"s, "leafBool"},
815 {"example-schema"s, "leafInt8"}, {"example-schema"s, "leafUint8"},
816 {"example-schema"s, "leafInt16"}, {"example-schema"s, "leafUint16"},
817 {"example-schema"s, "leafInt32"}, {"example-schema"s, "leafUint32"},
818 {"example-schema"s, "leafInt64"}, {"example-schema"s, "leafUint64"},
819 {"example-schema"s, "leafEnum"}, {"example-schema"s, "leafEnumTypedef"},
820 {"example-schema"s, "leafEnumTypedefRestricted"}, {"example-schema"s, "leafEnumTypedefRestricted2"},
821 {"example-schema"s, "foodIdentLeaf"}, {"example-schema"s, "pizzaIdentLeaf"}, {"example-schema"s, "foodDrinkIdentLeaf"},
822 {"example-schema"s, "_list"}, {"example-schema"s, "twoKeyList"}, {"second-schema"s, "bla"},
823 {"example-schema"s, "carry"}, {"example-schema"s, "zero"}, {"example-schema"s, "direction"},
824 {"example-schema"s, "interrupt"},
825 {"example-schema"s, "ethernet"}, {"example-schema"s, "loopback"},
826 {"example-schema"s, "pizzaSize"},
827 {"example-schema"s, "length"}, {"example-schema"s, "wavelength"},
828 {"example-schema"s, "duration"}, {"example-schema"s, "another-duration"},
829 {"example-schema"s, "activeNumber"},
830 {"example-schema"s, "numberOrString"},
831 {"example-schema"s, "portSettings"},
832 {"example-schema"s, "portMapping"},
833 {"example-schema"s, "activeMappedPort"},
834 {"example-schema"s, "activePort"},
835 {"example-schema"s, "clockSpeed"},
836 {"example-schema"s, "deprecatedLeaf"},
837 {"example-schema"s, "obsoleteLeaf"},
838 {"example-schema"s, "obsoleteLeafWithDeprecatedType"},
839 {"example-schema"s, "obsoleteLeafWithObsoleteType"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200840 {"example-schema"s, "myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100841 {"example-schema"s, "rpcOneOutput"},
842 {"example-schema"s, "rpcOneInput"},
Václav Kubernát82d74632020-05-11 15:59:53 +0200843 {"example-schema"s, "systemStats"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200844 {"example-schema"s, "dummyLeaf"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200845 {"example-schema"s, "addresses"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100846 {"example-schema"s, "subLeaf"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100847 {"example-schema"s, "flagBits"},
Václav Kubernát97f6b602022-01-17 23:55:51 +0100848 {"example-schema"s, "leafFoodTypedef"},
849 {"example-schema"s, "leafNoValidIdent"}};
Václav Kubernát3a823f42020-04-29 23:40:21 +0200850 }
851
852 SECTION("example-schema:a")
853 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200854 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200855 set = {
856 {boost::none, "a2"},
857 {boost::none, "leafa"},
858 {"second-schema"s, "augmentedContainer"}
859 };
Václav Kubernát3a823f42020-04-29 23:40:21 +0200860 }
861
862 SECTION("example-schema:ethernet")
863 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200864 path.m_nodes.emplace_back(module_{"example-schema"}, container_("ethernet"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200865 set = {{boost::none, "ip"}};
866 }
867
868 SECTION("second-schema:bla")
869 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200870 path.m_nodes.emplace_back(module_{"second-schema"}, container_("bla"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200871 set = {{boost::none, "bla2"}};
Václav Kubernát3a823f42020-04-29 23:40:21 +0200872 }
873
874 REQUIRE(ys.availableNodes(path, Recursion::NonRecursive) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200875 }
876
Václav Kubernát3a823f42020-04-29 23:40:21 +0200877 SECTION("modules")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200878 {
Václav Kubernát3a823f42020-04-29 23:40:21 +0200879 std::string module;
Václav Kubernát95b08872020-04-28 01:04:17 +0200880 std::set<ModuleNodePair> expectedNonRecursive;
881 std::set<ModuleNodePair> expectedRecursive;
882 using namespace std::string_literals;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200883 SECTION("example-schema")
884 {
885 module = "example-schema";
886 expectedNonRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +0200887 {"example-schema"s, "_list"},
888 {"example-schema"s, "a"},
889 {"example-schema"s, "activeMappedPort"},
890 {"example-schema"s, "activeNumber"},
891 {"example-schema"s, "activePort"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200892 {"example-schema"s, "addresses"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200893 {"example-schema"s, "another-duration"},
894 {"example-schema"s, "b"},
895 {"example-schema"s, "carry"},
896 {"example-schema"s, "clockSpeed"},
897 {"example-schema"s, "deprecatedLeaf"},
898 {"example-schema"s, "direction"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200899 {"example-schema"s, "dummyLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200900 {"example-schema"s, "duration"},
901 {"example-schema"s, "ethernet"},
902 {"example-schema"s, "foodDrinkIdentLeaf"},
903 {"example-schema"s, "foodIdentLeaf"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100904 {"example-schema"s, "flagBits"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200905 {"example-schema"s, "interrupt"},
906 {"example-schema"s, "leafBool"},
907 {"example-schema"s, "leafDecimal"},
908 {"example-schema"s, "leafEnum"},
909 {"example-schema"s, "leafEnumTypedef"},
910 {"example-schema"s, "leafEnumTypedefRestricted"},
911 {"example-schema"s, "leafEnumTypedefRestricted2"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100912 {"example-schema"s, "leafFoodTypedef"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200913 {"example-schema"s, "leafInt16"},
914 {"example-schema"s, "leafInt32"},
915 {"example-schema"s, "leafInt64"},
916 {"example-schema"s, "leafInt8"},
Václav Kubernát97f6b602022-01-17 23:55:51 +0100917 {"example-schema"s, "leafNoValidIdent"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200918 {"example-schema"s, "leafString"},
919 {"example-schema"s, "leafUint16"},
920 {"example-schema"s, "leafUint32"},
921 {"example-schema"s, "leafUint64"},
922 {"example-schema"s, "leafUint8"},
923 {"example-schema"s, "length"},
924 {"example-schema"s, "loopback"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200925 {"example-schema"s, "myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100926 {"example-schema"s, "rpcOneOutput"},
927 {"example-schema"s, "rpcOneInput"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200928 {"example-schema"s, "numberOrString"},
929 {"example-schema"s, "obsoleteLeaf"},
930 {"example-schema"s, "obsoleteLeafWithDeprecatedType"},
931 {"example-schema"s, "obsoleteLeafWithObsoleteType"},
932 {"example-schema"s, "pizzaIdentLeaf"},
933 {"example-schema"s, "pizzaSize"},
934 {"example-schema"s, "portMapping"},
935 {"example-schema"s, "portSettings"},
936 {"example-schema"s, "systemStats"},
937 {"example-schema"s, "twoKeyList"},
938 {"example-schema"s, "wavelength"},
Václav Kubernát82d74632020-05-11 15:59:53 +0200939 {"example-schema"s, "zero"},
940 {"example-schema"s, "subLeaf"}
Václav Kubernát3a823f42020-04-29 23:40:21 +0200941 };
942 expectedRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +0200943 {boost::none, "/example-schema:_list"},
944 {boost::none, "/example-schema:_list/contInList"},
945 {boost::none, "/example-schema:_list/number"},
946 {boost::none, "/example-schema:a"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200947 {boost::none, "/example-schema:addresses"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200948 {boost::none, "/example-schema:a/a2"},
949 {boost::none, "/example-schema:a/a2/a3"},
950 {boost::none, "/example-schema:a/leafa"},
951 {boost::none, "/example-schema:a/second-schema:augmentedContainer"},
952 {boost::none, "/example-schema:activeMappedPort"},
953 {boost::none, "/example-schema:activeNumber"},
954 {boost::none, "/example-schema:activePort"},
955 {boost::none, "/example-schema:another-duration"},
956 {boost::none, "/example-schema:b"},
957 {boost::none, "/example-schema:b/b2"},
958 {boost::none, "/example-schema:b/b2/b3"},
959 {boost::none, "/example-schema:carry"},
960 {boost::none, "/example-schema:clockSpeed"},
961 {boost::none, "/example-schema:deprecatedLeaf"},
962 {boost::none, "/example-schema:direction"},
963 {boost::none, "/example-schema:duration"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200964 {boost::none, "/example-schema:dummyLeaf"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100965 {boost::none, "/example-schema:flagBits"},
966 {boost::none, "/example-schema:foodDrinkIdentLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200967 {boost::none, "/example-schema:foodDrinkIdentLeaf"},
968 {boost::none, "/example-schema:foodIdentLeaf"},
969 {boost::none, "/example-schema:interface/caseEthernet/ethernet"},
970 {boost::none, "/example-schema:interface/caseEthernet/ethernet/ip"},
971 {boost::none, "/example-schema:interface/caseLoopback/loopback"},
972 {boost::none, "/example-schema:interface/caseLoopback/loopback/ip"},
973 {boost::none, "/example-schema:interrupt"},
974 {boost::none, "/example-schema:leafBool"},
975 {boost::none, "/example-schema:leafDecimal"},
976 {boost::none, "/example-schema:leafEnum"},
977 {boost::none, "/example-schema:leafEnumTypedef"},
978 {boost::none, "/example-schema:leafEnumTypedefRestricted"},
979 {boost::none, "/example-schema:leafEnumTypedefRestricted2"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100980 {boost::none, "/example-schema:leafFoodTypedef"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200981 {boost::none, "/example-schema:leafInt16"},
982 {boost::none, "/example-schema:leafInt32"},
983 {boost::none, "/example-schema:leafInt64"},
984 {boost::none, "/example-schema:leafInt8"},
Václav Kubernát97f6b602022-01-17 23:55:51 +0100985 {boost::none, "/example-schema:leafNoValidIdent"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200986 {boost::none, "/example-schema:leafString"},
987 {boost::none, "/example-schema:leafUint16"},
988 {boost::none, "/example-schema:leafUint32"},
989 {boost::none, "/example-schema:leafUint64"},
990 {boost::none, "/example-schema:leafUint8"},
991 {boost::none, "/example-schema:length"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200992 {boost::none, "/example-schema:myRpc"},
993 {boost::none, "/example-schema:myRpc/input"},
994 {boost::none, "/example-schema:myRpc/output"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100995 {boost::none, "/example-schema:rpcOneOutput"},
996 {boost::none, "/example-schema:rpcOneOutput/input"},
997 {boost::none, "/example-schema:rpcOneOutput/output"},
998 {boost::none, "/example-schema:rpcOneOutput/output/ahoj"},
999 {boost::none, "/example-schema:rpcOneInput"},
1000 {boost::none, "/example-schema:rpcOneInput/input"},
1001 {boost::none, "/example-schema:rpcOneInput/input/ahoj"},
1002 {boost::none, "/example-schema:rpcOneInput/output"},
Václav Kubernát95b08872020-04-28 01:04:17 +02001003 {boost::none, "/example-schema:numberOrString"},
1004 {boost::none, "/example-schema:obsoleteLeaf"},
1005 {boost::none, "/example-schema:obsoleteLeafWithDeprecatedType"},
1006 {boost::none, "/example-schema:obsoleteLeafWithObsoleteType"},
1007 {boost::none, "/example-schema:pizzaIdentLeaf"},
1008 {boost::none, "/example-schema:pizzaSize"},
1009 {boost::none, "/example-schema:portMapping"},
1010 {boost::none, "/example-schema:portMapping/port"},
1011 {boost::none, "/example-schema:portSettings"},
1012 {boost::none, "/example-schema:portSettings/port"},
Václav Kubernáta8789602020-07-20 15:18:19 +02001013 {boost::none, "/example-schema:portSettings/shutdown"},
1014 {boost::none, "/example-schema:portSettings/shutdown/input"},
1015 {boost::none, "/example-schema:portSettings/shutdown/output"},
1016 {boost::none, "/example-schema:portSettings/shutdown/output/success"},
Václav Kubernát95b08872020-04-28 01:04:17 +02001017 {boost::none, "/example-schema:systemStats"},
1018 {boost::none, "/example-schema:systemStats/upTime"},
Václav Kubernát82d74632020-05-11 15:59:53 +02001019 {boost::none, "/example-schema:subLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +02001020 {boost::none, "/example-schema:twoKeyList"},
1021 {boost::none, "/example-schema:twoKeyList/name"},
1022 {boost::none, "/example-schema:twoKeyList/number"},
1023 {boost::none, "/example-schema:wavelength"},
1024 {boost::none, "/example-schema:zero"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001025 };
1026 }
Václav Kubernát3a823f42020-04-29 23:40:21 +02001027 SECTION("second-schema")
1028 {
1029 module = "second-schema";
1030 expectedNonRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +02001031 {"second-schema"s, "bla"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001032 };
1033 expectedRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +02001034 {boost::none, "/second-schema:bla"},
1035 {boost::none, "/second-schema:bla/bla2"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001036 };
1037 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001038
Václav Kubernát3a823f42020-04-29 23:40:21 +02001039 REQUIRE(ys.availableNodes(module_{module}, Recursion::NonRecursive) == expectedNonRecursive);
1040 REQUIRE(ys.availableNodes(module_{module}, Recursion::Recursive) == expectedRecursive);
Václav Kubernát47a3f672019-11-08 15:42:43 +01001041 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001042 }
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001043 SECTION("nodeType")
1044 {
1045 yang::NodeTypes expected;
1046 SECTION("leafInt32")
1047 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001048 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001049 expected = yang::NodeTypes::Leaf;
1050 }
1051
1052 SECTION("a")
1053 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001054 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001055 expected = yang::NodeTypes::Container;
1056 }
1057
1058 SECTION("a/a2/a3")
1059 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001060 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1061 path.m_nodes.emplace_back(container_("a2"));
1062 path.m_nodes.emplace_back(container_("a3"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001063 expected = yang::NodeTypes::PresenceContainer;
1064 }
1065
1066 SECTION("_list")
1067 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001068 path.m_nodes.emplace_back(module_{"example-schema"}, list_("_list"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001069 expected = yang::NodeTypes::List;
1070 }
1071
Václav Kubernát82d74632020-05-11 15:59:53 +02001072 SECTION("subLeaf")
1073 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001074 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("subLeaf"));
Václav Kubernát82d74632020-05-11 15:59:53 +02001075 expected = yang::NodeTypes::Leaf;
1076 }
1077
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001078 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1079 }
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001080
1081 SECTION("description")
1082 {
1083 std::optional<std::string> expected;
1084 SECTION("leafInt32")
1085 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001086 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001087 expected = "A 32-bit integer leaf.";
1088 }
1089
1090 SECTION("leafString")
1091 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001092 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafString"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001093 }
1094
Václav Kubernát2984f442020-02-20 17:43:35 +01001095 SECTION("numberOrString")
1096 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001097 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("numberOrString"));
Václav Kubernát2984f442020-02-20 17:43:35 +01001098 expected = "Can be an int32 or a string.";
1099 }
1100
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001101 REQUIRE(ys.description(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1102 }
1103
Václav Kubernáta1c4c9e2020-04-22 00:37:52 +02001104 SECTION("status")
1105 {
1106 REQUIRE(ys.status("/example-schema:leafUint64") == yang::Status::Current);
1107 REQUIRE(ys.status("/example-schema:obsoleteLeaf") == yang::Status::Obsolete);
1108 REQUIRE(ys.status("/example-schema:deprecatedLeaf") == yang::Status::Deprecated);
1109 REQUIRE(ys.status("/example-schema:obsoleteLeafWithDeprecatedType") == yang::Status::Obsolete);
1110 REQUIRE(ys.status("/example-schema:obsoleteLeafWithObsoleteType") == yang::Status::Obsolete);
1111 }
1112
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001113 SECTION("units")
1114 {
Václav Kubernát13b23d72020-04-16 21:49:51 +02001115 yang::LeafDataType expectedType;
1116 std::optional<std::string> expectedUnits;
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001117 SECTION("length")
1118 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001119 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("length"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001120 expectedType.emplace<yang::Int32>();
1121 expectedUnits = "m";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001122 }
1123
1124 SECTION("wavelength")
1125 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001126 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("wavelength"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001127 expectedType.emplace<yang::Decimal>();
1128 expectedUnits = "nm";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001129 }
1130
1131 SECTION("leafInt32")
1132 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001133 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001134 expectedType.emplace<yang::Int32>();
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001135 }
1136
1137 SECTION("duration")
1138 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001139 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("duration"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001140 expectedType.emplace<yang::Int32>();
1141 expectedUnits = "s";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001142 }
1143
1144 SECTION("another-duration")
1145 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001146 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("another-duration"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001147 expectedType.emplace<yang::Int32>();
1148 expectedUnits = "vt";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001149 }
Václav Kubernát5b8a8f32020-05-20 00:57:22 +02001150 auto nodeType = ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded));
1151 REQUIRE((nodeType == yang::NodeTypes::Leaf || nodeType == yang::NodeTypes::LeafList));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001152 REQUIRE(ys.leafType(pathToSchemaString(path, Prefixes::WhenNeeded)) == yang::TypeInfo{expectedType, expectedUnits});
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001153 }
1154
Václav Kubernát1ae24f42020-12-01 02:32:04 +01001155 SECTION("type description")
1156 {
1157 yang::LeafDataType expectedType = createEnum({"lol", "data"});
1158 std::optional<std::string> expectedDescription;
1159
1160 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafEnumTypedefRestricted2"));
1161 expectedDescription = "This is a restricted enum typedef.";
1162 REQUIRE(ys.leafType(pathToSchemaString(path, Prefixes::WhenNeeded)) == yang::TypeInfo{expectedType, std::nullopt, expectedDescription});
1163 }
1164
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001165 SECTION("nodeType")
1166 {
1167 yang::NodeTypes expected;
1168 SECTION("leafInt32")
1169 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001170 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001171 expected = yang::NodeTypes::Leaf;
1172 }
1173
1174 SECTION("a")
1175 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001176 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001177 expected = yang::NodeTypes::Container;
1178 }
1179
1180 SECTION("a/a2/a3")
1181 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001182 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1183 path.m_nodes.emplace_back(container_("a2"));
1184 path.m_nodes.emplace_back(container_("a3"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001185 expected = yang::NodeTypes::PresenceContainer;
1186 }
1187
1188 SECTION("_list")
1189 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001190 path.m_nodes.emplace_back(module_{"example-schema"}, list_("_list"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001191 expected = yang::NodeTypes::List;
1192 }
1193
1194 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1195 }
Václav Kubernátbd5e3c22020-02-19 15:22:00 +01001196
1197 SECTION("leafrefPath")
1198 {
1199 REQUIRE(ys.leafrefPath("/example-schema:activeNumber") == "/example-schema:_list/number");
1200 }
Václav Kubernát0599e9f2020-04-21 09:51:33 +02001201
1202 SECTION("isConfig")
1203 {
1204 REQUIRE(ys.isConfig("/example-schema:leafInt32"));
1205 REQUIRE_FALSE(ys.isConfig("/example-schema:clockSpeed"));
1206 REQUIRE_FALSE(ys.isConfig("/example-schema:systemStats"));
1207 REQUIRE_FALSE(ys.isConfig("/example-schema:systemStats/upTime"));
1208 }
Václav Kubernátbd0d5c82020-04-21 10:22:03 +02001209
Václav Kubernátb1a75c62020-04-21 15:20:16 +02001210 SECTION("defaultValue")
1211 {
1212 REQUIRE(ys.defaultValue("/example-schema:leafUint64") == "9001");
1213 REQUIRE(ys.defaultValue("/example-schema:leafEnumTypedefRestricted") == "data");
1214 REQUIRE(ys.defaultValue("/example-schema:leafInt32") == std::nullopt);
1215 }
1216
Václav Kubernát76ba4ec2020-05-18 13:26:56 +02001217 SECTION("leafTypeName")
1218 {
1219 REQUIRE(ys.leafTypeName("/example-schema:leafEnumTypedefRestricted") == "enumTypedef");
1220 REQUIRE(ys.leafTypeName("/example-schema:leafInt32") == std::nullopt);
1221 }
Václav Kubernáta8789602020-07-20 15:18:19 +02001222
1223 SECTION("dataPathToSchemaPath")
1224 {
1225 REQUIRE(ys.dataPathToSchemaPath("/example-schema:portSettings[port='eth0']") == "/example-schema:portSettings");
1226 REQUIRE(ys.dataPathToSchemaPath("/example-schema:portSettings[port='eth0']/shutdown") == "/example-schema:portSettings/shutdown");
1227 }
Václav Kubernátd8408e02020-12-02 05:13:27 +01001228
1229 SECTION("has input nodes")
1230 {
1231 bool expected;
1232 SECTION("example-schema:myRpc")
1233 {
1234 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"myRpc"});
1235 expected = false;
1236 }
1237
1238 SECTION("example-schema:rpcOneInput")
1239 {
1240 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"rpcOneInput"});
1241 expected = true;
1242 }
1243
1244 SECTION("example-schema:rpcOneOutput")
1245 {
1246 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"rpcOneOutput"});
1247 expected = false;
1248 }
1249
1250 REQUIRE(ys.hasInputNodes(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1251 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001252 }
1253
1254 SECTION("negative")
1255 {
1256 SECTION("nonexistent nodes")
1257 {
1258 SECTION("example-schema:coze")
1259 {
1260 node.first = "example-schema";
1261 node.second = "coze";
1262 }
1263
1264 SECTION("example-schema:a/nevim")
1265 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001266 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001267 node.second = "nevim";
1268 }
1269
1270 SECTION("modul:a/nevim")
1271 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001272 path.m_nodes.emplace_back(module_{"modul"}, container_("a"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001273 node.second = "nevim";
1274 }
1275
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001276 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001277 }
1278
1279 SECTION("nodetype-specific methods called with different nodetypes")
1280 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001281 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1282 path.m_nodes.emplace_back(container_("a2"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001283
Václav Kubernát912b9492020-05-29 02:03:40 +02001284 REQUIRE(!ys.listHasKey(path, "chacha"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001285 }
1286
1287 SECTION("nonexistent module")
1288 {
Václav Kubernát75877de2019-11-20 17:43:02 +01001289 REQUIRE(!ys.isModule("notAModule"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001290 }
Václav Kubernáteeb38842019-03-20 19:46:05 +01001291
Václav Kubernát7d82da72019-04-11 15:16:38 +02001292 SECTION("grouping is not a node")
1293 {
1294 SECTION("example-schema:arithmeticFlags")
1295 {
1296 node.first = "example-schema";
1297 node.second = "arithmeticFlags";
1298 }
1299
1300 SECTION("example-schema:flags")
1301 {
1302 node.first = "example-schema";
1303 node.second = "startAndStop";
1304 }
1305
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001306 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát7d82da72019-04-11 15:16:38 +02001307 }
Václav Kubernát280df4a2019-11-01 14:46:34 +01001308
1309 SECTION("choice is not a node")
1310 {
1311 SECTION("example-schema:interface")
1312 {
1313 node.first = "example-schema";
1314 node.second = "interface";
1315 }
1316
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001317 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát280df4a2019-11-01 14:46:34 +01001318 }
1319
1320 SECTION("case is not a node")
1321 {
1322 SECTION("example-schema:caseLoopback")
1323 {
1324 node.first = "example-schema";
1325 node.second = "caseLoopback";
1326 }
1327
1328 SECTION("example-schema:caseEthernet")
1329 {
1330 node.first = "example-schema";
1331 node.second = "caseEthernet";
1332 }
1333
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001334 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát280df4a2019-11-01 14:46:34 +01001335 }
Václav Kubernátf44bdda2020-06-22 15:58:41 +02001336
1337 SECTION("enableFeature - non existing module")
1338 {
1339 REQUIRE_THROWS_AS(ys.enableFeature("non-existing", "just-no"), std::runtime_error);
1340 }
Václav Kubernát7aaf6dc2020-06-26 18:03:57 +02001341
1342 SECTION("enableFeature - non existing feature")
1343 {
1344 REQUIRE_THROWS_AS(ys.enableFeature("example-schema", "just-no"), std::runtime_error);
1345 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001346 }
1347}