1 /*
2 * SysDB - t/unit/core/data_test.c
3 * Copyright (C) 2014 Sebastian 'tokkee' Harl <sh@tokkee.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
28 #if HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include "core/data.h"
33 #include "testutils.h"
35 #include <check.h>
37 static regex_t empty_re;
39 START_TEST(test_data)
40 {
41 sdb_data_t d1, d2;
42 int check;
44 bool bool_values[] = { true, false, false, true };
45 int64_t int_values[] = { 47, 11, 23 };
46 char *string_values[] = { "foo", "bar", "qux" "baz" };
47 size_t i;
49 d2.type = SDB_TYPE_BOOLEAN;
50 d2.data.boolean = true;
51 memset(&d1, 0, sizeof(d1));
52 check = sdb_data_copy(&d1, &d2);
53 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
54 fail_unless(d1.type == d2.type,
55 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
56 d1.type, d2.type);
57 fail_unless(d1.data.boolean == d2.data.boolean,
58 "sdb_data_copy() didn't copy boolean data: got: %d; expected: %d",
59 d1.data.boolean, d2.data.boolean);
61 d2.type = SDB_TYPE_INTEGER;
62 d2.data.integer = 4711;
63 memset(&d1, 0, sizeof(d1));
64 check = sdb_data_copy(&d1, &d2);
65 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
66 fail_unless(d1.type == d2.type,
67 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
68 d1.type, d2.type);
69 fail_unless(d1.data.integer == d2.data.integer,
70 "sdb_data_copy() didn't copy integer data: got: %d; expected: %d",
71 d1.data.integer, d2.data.integer);
73 d2.type = SDB_TYPE_DECIMAL;
74 d2.data.decimal = 47.11;
75 check = sdb_data_copy(&d1, &d2);
76 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
77 fail_unless(d1.type == d2.type,
78 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
79 d1.type, d2.type);
80 fail_unless(d1.data.decimal == d2.data.decimal,
81 "sdb_data_copy() didn't copy decimal data: got: %f; expected: %f",
82 d1.data.decimal, d2.data.decimal);
84 d2.type = SDB_TYPE_STRING;
85 d2.data.string = "some string";
86 check = sdb_data_copy(&d1, &d2);
87 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
88 fail_unless(d1.type == d2.type,
89 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
90 d1.type, d2.type);
91 fail_unless(!strcmp(d1.data.string, d2.data.string),
92 "sdb_data_copy() didn't copy string data: got: %s; expected: %s",
93 d1.data.string, d2.data.string);
95 sdb_data_free_datum(&d1);
96 fail_unless(d1.data.string == NULL,
97 "sdb_data_free_datum() didn't free string data");
99 d1.type = 0;
100 d2.type = SDB_TYPE_STRING;
101 d2.data.string = NULL;
102 check = sdb_data_copy(&d1, &d2);
103 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
104 fail_unless(d1.type == d2.type,
105 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
106 d1.type, d2.type);
107 fail_unless(d1.data.string == d2.data.string,
108 "sdb_data_copy() didn't copy string data: got: %s; expected: %s",
109 d1.data.string, d2.data.string);
111 sdb_data_free_datum(&d1);
112 fail_unless(d1.data.string == NULL,
113 "sdb_data_free_datum() didn't free string data");
115 d2.type = SDB_TYPE_DATETIME;
116 d2.data.datetime = 4711;
117 check = sdb_data_copy(&d1, &d2);
118 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
119 fail_unless(d1.type == d2.type,
120 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
121 d1.type, d2.type);
122 fail_unless(d1.data.datetime == d2.data.datetime,
123 "sdb_data_copy() didn't copy datetime data: got: %d; expected: %d",
124 d1.data.datetime, d2.data.datetime);
126 d2.type = SDB_TYPE_BINARY;
127 d2.data.binary.datum = (unsigned char *)"some string";
128 d2.data.binary.length = strlen((const char *)d2.data.binary.datum);
129 check = sdb_data_copy(&d1, &d2);
130 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
131 fail_unless(d1.type == d2.type,
132 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
133 d1.type, d2.type);
134 fail_unless(d1.data.binary.length == d2.data.binary.length,
135 "sdb_data_copy() didn't copy length; got: %d; expected: 5d",
136 d1.data.binary.length, d2.data.binary.length);
137 fail_unless(!memcmp(d1.data.binary.datum, d2.data.binary.datum,
138 d2.data.binary.length),
139 "sdb_data_copy() didn't copy binary data: got: %s; expected: %s",
140 d1.data.binary.datum, d2.data.binary.datum);
142 sdb_data_free_datum(&d1);
143 fail_unless(d1.data.binary.length == 0,
144 "sdb_data_free_datum() didn't reset binary datum length");
145 fail_unless(d1.data.binary.datum == NULL,
146 "sdb_data_free_datum() didn't free binary datum");
148 d1.type = 0;
149 d2.type = SDB_TYPE_BINARY;
150 d2.data.binary.datum = NULL;
151 d2.data.binary.length = 0;
152 check = sdb_data_copy(&d1, &d2);
153 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
154 fail_unless(d1.type == d2.type,
155 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
156 d1.type, d2.type);
157 fail_unless(d1.data.binary.length == d2.data.binary.length,
158 "sdb_data_copy() didn't copy length; got: %d; expected: 5d",
159 d1.data.binary.length, d2.data.binary.length);
160 fail_unless(d1.data.binary.datum == d2.data.binary.datum,
161 "sdb_data_copy() didn't copy binary data: got: %s; expected: %s",
162 d1.data.binary.datum, d2.data.binary.datum);
164 sdb_data_free_datum(&d1);
165 fail_unless(d1.data.binary.length == 0,
166 "sdb_data_free_datum() didn't reset binary datum length");
167 fail_unless(d1.data.binary.datum == NULL,
168 "sdb_data_free_datum() didn't free binary datum");
170 check = sdb_data_parse(".", SDB_TYPE_REGEX, &d2);
171 fail_unless(check == 0,
172 "INTERNAL ERROR: Failed to parse regex '.'");
173 ck_assert(d2.type == SDB_TYPE_REGEX);
174 check = sdb_data_copy(&d1, &d2);
175 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
176 fail_unless(d1.type == d2.type,
177 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
178 d1.type, d2.type);
179 fail_unless(d1.data.re.raw != d2.data.re.raw,
180 "sdb_data_copy() copy string pointer");
181 fail_unless(!strcmp(d1.data.re.raw, d2.data.re.raw),
182 "sdb_data_copy() didn't copy raw regex: got: %s; expected: %s",
183 d1.data.re.raw, d2.data.re.raw);
184 sdb_data_free_datum(&d2);
186 sdb_data_free_datum(&d1);
187 fail_unless(d1.data.re.raw == NULL,
188 "sdb_data_free_datum() didn't reset raw regex");
190 d2.type = SDB_TYPE_REGEX;
191 d2.data.re.raw = NULL;
192 check = sdb_data_copy(&d1, &d2);
193 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
194 fail_unless(d1.type == d2.type,
195 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
196 d1.type, d2.type);
198 d2.type = SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN;
199 d2.data.array.length = SDB_STATIC_ARRAY_LEN(bool_values);
200 d2.data.array.values = bool_values;
201 check = sdb_data_copy(&d1, &d2);
202 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
203 fail_unless(d1.type == d2.type,
204 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
205 d1.type, d2.type);
206 fail_unless(d1.data.array.values != d2.data.array.values,
207 "sdb_data_copy() didn't copy values: got: %p; expected: %p",
208 d1.data.array.values, d2.data.array.values);
209 for (i = 0; i < SDB_STATIC_ARRAY_LEN(bool_values); ++i) {
210 bool *b1 = d1.data.array.values;
211 bool *b2 = d2.data.array.values;
212 fail_unless(b1[i] == b2[i],
213 "sdb_data_copy() modified boolean value %d: "
214 "got: %d; expected: %d", i, b1[i], b2[i]);
215 }
216 sdb_data_free_datum(&d1);
218 d2.type = SDB_TYPE_ARRAY | SDB_TYPE_INTEGER;
219 d2.data.array.length = SDB_STATIC_ARRAY_LEN(int_values);
220 d2.data.array.values = int_values;
221 check = sdb_data_copy(&d1, &d2);
222 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
223 fail_unless(d1.type == d2.type,
224 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
225 d1.type, d2.type);
226 fail_unless(d1.data.array.values != d2.data.array.values,
227 "sdb_data_copy() didn't copy values: got: %p; expected: %p",
228 d1.data.array.values, d2.data.array.values);
229 for (i = 0; i < SDB_STATIC_ARRAY_LEN(int_values); ++i) {
230 int *i1 = d1.data.array.values;
231 int *i2 = d2.data.array.values;
232 fail_unless(i1[i] == i2[i],
233 "sdb_data_copy() modified integer value %d: "
234 "got: %d; expected: %d", i, i1[i], i2[i]);
235 }
236 sdb_data_free_datum(&d1);
238 d2.type = SDB_TYPE_ARRAY | SDB_TYPE_STRING;
239 d2.data.array.length = SDB_STATIC_ARRAY_LEN(string_values);
240 d2.data.array.values = string_values;
241 check = sdb_data_copy(&d1, &d2);
242 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
243 fail_unless(d1.type == d2.type,
244 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
245 d1.type, d2.type);
246 fail_unless(d1.data.array.values != d2.data.array.values,
247 "sdb_data_copy() didn't copy values: got: %p; expected: %p",
248 d1.data.array.values, d2.data.array.values);
249 for (i = 0; i < SDB_STATIC_ARRAY_LEN(string_values); ++i) {
250 char **s1 = d1.data.array.values;
251 char **s2 = d2.data.array.values;
252 fail_unless(s1[i] != s2[i],
253 "sdb_data_copy() didn't copy string value %d", i);
254 fail_unless(!strcmp(s1[i], s2[i]),
255 "sdb_data_copy() modified string value %d: "
256 "got: %s; expected: %s", i, s1[i], s2[i]);
257 }
258 sdb_data_free_datum(&d1);
259 }
260 END_TEST
262 START_TEST(test_cmp)
263 {
264 regex_t dummy_re;
265 bool bool_values1[] = { true, false, false, true };
266 bool bool_values2[] = { true, false, true, false };
267 int64_t int_values1[] = { 1, 2, 3 };
268 int64_t int_values2[] = { 1, 3, 2 };
269 double dec_values1[] = { 12.34, 47.11 };
270 double dec_values2[] = { 47.11, 12.34 };
271 char *string_values1[] = { "a", "b", "c" };
272 char *string_values2[] = { "a", "c", "b" };
273 sdb_time_t dt_values1[] = { 4711, 1234567890123456789L };
274 sdb_time_t dt_values2[] = { 1234567890123456789L, 4711 };
275 struct {
276 size_t length;
277 unsigned char *datum;
278 } bin_values1[] = {
279 { 3, (unsigned char *)"\x1\x2\x3" },
280 { 4, (unsigned char *)"\x42\x0\xa\x1b" },
281 };
282 struct {
283 size_t length;
284 unsigned char *datum;
285 } bin_values2[] = {
286 { 4, (unsigned char *)"\x42\x0\xa\x1b" },
287 { 3, (unsigned char *)"\x1\x2\x3" },
288 };
289 struct {
290 char *raw;
291 regex_t regex;
292 } re_values1[] = {
293 { "dummy regex A", dummy_re },
294 };
295 struct {
296 char *raw;
297 regex_t regex;
298 } re_values2[] = {
299 { "dummy regex B", dummy_re },
300 };
302 struct {
303 sdb_data_t d1;
304 sdb_data_t d2;
305 int expected;
306 } golden_data[] = {
307 {
308 { SDB_TYPE_BOOLEAN, { .boolean = false } },
309 { SDB_TYPE_BOOLEAN, { .boolean = true } },
310 -1,
311 },
312 {
313 { SDB_TYPE_BOOLEAN, { .boolean = true } },
314 { SDB_TYPE_BOOLEAN, { .boolean = true } },
315 0,
316 },
317 {
318 { SDB_TYPE_BOOLEAN, { .boolean = true } },
319 { SDB_TYPE_BOOLEAN, { .boolean = false } },
320 1,
321 },
322 {
323 { SDB_TYPE_INTEGER, { .integer = 47 } },
324 { SDB_TYPE_INTEGER, { .integer = 4711 } },
325 -1,
326 },
327 {
328 { SDB_TYPE_INTEGER, { .integer = 4711 } },
329 { SDB_TYPE_INTEGER, { .integer = 4711 } },
330 0,
331 },
332 {
333 { SDB_TYPE_INTEGER, { .integer = 4711 } },
334 { SDB_TYPE_INTEGER, { .integer = 47 } },
335 1,
336 },
337 {
338 { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
339 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
340 -1,
341 },
342 {
343 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
344 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
345 0,
346 },
347 {
348 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
349 { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
350 1,
351 },
352 {
353 { SDB_TYPE_STRING, { .string = NULL } },
354 { SDB_TYPE_STRING, { .string = "" } },
355 -1,
356 },
357 {
358 { SDB_TYPE_STRING, { .string = NULL } },
359 { SDB_TYPE_STRING, { .string = NULL } },
360 0,
361 },
362 {
363 { SDB_TYPE_STRING, { .string = "" } },
364 { SDB_TYPE_STRING, { .string = NULL } },
365 1,
366 },
367 {
368 { SDB_TYPE_STRING, { .string = "a" } },
369 { SDB_TYPE_STRING, { .string = "b" } },
370 -1,
371 },
372 {
373 { SDB_TYPE_STRING, { .string = "a" } },
374 { SDB_TYPE_STRING, { .string = "ab" } },
375 -1,
376 },
377 {
378 { SDB_TYPE_STRING, { .string = "a" } },
379 { SDB_TYPE_STRING, { .string = "a" } },
380 0,
381 },
382 {
383 { SDB_TYPE_STRING, { .string = "b" } },
384 { SDB_TYPE_STRING, { .string = "a" } },
385 1,
386 },
387 {
388 { SDB_TYPE_STRING, { .string = "ab" } },
389 { SDB_TYPE_STRING, { .string = "a" } },
390 1,
391 },
392 {
393 { SDB_TYPE_DATETIME, { .datetime = 471147114711471000 } },
394 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
395 -1,
396 },
397 {
398 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
399 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
400 0,
401 },
402 {
403 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
404 { SDB_TYPE_DATETIME, { .datetime = 471147114711471000 } },
405 1,
406 },
407 {
408 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
409 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
410 -1,
411 },
412 {
413 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
414 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
415 0,
416 },
417 {
418 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
419 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
420 1,
421 },
422 {
423 {
424 SDB_TYPE_BINARY,
425 { .binary = { 3, (unsigned char *)"a\0a" } },
426 },
427 {
428 SDB_TYPE_BINARY,
429 { .binary = { 3, (unsigned char *)"a\0b" } },
430 },
431 -1,
432 },
433 {
434 {
435 SDB_TYPE_BINARY,
436 { .binary = { 1, (unsigned char *)"a" } },
437 },
438 {
439 SDB_TYPE_BINARY,
440 { .binary = { 3, (unsigned char *)"a\0\0" } },
441 },
442 -1,
443 },
444 {
445 {
446 SDB_TYPE_BINARY,
447 { .binary = { 3, (unsigned char *)"a\0a" } },
448 },
449 {
450 SDB_TYPE_BINARY,
451 { .binary = { 3, (unsigned char *)"a\0a" } },
452 },
453 0,
454 },
455 {
456 {
457 SDB_TYPE_BINARY,
458 { .binary = { 3, (unsigned char *)"a\0b" } },
459 },
460 {
461 SDB_TYPE_BINARY,
462 { .binary = { 3, (unsigned char *)"a\0a" } },
463 },
464 1,
465 },
466 {
467 {
468 SDB_TYPE_BINARY,
469 { .binary = { 3, (unsigned char *)"a\0\0" } },
470 },
471 {
472 SDB_TYPE_BINARY,
473 { .binary = { 1, (unsigned char *)"a" } },
474 },
475 1,
476 },
477 {
478 { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
479 { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
480 0,
481 },
482 {
483 { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
484 { SDB_TYPE_REGEX, { .re = { "b", empty_re } } },
485 -1,
486 },
487 {
488 { SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN, { .array = { 0, NULL } } },
489 { SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN, { .array = { 0, NULL } } },
490 0,
491 },
492 {
493 { SDB_TYPE_REGEX, { .re = { "b", empty_re } } },
494 { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
495 1,
496 },
497 {
498 { SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN, { .array = { 0, NULL } } },
499 {
500 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
501 { .array = { SDB_STATIC_ARRAY_LEN(bool_values1), bool_values1 } },
502 },
503 -1,
504 },
505 {
506 {
507 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
508 { .array = { SDB_STATIC_ARRAY_LEN(bool_values1), bool_values1 } },
509 },
510 { SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN, { .array = { 0, NULL } } },
511 1,
512 },
513 {
514 {
515 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
516 { .array = { SDB_STATIC_ARRAY_LEN(bool_values1), bool_values1 } },
517 },
518 {
519 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
520 { .array = { SDB_STATIC_ARRAY_LEN(bool_values1), bool_values1 } },
521 },
522 0,
523 },
524 {
525 {
526 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
527 { .array = { SDB_STATIC_ARRAY_LEN(bool_values1), bool_values1 } },
528 },
529 {
530 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
531 { .array = { SDB_STATIC_ARRAY_LEN(bool_values2), bool_values2 } },
532 },
533 -1,
534 },
535 {
536 {
537 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
538 { .array = { SDB_STATIC_ARRAY_LEN(bool_values2), bool_values2 } },
539 },
540 {
541 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
542 { .array = { SDB_STATIC_ARRAY_LEN(bool_values1), bool_values1 } },
543 },
544 1,
545 },
546 {
547 { SDB_TYPE_ARRAY | SDB_TYPE_INTEGER, { .array = { 0, NULL } } },
548 { SDB_TYPE_ARRAY | SDB_TYPE_INTEGER, { .array = { 0, NULL } } },
549 0,
550 },
551 {
552 { SDB_TYPE_ARRAY | SDB_TYPE_INTEGER, { .array = { 0, NULL } } },
553 {
554 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
555 { .array = { SDB_STATIC_ARRAY_LEN(int_values1), int_values1 } },
556 },
557 -1,
558 },
559 {
560 {
561 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
562 { .array = { SDB_STATIC_ARRAY_LEN(int_values1), int_values1 } },
563 },
564 { SDB_TYPE_ARRAY | SDB_TYPE_INTEGER, { .array = { 0, NULL } } },
565 1,
566 },
567 {
568 {
569 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
570 { .array = { SDB_STATIC_ARRAY_LEN(int_values1), int_values1 } },
571 },
572 {
573 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
574 { .array = { SDB_STATIC_ARRAY_LEN(int_values1), int_values1 } },
575 },
576 0,
577 },
578 {
579 {
580 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
581 { .array = { SDB_STATIC_ARRAY_LEN(int_values1), int_values1 } },
582 },
583 {
584 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
585 { .array = { SDB_STATIC_ARRAY_LEN(int_values2), int_values2 } },
586 },
587 -1,
588 },
589 {
590 {
591 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
592 { .array = { SDB_STATIC_ARRAY_LEN(int_values2), int_values2 } },
593 },
594 {
595 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
596 { .array = { SDB_STATIC_ARRAY_LEN(int_values1), int_values1 } },
597 },
598 1,
599 },
600 {
601 {
602 SDB_TYPE_ARRAY | SDB_TYPE_DECIMAL,
603 { .array = { SDB_STATIC_ARRAY_LEN(dec_values1), dec_values1 } },
604 },
605 {
606 SDB_TYPE_ARRAY | SDB_TYPE_DECIMAL,
607 { .array = { SDB_STATIC_ARRAY_LEN(dec_values1), dec_values1 } },
608 },
609 0,
610 },
611 {
612 {
613 SDB_TYPE_ARRAY | SDB_TYPE_DECIMAL,
614 { .array = { SDB_STATIC_ARRAY_LEN(dec_values1), dec_values1 } },
615 },
616 {
617 SDB_TYPE_ARRAY | SDB_TYPE_DECIMAL,
618 { .array = { SDB_STATIC_ARRAY_LEN(dec_values2), dec_values2 } },
619 },
620 -1,
621 },
622 {
623 {
624 SDB_TYPE_ARRAY | SDB_TYPE_DECIMAL,
625 { .array = { SDB_STATIC_ARRAY_LEN(dec_values2), dec_values2 } },
626 },
627 {
628 SDB_TYPE_ARRAY | SDB_TYPE_DECIMAL,
629 { .array = { SDB_STATIC_ARRAY_LEN(dec_values1), dec_values1 } },
630 },
631 1,
632 },
633 {
634 { SDB_TYPE_ARRAY | SDB_TYPE_STRING, { .array = { 0, NULL } } },
635 { SDB_TYPE_ARRAY | SDB_TYPE_STRING, { .array = { 0, NULL } } },
636 0,
637 },
638 {
639 { SDB_TYPE_ARRAY | SDB_TYPE_STRING, { .array = { 0, NULL } } },
640 {
641 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
642 { .array = { SDB_STATIC_ARRAY_LEN(string_values1), string_values1 } },
643 },
644 -1,
645 },
646 {
647 {
648 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
649 { .array = { SDB_STATIC_ARRAY_LEN(string_values1), string_values1 } },
650 },
651 { SDB_TYPE_ARRAY | SDB_TYPE_STRING, { .array = { 0, NULL } } },
652 1,
653 },
654 {
655 {
656 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
657 { .array = { SDB_STATIC_ARRAY_LEN(string_values1), string_values1 } },
658 },
659 {
660 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
661 { .array = { SDB_STATIC_ARRAY_LEN(string_values1), string_values1 } },
662 },
663 0,
664 },
665 {
666 {
667 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
668 { .array = { SDB_STATIC_ARRAY_LEN(string_values1), string_values1 } },
669 },
670 {
671 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
672 { .array = { SDB_STATIC_ARRAY_LEN(string_values2), string_values2 } },
673 },
674 -1,
675 },
676 {
677 {
678 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
679 { .array = { SDB_STATIC_ARRAY_LEN(string_values2), string_values2 } },
680 },
681 {
682 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
683 { .array = { SDB_STATIC_ARRAY_LEN(string_values1), string_values1 } },
684 },
685 1,
686 },
687 {
688 {
689 SDB_TYPE_ARRAY | SDB_TYPE_DATETIME,
690 { .array = { SDB_STATIC_ARRAY_LEN(dt_values1), dt_values1 } },
691 },
692 {
693 SDB_TYPE_ARRAY | SDB_TYPE_DATETIME,
694 { .array = { SDB_STATIC_ARRAY_LEN(dt_values1), dt_values1 } },
695 },
696 0,
697 },
698 {
699 {
700 SDB_TYPE_ARRAY | SDB_TYPE_DATETIME,
701 { .array = { SDB_STATIC_ARRAY_LEN(dt_values1), dt_values1 } },
702 },
703 {
704 SDB_TYPE_ARRAY | SDB_TYPE_DATETIME,
705 { .array = { SDB_STATIC_ARRAY_LEN(dt_values2), dt_values2 } },
706 },
707 -1,
708 },
709 {
710 {
711 SDB_TYPE_ARRAY | SDB_TYPE_DATETIME,
712 { .array = { SDB_STATIC_ARRAY_LEN(dt_values2), dt_values2 } },
713 },
714 {
715 SDB_TYPE_ARRAY | SDB_TYPE_DATETIME,
716 { .array = { SDB_STATIC_ARRAY_LEN(dt_values1), dt_values1 } },
717 },
718 1,
719 },
720 {
721 {
722 SDB_TYPE_ARRAY | SDB_TYPE_BINARY,
723 { .array = { SDB_STATIC_ARRAY_LEN(bin_values1), bin_values1 } },
724 },
725 {
726 SDB_TYPE_ARRAY | SDB_TYPE_BINARY,
727 { .array = { SDB_STATIC_ARRAY_LEN(bin_values1), bin_values1 } },
728 },
729 0,
730 },
731 {
732 {
733 SDB_TYPE_ARRAY | SDB_TYPE_BINARY,
734 { .array = { SDB_STATIC_ARRAY_LEN(bin_values1), bin_values1 } },
735 },
736 {
737 SDB_TYPE_ARRAY | SDB_TYPE_BINARY,
738 { .array = { SDB_STATIC_ARRAY_LEN(bin_values2), bin_values2 } },
739 },
740 -1,
741 },
742 {
743 {
744 SDB_TYPE_ARRAY | SDB_TYPE_BINARY,
745 { .array = { SDB_STATIC_ARRAY_LEN(bin_values2), bin_values2 } },
746 },
747 {
748 SDB_TYPE_ARRAY | SDB_TYPE_BINARY,
749 { .array = { SDB_STATIC_ARRAY_LEN(bin_values1), bin_values1 } },
750 },
751 1,
752 },
753 {
754 {
755 SDB_TYPE_ARRAY | SDB_TYPE_REGEX,
756 { .array = { SDB_STATIC_ARRAY_LEN(re_values1), re_values1 } },
757 },
758 {
759 SDB_TYPE_ARRAY | SDB_TYPE_REGEX,
760 { .array = { SDB_STATIC_ARRAY_LEN(re_values1), re_values1 } },
761 },
762 0,
763 },
764 {
765 {
766 SDB_TYPE_ARRAY | SDB_TYPE_REGEX,
767 { .array = { SDB_STATIC_ARRAY_LEN(re_values1), re_values1 } },
768 },
769 {
770 SDB_TYPE_ARRAY | SDB_TYPE_REGEX,
771 { .array = { SDB_STATIC_ARRAY_LEN(re_values2), re_values2 } },
772 },
773 -1,
774 },
775 {
776 {
777 SDB_TYPE_ARRAY | SDB_TYPE_REGEX,
778 { .array = { SDB_STATIC_ARRAY_LEN(re_values2), re_values2 } },
779 },
780 {
781 SDB_TYPE_ARRAY | SDB_TYPE_REGEX,
782 { .array = { SDB_STATIC_ARRAY_LEN(re_values1), re_values1 } },
783 },
784 1,
785 },
786 };
788 size_t i;
790 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
791 int check = sdb_data_cmp(&golden_data[i].d1, &golden_data[i].d2);
792 check = check < 0 ? -1 : check > 0 ? 1 : 0;
793 if (check != golden_data[i].expected) {
794 char d1_str[64] = "", d2_str[64] = "";
795 sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
796 SDB_DOUBLE_QUOTED);
797 sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
798 SDB_DOUBLE_QUOTED);
799 fail("sdb_data_cmp(%s, %s) = %d; expected: %d",
800 d1_str, d2_str, check, golden_data[i].expected);
801 }
802 }
803 }
804 END_TEST
806 START_TEST(test_strcmp)
807 {
808 struct {
809 sdb_data_t d1;
810 sdb_data_t d2;
811 int expected;
812 } golden_data[] = {
813 /* same data as for the sdb_data_cmp test; in case the types match,
814 * both functions should behave the same (except for some loss in
815 * precision, e.g. when formatting datetime values) */
816 {
817 { SDB_TYPE_BOOLEAN, { .boolean = false } },
818 { SDB_TYPE_BOOLEAN, { .boolean = true } },
819 -1,
820 },
821 {
822 { SDB_TYPE_BOOLEAN, { .boolean = true } },
823 { SDB_TYPE_BOOLEAN, { .boolean = true } },
824 0,
825 },
826 {
827 { SDB_TYPE_BOOLEAN, { .boolean = true } },
828 { SDB_TYPE_BOOLEAN, { .boolean = false } },
829 1,
830 },
831 {
832 { SDB_TYPE_INTEGER, { .integer = 47 } },
833 { SDB_TYPE_INTEGER, { .integer = 4711 } },
834 -1,
835 },
836 {
837 { SDB_TYPE_INTEGER, { .integer = 4711 } },
838 { SDB_TYPE_INTEGER, { .integer = 4711 } },
839 0,
840 },
841 {
842 { SDB_TYPE_INTEGER, { .integer = 4711 } },
843 { SDB_TYPE_INTEGER, { .integer = 47 } },
844 1,
845 },
846 {
847 { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
848 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
849 -1,
850 },
851 {
852 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
853 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
854 0,
855 },
856 {
857 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
858 { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
859 1,
860 },
861 {
862 { SDB_TYPE_STRING, { .string = NULL } },
863 { SDB_TYPE_STRING, { .string = "" } },
864 -1,
865 },
866 {
867 { SDB_TYPE_STRING, { .string = NULL } },
868 { SDB_TYPE_STRING, { .string = NULL } },
869 0,
870 },
871 {
872 { SDB_TYPE_STRING, { .string = "" } },
873 { SDB_TYPE_STRING, { .string = NULL } },
874 1,
875 },
876 {
877 { SDB_TYPE_STRING, { .string = "a" } },
878 { SDB_TYPE_STRING, { .string = "b" } },
879 -1,
880 },
881 {
882 { SDB_TYPE_STRING, { .string = "a" } },
883 { SDB_TYPE_STRING, { .string = "ab" } },
884 -1,
885 },
886 {
887 { SDB_TYPE_STRING, { .string = "a" } },
888 { SDB_TYPE_STRING, { .string = "a" } },
889 0,
890 },
891 {
892 { SDB_TYPE_STRING, { .string = "b" } },
893 { SDB_TYPE_STRING, { .string = "a" } },
894 1,
895 },
896 {
897 { SDB_TYPE_STRING, { .string = "ab" } },
898 { SDB_TYPE_STRING, { .string = "a" } },
899 1,
900 },
901 {
902 { SDB_TYPE_DATETIME, { .datetime = 471047114711471100 } },
903 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
904 -1,
905 },
906 {
907 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
908 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
909 0,
910 },
911 {
912 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
913 { SDB_TYPE_DATETIME, { .datetime = 471047114711471100 } },
914 1,
915 },
916 {
917 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
918 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
919 -1,
920 },
921 {
922 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
923 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
924 0,
925 },
926 {
927 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
928 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
929 1,
930 },
931 {
932 {
933 SDB_TYPE_BINARY,
934 { .binary = { 3, (unsigned char *)"a\0a" } },
935 },
936 {
937 SDB_TYPE_BINARY,
938 { .binary = { 3, (unsigned char *)"a\0b" } },
939 },
940 -1,
941 },
942 {
943 {
944 SDB_TYPE_BINARY,
945 { .binary = { 1, (unsigned char *)"a" } },
946 },
947 {
948 SDB_TYPE_BINARY,
949 { .binary = { 3, (unsigned char *)"a\0\0" } },
950 },
951 -1,
952 },
953 {
954 {
955 SDB_TYPE_BINARY,
956 { .binary = { 3, (unsigned char *)"a\0a" } },
957 },
958 {
959 SDB_TYPE_BINARY,
960 { .binary = { 3, (unsigned char *)"a\0a" } },
961 },
962 0,
963 },
964 {
965 {
966 SDB_TYPE_BINARY,
967 { .binary = { 3, (unsigned char *)"a\0b" } },
968 },
969 {
970 SDB_TYPE_BINARY,
971 { .binary = { 3, (unsigned char *)"a\0a" } },
972 },
973 1,
974 },
975 {
976 {
977 SDB_TYPE_BINARY,
978 { .binary = { 3, (unsigned char *)"a\0\0" } },
979 },
980 {
981 SDB_TYPE_BINARY,
982 { .binary = { 1, (unsigned char *)"a" } },
983 },
984 1,
985 },
986 {
987 { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
988 { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
989 0,
990 },
991 {
992 { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
993 { SDB_TYPE_REGEX, { .re = { "b", empty_re } } },
994 -1,
995 },
996 {
997 { SDB_TYPE_REGEX, { .re = { "b", empty_re } } },
998 { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
999 1,
1000 },
1001 /* type mismatches */
1002 {
1003 { SDB_TYPE_BOOLEAN, { .boolean = true } },
1004 { SDB_TYPE_INTEGER, { .integer = 1 } },
1005 1,
1006 },
1007 {
1008 { SDB_TYPE_BOOLEAN, { .boolean = true } },
1009 { SDB_TYPE_STRING, { .string = "true" } },
1010 0,
1011 },
1012 {
1013 { SDB_TYPE_INTEGER, { .integer = 123 } },
1014 { SDB_TYPE_STRING, { .string = "123" } },
1015 0,
1016 },
1017 {
1018 { SDB_TYPE_INTEGER, { .integer = 120 } },
1019 { SDB_TYPE_STRING, { .string = "123" } },
1020 -1,
1021 },
1022 {
1023 { SDB_TYPE_STRING, { .string = "123" } },
1024 { SDB_TYPE_INTEGER, { .integer = 120 } },
1025 1,
1026 },
1027 {
1028 { SDB_TYPE_STRING, { .string = "12.3" } },
1029 { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
1030 0,
1031 },
1032 {
1033 { SDB_TYPE_STRING, { .string = "12.0" } },
1034 { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
1035 -1,
1036 },
1037 {
1038 { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
1039 { SDB_TYPE_STRING, { .string = "12.0" } },
1040 1,
1041 },
1042 {
1043 { SDB_TYPE_REGEX, { .re = { "regex", empty_re } } },
1044 { SDB_TYPE_STRING, { .string = "/regex/" } },
1045 0,
1046 },
1047 /* TODO: add support for arrays */
1048 };
1050 size_t i;
1052 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
1053 int check = sdb_data_strcmp(&golden_data[i].d1, &golden_data[i].d2);
1054 check = check < 0 ? -1 : check > 0 ? 1 : 0;
1055 if (check != golden_data[i].expected) {
1056 char d1_str[64] = "", d2_str[64] = "";
1057 sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
1058 SDB_DOUBLE_QUOTED);
1059 sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
1060 SDB_DOUBLE_QUOTED);
1061 fail("sdb_data_strcmp(%s, %s) = %d; expected: %d",
1062 d1_str, d2_str, check, golden_data[i].expected);
1063 }
1064 }
1065 }
1066 END_TEST
1068 START_TEST(test_inarray)
1069 {
1070 bool bool_values[] = { true, false, true };
1071 bool bool_values2[] = { false, true };
1072 bool bool_values3[] = { true, true, true };
1073 bool bool_values4[] = { false, false };
1074 int64_t int_values[] = { 47, 11, 64 };
1075 int64_t int_values2[] = { 64, 11 };
1076 int64_t int_values3[] = { 47, 11, 42 };
1077 double dec_values[] = { 12.3, 47.11, 64.0 };
1078 double dec_values2[] = { 12.3, 47.11 };
1079 double dec_values3[] = { 2.3, 47.11 };
1080 char *string_values[] = { "foo", "bar", "qux", "baz" };
1081 char *string_values2[] = { "qux", "bar" };
1082 char *string_values3[] = { "foo", "bar", "qux", "baz", "bay" };
1084 sdb_data_t bool_array = {
1085 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
1086 { .array = { SDB_STATIC_ARRAY_LEN(bool_values), bool_values } }
1087 };
1088 sdb_data_t bool_array2 = {
1089 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
1090 { .array = { SDB_STATIC_ARRAY_LEN(bool_values2), bool_values2 } }
1091 };
1092 sdb_data_t bool_array3 = {
1093 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
1094 { .array = { SDB_STATIC_ARRAY_LEN(bool_values3), bool_values3 } }
1095 };
1096 sdb_data_t bool_array4 = {
1097 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
1098 { .array = { SDB_STATIC_ARRAY_LEN(bool_values4), bool_values4 } }
1099 };
1100 sdb_data_t int_array = {
1101 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
1102 { .array = { SDB_STATIC_ARRAY_LEN(int_values), int_values } }
1103 };
1104 sdb_data_t int_array2 = {
1105 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
1106 { .array = { SDB_STATIC_ARRAY_LEN(int_values2), int_values2 } }
1107 };
1108 sdb_data_t int_array3 = {
1109 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
1110 { .array = { SDB_STATIC_ARRAY_LEN(int_values3), int_values3 } }
1111 };
1112 sdb_data_t dec_array = {
1113 SDB_TYPE_ARRAY | SDB_TYPE_DECIMAL,
1114 { .array = { SDB_STATIC_ARRAY_LEN(dec_values), dec_values } }
1115 };
1116 sdb_data_t dec_array2 = {
1117 SDB_TYPE_ARRAY | SDB_TYPE_DECIMAL,
1118 { .array = { SDB_STATIC_ARRAY_LEN(dec_values2), dec_values2 } }
1119 };
1120 sdb_data_t dec_array3 = {
1121 SDB_TYPE_ARRAY | SDB_TYPE_DECIMAL,
1122 { .array = { SDB_STATIC_ARRAY_LEN(dec_values3), dec_values3 } }
1123 };
1124 sdb_data_t string_array = {
1125 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
1126 { .array = { SDB_STATIC_ARRAY_LEN(string_values), string_values } }
1127 };
1128 sdb_data_t string_array2 = {
1129 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
1130 { .array = { SDB_STATIC_ARRAY_LEN(string_values2), string_values2 } }
1131 };
1132 sdb_data_t string_array3 = {
1133 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
1134 { .array = { SDB_STATIC_ARRAY_LEN(string_values3), string_values3 } }
1135 };
1137 struct {
1138 sdb_data_t value;
1139 sdb_data_t array;
1140 _Bool expected;
1141 } golden_data[] = {
1142 { { SDB_TYPE_BOOLEAN, { .boolean = true } }, bool_array, 1 },
1143 { { SDB_TYPE_BOOLEAN, { .boolean = true } }, bool_array4, 0 },
1144 { { SDB_TYPE_BOOLEAN, { .boolean = false } }, bool_array, 1 },
1145 { { SDB_TYPE_INTEGER, { .integer = 47 } }, int_array, 1 },
1146 { { SDB_TYPE_INTEGER, { .integer = 11 } }, int_array, 1 },
1147 { { SDB_TYPE_INTEGER, { .integer = 64 } }, int_array, 1 },
1148 { { SDB_TYPE_INTEGER, { .integer = 65 } }, int_array, 0 },
1149 { { SDB_TYPE_NULL, { .integer = 0 } }, int_array, 0 },
1150 { { SDB_TYPE_DECIMAL, { .decimal = 12.3 } }, dec_array, 1 },
1151 { { SDB_TYPE_DECIMAL, { .decimal = 47.11 } }, dec_array, 1 },
1152 { { SDB_TYPE_DECIMAL, { .decimal = 64.0 } }, dec_array, 1 },
1153 { { SDB_TYPE_DECIMAL, { .decimal = 60.0 } }, dec_array, 0 },
1154 { { SDB_TYPE_INTEGER, { .integer = 64 } }, dec_array, 0 },
1155 { { SDB_TYPE_NULL, { .integer = 0 } }, dec_array, 0 },
1156 { { SDB_TYPE_STRING, { .string = "Foo" } }, string_array, 1 },
1157 { { SDB_TYPE_STRING, { .string = "FOO" } }, string_array, 1 },
1158 { { SDB_TYPE_STRING, { .string = "foo" } }, string_array, 1 },
1159 { { SDB_TYPE_STRING, { .string = "bar" } }, string_array, 1 },
1160 { { SDB_TYPE_STRING, { .string = "qux" } }, string_array, 1 },
1161 { { SDB_TYPE_STRING, { .string = "baz" } }, string_array, 1 },
1162 { { SDB_TYPE_STRING, { .string = "ba" } }, string_array, 0 },
1163 { { SDB_TYPE_STRING, { .string = "abc" } }, string_array, 0 },
1164 { { SDB_TYPE_NULL, { .integer = 0 } }, string_array, 0 },
1165 { bool_array, { SDB_TYPE_BOOLEAN, { .boolean = true } }, 0 },
1166 { int_array, { SDB_TYPE_INTEGER, { .integer = 47 } }, 0 },
1167 { bool_array, bool_array, 1 },
1168 { bool_array2, bool_array, 1 },
1169 { bool_array, bool_array2, 1 },
1170 { bool_array, bool_array3, 0 },
1171 { bool_array, bool_array4, 0 },
1172 { bool_array2, bool_array3, 0 },
1173 { bool_array2, bool_array4, 0 },
1174 { bool_array3, bool_array4, 0 },
1175 { bool_array4, bool_array3, 0 },
1176 { int_array, int_array, 1 },
1177 { int_array2, int_array, 1 },
1178 { int_array3, int_array, 0 },
1179 { dec_array2, int_array, 0 },
1180 { string_array2, int_array, 0 },
1181 { dec_array, dec_array, 1 },
1182 { dec_array2, dec_array, 1 },
1183 { dec_array3, dec_array, 0 },
1184 { int_array2, dec_array, 0 },
1185 { string_array2, dec_array, 0 },
1186 { string_array, string_array, 1 },
1187 { string_array2, string_array, 1 },
1188 { string_array3, string_array, 0 },
1189 { int_array2, string_array, 0 },
1190 { dec_array2, string_array, 0 },
1191 {
1192 { SDB_TYPE_INTEGER | SDB_TYPE_ARRAY, { .array = { 0, NULL } } },
1193 int_array, 1,
1194 },
1195 {
1196 { SDB_TYPE_INTEGER | SDB_TYPE_ARRAY, { .array = { 0, NULL } } },
1197 dec_array, 0,
1198 },
1199 {
1200 { SDB_TYPE_DECIMAL | SDB_TYPE_ARRAY, { .array = { 0, NULL } } },
1201 dec_array, 1,
1202 },
1203 {
1204 { SDB_TYPE_DECIMAL | SDB_TYPE_ARRAY, { .array = { 0, NULL } } },
1205 int_array, 0,
1206 },
1207 {
1208 { SDB_TYPE_STRING | SDB_TYPE_ARRAY, { .array = { 0, NULL } } },
1209 string_array, 1,
1210 },
1211 {
1212 { SDB_TYPE_STRING | SDB_TYPE_ARRAY, { .array = { 0, NULL } } },
1213 dec_array, 0,
1214 },
1215 };
1217 size_t i;
1219 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
1220 char v_str[1024] = "", a_str[1024] = "";
1221 _Bool check;
1223 sdb_data_format(&golden_data[i].value,
1224 v_str, sizeof(v_str), SDB_UNQUOTED);
1225 sdb_data_format(&golden_data[i].array,
1226 a_str, sizeof(a_str), SDB_UNQUOTED);
1228 check = sdb_data_inarray(&golden_data[i].value, &golden_data[i].array);
1229 fail_unless(check == golden_data[i].expected,
1230 "sdb_data_inarray(%s, %s) = %d; expected: %d",
1231 v_str, a_str, check, golden_data[i].expected);
1232 }
1233 }
1234 END_TEST
1236 START_TEST(test_array_get)
1237 {
1238 bool bool_values[] = { true, false, false };
1239 int64_t int_values[] = { 47, 11, 64 };
1240 double dec_values[] = { 12.3, 47.11, 64.0 };
1241 char *string_values[] = { "foo", "bar", "qux", "baz" };
1243 sdb_data_t bool_array = {
1244 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
1245 { .array = { SDB_STATIC_ARRAY_LEN(bool_values), bool_values } }
1246 };
1247 sdb_data_t int_array = {
1248 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
1249 { .array = { SDB_STATIC_ARRAY_LEN(int_values), int_values } }
1250 };
1251 sdb_data_t dec_array = {
1252 SDB_TYPE_ARRAY | SDB_TYPE_DECIMAL,
1253 { .array = { SDB_STATIC_ARRAY_LEN(dec_values), dec_values } }
1254 };
1255 sdb_data_t string_array = {
1256 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
1257 { .array = { SDB_STATIC_ARRAY_LEN(string_values), string_values } }
1258 };
1260 struct {
1261 sdb_data_t array;
1262 size_t i;
1263 sdb_data_t expected;
1264 } golden_data[] = {
1265 { bool_array, 0, { SDB_TYPE_BOOLEAN, { .boolean = true } } },
1266 { bool_array, 1, { SDB_TYPE_BOOLEAN, { .boolean = false } } },
1267 { bool_array, 2, { SDB_TYPE_BOOLEAN, { .boolean = false } } },
1268 { bool_array, 3, { -1, { .integer = 0 } } },
1269 { int_array, 0, { SDB_TYPE_INTEGER, { .integer = 47 } } },
1270 { int_array, 1, { SDB_TYPE_INTEGER, { .integer = 11 } } },
1271 { int_array, 2, { SDB_TYPE_INTEGER, { .integer = 64 } } },
1272 { int_array, 3, { -1, { .integer = 0 } } },
1273 { dec_array, 0, { SDB_TYPE_DECIMAL, { .decimal = 12.3 } } },
1274 { dec_array, 1, { SDB_TYPE_DECIMAL, { .decimal = 47.11 } } },
1275 { dec_array, 2, { SDB_TYPE_DECIMAL, { .decimal = 64.0 } } },
1276 { dec_array, 3, { -1, { .integer = 0 } } },
1277 { string_array, 0, { SDB_TYPE_STRING, { .string = "foo" } } },
1278 { string_array, 1, { SDB_TYPE_STRING, { .string = "bar" } } },
1279 { string_array, 2, { SDB_TYPE_STRING, { .string = "qux" } } },
1280 { string_array, 3, { SDB_TYPE_STRING, { .string = "baz" } } },
1281 { string_array, 4, { -1, { .integer = 0 } } },
1282 { { SDB_TYPE_INTEGER, { .integer = 666 } }, 0, { -1, { .integer = 0 } } },
1283 { { SDB_TYPE_INTEGER, { .integer = 666 } }, 1, { -1, { .integer = 0 } } },
1284 {
1285 { SDB_TYPE_ARRAY | SDB_TYPE_INTEGER, { .array = { 0, NULL } } },
1286 0, { -1, { .integer = 0 } },
1287 },
1288 {
1289 { SDB_TYPE_ARRAY | SDB_TYPE_DECIMAL, { .array = { 0, NULL } } },
1290 0, { -1, { .integer = 0 } },
1291 },
1292 {
1293 { SDB_TYPE_ARRAY | SDB_TYPE_STRING, { .array = { 0, NULL } } },
1294 0, { -1, { .integer = 0 } },
1295 },
1296 };
1298 size_t i;
1300 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
1301 char a_str[1024] = "", v_str[1024] = "", exp_str[1024] = "";
1302 sdb_data_t value = SDB_DATA_INIT;
1303 int check;
1305 sdb_data_format(&golden_data[i].array,
1306 a_str, sizeof(a_str), SDB_UNQUOTED);
1307 sdb_data_format(&golden_data[i].expected,
1308 exp_str, sizeof(exp_str), SDB_UNQUOTED);
1310 check = sdb_data_array_get(&golden_data[i].array,
1311 golden_data[i].i, &value);
1313 sdb_data_format(&value, v_str, sizeof(v_str), SDB_UNQUOTED);
1315 if (golden_data[i].expected.type < 0) {
1316 fail_unless(check < 0,
1317 "sdb_data_array_get(%s, %zu) = %d (%s); expected: <0",
1318 a_str, golden_data[i].i, check, v_str);
1319 continue;
1320 }
1322 fail_unless(check == 0,
1323 "sdb_data_array_get(%s, %zu) = %d; expected: 0",
1324 a_str, golden_data[i].i, check);
1325 fail_unless(! sdb_data_cmp(&value, &golden_data[i].expected),
1326 "sdb_data_array_get(%s, %zu) -> '%s'; expected: '%s'",
1327 a_str, golden_data[i].i, v_str, exp_str);
1328 }
1329 }
1330 END_TEST
1332 START_TEST(test_parse_op)
1333 {
1334 struct {
1335 const char *op;
1336 int id;
1337 } golden_data[] = {
1338 { "+", SDB_DATA_ADD },
1339 { "-", SDB_DATA_SUB },
1340 { "*", SDB_DATA_MUL },
1341 { "/", SDB_DATA_DIV },
1342 { "%", SDB_DATA_MOD },
1343 { "||", SDB_DATA_CONCAT },
1344 { "&&", -1 },
1345 };
1347 size_t i;
1349 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
1350 const char *op;
1351 int id;
1353 id = sdb_data_parse_op(golden_data[i].op);
1354 fail_unless(id == golden_data[i].id,
1355 "sdb_data_parse_op(%s) = %d; expected: %d",
1356 golden_data[i].op, id, golden_data[i].id);
1358 if (id <= 0)
1359 continue;
1361 op = SDB_DATA_OP_TO_STRING(id);
1362 fail_unless(!strcmp(op, golden_data[i].op),
1363 "SDB_DATA_OP_TO_STRING(%d) = '%s'; expected: '%s'",
1364 id, op, golden_data[i].op);
1365 }
1366 }
1367 END_TEST
1369 START_TEST(test_expr_eval)
1370 {
1371 sdb_data_t err = { -1, { .integer = 0 } };
1373 bool bool_values[] = { true, false, true };
1374 bool expected_bool_append[] = { true, false, true, true };
1375 bool expected_bool_prepend[] = { true, true, false, true };
1376 bool expected_bool_concat[] = { true, false, true, true, false, true };
1377 int64_t int_values[] = { 47, 11, 23 };
1378 int64_t expected_int_append[] = { 47, 11, 23, 42 };
1379 int64_t expected_int_prepend[] = { 42, 47, 11, 23 };
1380 int64_t expected_int_concat[] = { 47, 11, 23, 47, 11, 23 };
1381 char *string_values[] = { "foo", "bar", "qux" "baz" };
1382 char *expected_string_append[] = { "foo", "bar", "qux" "baz", "bay" };
1383 char *expected_string_prepend[] = { "bay", "foo", "bar", "qux" "baz" };
1384 char *expected_string_concat[] =
1385 { "foo", "bar", "qux" "baz", "foo", "bar", "qux" "baz" };
1387 struct {
1388 sdb_data_t d1;
1389 sdb_data_t d2;
1390 sdb_data_t expected_add;
1391 sdb_data_t expected_sub;
1392 sdb_data_t expected_mul;
1393 sdb_data_t expected_div;
1394 sdb_data_t expected_mod;
1395 sdb_data_t expected_concat;
1396 } golden_data[] = {
1397 {
1398 { SDB_TYPE_BOOLEAN, { .boolean = true } },
1399 { SDB_TYPE_BOOLEAN, { .boolean = false } },
1400 err,
1401 err,
1402 err,
1403 err,
1404 err,
1405 err,
1406 },
1407 {
1408 { SDB_TYPE_INTEGER, { .integer = 4711 } },
1409 { SDB_TYPE_INTEGER, { .integer = 47 } },
1410 { SDB_TYPE_INTEGER, { .integer = 4758 } },
1411 { SDB_TYPE_INTEGER, { .integer = 4664 } },
1412 { SDB_TYPE_INTEGER, { .integer = 221417 } },
1413 { SDB_TYPE_INTEGER, { .integer = 100 } },
1414 { SDB_TYPE_INTEGER, { .integer = 11 } },
1415 err,
1416 },
1417 {
1418 { SDB_TYPE_DECIMAL, { .decimal = 35.0 } },
1419 { SDB_TYPE_DECIMAL, { .decimal = 17.5 } },
1420 { SDB_TYPE_DECIMAL, { .decimal = 52.5 } },
1421 { SDB_TYPE_DECIMAL, { .decimal = 17.5 } },
1422 { SDB_TYPE_DECIMAL, { .decimal = 612.5 } },
1423 { SDB_TYPE_DECIMAL, { .decimal = 2.0 } },
1424 { SDB_TYPE_DECIMAL, { .decimal = 0.0 } },
1425 err,
1426 },
1427 {
1428 { SDB_TYPE_STRING, { .string = NULL } },
1429 { SDB_TYPE_STRING, { .string = "" } },
1430 SDB_DATA_NULL,
1431 SDB_DATA_NULL,
1432 SDB_DATA_NULL,
1433 SDB_DATA_NULL,
1434 SDB_DATA_NULL,
1435 SDB_DATA_NULL,
1436 },
1437 {
1438 { SDB_TYPE_STRING, { .string = NULL } },
1439 { SDB_TYPE_STRING, { .string = NULL } },
1440 SDB_DATA_NULL,
1441 SDB_DATA_NULL,
1442 SDB_DATA_NULL,
1443 SDB_DATA_NULL,
1444 SDB_DATA_NULL,
1445 SDB_DATA_NULL,
1446 },
1447 {
1448 { SDB_TYPE_STRING, { .string = "" } },
1449 { SDB_TYPE_STRING, { .string = NULL } },
1450 SDB_DATA_NULL,
1451 SDB_DATA_NULL,
1452 SDB_DATA_NULL,
1453 SDB_DATA_NULL,
1454 SDB_DATA_NULL,
1455 SDB_DATA_NULL,
1456 },
1457 {
1458 { SDB_TYPE_STRING, { .string = "a" } },
1459 { SDB_TYPE_STRING, { .string = "b" } },
1460 err,
1461 err,
1462 err,
1463 err,
1464 err,
1465 { SDB_TYPE_STRING, { .string = "ab" } },
1466 },
1467 {
1468 { SDB_TYPE_DATETIME, { .datetime = 47114711 } },
1469 { SDB_TYPE_DATETIME, { .datetime = 4711 } },
1470 { SDB_TYPE_DATETIME, { .datetime = 47119422 } },
1471 { SDB_TYPE_DATETIME, { .datetime = 47110000 } },
1472 { SDB_TYPE_DATETIME, { .datetime = 221957403521 } },
1473 { SDB_TYPE_DATETIME, { .datetime = 10001 } },
1474 { SDB_TYPE_DATETIME, { .datetime = 0 } },
1475 err,
1476 },
1477 {
1478 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
1479 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
1480 SDB_DATA_NULL,
1481 SDB_DATA_NULL,
1482 SDB_DATA_NULL,
1483 SDB_DATA_NULL,
1484 SDB_DATA_NULL,
1485 SDB_DATA_NULL,
1486 },
1487 {
1488 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
1489 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
1490 SDB_DATA_NULL,
1491 SDB_DATA_NULL,
1492 SDB_DATA_NULL,
1493 SDB_DATA_NULL,
1494 SDB_DATA_NULL,
1495 SDB_DATA_NULL,
1496 },
1497 {
1498 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
1499 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
1500 SDB_DATA_NULL,
1501 SDB_DATA_NULL,
1502 SDB_DATA_NULL,
1503 SDB_DATA_NULL,
1504 SDB_DATA_NULL,
1505 SDB_DATA_NULL,
1506 },
1507 {
1508 {
1509 SDB_TYPE_BINARY,
1510 { .binary = { 3, (unsigned char *)"a\0a" } },
1511 },
1512 {
1513 SDB_TYPE_BINARY,
1514 { .binary = { 3, (unsigned char *)"b\0b" } },
1515 },
1516 err,
1517 err,
1518 err,
1519 err,
1520 err,
1521 {
1522 SDB_TYPE_BINARY,
1523 { .binary = { 6, (unsigned char *)"a\0ab\0b" } },
1524 },
1525 },
1526 {
1527 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
1528 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
1529 err,
1530 err,
1531 err,
1532 err,
1533 err,
1534 err,
1535 },
1536 {
1537 {
1538 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
1539 { .array = { SDB_STATIC_ARRAY_LEN(bool_values), bool_values } },
1540 },
1541 {
1542 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
1543 { .array = { SDB_STATIC_ARRAY_LEN(bool_values), bool_values } },
1544 },
1545 err,
1546 err,
1547 err,
1548 err,
1549 err,
1550 {
1551 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
1552 { .array = {
1553 SDB_STATIC_ARRAY_LEN(expected_bool_concat),
1554 expected_bool_concat
1555 } },
1556 },
1557 },
1558 {
1559 {
1560 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
1561 { .array = { SDB_STATIC_ARRAY_LEN(bool_values), bool_values } },
1562 },
1563 { SDB_TYPE_BOOLEAN, { .boolean = true }, },
1564 err,
1565 err,
1566 err,
1567 err,
1568 err,
1569 {
1570 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
1571 { .array = {
1572 SDB_STATIC_ARRAY_LEN(expected_bool_append),
1573 expected_bool_append
1574 } },
1575 },
1576 },
1577 {
1578 { SDB_TYPE_BOOLEAN, { .boolean = true }, },
1579 {
1580 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
1581 { .array = { SDB_STATIC_ARRAY_LEN(bool_values), bool_values } },
1582 },
1583 err,
1584 err,
1585 err,
1586 err,
1587 err,
1588 {
1589 SDB_TYPE_ARRAY | SDB_TYPE_BOOLEAN,
1590 { .array = {
1591 SDB_STATIC_ARRAY_LEN(expected_bool_prepend),
1592 expected_bool_prepend
1593 } },
1594 },
1595 },
1596 {
1597 {
1598 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
1599 { .array = { SDB_STATIC_ARRAY_LEN(int_values), int_values } },
1600 },
1601 {
1602 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
1603 { .array = { SDB_STATIC_ARRAY_LEN(int_values), int_values } },
1604 },
1605 err,
1606 err,
1607 err,
1608 err,
1609 err,
1610 {
1611 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
1612 { .array = {
1613 SDB_STATIC_ARRAY_LEN(expected_int_concat),
1614 expected_int_concat
1615 } },
1616 },
1617 },
1618 {
1619 {
1620 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
1621 { .array = { SDB_STATIC_ARRAY_LEN(int_values), int_values } },
1622 },
1623 { SDB_TYPE_INTEGER, { .integer = 42 }, },
1624 err,
1625 err,
1626 err,
1627 err,
1628 err,
1629 {
1630 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
1631 { .array = {
1632 SDB_STATIC_ARRAY_LEN(expected_int_append),
1633 expected_int_append
1634 } },
1635 },
1636 },
1637 {
1638 { SDB_TYPE_INTEGER, { .integer = 42 }, },
1639 {
1640 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
1641 { .array = { SDB_STATIC_ARRAY_LEN(int_values), int_values } },
1642 },
1643 err,
1644 err,
1645 err,
1646 err,
1647 err,
1648 {
1649 SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
1650 { .array = {
1651 SDB_STATIC_ARRAY_LEN(expected_int_prepend),
1652 expected_int_prepend
1653 } },
1654 },
1655 },
1656 {
1657 {
1658 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
1659 { .array = { SDB_STATIC_ARRAY_LEN(string_values), string_values } },
1660 },
1661 {
1662 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
1663 { .array = { SDB_STATIC_ARRAY_LEN(string_values), string_values } },
1664 },
1665 err,
1666 err,
1667 err,
1668 err,
1669 err,
1670 {
1671 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
1672 { .array = {
1673 SDB_STATIC_ARRAY_LEN(expected_string_concat),
1674 expected_string_concat
1675 } },
1676 },
1677 },
1678 {
1679 {
1680 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
1681 { .array = { SDB_STATIC_ARRAY_LEN(string_values), string_values } },
1682 },
1683 { SDB_TYPE_STRING, { .string = "bay" } },
1684 err,
1685 err,
1686 err,
1687 err,
1688 err,
1689 {
1690 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
1691 { .array = {
1692 SDB_STATIC_ARRAY_LEN(expected_string_append),
1693 expected_string_append
1694 } },
1695 },
1696 },
1697 {
1698 { SDB_TYPE_STRING, { .string = "bay" } },
1699 {
1700 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
1701 { .array = { SDB_STATIC_ARRAY_LEN(string_values), string_values } },
1702 },
1703 err,
1704 err,
1705 err,
1706 err,
1707 err,
1708 {
1709 SDB_TYPE_ARRAY | SDB_TYPE_STRING,
1710 { .array = {
1711 SDB_STATIC_ARRAY_LEN(expected_string_prepend),
1712 expected_string_prepend
1713 } },
1714 },
1715 },
1716 {
1717 { SDB_TYPE_INTEGER | SDB_TYPE_ARRAY, { .array = { 0, NULL } } },
1718 {
1719 SDB_TYPE_INTEGER | SDB_TYPE_ARRAY,
1720 { .array = { SDB_STATIC_ARRAY_LEN(int_values), int_values } },
1721 },
1722 err,
1723 err,
1724 err,
1725 err,
1726 err,
1727 {
1728 SDB_TYPE_INTEGER | SDB_TYPE_ARRAY,
1729 { .array = { SDB_STATIC_ARRAY_LEN(int_values), int_values } },
1730 },
1731 },
1732 {
1733 {
1734 SDB_TYPE_INTEGER | SDB_TYPE_ARRAY,
1735 { .array = { SDB_STATIC_ARRAY_LEN(int_values), int_values } },
1736 },
1737 { SDB_TYPE_INTEGER | SDB_TYPE_ARRAY, { .array = { 0, NULL } } },
1738 err,
1739 err,
1740 err,
1741 err,
1742 err,
1743 {
1744 SDB_TYPE_INTEGER | SDB_TYPE_ARRAY,
1745 { .array = { SDB_STATIC_ARRAY_LEN(int_values), int_values } },
1746 },
1747 },
1748 {
1749 { SDB_TYPE_STRING | SDB_TYPE_ARRAY, { .array = { 0, NULL } } },
1750 {
1751 SDB_TYPE_STRING | SDB_TYPE_ARRAY,
1752 { .array = { SDB_STATIC_ARRAY_LEN(string_values), string_values } },
1753 },
1754 err,
1755 err,
1756 err,
1757 err,
1758 err,
1759 {
1760 SDB_TYPE_STRING | SDB_TYPE_ARRAY,
1761 { .array = { SDB_STATIC_ARRAY_LEN(string_values), string_values } },
1762 },
1763 },
1764 {
1765 {
1766 SDB_TYPE_STRING | SDB_TYPE_ARRAY,
1767 { .array = { SDB_STATIC_ARRAY_LEN(string_values), string_values } },
1768 },
1769 { SDB_TYPE_STRING | SDB_TYPE_ARRAY, { .array = { 0, NULL } } },
1770 err,
1771 err,
1772 err,
1773 err,
1774 err,
1775 {
1776 SDB_TYPE_STRING | SDB_TYPE_ARRAY,
1777 { .array = { SDB_STATIC_ARRAY_LEN(string_values), string_values } },
1778 },
1779 },
1780 {
1781 { SDB_TYPE_NULL, { .integer = 0 } },
1782 { SDB_TYPE_NULL, { .integer = 0 } },
1783 SDB_DATA_NULL,
1784 SDB_DATA_NULL,
1785 SDB_DATA_NULL,
1786 SDB_DATA_NULL,
1787 SDB_DATA_NULL,
1788 SDB_DATA_NULL,
1789 },
1790 {
1791 { SDB_TYPE_NULL, { .integer = 0 } },
1792 { SDB_TYPE_INTEGER, { .integer = 42 } },
1793 SDB_DATA_NULL,
1794 SDB_DATA_NULL,
1795 SDB_DATA_NULL,
1796 SDB_DATA_NULL,
1797 SDB_DATA_NULL,
1798 SDB_DATA_NULL,
1799 },
1800 {
1801 { SDB_TYPE_INTEGER, { .integer = 42 } },
1802 { SDB_TYPE_NULL, { .integer = 0 } },
1803 SDB_DATA_NULL,
1804 SDB_DATA_NULL,
1805 SDB_DATA_NULL,
1806 SDB_DATA_NULL,
1807 SDB_DATA_NULL,
1808 SDB_DATA_NULL,
1809 },
1810 {
1811 { SDB_TYPE_NULL, { .integer = 0 } },
1812 { SDB_TYPE_DECIMAL, { .decimal = 47.11 } },
1813 SDB_DATA_NULL,
1814 SDB_DATA_NULL,
1815 SDB_DATA_NULL,
1816 SDB_DATA_NULL,
1817 SDB_DATA_NULL,
1818 SDB_DATA_NULL,
1819 },
1820 {
1821 { SDB_TYPE_DECIMAL, { .decimal = 47.11 } },
1822 { SDB_TYPE_NULL, { .integer = 0 } },
1823 SDB_DATA_NULL,
1824 SDB_DATA_NULL,
1825 SDB_DATA_NULL,
1826 SDB_DATA_NULL,
1827 SDB_DATA_NULL,
1828 SDB_DATA_NULL,
1829 },
1830 {
1831 { SDB_TYPE_NULL, { .integer = 0 } },
1832 { SDB_TYPE_STRING, { .string = "47.11" } },
1833 SDB_DATA_NULL,
1834 SDB_DATA_NULL,
1835 SDB_DATA_NULL,
1836 SDB_DATA_NULL,
1837 SDB_DATA_NULL,
1838 SDB_DATA_NULL,
1839 },
1840 {
1841 { SDB_TYPE_STRING, { .string = "47.11" } },
1842 { SDB_TYPE_NULL, { .integer = 0 } },
1843 SDB_DATA_NULL,
1844 SDB_DATA_NULL,
1845 SDB_DATA_NULL,
1846 SDB_DATA_NULL,
1847 SDB_DATA_NULL,
1848 SDB_DATA_NULL,
1849 },
1850 {
1851 { SDB_TYPE_NULL, { .integer = 0 } },
1852 { SDB_TYPE_DATETIME, { .datetime = 4711 } },
1853 SDB_DATA_NULL,
1854 SDB_DATA_NULL,
1855 SDB_DATA_NULL,
1856 SDB_DATA_NULL,
1857 SDB_DATA_NULL,
1858 SDB_DATA_NULL,
1859 },
1860 {
1861 { SDB_TYPE_DATETIME, { .datetime = 4711 } },
1862 { SDB_TYPE_NULL, { .integer = 0 } },
1863 SDB_DATA_NULL,
1864 SDB_DATA_NULL,
1865 SDB_DATA_NULL,
1866 SDB_DATA_NULL,
1867 SDB_DATA_NULL,
1868 SDB_DATA_NULL,
1869 },
1870 {
1871 { SDB_TYPE_NULL, { .integer = 0 } },
1872 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
1873 SDB_DATA_NULL,
1874 SDB_DATA_NULL,
1875 SDB_DATA_NULL,
1876 SDB_DATA_NULL,
1877 SDB_DATA_NULL,
1878 SDB_DATA_NULL,
1879 },
1880 {
1881 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
1882 { SDB_TYPE_NULL, { .integer = 0 } },
1883 SDB_DATA_NULL,
1884 SDB_DATA_NULL,
1885 SDB_DATA_NULL,
1886 SDB_DATA_NULL,
1887 SDB_DATA_NULL,
1888 SDB_DATA_NULL,
1889 },
1890 {
1891 { SDB_TYPE_NULL, { .integer = 0 } },
1892 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
1893 SDB_DATA_NULL,
1894 SDB_DATA_NULL,
1895 SDB_DATA_NULL,
1896 SDB_DATA_NULL,
1897 SDB_DATA_NULL,
1898 SDB_DATA_NULL,
1899 },
1900 {
1901 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
1902 { SDB_TYPE_NULL, { .integer = 0 } },
1903 SDB_DATA_NULL,
1904 SDB_DATA_NULL,
1905 SDB_DATA_NULL,
1906 SDB_DATA_NULL,
1907 SDB_DATA_NULL,
1908 SDB_DATA_NULL,
1909 },
1910 /* supported type-mismatches */
1911 {
1912 /* int * datetime */
1913 { SDB_TYPE_INTEGER, { .integer = 20 } },
1914 { SDB_TYPE_DATETIME, { .datetime = 2 } },
1915 err,
1916 err,
1917 { SDB_TYPE_DATETIME, { .datetime = 40 } },
1918 err,
1919 err,
1920 err,
1921 },
1922 {
1923 /* datetime * int, datetime / int, datetime % int */
1924 { SDB_TYPE_DATETIME, { .datetime = 20 } },
1925 { SDB_TYPE_INTEGER, { .integer = 2 } },
1926 err,
1927 err,
1928 { SDB_TYPE_DATETIME, { .datetime = 40 } },
1929 { SDB_TYPE_DATETIME, { .datetime = 10 } },
1930 { SDB_TYPE_DATETIME, { .datetime = 0 } },
1931 err,
1932 },
1933 {
1934 /* float * datetime */
1935 { SDB_TYPE_DECIMAL, { .decimal = 20.0 } },
1936 { SDB_TYPE_DATETIME, { .datetime = 2 } },
1937 err,
1938 err,
1939 { SDB_TYPE_DATETIME, { .datetime = 40 } },
1940 err,
1941 err,
1942 err,
1943 },
1944 {
1945 /* datetime * float, datetime / float, datetime % float */
1946 { SDB_TYPE_DATETIME, { .datetime = 20 } },
1947 { SDB_TYPE_DECIMAL, { .decimal = 2.0 } },
1948 err,
1949 err,
1950 { SDB_TYPE_DATETIME, { .datetime = 40 } },
1951 { SDB_TYPE_DATETIME, { .datetime = 10 } },
1952 { SDB_TYPE_DATETIME, { .datetime = 0 } },
1953 err,
1954 },
1955 /* unsupported type-mismatches */
1956 {
1957 { SDB_TYPE_BOOLEAN, { .boolean = true } },
1958 { SDB_TYPE_DECIMAL, { .decimal = 20.0 } },
1959 err, err, err, err, err, err,
1960 },
1961 {
1962 { SDB_TYPE_BOOLEAN, { .boolean = true } },
1963 { SDB_TYPE_STRING, { .string = "20" } },
1964 err, err, err, err, err, err,
1965 },
1966 {
1967 { SDB_TYPE_BOOLEAN, { .boolean = true } },
1968 { SDB_TYPE_BINARY, { .binary = { 2, (unsigned char *)"20" } } },
1969 err, err, err, err, err, err,
1970 },
1971 {
1972 { SDB_TYPE_BOOLEAN, { .boolean = true } },
1973 { SDB_TYPE_BINARY, { .binary = { 3, (unsigned char *)"20" } } },
1974 err, err, err, err, err, err,
1975 },
1976 {
1977 { SDB_TYPE_BOOLEAN, { .boolean = true } },
1978 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
1979 err, err, err, err, err, err,
1980 },
1981 {
1982 { SDB_TYPE_BOOLEAN, { .boolean = true } },
1983 { SDB_TYPE_REGEX + 1, { .boolean = 0 } },
1984 err, err, err, err, err, err,
1985 },
1986 {
1987 { SDB_TYPE_DECIMAL, { .decimal = 20.0 } },
1988 { SDB_TYPE_BOOLEAN, { .boolean = true } },
1989 err, err, err, err, err, err,
1990 },
1991 {
1992 { SDB_TYPE_INTEGER, { .integer = 20 } },
1993 { SDB_TYPE_DECIMAL, { .decimal = 20.0 } },
1994 err, err, err, err, err, err,
1995 },
1996 {
1997 { SDB_TYPE_INTEGER, { .integer = 20 } },
1998 { SDB_TYPE_STRING, { .string = "20" } },
1999 err, err, err, err, err, err,
2000 },
2001 {
2002 { SDB_TYPE_INTEGER, { .integer = 20 } },
2003 { SDB_TYPE_BINARY, { .binary = { 2, (unsigned char *)"20" } } },
2004 err, err, err, err, err, err,
2005 },
2006 {
2007 { SDB_TYPE_INTEGER, { .integer = 20 } },
2008 { SDB_TYPE_BINARY, { .binary = { 3, (unsigned char *)"20" } } },
2009 err, err, err, err, err, err,
2010 },
2011 {
2012 { SDB_TYPE_INTEGER, { .integer = 20 } },
2013 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
2014 err, err, err, err, err, err,
2015 },
2016 {
2017 { SDB_TYPE_INTEGER, { .integer = 20 } },
2018 { SDB_TYPE_REGEX + 1, { .integer = 0 } },
2019 err, err, err, err, err, err,
2020 },
2021 {
2022 { SDB_TYPE_DECIMAL, { .decimal = 20.0 } },
2023 { SDB_TYPE_INTEGER, { .integer = 20 } },
2024 err, err, err, err, err, err,
2025 },
2026 {
2027 { SDB_TYPE_DECIMAL, { .decimal = 20.0 } },
2028 { SDB_TYPE_STRING, { .string = "20.0" } },
2029 err, err, err, err, err, err,
2030 },
2031 {
2032 { SDB_TYPE_DECIMAL, { .decimal = 20.0 } },
2033 { SDB_TYPE_BINARY, { .binary = { 2, (unsigned char *)"20" } } },
2034 err, err, err, err, err, err,
2035 },
2036 {
2037 { SDB_TYPE_DECIMAL, { .decimal = 20.0 } },
2038 { SDB_TYPE_BINARY, { .binary = { 3, (unsigned char *)"20" } } },
2039 err, err, err, err, err, err,
2040 },
2041 {
2042 { SDB_TYPE_DECIMAL, { .decimal = 20.0 } },
2043 { SDB_TYPE_BINARY, { .binary = { 4, (unsigned char *)"20.0" } } },
2044 err, err, err, err, err, err,
2045 },
2046 {
2047 { SDB_TYPE_DECIMAL, { .decimal = 20.0 } },
2048 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
2049 err, err, err, err, err, err,
2050 },
2051 {
2052 { SDB_TYPE_DECIMAL, { .decimal = 20.0 } },
2053 { SDB_TYPE_REGEX + 1, { .integer = 0 } },
2054 err, err, err, err, err, err,
2055 },
2056 {
2057 { SDB_TYPE_STRING, { .string = "20" } },
2058 { SDB_TYPE_INTEGER, { .integer = 20 } },
2059 err, err, err, err, err, err,
2060 },
2061 {
2062 { SDB_TYPE_STRING, { .string = "20" } },
2063 { SDB_TYPE_DECIMAL, { .decimal = 20.0 } },
2064 err, err, err, err, err, err,
2065 },
2066 {
2067 { SDB_TYPE_STRING, { .string = "20" } },
2068 { SDB_TYPE_DATETIME, { .datetime = 20 } },
2069 err, err, err, err, err, err,
2070 },
2071 {
2072 { SDB_TYPE_STRING, { .string = "20" } },
2073 { SDB_TYPE_BINARY, { .binary = { 2, (unsigned char *)"20" } } },
2074 err, err, err, err, err, err,
2075 },
2076 {
2077 { SDB_TYPE_STRING, { .string = "20" } },
2078 { SDB_TYPE_BINARY, { .binary = { 3, (unsigned char *)"20" } } },
2079 err, err, err, err, err, err,
2080 },
2081 {
2082 { SDB_TYPE_STRING, { .string = "20" } },
2083 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
2084 err, err, err, err, err, err,
2085 },
2086 {
2087 { SDB_TYPE_STRING, { .string = "20" } },
2088 { SDB_TYPE_REGEX + 1, { .integer = 0 } },
2089 err, err, err, err, err, err,
2090 },
2091 {
2092 { SDB_TYPE_DATETIME, { .datetime = 20 } },
2093 { SDB_TYPE_STRING, { .string = "20" } },
2094 err, err, err, err, err, err,
2095 },
2096 {
2097 { SDB_TYPE_DATETIME, { .datetime = 20 } },
2098 { SDB_TYPE_BINARY, { .binary = { 2, (unsigned char *)"20" } } },
2099 err, err, err, err, err, err,
2100 },
2101 {
2102 { SDB_TYPE_DATETIME, { .datetime = 20 } },
2103 { SDB_TYPE_BINARY, { .binary = { 3, (unsigned char *)"20" } } },
2104 err, err, err, err, err, err,
2105 },
2106 {
2107 { SDB_TYPE_DATETIME, { .datetime = 20 } },
2108 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
2109 err, err, err, err, err, err,
2110 },
2111 {
2112 { SDB_TYPE_DATETIME, { .datetime = 20 } },
2113 { SDB_TYPE_REGEX + 1, { .integer = 0 } },
2114 err, err, err, err, err, err,
2115 },
2116 {
2117 { SDB_TYPE_BINARY, { .binary = { 2, (unsigned char *)"20" } } },
2118 { SDB_TYPE_INTEGER, { .integer = 20 } },
2119 err, err, err, err, err, err,
2120 },
2121 {
2122 { SDB_TYPE_BINARY, { .binary = { 3, (unsigned char *)"20" } } },
2123 { SDB_TYPE_INTEGER, { .integer = 20 } },
2124 err, err, err, err, err, err,
2125 },
2126 {
2127 { SDB_TYPE_BINARY, { .binary = { 2, (unsigned char *)"20" } } },
2128 { SDB_TYPE_DECIMAL, { .decimal = 20.0 } },
2129 err, err, err, err, err, err,
2130 },
2131 {
2132 { SDB_TYPE_BINARY, { .binary = { 3, (unsigned char *)"20" } } },
2133 { SDB_TYPE_DECIMAL, { .decimal = 20.0 } },
2134 err, err, err, err, err, err,
2135 },
2136 {
2137 { SDB_TYPE_BINARY, { .binary = { 2, (unsigned char *)"20" } } },
2138 { SDB_TYPE_DATETIME, { .datetime = 20 } },
2139 err, err, err, err, err, err,
2140 },
2141 {
2142 { SDB_TYPE_BINARY, { .binary = { 3, (unsigned char *)"20" } } },
2143 { SDB_TYPE_DATETIME, { .datetime = 20 } },
2144 err, err, err, err, err, err,
2145 },
2146 {
2147 { SDB_TYPE_BINARY, { .binary = { 2, (unsigned char *)"20" } } },
2148 { SDB_TYPE_STRING, { .string = "20" } },
2149 err, err, err, err, err, err,
2150 },
2151 {
2152 { SDB_TYPE_BINARY, { .binary = { 3, (unsigned char *)"20" } } },
2153 { SDB_TYPE_STRING, { .string = "20" } },
2154 err, err, err, err, err, err,
2155 },
2156 {
2157 { SDB_TYPE_BINARY, { .binary = { 2, (unsigned char *)"20" } } },
2158 { SDB_TYPE_STRING, { .string = "20" } },
2159 err, err, err, err, err, err,
2160 },
2161 {
2162 { SDB_TYPE_BINARY, { .binary = { 3, (unsigned char *)"20" } } },
2163 { SDB_TYPE_STRING, { .string = "20" } },
2164 err, err, err, err, err, err,
2165 },
2166 {
2167 { SDB_TYPE_BINARY, { .binary = { 2, (unsigned char *)"20" } } },
2168 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
2169 err, err, err, err, err, err,
2170 },
2171 {
2172 { SDB_TYPE_BINARY, { .binary = { 3, (unsigned char *)"20" } } },
2173 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
2174 err, err, err, err, err, err,
2175 },
2176 {
2177 { SDB_TYPE_BINARY, { .binary = { 2, (unsigned char *)"20" } } },
2178 { SDB_TYPE_REGEX + 1, { .integer = 0 } },
2179 err, err, err, err, err, err,
2180 },
2181 {
2182 { SDB_TYPE_BINARY, { .binary = { 3, (unsigned char *)"20" } } },
2183 { SDB_TYPE_REGEX + 1, { .integer = 0 } },
2184 err, err, err, err, err, err,
2185 },
2186 {
2187 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
2188 { SDB_TYPE_INTEGER, { .integer = 20 } },
2189 err, err, err, err, err, err,
2190 },
2191 {
2192 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
2193 { SDB_TYPE_DECIMAL, { .decimal = 20.0 } },
2194 err, err, err, err, err, err,
2195 },
2196 {
2197 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
2198 { SDB_TYPE_STRING, { .string = "20" } },
2199 err, err, err, err, err, err,
2200 },
2201 {
2202 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
2203 { SDB_TYPE_DATETIME, { .datetime = 20 } },
2204 err, err, err, err, err, err,
2205 },
2206 {
2207 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
2208 { SDB_TYPE_BINARY, { .binary = { 2, (unsigned char *)"20" } } },
2209 err, err, err, err, err, err,
2210 },
2211 {
2212 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
2213 { SDB_TYPE_BINARY, { .binary = { 3, (unsigned char *)"20" } } },
2214 err, err, err, err, err, err,
2215 },
2216 {
2217 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
2218 { SDB_TYPE_REGEX + 1, { .integer = 0 } },
2219 err, err, err, err, err, err,
2220 },
2221 };
2223 size_t i;
2225 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
2226 struct {
2227 int op;
2228 sdb_data_t expected;
2229 } tests[] = {
2230 { SDB_DATA_ADD, golden_data[i].expected_add },
2231 { SDB_DATA_SUB, golden_data[i].expected_sub },
2232 { SDB_DATA_MUL, golden_data[i].expected_mul },
2233 { SDB_DATA_DIV, golden_data[i].expected_div },
2234 { SDB_DATA_MOD, golden_data[i].expected_mod },
2235 { SDB_DATA_CONCAT, golden_data[i].expected_concat },
2236 };
2238 size_t j;
2239 for (j = 0; j < SDB_STATIC_ARRAY_LEN(tests); ++j) {
2240 sdb_data_t res;
2241 int check;
2242 int type1, type2, type;
2244 char d1_str[64] = "", d2_str[64] = "";
2245 sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
2246 SDB_DOUBLE_QUOTED);
2247 sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
2248 SDB_DOUBLE_QUOTED);
2250 type1 = golden_data[i].d1.type;
2251 type2 = golden_data[i].d2.type;
2252 if (sdb_data_isnull(&golden_data[i].d1))
2253 type1 = SDB_TYPE_NULL;
2254 if (sdb_data_isnull(&golden_data[i].d2))
2255 type2 = SDB_TYPE_NULL;
2256 type = sdb_data_expr_type(tests[j].op, type1, type2);
2258 check = sdb_data_expr_eval(tests[j].op,
2259 &golden_data[i].d1, &golden_data[i].d2, &res);
2260 fail_unless((check == 0) == (tests[j].expected.type != -1),
2261 "sdb_data_expr_eval(%s, %s, %s) = %d; expected: %d",
2262 SDB_DATA_OP_TO_STRING(tests[j].op), d1_str, d2_str, check,
2263 tests[j].expected.type == -1 ? -1 : 0);
2265 fail_unless(tests[j].expected.type == type,
2266 "sdb_data_expr_eval(%s, %s, %s) expected to evaluate "
2267 "to type %d while sdb_data_expr_type(%d, %d, %d) "
2268 "predicted type %d", SDB_DATA_OP_TO_STRING(tests[j].op),
2269 d1_str, d2_str, tests[j].expected.type,
2270 tests[j].op, golden_data[i].d1.type,
2271 golden_data[i].d2.type, type);
2273 if (tests[j].expected.type == -1)
2274 continue;
2276 if (tests[j].expected.type == SDB_TYPE_NULL) {
2277 fail_unless(res.type == SDB_TYPE_NULL,
2278 "sdb_data_expr_eval(%s, %s, %s) evaluated to "
2279 "type %d; expected: SDB_TYPE_NULL",
2280 SDB_DATA_OP_TO_STRING(tests[j].op),
2281 d1_str, d2_str, res.type);
2282 continue;
2283 }
2285 check = sdb_data_cmp(&res, &tests[j].expected);
2286 if (check != 0) {
2287 char res_str[64] = "", expected_str[64] = "";
2288 sdb_data_format(&res, res_str, sizeof(res_str),
2289 SDB_DOUBLE_QUOTED);
2290 sdb_data_format(&tests[j].expected, expected_str,
2291 sizeof(expected_str), SDB_DOUBLE_QUOTED);
2292 fail("sdb_data_expr_eval(%s, %s, %s) evaluated to %s "
2293 "(type %d); expected: %s (type %d)",
2294 SDB_DATA_OP_TO_STRING(tests[j].op),
2295 d1_str, d2_str, res_str, res.type,
2296 expected_str, tests[j].expected.type);
2297 }
2299 sdb_data_free_datum(&res);
2300 }
2301 }
2302 }
2303 END_TEST
2305 START_TEST(test_format)
2306 {
2307 bool bool_values[] = { false, true, false };
2308 int64_t int_values[] = { 47, 11, 23 };
2309 char *string_values[] = { "foo", "bar", "qux", "baz" };
2311 struct {
2312 sdb_data_t datum;
2313 const char *expected;
2314 } golden_data[] = {
2315 {
2316 { SDB_TYPE_NULL, { .integer = 0 } },
2317 "NULL",
2318 },
2319 {
2320 { SDB_TYPE_BOOLEAN, { .boolean = true } },
2321 "true",
2322 },
2323 {
2324 { SDB_TYPE_BOOLEAN, { .boolean = false } },
2325 "false",
2326 },
2327 {
2328 { SDB_TYPE_INTEGER, { .integer = 4711 } },
2329 "4711",
2330 },
2331 {
2332 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
2333 "65536",
2334 },
2335 {
2336 { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
2337 "12.3",
2338 },
2339 {
2340 { SDB_TYPE_STRING, { .string = NULL } },
2341 "NULL",
2342 },
2343 {
2344 { SDB_TYPE_STRING, { .string = "this is a test" } },
2345 "\"this is a test\"",
2346 },
2347 {
2348 { SDB_TYPE_STRING, { .string = "special \\ \" characters" } },
2349 "\"special \\\\ \\\" characters\"",
2350 },
2351 {
2352 { SDB_TYPE_DATETIME, { .datetime= 471147114711471100 } },
2353 "\"1984-12-06 02:11:54.711471100 +0000\"",
2354 },
2355 {
2356 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
2357 "NULL",
2358 },
2359 {
2360 {
2361 SDB_TYPE_BINARY,
2362 { .binary = { 12, (unsigned char *)"binary\0crap\x42" } },
2363 },
2364 "\"\\x62\\x69\\x6e\\x61\\x72\\x79\\x0\\x63\\x72\\x61\\x70\\x42\"",
2365 },
2366 {
2367 { SDB_TYPE_REGEX, { .re = { "some regex", empty_re } } },
2368 "\"/some regex/\"",
2369 },
2370 {
2371 { SDB_TYPE_INTEGER | SDB_TYPE_ARRAY, { .array = { 0, NULL } } },
2372 "[]",
2373 },
2374 {
2375 {
2376 SDB_TYPE_BOOLEAN | SDB_TYPE_ARRAY,
2377 { .array = { SDB_STATIC_ARRAY_LEN(bool_values), bool_values } },
2378 },
2379 "[false, true, false]",
2380 },
2381 {
2382 {
2383 SDB_TYPE_INTEGER | SDB_TYPE_ARRAY,
2384 { .array = { SDB_STATIC_ARRAY_LEN(int_values), int_values } },
2385 },
2386 "[47, 11, 23]",
2387 },
2388 {
2389 {
2390 SDB_TYPE_STRING | SDB_TYPE_ARRAY,
2391 { .array = { SDB_STATIC_ARRAY_LEN(string_values), string_values } },
2392 },
2393 "[\"foo\", \"bar\", \"qux\", \"baz\"]",
2394 },
2395 };
2397 size_t i;
2399 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
2400 sdb_data_t *datum = &golden_data[i].datum;
2401 char buf[sdb_data_strlen(datum) + 2];
2402 size_t check_null, check;
2404 memset(buf, (int)'A', sizeof(buf));
2406 check_null = sdb_data_format(datum, NULL, 0, SDB_DOUBLE_QUOTED);
2407 check = sdb_data_format(datum, buf, sizeof(buf) - 1,
2408 SDB_DOUBLE_QUOTED);
2409 fail_unless(check > 0,
2410 "sdb_data_format(type=%s) = %d; expected: >0",
2411 SDB_TYPE_TO_STRING(datum->type), check);
2412 fail_unless(! strcmp(buf, golden_data[i].expected),
2413 "sdb_data_format(type=%s) used wrong format: %s; expected: %s",
2414 SDB_TYPE_TO_STRING(datum->type), buf, golden_data[i].expected);
2416 fail_unless(check_null == check,
2417 "sdb_data_format(type=%s, NULL) = %d; "
2418 "expected %d (matching sdb_data_format(type=%s, <buf>))",
2419 SDB_TYPE_TO_STRING(datum->type), check_null,
2420 check, SDB_TYPE_TO_STRING(datum->type));
2421 fail_unless(check == strlen(golden_data[i].expected),
2422 "sdb_data_format(type=%s) = %d; expected %zu (strlen)",
2423 SDB_TYPE_TO_STRING(datum->type), check,
2424 strlen(golden_data[i].expected));
2426 fail_unless(check <= sizeof(buf) - 2,
2427 "sdb_data_format(type=%s) wrote %d bytes; "
2428 "expected <= %zu based on sdb_data_strlen()",
2429 SDB_TYPE_TO_STRING(datum->type), check, sizeof(buf) - 2);
2431 fail_unless(buf[sizeof(buf) - 2] == '\0',
2432 "sdb_data_format(type=%s) did not nul-terminate the buffer",
2433 SDB_TYPE_TO_STRING(datum->type));
2434 fail_unless(buf[sizeof(buf) - 1] == 'A',
2435 "sdb_data_format(type=%s) wrote past the end of the buffer",
2436 SDB_TYPE_TO_STRING(datum->type));
2437 }
2438 }
2439 END_TEST
2441 START_TEST(test_parse)
2442 {
2443 struct {
2444 char *input;
2445 sdb_data_t result;
2446 int expected;
2447 } golden_data[] = {
2448 { "true", { SDB_TYPE_BOOLEAN, { .boolean = true } }, 0 },
2449 { "FALSE", { SDB_TYPE_BOOLEAN, { .boolean = false } }, 0 },
2450 { "yes", { SDB_TYPE_BOOLEAN, { .boolean = false } }, -1 },
2451 { "4711", { SDB_TYPE_INTEGER, { .integer = 4711 } }, 0 },
2452 { "0x10", { SDB_TYPE_INTEGER, { .integer = 16 } }, 0 },
2453 { "010", { SDB_TYPE_INTEGER, { .integer = 8 } }, 0 },
2454 { "abc", { SDB_TYPE_INTEGER, { .integer = 0 } }, -1 },
2455 { "1.2", { SDB_TYPE_DECIMAL, { .decimal = 1.2 } }, 0 },
2456 { "0x1p+16", { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } }, 0 },
2457 { "abc", { SDB_TYPE_DECIMAL, { .decimal = 0.0 } }, -1 },
2458 { "abc", { SDB_TYPE_STRING, { .string = "abc" } }, 0 },
2459 { ".4", { SDB_TYPE_DATETIME, { .datetime = 400000000 } }, 0 },
2460 { "abc", { SDB_TYPE_DATETIME, { .datetime = 0 } }, -1 },
2461 { "abc", { SDB_TYPE_BINARY,
2462 { .binary = { 3, (unsigned char *)"abc" } } }, 0 },
2463 { "abc", { SDB_TYPE_REGEX, { .re = { "abc", empty_re } } }, 0 },
2464 { "(|", { SDB_TYPE_REGEX, { .re = { "", empty_re } } }, -1 },
2465 };
2467 size_t i;
2469 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
2470 sdb_data_t result;
2471 int type, check;
2473 memset(&result, 0, sizeof(result));
2474 type = golden_data[i].result.type;
2475 check = sdb_data_parse(golden_data[i].input, type, &result);
2476 fail_unless(check == golden_data[i].expected,
2477 "sdb_data_parse(%s, %d, <d>) = %d; expected: %d",
2478 golden_data[i].input, type, check, golden_data[i].expected);
2480 if (check)
2481 continue;
2483 fail_unless(sdb_data_cmp(&result, &golden_data[i].result) == 0,
2484 "sdb_data_parse(%s, %d, <d>) did not create expected result",
2485 golden_data[i].input, type);
2487 if (type == SDB_TYPE_STRING)
2488 fail_unless(golden_data[i].input != result.data.string,
2489 "sdb_data_parse(%s, %d, <d>) copied input string",
2490 golden_data[i].input, type);
2491 if (type == SDB_TYPE_BINARY)
2492 fail_unless(golden_data[i].input != (char *)result.data.binary.datum,
2493 "sdb_data_parse(%s, %d, <d>) copied input string",
2494 golden_data[i].input, type);
2495 if (type == SDB_TYPE_REGEX)
2496 fail_unless(golden_data[i].input != result.data.re.raw,
2497 "sdb_data_parse(%s, %d, <d>) copied input string",
2498 golden_data[i].input, type);
2499 sdb_data_free_datum(&result);
2500 }
2501 }
2502 END_TEST
2504 TEST_MAIN("core::data")
2505 {
2506 TCase *tc = tcase_create("core");
2507 tcase_add_test(tc, test_data);
2508 tcase_add_test(tc, test_cmp);
2509 tcase_add_test(tc, test_strcmp);
2510 tcase_add_test(tc, test_inarray);
2511 tcase_add_test(tc, test_array_get);
2512 tcase_add_test(tc, test_parse_op);
2513 tcase_add_test(tc, test_expr_eval);
2514 tcase_add_test(tc, test_format);
2515 tcase_add_test(tc, test_parse);
2516 ADD_TCASE(tc);
2517 }
2518 TEST_MAIN_END
2520 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */