Code

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