blob: b4bec4833ce355558329431acaa2cc910611ed95 [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
Jan Kundráta33cf082019-03-28 11:55:57 +01009#include "trompeloeil_doctest.h"
Václav Kubernát0d4db442018-07-18 17:18:43 +020010#include "yang_schema.hpp"
11
Václav Kubernát4f77a252019-02-19 16:51:30 +010012const char* second_schema = R"(
13module second-schema {
14 namespace "http://example.com/nevim";
15 prefix second;
16
17 import example-schema {
18 prefix "example";
19 }
20
21 augment /example:a {
22 container augmentedContainer {
23 }
24 }
25
26 container bla {
27 container bla2 {
28 }
29 }
30}
31)";
32
33const char* example_schema = R"(
Václav Kubernát0d4db442018-07-18 17:18:43 +020034module example-schema {
Václav Kubernát6a713d62018-10-03 18:47:34 +020035 yang-version 1.1;
Václav Kubernát0d4db442018-07-18 17:18:43 +020036 namespace "http://example.com/example-sports";
37 prefix coze;
38
39 container a {
40 container a2 {
41 container a3 {
42 presence true;
43 }
44 }
45
46 leaf leafa {
47 type string;
48 }
49 }
50
51 container b {
52 container b2 {
53 presence true;
54 container b3 {
55 }
56 }
57 }
58
59 leaf leafString {
60 type string;
61 }
62
63 leaf leafDecimal {
64 type decimal64 {
65 fraction-digits 5;
66 }
67 }
68
69 leaf leafBool {
70 type boolean;
71 }
72
73 leaf leafInt {
74 type int32;
75 }
76
77 leaf leafUint {
78 type uint32;
79 }
80
81 leaf leafEnum {
82 type enumeration {
83 enum lol;
84 enum data;
85 enum coze;
86 }
87 }
88
Václav Kubernát6a713d62018-10-03 18:47:34 +020089 typedef enumTypedef {
90 type enumeration {
91 enum lol;
92 enum data;
93 enum coze;
94 }
95 }
96
97 typedef enumTypedefRestricted {
98 type enumTypedef {
99 enum lol;
100 enum data;
101 }
102 }
103
104 leaf leafEnumTypedef {
105 type enumTypedef;
106 }
107
108 leaf leafEnumTypedefRestricted {
109 type enumTypedef {
110 enum data;
111 enum coze;
112 }
113 }
114
115 leaf leafEnumTypedefRestricted2 {
116 type enumTypedefRestricted;
117 }
118
Václav Kubernát0d4db442018-07-18 17:18:43 +0200119 list _list {
120 key number;
121
122 leaf number {
123 type int32;
124 }
125
126 container contInList {
127 presence true;
128 }
129 }
130
131 list twoKeyList {
132 key "name number";
133
134 leaf number {
135 type int32;
136 }
137
138 leaf name {
139 type string;
140 }
141 }
142})";
143
144TEST_CASE("yangschema")
145{
Václav Kubernát4f77a252019-02-19 16:51:30 +0100146 using namespace std::string_view_literals;
Václav Kubernát0d4db442018-07-18 17:18:43 +0200147 YangSchema ys;
Václav Kubernát4f77a252019-02-19 16:51:30 +0100148 ys.registerModuleCallback([]([[maybe_unused]] auto modName, auto, auto) {
149 assert("example-schema"sv == modName);
150 return example_schema;
151 });
152 ys.addSchemaString(second_schema);
153
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200154 schemaPath_ path;
Václav Kubernát0d4db442018-07-18 17:18:43 +0200155 ModuleNodePair node;
156
157 SECTION("positive")
158 {
159 SECTION("isContainer")
160 {
161 SECTION("example-schema:a")
162 {
163 node.first = "example-schema";
164 node.second = "a";
165 }
166
167 SECTION("example-schema:a/a2")
168 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200169 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200170 node.second = "a2";
171 }
172
173 REQUIRE(ys.isContainer(path, node));
174 }
175 SECTION("isLeaf")
176 {
177 SECTION("example-schema:leafString")
178 {
179 node.first = "example-schema";
180 node.second = "leafString";
181 }
182
183 SECTION("example-schema:a/leafa")
184 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200185 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200186 node.first = "example-schema";
187 node.second = "leafa";
188 }
189
190 REQUIRE(ys.isLeaf(path, node));
191 }
192 SECTION("isModule")
193 {
194 REQUIRE(ys.isModule(path, "example-schema"));
195 }
196 SECTION("isList")
197 {
198 SECTION("example-schema:_list")
199 {
200 node.first = "example-schema";
201 node.second = "_list";
202 }
203
204 SECTION("example-schema:twoKeyList")
205 {
206 node.first = "example-schema";
207 node.second = "twoKeyList";
208 }
209
210 REQUIRE(ys.isList(path, node));
211 }
212 SECTION("isPresenceContainer")
213 {
214 SECTION("example-schema:a/a2/a3")
215 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200216 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
217 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a2")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200218 node.second = "a3";
219 }
220
221 REQUIRE(ys.isPresenceContainer(path, node));
222 }
223 SECTION("leafEnumHasValue")
224 {
Václav Kubernát0d4db442018-07-18 17:18:43 +0200225 std::string value;
Václav Kubernát6a713d62018-10-03 18:47:34 +0200226 SECTION("leafEnum")
227 {
228 node.first = "example-schema";
229 node.second = "leafEnum";
Václav Kubernát0d4db442018-07-18 17:18:43 +0200230
Václav Kubernát6a713d62018-10-03 18:47:34 +0200231 SECTION("lol")
232 value = "lol";
Václav Kubernát0d4db442018-07-18 17:18:43 +0200233
Václav Kubernát6a713d62018-10-03 18:47:34 +0200234 SECTION("data")
235 value = "data";
Václav Kubernát0d4db442018-07-18 17:18:43 +0200236
Václav Kubernát6a713d62018-10-03 18:47:34 +0200237 SECTION("coze")
238 value = "coze";
239 }
240
241 SECTION("leafEnumTypedef")
242 {
243 node.first = "example-schema";
244 node.second = "leafEnumTypedef";
245
246 SECTION("lol")
247 value = "lol";
248
249 SECTION("data")
250 value = "data";
251
252 SECTION("coze")
253 value = "coze";
254 }
255
256 SECTION("leafEnumTypedefRestricted")
257 {
258 node.first = "example-schema";
259 node.second = "leafEnumTypedefRestricted";
260
261 SECTION("data")
262 value = "data";
263
264 SECTION("coze")
265 value = "coze";
266 }
267
268 SECTION("leafEnumTypedefRestricted2")
269 {
270 node.first = "example-schema";
271 node.second = "leafEnumTypedefRestricted2";
272
273 SECTION("lol")
274 value = "lol";
275
276 SECTION("data")
277 value = "data";
278 }
Václav Kubernát0d4db442018-07-18 17:18:43 +0200279
280 REQUIRE(ys.leafEnumHasValue(path, node, value));
281 }
282 SECTION("listHasKey")
283 {
284 std::string key;
285
286 SECTION("_list")
287 {
288 node.first = "example-schema";
289 node.second = "_list";
290 SECTION("number")
291 key = "number";
292 }
293
294 SECTION("twoKeyList")
295 {
296 node.first = "example-schema";
297 node.second = "twoKeyList";
298 SECTION("number")
299 key = "number";
300 SECTION("name")
301 key = "name";
302 }
303
304 REQUIRE(ys.listHasKey(path, node, key));
305 }
306 SECTION("listKeys")
307 {
308 std::set<std::string> set;
309
310 SECTION("_list")
311 {
312 set = {"number"};
313 node.first = "example-schema";
314 node.second = "_list";
315 }
316
317 SECTION("twoKeyList")
318 {
319 set = {"number", "name"};
320 node.first = "example-schema";
321 node.second = "twoKeyList";
322 }
323
324 REQUIRE(ys.listKeys(path, node) == set);
325 }
326 SECTION("leafType")
327 {
328 yang::LeafDataTypes type;
329
330 SECTION("leafString")
331 {
332 node.first = "example-schema";
333 node.second = "leafString";
334 type = yang::LeafDataTypes::String;
335 }
336
337 SECTION("leafDecimal")
338 {
339 node.first = "example-schema";
340 node.second = "leafDecimal";
341 type = yang::LeafDataTypes::Decimal;
342 }
343
344 SECTION("leafBool")
345 {
346 node.first = "example-schema";
347 node.second = "leafBool";
348 type = yang::LeafDataTypes::Bool;
349 }
350
351 SECTION("leafInt")
352 {
353 node.first = "example-schema";
354 node.second = "leafInt";
355 type = yang::LeafDataTypes::Int;
356 }
357
358 SECTION("leafUint")
359 {
360 node.first = "example-schema";
361 node.second = "leafUint";
362 type = yang::LeafDataTypes::Uint;
363 }
364
365 SECTION("leafEnum")
366 {
367 node.first = "example-schema";
368 node.second = "leafEnum";
369 type = yang::LeafDataTypes::Enum;
370 }
371
372 REQUIRE(ys.leafType(path, node) == type);
373 }
374 SECTION("childNodes")
375 {
376 std::set<std::string> set;
377
378 SECTION("<root>")
379 {
380 set = {"example-schema:a", "example-schema:b", "example-schema:leafString",
381 "example-schema:leafDecimal", "example-schema:leafBool", "example-schema:leafInt",
Václav Kubernát6a713d62018-10-03 18:47:34 +0200382 "example-schema:leafUint", "example-schema:leafEnum", "example-schema:leafEnumTypedef",
383 "example-schema:leafEnumTypedefRestricted", "example-schema:leafEnumTypedefRestricted2",
Václav Kubernát4f77a252019-02-19 16:51:30 +0100384 "example-schema:_list", "example-schema:twoKeyList", "second-schema:bla"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200385 }
386
Václav Kubernát4f77a252019-02-19 16:51:30 +0100387 SECTION("example-schema:a")
Václav Kubernát0d4db442018-07-18 17:18:43 +0200388 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200389 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát4f77a252019-02-19 16:51:30 +0100390 set = {"a2", "leafa", "second-schema:augmentedContainer"};
391 }
392
393 SECTION("second-schema:bla")
394 {
395 path.m_nodes.push_back(schemaNode_(module_{"second-schema"}, container_("bla")));
396 set = {"bla2"};
Václav Kubernát0d4db442018-07-18 17:18:43 +0200397 }
398
Václav Kubernáte7d4aea2018-09-11 18:15:48 +0200399 REQUIRE(ys.childNodes(path, Recursion::NonRecursive) == set);
Václav Kubernát0d4db442018-07-18 17:18:43 +0200400 }
401 }
402
403 SECTION("negative")
404 {
405 SECTION("nonexistent nodes")
406 {
407 SECTION("example-schema:coze")
408 {
409 node.first = "example-schema";
410 node.second = "coze";
411 }
412
413 SECTION("example-schema:a/nevim")
414 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200415 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200416 node.second = "nevim";
417 }
418
419 SECTION("modul:a/nevim")
420 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200421 path.m_nodes.push_back(schemaNode_(module_{"modul"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200422 node.second = "nevim";
423 }
424
425 REQUIRE(!ys.isPresenceContainer(path, node));
426 REQUIRE(!ys.isList(path, node));
427 REQUIRE(!ys.isLeaf(path, node));
428 REQUIRE(!ys.isContainer(path, node));
429 }
430
431 SECTION("\"is\" methods return false for existing nodes for different nodetypes")
432 {
433 SECTION("example-schema:a")
434 {
435 node.first = "example-schema";
436 node.second = "a";
437 }
438
439 SECTION("example-schema:a/a2")
440 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200441 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200442 node.second = "a2";
443 }
444
445 REQUIRE(!ys.isPresenceContainer(path, node));
446 REQUIRE(!ys.isList(path, node));
447 REQUIRE(!ys.isLeaf(path, node));
448 }
449
450 SECTION("nodetype-specific methods called with different nodetypes")
451 {
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200452 path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
Václav Kubernát0d4db442018-07-18 17:18:43 +0200453 node.second = "a2";
454
455 REQUIRE(!ys.leafEnumHasValue(path, node, "haha"));
456 REQUIRE(!ys.listHasKey(path, node, "chacha"));
457 }
458
459 SECTION("nonexistent module")
460 {
461 REQUIRE(!ys.isModule(path, "notAModule"));
462 }
463 }
464}