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