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