Code

data: Support some arithmetic expressions on mismatching types.
[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 <check.h>
33 START_TEST(test_data)
34 {
35         sdb_data_t d1, d2;
36         int check;
38         d2.type = SDB_TYPE_INTEGER;
39         d2.data.integer = 4711;
40         memset(&d1, 0, sizeof(d1));
41         check = sdb_data_copy(&d1, &d2);
42         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
43         fail_unless(d1.type == d2.type,
44                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
45                         d1.type, d2.type);
46         fail_unless(d1.data.integer == d2.data.integer,
47                         "sdb_data_copy() didn't copy integer data: got: %d; expected: %d",
48                         d1.data.integer, d2.data.integer);
50         d2.type = SDB_TYPE_DECIMAL;
51         d2.data.decimal = 47.11;
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.decimal == d2.data.decimal,
58                         "sdb_data_copy() didn't copy decimal data: got: %f; expected: %f",
59                         d1.data.decimal, d2.data.decimal);
61         d2.type = SDB_TYPE_STRING;
62         d2.data.string = "some string";
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(!strcmp(d1.data.string, d2.data.string),
69                         "sdb_data_copy() didn't copy string data: got: %s; expected: %s",
70                         d1.data.string, d2.data.string);
72         sdb_data_free_datum(&d1);
73         fail_unless(d1.data.string == NULL,
74                         "sdb_data_free_datum() didn't free string data");
76         d2.type = SDB_TYPE_DATETIME;
77         d2.data.datetime = 4711;
78         check = sdb_data_copy(&d1, &d2);
79         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
80         fail_unless(d1.type == d2.type,
81                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
82                         d1.type, d2.type);
83         fail_unless(d1.data.datetime == d2.data.datetime,
84                         "sdb_data_copy() didn't copy datetime data: got: %d; expected: %d",
85                         d1.data.datetime, d2.data.datetime);
87         d2.type = SDB_TYPE_BINARY;
88         d2.data.binary.datum = (unsigned char *)"some string";
89         d2.data.binary.length = strlen((const char *)d2.data.binary.datum);
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.binary.length == d2.data.binary.length,
96                         "sdb_data_copy() didn't copy length; got: %d; expected: 5d",
97                         d1.data.binary.length, d2.data.binary.length);
98         fail_unless(!memcmp(d1.data.binary.datum, d2.data.binary.datum,
99                                 d2.data.binary.length),
100                         "sdb_data_copy() didn't copy binary data: got: %s; expected: %s",
101                         d1.data.string, d2.data.string);
103         sdb_data_free_datum(&d1);
104         fail_unless(d1.data.binary.length == 0,
105                         "sdb_data_free_datum() didn't reset binary datum length");
106         fail_unless(d1.data.binary.datum == NULL,
107                         "sdb_data_free_datum() didn't free binary datum");
109 END_TEST
111 START_TEST(test_cmp)
113         struct {
114                 sdb_data_t d1;
115                 sdb_data_t d2;
116                 int expected;
117         } golden_data[] = {
118                 {
119                         { SDB_TYPE_INTEGER, { .integer = 47 } },
120                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
121                         -1,
122                 },
123                 {
124                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
125                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
126                         0,
127                 },
128                 {
129                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
130                         { SDB_TYPE_INTEGER, { .integer = 47 } },
131                         1,
132                 },
133                 {
134                         { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
135                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
136                         -1,
137                 },
138                 {
139                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
140                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
141                         0,
142                 },
143                 {
144                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
145                         { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
146                         1,
147                 },
148                 {
149                         { SDB_TYPE_STRING, { .string = NULL } },
150                         { SDB_TYPE_STRING, { .string = "" } },
151                         -1,
152                 },
153                 {
154                         { SDB_TYPE_STRING, { .string = NULL } },
155                         { SDB_TYPE_STRING, { .string = NULL } },
156                         0,
157                 },
158                 {
159                         { SDB_TYPE_STRING, { .string = "" } },
160                         { SDB_TYPE_STRING, { .string = NULL } },
161                         1,
162                 },
163                 {
164                         { SDB_TYPE_STRING, { .string = "a" } },
165                         { SDB_TYPE_STRING, { .string = "b" } },
166                         -1,
167                 },
168                 {
169                         { SDB_TYPE_STRING, { .string = "a" } },
170                         { SDB_TYPE_STRING, { .string = "ab" } },
171                         -1,
172                 },
173                 {
174                         { SDB_TYPE_STRING, { .string = "a" } },
175                         { SDB_TYPE_STRING, { .string = "a" } },
176                         0,
177                 },
178                 {
179                         { SDB_TYPE_STRING, { .string = "b" } },
180                         { SDB_TYPE_STRING, { .string = "a" } },
181                         1,
182                 },
183                 {
184                         { SDB_TYPE_STRING, { .string = "ab" } },
185                         { SDB_TYPE_STRING, { .string = "a" } },
186                         1,
187                 },
188                 {
189                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471000 } },
190                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
191                         -1,
192                 },
193                 {
194                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
195                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
196                         0,
197                 },
198                 {
199                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
200                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471000 } },
201                         1,
202                 },
203                 {
204                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
205                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
206                         -1,
207                 },
208                 {
209                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
210                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
211                         0,
212                 },
213                 {
214                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
215                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
216                         1,
217                 },
218                 {
219                         {
220                                 SDB_TYPE_BINARY,
221                                 { .binary = { 3, (unsigned char *)"a\0a" } },
222                         },
223                         {
224                                 SDB_TYPE_BINARY,
225                                 { .binary = { 3, (unsigned char *)"a\0b" } },
226                         },
227                         -1,
228                 },
229                 {
230                         {
231                                 SDB_TYPE_BINARY,
232                                 { .binary = { 1, (unsigned char *)"a" } },
233                         },
234                         {
235                                 SDB_TYPE_BINARY,
236                                 { .binary = { 3, (unsigned char *)"a\0\0" } },
237                         },
238                         -1,
239                 },
240                 {
241                         {
242                                 SDB_TYPE_BINARY,
243                                 { .binary = { 3, (unsigned char *)"a\0a" } },
244                         },
245                         {
246                                 SDB_TYPE_BINARY,
247                                 { .binary = { 3, (unsigned char *)"a\0a" } },
248                         },
249                         0,
250                 },
251                 {
252                         {
253                                 SDB_TYPE_BINARY,
254                                 { .binary = { 3, (unsigned char *)"a\0b" } },
255                         },
256                         {
257                                 SDB_TYPE_BINARY,
258                                 { .binary = { 3, (unsigned char *)"a\0a" } },
259                         },
260                         1,
261                 },
262                 {
263                         {
264                                 SDB_TYPE_BINARY,
265                                 { .binary = { 3, (unsigned char *)"a\0\0" } },
266                         },
267                         {
268                                 SDB_TYPE_BINARY,
269                                 { .binary = { 1, (unsigned char *)"a" } },
270                         },
271                         1,
272                 },
273         };
275         size_t i;
277         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
278                 int check = sdb_data_cmp(&golden_data[i].d1, &golden_data[i].d2);
279                 check = check < 0 ? -1 : check > 0 ? 1 : 0;
280                 if (check != golden_data[i].expected) {
281                         char d1_str[64] = "", d2_str[64] = "";
282                         sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
283                                         SDB_DOUBLE_QUOTED);
284                         sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
285                                         SDB_DOUBLE_QUOTED);
286                         fail("sdb_data_cmp(%s, %s) = %d; expected: %d",
287                                         d1_str, d2_str, check, golden_data[i].expected);
288                 }
289         }
291 END_TEST
293 START_TEST(test_expr_eval)
295         struct {
296                 sdb_data_t d1;
297                 sdb_data_t d2;
298                 sdb_data_t expected_add;
299                 sdb_data_t expected_sub;
300                 sdb_data_t expected_mul;
301                 sdb_data_t expected_div;
302                 sdb_data_t expected_mod;
303                 sdb_data_t expected_concat;
304         } golden_data[] = {
305                 {
306                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
307                         { SDB_TYPE_INTEGER, { .integer = 47 } },
308                         { SDB_TYPE_INTEGER, { .integer = 4758 } },
309                         { SDB_TYPE_INTEGER, { .integer = 4664 } },
310                         { SDB_TYPE_INTEGER, { .integer = 221417 } },
311                         { SDB_TYPE_INTEGER, { .integer = 100 } },
312                         { SDB_TYPE_INTEGER, { .integer = 11 } },
313                         SDB_DATA_INIT,
314                 },
315                 {
316                         { SDB_TYPE_DECIMAL, { .decimal = 35.0 } },
317                         { SDB_TYPE_DECIMAL, { .decimal = 17.5 } },
318                         { SDB_TYPE_DECIMAL, { .decimal = 52.5 } },
319                         { SDB_TYPE_DECIMAL, { .decimal = 17.5 } },
320                         { SDB_TYPE_DECIMAL, { .decimal = 612.5 } },
321                         { SDB_TYPE_DECIMAL, { .decimal = 2.0 } },
322                         { SDB_TYPE_DECIMAL, { .decimal = 0.0 } },
323                         SDB_DATA_INIT,
324                 },
325                 {
326                         { SDB_TYPE_STRING, { .string = NULL } },
327                         { SDB_TYPE_STRING, { .string = "" } },
328                         SDB_DATA_INIT,
329                         SDB_DATA_INIT,
330                         SDB_DATA_INIT,
331                         SDB_DATA_INIT,
332                         SDB_DATA_INIT,
333                         { SDB_TYPE_STRING, { .string = "" } },
334                 },
335                 {
336                         { SDB_TYPE_STRING, { .string = NULL } },
337                         { SDB_TYPE_STRING, { .string = NULL } },
338                         SDB_DATA_INIT,
339                         SDB_DATA_INIT,
340                         SDB_DATA_INIT,
341                         SDB_DATA_INIT,
342                         SDB_DATA_INIT,
343                         { SDB_TYPE_STRING, { .string = NULL } },
344                 },
345                 {
346                         { SDB_TYPE_STRING, { .string = "" } },
347                         { SDB_TYPE_STRING, { .string = NULL } },
348                         SDB_DATA_INIT,
349                         SDB_DATA_INIT,
350                         SDB_DATA_INIT,
351                         SDB_DATA_INIT,
352                         SDB_DATA_INIT,
353                         { SDB_TYPE_STRING, { .string = "" } },
354                 },
355                 {
356                         { SDB_TYPE_STRING, { .string = "a" } },
357                         { SDB_TYPE_STRING, { .string = "b" } },
358                         SDB_DATA_INIT,
359                         SDB_DATA_INIT,
360                         SDB_DATA_INIT,
361                         SDB_DATA_INIT,
362                         SDB_DATA_INIT,
363                         { SDB_TYPE_STRING, { .string = "ab" } },
364                 },
365                 {
366                         { SDB_TYPE_DATETIME, { .datetime = 47114711 } },
367                         { SDB_TYPE_DATETIME, { .datetime = 4711 } },
368                         { SDB_TYPE_DATETIME, { .datetime = 47119422 } },
369                         { SDB_TYPE_DATETIME, { .datetime = 47110000 } },
370                         { SDB_TYPE_DATETIME, { .datetime = 221957403521 } },
371                         { SDB_TYPE_DATETIME, { .datetime = 10001 } },
372                         { SDB_TYPE_DATETIME, { .datetime = 0 } },
373                         SDB_DATA_INIT,
374                 },
375                 {
376                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
377                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
378                         SDB_DATA_INIT,
379                         SDB_DATA_INIT,
380                         SDB_DATA_INIT,
381                         SDB_DATA_INIT,
382                         SDB_DATA_INIT,
383                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
384                 },
385                 {
386                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
387                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
388                         SDB_DATA_INIT,
389                         SDB_DATA_INIT,
390                         SDB_DATA_INIT,
391                         SDB_DATA_INIT,
392                         SDB_DATA_INIT,
393                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
394                 },
395                 {
396                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
397                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
398                         SDB_DATA_INIT,
399                         SDB_DATA_INIT,
400                         SDB_DATA_INIT,
401                         SDB_DATA_INIT,
402                         SDB_DATA_INIT,
403                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
404                 },
405                 {
406                         {
407                                 SDB_TYPE_BINARY,
408                                 { .binary = { 3, (unsigned char *)"a\0a" } },
409                         },
410                         {
411                                 SDB_TYPE_BINARY,
412                                 { .binary = { 3, (unsigned char *)"b\0b" } },
413                         },
414                         SDB_DATA_INIT,
415                         SDB_DATA_INIT,
416                         SDB_DATA_INIT,
417                         SDB_DATA_INIT,
418                         SDB_DATA_INIT,
419                         {
420                                 SDB_TYPE_BINARY,
421                                 { .binary = { 6, (unsigned char *)"a\0ab\0b" } },
422                         },
423                 },
424                 /* supported type-mismatches */
425                 {
426                         /* int * datetime */
427                         { SDB_TYPE_INTEGER,  { .integer  = 20 } },
428                         { SDB_TYPE_DATETIME, { .datetime = 2 } },
429                         SDB_DATA_INIT,
430                         SDB_DATA_INIT,
431                         { SDB_TYPE_DATETIME, { .datetime = 40 } },
432                         SDB_DATA_INIT,
433                         SDB_DATA_INIT,
434                         SDB_DATA_INIT,
435                 },
436                 {
437                         /* datetime * int, datetime / int, datetime % int */
438                         { SDB_TYPE_DATETIME, { .datetime = 20 } },
439                         { SDB_TYPE_INTEGER,  { .integer  = 2 } },
440                         SDB_DATA_INIT,
441                         SDB_DATA_INIT,
442                         { SDB_TYPE_DATETIME, { .datetime = 40 } },
443                         { SDB_TYPE_DATETIME, { .datetime = 10 } },
444                         { SDB_TYPE_DATETIME, { .datetime = 0 } },
445                         SDB_DATA_INIT,
446                 },
447                 {
448                         /* float * datetime */
449                         { SDB_TYPE_DECIMAL,  { .decimal  = 20.0 } },
450                         { SDB_TYPE_DATETIME, { .datetime = 2 } },
451                         SDB_DATA_INIT,
452                         SDB_DATA_INIT,
453                         { SDB_TYPE_DATETIME, { .datetime = 40 } },
454                         SDB_DATA_INIT,
455                         SDB_DATA_INIT,
456                         SDB_DATA_INIT,
457                 },
458                 {
459                         /* datetime * float, datetime / float, datetime % float */
460                         { SDB_TYPE_DATETIME, { .datetime = 20 } },
461                         { SDB_TYPE_DECIMAL,  { .decimal  = 2.0 } },
462                         SDB_DATA_INIT,
463                         SDB_DATA_INIT,
464                         { SDB_TYPE_DATETIME, { .datetime = 40 } },
465                         { SDB_TYPE_DATETIME, { .datetime = 10 } },
466                         { SDB_TYPE_DATETIME, { .datetime = 0 } },
467                         SDB_DATA_INIT,
468                 },
469         };
471         size_t i;
473         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
474                 struct {
475                         int op;
476                         sdb_data_t expected;
477                 } tests[] = {
478                         { SDB_DATA_ADD, golden_data[i].expected_add },
479                         { SDB_DATA_SUB, golden_data[i].expected_sub },
480                         { SDB_DATA_MUL, golden_data[i].expected_mul },
481                         { SDB_DATA_DIV, golden_data[i].expected_div },
482                         { SDB_DATA_MOD, golden_data[i].expected_mod },
483                         { SDB_DATA_CONCAT, golden_data[i].expected_concat },
484                 };
486                 size_t j;
487                 for (j = 0; j < SDB_STATIC_ARRAY_LEN(tests); ++j) {
488                         sdb_data_t res;
489                         int check;
491                         char d1_str[64] = "", d2_str[64] = "";
492                         sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
493                                         SDB_DOUBLE_QUOTED);
494                         sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
495                                         SDB_DOUBLE_QUOTED);
497                         check = sdb_data_expr_eval(tests[j].op,
498                                         &golden_data[i].d1, &golden_data[i].d2, &res);
499                         fail_unless((check == 0) == (tests[j].expected.type != 0),
500                                         "sdb_data_expr_eval(%s, %s, %s) = %d; expected: %d",
501                                         SDB_DATA_OP_TO_STRING(tests[j].op), d1_str, d2_str, check,
502                                         tests[j].expected.type == 0 ? -1 : 0);
503                         if (tests[j].expected.type == 0)
504                                 continue;
506                         check = sdb_data_cmp(&res, &tests[j].expected);
507                         if (check != 0) {
508                                 char res_str[64] = "", expected_str[64] = "";
509                                 sdb_data_format(&res, res_str, sizeof(res_str),
510                                                 SDB_DOUBLE_QUOTED);
511                                 sdb_data_format(&tests[j].expected, expected_str,
512                                                 sizeof(expected_str), SDB_DOUBLE_QUOTED);
513                                 fail("sdb_data_expr_eval(%s, %s, %s) evaluated to %s; "
514                                                 "expected: %s", SDB_DATA_OP_TO_STRING(tests[j].op),
515                                                 d1_str, d2_str, res_str, expected_str);
516                         }
518                         sdb_data_free_datum(&res);
519                 }
520         }
522 END_TEST
524 START_TEST(test_format)
526         struct {
527                 sdb_data_t datum;
528                 const char *expected;
529         } golden_data[] = {
530                 {
531                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
532                         "4711",
533                 },
534                 {
535                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
536                         "0x1p+16",
537                 },
538                 {
539                         { SDB_TYPE_STRING, { .string = NULL } },
540                         "\"NULL\"",
541                 },
542                 {
543                         { SDB_TYPE_STRING, { .string = "this is a test" } },
544                         "\"this is a test\"",
545                 },
546                 {
547                         { SDB_TYPE_STRING, { .string = "special \\ \" characters" } },
548                         "\"special \\\\ \\\" characters\"",
549                 },
550                 {
551                         { SDB_TYPE_DATETIME, { .datetime= 471147114711471100 } },
552                         "\"1984-12-06 02:11:54 +0000\"",
553                 },
554                 {
555                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
556                         "\"\"",
557                 },
558                 {
559                         {
560                                 SDB_TYPE_BINARY,
561                                 { .binary = { 12, (unsigned char *)"binary\0crap\x42" } },
562                         },
563                         "\"\\x62\\x69\\x6e\\x61\\x72\\x79\\x0\\x63\\x72\\x61\\x70\\x42\"",
564                 },
565         };
567         size_t i;
569         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
570                 sdb_data_t *datum = &golden_data[i].datum;
571                 char buf[sdb_data_strlen(datum) + 2];
572                 int check;
574                 memset(buf, (int)'A', sizeof(buf));
576                 check = sdb_data_format(datum, buf, sizeof(buf) - 1,
577                                 SDB_DOUBLE_QUOTED);
578                 fail_unless(check > 0,
579                                 "sdb_data_format(type=%s) = %d; expected: >0",
580                                 SDB_TYPE_TO_STRING(datum->type), check);
581                 fail_unless(! strcmp(buf, golden_data[i].expected),
582                                 "sdb_data_format(type=%s) used wrong format: %s; expected: %s",
583                                 SDB_TYPE_TO_STRING(datum->type), buf, golden_data[i].expected);
585                 fail_unless((size_t)check <= sizeof(buf) - 2,
586                                 "sdb_data_format(type=%s) wrote %d bytes; "
587                                 "expected <= %zu based on sdb_data_strlen()",
588                                 SDB_TYPE_TO_STRING(datum->type), check, sizeof(buf) - 2);
590                 fail_unless(buf[sizeof(buf) - 2] == '\0',
591                                 "sdb_data_format(type=%s) did not nul-terminate the buffer",
592                                 SDB_TYPE_TO_STRING(datum->type));
593                 fail_unless(buf[sizeof(buf) - 1] == 'A',
594                                 "sdb_data_format(type=%s) wrote past the end of the buffer",
595                                 SDB_TYPE_TO_STRING(datum->type));
596         }
598 END_TEST
600 START_TEST(test_parse)
602         struct {
603                 char *input;
604                 sdb_data_t result;
605                 int expected;
606         } golden_data[] = {
607                 { "4711",    { SDB_TYPE_INTEGER,  { .integer  = 4711 } },       0 },
608                 { "0x10",    { SDB_TYPE_INTEGER,  { .integer  = 16 } },         0 },
609                 { "010",     { SDB_TYPE_INTEGER,  { .integer  = 8 } },          0 },
610                 { "abc",     { SDB_TYPE_INTEGER,  { .integer  = 0 } },         -1 },
611                 { "1.2",     { SDB_TYPE_DECIMAL,  { .decimal  = 1.2 } },        0 },
612                 { "0x1p+16", { SDB_TYPE_DECIMAL,  { .decimal  = 65536.0 } },    0 },
613                 { "abc",     { SDB_TYPE_DECIMAL,  { .decimal  = 0.0 } },       -1 },
614                 { "abc",     { SDB_TYPE_STRING,   { .string   = "abc" } },      0 },
615                 { ".4",      { SDB_TYPE_DATETIME, { .datetime = 400000000 } },  0 },
616                 { "abc",     { SDB_TYPE_DATETIME, { .datetime = 0 } },         -1 },
617                 { "abc",     { SDB_TYPE_BINARY,
618                                          { .binary = { 3, (unsigned char *)"abc" } } }, 0 },
619         };
621         size_t i;
623         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
624                 sdb_data_t result;
625                 int type, check;
627                 memset(&result, 0, sizeof(result));
628                 type = golden_data[i].result.type;
629                 check = sdb_data_parse(golden_data[i].input, type, &result);
630                 fail_unless(check == golden_data[i].expected,
631                                 "sdb_data_parse(%s, %d, <d>) = %d; expected: %d",
632                                 golden_data[i].input, type, check, golden_data[i].expected);
634                 if (check)
635                         continue;
637                 fail_unless(sdb_data_cmp(&result, &golden_data[i].result) == 0,
638                                 "sdb_data_parse(%s, %d, <d>) did not create expected result",
639                                 golden_data[i].input, type);
641                 if (type == SDB_TYPE_STRING)
642                         fail_unless(golden_data[i].input == result.data.string,
643                                         "sdb_data_parse(%s, %d, <d>) modified input string",
644                                         golden_data[i].input, type);
645                 if (type == SDB_TYPE_BINARY)
646                         fail_unless(golden_data[i].input == (char *)result.data.binary.datum,
647                                         "sdb_data_parse(%s, %d, <d>) modified input string",
648                                         golden_data[i].input, type);
649         }
651 END_TEST
653 Suite *
654 core_data_suite(void)
656         Suite *s = suite_create("core::data");
657         TCase *tc;
659         tc = tcase_create("core");
660         tcase_add_test(tc, test_data);
661         tcase_add_test(tc, test_cmp);
662         tcase_add_test(tc, test_expr_eval);
663         tcase_add_test(tc, test_format);
664         tcase_add_test(tc, test_parse);
665         suite_add_tcase(s, tc);
667         return s;
668 } /* core_data_suite */
670 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */