blob: f56a27bdc5e1e091ef293c2852649e5f5783f5f0 [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 }
Jan Kundrátbb7aa852023-08-30 11:51:43 +0200476
477 leaf iid-valid {
478 type instance-identifier;
479 }
480
481 leaf iid-relaxed {
482 type instance-identifier {
483 require-instance false;
484 }
485 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200486})";
487
488TEST_CASE("yangschema")
489{
490 YangSchema ys;
Jan Kundrátf59b83c2022-03-18 18:12:08 +0100491 ys.registerModuleCallback([](const auto modName, auto, const auto subModule, auto) {
492 if (modName != "example-schema") {
493 throw std::logic_error("unrecognized module " + std::string{modName});
Václav Kubernát82d74632020-05-11 15:59:53 +0200494 }
Jan Kundrátf59b83c2022-03-18 18:12:08 +0100495 if (!subModule) {
Václav Kubernát82d74632020-05-11 15:59:53 +0200496 return example_schema;
497 }
Jan Kundrátf59b83c2022-03-18 18:12:08 +0100498 if (*subModule == "sub-module") {
Václav Kubernát82d74632020-05-11 15:59:53 +0200499 return included_submodule;
500 }
501
Jan Kundrátf59b83c2022-03-18 18:12:08 +0100502 throw std::logic_error("unrecognized submodule " + std::string{*subModule});
Václav Kubernát4f77a252019-02-19 16:51:30 +0100503 });
504 ys.addSchemaString(second_schema);
Václav Kubernát4841f132022-01-12 00:52:30 +0100505 ys.addSchemaString(R"(
506module schema-with-revision {
507 yang-version 1.1;
508 namespace "http://example.com/lol";
509 prefix oof;
510
511 revision "2022-01-12";
512}
513 )");
Václav Kubernát4f77a252019-02-19 16:51:30 +0100514
Václav Kubernátefcac932020-01-10 15:26:32 +0100515 schemaPath_ path{Scope::Absolute, {}};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200516 ModuleNodePair node;
517
518 SECTION("positive")
519 {
Václav Kubernát0d4db442018-07-18 17:18:43 +0200520 SECTION("isModule")
521 {
Václav Kubernát75877de2019-11-20 17:43:02 +0100522 REQUIRE(ys.isModule("example-schema"));
Václav Kubernát4841f132022-01-12 00:52:30 +0100523 REQUIRE(ys.isModule("schema-with-revision"));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200524 }
Václav Kubernáteeb38842019-03-20 19:46:05 +0100525
Václav Kubernát0d4db442018-07-18 17:18:43 +0200526 SECTION("listHasKey")
527 {
528 std::string key;
529
530 SECTION("_list")
531 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200532 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"_list"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200533 SECTION("number")
Václav Kubernát912b9492020-05-29 02:03:40 +0200534 {
535 key = "number";
536 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200537 }
538
539 SECTION("twoKeyList")
540 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200541 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"twoKeyList"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200542 SECTION("number")
Václav Kubernát912b9492020-05-29 02:03:40 +0200543 {
544 key = "number";
545 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200546 SECTION("name")
Václav Kubernát912b9492020-05-29 02:03:40 +0200547 {
548 key = "name";
549 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200550 }
551
Václav Kubernát912b9492020-05-29 02:03:40 +0200552 REQUIRE(ys.listHasKey(path, key));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200553 }
554 SECTION("listKeys")
555 {
556 std::set<std::string> set;
557
558 SECTION("_list")
559 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200560 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"_list"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200561 set = {"number"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200562 }
563
564 SECTION("twoKeyList")
565 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200566 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"twoKeyList"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200567 set = {"number", "name"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200568 }
569
Václav Kubernát912b9492020-05-29 02:03:40 +0200570 REQUIRE(ys.listKeys(path) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200571 }
572 SECTION("leafType")
573 {
Václav Kubernát3a99f002020-03-31 02:27:41 +0200574 yang::LeafDataType type;
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100575 std::optional<std::string> expectedDescription;
Václav Kubernát0d4db442018-07-18 17:18:43 +0200576
577 SECTION("leafString")
578 {
579 node.first = "example-schema";
580 node.second = "leafString";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200581 type = yang::String{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200582 }
583
584 SECTION("leafDecimal")
585 {
586 node.first = "example-schema";
587 node.second = "leafDecimal";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200588 type = yang::Decimal{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200589 }
590
591 SECTION("leafBool")
592 {
593 node.first = "example-schema";
594 node.second = "leafBool";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200595 type = yang::Bool{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200596 }
597
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200598 SECTION("leafInt8")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200599 {
600 node.first = "example-schema";
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200601 node.second = "leafInt8";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200602 type = yang::Int8{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200603 }
604
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200605 SECTION("leafUint8")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200606 {
607 node.first = "example-schema";
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200608 node.second = "leafUint8";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200609 type = yang::Uint8{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200610 }
611
Václav Kubernátb6d02752020-04-03 00:25:10 +0200612 SECTION("leafInt16")
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200613 {
614 node.first = "example-schema";
615 node.second = "leafInt16";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200616 type = yang::Int16{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200617 }
618
619 SECTION("leafUint16")
620 {
621 node.first = "example-schema";
622 node.second = "leafUint16";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200623 type = yang::Uint16{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200624 }
625
626 SECTION("leafInt32")
627 {
628 node.first = "example-schema";
629 node.second = "leafInt32";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200630 type = yang::Int32{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200631 }
632
633 SECTION("leafUint32")
634 {
635 node.first = "example-schema";
636 node.second = "leafUint32";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200637 type = yang::Uint32{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200638 }
639
640 SECTION("leafInt64")
641 {
642 node.first = "example-schema";
643 node.second = "leafInt64";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200644 type = yang::Int64{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200645 }
646
647 SECTION("leafUint64")
648 {
649 node.first = "example-schema";
650 node.second = "leafUint64";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200651 type = yang::Uint64{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200652 }
653
654 SECTION("leafEnum")
655 {
656 node.first = "example-schema";
657 node.second = "leafEnum";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200658 type = createEnum({"lol", "data", "coze"});
659 }
660
661 SECTION("leafEnumTypedef")
662 {
663 node.first = "example-schema";
664 node.second = "leafEnumTypedef";
665 type = createEnum({"lol", "data", "coze"});
666 }
667
668 SECTION("leafEnumTypedefRestricted")
669 {
670 node.first = "example-schema";
671 node.second = "leafEnumTypedefRestricted";
672 type = createEnum({"data", "coze"});
673 }
674
675 SECTION("leafEnumTypedefRestricted2")
676 {
677 node.first = "example-schema";
678 node.second = "leafEnumTypedefRestricted2";
679 type = createEnum({"lol", "data"});
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100680 expectedDescription = "This is a restricted enum typedef.";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200681 }
682
683 SECTION("pizzaSize")
684 {
685 node.first = "example-schema";
686 node.second = "pizzaSize";
687
688 SECTION("bigPizzas disabled")
689 {
690 type = createEnum({"small", "medium"});
691 }
692 SECTION("bigPizzas enabled")
693 {
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200694 ys.setEnabledFeatures("example-schema", {"bigPizzas"});
Václav Kubernát3a99f002020-03-31 02:27:41 +0200695 type = createEnum({"small", "medium", "large"});
696 }
697 }
698
699 SECTION("foodIdentLeaf")
700 {
701 node.first = "example-schema";
702 node.second = "foodIdentLeaf";
703 type = yang::IdentityRef{{{"second-schema", "pineapple"},
Václav Kubernát3a99f002020-03-31 02:27:41 +0200704 {"example-schema", "pizza"},
705 {"example-schema", "hawaii"},
706 {"example-schema", "fruit"}}};
707 }
708
709 SECTION("pizzaIdentLeaf")
710 {
711 node.first = "example-schema";
712 node.second = "pizzaIdentLeaf";
713
714 type = yang::IdentityRef{{
Václav Kubernát3a99f002020-03-31 02:27:41 +0200715 {"example-schema", "hawaii"},
716 }};
717 }
718
719 SECTION("foodDrinkIdentLeaf")
720 {
721 node.first = "example-schema";
722 node.second = "foodDrinkIdentLeaf";
723
724 type = yang::IdentityRef{{
Václav Kubernát3a99f002020-03-31 02:27:41 +0200725 {"example-schema", "fruit"},
726 {"example-schema", "hawaii"},
727 {"example-schema", "pizza"},
728 {"example-schema", "voda"},
729 {"second-schema", "pineapple"},
730 }};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200731 }
732
Václav Kubernátb6d02752020-04-03 00:25:10 +0200733 SECTION("activeNumber")
734 {
735 node.first = "example-schema";
736 node.second = "activeNumber";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200737 type.emplace<yang::LeafRef>(
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200738 "/_list/number",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200739 std::make_unique<yang::TypeInfo>(ys.leafType("/example-schema:_list/number"))
Václav Kubernát3a99f002020-03-31 02:27:41 +0200740 );
Václav Kubernátb6d02752020-04-03 00:25:10 +0200741 }
742
Václav Kubernát2984f442020-02-20 17:43:35 +0100743 SECTION("activePort")
744 {
745 node.first = "example-schema";
746 node.second = "activePort";
747
Václav Kubernát1dc9e3e2020-06-09 15:22:39 +0200748 yang::Enum enums({});
749 SECTION("weird ports disabled")
750 {
751 enums = createEnum({"utf2", "utf3"});
752 }
753 SECTION("weird ports enabled")
754 {
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200755 ys.setEnabledFeatures("example-schema", {"weirdPortNames"});
Václav Kubernát1dc9e3e2020-06-09 15:22:39 +0200756 enums = createEnum({"WEIRD", "utf2", "utf3"});
757 }
Václav Kubernát2984f442020-02-20 17:43:35 +0100758
759 type = yang::Union{{
Václav Kubernát13b23d72020-04-16 21:49:51 +0200760 yang::TypeInfo{createEnum({"wlan0", "wlan1"})},
761 yang::TypeInfo{yang::LeafRef{
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200762 "../portSettings/port",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200763 std::make_unique<yang::TypeInfo>(createEnum({"eth0", "eth1", "eth2"}))
764 }},
765 yang::TypeInfo{yang::LeafRef{
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200766 "../activeMappedPort",
767 std::make_unique<yang::TypeInfo>(enums)
Václav Kubernát13b23d72020-04-16 21:49:51 +0200768 }},
Jan Kundrát379bb572020-05-07 03:23:13 +0200769 yang::TypeInfo{yang::Empty{}},
Václav Kubernát2984f442020-02-20 17:43:35 +0100770 }};
771 }
772
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200773 SECTION("addresses")
774 {
775 node.first = "example-schema";
776 node.second = "addresses";
777 type.emplace<yang::String>();
778 }
779
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100780 SECTION("flagBits")
781 {
782 node.first = "example-schema";
783 node.second = "flagBits";
784 type = yang::Bits{{"carry", "sign", "overflow"}};
785 }
786
Václav Kubernátfa36c822021-01-25 07:51:02 +0100787 SECTION("foodTypedef")
788 {
789 node.first = "example-schema";
790 node.second = "leafFoodTypedef";
791 type = yang::IdentityRef{{
Václav Kubernátfa36c822021-01-25 07:51:02 +0100792 {"example-schema", "fruit"},
793 {"example-schema", "hawaii"},
794 {"example-schema", "pizza"},
795 {"second-schema", "pineapple"},
796 }};
797 }
798
Václav Kubernát97f6b602022-01-17 23:55:51 +0100799 SECTION("leafNoValidIdent")
800 {
801 node.first = "example-schema";
802 node.second = "leafNoValidIdent";
803 type = yang::IdentityRef{{}};
804 }
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200805
Jan Kundrátbb7aa852023-08-30 11:51:43 +0200806 SECTION("instance-identifier required")
807 {
808 node.first = "example-schema";
809 node.second = "iid-valid";
810 type = yang::InstanceIdentifier{};
811 }
812
813 SECTION("instance-identifier relaxed")
814 {
815 node.first = "example-schema";
816 node.second = "iid-relaxed";
817 type = yang::InstanceIdentifier{};
818 }
819
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100820 REQUIRE(ys.leafType(path, node) == yang::TypeInfo(type, std::nullopt, expectedDescription));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200821 }
Václav Kubernát3a823f42020-04-29 23:40:21 +0200822 SECTION("availableNodes")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200823 {
Václav Kubernát3a823f42020-04-29 23:40:21 +0200824 // TODO: merge "path" and "module" sections and add recursive versions to the path section
825 SECTION("paths")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200826 {
Václav Kubernát95b08872020-04-28 01:04:17 +0200827 std::set<ModuleNodePair> set;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200828
Václav Kubernát95b08872020-04-28 01:04:17 +0200829 using namespace std::string_literals;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200830 SECTION("<root>")
831 {
Václav Kubernát95b08872020-04-28 01:04:17 +0200832 set = {{"example-schema"s, "a"}, {"example-schema"s, "b"}, {"example-schema"s, "leafString"},
833 {"example-schema"s, "leafDecimal"}, {"example-schema"s, "leafBool"},
834 {"example-schema"s, "leafInt8"}, {"example-schema"s, "leafUint8"},
835 {"example-schema"s, "leafInt16"}, {"example-schema"s, "leafUint16"},
836 {"example-schema"s, "leafInt32"}, {"example-schema"s, "leafUint32"},
837 {"example-schema"s, "leafInt64"}, {"example-schema"s, "leafUint64"},
838 {"example-schema"s, "leafEnum"}, {"example-schema"s, "leafEnumTypedef"},
839 {"example-schema"s, "leafEnumTypedefRestricted"}, {"example-schema"s, "leafEnumTypedefRestricted2"},
840 {"example-schema"s, "foodIdentLeaf"}, {"example-schema"s, "pizzaIdentLeaf"}, {"example-schema"s, "foodDrinkIdentLeaf"},
841 {"example-schema"s, "_list"}, {"example-schema"s, "twoKeyList"}, {"second-schema"s, "bla"},
842 {"example-schema"s, "carry"}, {"example-schema"s, "zero"}, {"example-schema"s, "direction"},
843 {"example-schema"s, "interrupt"},
844 {"example-schema"s, "ethernet"}, {"example-schema"s, "loopback"},
845 {"example-schema"s, "pizzaSize"},
846 {"example-schema"s, "length"}, {"example-schema"s, "wavelength"},
847 {"example-schema"s, "duration"}, {"example-schema"s, "another-duration"},
848 {"example-schema"s, "activeNumber"},
849 {"example-schema"s, "numberOrString"},
850 {"example-schema"s, "portSettings"},
851 {"example-schema"s, "portMapping"},
852 {"example-schema"s, "activeMappedPort"},
853 {"example-schema"s, "activePort"},
854 {"example-schema"s, "clockSpeed"},
855 {"example-schema"s, "deprecatedLeaf"},
856 {"example-schema"s, "obsoleteLeaf"},
857 {"example-schema"s, "obsoleteLeafWithDeprecatedType"},
858 {"example-schema"s, "obsoleteLeafWithObsoleteType"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200859 {"example-schema"s, "myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100860 {"example-schema"s, "rpcOneOutput"},
861 {"example-schema"s, "rpcOneInput"},
Václav Kubernát82d74632020-05-11 15:59:53 +0200862 {"example-schema"s, "systemStats"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200863 {"example-schema"s, "dummyLeaf"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200864 {"example-schema"s, "addresses"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100865 {"example-schema"s, "subLeaf"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100866 {"example-schema"s, "flagBits"},
Václav Kubernát97f6b602022-01-17 23:55:51 +0100867 {"example-schema"s, "leafFoodTypedef"},
Jan Kundrátbb7aa852023-08-30 11:51:43 +0200868 {"example-schema"s, "leafNoValidIdent"},
869 {"example-schema"s, "iid-valid"},
870 {"example-schema"s, "iid-relaxed"},
871 };
Václav Kubernát3a823f42020-04-29 23:40:21 +0200872 }
873
874 SECTION("example-schema:a")
875 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200876 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200877 set = {
878 {boost::none, "a2"},
879 {boost::none, "leafa"},
880 {"second-schema"s, "augmentedContainer"}
881 };
Václav Kubernát3a823f42020-04-29 23:40:21 +0200882 }
883
884 SECTION("example-schema:ethernet")
885 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200886 path.m_nodes.emplace_back(module_{"example-schema"}, container_("ethernet"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200887 set = {{boost::none, "ip"}};
888 }
889
890 SECTION("second-schema:bla")
891 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200892 path.m_nodes.emplace_back(module_{"second-schema"}, container_("bla"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200893 set = {{boost::none, "bla2"}};
Václav Kubernát3a823f42020-04-29 23:40:21 +0200894 }
895
896 REQUIRE(ys.availableNodes(path, Recursion::NonRecursive) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200897 }
898
Václav Kubernát3a823f42020-04-29 23:40:21 +0200899 SECTION("modules")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200900 {
Václav Kubernát3a823f42020-04-29 23:40:21 +0200901 std::string module;
Václav Kubernát95b08872020-04-28 01:04:17 +0200902 std::set<ModuleNodePair> expectedNonRecursive;
903 std::set<ModuleNodePair> expectedRecursive;
904 using namespace std::string_literals;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200905 SECTION("example-schema")
906 {
907 module = "example-schema";
908 expectedNonRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +0200909 {"example-schema"s, "_list"},
910 {"example-schema"s, "a"},
911 {"example-schema"s, "activeMappedPort"},
912 {"example-schema"s, "activeNumber"},
913 {"example-schema"s, "activePort"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200914 {"example-schema"s, "addresses"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200915 {"example-schema"s, "another-duration"},
916 {"example-schema"s, "b"},
917 {"example-schema"s, "carry"},
918 {"example-schema"s, "clockSpeed"},
919 {"example-schema"s, "deprecatedLeaf"},
920 {"example-schema"s, "direction"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200921 {"example-schema"s, "dummyLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200922 {"example-schema"s, "duration"},
923 {"example-schema"s, "ethernet"},
924 {"example-schema"s, "foodDrinkIdentLeaf"},
925 {"example-schema"s, "foodIdentLeaf"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100926 {"example-schema"s, "flagBits"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200927 {"example-schema"s, "interrupt"},
Jan Kundrátbb7aa852023-08-30 11:51:43 +0200928 {"example-schema"s, "iid-relaxed"},
929 {"example-schema"s, "iid-valid"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200930 {"example-schema"s, "leafBool"},
931 {"example-schema"s, "leafDecimal"},
932 {"example-schema"s, "leafEnum"},
933 {"example-schema"s, "leafEnumTypedef"},
934 {"example-schema"s, "leafEnumTypedefRestricted"},
935 {"example-schema"s, "leafEnumTypedefRestricted2"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100936 {"example-schema"s, "leafFoodTypedef"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200937 {"example-schema"s, "leafInt16"},
938 {"example-schema"s, "leafInt32"},
939 {"example-schema"s, "leafInt64"},
940 {"example-schema"s, "leafInt8"},
Václav Kubernát97f6b602022-01-17 23:55:51 +0100941 {"example-schema"s, "leafNoValidIdent"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200942 {"example-schema"s, "leafString"},
943 {"example-schema"s, "leafUint16"},
944 {"example-schema"s, "leafUint32"},
945 {"example-schema"s, "leafUint64"},
946 {"example-schema"s, "leafUint8"},
947 {"example-schema"s, "length"},
948 {"example-schema"s, "loopback"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200949 {"example-schema"s, "myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100950 {"example-schema"s, "rpcOneOutput"},
951 {"example-schema"s, "rpcOneInput"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200952 {"example-schema"s, "numberOrString"},
953 {"example-schema"s, "obsoleteLeaf"},
954 {"example-schema"s, "obsoleteLeafWithDeprecatedType"},
955 {"example-schema"s, "obsoleteLeafWithObsoleteType"},
956 {"example-schema"s, "pizzaIdentLeaf"},
957 {"example-schema"s, "pizzaSize"},
958 {"example-schema"s, "portMapping"},
959 {"example-schema"s, "portSettings"},
960 {"example-schema"s, "systemStats"},
961 {"example-schema"s, "twoKeyList"},
962 {"example-schema"s, "wavelength"},
Václav Kubernát82d74632020-05-11 15:59:53 +0200963 {"example-schema"s, "zero"},
964 {"example-schema"s, "subLeaf"}
Václav Kubernát3a823f42020-04-29 23:40:21 +0200965 };
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200966
Václav Kubernát3a823f42020-04-29 23:40:21 +0200967 expectedRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +0200968 {boost::none, "/example-schema:_list"},
969 {boost::none, "/example-schema:_list/contInList"},
970 {boost::none, "/example-schema:_list/number"},
971 {boost::none, "/example-schema:a"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200972 {boost::none, "/example-schema:addresses"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200973 {boost::none, "/example-schema:a/a2"},
974 {boost::none, "/example-schema:a/a2/a3"},
975 {boost::none, "/example-schema:a/leafa"},
976 {boost::none, "/example-schema:a/second-schema:augmentedContainer"},
977 {boost::none, "/example-schema:activeMappedPort"},
978 {boost::none, "/example-schema:activeNumber"},
979 {boost::none, "/example-schema:activePort"},
980 {boost::none, "/example-schema:another-duration"},
981 {boost::none, "/example-schema:b"},
982 {boost::none, "/example-schema:b/b2"},
983 {boost::none, "/example-schema:b/b2/b3"},
984 {boost::none, "/example-schema:carry"},
985 {boost::none, "/example-schema:clockSpeed"},
986 {boost::none, "/example-schema:deprecatedLeaf"},
987 {boost::none, "/example-schema:direction"},
988 {boost::none, "/example-schema:duration"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200989 {boost::none, "/example-schema:dummyLeaf"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100990 {boost::none, "/example-schema:flagBits"},
991 {boost::none, "/example-schema:foodDrinkIdentLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200992 {boost::none, "/example-schema:foodDrinkIdentLeaf"},
993 {boost::none, "/example-schema:foodIdentLeaf"},
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200994 {boost::none, "/example-schema:ethernet"},
995 {boost::none, "/example-schema:ethernet/ip"},
996 {boost::none, "/example-schema:loopback"},
997 {boost::none, "/example-schema:loopback/ip"},
Jan Kundrátbb7aa852023-08-30 11:51:43 +0200998 {boost::none, "/example-schema:iid-relaxed"},
999 {boost::none, "/example-schema:iid-valid"},
Václav Kubernát95b08872020-04-28 01:04:17 +02001000 {boost::none, "/example-schema:interrupt"},
1001 {boost::none, "/example-schema:leafBool"},
1002 {boost::none, "/example-schema:leafDecimal"},
1003 {boost::none, "/example-schema:leafEnum"},
1004 {boost::none, "/example-schema:leafEnumTypedef"},
1005 {boost::none, "/example-schema:leafEnumTypedefRestricted"},
1006 {boost::none, "/example-schema:leafEnumTypedefRestricted2"},
Václav Kubernátfa36c822021-01-25 07:51:02 +01001007 {boost::none, "/example-schema:leafFoodTypedef"},
Václav Kubernát95b08872020-04-28 01:04:17 +02001008 {boost::none, "/example-schema:leafInt16"},
1009 {boost::none, "/example-schema:leafInt32"},
1010 {boost::none, "/example-schema:leafInt64"},
1011 {boost::none, "/example-schema:leafInt8"},
Václav Kubernát97f6b602022-01-17 23:55:51 +01001012 {boost::none, "/example-schema:leafNoValidIdent"},
Václav Kubernát95b08872020-04-28 01:04:17 +02001013 {boost::none, "/example-schema:leafString"},
1014 {boost::none, "/example-schema:leafUint16"},
1015 {boost::none, "/example-schema:leafUint32"},
1016 {boost::none, "/example-schema:leafUint64"},
1017 {boost::none, "/example-schema:leafUint8"},
1018 {boost::none, "/example-schema:length"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +02001019 {boost::none, "/example-schema:myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +01001020 {boost::none, "/example-schema:rpcOneOutput"},
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001021 {boost::none, "/example-schema:rpcOneOutput/ahoj"},
Václav Kubernátd8408e02020-12-02 05:13:27 +01001022 {boost::none, "/example-schema:rpcOneInput"},
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001023 {boost::none, "/example-schema:rpcOneInput/ahoj"},
Václav Kubernát95b08872020-04-28 01:04:17 +02001024 {boost::none, "/example-schema:numberOrString"},
1025 {boost::none, "/example-schema:obsoleteLeaf"},
1026 {boost::none, "/example-schema:obsoleteLeafWithDeprecatedType"},
1027 {boost::none, "/example-schema:obsoleteLeafWithObsoleteType"},
1028 {boost::none, "/example-schema:pizzaIdentLeaf"},
1029 {boost::none, "/example-schema:pizzaSize"},
1030 {boost::none, "/example-schema:portMapping"},
1031 {boost::none, "/example-schema:portMapping/port"},
1032 {boost::none, "/example-schema:portSettings"},
1033 {boost::none, "/example-schema:portSettings/port"},
1034 {boost::none, "/example-schema:systemStats"},
1035 {boost::none, "/example-schema:systemStats/upTime"},
Václav Kubernát82d74632020-05-11 15:59:53 +02001036 {boost::none, "/example-schema:subLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +02001037 {boost::none, "/example-schema:twoKeyList"},
1038 {boost::none, "/example-schema:twoKeyList/name"},
1039 {boost::none, "/example-schema:twoKeyList/number"},
1040 {boost::none, "/example-schema:wavelength"},
1041 {boost::none, "/example-schema:zero"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001042 };
1043 }
Václav Kubernát3a823f42020-04-29 23:40:21 +02001044 SECTION("second-schema")
1045 {
1046 module = "second-schema";
1047 expectedNonRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +02001048 {"second-schema"s, "bla"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001049 };
1050 expectedRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +02001051 {boost::none, "/second-schema:bla"},
1052 {boost::none, "/second-schema:bla/bla2"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001053 };
1054 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001055
Václav Kubernát3a823f42020-04-29 23:40:21 +02001056 REQUIRE(ys.availableNodes(module_{module}, Recursion::NonRecursive) == expectedNonRecursive);
1057 REQUIRE(ys.availableNodes(module_{module}, Recursion::Recursive) == expectedRecursive);
Václav Kubernát47a3f672019-11-08 15:42:43 +01001058 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001059 }
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001060 SECTION("nodeType")
1061 {
1062 yang::NodeTypes expected;
1063 SECTION("leafInt32")
1064 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001065 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001066 expected = yang::NodeTypes::Leaf;
1067 }
1068
1069 SECTION("a")
1070 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001071 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001072 expected = yang::NodeTypes::Container;
1073 }
1074
1075 SECTION("a/a2/a3")
1076 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001077 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1078 path.m_nodes.emplace_back(container_("a2"));
1079 path.m_nodes.emplace_back(container_("a3"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001080 expected = yang::NodeTypes::PresenceContainer;
1081 }
1082
1083 SECTION("_list")
1084 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001085 path.m_nodes.emplace_back(module_{"example-schema"}, list_("_list"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001086 expected = yang::NodeTypes::List;
1087 }
1088
Václav Kubernát82d74632020-05-11 15:59:53 +02001089 SECTION("subLeaf")
1090 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001091 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("subLeaf"));
Václav Kubernát82d74632020-05-11 15:59:53 +02001092 expected = yang::NodeTypes::Leaf;
1093 }
1094
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001095 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1096 }
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001097
1098 SECTION("description")
1099 {
1100 std::optional<std::string> expected;
1101 SECTION("leafInt32")
1102 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001103 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001104 expected = "A 32-bit integer leaf.";
1105 }
1106
1107 SECTION("leafString")
1108 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001109 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafString"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001110 }
1111
Václav Kubernát2984f442020-02-20 17:43:35 +01001112 SECTION("numberOrString")
1113 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001114 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("numberOrString"));
Václav Kubernát2984f442020-02-20 17:43:35 +01001115 expected = "Can be an int32 or a string.";
1116 }
1117
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001118 REQUIRE(ys.description(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1119 }
1120
Václav Kubernáta1c4c9e2020-04-22 00:37:52 +02001121 SECTION("status")
1122 {
1123 REQUIRE(ys.status("/example-schema:leafUint64") == yang::Status::Current);
1124 REQUIRE(ys.status("/example-schema:obsoleteLeaf") == yang::Status::Obsolete);
1125 REQUIRE(ys.status("/example-schema:deprecatedLeaf") == yang::Status::Deprecated);
1126 REQUIRE(ys.status("/example-schema:obsoleteLeafWithDeprecatedType") == yang::Status::Obsolete);
1127 REQUIRE(ys.status("/example-schema:obsoleteLeafWithObsoleteType") == yang::Status::Obsolete);
1128 }
1129
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001130 SECTION("units")
1131 {
Václav Kubernát13b23d72020-04-16 21:49:51 +02001132 yang::LeafDataType expectedType;
1133 std::optional<std::string> expectedUnits;
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001134 SECTION("length")
1135 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001136 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("length"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001137 expectedType.emplace<yang::Int32>();
1138 expectedUnits = "m";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001139 }
1140
1141 SECTION("wavelength")
1142 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001143 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("wavelength"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001144 expectedType.emplace<yang::Decimal>();
1145 expectedUnits = "nm";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001146 }
1147
1148 SECTION("leafInt32")
1149 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001150 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001151 expectedType.emplace<yang::Int32>();
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001152 }
1153
1154 SECTION("duration")
1155 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001156 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("duration"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001157 expectedType.emplace<yang::Int32>();
1158 expectedUnits = "s";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001159 }
1160
1161 SECTION("another-duration")
1162 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001163 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("another-duration"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001164 expectedType.emplace<yang::Int32>();
1165 expectedUnits = "vt";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001166 }
Václav Kubernát5b8a8f32020-05-20 00:57:22 +02001167 auto nodeType = ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded));
1168 REQUIRE((nodeType == yang::NodeTypes::Leaf || nodeType == yang::NodeTypes::LeafList));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001169 REQUIRE(ys.leafType(pathToSchemaString(path, Prefixes::WhenNeeded)) == yang::TypeInfo{expectedType, expectedUnits});
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001170 }
1171
Václav Kubernát1ae24f42020-12-01 02:32:04 +01001172 SECTION("type description")
1173 {
1174 yang::LeafDataType expectedType = createEnum({"lol", "data"});
1175 std::optional<std::string> expectedDescription;
1176
1177 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafEnumTypedefRestricted2"));
1178 expectedDescription = "This is a restricted enum typedef.";
1179 REQUIRE(ys.leafType(pathToSchemaString(path, Prefixes::WhenNeeded)) == yang::TypeInfo{expectedType, std::nullopt, expectedDescription});
1180 }
1181
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001182 SECTION("nodeType")
1183 {
1184 yang::NodeTypes expected;
1185 SECTION("leafInt32")
1186 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001187 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001188 expected = yang::NodeTypes::Leaf;
1189 }
1190
1191 SECTION("a")
1192 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001193 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001194 expected = yang::NodeTypes::Container;
1195 }
1196
1197 SECTION("a/a2/a3")
1198 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001199 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1200 path.m_nodes.emplace_back(container_("a2"));
1201 path.m_nodes.emplace_back(container_("a3"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001202 expected = yang::NodeTypes::PresenceContainer;
1203 }
1204
1205 SECTION("_list")
1206 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001207 path.m_nodes.emplace_back(module_{"example-schema"}, list_("_list"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001208 expected = yang::NodeTypes::List;
1209 }
1210
1211 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1212 }
Václav Kubernátbd5e3c22020-02-19 15:22:00 +01001213
1214 SECTION("leafrefPath")
1215 {
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001216 REQUIRE(ys.leafrefPath("/example-schema:activeNumber") == "/_list/number");
Václav Kubernátbd5e3c22020-02-19 15:22:00 +01001217 }
Václav Kubernát0599e9f2020-04-21 09:51:33 +02001218
1219 SECTION("isConfig")
1220 {
1221 REQUIRE(ys.isConfig("/example-schema:leafInt32"));
Václav Kubernátc8e5ed02022-03-23 12:46:54 +01001222 REQUIRE(ys.isConfig("/example-schema:rpcOneInput/ahoj"));
Václav Kubernát0599e9f2020-04-21 09:51:33 +02001223 REQUIRE_FALSE(ys.isConfig("/example-schema:clockSpeed"));
1224 REQUIRE_FALSE(ys.isConfig("/example-schema:systemStats"));
1225 REQUIRE_FALSE(ys.isConfig("/example-schema:systemStats/upTime"));
1226 }
Václav Kubernátbd0d5c82020-04-21 10:22:03 +02001227
Václav Kubernátb1a75c62020-04-21 15:20:16 +02001228 SECTION("defaultValue")
1229 {
1230 REQUIRE(ys.defaultValue("/example-schema:leafUint64") == "9001");
1231 REQUIRE(ys.defaultValue("/example-schema:leafEnumTypedefRestricted") == "data");
1232 REQUIRE(ys.defaultValue("/example-schema:leafInt32") == std::nullopt);
1233 }
1234
Václav Kubernát76ba4ec2020-05-18 13:26:56 +02001235 SECTION("leafTypeName")
1236 {
1237 REQUIRE(ys.leafTypeName("/example-schema:leafEnumTypedefRestricted") == "enumTypedef");
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001238 REQUIRE(ys.leafTypeName("/example-schema:leafInt32") == "int32");
Václav Kubernát76ba4ec2020-05-18 13:26:56 +02001239 }
Václav Kubernáta8789602020-07-20 15:18:19 +02001240
1241 SECTION("dataPathToSchemaPath")
1242 {
1243 REQUIRE(ys.dataPathToSchemaPath("/example-schema:portSettings[port='eth0']") == "/example-schema:portSettings");
1244 REQUIRE(ys.dataPathToSchemaPath("/example-schema:portSettings[port='eth0']/shutdown") == "/example-schema:portSettings/shutdown");
1245 }
Václav Kubernátd8408e02020-12-02 05:13:27 +01001246
1247 SECTION("has input nodes")
1248 {
1249 bool expected;
1250 SECTION("example-schema:myRpc")
1251 {
1252 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"myRpc"});
1253 expected = false;
1254 }
1255
1256 SECTION("example-schema:rpcOneInput")
1257 {
1258 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"rpcOneInput"});
1259 expected = true;
1260 }
1261
1262 SECTION("example-schema:rpcOneOutput")
1263 {
1264 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"rpcOneOutput"});
1265 expected = false;
1266 }
1267
1268 REQUIRE(ys.hasInputNodes(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1269 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001270 }
1271
1272 SECTION("negative")
1273 {
1274 SECTION("nonexistent nodes")
1275 {
1276 SECTION("example-schema:coze")
1277 {
1278 node.first = "example-schema";
1279 node.second = "coze";
1280 }
1281
1282 SECTION("example-schema:a/nevim")
1283 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001284 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001285 node.second = "nevim";
1286 }
1287
1288 SECTION("modul:a/nevim")
1289 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001290 path.m_nodes.emplace_back(module_{"modul"}, container_("a"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001291 node.second = "nevim";
1292 }
1293
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001294 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001295 }
1296
1297 SECTION("nodetype-specific methods called with different nodetypes")
1298 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001299 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1300 path.m_nodes.emplace_back(container_("a2"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001301
Václav Kubernát912b9492020-05-29 02:03:40 +02001302 REQUIRE(!ys.listHasKey(path, "chacha"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001303 }
1304
1305 SECTION("nonexistent module")
1306 {
Václav Kubernát75877de2019-11-20 17:43:02 +01001307 REQUIRE(!ys.isModule("notAModule"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001308 }
Václav Kubernáteeb38842019-03-20 19:46:05 +01001309
Václav Kubernát7d82da72019-04-11 15:16:38 +02001310 SECTION("grouping is not a node")
1311 {
1312 SECTION("example-schema:arithmeticFlags")
1313 {
1314 node.first = "example-schema";
1315 node.second = "arithmeticFlags";
1316 }
1317
1318 SECTION("example-schema:flags")
1319 {
1320 node.first = "example-schema";
1321 node.second = "startAndStop";
1322 }
1323
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001324 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát7d82da72019-04-11 15:16:38 +02001325 }
Václav Kubernát280df4a2019-11-01 14:46:34 +01001326
1327 SECTION("choice is not a node")
1328 {
1329 SECTION("example-schema:interface")
1330 {
1331 node.first = "example-schema";
1332 node.second = "interface";
1333 }
1334
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001335 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát280df4a2019-11-01 14:46:34 +01001336 }
1337
1338 SECTION("case is not a node")
1339 {
1340 SECTION("example-schema:caseLoopback")
1341 {
1342 node.first = "example-schema";
1343 node.second = "caseLoopback";
1344 }
1345
1346 SECTION("example-schema:caseEthernet")
1347 {
1348 node.first = "example-schema";
1349 node.second = "caseEthernet";
1350 }
1351
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001352 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát280df4a2019-11-01 14:46:34 +01001353 }
Václav Kubernátf44bdda2020-06-22 15:58:41 +02001354
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001355 SECTION("setEnabledFeatures - non existing module")
Václav Kubernátf44bdda2020-06-22 15:58:41 +02001356 {
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001357 REQUIRE_THROWS_AS(ys.setEnabledFeatures("non-existing", {"just-no"}), std::runtime_error);
Václav Kubernátf44bdda2020-06-22 15:58:41 +02001358 }
Václav Kubernát7aaf6dc2020-06-26 18:03:57 +02001359
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001360 SECTION("setEnabledFeatures - non existing feature")
Václav Kubernát7aaf6dc2020-06-26 18:03:57 +02001361 {
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001362 REQUIRE_THROWS_AS(ys.setEnabledFeatures("example-schema", {"just-no"}), std::runtime_error);
Václav Kubernát7aaf6dc2020-06-26 18:03:57 +02001363 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001364 }
1365}