blob: 205616c0e95a9c01db6fedd7555141f9b63fb185 [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 {
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200686 ys.setEnabledFeatures("example-schema", {"bigPizzas"});
Václav Kubernát3a99f002020-03-31 02:27:41 +0200687 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>(
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200730 "/_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 {
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200747 ys.setEnabledFeatures("example-schema", {"weirdPortNames"});
Václav Kubernát1dc9e3e2020-06-09 15:22:39 +0200748 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átcfdb9222021-07-07 22:36:24 +0200754 "../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átcfdb9222021-07-07 22:36:24 +0200758 "../activeMappedPort",
759 std::make_unique<yang::TypeInfo>(enums)
Václav Kubernát13b23d72020-04-16 21:49:51 +0200760 }},
Jan Kundrát379bb572020-05-07 03:23:13 +0200761 yang::TypeInfo{yang::Empty{}},
Václav Kubernát2984f442020-02-20 17:43:35 +0100762 }};
763 }
764
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200765 SECTION("addresses")
766 {
767 node.first = "example-schema";
768 node.second = "addresses";
769 type.emplace<yang::String>();
770 }
771
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100772 SECTION("flagBits")
773 {
774 node.first = "example-schema";
775 node.second = "flagBits";
776 type = yang::Bits{{"carry", "sign", "overflow"}};
777 }
778
Václav Kubernátfa36c822021-01-25 07:51:02 +0100779 SECTION("foodTypedef")
780 {
781 node.first = "example-schema";
782 node.second = "leafFoodTypedef";
783 type = yang::IdentityRef{{
Václav Kubernátfa36c822021-01-25 07:51:02 +0100784 {"example-schema", "fruit"},
785 {"example-schema", "hawaii"},
786 {"example-schema", "pizza"},
787 {"second-schema", "pineapple"},
788 }};
789 }
790
Václav Kubernát97f6b602022-01-17 23:55:51 +0100791 SECTION("leafNoValidIdent")
792 {
793 node.first = "example-schema";
794 node.second = "leafNoValidIdent";
795 type = yang::IdentityRef{{}};
796 }
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200797
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100798 REQUIRE(ys.leafType(path, node) == yang::TypeInfo(type, std::nullopt, expectedDescription));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200799 }
Václav Kubernát3a823f42020-04-29 23:40:21 +0200800 SECTION("availableNodes")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200801 {
Václav Kubernát3a823f42020-04-29 23:40:21 +0200802 // TODO: merge "path" and "module" sections and add recursive versions to the path section
803 SECTION("paths")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200804 {
Václav Kubernát95b08872020-04-28 01:04:17 +0200805 std::set<ModuleNodePair> set;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200806
Václav Kubernát95b08872020-04-28 01:04:17 +0200807 using namespace std::string_literals;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200808 SECTION("<root>")
809 {
Václav Kubernát95b08872020-04-28 01:04:17 +0200810 set = {{"example-schema"s, "a"}, {"example-schema"s, "b"}, {"example-schema"s, "leafString"},
811 {"example-schema"s, "leafDecimal"}, {"example-schema"s, "leafBool"},
812 {"example-schema"s, "leafInt8"}, {"example-schema"s, "leafUint8"},
813 {"example-schema"s, "leafInt16"}, {"example-schema"s, "leafUint16"},
814 {"example-schema"s, "leafInt32"}, {"example-schema"s, "leafUint32"},
815 {"example-schema"s, "leafInt64"}, {"example-schema"s, "leafUint64"},
816 {"example-schema"s, "leafEnum"}, {"example-schema"s, "leafEnumTypedef"},
817 {"example-schema"s, "leafEnumTypedefRestricted"}, {"example-schema"s, "leafEnumTypedefRestricted2"},
818 {"example-schema"s, "foodIdentLeaf"}, {"example-schema"s, "pizzaIdentLeaf"}, {"example-schema"s, "foodDrinkIdentLeaf"},
819 {"example-schema"s, "_list"}, {"example-schema"s, "twoKeyList"}, {"second-schema"s, "bla"},
820 {"example-schema"s, "carry"}, {"example-schema"s, "zero"}, {"example-schema"s, "direction"},
821 {"example-schema"s, "interrupt"},
822 {"example-schema"s, "ethernet"}, {"example-schema"s, "loopback"},
823 {"example-schema"s, "pizzaSize"},
824 {"example-schema"s, "length"}, {"example-schema"s, "wavelength"},
825 {"example-schema"s, "duration"}, {"example-schema"s, "another-duration"},
826 {"example-schema"s, "activeNumber"},
827 {"example-schema"s, "numberOrString"},
828 {"example-schema"s, "portSettings"},
829 {"example-schema"s, "portMapping"},
830 {"example-schema"s, "activeMappedPort"},
831 {"example-schema"s, "activePort"},
832 {"example-schema"s, "clockSpeed"},
833 {"example-schema"s, "deprecatedLeaf"},
834 {"example-schema"s, "obsoleteLeaf"},
835 {"example-schema"s, "obsoleteLeafWithDeprecatedType"},
836 {"example-schema"s, "obsoleteLeafWithObsoleteType"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200837 {"example-schema"s, "myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100838 {"example-schema"s, "rpcOneOutput"},
839 {"example-schema"s, "rpcOneInput"},
Václav Kubernát82d74632020-05-11 15:59:53 +0200840 {"example-schema"s, "systemStats"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200841 {"example-schema"s, "dummyLeaf"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200842 {"example-schema"s, "addresses"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100843 {"example-schema"s, "subLeaf"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100844 {"example-schema"s, "flagBits"},
Václav Kubernát97f6b602022-01-17 23:55:51 +0100845 {"example-schema"s, "leafFoodTypedef"},
846 {"example-schema"s, "leafNoValidIdent"}};
Václav Kubernát3a823f42020-04-29 23:40:21 +0200847 }
848
849 SECTION("example-schema:a")
850 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200851 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200852 set = {
853 {boost::none, "a2"},
854 {boost::none, "leafa"},
855 {"second-schema"s, "augmentedContainer"}
856 };
Václav Kubernát3a823f42020-04-29 23:40:21 +0200857 }
858
859 SECTION("example-schema:ethernet")
860 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200861 path.m_nodes.emplace_back(module_{"example-schema"}, container_("ethernet"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200862 set = {{boost::none, "ip"}};
863 }
864
865 SECTION("second-schema:bla")
866 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200867 path.m_nodes.emplace_back(module_{"second-schema"}, container_("bla"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200868 set = {{boost::none, "bla2"}};
Václav Kubernát3a823f42020-04-29 23:40:21 +0200869 }
870
871 REQUIRE(ys.availableNodes(path, Recursion::NonRecursive) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200872 }
873
Václav Kubernát3a823f42020-04-29 23:40:21 +0200874 SECTION("modules")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200875 {
Václav Kubernát3a823f42020-04-29 23:40:21 +0200876 std::string module;
Václav Kubernát95b08872020-04-28 01:04:17 +0200877 std::set<ModuleNodePair> expectedNonRecursive;
878 std::set<ModuleNodePair> expectedRecursive;
879 using namespace std::string_literals;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200880 SECTION("example-schema")
881 {
882 module = "example-schema";
883 expectedNonRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +0200884 {"example-schema"s, "_list"},
885 {"example-schema"s, "a"},
886 {"example-schema"s, "activeMappedPort"},
887 {"example-schema"s, "activeNumber"},
888 {"example-schema"s, "activePort"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200889 {"example-schema"s, "addresses"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200890 {"example-schema"s, "another-duration"},
891 {"example-schema"s, "b"},
892 {"example-schema"s, "carry"},
893 {"example-schema"s, "clockSpeed"},
894 {"example-schema"s, "deprecatedLeaf"},
895 {"example-schema"s, "direction"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200896 {"example-schema"s, "dummyLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200897 {"example-schema"s, "duration"},
898 {"example-schema"s, "ethernet"},
899 {"example-schema"s, "foodDrinkIdentLeaf"},
900 {"example-schema"s, "foodIdentLeaf"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100901 {"example-schema"s, "flagBits"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200902 {"example-schema"s, "interrupt"},
903 {"example-schema"s, "leafBool"},
904 {"example-schema"s, "leafDecimal"},
905 {"example-schema"s, "leafEnum"},
906 {"example-schema"s, "leafEnumTypedef"},
907 {"example-schema"s, "leafEnumTypedefRestricted"},
908 {"example-schema"s, "leafEnumTypedefRestricted2"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100909 {"example-schema"s, "leafFoodTypedef"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200910 {"example-schema"s, "leafInt16"},
911 {"example-schema"s, "leafInt32"},
912 {"example-schema"s, "leafInt64"},
913 {"example-schema"s, "leafInt8"},
Václav Kubernát97f6b602022-01-17 23:55:51 +0100914 {"example-schema"s, "leafNoValidIdent"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200915 {"example-schema"s, "leafString"},
916 {"example-schema"s, "leafUint16"},
917 {"example-schema"s, "leafUint32"},
918 {"example-schema"s, "leafUint64"},
919 {"example-schema"s, "leafUint8"},
920 {"example-schema"s, "length"},
921 {"example-schema"s, "loopback"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200922 {"example-schema"s, "myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100923 {"example-schema"s, "rpcOneOutput"},
924 {"example-schema"s, "rpcOneInput"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200925 {"example-schema"s, "numberOrString"},
926 {"example-schema"s, "obsoleteLeaf"},
927 {"example-schema"s, "obsoleteLeafWithDeprecatedType"},
928 {"example-schema"s, "obsoleteLeafWithObsoleteType"},
929 {"example-schema"s, "pizzaIdentLeaf"},
930 {"example-schema"s, "pizzaSize"},
931 {"example-schema"s, "portMapping"},
932 {"example-schema"s, "portSettings"},
933 {"example-schema"s, "systemStats"},
934 {"example-schema"s, "twoKeyList"},
935 {"example-schema"s, "wavelength"},
Václav Kubernát82d74632020-05-11 15:59:53 +0200936 {"example-schema"s, "zero"},
937 {"example-schema"s, "subLeaf"}
Václav Kubernát3a823f42020-04-29 23:40:21 +0200938 };
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200939
Václav Kubernát3a823f42020-04-29 23:40:21 +0200940 expectedRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +0200941 {boost::none, "/example-schema:_list"},
942 {boost::none, "/example-schema:_list/contInList"},
943 {boost::none, "/example-schema:_list/number"},
944 {boost::none, "/example-schema:a"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200945 {boost::none, "/example-schema:addresses"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200946 {boost::none, "/example-schema:a/a2"},
947 {boost::none, "/example-schema:a/a2/a3"},
948 {boost::none, "/example-schema:a/leafa"},
949 {boost::none, "/example-schema:a/second-schema:augmentedContainer"},
950 {boost::none, "/example-schema:activeMappedPort"},
951 {boost::none, "/example-schema:activeNumber"},
952 {boost::none, "/example-schema:activePort"},
953 {boost::none, "/example-schema:another-duration"},
954 {boost::none, "/example-schema:b"},
955 {boost::none, "/example-schema:b/b2"},
956 {boost::none, "/example-schema:b/b2/b3"},
957 {boost::none, "/example-schema:carry"},
958 {boost::none, "/example-schema:clockSpeed"},
959 {boost::none, "/example-schema:deprecatedLeaf"},
960 {boost::none, "/example-schema:direction"},
961 {boost::none, "/example-schema:duration"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200962 {boost::none, "/example-schema:dummyLeaf"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100963 {boost::none, "/example-schema:flagBits"},
964 {boost::none, "/example-schema:foodDrinkIdentLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200965 {boost::none, "/example-schema:foodDrinkIdentLeaf"},
966 {boost::none, "/example-schema:foodIdentLeaf"},
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200967 {boost::none, "/example-schema:ethernet"},
968 {boost::none, "/example-schema:ethernet/ip"},
969 {boost::none, "/example-schema:loopback"},
970 {boost::none, "/example-schema:loopback/ip"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200971 {boost::none, "/example-schema:interrupt"},
972 {boost::none, "/example-schema:leafBool"},
973 {boost::none, "/example-schema:leafDecimal"},
974 {boost::none, "/example-schema:leafEnum"},
975 {boost::none, "/example-schema:leafEnumTypedef"},
976 {boost::none, "/example-schema:leafEnumTypedefRestricted"},
977 {boost::none, "/example-schema:leafEnumTypedefRestricted2"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100978 {boost::none, "/example-schema:leafFoodTypedef"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200979 {boost::none, "/example-schema:leafInt16"},
980 {boost::none, "/example-schema:leafInt32"},
981 {boost::none, "/example-schema:leafInt64"},
982 {boost::none, "/example-schema:leafInt8"},
Václav Kubernát97f6b602022-01-17 23:55:51 +0100983 {boost::none, "/example-schema:leafNoValidIdent"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200984 {boost::none, "/example-schema:leafString"},
985 {boost::none, "/example-schema:leafUint16"},
986 {boost::none, "/example-schema:leafUint32"},
987 {boost::none, "/example-schema:leafUint64"},
988 {boost::none, "/example-schema:leafUint8"},
989 {boost::none, "/example-schema:length"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200990 {boost::none, "/example-schema:myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100991 {boost::none, "/example-schema:rpcOneOutput"},
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200992 {boost::none, "/example-schema:rpcOneOutput/ahoj"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100993 {boost::none, "/example-schema:rpcOneInput"},
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200994 {boost::none, "/example-schema:rpcOneInput/ahoj"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200995 {boost::none, "/example-schema:numberOrString"},
996 {boost::none, "/example-schema:obsoleteLeaf"},
997 {boost::none, "/example-schema:obsoleteLeafWithDeprecatedType"},
998 {boost::none, "/example-schema:obsoleteLeafWithObsoleteType"},
999 {boost::none, "/example-schema:pizzaIdentLeaf"},
1000 {boost::none, "/example-schema:pizzaSize"},
1001 {boost::none, "/example-schema:portMapping"},
1002 {boost::none, "/example-schema:portMapping/port"},
1003 {boost::none, "/example-schema:portSettings"},
1004 {boost::none, "/example-schema:portSettings/port"},
1005 {boost::none, "/example-schema:systemStats"},
1006 {boost::none, "/example-schema:systemStats/upTime"},
Václav Kubernát82d74632020-05-11 15:59:53 +02001007 {boost::none, "/example-schema:subLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +02001008 {boost::none, "/example-schema:twoKeyList"},
1009 {boost::none, "/example-schema:twoKeyList/name"},
1010 {boost::none, "/example-schema:twoKeyList/number"},
1011 {boost::none, "/example-schema:wavelength"},
1012 {boost::none, "/example-schema:zero"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001013 };
1014 }
Václav Kubernát3a823f42020-04-29 23:40:21 +02001015 SECTION("second-schema")
1016 {
1017 module = "second-schema";
1018 expectedNonRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +02001019 {"second-schema"s, "bla"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001020 };
1021 expectedRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +02001022 {boost::none, "/second-schema:bla"},
1023 {boost::none, "/second-schema:bla/bla2"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001024 };
1025 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001026
Václav Kubernát3a823f42020-04-29 23:40:21 +02001027 REQUIRE(ys.availableNodes(module_{module}, Recursion::NonRecursive) == expectedNonRecursive);
1028 REQUIRE(ys.availableNodes(module_{module}, Recursion::Recursive) == expectedRecursive);
Václav Kubernát47a3f672019-11-08 15:42:43 +01001029 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001030 }
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001031 SECTION("nodeType")
1032 {
1033 yang::NodeTypes expected;
1034 SECTION("leafInt32")
1035 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001036 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001037 expected = yang::NodeTypes::Leaf;
1038 }
1039
1040 SECTION("a")
1041 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001042 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001043 expected = yang::NodeTypes::Container;
1044 }
1045
1046 SECTION("a/a2/a3")
1047 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001048 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1049 path.m_nodes.emplace_back(container_("a2"));
1050 path.m_nodes.emplace_back(container_("a3"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001051 expected = yang::NodeTypes::PresenceContainer;
1052 }
1053
1054 SECTION("_list")
1055 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001056 path.m_nodes.emplace_back(module_{"example-schema"}, list_("_list"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001057 expected = yang::NodeTypes::List;
1058 }
1059
Václav Kubernát82d74632020-05-11 15:59:53 +02001060 SECTION("subLeaf")
1061 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001062 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("subLeaf"));
Václav Kubernát82d74632020-05-11 15:59:53 +02001063 expected = yang::NodeTypes::Leaf;
1064 }
1065
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001066 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1067 }
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001068
1069 SECTION("description")
1070 {
1071 std::optional<std::string> expected;
1072 SECTION("leafInt32")
1073 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001074 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001075 expected = "A 32-bit integer leaf.";
1076 }
1077
1078 SECTION("leafString")
1079 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001080 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafString"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001081 }
1082
Václav Kubernát2984f442020-02-20 17:43:35 +01001083 SECTION("numberOrString")
1084 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001085 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("numberOrString"));
Václav Kubernát2984f442020-02-20 17:43:35 +01001086 expected = "Can be an int32 or a string.";
1087 }
1088
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001089 REQUIRE(ys.description(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1090 }
1091
Václav Kubernáta1c4c9e2020-04-22 00:37:52 +02001092 SECTION("status")
1093 {
1094 REQUIRE(ys.status("/example-schema:leafUint64") == yang::Status::Current);
1095 REQUIRE(ys.status("/example-schema:obsoleteLeaf") == yang::Status::Obsolete);
1096 REQUIRE(ys.status("/example-schema:deprecatedLeaf") == yang::Status::Deprecated);
1097 REQUIRE(ys.status("/example-schema:obsoleteLeafWithDeprecatedType") == yang::Status::Obsolete);
1098 REQUIRE(ys.status("/example-schema:obsoleteLeafWithObsoleteType") == yang::Status::Obsolete);
1099 }
1100
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001101 SECTION("units")
1102 {
Václav Kubernát13b23d72020-04-16 21:49:51 +02001103 yang::LeafDataType expectedType;
1104 std::optional<std::string> expectedUnits;
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001105 SECTION("length")
1106 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001107 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("length"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001108 expectedType.emplace<yang::Int32>();
1109 expectedUnits = "m";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001110 }
1111
1112 SECTION("wavelength")
1113 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001114 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("wavelength"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001115 expectedType.emplace<yang::Decimal>();
1116 expectedUnits = "nm";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001117 }
1118
1119 SECTION("leafInt32")
1120 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001121 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001122 expectedType.emplace<yang::Int32>();
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001123 }
1124
1125 SECTION("duration")
1126 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001127 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("duration"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001128 expectedType.emplace<yang::Int32>();
1129 expectedUnits = "s";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001130 }
1131
1132 SECTION("another-duration")
1133 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001134 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("another-duration"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001135 expectedType.emplace<yang::Int32>();
1136 expectedUnits = "vt";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001137 }
Václav Kubernát5b8a8f32020-05-20 00:57:22 +02001138 auto nodeType = ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded));
1139 REQUIRE((nodeType == yang::NodeTypes::Leaf || nodeType == yang::NodeTypes::LeafList));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001140 REQUIRE(ys.leafType(pathToSchemaString(path, Prefixes::WhenNeeded)) == yang::TypeInfo{expectedType, expectedUnits});
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001141 }
1142
Václav Kubernát1ae24f42020-12-01 02:32:04 +01001143 SECTION("type description")
1144 {
1145 yang::LeafDataType expectedType = createEnum({"lol", "data"});
1146 std::optional<std::string> expectedDescription;
1147
1148 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafEnumTypedefRestricted2"));
1149 expectedDescription = "This is a restricted enum typedef.";
1150 REQUIRE(ys.leafType(pathToSchemaString(path, Prefixes::WhenNeeded)) == yang::TypeInfo{expectedType, std::nullopt, expectedDescription});
1151 }
1152
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001153 SECTION("nodeType")
1154 {
1155 yang::NodeTypes expected;
1156 SECTION("leafInt32")
1157 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001158 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001159 expected = yang::NodeTypes::Leaf;
1160 }
1161
1162 SECTION("a")
1163 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001164 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001165 expected = yang::NodeTypes::Container;
1166 }
1167
1168 SECTION("a/a2/a3")
1169 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001170 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1171 path.m_nodes.emplace_back(container_("a2"));
1172 path.m_nodes.emplace_back(container_("a3"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001173 expected = yang::NodeTypes::PresenceContainer;
1174 }
1175
1176 SECTION("_list")
1177 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001178 path.m_nodes.emplace_back(module_{"example-schema"}, list_("_list"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001179 expected = yang::NodeTypes::List;
1180 }
1181
1182 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1183 }
Václav Kubernátbd5e3c22020-02-19 15:22:00 +01001184
1185 SECTION("leafrefPath")
1186 {
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001187 REQUIRE(ys.leafrefPath("/example-schema:activeNumber") == "/_list/number");
Václav Kubernátbd5e3c22020-02-19 15:22:00 +01001188 }
Václav Kubernát0599e9f2020-04-21 09:51:33 +02001189
1190 SECTION("isConfig")
1191 {
1192 REQUIRE(ys.isConfig("/example-schema:leafInt32"));
1193 REQUIRE_FALSE(ys.isConfig("/example-schema:clockSpeed"));
1194 REQUIRE_FALSE(ys.isConfig("/example-schema:systemStats"));
1195 REQUIRE_FALSE(ys.isConfig("/example-schema:systemStats/upTime"));
1196 }
Václav Kubernátbd0d5c82020-04-21 10:22:03 +02001197
Václav Kubernátb1a75c62020-04-21 15:20:16 +02001198 SECTION("defaultValue")
1199 {
1200 REQUIRE(ys.defaultValue("/example-schema:leafUint64") == "9001");
1201 REQUIRE(ys.defaultValue("/example-schema:leafEnumTypedefRestricted") == "data");
1202 REQUIRE(ys.defaultValue("/example-schema:leafInt32") == std::nullopt);
1203 }
1204
Václav Kubernát76ba4ec2020-05-18 13:26:56 +02001205 SECTION("leafTypeName")
1206 {
1207 REQUIRE(ys.leafTypeName("/example-schema:leafEnumTypedefRestricted") == "enumTypedef");
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001208 REQUIRE(ys.leafTypeName("/example-schema:leafInt32") == "int32");
Václav Kubernát76ba4ec2020-05-18 13:26:56 +02001209 }
Václav Kubernáta8789602020-07-20 15:18:19 +02001210
1211 SECTION("dataPathToSchemaPath")
1212 {
1213 REQUIRE(ys.dataPathToSchemaPath("/example-schema:portSettings[port='eth0']") == "/example-schema:portSettings");
1214 REQUIRE(ys.dataPathToSchemaPath("/example-schema:portSettings[port='eth0']/shutdown") == "/example-schema:portSettings/shutdown");
1215 }
Václav Kubernátd8408e02020-12-02 05:13:27 +01001216
1217 SECTION("has input nodes")
1218 {
1219 bool expected;
1220 SECTION("example-schema:myRpc")
1221 {
1222 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"myRpc"});
1223 expected = false;
1224 }
1225
1226 SECTION("example-schema:rpcOneInput")
1227 {
1228 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"rpcOneInput"});
1229 expected = true;
1230 }
1231
1232 SECTION("example-schema:rpcOneOutput")
1233 {
1234 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"rpcOneOutput"});
1235 expected = false;
1236 }
1237
1238 REQUIRE(ys.hasInputNodes(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1239 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001240 }
1241
1242 SECTION("negative")
1243 {
1244 SECTION("nonexistent nodes")
1245 {
1246 SECTION("example-schema:coze")
1247 {
1248 node.first = "example-schema";
1249 node.second = "coze";
1250 }
1251
1252 SECTION("example-schema:a/nevim")
1253 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001254 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001255 node.second = "nevim";
1256 }
1257
1258 SECTION("modul:a/nevim")
1259 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001260 path.m_nodes.emplace_back(module_{"modul"}, container_("a"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001261 node.second = "nevim";
1262 }
1263
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001264 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001265 }
1266
1267 SECTION("nodetype-specific methods called with different nodetypes")
1268 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001269 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1270 path.m_nodes.emplace_back(container_("a2"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001271
Václav Kubernát912b9492020-05-29 02:03:40 +02001272 REQUIRE(!ys.listHasKey(path, "chacha"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001273 }
1274
1275 SECTION("nonexistent module")
1276 {
Václav Kubernát75877de2019-11-20 17:43:02 +01001277 REQUIRE(!ys.isModule("notAModule"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001278 }
Václav Kubernáteeb38842019-03-20 19:46:05 +01001279
Václav Kubernát7d82da72019-04-11 15:16:38 +02001280 SECTION("grouping is not a node")
1281 {
1282 SECTION("example-schema:arithmeticFlags")
1283 {
1284 node.first = "example-schema";
1285 node.second = "arithmeticFlags";
1286 }
1287
1288 SECTION("example-schema:flags")
1289 {
1290 node.first = "example-schema";
1291 node.second = "startAndStop";
1292 }
1293
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001294 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát7d82da72019-04-11 15:16:38 +02001295 }
Václav Kubernát280df4a2019-11-01 14:46:34 +01001296
1297 SECTION("choice is not a node")
1298 {
1299 SECTION("example-schema:interface")
1300 {
1301 node.first = "example-schema";
1302 node.second = "interface";
1303 }
1304
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001305 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát280df4a2019-11-01 14:46:34 +01001306 }
1307
1308 SECTION("case is not a node")
1309 {
1310 SECTION("example-schema:caseLoopback")
1311 {
1312 node.first = "example-schema";
1313 node.second = "caseLoopback";
1314 }
1315
1316 SECTION("example-schema:caseEthernet")
1317 {
1318 node.first = "example-schema";
1319 node.second = "caseEthernet";
1320 }
1321
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001322 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát280df4a2019-11-01 14:46:34 +01001323 }
Václav Kubernátf44bdda2020-06-22 15:58:41 +02001324
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001325 SECTION("setEnabledFeatures - non existing module")
Václav Kubernátf44bdda2020-06-22 15:58:41 +02001326 {
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001327 REQUIRE_THROWS_AS(ys.setEnabledFeatures("non-existing", {"just-no"}), std::runtime_error);
Václav Kubernátf44bdda2020-06-22 15:58:41 +02001328 }
Václav Kubernát7aaf6dc2020-06-26 18:03:57 +02001329
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001330 SECTION("setEnabledFeatures - non existing feature")
Václav Kubernát7aaf6dc2020-06-26 18:03:57 +02001331 {
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001332 REQUIRE_THROWS_AS(ys.setEnabledFeatures("example-schema", {"just-no"}), std::runtime_error);
Václav Kubernát7aaf6dc2020-06-26 18:03:57 +02001333 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001334 }
1335}