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