blob: 6bacb27ccc5d809b4495937b8c3e2b6181b6b622 [file] [log] [blame]
Michal Vasko93923692021-05-07 15:28:02 +02001/**
Michal Vasko14795a42020-05-22 16:44:44 +02002 * @file test_xpath.c
3 * @author: Michal Vasko <mvasko@cesnet.cz>
4 * @brief unit tests for XPath evaluation
5 *
6 * Copyright (c) 2020 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
Radek Iša56ca9e42020-09-08 18:42:00 +020014#define _UTEST_MAIN_
15#include "utests.h"
Michal Vasko14795a42020-05-22 16:44:44 +020016
Michal Vasko14795a42020-05-22 16:44:44 +020017#include <string.h>
18
Radek Krejci70593c12020-06-13 20:48:09 +020019#include "context.h"
Radek Krejci7931b192020-06-25 17:05:03 +020020#include "parser_data.h"
Radek Krejci70593c12020-06-13 20:48:09 +020021#include "set.h"
Radek Krejcief5f7672021-04-01 17:04:12 +020022#include "tests_config.h"
Radek Krejci70593c12020-06-13 20:48:09 +020023#include "tree_data.h"
24#include "tree_schema.h"
Michal Vasko14795a42020-05-22 16:44:44 +020025
Radek Iša56ca9e42020-09-08 18:42:00 +020026const char *schema_a =
27 "module a {\n"
28 " namespace urn:tests:a;\n"
29 " prefix a;\n"
30 " yang-version 1.1;\n"
31 "\n"
Michal Vasko93923692021-05-07 15:28:02 +020032 " identity id_a;\n"
33 " identity id_b {\n"
34 " base id_a;\n"
35 " }\n"
36 " identity id_c {\n"
37 " base id_b;\n"
38 " }\n"
39 "\n"
Radek Iša56ca9e42020-09-08 18:42:00 +020040 " list l1 {\n"
41 " key \"a b\";\n"
42 " leaf a {\n"
43 " type string;\n"
44 " }\n"
45 " leaf b {\n"
46 " type string;\n"
47 " }\n"
48 " leaf c {\n"
49 " type string;\n"
50 " }\n"
51 " }\n"
52 " leaf foo {\n"
53 " type string;\n"
54 " }\n"
55 " leaf foo2 {\n"
56 " type uint8;\n"
57 " }\n"
Michal Vasko93923692021-05-07 15:28:02 +020058 " leaf foo3 {\n"
59 " type identityref {\n"
60 " base id_a;\n"
61 " }\n"
62 " }\n"
Michal Vasko00099082022-07-28 10:07:41 +020063 " leaf foo4 {\n"
64 " type decimal64 {\n"
65 " fraction-digits 5;\n"
66 " }\n"
67 " }\n"
Radek Iša56ca9e42020-09-08 18:42:00 +020068 " container c {\n"
69 " leaf x {\n"
70 " type string;\n"
71 " }\n"
72 " list ll {\n"
73 " key \"a\";\n"
74 " leaf a {\n"
75 " type string;\n"
76 " }\n"
77 " list ll {\n"
78 " key \"a\";\n"
79 " leaf a {\n"
80 " type string;\n"
81 " }\n"
82 " leaf b {\n"
83 " type string;\n"
84 " }\n"
85 " }\n"
86 " }\n"
87 " leaf-list ll2 {\n"
88 " type string;\n"
89 " }\n"
90 " }\n"
91 "}";
Michal Vasko14795a42020-05-22 16:44:44 +020092
93static int
94setup(void **state)
95{
Radek Iša56ca9e42020-09-08 18:42:00 +020096 UTEST_SETUP;
Michal Vasko14795a42020-05-22 16:44:44 +020097
Radek Iša56ca9e42020-09-08 18:42:00 +020098 UTEST_ADD_MODULE(schema_a, LYS_IN_YANG, NULL, NULL);
Michal Vaskoa353cce2022-11-14 10:09:55 +010099 lys_parse_path(UTEST_LYCTX, TESTS_DIR_MODULES_YANG "/ietf-interfaces@2014-05-08.yang", LYS_IN_YANG, NULL);
Michal Vasko14795a42020-05-22 16:44:44 +0200100
101 return 0;
102}
103
Michal Vasko14795a42020-05-22 16:44:44 +0200104static void
aPiecekfff4dca2021-10-07 10:59:53 +0200105test_predicate(void **state)
106{
107 const char *data;
108 struct lyd_node *tree;
109 struct ly_set *set;
110
111 data =
Michal Vasko49fec8e2022-05-24 10:28:33 +0200112 "<foo2 xmlns=\"urn:tests:a\">50</foo2>"
Michal Vasko3d969ff2022-07-29 15:02:08 +0200113 "<l1 xmlns=\"urn:tests:a\">"
114 " <a>a1</a>"
115 " <b>b1</b>"
116 " <c>c1</c>"
117 "</l1>"
118 "<l1 xmlns=\"urn:tests:a\">"
119 " <a>a2</a>"
120 " <b>b2</b>"
121 "</l1>"
122 "<l1 xmlns=\"urn:tests:a\">"
123 " <a>a3</a>"
124 " <b>b3</b>"
125 "</l1>"
126 "<l1 xmlns=\"urn:tests:a\">"
127 " <a>a4</a>"
128 " <b>b4</b>"
129 " <c>c4</c>"
130 "</l1>"
131 "<l1 xmlns=\"urn:tests:a\">"
132 " <a>a5</a>"
133 " <b>b5</b>"
134 " <c>c5</c>"
135 "</l1>"
Michal Vasko49fec8e2022-05-24 10:28:33 +0200136 "<c xmlns=\"urn:tests:a\">"
Michal Vasko3d969ff2022-07-29 15:02:08 +0200137 " <x>key2</x>"
Michal Vasko49fec8e2022-05-24 10:28:33 +0200138 " <ll>"
139 " <a>key1</a>"
140 " <ll>"
141 " <a>key11</a>"
142 " <b>val11</b>"
143 " </ll>"
144 " <ll>"
145 " <a>key12</a>"
146 " <b>val12</b>"
147 " </ll>"
148 " <ll>"
149 " <a>key13</a>"
150 " <b>val13</b>"
151 " </ll>"
152 " </ll>"
153 " <ll>"
154 " <a>key2</a>"
155 " <ll>"
156 " <a>key21</a>"
157 " <b>val21</b>"
158 " </ll>"
159 " <ll>"
160 " <a>key22</a>"
161 " <b>val22</b>"
162 " </ll>"
163 " </ll>"
Michal Vasko3d969ff2022-07-29 15:02:08 +0200164 " <ll>"
165 " <a>key3</a>"
166 " <ll>"
167 " <a>key31</a>"
168 " <b>val31</b>"
169 " </ll>"
170 " <ll>"
171 " <a>key32</a>"
172 " <b>val32</b>"
173 " </ll>"
174 " </ll>"
Michal Vasko49fec8e2022-05-24 10:28:33 +0200175 "</c>";
aPiecekfff4dca2021-10-07 10:59:53 +0200176 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
177 assert_non_null(tree);
178
Michal Vasko49fec8e2022-05-24 10:28:33 +0200179 /* predicate after number */
aPiecekfff4dca2021-10-07 10:59:53 +0200180 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/foo2[4[3 = 3]]", &set));
Michal Vasko49fec8e2022-05-24 10:28:33 +0200181 assert_int_equal(0, set->count);
182 ly_set_free(set, NULL);
183
184 /* reverse axis */
185 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/c/child::ll[2]/preceding::ll[3]", &set));
186 assert_int_equal(1, set->count);
187 assert_string_equal("key11", lyd_get_value(lyd_child(set->dnodes[0])));
aPiecekfff4dca2021-10-07 10:59:53 +0200188 ly_set_free(set, NULL);
189
Michal Vasko3d969ff2022-07-29 15:02:08 +0200190 /* special predicate evaluated using hashes */
191 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:l1[a=concat('a', '1')][b=substring('ab1',2)]", &set));
192 assert_int_equal(1, set->count);
193 ly_set_free(set, NULL);
194
195 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/ll[a=../x]", &set));
196 assert_int_equal(1, set->count);
197 ly_set_free(set, NULL);
198
199 /* cannot use hashes */
200 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/ll[a=substring(ll/a,1,4)]", &set));
201 assert_int_equal(3, set->count);
202 ly_set_free(set, NULL);
203
aPiecekfff4dca2021-10-07 10:59:53 +0200204 lyd_free_all(tree);
205}
206
207static void
aPiecekadc1e4f2021-10-07 11:15:12 +0200208test_union(void **state)
209{
210 const char *data;
211 struct lyd_node *tree;
212 struct ly_set *set;
213
214 data =
215 "<l1 xmlns=\"urn:tests:a\">\n"
216 " <a>a1</a>\n"
217 " <b>b1</b>\n"
218 " <c>c1</c>\n"
219 "</l1>\n"
220 "<l1 xmlns=\"urn:tests:a\">\n"
221 " <a>a2</a>\n"
222 " <b>b2</b>\n"
223 "</l1>"
224 "<l1 xmlns=\"urn:tests:a\">\n"
225 " <a>a3</a>\n"
226 " <b>b3</b>\n"
227 " <c>c3</c>\n"
228 "</l1>";
229 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
230 assert_non_null(tree);
231
232 /* Predicate for operand. */
233 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/l1[c[../a = 'a1'] | c]/a", &set));
234 ly_set_free(set, NULL);
235
236 lyd_free_all(tree);
237}
238
239static void
Michal Vaskoe2be5462021-08-04 10:49:42 +0200240test_invalid(void **state)
241{
242 const char *data =
243 "<foo2 xmlns=\"urn:tests:a\">50</foo2>";
244 struct lyd_node *tree;
245 struct ly_set *set;
246
247 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
248 assert_non_null(tree);
249
250 assert_int_equal(LY_EVALID, lyd_find_xpath(tree, "/a:foo2[.=]", &set));
251 assert_null(set);
252
253 assert_int_equal(LY_EVALID, lyd_find_xpath(tree, "/a:", &set));
254 assert_null(set);
255
256 lyd_free_all(tree);
257}
258
259static void
Michal Vasko14795a42020-05-22 16:44:44 +0200260test_hash(void **state)
261{
Michal Vasko14795a42020-05-22 16:44:44 +0200262 const char *data =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100263 "<l1 xmlns=\"urn:tests:a\">\n"
264 " <a>a1</a>\n"
265 " <b>b1</b>\n"
266 " <c>c1</c>\n"
267 "</l1>\n"
268 "<l1 xmlns=\"urn:tests:a\">\n"
269 " <a>a2</a>\n"
270 " <b>b2</b>\n"
271 "</l1>\n"
272 "<l1 xmlns=\"urn:tests:a\">\n"
273 " <a>a3</a>\n"
274 " <b>b3</b>\n"
275 " <c>c3</c>\n"
276 "</l1>\n"
277 "<foo xmlns=\"urn:tests:a\">foo value</foo>\n"
278 "<c xmlns=\"urn:tests:a\">\n"
279 " <x>val</x>\n"
280 " <ll>\n"
281 " <a>val_a</a>\n"
282 " <ll>\n"
283 " <a>val_a</a>\n"
284 " <b>val</b>\n"
285 " </ll>\n"
286 " <ll>\n"
287 " <a>val_b</a>\n"
288 " </ll>\n"
289 " </ll>\n"
290 " <ll>\n"
291 " <a>val_b</a>\n"
292 " <ll>\n"
293 " <a>val_a</a>\n"
294 " </ll>\n"
295 " <ll>\n"
296 " <a>val_b</a>\n"
297 " <b>val</b>\n"
298 " </ll>\n"
299 " </ll>\n"
300 " <ll>\n"
301 " <a>val_c</a>\n"
302 " <ll>\n"
303 " <a>val_a</a>\n"
304 " </ll>\n"
305 " <ll>\n"
306 " <a>val_b</a>\n"
307 " </ll>\n"
308 " </ll>\n"
309 " <ll2>one</ll2>\n"
310 " <ll2>two</ll2>\n"
311 " <ll2>three</ll2>\n"
312 " <ll2>four</ll2>\n"
313 "</c>";
Michal Vasko14795a42020-05-22 16:44:44 +0200314 struct lyd_node *tree, *node;
315 struct ly_set *set;
Michal Vasko14795a42020-05-22 16:44:44 +0200316
Radek Iša56ca9e42020-09-08 18:42:00 +0200317 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
Michal Vasko14795a42020-05-22 16:44:44 +0200318 assert_non_null(tree);
319
320 /* top-level, so hash table is not ultimately used but instances can be compared based on hashes */
321 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:l1[a='a3'][b='b3']", &set));
322 assert_int_equal(1, set->count);
323
324 node = set->objs[0];
325 assert_string_equal(node->schema->name, "l1");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200326 node = lyd_child(node);
Michal Vasko14795a42020-05-22 16:44:44 +0200327 assert_string_equal(node->schema->name, "a");
Radek Krejci6d5ba0c2021-04-26 07:49:59 +0200328 assert_string_equal(lyd_get_value(node), "a3");
Michal Vasko14795a42020-05-22 16:44:44 +0200329
330 ly_set_free(set, NULL);
331
332 /* hashes should be used for both searches (well, there are not enough nested ll instances, so technically not true) */
333 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/ll[a='val_b']/ll[a='val_b']", &set));
334 assert_int_equal(1, set->count);
335
336 node = set->objs[0];
337 assert_string_equal(node->schema->name, "ll");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200338 node = lyd_child(node);
Michal Vasko14795a42020-05-22 16:44:44 +0200339 assert_string_equal(node->schema->name, "a");
Radek Krejci6d5ba0c2021-04-26 07:49:59 +0200340 assert_string_equal(lyd_get_value(node), "val_b");
Michal Vasko14795a42020-05-22 16:44:44 +0200341 node = node->next;
342 assert_string_equal(node->schema->name, "b");
343 assert_null(node->next);
344
345 ly_set_free(set, NULL);
346
347 /* hashes are not used */
348 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c//ll[a='val_b']", &set));
349 assert_int_equal(4, set->count);
350
351 ly_set_free(set, NULL);
352
Michal Vasko660cc8f2020-05-25 10:33:19 +0200353 /* hashes used even for leaf-lists */
354 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/ll2[. = 'three']", &set));
355 assert_int_equal(1, set->count);
356
357 node = set->objs[0];
358 assert_string_equal(node->schema->name, "ll2");
Radek Krejci6d5ba0c2021-04-26 07:49:59 +0200359 assert_string_equal(lyd_get_value(node), "three");
Michal Vasko660cc8f2020-05-25 10:33:19 +0200360
361 ly_set_free(set, NULL);
362
Michal Vasko14795a42020-05-22 16:44:44 +0200363 /* not found using hashes */
364 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/ll[a='val_d']", &set));
365 assert_int_equal(0, set->count);
366
367 ly_set_free(set, NULL);
368
369 /* white-spaces are also ok */
370 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/ll[ \na = 'val_c' ]", &set));
371 assert_int_equal(1, set->count);
372
373 ly_set_free(set, NULL);
374
375 lyd_free_all(tree);
Michal Vasko14795a42020-05-22 16:44:44 +0200376}
377
Michal Vasko61ac2f62020-05-25 12:39:51 +0200378static void
379test_toplevel(void **state)
380{
Radek Iša56ca9e42020-09-08 18:42:00 +0200381 const char *schema_b =
382 "module b {\n"
383 " namespace urn:tests:b;\n"
384 " prefix b;\n"
385 " yang-version 1.1;\n"
386 "\n"
387 " list l2 {\n"
388 " key \"a\";\n"
389 " leaf a {\n"
390 " type uint16;\n"
391 " }\n"
392 " leaf b {\n"
393 " type uint16;\n"
394 " }\n"
395 " }\n"
396 "}";
Michal Vasko61ac2f62020-05-25 12:39:51 +0200397 const char *data =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100398 "<l1 xmlns=\"urn:tests:a\">\n"
399 " <a>a1</a>\n"
400 " <b>b1</b>\n"
401 " <c>c1</c>\n"
402 "</l1>\n"
403 "<l1 xmlns=\"urn:tests:a\">\n"
404 " <a>a2</a>\n"
405 " <b>b2</b>\n"
406 "</l1>\n"
407 "<l1 xmlns=\"urn:tests:a\">\n"
408 " <a>a3</a>\n"
409 " <b>b3</b>\n"
410 " <c>c3</c>\n"
411 "</l1>\n"
412 "<foo xmlns=\"urn:tests:a\">foo value</foo>\n"
413 "<l2 xmlns=\"urn:tests:b\">\n"
414 " <a>1</a>\n"
415 " <b>1</b>\n"
416 "</l2>\n"
417 "<l2 xmlns=\"urn:tests:b\">\n"
418 " <a>2</a>\n"
419 " <b>1</b>\n"
420 "</l2>\n"
421 "<l2 xmlns=\"urn:tests:b\">\n"
422 " <a>3</a>\n"
423 " <b>1</b>\n"
424 "</l2>";
Michal Vaskof60e7102020-05-26 10:48:59 +0200425 struct lyd_node *tree;
Michal Vasko61ac2f62020-05-25 12:39:51 +0200426 struct ly_set *set;
Michal Vasko61ac2f62020-05-25 12:39:51 +0200427
Radek Iša56ca9e42020-09-08 18:42:00 +0200428 UTEST_ADD_MODULE(schema_b, LYS_IN_YANG, NULL, NULL);
429
430 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
Michal Vasko61ac2f62020-05-25 12:39:51 +0200431 assert_non_null(tree);
432
433 /* all top-level nodes from one module (default container as well) */
434 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:*", &set));
435 assert_int_equal(5, set->count);
436
437 ly_set_free(set, NULL);
438
439 /* all top-level nodes from all modules */
440 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/*", &set));
441 assert_int_equal(8, set->count);
442
443 ly_set_free(set, NULL);
444
445 /* all nodes from one module */
446 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "//a:*", &set));
447 assert_int_equal(13, set->count);
448
449 ly_set_free(set, NULL);
450
451 /* all nodes from all modules */
452 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "//*", &set));
453 assert_int_equal(22, set->count);
454
455 ly_set_free(set, NULL);
456
457 /* all nodes from all modules #2 */
458 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "//.", &set));
459 assert_int_equal(22, set->count);
460
461 ly_set_free(set, NULL);
462
463 lyd_free_all(tree);
Michal Vasko61ac2f62020-05-25 12:39:51 +0200464}
465
Michal Vasko519fd602020-05-26 12:17:39 +0200466static void
467test_atomize(void **state)
468{
Michal Vasko519fd602020-05-26 12:17:39 +0200469 struct ly_set *set;
470 const struct lys_module *mod;
471
Radek Iša56ca9e42020-09-08 18:42:00 +0200472 mod = ly_ctx_get_module_latest(UTEST_LYCTX, "a");
473 assert_non_null(mod);
Michal Vasko519fd602020-05-26 12:17:39 +0200474
475 /* some random paths just making sure the API function works */
Michal Vasko400e9672021-01-11 13:39:17 +0100476 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/a:*", 0, &set));
Michal Vasko00099082022-07-28 10:07:41 +0200477 assert_int_equal(6, set->count);
Michal Vasko519fd602020-05-26 12:17:39 +0200478 ly_set_free(set, NULL);
479
480 /* all nodes from all modules (including internal, which can change easily, so check just the test modules) */
Michal Vasko400e9672021-01-11 13:39:17 +0100481 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "//.", 0, &set));
Michal Vasko93923692021-05-07 15:28:02 +0200482 assert_in_range(set->count, 17, UINT32_MAX);
Michal Vasko519fd602020-05-26 12:17:39 +0200483 ly_set_free(set, NULL);
484
Michal Vasko400e9672021-01-11 13:39:17 +0100485 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/a:c/ll[a='val1']/ll[a='val2']/b", 0, &set));
486 assert_int_equal(6, set->count);
Michal Vasko49fec8e2022-05-24 10:28:33 +0200487 ly_set_free(set, NULL);
Michal Vasko519fd602020-05-26 12:17:39 +0200488
Michal Vaskoa353cce2022-11-14 10:09:55 +0100489 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/ietf-interfaces:interfaces/*", 0, &set));
490 assert_int_equal(2, set->count);
491 ly_set_free(set, NULL);
492
493 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/*", 0, &set));
494 assert_int_equal(13, set->count);
495 ly_set_free(set, NULL);
496
Michal Vasko49fec8e2022-05-24 10:28:33 +0200497 /*
498 * axes
499 */
500
501 /* ancestor */
502 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "//ll[a and b]/a/ancestor::node()", 0, &set));
503 assert_int_equal(6, set->count);
504 ly_set_free(set, NULL);
505
506 /* ancestor-or-self */
507 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "//ll[a and b]/ancestor-or-self::ll", 0, &set));
508 assert_int_equal(5, set->count);
509 ly_set_free(set, NULL);
510
511 /* attribute */
512 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/l1/attribute::key", 0, &set));
513 assert_int_equal(1, set->count);
514 ly_set_free(set, NULL);
515
516 /* child */
517 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/child::l1/child::a", 0, &set));
518 assert_int_equal(2, set->count);
519 ly_set_free(set, NULL);
520
521 /* descendant */
522 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/descendant::c/descendant::b", 0, &set));
523 assert_int_equal(3, set->count);
524 ly_set_free(set, NULL);
525
526 /* descendant-or-self */
527 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/a:*/descendant-or-self::c", 0, &set));
Michal Vasko00099082022-07-28 10:07:41 +0200528 assert_int_equal(7, set->count);
Michal Vasko49fec8e2022-05-24 10:28:33 +0200529 ly_set_free(set, NULL);
530
531 /* following */
532 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/c/x/following::a", 0, &set));
533 assert_int_equal(4, set->count);
534 ly_set_free(set, NULL);
535
536 /* following-sibling */
537 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/c/x/following-sibling::ll", 0, &set));
538 assert_int_equal(3, set->count);
539 ly_set_free(set, NULL);
540
541 /* parent */
542 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/child::a:*/c/parent::l1", 0, &set));
Michal Vasko00099082022-07-28 10:07:41 +0200543 assert_int_equal(7, set->count);
Michal Vasko49fec8e2022-05-24 10:28:33 +0200544 ly_set_free(set, NULL);
545
546 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/child::a:c//..", 0, &set));
547 assert_int_equal(8, set->count);
548 ly_set_free(set, NULL);
549
550 /* preceding */
551 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/c/preceding::a", 0, &set));
552 assert_int_equal(2, set->count);
553 ly_set_free(set, NULL);
554
555 /* preceding-sibling */
556 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/c/ll/preceding-sibling::node()", 0, &set));
557 assert_int_equal(3, set->count);
558 ly_set_free(set, NULL);
559
560 /* self */
561 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/c/self::c/ll/ll/b/self::b", 0, &set));
562 assert_int_equal(4, set->count);
Michal Vasko519fd602020-05-26 12:17:39 +0200563 ly_set_free(set, NULL);
564}
565
Michal Vasko4c7763f2020-07-27 17:40:37 +0200566static void
567test_canonize(void **state)
568{
Michal Vasko4c7763f2020-07-27 17:40:37 +0200569 const char *data =
Michal Vasko00099082022-07-28 10:07:41 +0200570 "<foo2 xmlns=\"urn:tests:a\">50</foo2>"
571 "<foo3 xmlns=\"urn:tests:a\" xmlns:a=\"urn:tests:a\">a:id_b</foo3>"
572 "<foo4 xmlns=\"urn:tests:a\">250.5</foo4>";
Michal Vasko4c7763f2020-07-27 17:40:37 +0200573 struct lyd_node *tree;
574 struct ly_set *set;
575
Radek Iša56ca9e42020-09-08 18:42:00 +0200576 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
Michal Vasko4c7763f2020-07-27 17:40:37 +0200577 assert_non_null(tree);
578
Michal Vasko00099082022-07-28 10:07:41 +0200579 /* integer */
Michal Vasko4c7763f2020-07-27 17:40:37 +0200580 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:foo2[.='050']", &set));
581 assert_int_equal(1, set->count);
582 ly_set_free(set, NULL);
583
Michal Vasko00099082022-07-28 10:07:41 +0200584 /* identityref */
585 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:foo3[.='id_b']", &set));
586 assert_int_equal(1, set->count);
587 ly_set_free(set, NULL);
588
589 /* decimal64 */
590 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:foo4[.='0250.500']", &set));
591 assert_int_equal(1, set->count);
592 ly_set_free(set, NULL);
Michal Vasko4c7763f2020-07-27 17:40:37 +0200593
594 lyd_free_all(tree);
Michal Vasko4c7763f2020-07-27 17:40:37 +0200595}
596
Michal Vasko93923692021-05-07 15:28:02 +0200597static void
598test_derived_from(void **state)
599{
600 const char *data =
601 "<foo3 xmlns=\"urn:tests:a\">id_c</foo3>";
602 struct lyd_node *tree;
603 struct ly_set *set;
604
605 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
606 assert_non_null(tree);
607
608 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:foo3[derived-from(., 'a:id_b')]", &set));
609 assert_int_equal(1, set->count);
610 ly_set_free(set, NULL);
611
612 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:foo3[derived-from(., 'a:id_a')]", &set));
613 assert_int_equal(1, set->count);
614 ly_set_free(set, NULL);
615
616 lyd_free_all(tree);
617}
618
Michal Vaskodb08ce52021-10-06 08:57:49 +0200619static void
620test_augment(void **state)
621{
622 const char *schema_b =
623 "module b {\n"
624 " namespace urn:tests:b;\n"
625 " prefix b;\n"
626 " yang-version 1.1;\n"
627 "\n"
628 " import a {\n"
629 " prefix a;\n"
630 " }\n"
631 "\n"
632 " augment /a:c {\n"
633 " leaf a {\n"
634 " type uint16;\n"
635 " }\n"
636 " }\n"
637 "}";
638 const char *data =
639 "<c xmlns=\"urn:tests:a\">\n"
640 " <x>value</x>\n"
641 " <ll>\n"
642 " <a>key</a>\n"
643 " </ll>\n"
644 " <a xmlns=\"urn:tests:b\">25</a>\n"
645 " <ll2>c1</ll2>\n"
646 "</c>";
647 struct lyd_node *tree;
648 struct ly_set *set;
649
650 UTEST_ADD_MODULE(schema_b, LYS_IN_YANG, NULL, NULL);
651
652 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
653 assert_non_null(tree);
654
655 /* get all children ignoring their module */
656 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/*", &set));
657 assert_int_equal(4, set->count);
658
659 ly_set_free(set, NULL);
660
661 lyd_free_all(tree);
662}
663
aPiecekfba75362021-10-07 12:39:48 +0200664static void
665test_variables(void **state)
666{
667 struct lyd_node *tree, *node;
668 struct ly_set *set;
669 const char *data;
670 struct lyxp_var *vars = NULL;
671
672#define LOCAL_SETUP(DATA, TREE) \
673 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, DATA, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &TREE)); \
674 assert_non_null(TREE);
675
676#define SET_NODE(NODE, SET, INDEX) \
677 assert_non_null(SET); \
678 assert_true(INDEX < SET->count); \
679 NODE = SET->objs[INDEX];
680
681#define LOCAL_TEARDOWN(SET, TREE, VARS) \
682 ly_set_free(SET, NULL); \
683 lyd_free_all(TREE); \
684 lyxp_vars_free(VARS); \
685 vars = NULL;
686
687 /* Eval variable to number. */
688 data =
689 "<l1 xmlns=\"urn:tests:a\">\n"
690 " <a>a1</a>\n"
691 " <b>b1</b>\n"
692 " <c>c1</c>\n"
693 "</l1>"
694 "<l1 xmlns=\"urn:tests:a\">\n"
695 " <a>a2</a>\n"
696 " <b>b2</b>\n"
697 " <c>c2</c>\n"
698 "</l1>";
699 LOCAL_SETUP(data, tree);
700 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "2"));
701 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var]/a", vars, &set));
702 SET_NODE(node, set, 0);
703 assert_string_equal(lyd_get_value(node), "a2");
704 LOCAL_TEARDOWN(set, tree, vars);
705
706 /* Eval variable to string. */
707 data =
708 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
709 LOCAL_SETUP(data, tree);
710 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "\"mstr\""));
711 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/foo[text() = $var]", vars, &set));
712 SET_NODE(node, set, 0);
713 assert_string_equal(lyd_get_value(node), "mstr");
714 LOCAL_TEARDOWN(set, tree, vars);
715
716 /* Eval variable to set of nodes. */
717 data =
718 "<l1 xmlns=\"urn:tests:a\">\n"
719 " <a>a1</a>\n"
720 " <b>b1</b>\n"
721 "</l1>"
722 "<l1 xmlns=\"urn:tests:a\">\n"
723 " <a>a2</a>\n"
724 " <b>b2</b>\n"
725 " <c>c2</c>\n"
726 "</l1>";
727 LOCAL_SETUP(data, tree);
728 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "c"));
729 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var]/a", vars, &set));
730 SET_NODE(node, set, 0);
731 assert_string_equal(lyd_get_value(node), "a2");
732 LOCAL_TEARDOWN(set, tree, vars);
733
734 /* Variable in union expr. */
735 data =
736 "<l1 xmlns=\"urn:tests:a\">\n"
737 " <a>a1</a>\n"
738 " <b>b1</b>\n"
739 " <c>c1</c>\n"
740 "</l1>"
741 "<l1 xmlns=\"urn:tests:a\">\n"
742 " <a>a2</a>\n"
743 " <b>b2</b>\n"
744 " <c>c2</c>\n"
745 "</l1>"
746 "<l1 xmlns=\"urn:tests:a\">\n"
747 " <a>a3</a>\n"
748 " <b>b3</b>\n"
749 " <c>c3</c>\n"
750 "</l1>";
751 LOCAL_SETUP(data, tree);
752 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "c[../a = 'a3']"));
753 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[c[../a = 'a1'] | $var]/a", vars, &set));
754 SET_NODE(node, set, 0);
755 assert_string_equal(lyd_get_value(node), "a1");
756 SET_NODE(node, set, 1);
757 assert_string_equal(lyd_get_value(node), "a3");
758 assert_int_equal(set->count, 2);
759 LOCAL_TEARDOWN(set, tree, vars);
760
761 /* Predicate after variable. */
762 data =
763 "<l1 xmlns=\"urn:tests:a\">\n"
764 " <a>a1</a>\n"
765 " <b>b1</b>\n"
766 " <c>c1</c>\n"
767 "</l1>"
768 "<l1 xmlns=\"urn:tests:a\">\n"
769 " <a>a2</a>\n"
770 " <b>b2</b>\n"
771 " <c>c2</c>\n"
772 "</l1>";
773 LOCAL_SETUP(data, tree);
774 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "c"));
775 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var[../a = 'a1']]/a", vars, &set));
776 SET_NODE(node, set, 0);
777 assert_string_equal(lyd_get_value(node), "a1");
778 LOCAL_TEARDOWN(set, tree, vars);
779
780 /* Variable in variable. */
781 data =
782 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
783 LOCAL_SETUP(data, tree);
784 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var1", "$var2"));
785 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var2", "\"mstr\""));
786 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/foo[text() = $var]", vars, &set));
787 SET_NODE(node, set, 0);
788 assert_string_equal(lyd_get_value(node), "mstr");
789 LOCAL_TEARDOWN(set, tree, vars);
790
791 /* Compare two variables. */
792 data =
793 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
794 LOCAL_SETUP(data, tree);
795 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var1", "\"str\""));
796 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var2", "\"str\""));
797 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/foo[$var1 = $var2]", vars, &set));
798 SET_NODE(node, set, 0);
799 assert_string_equal(lyd_get_value(node), "mstr");
800 LOCAL_TEARDOWN(set, tree, vars);
801
802 /* Arithmetic operation with variable. */
803 data =
804 "<foo2 xmlns=\"urn:tests:a\">4</foo2>";
805 LOCAL_SETUP(data, tree);
806 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var1", "2"));
807 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/foo2[.= ($var1 * 2)]", vars, &set));
808 SET_NODE(node, set, 0);
809 assert_string_equal(lyd_get_value(node), "4");
810 LOCAL_TEARDOWN(set, tree, vars);
811
812 /* Variable as function parameter. */
813 data =
814 "<l1 xmlns=\"urn:tests:a\">\n"
815 " <a>a1</a>\n"
816 " <b>b1</b>\n"
817 " <c>c1</c>\n"
818 "</l1>"
819 "<l1 xmlns=\"urn:tests:a\">\n"
820 " <a>a2</a>\n"
821 " <b>b2</b>\n"
822 "</l1>";
823 LOCAL_SETUP(data, tree);
824 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "./c"));
825 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[count($var) = 1]/a", vars, &set));
826 SET_NODE(node, set, 0);
827 assert_string_equal(lyd_get_value(node), "a1");
828 LOCAL_TEARDOWN(set, tree, vars);
829
830 /* Variable in path expr. */
831 /* NOTE: The variable can only be at the beginning of the expression path. */
832 data =
833 "<l1 xmlns=\"urn:tests:a\">\n"
834 " <a>a1</a>\n"
835 " <b>b1</b>\n"
836 " <c>c1</c>\n"
837 "</l1>"
838 "<l1 xmlns=\"urn:tests:a\">\n"
839 " <a>a2</a>\n"
840 " <b>b2</b>\n"
841 "</l1>";
842 LOCAL_SETUP(data, tree);
843 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "/l1"));
844 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var/a]", vars, &set));
845 assert_int_equal(set->count, 2);
846 LOCAL_TEARDOWN(set, tree, vars);
847
848 /* Variable as function. */
849 data =
850 "<l1 xmlns=\"urn:tests:a\">\n"
851 " <a>a1</a>\n"
852 " <b>b1</b>\n"
853 " <c>c1</c>\n"
854 "</l1>"
855 "<l1 xmlns=\"urn:tests:a\">\n"
856 " <a>a2</a>\n"
857 " <b>b2</b>\n"
858 "</l1>";
859 LOCAL_SETUP(data, tree);
860 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "position()"));
861 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var = 2]/a", vars, &set));
862 SET_NODE(node, set, 0);
863 assert_string_equal(lyd_get_value(node), "a2");
864 LOCAL_TEARDOWN(set, tree, vars);
865
866 /* Dynamic change of value. */
867 data =
868 "<l1 xmlns=\"urn:tests:a\">\n"
869 " <a>a1</a>\n"
870 " <b>b1</b>\n"
871 " <c>c1</c>\n"
872 "</l1>"
873 "<l1 xmlns=\"urn:tests:a\">\n"
874 " <a>a2</a>\n"
875 " <b>b2</b>\n"
876 " <c>c2</c>\n"
877 "</l1>";
878 LOCAL_SETUP(data, tree);
879 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "1"));
880 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var]/a", vars, &set));
881 SET_NODE(node, set, 0);
882 assert_string_equal(lyd_get_value(node), "a1");
883 ly_set_free(set, NULL);
884 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "2"));
885 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var]/a", vars, &set));
886 SET_NODE(node, set, 0);
887 assert_string_equal(lyd_get_value(node), "a2");
888 LOCAL_TEARDOWN(set, tree, vars);
889
890 /* Variable not defined. */
891 data =
892 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
893 LOCAL_SETUP(data, tree);
894 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var1", "\"mstr\""));
895 assert_int_equal(LY_ENOTFOUND, lyd_find_xpath2(tree, "/foo[text() = $var55]", vars, &set));
896 LOCAL_TEARDOWN(set, tree, vars);
897
898 /* Syntax error in value. */
899 data =
900 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
901 LOCAL_SETUP(data, tree);
902 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "\""));
903 assert_int_equal(LY_EVALID, lyd_find_xpath2(tree, "/foo[$var]", vars, &set));
904 LOCAL_TEARDOWN(set, tree, vars);
905
906 /* Prefix is not supported. */
907 data =
908 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
909 LOCAL_SETUP(data, tree);
910 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "\""));
911 assert_int_equal(LY_EVALID, lyd_find_xpath2(tree, "/foo[$pref:var]", vars, &set));
912 assert_string_equal("Variable with prefix is not supported.", _UC->err_msg);
913 LOCAL_TEARDOWN(set, tree, vars);
914
915#undef LOCAL_SETUP
916#undef LOCAL_TEARDOWN
917}
918
Michal Vasko49fec8e2022-05-24 10:28:33 +0200919static void
920test_axes(void **state)
921{
922 const char *data;
923 struct lyd_node *tree;
924 struct ly_set *set;
925
926 data =
927 "<l1 xmlns=\"urn:tests:a\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\">\n"
928 " <a>a1</a>\n"
929 " <b yang:operation=\"replace\">b1</b>\n"
930 " <c yang:operation=\"none\">c1</c>\n"
931 "</l1>\n"
932 "<l1 xmlns=\"urn:tests:a\">\n"
933 " <a>a2</a>\n"
934 " <b>b2</b>\n"
935 "</l1>"
936 "<l1 xmlns=\"urn:tests:a\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\">\n"
Michal Vasko79a7a872022-06-17 09:00:48 +0200937 " <a yang:operation=\"none\" yang:key=\"[no-key='no-value']\">a3</a>\n"
Michal Vasko49fec8e2022-05-24 10:28:33 +0200938 " <b>b3</b>\n"
939 " <c yang:value=\"no-val\">c3</c>\n"
940 "</l1>"
941 "<c xmlns=\"urn:tests:a\">"
942 " <x>val</x>"
943 " <ll>"
944 " <a>key1</a>"
945 " <ll>"
946 " <a>key11</a>"
947 " <b>val11</b>"
948 " </ll>"
949 " <ll>"
950 " <a>key12</a>"
951 " <b>val12</b>"
952 " </ll>"
953 " <ll>"
954 " <a>key13</a>"
955 " <b>val13</b>"
956 " </ll>"
957 " </ll>"
958 " <ll>"
959 " <a>key2</a>"
960 " <ll>"
961 " <a>key21</a>"
962 " <b>val21</b>"
963 " </ll>"
964 " <ll>"
965 " <a>key22</a>"
966 " <b>val22</b>"
967 " </ll>"
968 " </ll>"
969 "</c>";
970 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
971 assert_non_null(tree);
972
973 /* ancestor */
974 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "//ll[a and b]/a/ancestor::node()", &set));
975 assert_int_equal(8, set->count);
976 ly_set_free(set, NULL);
977
978 /* ancestor-or-self */
979 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "//ll[a and b]/ancestor-or-self::ll", &set));
980 assert_int_equal(7, set->count);
981 ly_set_free(set, NULL);
982
983 /* attribute */
984 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/l1/@operation", &set));
985 assert_int_equal(0, set->count);
986 ly_set_free(set, NULL);
987
988 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/l1/attribute::key", &set));
989 assert_int_equal(0, set->count);
990 ly_set_free(set, NULL);
991
992 /* child */
993 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/child::l1/child::a", &set));
994 assert_int_equal(3, set->count);
995 ly_set_free(set, NULL);
996
997 /* descendant */
998 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/descendant::c/descendant::b", &set));
999 assert_int_equal(5, set->count);
1000 ly_set_free(set, NULL);
1001
1002 /* descendant-or-self */
1003 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "//c", &set));
1004 assert_int_equal(3, set->count);
1005 ly_set_free(set, NULL);
1006
1007 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/descendant-or-self::node()/c", &set));
1008 assert_int_equal(3, set->count);
1009 ly_set_free(set, NULL);
1010
1011 /* following */
1012 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/c/x/following::a", &set));
1013 assert_int_equal(7, set->count);
1014 ly_set_free(set, NULL);
1015
1016 /* following-sibling */
1017 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/c/x/following-sibling::ll", &set));
1018 assert_int_equal(2, set->count);
1019 ly_set_free(set, NULL);
1020
1021 /* parent */
1022 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/child::*/c/parent::l1", &set));
1023 assert_int_equal(2, set->count);
1024 ly_set_free(set, NULL);
1025
1026 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/child::c//..", &set));
1027 assert_int_equal(8, set->count);
1028 ly_set_free(set, NULL);
1029
1030 /* preceding */
1031 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/c/preceding::a", &set));
1032 assert_int_equal(3, set->count);
1033 ly_set_free(set, NULL);
1034
1035 /* preceding-sibling */
1036 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/c/ll/preceding-sibling::node()", &set));
1037 assert_int_equal(2, set->count);
1038 ly_set_free(set, NULL);
1039
1040 /* self */
1041 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/c/self::c/ll/ll/b/self::b", &set));
1042 assert_int_equal(5, set->count);
1043 ly_set_free(set, NULL);
1044
1045 lyd_free_all(tree);
1046}
1047
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001048int
1049main(void)
Michal Vasko14795a42020-05-22 16:44:44 +02001050{
1051 const struct CMUnitTest tests[] = {
aPiecekfff4dca2021-10-07 10:59:53 +02001052 UTEST(test_predicate, setup),
aPiecekadc1e4f2021-10-07 11:15:12 +02001053 UTEST(test_union, setup),
Michal Vaskoe2be5462021-08-04 10:49:42 +02001054 UTEST(test_invalid, setup),
Radek Iša56ca9e42020-09-08 18:42:00 +02001055 UTEST(test_hash, setup),
1056 UTEST(test_toplevel, setup),
1057 UTEST(test_atomize, setup),
1058 UTEST(test_canonize, setup),
Michal Vasko93923692021-05-07 15:28:02 +02001059 UTEST(test_derived_from, setup),
Michal Vaskodb08ce52021-10-06 08:57:49 +02001060 UTEST(test_augment, setup),
aPiecekfba75362021-10-07 12:39:48 +02001061 UTEST(test_variables, setup),
Michal Vasko49fec8e2022-05-24 10:28:33 +02001062 UTEST(test_axes, setup),
Michal Vasko14795a42020-05-22 16:44:44 +02001063 };
1064
1065 return cmocka_run_group_tests(tests, NULL, NULL);
1066}