Code

data: Added basic support for arrays.
[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 #include "core/data.h"
29 #include "libsysdb_test.h"
31 #include <assert.h>
32 #include <check.h>
34 static regex_t empty_re;
36 START_TEST(test_data)
37 {
38         sdb_data_t d1, d2;
39         int check;
41         int int_values[] = { 47, 11, 23 };
42         char *string_values[] = { "foo", "bar", "qux" "baz" };
43         size_t i;
45         d2.type = SDB_TYPE_INTEGER;
46         d2.data.integer = 4711;
47         memset(&d1, 0, sizeof(d1));
48         check = sdb_data_copy(&d1, &d2);
49         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
50         fail_unless(d1.type == d2.type,
51                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
52                         d1.type, d2.type);
53         fail_unless(d1.data.integer == d2.data.integer,
54                         "sdb_data_copy() didn't copy integer data: got: %d; expected: %d",
55                         d1.data.integer, d2.data.integer);
57         d2.type = SDB_TYPE_DECIMAL;
58         d2.data.decimal = 47.11;
59         check = sdb_data_copy(&d1, &d2);
60         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
61         fail_unless(d1.type == d2.type,
62                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
63                         d1.type, d2.type);
64         fail_unless(d1.data.decimal == d2.data.decimal,
65                         "sdb_data_copy() didn't copy decimal data: got: %f; expected: %f",
66                         d1.data.decimal, d2.data.decimal);
68         d2.type = SDB_TYPE_STRING;
69         d2.data.string = "some string";
70         check = sdb_data_copy(&d1, &d2);
71         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
72         fail_unless(d1.type == d2.type,
73                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
74                         d1.type, d2.type);
75         fail_unless(!strcmp(d1.data.string, d2.data.string),
76                         "sdb_data_copy() didn't copy string data: got: %s; expected: %s",
77                         d1.data.string, d2.data.string);
79         sdb_data_free_datum(&d1);
80         fail_unless(d1.data.string == NULL,
81                         "sdb_data_free_datum() didn't free string data");
83         d1.type = 0;
84         d2.type = SDB_TYPE_STRING;
85         d2.data.string = NULL;
86         check = sdb_data_copy(&d1, &d2);
87         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
88         fail_unless(d1.type == d2.type,
89                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
90                         d1.type, d2.type);
91         fail_unless(d1.data.string == d2.data.string,
92                         "sdb_data_copy() didn't copy string data: got: %s; expected: %s",
93                         d1.data.string, d2.data.string);
95         sdb_data_free_datum(&d1);
96         fail_unless(d1.data.string == NULL,
97                         "sdb_data_free_datum() didn't free string data");
99         d2.type = SDB_TYPE_DATETIME;
100         d2.data.datetime = 4711;
101         check = sdb_data_copy(&d1, &d2);
102         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
103         fail_unless(d1.type == d2.type,
104                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
105                         d1.type, d2.type);
106         fail_unless(d1.data.datetime == d2.data.datetime,
107                         "sdb_data_copy() didn't copy datetime data: got: %d; expected: %d",
108                         d1.data.datetime, d2.data.datetime);
110         d2.type = SDB_TYPE_BINARY;
111         d2.data.binary.datum = (unsigned char *)"some string";
112         d2.data.binary.length = strlen((const char *)d2.data.binary.datum);
113         check = sdb_data_copy(&d1, &d2);
114         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
115         fail_unless(d1.type == d2.type,
116                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
117                         d1.type, d2.type);
118         fail_unless(d1.data.binary.length == d2.data.binary.length,
119                         "sdb_data_copy() didn't copy length; got: %d; expected: 5d",
120                         d1.data.binary.length, d2.data.binary.length);
121         fail_unless(!memcmp(d1.data.binary.datum, d2.data.binary.datum,
122                                 d2.data.binary.length),
123                         "sdb_data_copy() didn't copy binary data: got: %s; expected: %s",
124                         d1.data.binary.datum, d2.data.binary.datum);
126         sdb_data_free_datum(&d1);
127         fail_unless(d1.data.binary.length == 0,
128                         "sdb_data_free_datum() didn't reset binary datum length");
129         fail_unless(d1.data.binary.datum == NULL,
130                         "sdb_data_free_datum() didn't free binary datum");
132         d1.type = 0;
133         d2.type = SDB_TYPE_BINARY;
134         d2.data.binary.datum = NULL;
135         d2.data.binary.length = 0;
136         check = sdb_data_copy(&d1, &d2);
137         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
138         fail_unless(d1.type == d2.type,
139                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
140                         d1.type, d2.type);
141         fail_unless(d1.data.binary.length == d2.data.binary.length,
142                         "sdb_data_copy() didn't copy length; got: %d; expected: 5d",
143                         d1.data.binary.length, d2.data.binary.length);
144         fail_unless(d1.data.binary.datum == d2.data.binary.datum,
145                         "sdb_data_copy() didn't copy binary data: got: %s; expected: %s",
146                         d1.data.binary.datum, d2.data.binary.datum);
148         sdb_data_free_datum(&d1);
149         fail_unless(d1.data.binary.length == 0,
150                         "sdb_data_free_datum() didn't reset binary datum length");
151         fail_unless(d1.data.binary.datum == NULL,
152                         "sdb_data_free_datum() didn't free binary datum");
154         check = sdb_data_parse(".", SDB_TYPE_REGEX, &d2);
155         fail_unless(check == 0,
156                         "INTERNAL ERROR: Failed to parse regex '.'");
157         assert(d2.type == SDB_TYPE_REGEX);
158         check = sdb_data_copy(&d1, &d2);
159         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
160         fail_unless(d1.type == d2.type,
161                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
162                         d1.type, d2.type);
163         fail_unless(d1.data.re.raw != d2.data.re.raw,
164                         "sdb_data_copy() copy string pointer");
165         fail_unless(!strcmp(d1.data.re.raw, d2.data.re.raw),
166                         "sdb_data_copy() didn't copy raw regex: got: %s; expected: %s",
167                         d1.data.re.raw, d2.data.re.raw);
168         sdb_data_free_datum(&d2);
170         sdb_data_free_datum(&d1);
171         fail_unless(d1.data.re.raw == NULL,
172                         "sdb_data_free_datum() didn't reset raw regex");
174         d2.type = SDB_TYPE_REGEX;
175         d2.data.re.raw = NULL;
176         check = sdb_data_copy(&d1, &d2);
177         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
178         fail_unless(d1.type == d2.type,
179                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
180                         d1.type, d2.type);
182         d2.type = SDB_TYPE_ARRAY | SDB_TYPE_INTEGER;
183         d2.data.array.length = SDB_STATIC_ARRAY_LEN(int_values);
184         d2.data.array.values = int_values;
185         check = sdb_data_copy(&d1, &d2);
186         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
187         fail_unless(d1.type == d2.type,
188                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
189                         d1.type, d2.type);
190         fail_unless(d1.data.array.values != d2.data.array.values,
191                         "sdb_data_copy() didn't copy values: got: %p; expected: %p",
192                         d1.data.array.values, d2.data.array.values);
193         for (i = 0; i < SDB_STATIC_ARRAY_LEN(int_values); ++i) {
194                 int *i1 = d1.data.array.values;
195                 int *i2 = d2.data.array.values;
196                 fail_unless(i1[i] == i2[i],
197                                 "sdb_data_copy() modified integer value %d: "
198                                 "got: %d; expected: %d", i, i1[i], i2[i]);
199         }
200         sdb_data_free_datum(&d1);
202         d2.type = SDB_TYPE_ARRAY | SDB_TYPE_STRING;
203         d2.data.array.length = SDB_STATIC_ARRAY_LEN(string_values);
204         d2.data.array.values = string_values;
205         check = sdb_data_copy(&d1, &d2);
206         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
207         fail_unless(d1.type == d2.type,
208                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
209                         d1.type, d2.type);
210         fail_unless(d1.data.array.values != d2.data.array.values,
211                         "sdb_data_copy() didn't copy values: got: %p; expected: %p",
212                         d1.data.array.values, d2.data.array.values);
213         for (i = 0; i < SDB_STATIC_ARRAY_LEN(string_values); ++i) {
214                 char **s1 = d1.data.array.values;
215                 char **s2 = d2.data.array.values;
216                 fail_unless(s1[i] != s2[i],
217                                 "sdb_data_copy() didn't copy string value %d", i);
218                 fail_unless(!strcmp(s1[i], s2[i]),
219                                 "sdb_data_copy() modified string value %d: "
220                                 "got: %s; expected: %s", i, s1[i], s2[i]);
221         }
222         sdb_data_free_datum(&d1);
224 END_TEST
226 START_TEST(test_cmp)
228         struct {
229                 sdb_data_t d1;
230                 sdb_data_t d2;
231                 int expected;
232         } golden_data[] = {
233                 {
234                         { SDB_TYPE_INTEGER, { .integer = 47 } },
235                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
236                         -1,
237                 },
238                 {
239                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
240                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
241                         0,
242                 },
243                 {
244                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
245                         { SDB_TYPE_INTEGER, { .integer = 47 } },
246                         1,
247                 },
248                 {
249                         { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
250                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
251                         -1,
252                 },
253                 {
254                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
255                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
256                         0,
257                 },
258                 {
259                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
260                         { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
261                         1,
262                 },
263                 {
264                         { SDB_TYPE_STRING, { .string = NULL } },
265                         { SDB_TYPE_STRING, { .string = "" } },
266                         -1,
267                 },
268                 {
269                         { SDB_TYPE_STRING, { .string = NULL } },
270                         { SDB_TYPE_STRING, { .string = NULL } },
271                         0,
272                 },
273                 {
274                         { SDB_TYPE_STRING, { .string = "" } },
275                         { SDB_TYPE_STRING, { .string = NULL } },
276                         1,
277                 },
278                 {
279                         { SDB_TYPE_STRING, { .string = "a" } },
280                         { SDB_TYPE_STRING, { .string = "b" } },
281                         -1,
282                 },
283                 {
284                         { SDB_TYPE_STRING, { .string = "a" } },
285                         { SDB_TYPE_STRING, { .string = "ab" } },
286                         -1,
287                 },
288                 {
289                         { SDB_TYPE_STRING, { .string = "a" } },
290                         { SDB_TYPE_STRING, { .string = "a" } },
291                         0,
292                 },
293                 {
294                         { SDB_TYPE_STRING, { .string = "b" } },
295                         { SDB_TYPE_STRING, { .string = "a" } },
296                         1,
297                 },
298                 {
299                         { SDB_TYPE_STRING, { .string = "ab" } },
300                         { SDB_TYPE_STRING, { .string = "a" } },
301                         1,
302                 },
303                 {
304                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471000 } },
305                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
306                         -1,
307                 },
308                 {
309                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
310                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
311                         0,
312                 },
313                 {
314                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
315                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471000 } },
316                         1,
317                 },
318                 {
319                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
320                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
321                         -1,
322                 },
323                 {
324                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
325                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
326                         0,
327                 },
328                 {
329                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
330                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
331                         1,
332                 },
333                 {
334                         {
335                                 SDB_TYPE_BINARY,
336                                 { .binary = { 3, (unsigned char *)"a\0a" } },
337                         },
338                         {
339                                 SDB_TYPE_BINARY,
340                                 { .binary = { 3, (unsigned char *)"a\0b" } },
341                         },
342                         -1,
343                 },
344                 {
345                         {
346                                 SDB_TYPE_BINARY,
347                                 { .binary = { 1, (unsigned char *)"a" } },
348                         },
349                         {
350                                 SDB_TYPE_BINARY,
351                                 { .binary = { 3, (unsigned char *)"a\0\0" } },
352                         },
353                         -1,
354                 },
355                 {
356                         {
357                                 SDB_TYPE_BINARY,
358                                 { .binary = { 3, (unsigned char *)"a\0a" } },
359                         },
360                         {
361                                 SDB_TYPE_BINARY,
362                                 { .binary = { 3, (unsigned char *)"a\0a" } },
363                         },
364                         0,
365                 },
366                 {
367                         {
368                                 SDB_TYPE_BINARY,
369                                 { .binary = { 3, (unsigned char *)"a\0b" } },
370                         },
371                         {
372                                 SDB_TYPE_BINARY,
373                                 { .binary = { 3, (unsigned char *)"a\0a" } },
374                         },
375                         1,
376                 },
377                 {
378                         {
379                                 SDB_TYPE_BINARY,
380                                 { .binary = { 3, (unsigned char *)"a\0\0" } },
381                         },
382                         {
383                                 SDB_TYPE_BINARY,
384                                 { .binary = { 1, (unsigned char *)"a" } },
385                         },
386                         1,
387                 },
388                 {
389                         { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
390                         { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
391                         0,
392                 },
393                 {
394                         { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
395                         { SDB_TYPE_REGEX, { .re = { "b", empty_re } } },
396                         -1,
397                 },
398                 {
399                         { SDB_TYPE_REGEX, { .re = { "b", empty_re } } },
400                         { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
401                         1,
402                 },
403         };
405         size_t i;
407         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
408                 int check = sdb_data_cmp(&golden_data[i].d1, &golden_data[i].d2);
409                 check = check < 0 ? -1 : check > 0 ? 1 : 0;
410                 if (check != golden_data[i].expected) {
411                         char d1_str[64] = "", d2_str[64] = "";
412                         sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
413                                         SDB_DOUBLE_QUOTED);
414                         sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
415                                         SDB_DOUBLE_QUOTED);
416                         fail("sdb_data_cmp(%s, %s) = %d; expected: %d",
417                                         d1_str, d2_str, check, golden_data[i].expected);
418                 }
419         }
421 END_TEST
423 START_TEST(test_strcmp)
425         struct {
426                 sdb_data_t d1;
427                 sdb_data_t d2;
428                 int expected;
429         } golden_data[] = {
430                 /* same data as for the sdb_data_cmp test; in case the types match,
431                  * both functions should behave the same (except for some loss in
432                  * precision, e.g. when formatting datetime values) */
433                 {
434                         { SDB_TYPE_INTEGER, { .integer = 47 } },
435                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
436                         -1,
437                 },
438                 {
439                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
440                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
441                         0,
442                 },
443                 {
444                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
445                         { SDB_TYPE_INTEGER, { .integer = 47 } },
446                         1,
447                 },
448                 {
449                         { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
450                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
451                         -1,
452                 },
453                 {
454                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
455                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
456                         0,
457                 },
458                 {
459                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
460                         { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
461                         1,
462                 },
463                 {
464                         { SDB_TYPE_STRING, { .string = NULL } },
465                         { SDB_TYPE_STRING, { .string = "" } },
466                         -1,
467                 },
468                 {
469                         { SDB_TYPE_STRING, { .string = NULL } },
470                         { SDB_TYPE_STRING, { .string = NULL } },
471                         0,
472                 },
473                 {
474                         { SDB_TYPE_STRING, { .string = "" } },
475                         { SDB_TYPE_STRING, { .string = NULL } },
476                         1,
477                 },
478                 {
479                         { SDB_TYPE_STRING, { .string = "a" } },
480                         { SDB_TYPE_STRING, { .string = "b" } },
481                         -1,
482                 },
483                 {
484                         { SDB_TYPE_STRING, { .string = "a" } },
485                         { SDB_TYPE_STRING, { .string = "ab" } },
486                         -1,
487                 },
488                 {
489                         { SDB_TYPE_STRING, { .string = "a" } },
490                         { SDB_TYPE_STRING, { .string = "a" } },
491                         0,
492                 },
493                 {
494                         { SDB_TYPE_STRING, { .string = "b" } },
495                         { SDB_TYPE_STRING, { .string = "a" } },
496                         1,
497                 },
498                 {
499                         { SDB_TYPE_STRING, { .string = "ab" } },
500                         { SDB_TYPE_STRING, { .string = "a" } },
501                         1,
502                 },
503                 {
504                         { SDB_TYPE_DATETIME, { .datetime = 471047114711471100 } },
505                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
506                         -1,
507                 },
508                 {
509                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
510                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
511                         0,
512                 },
513                 {
514                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
515                         { SDB_TYPE_DATETIME, { .datetime = 471047114711471100 } },
516                         1,
517                 },
518                 {
519                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
520                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
521                         -1,
522                 },
523                 {
524                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
525                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
526                         0,
527                 },
528                 {
529                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
530                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
531                         1,
532                 },
533                 {
534                         {
535                                 SDB_TYPE_BINARY,
536                                 { .binary = { 3, (unsigned char *)"a\0a" } },
537                         },
538                         {
539                                 SDB_TYPE_BINARY,
540                                 { .binary = { 3, (unsigned char *)"a\0b" } },
541                         },
542                         -1,
543                 },
544                 {
545                         {
546                                 SDB_TYPE_BINARY,
547                                 { .binary = { 1, (unsigned char *)"a" } },
548                         },
549                         {
550                                 SDB_TYPE_BINARY,
551                                 { .binary = { 3, (unsigned char *)"a\0\0" } },
552                         },
553                         -1,
554                 },
555                 {
556                         {
557                                 SDB_TYPE_BINARY,
558                                 { .binary = { 3, (unsigned char *)"a\0a" } },
559                         },
560                         {
561                                 SDB_TYPE_BINARY,
562                                 { .binary = { 3, (unsigned char *)"a\0a" } },
563                         },
564                         0,
565                 },
566                 {
567                         {
568                                 SDB_TYPE_BINARY,
569                                 { .binary = { 3, (unsigned char *)"a\0b" } },
570                         },
571                         {
572                                 SDB_TYPE_BINARY,
573                                 { .binary = { 3, (unsigned char *)"a\0a" } },
574                         },
575                         1,
576                 },
577                 {
578                         {
579                                 SDB_TYPE_BINARY,
580                                 { .binary = { 3, (unsigned char *)"a\0\0" } },
581                         },
582                         {
583                                 SDB_TYPE_BINARY,
584                                 { .binary = { 1, (unsigned char *)"a" } },
585                         },
586                         1,
587                 },
588                 {
589                         { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
590                         { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
591                         0,
592                 },
593                 {
594                         { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
595                         { SDB_TYPE_REGEX, { .re = { "b", empty_re } } },
596                         -1,
597                 },
598                 {
599                         { SDB_TYPE_REGEX, { .re = { "b", empty_re } } },
600                         { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
601                         1,
602                 },
603                 /* type mismatches */
604                 {
605                         { SDB_TYPE_INTEGER, { .integer = 123 } },
606                         { SDB_TYPE_STRING, { .string = "123" } },
607                         0,
608                 },
609                 {
610                         { SDB_TYPE_INTEGER, { .integer = 120 } },
611                         { SDB_TYPE_STRING, { .string = "123" } },
612                         -1,
613                 },
614                 {
615                         { SDB_TYPE_STRING, { .string = "123" } },
616                         { SDB_TYPE_INTEGER, { .integer = 120 } },
617                         1,
618                 },
619                 {
620                         { SDB_TYPE_STRING, { .string = "12.3" } },
621                         { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
622                         0,
623                 },
624                 {
625                         { SDB_TYPE_STRING, { .string = "12.0" } },
626                         { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
627                         -1,
628                 },
629                 {
630                         { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
631                         { SDB_TYPE_STRING, { .string = "12.0" } },
632                         1,
633                 },
634                 {
635                         { SDB_TYPE_REGEX, { .re = { "regex", empty_re } } },
636                         { SDB_TYPE_STRING, { .string = "/regex/" } },
637                         0,
638                 },
639         };
641         size_t i;
643         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
644                 int check = sdb_data_strcmp(&golden_data[i].d1, &golden_data[i].d2);
645                 check = check < 0 ? -1 : check > 0 ? 1 : 0;
646                 if (check != golden_data[i].expected) {
647                         char d1_str[64] = "", d2_str[64] = "";
648                         sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
649                                         SDB_DOUBLE_QUOTED);
650                         sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
651                                         SDB_DOUBLE_QUOTED);
652                         fail("sdb_data_strcmp(%s, %s) = %d; expected: %d",
653                                         d1_str, d2_str, check, golden_data[i].expected);
654                 }
655         }
657 END_TEST
659 START_TEST(test_parse_op)
661         struct {
662                 const char *op;
663                 int id;
664         } golden_data[] = {
665                 { "+",  SDB_DATA_ADD },
666                 { "-",  SDB_DATA_SUB },
667                 { "*",  SDB_DATA_MUL },
668                 { "/",  SDB_DATA_DIV },
669                 { "%",  SDB_DATA_MOD },
670                 { "||", SDB_DATA_CONCAT },
671                 { "&&", -1 },
672         };
674         size_t i;
676         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
677                 const char *op;
678                 int id;
680                 id = sdb_data_parse_op(golden_data[i].op);
681                 fail_unless(id == golden_data[i].id,
682                                 "sdb_data_parse_op(%s) = %d; expected: %d",
683                                 golden_data[i].op, id, golden_data[i].id);
685                 if (id <= 0)
686                         continue;
688                 op = SDB_DATA_OP_TO_STRING(id);
689                 fail_unless(!strcmp(op, golden_data[i].op),
690                                 "SDB_DATA_OP_TO_STRING(%d) = '%s'; expected: '%s'",
691                                 id, op, golden_data[i].op);
692         }
694 END_TEST
696 START_TEST(test_expr_eval)
698         sdb_data_t err = { -1, { .integer = 0 } };
700         struct {
701                 sdb_data_t d1;
702                 sdb_data_t d2;
703                 sdb_data_t expected_add;
704                 sdb_data_t expected_sub;
705                 sdb_data_t expected_mul;
706                 sdb_data_t expected_div;
707                 sdb_data_t expected_mod;
708                 sdb_data_t expected_concat;
709         } golden_data[] = {
710                 {
711                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
712                         { SDB_TYPE_INTEGER, { .integer = 47 } },
713                         { SDB_TYPE_INTEGER, { .integer = 4758 } },
714                         { SDB_TYPE_INTEGER, { .integer = 4664 } },
715                         { SDB_TYPE_INTEGER, { .integer = 221417 } },
716                         { SDB_TYPE_INTEGER, { .integer = 100 } },
717                         { SDB_TYPE_INTEGER, { .integer = 11 } },
718                         err,
719                 },
720                 {
721                         { SDB_TYPE_DECIMAL, { .decimal = 35.0 } },
722                         { SDB_TYPE_DECIMAL, { .decimal = 17.5 } },
723                         { SDB_TYPE_DECIMAL, { .decimal = 52.5 } },
724                         { SDB_TYPE_DECIMAL, { .decimal = 17.5 } },
725                         { SDB_TYPE_DECIMAL, { .decimal = 612.5 } },
726                         { SDB_TYPE_DECIMAL, { .decimal = 2.0 } },
727                         { SDB_TYPE_DECIMAL, { .decimal = 0.0 } },
728                         err,
729                 },
730                 {
731                         { SDB_TYPE_STRING, { .string = NULL } },
732                         { SDB_TYPE_STRING, { .string = "" } },
733                         SDB_DATA_NULL,
734                         SDB_DATA_NULL,
735                         SDB_DATA_NULL,
736                         SDB_DATA_NULL,
737                         SDB_DATA_NULL,
738                         SDB_DATA_NULL,
739                 },
740                 {
741                         { SDB_TYPE_STRING, { .string = NULL } },
742                         { SDB_TYPE_STRING, { .string = NULL } },
743                         SDB_DATA_NULL,
744                         SDB_DATA_NULL,
745                         SDB_DATA_NULL,
746                         SDB_DATA_NULL,
747                         SDB_DATA_NULL,
748                         SDB_DATA_NULL,
749                 },
750                 {
751                         { SDB_TYPE_STRING, { .string = "" } },
752                         { SDB_TYPE_STRING, { .string = NULL } },
753                         SDB_DATA_NULL,
754                         SDB_DATA_NULL,
755                         SDB_DATA_NULL,
756                         SDB_DATA_NULL,
757                         SDB_DATA_NULL,
758                         SDB_DATA_NULL,
759                 },
760                 {
761                         { SDB_TYPE_STRING, { .string = "a" } },
762                         { SDB_TYPE_STRING, { .string = "b" } },
763                         err,
764                         err,
765                         err,
766                         err,
767                         err,
768                         { SDB_TYPE_STRING, { .string = "ab" } },
769                 },
770                 {
771                         { SDB_TYPE_DATETIME, { .datetime = 47114711 } },
772                         { SDB_TYPE_DATETIME, { .datetime = 4711 } },
773                         { SDB_TYPE_DATETIME, { .datetime = 47119422 } },
774                         { SDB_TYPE_DATETIME, { .datetime = 47110000 } },
775                         { SDB_TYPE_DATETIME, { .datetime = 221957403521 } },
776                         { SDB_TYPE_DATETIME, { .datetime = 10001 } },
777                         { SDB_TYPE_DATETIME, { .datetime = 0 } },
778                         err,
779                 },
780                 {
781                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
782                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
783                         SDB_DATA_NULL,
784                         SDB_DATA_NULL,
785                         SDB_DATA_NULL,
786                         SDB_DATA_NULL,
787                         SDB_DATA_NULL,
788                         SDB_DATA_NULL,
789                 },
790                 {
791                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
792                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
793                         SDB_DATA_NULL,
794                         SDB_DATA_NULL,
795                         SDB_DATA_NULL,
796                         SDB_DATA_NULL,
797                         SDB_DATA_NULL,
798                         SDB_DATA_NULL,
799                 },
800                 {
801                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
802                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
803                         SDB_DATA_NULL,
804                         SDB_DATA_NULL,
805                         SDB_DATA_NULL,
806                         SDB_DATA_NULL,
807                         SDB_DATA_NULL,
808                         SDB_DATA_NULL,
809                 },
810                 {
811                         {
812                                 SDB_TYPE_BINARY,
813                                 { .binary = { 3, (unsigned char *)"a\0a" } },
814                         },
815                         {
816                                 SDB_TYPE_BINARY,
817                                 { .binary = { 3, (unsigned char *)"b\0b" } },
818                         },
819                         err,
820                         err,
821                         err,
822                         err,
823                         err,
824                         {
825                                 SDB_TYPE_BINARY,
826                                 { .binary = { 6, (unsigned char *)"a\0ab\0b" } },
827                         },
828                 },
829                 {
830                         { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
831                         { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
832                         err,
833                         err,
834                         err,
835                         err,
836                         err,
837                         err,
838                 },
839                 {
840                         { SDB_TYPE_NULL, { .integer = 0 } },
841                         { SDB_TYPE_NULL, { .integer = 0 } },
842                         SDB_DATA_NULL,
843                         SDB_DATA_NULL,
844                         SDB_DATA_NULL,
845                         SDB_DATA_NULL,
846                         SDB_DATA_NULL,
847                         SDB_DATA_NULL,
848                 },
849                 {
850                         { SDB_TYPE_NULL, { .integer = 0 } },
851                         { SDB_TYPE_INTEGER, { .integer = 42 } },
852                         SDB_DATA_NULL,
853                         SDB_DATA_NULL,
854                         SDB_DATA_NULL,
855                         SDB_DATA_NULL,
856                         SDB_DATA_NULL,
857                         SDB_DATA_NULL,
858                 },
859                 {
860                         { SDB_TYPE_INTEGER, { .integer = 42 } },
861                         { SDB_TYPE_NULL, { .integer = 0 } },
862                         SDB_DATA_NULL,
863                         SDB_DATA_NULL,
864                         SDB_DATA_NULL,
865                         SDB_DATA_NULL,
866                         SDB_DATA_NULL,
867                         SDB_DATA_NULL,
868                 },
869                 {
870                         { SDB_TYPE_NULL, { .integer = 0 } },
871                         { SDB_TYPE_DECIMAL, { .decimal = 47.11 } },
872                         SDB_DATA_NULL,
873                         SDB_DATA_NULL,
874                         SDB_DATA_NULL,
875                         SDB_DATA_NULL,
876                         SDB_DATA_NULL,
877                         SDB_DATA_NULL,
878                 },
879                 {
880                         { SDB_TYPE_DECIMAL, { .decimal = 47.11 } },
881                         { SDB_TYPE_NULL, { .integer = 0 } },
882                         SDB_DATA_NULL,
883                         SDB_DATA_NULL,
884                         SDB_DATA_NULL,
885                         SDB_DATA_NULL,
886                         SDB_DATA_NULL,
887                         SDB_DATA_NULL,
888                 },
889                 {
890                         { SDB_TYPE_NULL, { .integer = 0 } },
891                         { SDB_TYPE_STRING, { .string = "47.11" } },
892                         SDB_DATA_NULL,
893                         SDB_DATA_NULL,
894                         SDB_DATA_NULL,
895                         SDB_DATA_NULL,
896                         SDB_DATA_NULL,
897                         SDB_DATA_NULL,
898                 },
899                 {
900                         { SDB_TYPE_STRING, { .string = "47.11" } },
901                         { SDB_TYPE_NULL, { .integer = 0 } },
902                         SDB_DATA_NULL,
903                         SDB_DATA_NULL,
904                         SDB_DATA_NULL,
905                         SDB_DATA_NULL,
906                         SDB_DATA_NULL,
907                         SDB_DATA_NULL,
908                 },
909                 {
910                         { SDB_TYPE_NULL, { .integer = 0 } },
911                         { SDB_TYPE_DATETIME, { .datetime = 4711 } },
912                         SDB_DATA_NULL,
913                         SDB_DATA_NULL,
914                         SDB_DATA_NULL,
915                         SDB_DATA_NULL,
916                         SDB_DATA_NULL,
917                         SDB_DATA_NULL,
918                 },
919                 {
920                         { SDB_TYPE_DATETIME, { .datetime = 4711 } },
921                         { SDB_TYPE_NULL, { .integer = 0 } },
922                         SDB_DATA_NULL,
923                         SDB_DATA_NULL,
924                         SDB_DATA_NULL,
925                         SDB_DATA_NULL,
926                         SDB_DATA_NULL,
927                         SDB_DATA_NULL,
928                 },
929                 {
930                         { SDB_TYPE_NULL, { .integer = 0 } },
931                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
932                         SDB_DATA_NULL,
933                         SDB_DATA_NULL,
934                         SDB_DATA_NULL,
935                         SDB_DATA_NULL,
936                         SDB_DATA_NULL,
937                         SDB_DATA_NULL,
938                 },
939                 {
940                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
941                         { SDB_TYPE_NULL, { .integer = 0 } },
942                         SDB_DATA_NULL,
943                         SDB_DATA_NULL,
944                         SDB_DATA_NULL,
945                         SDB_DATA_NULL,
946                         SDB_DATA_NULL,
947                         SDB_DATA_NULL,
948                 },
949                 {
950                         { SDB_TYPE_NULL, { .integer = 0 } },
951                         { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
952                         SDB_DATA_NULL,
953                         SDB_DATA_NULL,
954                         SDB_DATA_NULL,
955                         SDB_DATA_NULL,
956                         SDB_DATA_NULL,
957                         SDB_DATA_NULL,
958                 },
959                 {
960                         { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
961                         { SDB_TYPE_NULL, { .integer = 0 } },
962                         SDB_DATA_NULL,
963                         SDB_DATA_NULL,
964                         SDB_DATA_NULL,
965                         SDB_DATA_NULL,
966                         SDB_DATA_NULL,
967                         SDB_DATA_NULL,
968                 },
969                 /* supported type-mismatches */
970                 {
971                         /* int * datetime */
972                         { SDB_TYPE_INTEGER,  { .integer  = 20 } },
973                         { SDB_TYPE_DATETIME, { .datetime = 2 } },
974                         err,
975                         err,
976                         { SDB_TYPE_DATETIME, { .datetime = 40 } },
977                         err,
978                         err,
979                         err,
980                 },
981                 {
982                         /* datetime * int, datetime / int, datetime % int */
983                         { SDB_TYPE_DATETIME, { .datetime = 20 } },
984                         { SDB_TYPE_INTEGER,  { .integer  = 2 } },
985                         err,
986                         err,
987                         { SDB_TYPE_DATETIME, { .datetime = 40 } },
988                         { SDB_TYPE_DATETIME, { .datetime = 10 } },
989                         { SDB_TYPE_DATETIME, { .datetime = 0 } },
990                         err,
991                 },
992                 {
993                         /* float * datetime */
994                         { SDB_TYPE_DECIMAL,  { .decimal  = 20.0 } },
995                         { SDB_TYPE_DATETIME, { .datetime = 2 } },
996                         err,
997                         err,
998                         { SDB_TYPE_DATETIME, { .datetime = 40 } },
999                         err,
1000                         err,
1001                         err,
1002                 },
1003                 {
1004                         /* datetime * float, datetime / float, datetime % float */
1005                         { SDB_TYPE_DATETIME, { .datetime = 20 } },
1006                         { SDB_TYPE_DECIMAL,  { .decimal  = 2.0 } },
1007                         err,
1008                         err,
1009                         { SDB_TYPE_DATETIME, { .datetime = 40 } },
1010                         { SDB_TYPE_DATETIME, { .datetime = 10 } },
1011                         { SDB_TYPE_DATETIME, { .datetime = 0 } },
1012                         err,
1013                 },
1014         };
1016         size_t i;
1018         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
1019                 struct {
1020                         int op;
1021                         sdb_data_t expected;
1022                 } tests[] = {
1023                         { SDB_DATA_ADD, golden_data[i].expected_add },
1024                         { SDB_DATA_SUB, golden_data[i].expected_sub },
1025                         { SDB_DATA_MUL, golden_data[i].expected_mul },
1026                         { SDB_DATA_DIV, golden_data[i].expected_div },
1027                         { SDB_DATA_MOD, golden_data[i].expected_mod },
1028                         { SDB_DATA_CONCAT, golden_data[i].expected_concat },
1029                 };
1031                 size_t j;
1032                 for (j = 0; j < SDB_STATIC_ARRAY_LEN(tests); ++j) {
1033                         sdb_data_t res;
1034                         int check;
1036                         char d1_str[64] = "", d2_str[64] = "";
1037                         sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
1038                                         SDB_DOUBLE_QUOTED);
1039                         sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
1040                                         SDB_DOUBLE_QUOTED);
1042                         check = sdb_data_expr_eval(tests[j].op,
1043                                         &golden_data[i].d1, &golden_data[i].d2, &res);
1044                         fail_unless((check == 0) == (tests[j].expected.type != -1),
1045                                         "sdb_data_expr_eval(%s, %s, %s) = %d; expected: %d",
1046                                         SDB_DATA_OP_TO_STRING(tests[j].op), d1_str, d2_str, check,
1047                                         tests[j].expected.type == -1 ? -1 : 0);
1048                         if (tests[j].expected.type == -1)
1049                                 continue;
1051                         if (tests[j].expected.type == SDB_TYPE_NULL) {
1052                                 fail_unless(res.type == SDB_TYPE_NULL,
1053                                                 "sdb_data_expr_eval(%s, %s, %s) evaluated to "
1054                                                 "type %d; expected: SDB_TYPE_NULL",
1055                                                 SDB_DATA_OP_TO_STRING(tests[j].op),
1056                                                 d1_str, d2_str, res.type);
1057                                 continue;
1058                         }
1060                         check = sdb_data_cmp(&res, &tests[j].expected);
1061                         if (check != 0) {
1062                                 char res_str[64] = "", expected_str[64] = "";
1063                                 sdb_data_format(&res, res_str, sizeof(res_str),
1064                                                 SDB_DOUBLE_QUOTED);
1065                                 sdb_data_format(&tests[j].expected, expected_str,
1066                                                 sizeof(expected_str), SDB_DOUBLE_QUOTED);
1067                                 fail("sdb_data_expr_eval(%s, %s, %s) evaluated to %s "
1068                                                 "(type %d); expected: %s (type %d)",
1069                                                 SDB_DATA_OP_TO_STRING(tests[j].op),
1070                                                 d1_str, d2_str, res_str, res.type,
1071                                                 expected_str, tests[j].expected.type);
1072                         }
1074                         sdb_data_free_datum(&res);
1075                 }
1076         }
1078 END_TEST
1080 START_TEST(test_format)
1082         struct {
1083                 sdb_data_t datum;
1084                 const char *expected;
1085         } golden_data[] = {
1086                 {
1087                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
1088                         "4711",
1089                 },
1090                 {
1091                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
1092                         "65536",
1093                 },
1094                 {
1095                         { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
1096                         "12.3",
1097                 },
1098                 {
1099                         { SDB_TYPE_STRING, { .string = NULL } },
1100                         "\"<NULL>\"",
1101                 },
1102                 {
1103                         { SDB_TYPE_STRING, { .string = "this is a test" } },
1104                         "\"this is a test\"",
1105                 },
1106                 {
1107                         { SDB_TYPE_STRING, { .string = "special \\ \" characters" } },
1108                         "\"special \\\\ \\\" characters\"",
1109                 },
1110                 {
1111                         { SDB_TYPE_DATETIME, { .datetime= 471147114711471100 } },
1112                         "\"1984-12-06 02:11:54 +0000\"",
1113                 },
1114                 {
1115                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
1116                         "\"<NULL>\"",
1117                 },
1118                 {
1119                         {
1120                                 SDB_TYPE_BINARY,
1121                                 { .binary = { 12, (unsigned char *)"binary\0crap\x42" } },
1122                         },
1123                         "\"\\x62\\x69\\x6e\\x61\\x72\\x79\\x0\\x63\\x72\\x61\\x70\\x42\"",
1124                 },
1125                 {
1126                         { SDB_TYPE_REGEX, { .re = { "some regex", empty_re } } },
1127                         "\"/some regex/\"",
1128                 },
1129         };
1131         size_t i;
1133         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
1134                 sdb_data_t *datum = &golden_data[i].datum;
1135                 char buf[sdb_data_strlen(datum) + 2];
1136                 int check;
1138                 memset(buf, (int)'A', sizeof(buf));
1140                 check = sdb_data_format(datum, buf, sizeof(buf) - 1,
1141                                 SDB_DOUBLE_QUOTED);
1142                 fail_unless(check > 0,
1143                                 "sdb_data_format(type=%s) = %d; expected: >0",
1144                                 SDB_TYPE_TO_STRING(datum->type), check);
1145                 fail_unless(! strcmp(buf, golden_data[i].expected),
1146                                 "sdb_data_format(type=%s) used wrong format: %s; expected: %s",
1147                                 SDB_TYPE_TO_STRING(datum->type), buf, golden_data[i].expected);
1149                 fail_unless((size_t)check <= sizeof(buf) - 2,
1150                                 "sdb_data_format(type=%s) wrote %d bytes; "
1151                                 "expected <= %zu based on sdb_data_strlen()",
1152                                 SDB_TYPE_TO_STRING(datum->type), check, sizeof(buf) - 2);
1154                 fail_unless(buf[sizeof(buf) - 2] == '\0',
1155                                 "sdb_data_format(type=%s) did not nul-terminate the buffer",
1156                                 SDB_TYPE_TO_STRING(datum->type));
1157                 fail_unless(buf[sizeof(buf) - 1] == 'A',
1158                                 "sdb_data_format(type=%s) wrote past the end of the buffer",
1159                                 SDB_TYPE_TO_STRING(datum->type));
1160         }
1162 END_TEST
1164 START_TEST(test_parse)
1166         struct {
1167                 char *input;
1168                 sdb_data_t result;
1169                 int expected;
1170         } golden_data[] = {
1171                 { "4711",    { SDB_TYPE_INTEGER,  { .integer  = 4711 } },          0 },
1172                 { "0x10",    { SDB_TYPE_INTEGER,  { .integer  = 16 } },            0 },
1173                 { "010",     { SDB_TYPE_INTEGER,  { .integer  = 8 } },             0 },
1174                 { "abc",     { SDB_TYPE_INTEGER,  { .integer  = 0 } },            -1 },
1175                 { "1.2",     { SDB_TYPE_DECIMAL,  { .decimal  = 1.2 } },           0 },
1176                 { "0x1p+16", { SDB_TYPE_DECIMAL,  { .decimal  = 65536.0 } },       0 },
1177                 { "abc",     { SDB_TYPE_DECIMAL,  { .decimal  = 0.0 } },          -1 },
1178                 { "abc",     { SDB_TYPE_STRING,   { .string   = "abc" } },         0 },
1179                 { ".4",      { SDB_TYPE_DATETIME, { .datetime = 400000000 } },     0 },
1180                 { "abc",     { SDB_TYPE_DATETIME, { .datetime = 0 } },            -1 },
1181                 { "abc",     { SDB_TYPE_BINARY,
1182                                          { .binary = { 3, (unsigned char *)"abc" } } }, 0 },
1183                 { "abc",     { SDB_TYPE_REGEX,    { .re = { "abc", empty_re } } }, 0 },
1184                 { "(|",      { SDB_TYPE_REGEX,    { .re = { "", empty_re } } },   -1 },
1185         };
1187         size_t i;
1189         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
1190                 sdb_data_t result;
1191                 int type, check;
1193                 memset(&result, 0, sizeof(result));
1194                 type = golden_data[i].result.type;
1195                 check = sdb_data_parse(golden_data[i].input, type, &result);
1196                 fail_unless(check == golden_data[i].expected,
1197                                 "sdb_data_parse(%s, %d, <d>) = %d; expected: %d",
1198                                 golden_data[i].input, type, check, golden_data[i].expected);
1200                 if (check)
1201                         continue;
1203                 fail_unless(sdb_data_cmp(&result, &golden_data[i].result) == 0,
1204                                 "sdb_data_parse(%s, %d, <d>) did not create expected result",
1205                                 golden_data[i].input, type);
1207                 if (type == SDB_TYPE_STRING)
1208                         fail_unless(golden_data[i].input == result.data.string,
1209                                         "sdb_data_parse(%s, %d, <d>) modified input string",
1210                                         golden_data[i].input, type);
1211                 if (type == SDB_TYPE_BINARY)
1212                         fail_unless(golden_data[i].input == (char *)result.data.binary.datum,
1213                                         "sdb_data_parse(%s, %d, <d>) modified input string",
1214                                         golden_data[i].input, type);
1215                 if (type == SDB_TYPE_REGEX) {
1216                         fail_unless(golden_data[i].input != result.data.re.raw,
1217                                         "sdb_data_parse(%s, %d, <d>) copied input string",
1218                                         golden_data[i].input, type);
1219                         sdb_data_free_datum(&result);
1220                 }
1221         }
1223 END_TEST
1225 Suite *
1226 core_data_suite(void)
1228         Suite *s = suite_create("core::data");
1229         TCase *tc;
1231         tc = tcase_create("core");
1232         tcase_add_test(tc, test_data);
1233         tcase_add_test(tc, test_cmp);
1234         tcase_add_test(tc, test_strcmp);
1235         tcase_add_test(tc, test_parse_op);
1236         tcase_add_test(tc, test_expr_eval);
1237         tcase_add_test(tc, test_format);
1238         tcase_add_test(tc, test_parse);
1239         suite_add_tcase(s, tc);
1241         return s;
1242 } /* core_data_suite */
1244 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */