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