blob: 0ba0af87b8312da2d1057d762cc9dbc450440834 [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{
480 YangSchema ys;
Jan Kundrátf59b83c2022-03-18 18:12:08 +0100481 ys.registerModuleCallback([](const auto modName, auto, const auto subModule, auto) {
482 if (modName != "example-schema") {
483 throw std::logic_error("unrecognized module " + std::string{modName});
Václav Kubernát82d74632020-05-11 15:59:53 +0200484 }
Jan Kundrátf59b83c2022-03-18 18:12:08 +0100485 if (!subModule) {
Václav Kubernát82d74632020-05-11 15:59:53 +0200486 return example_schema;
487 }
Jan Kundrátf59b83c2022-03-18 18:12:08 +0100488 if (*subModule == "sub-module") {
Václav Kubernát82d74632020-05-11 15:59:53 +0200489 return included_submodule;
490 }
491
Jan Kundrátf59b83c2022-03-18 18:12:08 +0100492 throw std::logic_error("unrecognized submodule " + std::string{*subModule});
Václav Kubernát4f77a252019-02-19 16:51:30 +0100493 });
494 ys.addSchemaString(second_schema);
Václav Kubernát4841f132022-01-12 00:52:30 +0100495 ys.addSchemaString(R"(
496module schema-with-revision {
497 yang-version 1.1;
498 namespace "http://example.com/lol";
499 prefix oof;
500
501 revision "2022-01-12";
502}
503 )");
Václav Kubernát4f77a252019-02-19 16:51:30 +0100504
Václav Kubernátefcac932020-01-10 15:26:32 +0100505 schemaPath_ path{Scope::Absolute, {}};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200506 ModuleNodePair node;
507
508 SECTION("positive")
509 {
Václav Kubernát0d4db442018-07-18 17:18:43 +0200510 SECTION("isModule")
511 {
Václav Kubernát75877de2019-11-20 17:43:02 +0100512 REQUIRE(ys.isModule("example-schema"));
Václav Kubernát4841f132022-01-12 00:52:30 +0100513 REQUIRE(ys.isModule("schema-with-revision"));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200514 }
Václav Kubernáteeb38842019-03-20 19:46:05 +0100515
Václav Kubernát0d4db442018-07-18 17:18:43 +0200516 SECTION("listHasKey")
517 {
518 std::string key;
519
520 SECTION("_list")
521 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200522 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"_list"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200523 SECTION("number")
Václav Kubernát912b9492020-05-29 02:03:40 +0200524 {
525 key = "number";
526 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200527 }
528
529 SECTION("twoKeyList")
530 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200531 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"twoKeyList"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200532 SECTION("number")
Václav Kubernát912b9492020-05-29 02:03:40 +0200533 {
534 key = "number";
535 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200536 SECTION("name")
Václav Kubernát912b9492020-05-29 02:03:40 +0200537 {
538 key = "name";
539 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200540 }
541
Václav Kubernát912b9492020-05-29 02:03:40 +0200542 REQUIRE(ys.listHasKey(path, key));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200543 }
544 SECTION("listKeys")
545 {
546 std::set<std::string> set;
547
548 SECTION("_list")
549 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200550 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"_list"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200551 set = {"number"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200552 }
553
554 SECTION("twoKeyList")
555 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200556 path.m_nodes.emplace_back(module_{"example-schema"}, list_{"twoKeyList"});
Václav Kubernát0d4db442018-07-18 17:18:43 +0200557 set = {"number", "name"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200558 }
559
Václav Kubernát912b9492020-05-29 02:03:40 +0200560 REQUIRE(ys.listKeys(path) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200561 }
562 SECTION("leafType")
563 {
Václav Kubernát3a99f002020-03-31 02:27:41 +0200564 yang::LeafDataType type;
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100565 std::optional<std::string> expectedDescription;
Václav Kubernát0d4db442018-07-18 17:18:43 +0200566
567 SECTION("leafString")
568 {
569 node.first = "example-schema";
570 node.second = "leafString";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200571 type = yang::String{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200572 }
573
574 SECTION("leafDecimal")
575 {
576 node.first = "example-schema";
577 node.second = "leafDecimal";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200578 type = yang::Decimal{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200579 }
580
581 SECTION("leafBool")
582 {
583 node.first = "example-schema";
584 node.second = "leafBool";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200585 type = yang::Bool{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200586 }
587
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200588 SECTION("leafInt8")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200589 {
590 node.first = "example-schema";
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200591 node.second = "leafInt8";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200592 type = yang::Int8{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200593 }
594
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200595 SECTION("leafUint8")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200596 {
597 node.first = "example-schema";
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200598 node.second = "leafUint8";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200599 type = yang::Uint8{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200600 }
601
Václav Kubernátb6d02752020-04-03 00:25:10 +0200602 SECTION("leafInt16")
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200603 {
604 node.first = "example-schema";
605 node.second = "leafInt16";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200606 type = yang::Int16{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200607 }
608
609 SECTION("leafUint16")
610 {
611 node.first = "example-schema";
612 node.second = "leafUint16";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200613 type = yang::Uint16{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200614 }
615
616 SECTION("leafInt32")
617 {
618 node.first = "example-schema";
619 node.second = "leafInt32";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200620 type = yang::Int32{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200621 }
622
623 SECTION("leafUint32")
624 {
625 node.first = "example-schema";
626 node.second = "leafUint32";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200627 type = yang::Uint32{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200628 }
629
630 SECTION("leafInt64")
631 {
632 node.first = "example-schema";
633 node.second = "leafInt64";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200634 type = yang::Int64{};
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200635 }
636
637 SECTION("leafUint64")
638 {
639 node.first = "example-schema";
640 node.second = "leafUint64";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200641 type = yang::Uint64{};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200642 }
643
644 SECTION("leafEnum")
645 {
646 node.first = "example-schema";
647 node.second = "leafEnum";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200648 type = createEnum({"lol", "data", "coze"});
649 }
650
651 SECTION("leafEnumTypedef")
652 {
653 node.first = "example-schema";
654 node.second = "leafEnumTypedef";
655 type = createEnum({"lol", "data", "coze"});
656 }
657
658 SECTION("leafEnumTypedefRestricted")
659 {
660 node.first = "example-schema";
661 node.second = "leafEnumTypedefRestricted";
662 type = createEnum({"data", "coze"});
663 }
664
665 SECTION("leafEnumTypedefRestricted2")
666 {
667 node.first = "example-schema";
668 node.second = "leafEnumTypedefRestricted2";
669 type = createEnum({"lol", "data"});
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100670 expectedDescription = "This is a restricted enum typedef.";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200671 }
672
673 SECTION("pizzaSize")
674 {
675 node.first = "example-schema";
676 node.second = "pizzaSize";
677
678 SECTION("bigPizzas disabled")
679 {
680 type = createEnum({"small", "medium"});
681 }
682 SECTION("bigPizzas enabled")
683 {
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200684 ys.setEnabledFeatures("example-schema", {"bigPizzas"});
Václav Kubernát3a99f002020-03-31 02:27:41 +0200685 type = createEnum({"small", "medium", "large"});
686 }
687 }
688
689 SECTION("foodIdentLeaf")
690 {
691 node.first = "example-schema";
692 node.second = "foodIdentLeaf";
693 type = yang::IdentityRef{{{"second-schema", "pineapple"},
Václav Kubernát3a99f002020-03-31 02:27:41 +0200694 {"example-schema", "pizza"},
695 {"example-schema", "hawaii"},
696 {"example-schema", "fruit"}}};
697 }
698
699 SECTION("pizzaIdentLeaf")
700 {
701 node.first = "example-schema";
702 node.second = "pizzaIdentLeaf";
703
704 type = yang::IdentityRef{{
Václav Kubernát3a99f002020-03-31 02:27:41 +0200705 {"example-schema", "hawaii"},
706 }};
707 }
708
709 SECTION("foodDrinkIdentLeaf")
710 {
711 node.first = "example-schema";
712 node.second = "foodDrinkIdentLeaf";
713
714 type = yang::IdentityRef{{
Václav Kubernát3a99f002020-03-31 02:27:41 +0200715 {"example-schema", "fruit"},
716 {"example-schema", "hawaii"},
717 {"example-schema", "pizza"},
718 {"example-schema", "voda"},
719 {"second-schema", "pineapple"},
720 }};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200721 }
722
Václav Kubernátb6d02752020-04-03 00:25:10 +0200723 SECTION("activeNumber")
724 {
725 node.first = "example-schema";
726 node.second = "activeNumber";
Václav Kubernát3a99f002020-03-31 02:27:41 +0200727 type.emplace<yang::LeafRef>(
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200728 "/_list/number",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200729 std::make_unique<yang::TypeInfo>(ys.leafType("/example-schema:_list/number"))
Václav Kubernát3a99f002020-03-31 02:27:41 +0200730 );
Václav Kubernátb6d02752020-04-03 00:25:10 +0200731 }
732
Václav Kubernát2984f442020-02-20 17:43:35 +0100733 SECTION("activePort")
734 {
735 node.first = "example-schema";
736 node.second = "activePort";
737
Václav Kubernát1dc9e3e2020-06-09 15:22:39 +0200738 yang::Enum enums({});
739 SECTION("weird ports disabled")
740 {
741 enums = createEnum({"utf2", "utf3"});
742 }
743 SECTION("weird ports enabled")
744 {
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200745 ys.setEnabledFeatures("example-schema", {"weirdPortNames"});
Václav Kubernát1dc9e3e2020-06-09 15:22:39 +0200746 enums = createEnum({"WEIRD", "utf2", "utf3"});
747 }
Václav Kubernát2984f442020-02-20 17:43:35 +0100748
749 type = yang::Union{{
Václav Kubernát13b23d72020-04-16 21:49:51 +0200750 yang::TypeInfo{createEnum({"wlan0", "wlan1"})},
751 yang::TypeInfo{yang::LeafRef{
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200752 "../portSettings/port",
Václav Kubernát13b23d72020-04-16 21:49:51 +0200753 std::make_unique<yang::TypeInfo>(createEnum({"eth0", "eth1", "eth2"}))
754 }},
755 yang::TypeInfo{yang::LeafRef{
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200756 "../activeMappedPort",
757 std::make_unique<yang::TypeInfo>(enums)
Václav Kubernát13b23d72020-04-16 21:49:51 +0200758 }},
Jan Kundrát379bb572020-05-07 03:23:13 +0200759 yang::TypeInfo{yang::Empty{}},
Václav Kubernát2984f442020-02-20 17:43:35 +0100760 }};
761 }
762
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200763 SECTION("addresses")
764 {
765 node.first = "example-schema";
766 node.second = "addresses";
767 type.emplace<yang::String>();
768 }
769
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100770 SECTION("flagBits")
771 {
772 node.first = "example-schema";
773 node.second = "flagBits";
774 type = yang::Bits{{"carry", "sign", "overflow"}};
775 }
776
Václav Kubernátfa36c822021-01-25 07:51:02 +0100777 SECTION("foodTypedef")
778 {
779 node.first = "example-schema";
780 node.second = "leafFoodTypedef";
781 type = yang::IdentityRef{{
Václav Kubernátfa36c822021-01-25 07:51:02 +0100782 {"example-schema", "fruit"},
783 {"example-schema", "hawaii"},
784 {"example-schema", "pizza"},
785 {"second-schema", "pineapple"},
786 }};
787 }
788
Václav Kubernát97f6b602022-01-17 23:55:51 +0100789 SECTION("leafNoValidIdent")
790 {
791 node.first = "example-schema";
792 node.second = "leafNoValidIdent";
793 type = yang::IdentityRef{{}};
794 }
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200795
Václav Kubernát1ae24f42020-12-01 02:32:04 +0100796 REQUIRE(ys.leafType(path, node) == yang::TypeInfo(type, std::nullopt, expectedDescription));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200797 }
Václav Kubernát3a823f42020-04-29 23:40:21 +0200798 SECTION("availableNodes")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200799 {
Václav Kubernát3a823f42020-04-29 23:40:21 +0200800 // TODO: merge "path" and "module" sections and add recursive versions to the path section
801 SECTION("paths")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200802 {
Václav Kubernát95b08872020-04-28 01:04:17 +0200803 std::set<ModuleNodePair> set;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200804
Václav Kubernát95b08872020-04-28 01:04:17 +0200805 using namespace std::string_literals;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200806 SECTION("<root>")
807 {
Václav Kubernát95b08872020-04-28 01:04:17 +0200808 set = {{"example-schema"s, "a"}, {"example-schema"s, "b"}, {"example-schema"s, "leafString"},
809 {"example-schema"s, "leafDecimal"}, {"example-schema"s, "leafBool"},
810 {"example-schema"s, "leafInt8"}, {"example-schema"s, "leafUint8"},
811 {"example-schema"s, "leafInt16"}, {"example-schema"s, "leafUint16"},
812 {"example-schema"s, "leafInt32"}, {"example-schema"s, "leafUint32"},
813 {"example-schema"s, "leafInt64"}, {"example-schema"s, "leafUint64"},
814 {"example-schema"s, "leafEnum"}, {"example-schema"s, "leafEnumTypedef"},
815 {"example-schema"s, "leafEnumTypedefRestricted"}, {"example-schema"s, "leafEnumTypedefRestricted2"},
816 {"example-schema"s, "foodIdentLeaf"}, {"example-schema"s, "pizzaIdentLeaf"}, {"example-schema"s, "foodDrinkIdentLeaf"},
817 {"example-schema"s, "_list"}, {"example-schema"s, "twoKeyList"}, {"second-schema"s, "bla"},
818 {"example-schema"s, "carry"}, {"example-schema"s, "zero"}, {"example-schema"s, "direction"},
819 {"example-schema"s, "interrupt"},
820 {"example-schema"s, "ethernet"}, {"example-schema"s, "loopback"},
821 {"example-schema"s, "pizzaSize"},
822 {"example-schema"s, "length"}, {"example-schema"s, "wavelength"},
823 {"example-schema"s, "duration"}, {"example-schema"s, "another-duration"},
824 {"example-schema"s, "activeNumber"},
825 {"example-schema"s, "numberOrString"},
826 {"example-schema"s, "portSettings"},
827 {"example-schema"s, "portMapping"},
828 {"example-schema"s, "activeMappedPort"},
829 {"example-schema"s, "activePort"},
830 {"example-schema"s, "clockSpeed"},
831 {"example-schema"s, "deprecatedLeaf"},
832 {"example-schema"s, "obsoleteLeaf"},
833 {"example-schema"s, "obsoleteLeafWithDeprecatedType"},
834 {"example-schema"s, "obsoleteLeafWithObsoleteType"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200835 {"example-schema"s, "myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100836 {"example-schema"s, "rpcOneOutput"},
837 {"example-schema"s, "rpcOneInput"},
Václav Kubernát82d74632020-05-11 15:59:53 +0200838 {"example-schema"s, "systemStats"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200839 {"example-schema"s, "dummyLeaf"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200840 {"example-schema"s, "addresses"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100841 {"example-schema"s, "subLeaf"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100842 {"example-schema"s, "flagBits"},
Václav Kubernát97f6b602022-01-17 23:55:51 +0100843 {"example-schema"s, "leafFoodTypedef"},
844 {"example-schema"s, "leafNoValidIdent"}};
Václav Kubernát3a823f42020-04-29 23:40:21 +0200845 }
846
847 SECTION("example-schema:a")
848 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200849 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200850 set = {
851 {boost::none, "a2"},
852 {boost::none, "leafa"},
853 {"second-schema"s, "augmentedContainer"}
854 };
Václav Kubernát3a823f42020-04-29 23:40:21 +0200855 }
856
857 SECTION("example-schema:ethernet")
858 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200859 path.m_nodes.emplace_back(module_{"example-schema"}, container_("ethernet"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200860 set = {{boost::none, "ip"}};
861 }
862
863 SECTION("second-schema:bla")
864 {
Václav Kubernátfaacd022020-07-08 16:44:38 +0200865 path.m_nodes.emplace_back(module_{"second-schema"}, container_("bla"));
Václav Kubernát95b08872020-04-28 01:04:17 +0200866 set = {{boost::none, "bla2"}};
Václav Kubernát3a823f42020-04-29 23:40:21 +0200867 }
868
869 REQUIRE(ys.availableNodes(path, Recursion::NonRecursive) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200870 }
871
Václav Kubernát3a823f42020-04-29 23:40:21 +0200872 SECTION("modules")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200873 {
Václav Kubernát3a823f42020-04-29 23:40:21 +0200874 std::string module;
Václav Kubernát95b08872020-04-28 01:04:17 +0200875 std::set<ModuleNodePair> expectedNonRecursive;
876 std::set<ModuleNodePair> expectedRecursive;
877 using namespace std::string_literals;
Václav Kubernát3a823f42020-04-29 23:40:21 +0200878 SECTION("example-schema")
879 {
880 module = "example-schema";
881 expectedNonRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +0200882 {"example-schema"s, "_list"},
883 {"example-schema"s, "a"},
884 {"example-schema"s, "activeMappedPort"},
885 {"example-schema"s, "activeNumber"},
886 {"example-schema"s, "activePort"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200887 {"example-schema"s, "addresses"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200888 {"example-schema"s, "another-duration"},
889 {"example-schema"s, "b"},
890 {"example-schema"s, "carry"},
891 {"example-schema"s, "clockSpeed"},
892 {"example-schema"s, "deprecatedLeaf"},
893 {"example-schema"s, "direction"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200894 {"example-schema"s, "dummyLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200895 {"example-schema"s, "duration"},
896 {"example-schema"s, "ethernet"},
897 {"example-schema"s, "foodDrinkIdentLeaf"},
898 {"example-schema"s, "foodIdentLeaf"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100899 {"example-schema"s, "flagBits"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200900 {"example-schema"s, "interrupt"},
901 {"example-schema"s, "leafBool"},
902 {"example-schema"s, "leafDecimal"},
903 {"example-schema"s, "leafEnum"},
904 {"example-schema"s, "leafEnumTypedef"},
905 {"example-schema"s, "leafEnumTypedefRestricted"},
906 {"example-schema"s, "leafEnumTypedefRestricted2"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100907 {"example-schema"s, "leafFoodTypedef"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200908 {"example-schema"s, "leafInt16"},
909 {"example-schema"s, "leafInt32"},
910 {"example-schema"s, "leafInt64"},
911 {"example-schema"s, "leafInt8"},
Václav Kubernát97f6b602022-01-17 23:55:51 +0100912 {"example-schema"s, "leafNoValidIdent"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200913 {"example-schema"s, "leafString"},
914 {"example-schema"s, "leafUint16"},
915 {"example-schema"s, "leafUint32"},
916 {"example-schema"s, "leafUint64"},
917 {"example-schema"s, "leafUint8"},
918 {"example-schema"s, "length"},
919 {"example-schema"s, "loopback"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200920 {"example-schema"s, "myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100921 {"example-schema"s, "rpcOneOutput"},
922 {"example-schema"s, "rpcOneInput"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200923 {"example-schema"s, "numberOrString"},
924 {"example-schema"s, "obsoleteLeaf"},
925 {"example-schema"s, "obsoleteLeafWithDeprecatedType"},
926 {"example-schema"s, "obsoleteLeafWithObsoleteType"},
927 {"example-schema"s, "pizzaIdentLeaf"},
928 {"example-schema"s, "pizzaSize"},
929 {"example-schema"s, "portMapping"},
930 {"example-schema"s, "portSettings"},
931 {"example-schema"s, "systemStats"},
932 {"example-schema"s, "twoKeyList"},
933 {"example-schema"s, "wavelength"},
Václav Kubernát82d74632020-05-11 15:59:53 +0200934 {"example-schema"s, "zero"},
935 {"example-schema"s, "subLeaf"}
Václav Kubernát3a823f42020-04-29 23:40:21 +0200936 };
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200937
Václav Kubernát3a823f42020-04-29 23:40:21 +0200938 expectedRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +0200939 {boost::none, "/example-schema:_list"},
940 {boost::none, "/example-schema:_list/contInList"},
941 {boost::none, "/example-schema:_list/number"},
942 {boost::none, "/example-schema:a"},
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200943 {boost::none, "/example-schema:addresses"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200944 {boost::none, "/example-schema:a/a2"},
945 {boost::none, "/example-schema:a/a2/a3"},
946 {boost::none, "/example-schema:a/leafa"},
947 {boost::none, "/example-schema:a/second-schema:augmentedContainer"},
948 {boost::none, "/example-schema:activeMappedPort"},
949 {boost::none, "/example-schema:activeNumber"},
950 {boost::none, "/example-schema:activePort"},
951 {boost::none, "/example-schema:another-duration"},
952 {boost::none, "/example-schema:b"},
953 {boost::none, "/example-schema:b/b2"},
954 {boost::none, "/example-schema:b/b2/b3"},
955 {boost::none, "/example-schema:carry"},
956 {boost::none, "/example-schema:clockSpeed"},
957 {boost::none, "/example-schema:deprecatedLeaf"},
958 {boost::none, "/example-schema:direction"},
959 {boost::none, "/example-schema:duration"},
Jan Kundrát379bb572020-05-07 03:23:13 +0200960 {boost::none, "/example-schema:dummyLeaf"},
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100961 {boost::none, "/example-schema:flagBits"},
962 {boost::none, "/example-schema:foodDrinkIdentLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200963 {boost::none, "/example-schema:foodDrinkIdentLeaf"},
964 {boost::none, "/example-schema:foodIdentLeaf"},
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200965 {boost::none, "/example-schema:ethernet"},
966 {boost::none, "/example-schema:ethernet/ip"},
967 {boost::none, "/example-schema:loopback"},
968 {boost::none, "/example-schema:loopback/ip"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200969 {boost::none, "/example-schema:interrupt"},
970 {boost::none, "/example-schema:leafBool"},
971 {boost::none, "/example-schema:leafDecimal"},
972 {boost::none, "/example-schema:leafEnum"},
973 {boost::none, "/example-schema:leafEnumTypedef"},
974 {boost::none, "/example-schema:leafEnumTypedefRestricted"},
975 {boost::none, "/example-schema:leafEnumTypedefRestricted2"},
Václav Kubernátfa36c822021-01-25 07:51:02 +0100976 {boost::none, "/example-schema:leafFoodTypedef"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200977 {boost::none, "/example-schema:leafInt16"},
978 {boost::none, "/example-schema:leafInt32"},
979 {boost::none, "/example-schema:leafInt64"},
980 {boost::none, "/example-schema:leafInt8"},
Václav Kubernát97f6b602022-01-17 23:55:51 +0100981 {boost::none, "/example-schema:leafNoValidIdent"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200982 {boost::none, "/example-schema:leafString"},
983 {boost::none, "/example-schema:leafUint16"},
984 {boost::none, "/example-schema:leafUint32"},
985 {boost::none, "/example-schema:leafUint64"},
986 {boost::none, "/example-schema:leafUint8"},
987 {boost::none, "/example-schema:length"},
Václav Kubernátaaafeae2020-05-05 15:41:45 +0200988 {boost::none, "/example-schema:myRpc"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100989 {boost::none, "/example-schema:rpcOneOutput"},
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200990 {boost::none, "/example-schema:rpcOneOutput/ahoj"},
Václav Kubernátd8408e02020-12-02 05:13:27 +0100991 {boost::none, "/example-schema:rpcOneInput"},
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200992 {boost::none, "/example-schema:rpcOneInput/ahoj"},
Václav Kubernát95b08872020-04-28 01:04:17 +0200993 {boost::none, "/example-schema:numberOrString"},
994 {boost::none, "/example-schema:obsoleteLeaf"},
995 {boost::none, "/example-schema:obsoleteLeafWithDeprecatedType"},
996 {boost::none, "/example-schema:obsoleteLeafWithObsoleteType"},
997 {boost::none, "/example-schema:pizzaIdentLeaf"},
998 {boost::none, "/example-schema:pizzaSize"},
999 {boost::none, "/example-schema:portMapping"},
1000 {boost::none, "/example-schema:portMapping/port"},
1001 {boost::none, "/example-schema:portSettings"},
1002 {boost::none, "/example-schema:portSettings/port"},
1003 {boost::none, "/example-schema:systemStats"},
1004 {boost::none, "/example-schema:systemStats/upTime"},
Václav Kubernát82d74632020-05-11 15:59:53 +02001005 {boost::none, "/example-schema:subLeaf"},
Václav Kubernát95b08872020-04-28 01:04:17 +02001006 {boost::none, "/example-schema:twoKeyList"},
1007 {boost::none, "/example-schema:twoKeyList/name"},
1008 {boost::none, "/example-schema:twoKeyList/number"},
1009 {boost::none, "/example-schema:wavelength"},
1010 {boost::none, "/example-schema:zero"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001011 };
1012 }
Václav Kubernát3a823f42020-04-29 23:40:21 +02001013 SECTION("second-schema")
1014 {
1015 module = "second-schema";
1016 expectedNonRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +02001017 {"second-schema"s, "bla"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001018 };
1019 expectedRecursive = {
Václav Kubernát95b08872020-04-28 01:04:17 +02001020 {boost::none, "/second-schema:bla"},
1021 {boost::none, "/second-schema:bla/bla2"}
Václav Kubernát3a823f42020-04-29 23:40:21 +02001022 };
1023 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001024
Václav Kubernát3a823f42020-04-29 23:40:21 +02001025 REQUIRE(ys.availableNodes(module_{module}, Recursion::NonRecursive) == expectedNonRecursive);
1026 REQUIRE(ys.availableNodes(module_{module}, Recursion::Recursive) == expectedRecursive);
Václav Kubernát47a3f672019-11-08 15:42:43 +01001027 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001028 }
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001029 SECTION("nodeType")
1030 {
1031 yang::NodeTypes expected;
1032 SECTION("leafInt32")
1033 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001034 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001035 expected = yang::NodeTypes::Leaf;
1036 }
1037
1038 SECTION("a")
1039 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001040 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001041 expected = yang::NodeTypes::Container;
1042 }
1043
1044 SECTION("a/a2/a3")
1045 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001046 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1047 path.m_nodes.emplace_back(container_("a2"));
1048 path.m_nodes.emplace_back(container_("a3"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001049 expected = yang::NodeTypes::PresenceContainer;
1050 }
1051
1052 SECTION("_list")
1053 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001054 path.m_nodes.emplace_back(module_{"example-schema"}, list_("_list"));
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001055 expected = yang::NodeTypes::List;
1056 }
1057
Václav Kubernát82d74632020-05-11 15:59:53 +02001058 SECTION("subLeaf")
1059 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001060 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("subLeaf"));
Václav Kubernát82d74632020-05-11 15:59:53 +02001061 expected = yang::NodeTypes::Leaf;
1062 }
1063
Václav Kubernát34ee85a2020-02-18 17:12:12 +01001064 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1065 }
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001066
1067 SECTION("description")
1068 {
1069 std::optional<std::string> expected;
1070 SECTION("leafInt32")
1071 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001072 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001073 expected = "A 32-bit integer leaf.";
1074 }
1075
1076 SECTION("leafString")
1077 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001078 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafString"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001079 }
1080
Václav Kubernát2984f442020-02-20 17:43:35 +01001081 SECTION("numberOrString")
1082 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001083 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("numberOrString"));
Václav Kubernát2984f442020-02-20 17:43:35 +01001084 expected = "Can be an int32 or a string.";
1085 }
1086
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001087 REQUIRE(ys.description(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1088 }
1089
Václav Kubernáta1c4c9e2020-04-22 00:37:52 +02001090 SECTION("status")
1091 {
1092 REQUIRE(ys.status("/example-schema:leafUint64") == yang::Status::Current);
1093 REQUIRE(ys.status("/example-schema:obsoleteLeaf") == yang::Status::Obsolete);
1094 REQUIRE(ys.status("/example-schema:deprecatedLeaf") == yang::Status::Deprecated);
1095 REQUIRE(ys.status("/example-schema:obsoleteLeafWithDeprecatedType") == yang::Status::Obsolete);
1096 REQUIRE(ys.status("/example-schema:obsoleteLeafWithObsoleteType") == yang::Status::Obsolete);
1097 }
1098
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001099 SECTION("units")
1100 {
Václav Kubernát13b23d72020-04-16 21:49:51 +02001101 yang::LeafDataType expectedType;
1102 std::optional<std::string> expectedUnits;
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001103 SECTION("length")
1104 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001105 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("length"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001106 expectedType.emplace<yang::Int32>();
1107 expectedUnits = "m";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001108 }
1109
1110 SECTION("wavelength")
1111 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001112 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("wavelength"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001113 expectedType.emplace<yang::Decimal>();
1114 expectedUnits = "nm";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001115 }
1116
1117 SECTION("leafInt32")
1118 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001119 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001120 expectedType.emplace<yang::Int32>();
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001121 }
1122
1123 SECTION("duration")
1124 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001125 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("duration"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001126 expectedType.emplace<yang::Int32>();
1127 expectedUnits = "s";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001128 }
1129
1130 SECTION("another-duration")
1131 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001132 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("another-duration"));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001133 expectedType.emplace<yang::Int32>();
1134 expectedUnits = "vt";
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001135 }
Václav Kubernát5b8a8f32020-05-20 00:57:22 +02001136 auto nodeType = ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded));
1137 REQUIRE((nodeType == yang::NodeTypes::Leaf || nodeType == yang::NodeTypes::LeafList));
Václav Kubernát13b23d72020-04-16 21:49:51 +02001138 REQUIRE(ys.leafType(pathToSchemaString(path, Prefixes::WhenNeeded)) == yang::TypeInfo{expectedType, expectedUnits});
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001139 }
1140
Václav Kubernát1ae24f42020-12-01 02:32:04 +01001141 SECTION("type description")
1142 {
1143 yang::LeafDataType expectedType = createEnum({"lol", "data"});
1144 std::optional<std::string> expectedDescription;
1145
1146 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafEnumTypedefRestricted2"));
1147 expectedDescription = "This is a restricted enum typedef.";
1148 REQUIRE(ys.leafType(pathToSchemaString(path, Prefixes::WhenNeeded)) == yang::TypeInfo{expectedType, std::nullopt, expectedDescription});
1149 }
1150
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001151 SECTION("nodeType")
1152 {
1153 yang::NodeTypes expected;
1154 SECTION("leafInt32")
1155 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001156 path.m_nodes.emplace_back(module_{"example-schema"}, leaf_("leafInt32"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001157 expected = yang::NodeTypes::Leaf;
1158 }
1159
1160 SECTION("a")
1161 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001162 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001163 expected = yang::NodeTypes::Container;
1164 }
1165
1166 SECTION("a/a2/a3")
1167 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001168 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1169 path.m_nodes.emplace_back(container_("a2"));
1170 path.m_nodes.emplace_back(container_("a3"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001171 expected = yang::NodeTypes::PresenceContainer;
1172 }
1173
1174 SECTION("_list")
1175 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001176 path.m_nodes.emplace_back(module_{"example-schema"}, list_("_list"));
Václav Kubernát1e09bd62020-02-17 15:13:38 +01001177 expected = yang::NodeTypes::List;
1178 }
1179
1180 REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1181 }
Václav Kubernátbd5e3c22020-02-19 15:22:00 +01001182
1183 SECTION("leafrefPath")
1184 {
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001185 REQUIRE(ys.leafrefPath("/example-schema:activeNumber") == "/_list/number");
Václav Kubernátbd5e3c22020-02-19 15:22:00 +01001186 }
Václav Kubernát0599e9f2020-04-21 09:51:33 +02001187
1188 SECTION("isConfig")
1189 {
1190 REQUIRE(ys.isConfig("/example-schema:leafInt32"));
Václav Kubernátc8e5ed02022-03-23 12:46:54 +01001191 REQUIRE(ys.isConfig("/example-schema:rpcOneInput/ahoj"));
Václav Kubernát0599e9f2020-04-21 09:51:33 +02001192 REQUIRE_FALSE(ys.isConfig("/example-schema:clockSpeed"));
1193 REQUIRE_FALSE(ys.isConfig("/example-schema:systemStats"));
1194 REQUIRE_FALSE(ys.isConfig("/example-schema:systemStats/upTime"));
1195 }
Václav Kubernátbd0d5c82020-04-21 10:22:03 +02001196
Václav Kubernátb1a75c62020-04-21 15:20:16 +02001197 SECTION("defaultValue")
1198 {
1199 REQUIRE(ys.defaultValue("/example-schema:leafUint64") == "9001");
1200 REQUIRE(ys.defaultValue("/example-schema:leafEnumTypedefRestricted") == "data");
1201 REQUIRE(ys.defaultValue("/example-schema:leafInt32") == std::nullopt);
1202 }
1203
Václav Kubernát76ba4ec2020-05-18 13:26:56 +02001204 SECTION("leafTypeName")
1205 {
1206 REQUIRE(ys.leafTypeName("/example-schema:leafEnumTypedefRestricted") == "enumTypedef");
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001207 REQUIRE(ys.leafTypeName("/example-schema:leafInt32") == "int32");
Václav Kubernát76ba4ec2020-05-18 13:26:56 +02001208 }
Václav Kubernáta8789602020-07-20 15:18:19 +02001209
1210 SECTION("dataPathToSchemaPath")
1211 {
1212 REQUIRE(ys.dataPathToSchemaPath("/example-schema:portSettings[port='eth0']") == "/example-schema:portSettings");
1213 REQUIRE(ys.dataPathToSchemaPath("/example-schema:portSettings[port='eth0']/shutdown") == "/example-schema:portSettings/shutdown");
1214 }
Václav Kubernátd8408e02020-12-02 05:13:27 +01001215
1216 SECTION("has input nodes")
1217 {
1218 bool expected;
1219 SECTION("example-schema:myRpc")
1220 {
1221 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"myRpc"});
1222 expected = false;
1223 }
1224
1225 SECTION("example-schema:rpcOneInput")
1226 {
1227 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"rpcOneInput"});
1228 expected = true;
1229 }
1230
1231 SECTION("example-schema:rpcOneOutput")
1232 {
1233 path.m_nodes.emplace_back(module_{"example-schema"}, rpcNode_{"rpcOneOutput"});
1234 expected = false;
1235 }
1236
1237 REQUIRE(ys.hasInputNodes(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
1238 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001239 }
1240
1241 SECTION("negative")
1242 {
1243 SECTION("nonexistent nodes")
1244 {
1245 SECTION("example-schema:coze")
1246 {
1247 node.first = "example-schema";
1248 node.second = "coze";
1249 }
1250
1251 SECTION("example-schema:a/nevim")
1252 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001253 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001254 node.second = "nevim";
1255 }
1256
1257 SECTION("modul:a/nevim")
1258 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001259 path.m_nodes.emplace_back(module_{"modul"}, container_("a"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001260 node.second = "nevim";
1261 }
1262
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001263 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001264 }
1265
1266 SECTION("nodetype-specific methods called with different nodetypes")
1267 {
Václav Kubernátfaacd022020-07-08 16:44:38 +02001268 path.m_nodes.emplace_back(module_{"example-schema"}, container_("a"));
1269 path.m_nodes.emplace_back(container_("a2"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001270
Václav Kubernát912b9492020-05-29 02:03:40 +02001271 REQUIRE(!ys.listHasKey(path, "chacha"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001272 }
1273
1274 SECTION("nonexistent module")
1275 {
Václav Kubernát75877de2019-11-20 17:43:02 +01001276 REQUIRE(!ys.isModule("notAModule"));
Václav Kubernát0d4db442018-07-18 17:18:43 +02001277 }
Václav Kubernáteeb38842019-03-20 19:46:05 +01001278
Václav Kubernát7d82da72019-04-11 15:16:38 +02001279 SECTION("grouping is not a node")
1280 {
1281 SECTION("example-schema:arithmeticFlags")
1282 {
1283 node.first = "example-schema";
1284 node.second = "arithmeticFlags";
1285 }
1286
1287 SECTION("example-schema:flags")
1288 {
1289 node.first = "example-schema";
1290 node.second = "startAndStop";
1291 }
1292
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001293 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát7d82da72019-04-11 15:16:38 +02001294 }
Václav Kubernát280df4a2019-11-01 14:46:34 +01001295
1296 SECTION("choice is not a node")
1297 {
1298 SECTION("example-schema:interface")
1299 {
1300 node.first = "example-schema";
1301 node.second = "interface";
1302 }
1303
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001304 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát280df4a2019-11-01 14:46:34 +01001305 }
1306
1307 SECTION("case is not a node")
1308 {
1309 SECTION("example-schema:caseLoopback")
1310 {
1311 node.first = "example-schema";
1312 node.second = "caseLoopback";
1313 }
1314
1315 SECTION("example-schema:caseEthernet")
1316 {
1317 node.first = "example-schema";
1318 node.second = "caseEthernet";
1319 }
1320
Václav Kubernáte811bfa2020-05-29 02:25:20 +02001321 REQUIRE_THROWS(ys.nodeType(path, node));
Václav Kubernát280df4a2019-11-01 14:46:34 +01001322 }
Václav Kubernátf44bdda2020-06-22 15:58:41 +02001323
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001324 SECTION("setEnabledFeatures - non existing module")
Václav Kubernátf44bdda2020-06-22 15:58:41 +02001325 {
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001326 REQUIRE_THROWS_AS(ys.setEnabledFeatures("non-existing", {"just-no"}), std::runtime_error);
Václav Kubernátf44bdda2020-06-22 15:58:41 +02001327 }
Václav Kubernát7aaf6dc2020-06-26 18:03:57 +02001328
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001329 SECTION("setEnabledFeatures - non existing feature")
Václav Kubernát7aaf6dc2020-06-26 18:03:57 +02001330 {
Václav Kubernátcfdb9222021-07-07 22:36:24 +02001331 REQUIRE_THROWS_AS(ys.setEnabledFeatures("example-schema", {"just-no"}), std::runtime_error);
Václav Kubernát7aaf6dc2020-06-26 18:03:57 +02001332 }
Václav Kubernát0d4db442018-07-18 17:18:43 +02001333 }
1334}