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