blob: 985ecc28e0e00fad47d4d10836838cc64778c551 [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
Michal Vasko3ef7e252022-11-16 08:29:49 +0100204 /* nested predicate */
205 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/a:ll[a:a=string(/a:l1[a:a='foo']/a:a)]/a:a", &set));
206 assert_int_equal(0, set->count);
207 ly_set_free(set, NULL);
208
aPiecekfff4dca2021-10-07 10:59:53 +0200209 lyd_free_all(tree);
210}
211
212static void
aPiecekadc1e4f2021-10-07 11:15:12 +0200213test_union(void **state)
214{
215 const char *data;
216 struct lyd_node *tree;
217 struct ly_set *set;
218
219 data =
220 "<l1 xmlns=\"urn:tests:a\">\n"
221 " <a>a1</a>\n"
222 " <b>b1</b>\n"
223 " <c>c1</c>\n"
224 "</l1>\n"
225 "<l1 xmlns=\"urn:tests:a\">\n"
226 " <a>a2</a>\n"
227 " <b>b2</b>\n"
228 "</l1>"
229 "<l1 xmlns=\"urn:tests:a\">\n"
230 " <a>a3</a>\n"
231 " <b>b3</b>\n"
232 " <c>c3</c>\n"
233 "</l1>";
234 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
235 assert_non_null(tree);
236
237 /* Predicate for operand. */
238 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/l1[c[../a = 'a1'] | c]/a", &set));
239 ly_set_free(set, NULL);
240
241 lyd_free_all(tree);
242}
243
244static void
Michal Vaskoe2be5462021-08-04 10:49:42 +0200245test_invalid(void **state)
246{
247 const char *data =
248 "<foo2 xmlns=\"urn:tests:a\">50</foo2>";
249 struct lyd_node *tree;
250 struct ly_set *set;
251
252 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
253 assert_non_null(tree);
254
255 assert_int_equal(LY_EVALID, lyd_find_xpath(tree, "/a:foo2[.=]", &set));
256 assert_null(set);
Michal Vasko62af3692023-02-09 14:00:09 +0100257 CHECK_LOG_CTX("Unexpected XPath token \"]\" (\"]\").", NULL);
Michal Vaskoe2be5462021-08-04 10:49:42 +0200258
259 assert_int_equal(LY_EVALID, lyd_find_xpath(tree, "/a:", &set));
260 assert_null(set);
Michal Vasko62af3692023-02-09 14:00:09 +0100261 CHECK_LOG_CTX("Invalid character 'a'[2] of expression '/a:'.", NULL);
Michal Vaskoe2be5462021-08-04 10:49:42 +0200262
263 lyd_free_all(tree);
264}
265
266static void
Michal Vasko14795a42020-05-22 16:44:44 +0200267test_hash(void **state)
268{
Michal Vasko14795a42020-05-22 16:44:44 +0200269 const char *data =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100270 "<l1 xmlns=\"urn:tests:a\">\n"
271 " <a>a1</a>\n"
272 " <b>b1</b>\n"
273 " <c>c1</c>\n"
274 "</l1>\n"
275 "<l1 xmlns=\"urn:tests:a\">\n"
276 " <a>a2</a>\n"
277 " <b>b2</b>\n"
278 "</l1>\n"
279 "<l1 xmlns=\"urn:tests:a\">\n"
280 " <a>a3</a>\n"
281 " <b>b3</b>\n"
282 " <c>c3</c>\n"
283 "</l1>\n"
284 "<foo xmlns=\"urn:tests:a\">foo value</foo>\n"
285 "<c xmlns=\"urn:tests:a\">\n"
286 " <x>val</x>\n"
287 " <ll>\n"
288 " <a>val_a</a>\n"
289 " <ll>\n"
290 " <a>val_a</a>\n"
291 " <b>val</b>\n"
292 " </ll>\n"
293 " <ll>\n"
294 " <a>val_b</a>\n"
295 " </ll>\n"
296 " </ll>\n"
297 " <ll>\n"
298 " <a>val_b</a>\n"
299 " <ll>\n"
300 " <a>val_a</a>\n"
301 " </ll>\n"
302 " <ll>\n"
303 " <a>val_b</a>\n"
304 " <b>val</b>\n"
305 " </ll>\n"
306 " </ll>\n"
307 " <ll>\n"
308 " <a>val_c</a>\n"
309 " <ll>\n"
310 " <a>val_a</a>\n"
311 " </ll>\n"
312 " <ll>\n"
313 " <a>val_b</a>\n"
314 " </ll>\n"
315 " </ll>\n"
316 " <ll2>one</ll2>\n"
317 " <ll2>two</ll2>\n"
318 " <ll2>three</ll2>\n"
319 " <ll2>four</ll2>\n"
320 "</c>";
Michal Vasko14795a42020-05-22 16:44:44 +0200321 struct lyd_node *tree, *node;
322 struct ly_set *set;
Michal Vasko14795a42020-05-22 16:44:44 +0200323
Radek Iša56ca9e42020-09-08 18:42:00 +0200324 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 +0200325 assert_non_null(tree);
326
327 /* top-level, so hash table is not ultimately used but instances can be compared based on hashes */
328 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:l1[a='a3'][b='b3']", &set));
329 assert_int_equal(1, set->count);
330
331 node = set->objs[0];
332 assert_string_equal(node->schema->name, "l1");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200333 node = lyd_child(node);
Michal Vasko14795a42020-05-22 16:44:44 +0200334 assert_string_equal(node->schema->name, "a");
Radek Krejci6d5ba0c2021-04-26 07:49:59 +0200335 assert_string_equal(lyd_get_value(node), "a3");
Michal Vasko14795a42020-05-22 16:44:44 +0200336
337 ly_set_free(set, NULL);
338
339 /* hashes should be used for both searches (well, there are not enough nested ll instances, so technically not true) */
340 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/ll[a='val_b']/ll[a='val_b']", &set));
341 assert_int_equal(1, set->count);
342
343 node = set->objs[0];
344 assert_string_equal(node->schema->name, "ll");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200345 node = lyd_child(node);
Michal Vasko14795a42020-05-22 16:44:44 +0200346 assert_string_equal(node->schema->name, "a");
Radek Krejci6d5ba0c2021-04-26 07:49:59 +0200347 assert_string_equal(lyd_get_value(node), "val_b");
Michal Vasko14795a42020-05-22 16:44:44 +0200348 node = node->next;
349 assert_string_equal(node->schema->name, "b");
350 assert_null(node->next);
351
352 ly_set_free(set, NULL);
353
354 /* hashes are not used */
355 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c//ll[a='val_b']", &set));
356 assert_int_equal(4, set->count);
357
358 ly_set_free(set, NULL);
359
Michal Vasko660cc8f2020-05-25 10:33:19 +0200360 /* hashes used even for leaf-lists */
361 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/ll2[. = 'three']", &set));
362 assert_int_equal(1, set->count);
363
364 node = set->objs[0];
365 assert_string_equal(node->schema->name, "ll2");
Radek Krejci6d5ba0c2021-04-26 07:49:59 +0200366 assert_string_equal(lyd_get_value(node), "three");
Michal Vasko660cc8f2020-05-25 10:33:19 +0200367
368 ly_set_free(set, NULL);
369
Michal Vasko14795a42020-05-22 16:44:44 +0200370 /* not found using hashes */
371 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/ll[a='val_d']", &set));
372 assert_int_equal(0, set->count);
373
374 ly_set_free(set, NULL);
375
376 /* white-spaces are also ok */
377 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/ll[ \na = 'val_c' ]", &set));
378 assert_int_equal(1, set->count);
379
380 ly_set_free(set, NULL);
381
382 lyd_free_all(tree);
Michal Vasko14795a42020-05-22 16:44:44 +0200383}
384
Michal Vasko61ac2f62020-05-25 12:39:51 +0200385static void
386test_toplevel(void **state)
387{
Radek Iša56ca9e42020-09-08 18:42:00 +0200388 const char *schema_b =
389 "module b {\n"
390 " namespace urn:tests:b;\n"
391 " prefix b;\n"
392 " yang-version 1.1;\n"
393 "\n"
394 " list l2 {\n"
395 " key \"a\";\n"
396 " leaf a {\n"
397 " type uint16;\n"
398 " }\n"
399 " leaf b {\n"
400 " type uint16;\n"
401 " }\n"
402 " }\n"
403 "}";
Michal Vasko61ac2f62020-05-25 12:39:51 +0200404 const char *data =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100405 "<l1 xmlns=\"urn:tests:a\">\n"
406 " <a>a1</a>\n"
407 " <b>b1</b>\n"
408 " <c>c1</c>\n"
409 "</l1>\n"
410 "<l1 xmlns=\"urn:tests:a\">\n"
411 " <a>a2</a>\n"
412 " <b>b2</b>\n"
413 "</l1>\n"
414 "<l1 xmlns=\"urn:tests:a\">\n"
415 " <a>a3</a>\n"
416 " <b>b3</b>\n"
417 " <c>c3</c>\n"
418 "</l1>\n"
419 "<foo xmlns=\"urn:tests:a\">foo value</foo>\n"
420 "<l2 xmlns=\"urn:tests:b\">\n"
421 " <a>1</a>\n"
422 " <b>1</b>\n"
423 "</l2>\n"
424 "<l2 xmlns=\"urn:tests:b\">\n"
425 " <a>2</a>\n"
426 " <b>1</b>\n"
427 "</l2>\n"
428 "<l2 xmlns=\"urn:tests:b\">\n"
429 " <a>3</a>\n"
430 " <b>1</b>\n"
431 "</l2>";
Michal Vaskof60e7102020-05-26 10:48:59 +0200432 struct lyd_node *tree;
Michal Vasko61ac2f62020-05-25 12:39:51 +0200433 struct ly_set *set;
Michal Vasko61ac2f62020-05-25 12:39:51 +0200434
Radek Iša56ca9e42020-09-08 18:42:00 +0200435 UTEST_ADD_MODULE(schema_b, LYS_IN_YANG, NULL, NULL);
436
437 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 +0200438 assert_non_null(tree);
439
440 /* all top-level nodes from one module (default container as well) */
441 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:*", &set));
442 assert_int_equal(5, set->count);
443
444 ly_set_free(set, NULL);
445
446 /* all top-level nodes from all modules */
447 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/*", &set));
448 assert_int_equal(8, set->count);
449
450 ly_set_free(set, NULL);
451
452 /* all nodes from one module */
453 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "//a:*", &set));
454 assert_int_equal(13, set->count);
455
456 ly_set_free(set, NULL);
457
458 /* all nodes from all modules */
459 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "//*", &set));
460 assert_int_equal(22, set->count);
461
462 ly_set_free(set, NULL);
463
464 /* all nodes from all modules #2 */
465 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "//.", &set));
466 assert_int_equal(22, set->count);
467
468 ly_set_free(set, NULL);
469
470 lyd_free_all(tree);
Michal Vasko61ac2f62020-05-25 12:39:51 +0200471}
472
Michal Vasko519fd602020-05-26 12:17:39 +0200473static void
474test_atomize(void **state)
475{
Michal Vasko519fd602020-05-26 12:17:39 +0200476 struct ly_set *set;
477 const struct lys_module *mod;
478
Radek Iša56ca9e42020-09-08 18:42:00 +0200479 mod = ly_ctx_get_module_latest(UTEST_LYCTX, "a");
480 assert_non_null(mod);
Michal Vasko519fd602020-05-26 12:17:39 +0200481
482 /* some random paths just making sure the API function works */
Michal Vasko400e9672021-01-11 13:39:17 +0100483 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/a:*", 0, &set));
Michal Vasko00099082022-07-28 10:07:41 +0200484 assert_int_equal(6, set->count);
Michal Vasko519fd602020-05-26 12:17:39 +0200485 ly_set_free(set, NULL);
486
487 /* all nodes from all modules (including internal, which can change easily, so check just the test modules) */
Michal Vasko400e9672021-01-11 13:39:17 +0100488 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "//.", 0, &set));
Michal Vasko93923692021-05-07 15:28:02 +0200489 assert_in_range(set->count, 17, UINT32_MAX);
Michal Vasko519fd602020-05-26 12:17:39 +0200490 ly_set_free(set, NULL);
491
Michal Vasko400e9672021-01-11 13:39:17 +0100492 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/a:c/ll[a='val1']/ll[a='val2']/b", 0, &set));
493 assert_int_equal(6, set->count);
Michal Vasko49fec8e2022-05-24 10:28:33 +0200494 ly_set_free(set, NULL);
Michal Vasko519fd602020-05-26 12:17:39 +0200495
Michal Vaskoa353cce2022-11-14 10:09:55 +0100496 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/ietf-interfaces:interfaces/*", 0, &set));
497 assert_int_equal(2, set->count);
498 ly_set_free(set, NULL);
499
500 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/*", 0, &set));
501 assert_int_equal(13, set->count);
502 ly_set_free(set, NULL);
503
Michal Vasko49fec8e2022-05-24 10:28:33 +0200504 /*
505 * axes
506 */
507
508 /* ancestor */
509 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "//ll[a and b]/a/ancestor::node()", 0, &set));
510 assert_int_equal(6, set->count);
511 ly_set_free(set, NULL);
512
513 /* ancestor-or-self */
514 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "//ll[a and b]/ancestor-or-self::ll", 0, &set));
515 assert_int_equal(5, set->count);
516 ly_set_free(set, NULL);
517
518 /* attribute */
519 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/l1/attribute::key", 0, &set));
520 assert_int_equal(1, set->count);
521 ly_set_free(set, NULL);
522
523 /* child */
524 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/child::l1/child::a", 0, &set));
525 assert_int_equal(2, set->count);
526 ly_set_free(set, NULL);
527
528 /* descendant */
529 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/descendant::c/descendant::b", 0, &set));
530 assert_int_equal(3, set->count);
531 ly_set_free(set, NULL);
532
533 /* descendant-or-self */
534 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 +0200535 assert_int_equal(7, set->count);
Michal Vasko49fec8e2022-05-24 10:28:33 +0200536 ly_set_free(set, NULL);
537
538 /* following */
539 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/c/x/following::a", 0, &set));
540 assert_int_equal(4, set->count);
541 ly_set_free(set, NULL);
542
543 /* following-sibling */
544 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/c/x/following-sibling::ll", 0, &set));
545 assert_int_equal(3, set->count);
546 ly_set_free(set, NULL);
547
548 /* parent */
549 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 +0200550 assert_int_equal(7, set->count);
Michal Vasko49fec8e2022-05-24 10:28:33 +0200551 ly_set_free(set, NULL);
552
553 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/child::a:c//..", 0, &set));
554 assert_int_equal(8, set->count);
555 ly_set_free(set, NULL);
556
557 /* preceding */
558 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/c/preceding::a", 0, &set));
559 assert_int_equal(2, set->count);
560 ly_set_free(set, NULL);
561
562 /* preceding-sibling */
563 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/c/ll/preceding-sibling::node()", 0, &set));
564 assert_int_equal(3, set->count);
565 ly_set_free(set, NULL);
566
567 /* self */
568 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/c/self::c/ll/ll/b/self::b", 0, &set));
569 assert_int_equal(4, set->count);
Michal Vasko519fd602020-05-26 12:17:39 +0200570 ly_set_free(set, NULL);
571}
572
Michal Vasko4c7763f2020-07-27 17:40:37 +0200573static void
574test_canonize(void **state)
575{
Michal Vasko4c7763f2020-07-27 17:40:37 +0200576 const char *data =
Michal Vasko00099082022-07-28 10:07:41 +0200577 "<foo2 xmlns=\"urn:tests:a\">50</foo2>"
578 "<foo3 xmlns=\"urn:tests:a\" xmlns:a=\"urn:tests:a\">a:id_b</foo3>"
579 "<foo4 xmlns=\"urn:tests:a\">250.5</foo4>";
Michal Vasko4c7763f2020-07-27 17:40:37 +0200580 struct lyd_node *tree;
581 struct ly_set *set;
582
Radek Iša56ca9e42020-09-08 18:42:00 +0200583 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 +0200584 assert_non_null(tree);
585
Michal Vasko00099082022-07-28 10:07:41 +0200586 /* integer */
Michal Vasko4c7763f2020-07-27 17:40:37 +0200587 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:foo2[.='050']", &set));
588 assert_int_equal(1, set->count);
589 ly_set_free(set, NULL);
590
Michal Vasko00099082022-07-28 10:07:41 +0200591 /* identityref */
592 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:foo3[.='id_b']", &set));
593 assert_int_equal(1, set->count);
594 ly_set_free(set, NULL);
595
596 /* decimal64 */
597 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:foo4[.='0250.500']", &set));
598 assert_int_equal(1, set->count);
599 ly_set_free(set, NULL);
Michal Vasko4c7763f2020-07-27 17:40:37 +0200600
601 lyd_free_all(tree);
Michal Vasko4c7763f2020-07-27 17:40:37 +0200602}
603
Michal Vasko93923692021-05-07 15:28:02 +0200604static void
605test_derived_from(void **state)
606{
607 const char *data =
608 "<foo3 xmlns=\"urn:tests:a\">id_c</foo3>";
609 struct lyd_node *tree;
610 struct ly_set *set;
611
612 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
613 assert_non_null(tree);
614
615 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:foo3[derived-from(., 'a:id_b')]", &set));
616 assert_int_equal(1, set->count);
617 ly_set_free(set, NULL);
618
619 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:foo3[derived-from(., 'a:id_a')]", &set));
620 assert_int_equal(1, set->count);
621 ly_set_free(set, NULL);
622
623 lyd_free_all(tree);
624}
625
Michal Vaskodb08ce52021-10-06 08:57:49 +0200626static void
627test_augment(void **state)
628{
629 const char *schema_b =
630 "module b {\n"
631 " namespace urn:tests:b;\n"
632 " prefix b;\n"
633 " yang-version 1.1;\n"
634 "\n"
635 " import a {\n"
636 " prefix a;\n"
637 " }\n"
638 "\n"
639 " augment /a:c {\n"
640 " leaf a {\n"
641 " type uint16;\n"
642 " }\n"
643 " }\n"
644 "}";
645 const char *data =
646 "<c xmlns=\"urn:tests:a\">\n"
647 " <x>value</x>\n"
648 " <ll>\n"
649 " <a>key</a>\n"
650 " </ll>\n"
651 " <a xmlns=\"urn:tests:b\">25</a>\n"
652 " <ll2>c1</ll2>\n"
653 "</c>";
654 struct lyd_node *tree;
655 struct ly_set *set;
656
657 UTEST_ADD_MODULE(schema_b, LYS_IN_YANG, NULL, NULL);
658
659 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
660 assert_non_null(tree);
661
662 /* get all children ignoring their module */
663 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/*", &set));
664 assert_int_equal(4, set->count);
665
666 ly_set_free(set, NULL);
667
668 lyd_free_all(tree);
669}
670
aPiecekfba75362021-10-07 12:39:48 +0200671static void
672test_variables(void **state)
673{
674 struct lyd_node *tree, *node;
675 struct ly_set *set;
676 const char *data;
677 struct lyxp_var *vars = NULL;
678
679#define LOCAL_SETUP(DATA, TREE) \
680 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, DATA, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &TREE)); \
681 assert_non_null(TREE);
682
683#define SET_NODE(NODE, SET, INDEX) \
684 assert_non_null(SET); \
685 assert_true(INDEX < SET->count); \
686 NODE = SET->objs[INDEX];
687
688#define LOCAL_TEARDOWN(SET, TREE, VARS) \
689 ly_set_free(SET, NULL); \
690 lyd_free_all(TREE); \
691 lyxp_vars_free(VARS); \
692 vars = NULL;
693
694 /* Eval variable to number. */
695 data =
696 "<l1 xmlns=\"urn:tests:a\">\n"
697 " <a>a1</a>\n"
698 " <b>b1</b>\n"
699 " <c>c1</c>\n"
700 "</l1>"
701 "<l1 xmlns=\"urn:tests:a\">\n"
702 " <a>a2</a>\n"
703 " <b>b2</b>\n"
704 " <c>c2</c>\n"
705 "</l1>";
706 LOCAL_SETUP(data, tree);
707 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "2"));
708 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var]/a", vars, &set));
709 SET_NODE(node, set, 0);
710 assert_string_equal(lyd_get_value(node), "a2");
711 LOCAL_TEARDOWN(set, tree, vars);
712
713 /* Eval variable to string. */
714 data =
715 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
716 LOCAL_SETUP(data, tree);
717 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "\"mstr\""));
718 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/foo[text() = $var]", vars, &set));
719 SET_NODE(node, set, 0);
720 assert_string_equal(lyd_get_value(node), "mstr");
721 LOCAL_TEARDOWN(set, tree, vars);
722
723 /* Eval variable to set of nodes. */
724 data =
725 "<l1 xmlns=\"urn:tests:a\">\n"
726 " <a>a1</a>\n"
727 " <b>b1</b>\n"
728 "</l1>"
729 "<l1 xmlns=\"urn:tests:a\">\n"
730 " <a>a2</a>\n"
731 " <b>b2</b>\n"
732 " <c>c2</c>\n"
733 "</l1>";
734 LOCAL_SETUP(data, tree);
735 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "c"));
736 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var]/a", vars, &set));
737 SET_NODE(node, set, 0);
738 assert_string_equal(lyd_get_value(node), "a2");
739 LOCAL_TEARDOWN(set, tree, vars);
740
741 /* Variable in union expr. */
742 data =
743 "<l1 xmlns=\"urn:tests:a\">\n"
744 " <a>a1</a>\n"
745 " <b>b1</b>\n"
746 " <c>c1</c>\n"
747 "</l1>"
748 "<l1 xmlns=\"urn:tests:a\">\n"
749 " <a>a2</a>\n"
750 " <b>b2</b>\n"
751 " <c>c2</c>\n"
752 "</l1>"
753 "<l1 xmlns=\"urn:tests:a\">\n"
754 " <a>a3</a>\n"
755 " <b>b3</b>\n"
756 " <c>c3</c>\n"
757 "</l1>";
758 LOCAL_SETUP(data, tree);
759 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "c[../a = 'a3']"));
760 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[c[../a = 'a1'] | $var]/a", vars, &set));
761 SET_NODE(node, set, 0);
762 assert_string_equal(lyd_get_value(node), "a1");
763 SET_NODE(node, set, 1);
764 assert_string_equal(lyd_get_value(node), "a3");
765 assert_int_equal(set->count, 2);
766 LOCAL_TEARDOWN(set, tree, vars);
767
768 /* Predicate after variable. */
769 data =
770 "<l1 xmlns=\"urn:tests:a\">\n"
771 " <a>a1</a>\n"
772 " <b>b1</b>\n"
773 " <c>c1</c>\n"
774 "</l1>"
775 "<l1 xmlns=\"urn:tests:a\">\n"
776 " <a>a2</a>\n"
777 " <b>b2</b>\n"
778 " <c>c2</c>\n"
779 "</l1>";
780 LOCAL_SETUP(data, tree);
781 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "c"));
782 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var[../a = 'a1']]/a", vars, &set));
783 SET_NODE(node, set, 0);
784 assert_string_equal(lyd_get_value(node), "a1");
785 LOCAL_TEARDOWN(set, tree, vars);
786
787 /* Variable in variable. */
788 data =
789 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
790 LOCAL_SETUP(data, tree);
791 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var1", "$var2"));
792 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var2", "\"mstr\""));
793 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/foo[text() = $var]", vars, &set));
794 SET_NODE(node, set, 0);
795 assert_string_equal(lyd_get_value(node), "mstr");
796 LOCAL_TEARDOWN(set, tree, vars);
797
798 /* Compare two variables. */
799 data =
800 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
801 LOCAL_SETUP(data, tree);
802 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var1", "\"str\""));
803 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var2", "\"str\""));
804 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/foo[$var1 = $var2]", vars, &set));
805 SET_NODE(node, set, 0);
806 assert_string_equal(lyd_get_value(node), "mstr");
807 LOCAL_TEARDOWN(set, tree, vars);
808
809 /* Arithmetic operation with variable. */
810 data =
811 "<foo2 xmlns=\"urn:tests:a\">4</foo2>";
812 LOCAL_SETUP(data, tree);
813 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var1", "2"));
814 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/foo2[.= ($var1 * 2)]", vars, &set));
815 SET_NODE(node, set, 0);
816 assert_string_equal(lyd_get_value(node), "4");
817 LOCAL_TEARDOWN(set, tree, vars);
818
819 /* Variable as function parameter. */
820 data =
821 "<l1 xmlns=\"urn:tests:a\">\n"
822 " <a>a1</a>\n"
823 " <b>b1</b>\n"
824 " <c>c1</c>\n"
825 "</l1>"
826 "<l1 xmlns=\"urn:tests:a\">\n"
827 " <a>a2</a>\n"
828 " <b>b2</b>\n"
829 "</l1>";
830 LOCAL_SETUP(data, tree);
831 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "./c"));
832 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[count($var) = 1]/a", vars, &set));
833 SET_NODE(node, set, 0);
834 assert_string_equal(lyd_get_value(node), "a1");
835 LOCAL_TEARDOWN(set, tree, vars);
836
837 /* Variable in path expr. */
838 /* NOTE: The variable can only be at the beginning of the expression path. */
839 data =
840 "<l1 xmlns=\"urn:tests:a\">\n"
841 " <a>a1</a>\n"
842 " <b>b1</b>\n"
843 " <c>c1</c>\n"
844 "</l1>"
845 "<l1 xmlns=\"urn:tests:a\">\n"
846 " <a>a2</a>\n"
847 " <b>b2</b>\n"
848 "</l1>";
849 LOCAL_SETUP(data, tree);
850 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "/l1"));
851 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var/a]", vars, &set));
852 assert_int_equal(set->count, 2);
853 LOCAL_TEARDOWN(set, tree, vars);
854
855 /* Variable as function. */
856 data =
857 "<l1 xmlns=\"urn:tests:a\">\n"
858 " <a>a1</a>\n"
859 " <b>b1</b>\n"
860 " <c>c1</c>\n"
861 "</l1>"
862 "<l1 xmlns=\"urn:tests:a\">\n"
863 " <a>a2</a>\n"
864 " <b>b2</b>\n"
865 "</l1>";
866 LOCAL_SETUP(data, tree);
867 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "position()"));
868 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var = 2]/a", vars, &set));
869 SET_NODE(node, set, 0);
870 assert_string_equal(lyd_get_value(node), "a2");
871 LOCAL_TEARDOWN(set, tree, vars);
872
873 /* Dynamic change of value. */
874 data =
875 "<l1 xmlns=\"urn:tests:a\">\n"
876 " <a>a1</a>\n"
877 " <b>b1</b>\n"
878 " <c>c1</c>\n"
879 "</l1>"
880 "<l1 xmlns=\"urn:tests:a\">\n"
881 " <a>a2</a>\n"
882 " <b>b2</b>\n"
883 " <c>c2</c>\n"
884 "</l1>";
885 LOCAL_SETUP(data, tree);
886 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "1"));
887 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var]/a", vars, &set));
888 SET_NODE(node, set, 0);
889 assert_string_equal(lyd_get_value(node), "a1");
890 ly_set_free(set, NULL);
891 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "2"));
892 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var]/a", vars, &set));
893 SET_NODE(node, set, 0);
894 assert_string_equal(lyd_get_value(node), "a2");
895 LOCAL_TEARDOWN(set, tree, vars);
896
897 /* Variable not defined. */
898 data =
899 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
900 LOCAL_SETUP(data, tree);
901 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var1", "\"mstr\""));
902 assert_int_equal(LY_ENOTFOUND, lyd_find_xpath2(tree, "/foo[text() = $var55]", vars, &set));
Michal Vasko90189962023-02-28 12:10:34 +0100903 CHECK_LOG_CTX("Variable \"var55\" not defined.", NULL);
aPiecekfba75362021-10-07 12:39:48 +0200904 LOCAL_TEARDOWN(set, tree, vars);
905
906 /* Syntax error in value. */
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[$var]", vars, &set));
Michal Vasko62af3692023-02-09 14:00:09 +0100912 CHECK_LOG_CTX("Unterminated string delimited with \" (\").", "Data location \"/a:foo\".");
aPiecekfba75362021-10-07 12:39:48 +0200913 LOCAL_TEARDOWN(set, tree, vars);
914
915 /* Prefix is not supported. */
916 data =
917 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
918 LOCAL_SETUP(data, tree);
919 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "\""));
920 assert_int_equal(LY_EVALID, lyd_find_xpath2(tree, "/foo[$pref:var]", vars, &set));
Michal Vasko62af3692023-02-09 14:00:09 +0100921 CHECK_LOG_CTX("Variable with prefix is not supported.", NULL);
aPiecekfba75362021-10-07 12:39:48 +0200922 LOCAL_TEARDOWN(set, tree, vars);
923
924#undef LOCAL_SETUP
925#undef LOCAL_TEARDOWN
926}
927
Michal Vasko49fec8e2022-05-24 10:28:33 +0200928static void
929test_axes(void **state)
930{
931 const char *data;
932 struct lyd_node *tree;
933 struct ly_set *set;
934
935 data =
936 "<l1 xmlns=\"urn:tests:a\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\">\n"
937 " <a>a1</a>\n"
938 " <b yang:operation=\"replace\">b1</b>\n"
939 " <c yang:operation=\"none\">c1</c>\n"
940 "</l1>\n"
941 "<l1 xmlns=\"urn:tests:a\">\n"
942 " <a>a2</a>\n"
943 " <b>b2</b>\n"
944 "</l1>"
945 "<l1 xmlns=\"urn:tests:a\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\">\n"
Michal Vasko79a7a872022-06-17 09:00:48 +0200946 " <a yang:operation=\"none\" yang:key=\"[no-key='no-value']\">a3</a>\n"
Michal Vasko49fec8e2022-05-24 10:28:33 +0200947 " <b>b3</b>\n"
948 " <c yang:value=\"no-val\">c3</c>\n"
949 "</l1>"
950 "<c xmlns=\"urn:tests:a\">"
951 " <x>val</x>"
952 " <ll>"
953 " <a>key1</a>"
954 " <ll>"
955 " <a>key11</a>"
956 " <b>val11</b>"
957 " </ll>"
958 " <ll>"
959 " <a>key12</a>"
960 " <b>val12</b>"
961 " </ll>"
962 " <ll>"
963 " <a>key13</a>"
964 " <b>val13</b>"
965 " </ll>"
966 " </ll>"
967 " <ll>"
968 " <a>key2</a>"
969 " <ll>"
970 " <a>key21</a>"
971 " <b>val21</b>"
972 " </ll>"
973 " <ll>"
974 " <a>key22</a>"
975 " <b>val22</b>"
976 " </ll>"
977 " </ll>"
978 "</c>";
979 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
980 assert_non_null(tree);
981
982 /* ancestor */
983 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "//ll[a and b]/a/ancestor::node()", &set));
984 assert_int_equal(8, set->count);
985 ly_set_free(set, NULL);
986
987 /* ancestor-or-self */
988 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "//ll[a and b]/ancestor-or-self::ll", &set));
989 assert_int_equal(7, set->count);
990 ly_set_free(set, NULL);
991
992 /* attribute */
993 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/l1/@operation", &set));
994 assert_int_equal(0, set->count);
995 ly_set_free(set, NULL);
996
997 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/l1/attribute::key", &set));
998 assert_int_equal(0, set->count);
999 ly_set_free(set, NULL);
1000
1001 /* child */
1002 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/child::l1/child::a", &set));
1003 assert_int_equal(3, set->count);
1004 ly_set_free(set, NULL);
1005
1006 /* descendant */
1007 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/descendant::c/descendant::b", &set));
1008 assert_int_equal(5, set->count);
1009 ly_set_free(set, NULL);
1010
1011 /* descendant-or-self */
1012 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "//c", &set));
1013 assert_int_equal(3, set->count);
1014 ly_set_free(set, NULL);
1015
1016 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/descendant-or-self::node()/c", &set));
1017 assert_int_equal(3, set->count);
1018 ly_set_free(set, NULL);
1019
1020 /* following */
1021 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/c/x/following::a", &set));
1022 assert_int_equal(7, set->count);
1023 ly_set_free(set, NULL);
1024
1025 /* following-sibling */
1026 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/c/x/following-sibling::ll", &set));
1027 assert_int_equal(2, set->count);
1028 ly_set_free(set, NULL);
1029
1030 /* parent */
1031 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/child::*/c/parent::l1", &set));
1032 assert_int_equal(2, set->count);
1033 ly_set_free(set, NULL);
1034
1035 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/child::c//..", &set));
1036 assert_int_equal(8, set->count);
1037 ly_set_free(set, NULL);
1038
1039 /* preceding */
1040 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/c/preceding::a", &set));
1041 assert_int_equal(3, set->count);
1042 ly_set_free(set, NULL);
1043
1044 /* preceding-sibling */
1045 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/c/ll/preceding-sibling::node()", &set));
1046 assert_int_equal(2, set->count);
1047 ly_set_free(set, NULL);
1048
1049 /* self */
1050 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/c/self::c/ll/ll/b/self::b", &set));
1051 assert_int_equal(5, set->count);
1052 ly_set_free(set, NULL);
1053
1054 lyd_free_all(tree);
1055}
1056
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001057int
1058main(void)
Michal Vasko14795a42020-05-22 16:44:44 +02001059{
1060 const struct CMUnitTest tests[] = {
aPiecekfff4dca2021-10-07 10:59:53 +02001061 UTEST(test_predicate, setup),
aPiecekadc1e4f2021-10-07 11:15:12 +02001062 UTEST(test_union, setup),
Michal Vaskoe2be5462021-08-04 10:49:42 +02001063 UTEST(test_invalid, setup),
Radek Iša56ca9e42020-09-08 18:42:00 +02001064 UTEST(test_hash, setup),
1065 UTEST(test_toplevel, setup),
1066 UTEST(test_atomize, setup),
1067 UTEST(test_canonize, setup),
Michal Vasko93923692021-05-07 15:28:02 +02001068 UTEST(test_derived_from, setup),
Michal Vaskodb08ce52021-10-06 08:57:49 +02001069 UTEST(test_augment, setup),
aPiecekfba75362021-10-07 12:39:48 +02001070 UTEST(test_variables, setup),
Michal Vasko49fec8e2022-05-24 10:28:33 +02001071 UTEST(test_axes, setup),
Michal Vasko14795a42020-05-22 16:44:44 +02001072 };
1073
1074 return cmocka_run_group_tests(tests, NULL, NULL);
1075}