blob: 74e310f8cad0d5278257ecba1f0dc702a6927dce [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"
Radek Iša56ca9e42020-09-08 18:42:00 +020063 " container c {\n"
64 " leaf x {\n"
65 " type string;\n"
66 " }\n"
67 " list ll {\n"
68 " key \"a\";\n"
69 " leaf a {\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 " leaf b {\n"
78 " type string;\n"
79 " }\n"
80 " }\n"
81 " }\n"
82 " leaf-list ll2 {\n"
83 " type string;\n"
84 " }\n"
85 " }\n"
86 "}";
Michal Vasko14795a42020-05-22 16:44:44 +020087
88static int
89setup(void **state)
90{
Radek Iša56ca9e42020-09-08 18:42:00 +020091 UTEST_SETUP;
Michal Vasko14795a42020-05-22 16:44:44 +020092
Radek Iša56ca9e42020-09-08 18:42:00 +020093 UTEST_ADD_MODULE(schema_a, LYS_IN_YANG, NULL, NULL);
Michal Vasko14795a42020-05-22 16:44:44 +020094
95 return 0;
96}
97
Michal Vasko14795a42020-05-22 16:44:44 +020098static void
aPiecekfff4dca2021-10-07 10:59:53 +020099test_predicate(void **state)
100{
101 const char *data;
102 struct lyd_node *tree;
103 struct ly_set *set;
104
105 data =
106 "<foo2 xmlns=\"urn:tests:a\">50</foo2>";
107 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
108 assert_non_null(tree);
109
110 /* Predicate after number. */
111 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/foo2[4[3 = 3]]", &set));
112 ly_set_free(set, NULL);
113
114 lyd_free_all(tree);
115}
116
117static void
aPiecekadc1e4f2021-10-07 11:15:12 +0200118test_union(void **state)
119{
120 const char *data;
121 struct lyd_node *tree;
122 struct ly_set *set;
123
124 data =
125 "<l1 xmlns=\"urn:tests:a\">\n"
126 " <a>a1</a>\n"
127 " <b>b1</b>\n"
128 " <c>c1</c>\n"
129 "</l1>\n"
130 "<l1 xmlns=\"urn:tests:a\">\n"
131 " <a>a2</a>\n"
132 " <b>b2</b>\n"
133 "</l1>"
134 "<l1 xmlns=\"urn:tests:a\">\n"
135 " <a>a3</a>\n"
136 " <b>b3</b>\n"
137 " <c>c3</c>\n"
138 "</l1>";
139 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
140 assert_non_null(tree);
141
142 /* Predicate for operand. */
143 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/l1[c[../a = 'a1'] | c]/a", &set));
144 ly_set_free(set, NULL);
145
146 lyd_free_all(tree);
147}
148
149static void
Michal Vaskoe2be5462021-08-04 10:49:42 +0200150test_invalid(void **state)
151{
152 const char *data =
153 "<foo2 xmlns=\"urn:tests:a\">50</foo2>";
154 struct lyd_node *tree;
155 struct ly_set *set;
156
157 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
158 assert_non_null(tree);
159
160 assert_int_equal(LY_EVALID, lyd_find_xpath(tree, "/a:foo2[.=]", &set));
161 assert_null(set);
162
163 assert_int_equal(LY_EVALID, lyd_find_xpath(tree, "/a:", &set));
164 assert_null(set);
165
166 lyd_free_all(tree);
167}
168
169static void
Michal Vasko14795a42020-05-22 16:44:44 +0200170test_hash(void **state)
171{
Michal Vasko14795a42020-05-22 16:44:44 +0200172 const char *data =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100173 "<l1 xmlns=\"urn:tests:a\">\n"
174 " <a>a1</a>\n"
175 " <b>b1</b>\n"
176 " <c>c1</c>\n"
177 "</l1>\n"
178 "<l1 xmlns=\"urn:tests:a\">\n"
179 " <a>a2</a>\n"
180 " <b>b2</b>\n"
181 "</l1>\n"
182 "<l1 xmlns=\"urn:tests:a\">\n"
183 " <a>a3</a>\n"
184 " <b>b3</b>\n"
185 " <c>c3</c>\n"
186 "</l1>\n"
187 "<foo xmlns=\"urn:tests:a\">foo value</foo>\n"
188 "<c xmlns=\"urn:tests:a\">\n"
189 " <x>val</x>\n"
190 " <ll>\n"
191 " <a>val_a</a>\n"
192 " <ll>\n"
193 " <a>val_a</a>\n"
194 " <b>val</b>\n"
195 " </ll>\n"
196 " <ll>\n"
197 " <a>val_b</a>\n"
198 " </ll>\n"
199 " </ll>\n"
200 " <ll>\n"
201 " <a>val_b</a>\n"
202 " <ll>\n"
203 " <a>val_a</a>\n"
204 " </ll>\n"
205 " <ll>\n"
206 " <a>val_b</a>\n"
207 " <b>val</b>\n"
208 " </ll>\n"
209 " </ll>\n"
210 " <ll>\n"
211 " <a>val_c</a>\n"
212 " <ll>\n"
213 " <a>val_a</a>\n"
214 " </ll>\n"
215 " <ll>\n"
216 " <a>val_b</a>\n"
217 " </ll>\n"
218 " </ll>\n"
219 " <ll2>one</ll2>\n"
220 " <ll2>two</ll2>\n"
221 " <ll2>three</ll2>\n"
222 " <ll2>four</ll2>\n"
223 "</c>";
Michal Vasko14795a42020-05-22 16:44:44 +0200224 struct lyd_node *tree, *node;
225 struct ly_set *set;
Michal Vasko14795a42020-05-22 16:44:44 +0200226
Radek Iša56ca9e42020-09-08 18:42:00 +0200227 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 +0200228 assert_non_null(tree);
229
230 /* top-level, so hash table is not ultimately used but instances can be compared based on hashes */
231 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:l1[a='a3'][b='b3']", &set));
232 assert_int_equal(1, set->count);
233
234 node = set->objs[0];
235 assert_string_equal(node->schema->name, "l1");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200236 node = lyd_child(node);
Michal Vasko14795a42020-05-22 16:44:44 +0200237 assert_string_equal(node->schema->name, "a");
Radek Krejci6d5ba0c2021-04-26 07:49:59 +0200238 assert_string_equal(lyd_get_value(node), "a3");
Michal Vasko14795a42020-05-22 16:44:44 +0200239
240 ly_set_free(set, NULL);
241
242 /* hashes should be used for both searches (well, there are not enough nested ll instances, so technically not true) */
243 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/ll[a='val_b']/ll[a='val_b']", &set));
244 assert_int_equal(1, set->count);
245
246 node = set->objs[0];
247 assert_string_equal(node->schema->name, "ll");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200248 node = lyd_child(node);
Michal Vasko14795a42020-05-22 16:44:44 +0200249 assert_string_equal(node->schema->name, "a");
Radek Krejci6d5ba0c2021-04-26 07:49:59 +0200250 assert_string_equal(lyd_get_value(node), "val_b");
Michal Vasko14795a42020-05-22 16:44:44 +0200251 node = node->next;
252 assert_string_equal(node->schema->name, "b");
253 assert_null(node->next);
254
255 ly_set_free(set, NULL);
256
257 /* hashes are not used */
258 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c//ll[a='val_b']", &set));
259 assert_int_equal(4, set->count);
260
261 ly_set_free(set, NULL);
262
Michal Vasko660cc8f2020-05-25 10:33:19 +0200263 /* hashes used even for leaf-lists */
264 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/ll2[. = 'three']", &set));
265 assert_int_equal(1, set->count);
266
267 node = set->objs[0];
268 assert_string_equal(node->schema->name, "ll2");
Radek Krejci6d5ba0c2021-04-26 07:49:59 +0200269 assert_string_equal(lyd_get_value(node), "three");
Michal Vasko660cc8f2020-05-25 10:33:19 +0200270
271 ly_set_free(set, NULL);
272
Michal Vasko14795a42020-05-22 16:44:44 +0200273 /* not found using hashes */
274 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/ll[a='val_d']", &set));
275 assert_int_equal(0, set->count);
276
277 ly_set_free(set, NULL);
278
279 /* white-spaces are also ok */
280 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/ll[ \na = 'val_c' ]", &set));
281 assert_int_equal(1, set->count);
282
283 ly_set_free(set, NULL);
284
285 lyd_free_all(tree);
Michal Vasko14795a42020-05-22 16:44:44 +0200286}
287
Michal Vasko61ac2f62020-05-25 12:39:51 +0200288static void
289test_toplevel(void **state)
290{
Radek Iša56ca9e42020-09-08 18:42:00 +0200291 const char *schema_b =
292 "module b {\n"
293 " namespace urn:tests:b;\n"
294 " prefix b;\n"
295 " yang-version 1.1;\n"
296 "\n"
297 " list l2 {\n"
298 " key \"a\";\n"
299 " leaf a {\n"
300 " type uint16;\n"
301 " }\n"
302 " leaf b {\n"
303 " type uint16;\n"
304 " }\n"
305 " }\n"
306 "}";
Michal Vasko61ac2f62020-05-25 12:39:51 +0200307 const char *data =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100308 "<l1 xmlns=\"urn:tests:a\">\n"
309 " <a>a1</a>\n"
310 " <b>b1</b>\n"
311 " <c>c1</c>\n"
312 "</l1>\n"
313 "<l1 xmlns=\"urn:tests:a\">\n"
314 " <a>a2</a>\n"
315 " <b>b2</b>\n"
316 "</l1>\n"
317 "<l1 xmlns=\"urn:tests:a\">\n"
318 " <a>a3</a>\n"
319 " <b>b3</b>\n"
320 " <c>c3</c>\n"
321 "</l1>\n"
322 "<foo xmlns=\"urn:tests:a\">foo value</foo>\n"
323 "<l2 xmlns=\"urn:tests:b\">\n"
324 " <a>1</a>\n"
325 " <b>1</b>\n"
326 "</l2>\n"
327 "<l2 xmlns=\"urn:tests:b\">\n"
328 " <a>2</a>\n"
329 " <b>1</b>\n"
330 "</l2>\n"
331 "<l2 xmlns=\"urn:tests:b\">\n"
332 " <a>3</a>\n"
333 " <b>1</b>\n"
334 "</l2>";
Michal Vaskof60e7102020-05-26 10:48:59 +0200335 struct lyd_node *tree;
Michal Vasko61ac2f62020-05-25 12:39:51 +0200336 struct ly_set *set;
Michal Vasko61ac2f62020-05-25 12:39:51 +0200337
Radek Iša56ca9e42020-09-08 18:42:00 +0200338 UTEST_ADD_MODULE(schema_b, LYS_IN_YANG, NULL, NULL);
339
340 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 +0200341 assert_non_null(tree);
342
343 /* all top-level nodes from one module (default container as well) */
344 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:*", &set));
345 assert_int_equal(5, set->count);
346
347 ly_set_free(set, NULL);
348
349 /* all top-level nodes from all modules */
350 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/*", &set));
351 assert_int_equal(8, set->count);
352
353 ly_set_free(set, NULL);
354
355 /* all nodes from one module */
356 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "//a:*", &set));
357 assert_int_equal(13, set->count);
358
359 ly_set_free(set, NULL);
360
361 /* all nodes from all modules */
362 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "//*", &set));
363 assert_int_equal(22, set->count);
364
365 ly_set_free(set, NULL);
366
367 /* all nodes from all modules #2 */
368 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "//.", &set));
369 assert_int_equal(22, set->count);
370
371 ly_set_free(set, NULL);
372
373 lyd_free_all(tree);
Michal Vasko61ac2f62020-05-25 12:39:51 +0200374}
375
Michal Vasko519fd602020-05-26 12:17:39 +0200376static void
377test_atomize(void **state)
378{
Michal Vasko519fd602020-05-26 12:17:39 +0200379 struct ly_set *set;
380 const struct lys_module *mod;
381
Radek Iša56ca9e42020-09-08 18:42:00 +0200382 mod = ly_ctx_get_module_latest(UTEST_LYCTX, "a");
383 assert_non_null(mod);
Michal Vasko519fd602020-05-26 12:17:39 +0200384
385 /* some random paths just making sure the API function works */
Michal Vasko400e9672021-01-11 13:39:17 +0100386 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/a:*", 0, &set));
Michal Vasko93923692021-05-07 15:28:02 +0200387 assert_int_equal(5, set->count);
Michal Vasko519fd602020-05-26 12:17:39 +0200388
389 ly_set_free(set, NULL);
390
391 /* all nodes from all modules (including internal, which can change easily, so check just the test modules) */
Michal Vasko400e9672021-01-11 13:39:17 +0100392 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "//.", 0, &set));
Michal Vasko93923692021-05-07 15:28:02 +0200393 assert_in_range(set->count, 17, UINT32_MAX);
Michal Vasko519fd602020-05-26 12:17:39 +0200394
395 ly_set_free(set, NULL);
396
Michal Vasko400e9672021-01-11 13:39:17 +0100397 assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/a:c/ll[a='val1']/ll[a='val2']/b", 0, &set));
398 assert_int_equal(6, set->count);
Michal Vasko519fd602020-05-26 12:17:39 +0200399
400 ly_set_free(set, NULL);
401}
402
Michal Vasko4c7763f2020-07-27 17:40:37 +0200403static void
404test_canonize(void **state)
405{
Michal Vasko4c7763f2020-07-27 17:40:37 +0200406 const char *data =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100407 "<foo2 xmlns=\"urn:tests:a\">50</foo2>";
Michal Vasko4c7763f2020-07-27 17:40:37 +0200408 struct lyd_node *tree;
409 struct ly_set *set;
410
Radek Iša56ca9e42020-09-08 18:42:00 +0200411 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 +0200412 assert_non_null(tree);
413
414 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:foo2[.='050']", &set));
415 assert_int_equal(1, set->count);
416 ly_set_free(set, NULL);
417
418 /* TODO more use-cases once there are some type plugins that have canonical values */
419
420 lyd_free_all(tree);
Michal Vasko4c7763f2020-07-27 17:40:37 +0200421}
422
Michal Vasko93923692021-05-07 15:28:02 +0200423static void
424test_derived_from(void **state)
425{
426 const char *data =
427 "<foo3 xmlns=\"urn:tests:a\">id_c</foo3>";
428 struct lyd_node *tree;
429 struct ly_set *set;
430
431 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
432 assert_non_null(tree);
433
434 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:foo3[derived-from(., 'a:id_b')]", &set));
435 assert_int_equal(1, set->count);
436 ly_set_free(set, NULL);
437
438 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:foo3[derived-from(., 'a:id_a')]", &set));
439 assert_int_equal(1, set->count);
440 ly_set_free(set, NULL);
441
442 lyd_free_all(tree);
443}
444
Michal Vaskodb08ce52021-10-06 08:57:49 +0200445static void
446test_augment(void **state)
447{
448 const char *schema_b =
449 "module b {\n"
450 " namespace urn:tests:b;\n"
451 " prefix b;\n"
452 " yang-version 1.1;\n"
453 "\n"
454 " import a {\n"
455 " prefix a;\n"
456 " }\n"
457 "\n"
458 " augment /a:c {\n"
459 " leaf a {\n"
460 " type uint16;\n"
461 " }\n"
462 " }\n"
463 "}";
464 const char *data =
465 "<c xmlns=\"urn:tests:a\">\n"
466 " <x>value</x>\n"
467 " <ll>\n"
468 " <a>key</a>\n"
469 " </ll>\n"
470 " <a xmlns=\"urn:tests:b\">25</a>\n"
471 " <ll2>c1</ll2>\n"
472 "</c>";
473 struct lyd_node *tree;
474 struct ly_set *set;
475
476 UTEST_ADD_MODULE(schema_b, LYS_IN_YANG, NULL, NULL);
477
478 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
479 assert_non_null(tree);
480
481 /* get all children ignoring their module */
482 assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:c/*", &set));
483 assert_int_equal(4, set->count);
484
485 ly_set_free(set, NULL);
486
487 lyd_free_all(tree);
488}
489
aPiecekfba75362021-10-07 12:39:48 +0200490static void
491test_variables(void **state)
492{
493 struct lyd_node *tree, *node;
494 struct ly_set *set;
495 const char *data;
496 struct lyxp_var *vars = NULL;
497
498#define LOCAL_SETUP(DATA, TREE) \
499 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, DATA, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &TREE)); \
500 assert_non_null(TREE);
501
502#define SET_NODE(NODE, SET, INDEX) \
503 assert_non_null(SET); \
504 assert_true(INDEX < SET->count); \
505 NODE = SET->objs[INDEX];
506
507#define LOCAL_TEARDOWN(SET, TREE, VARS) \
508 ly_set_free(SET, NULL); \
509 lyd_free_all(TREE); \
510 lyxp_vars_free(VARS); \
511 vars = NULL;
512
513 /* Eval variable to number. */
514 data =
515 "<l1 xmlns=\"urn:tests:a\">\n"
516 " <a>a1</a>\n"
517 " <b>b1</b>\n"
518 " <c>c1</c>\n"
519 "</l1>"
520 "<l1 xmlns=\"urn:tests:a\">\n"
521 " <a>a2</a>\n"
522 " <b>b2</b>\n"
523 " <c>c2</c>\n"
524 "</l1>";
525 LOCAL_SETUP(data, tree);
526 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "2"));
527 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var]/a", vars, &set));
528 SET_NODE(node, set, 0);
529 assert_string_equal(lyd_get_value(node), "a2");
530 LOCAL_TEARDOWN(set, tree, vars);
531
532 /* Eval variable to string. */
533 data =
534 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
535 LOCAL_SETUP(data, tree);
536 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "\"mstr\""));
537 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/foo[text() = $var]", vars, &set));
538 SET_NODE(node, set, 0);
539 assert_string_equal(lyd_get_value(node), "mstr");
540 LOCAL_TEARDOWN(set, tree, vars);
541
542 /* Eval variable to set of nodes. */
543 data =
544 "<l1 xmlns=\"urn:tests:a\">\n"
545 " <a>a1</a>\n"
546 " <b>b1</b>\n"
547 "</l1>"
548 "<l1 xmlns=\"urn:tests:a\">\n"
549 " <a>a2</a>\n"
550 " <b>b2</b>\n"
551 " <c>c2</c>\n"
552 "</l1>";
553 LOCAL_SETUP(data, tree);
554 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "c"));
555 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var]/a", vars, &set));
556 SET_NODE(node, set, 0);
557 assert_string_equal(lyd_get_value(node), "a2");
558 LOCAL_TEARDOWN(set, tree, vars);
559
560 /* Variable in union expr. */
561 data =
562 "<l1 xmlns=\"urn:tests:a\">\n"
563 " <a>a1</a>\n"
564 " <b>b1</b>\n"
565 " <c>c1</c>\n"
566 "</l1>"
567 "<l1 xmlns=\"urn:tests:a\">\n"
568 " <a>a2</a>\n"
569 " <b>b2</b>\n"
570 " <c>c2</c>\n"
571 "</l1>"
572 "<l1 xmlns=\"urn:tests:a\">\n"
573 " <a>a3</a>\n"
574 " <b>b3</b>\n"
575 " <c>c3</c>\n"
576 "</l1>";
577 LOCAL_SETUP(data, tree);
578 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "c[../a = 'a3']"));
579 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[c[../a = 'a1'] | $var]/a", vars, &set));
580 SET_NODE(node, set, 0);
581 assert_string_equal(lyd_get_value(node), "a1");
582 SET_NODE(node, set, 1);
583 assert_string_equal(lyd_get_value(node), "a3");
584 assert_int_equal(set->count, 2);
585 LOCAL_TEARDOWN(set, tree, vars);
586
587 /* Predicate after variable. */
588 data =
589 "<l1 xmlns=\"urn:tests:a\">\n"
590 " <a>a1</a>\n"
591 " <b>b1</b>\n"
592 " <c>c1</c>\n"
593 "</l1>"
594 "<l1 xmlns=\"urn:tests:a\">\n"
595 " <a>a2</a>\n"
596 " <b>b2</b>\n"
597 " <c>c2</c>\n"
598 "</l1>";
599 LOCAL_SETUP(data, tree);
600 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "c"));
601 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var[../a = 'a1']]/a", vars, &set));
602 SET_NODE(node, set, 0);
603 assert_string_equal(lyd_get_value(node), "a1");
604 LOCAL_TEARDOWN(set, tree, vars);
605
606 /* Variable in variable. */
607 data =
608 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
609 LOCAL_SETUP(data, tree);
610 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var1", "$var2"));
611 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var2", "\"mstr\""));
612 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/foo[text() = $var]", vars, &set));
613 SET_NODE(node, set, 0);
614 assert_string_equal(lyd_get_value(node), "mstr");
615 LOCAL_TEARDOWN(set, tree, vars);
616
617 /* Compare two variables. */
618 data =
619 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
620 LOCAL_SETUP(data, tree);
621 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var1", "\"str\""));
622 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var2", "\"str\""));
623 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/foo[$var1 = $var2]", vars, &set));
624 SET_NODE(node, set, 0);
625 assert_string_equal(lyd_get_value(node), "mstr");
626 LOCAL_TEARDOWN(set, tree, vars);
627
628 /* Arithmetic operation with variable. */
629 data =
630 "<foo2 xmlns=\"urn:tests:a\">4</foo2>";
631 LOCAL_SETUP(data, tree);
632 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var1", "2"));
633 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/foo2[.= ($var1 * 2)]", vars, &set));
634 SET_NODE(node, set, 0);
635 assert_string_equal(lyd_get_value(node), "4");
636 LOCAL_TEARDOWN(set, tree, vars);
637
638 /* Variable as function parameter. */
639 data =
640 "<l1 xmlns=\"urn:tests:a\">\n"
641 " <a>a1</a>\n"
642 " <b>b1</b>\n"
643 " <c>c1</c>\n"
644 "</l1>"
645 "<l1 xmlns=\"urn:tests:a\">\n"
646 " <a>a2</a>\n"
647 " <b>b2</b>\n"
648 "</l1>";
649 LOCAL_SETUP(data, tree);
650 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "./c"));
651 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[count($var) = 1]/a", vars, &set));
652 SET_NODE(node, set, 0);
653 assert_string_equal(lyd_get_value(node), "a1");
654 LOCAL_TEARDOWN(set, tree, vars);
655
656 /* Variable in path expr. */
657 /* NOTE: The variable can only be at the beginning of the expression path. */
658 data =
659 "<l1 xmlns=\"urn:tests:a\">\n"
660 " <a>a1</a>\n"
661 " <b>b1</b>\n"
662 " <c>c1</c>\n"
663 "</l1>"
664 "<l1 xmlns=\"urn:tests:a\">\n"
665 " <a>a2</a>\n"
666 " <b>b2</b>\n"
667 "</l1>";
668 LOCAL_SETUP(data, tree);
669 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "/l1"));
670 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var/a]", vars, &set));
671 assert_int_equal(set->count, 2);
672 LOCAL_TEARDOWN(set, tree, vars);
673
674 /* Variable as function. */
675 data =
676 "<l1 xmlns=\"urn:tests:a\">\n"
677 " <a>a1</a>\n"
678 " <b>b1</b>\n"
679 " <c>c1</c>\n"
680 "</l1>"
681 "<l1 xmlns=\"urn:tests:a\">\n"
682 " <a>a2</a>\n"
683 " <b>b2</b>\n"
684 "</l1>";
685 LOCAL_SETUP(data, tree);
686 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "position()"));
687 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var = 2]/a", vars, &set));
688 SET_NODE(node, set, 0);
689 assert_string_equal(lyd_get_value(node), "a2");
690 LOCAL_TEARDOWN(set, tree, vars);
691
692 /* Dynamic change of value. */
693 data =
694 "<l1 xmlns=\"urn:tests:a\">\n"
695 " <a>a1</a>\n"
696 " <b>b1</b>\n"
697 " <c>c1</c>\n"
698 "</l1>"
699 "<l1 xmlns=\"urn:tests:a\">\n"
700 " <a>a2</a>\n"
701 " <b>b2</b>\n"
702 " <c>c2</c>\n"
703 "</l1>";
704 LOCAL_SETUP(data, tree);
705 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "1"));
706 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var]/a", vars, &set));
707 SET_NODE(node, set, 0);
708 assert_string_equal(lyd_get_value(node), "a1");
709 ly_set_free(set, NULL);
710 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "2"));
711 assert_int_equal(LY_SUCCESS, lyd_find_xpath2(tree, "/l1[$var]/a", vars, &set));
712 SET_NODE(node, set, 0);
713 assert_string_equal(lyd_get_value(node), "a2");
714 LOCAL_TEARDOWN(set, tree, vars);
715
716 /* Variable not defined. */
717 data =
718 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
719 LOCAL_SETUP(data, tree);
720 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var1", "\"mstr\""));
721 assert_int_equal(LY_ENOTFOUND, lyd_find_xpath2(tree, "/foo[text() = $var55]", vars, &set));
722 LOCAL_TEARDOWN(set, tree, vars);
723
724 /* Syntax error in value. */
725 data =
726 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
727 LOCAL_SETUP(data, tree);
728 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "\""));
729 assert_int_equal(LY_EVALID, lyd_find_xpath2(tree, "/foo[$var]", vars, &set));
730 LOCAL_TEARDOWN(set, tree, vars);
731
732 /* Prefix is not supported. */
733 data =
734 "<foo xmlns=\"urn:tests:a\">mstr</foo>";
735 LOCAL_SETUP(data, tree);
736 assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "\""));
737 assert_int_equal(LY_EVALID, lyd_find_xpath2(tree, "/foo[$pref:var]", vars, &set));
738 assert_string_equal("Variable with prefix is not supported.", _UC->err_msg);
739 LOCAL_TEARDOWN(set, tree, vars);
740
741#undef LOCAL_SETUP
742#undef LOCAL_TEARDOWN
743}
744
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100745int
746main(void)
Michal Vasko14795a42020-05-22 16:44:44 +0200747{
748 const struct CMUnitTest tests[] = {
aPiecekfff4dca2021-10-07 10:59:53 +0200749 UTEST(test_predicate, setup),
aPiecekadc1e4f2021-10-07 11:15:12 +0200750 UTEST(test_union, setup),
Michal Vaskoe2be5462021-08-04 10:49:42 +0200751 UTEST(test_invalid, setup),
Radek Iša56ca9e42020-09-08 18:42:00 +0200752 UTEST(test_hash, setup),
753 UTEST(test_toplevel, setup),
754 UTEST(test_atomize, setup),
755 UTEST(test_canonize, setup),
Michal Vasko93923692021-05-07 15:28:02 +0200756 UTEST(test_derived_from, setup),
Michal Vaskodb08ce52021-10-06 08:57:49 +0200757 UTEST(test_augment, setup),
aPiecekfba75362021-10-07 12:39:48 +0200758 UTEST(test_variables, setup),
Michal Vasko14795a42020-05-22 16:44:44 +0200759 };
760
761 return cmocka_run_group_tests(tests, NULL, NULL);
762}