Code

data_test: Fixed name/order of the cmp() and strcmp() tests.
[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         d1.type = 0;
77         d2.type = SDB_TYPE_STRING;
78         d2.data.string = NULL;
79         check = sdb_data_copy(&d1, &d2);
80         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
81         fail_unless(d1.type == d2.type,
82                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
83                         d1.type, d2.type);
84         fail_unless(d1.data.string == d2.data.string,
85                         "sdb_data_copy() didn't copy string data: got: %s; expected: %s",
86                         d1.data.string, d2.data.string);
88         sdb_data_free_datum(&d1);
89         fail_unless(d1.data.string == NULL,
90                         "sdb_data_free_datum() didn't free string data");
92         d2.type = SDB_TYPE_DATETIME;
93         d2.data.datetime = 4711;
94         check = sdb_data_copy(&d1, &d2);
95         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
96         fail_unless(d1.type == d2.type,
97                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
98                         d1.type, d2.type);
99         fail_unless(d1.data.datetime == d2.data.datetime,
100                         "sdb_data_copy() didn't copy datetime data: got: %d; expected: %d",
101                         d1.data.datetime, d2.data.datetime);
103         d2.type = SDB_TYPE_BINARY;
104         d2.data.binary.datum = (unsigned char *)"some string";
105         d2.data.binary.length = strlen((const char *)d2.data.binary.datum);
106         check = sdb_data_copy(&d1, &d2);
107         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
108         fail_unless(d1.type == d2.type,
109                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
110                         d1.type, d2.type);
111         fail_unless(d1.data.binary.length == d2.data.binary.length,
112                         "sdb_data_copy() didn't copy length; got: %d; expected: 5d",
113                         d1.data.binary.length, d2.data.binary.length);
114         fail_unless(!memcmp(d1.data.binary.datum, d2.data.binary.datum,
115                                 d2.data.binary.length),
116                         "sdb_data_copy() didn't copy binary data: got: %s; expected: %s",
117                         d1.data.binary.datum, d2.data.binary.datum);
119         sdb_data_free_datum(&d1);
120         fail_unless(d1.data.binary.length == 0,
121                         "sdb_data_free_datum() didn't reset binary datum length");
122         fail_unless(d1.data.binary.datum == NULL,
123                         "sdb_data_free_datum() didn't free binary datum");
125         d1.type = 0;
126         d2.type = SDB_TYPE_BINARY;
127         d2.data.binary.datum = NULL;
128         d2.data.binary.length = 0;
129         check = sdb_data_copy(&d1, &d2);
130         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
131         fail_unless(d1.type == d2.type,
132                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
133                         d1.type, d2.type);
134         fail_unless(d1.data.binary.length == d2.data.binary.length,
135                         "sdb_data_copy() didn't copy length; got: %d; expected: 5d",
136                         d1.data.binary.length, d2.data.binary.length);
137         fail_unless(d1.data.binary.datum == d2.data.binary.datum,
138                         "sdb_data_copy() didn't copy binary data: got: %s; expected: %s",
139                         d1.data.binary.datum, d2.data.binary.datum);
141         sdb_data_free_datum(&d1);
142         fail_unless(d1.data.binary.length == 0,
143                         "sdb_data_free_datum() didn't reset binary datum length");
144         fail_unless(d1.data.binary.datum == NULL,
145                         "sdb_data_free_datum() didn't free binary datum");
147 END_TEST
149 START_TEST(test_cmp)
151         struct {
152                 sdb_data_t d1;
153                 sdb_data_t d2;
154                 int expected;
155         } golden_data[] = {
156                 {
157                         { SDB_TYPE_INTEGER, { .integer = 47 } },
158                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
159                         -1,
160                 },
161                 {
162                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
163                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
164                         0,
165                 },
166                 {
167                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
168                         { SDB_TYPE_INTEGER, { .integer = 47 } },
169                         1,
170                 },
171                 {
172                         { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
173                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
174                         -1,
175                 },
176                 {
177                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
178                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
179                         0,
180                 },
181                 {
182                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
183                         { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
184                         1,
185                 },
186                 {
187                         { SDB_TYPE_STRING, { .string = NULL } },
188                         { SDB_TYPE_STRING, { .string = "" } },
189                         -1,
190                 },
191                 {
192                         { SDB_TYPE_STRING, { .string = NULL } },
193                         { SDB_TYPE_STRING, { .string = NULL } },
194                         0,
195                 },
196                 {
197                         { SDB_TYPE_STRING, { .string = "" } },
198                         { SDB_TYPE_STRING, { .string = NULL } },
199                         1,
200                 },
201                 {
202                         { SDB_TYPE_STRING, { .string = "a" } },
203                         { SDB_TYPE_STRING, { .string = "b" } },
204                         -1,
205                 },
206                 {
207                         { SDB_TYPE_STRING, { .string = "a" } },
208                         { SDB_TYPE_STRING, { .string = "ab" } },
209                         -1,
210                 },
211                 {
212                         { SDB_TYPE_STRING, { .string = "a" } },
213                         { SDB_TYPE_STRING, { .string = "a" } },
214                         0,
215                 },
216                 {
217                         { SDB_TYPE_STRING, { .string = "b" } },
218                         { SDB_TYPE_STRING, { .string = "a" } },
219                         1,
220                 },
221                 {
222                         { SDB_TYPE_STRING, { .string = "ab" } },
223                         { SDB_TYPE_STRING, { .string = "a" } },
224                         1,
225                 },
226                 {
227                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471000 } },
228                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
229                         -1,
230                 },
231                 {
232                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
233                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
234                         0,
235                 },
236                 {
237                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
238                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471000 } },
239                         1,
240                 },
241                 {
242                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
243                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
244                         -1,
245                 },
246                 {
247                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
248                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
249                         0,
250                 },
251                 {
252                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
253                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
254                         1,
255                 },
256                 {
257                         {
258                                 SDB_TYPE_BINARY,
259                                 { .binary = { 3, (unsigned char *)"a\0a" } },
260                         },
261                         {
262                                 SDB_TYPE_BINARY,
263                                 { .binary = { 3, (unsigned char *)"a\0b" } },
264                         },
265                         -1,
266                 },
267                 {
268                         {
269                                 SDB_TYPE_BINARY,
270                                 { .binary = { 1, (unsigned char *)"a" } },
271                         },
272                         {
273                                 SDB_TYPE_BINARY,
274                                 { .binary = { 3, (unsigned char *)"a\0\0" } },
275                         },
276                         -1,
277                 },
278                 {
279                         {
280                                 SDB_TYPE_BINARY,
281                                 { .binary = { 3, (unsigned char *)"a\0a" } },
282                         },
283                         {
284                                 SDB_TYPE_BINARY,
285                                 { .binary = { 3, (unsigned char *)"a\0a" } },
286                         },
287                         0,
288                 },
289                 {
290                         {
291                                 SDB_TYPE_BINARY,
292                                 { .binary = { 3, (unsigned char *)"a\0b" } },
293                         },
294                         {
295                                 SDB_TYPE_BINARY,
296                                 { .binary = { 3, (unsigned char *)"a\0a" } },
297                         },
298                         1,
299                 },
300                 {
301                         {
302                                 SDB_TYPE_BINARY,
303                                 { .binary = { 3, (unsigned char *)"a\0\0" } },
304                         },
305                         {
306                                 SDB_TYPE_BINARY,
307                                 { .binary = { 1, (unsigned char *)"a" } },
308                         },
309                         1,
310                 },
311         };
313         size_t i;
315         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
316                 int check = sdb_data_cmp(&golden_data[i].d1, &golden_data[i].d2);
317                 check = check < 0 ? -1 : check > 0 ? 1 : 0;
318                 if (check != golden_data[i].expected) {
319                         char d1_str[64] = "", d2_str[64] = "";
320                         sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
321                                         SDB_DOUBLE_QUOTED);
322                         sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
323                                         SDB_DOUBLE_QUOTED);
324                         fail("sdb_data_cmp(%s, %s) = %d; expected: %d",
325                                         d1_str, d2_str, check, golden_data[i].expected);
326                 }
327         }
329 END_TEST
331 START_TEST(test_strcmp)
333         struct {
334                 sdb_data_t d1;
335                 sdb_data_t d2;
336                 int expected;
337         } golden_data[] = {
338                 /* same data as for the sdb_data_cmp test; in case the types match,
339                  * both functions should behave the same (except for some loss in
340                  * precision, e.g. when formatting datetime values) */
341                 {
342                         { SDB_TYPE_INTEGER, { .integer = 47 } },
343                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
344                         -1,
345                 },
346                 {
347                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
348                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
349                         0,
350                 },
351                 {
352                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
353                         { SDB_TYPE_INTEGER, { .integer = 47 } },
354                         1,
355                 },
356                 {
357                         { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
358                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
359                         -1,
360                 },
361                 {
362                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
363                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
364                         0,
365                 },
366                 {
367                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
368                         { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
369                         1,
370                 },
371                 {
372                         { SDB_TYPE_STRING, { .string = NULL } },
373                         { SDB_TYPE_STRING, { .string = "" } },
374                         -1,
375                 },
376                 {
377                         { SDB_TYPE_STRING, { .string = NULL } },
378                         { SDB_TYPE_STRING, { .string = NULL } },
379                         0,
380                 },
381                 {
382                         { SDB_TYPE_STRING, { .string = "" } },
383                         { SDB_TYPE_STRING, { .string = NULL } },
384                         1,
385                 },
386                 {
387                         { SDB_TYPE_STRING, { .string = "a" } },
388                         { SDB_TYPE_STRING, { .string = "b" } },
389                         -1,
390                 },
391                 {
392                         { SDB_TYPE_STRING, { .string = "a" } },
393                         { SDB_TYPE_STRING, { .string = "ab" } },
394                         -1,
395                 },
396                 {
397                         { SDB_TYPE_STRING, { .string = "a" } },
398                         { SDB_TYPE_STRING, { .string = "a" } },
399                         0,
400                 },
401                 {
402                         { SDB_TYPE_STRING, { .string = "b" } },
403                         { SDB_TYPE_STRING, { .string = "a" } },
404                         1,
405                 },
406                 {
407                         { SDB_TYPE_STRING, { .string = "ab" } },
408                         { SDB_TYPE_STRING, { .string = "a" } },
409                         1,
410                 },
411                 {
412                         { SDB_TYPE_DATETIME, { .datetime = 471047114711471100 } },
413                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
414                         -1,
415                 },
416                 {
417                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
418                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
419                         0,
420                 },
421                 {
422                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
423                         { SDB_TYPE_DATETIME, { .datetime = 471047114711471100 } },
424                         1,
425                 },
426                 {
427                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
428                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
429                         -1,
430                 },
431                 {
432                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
433                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
434                         0,
435                 },
436                 {
437                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
438                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
439                         1,
440                 },
441                 {
442                         {
443                                 SDB_TYPE_BINARY,
444                                 { .binary = { 3, (unsigned char *)"a\0a" } },
445                         },
446                         {
447                                 SDB_TYPE_BINARY,
448                                 { .binary = { 3, (unsigned char *)"a\0b" } },
449                         },
450                         -1,
451                 },
452                 {
453                         {
454                                 SDB_TYPE_BINARY,
455                                 { .binary = { 1, (unsigned char *)"a" } },
456                         },
457                         {
458                                 SDB_TYPE_BINARY,
459                                 { .binary = { 3, (unsigned char *)"a\0\0" } },
460                         },
461                         -1,
462                 },
463                 {
464                         {
465                                 SDB_TYPE_BINARY,
466                                 { .binary = { 3, (unsigned char *)"a\0a" } },
467                         },
468                         {
469                                 SDB_TYPE_BINARY,
470                                 { .binary = { 3, (unsigned char *)"a\0a" } },
471                         },
472                         0,
473                 },
474                 {
475                         {
476                                 SDB_TYPE_BINARY,
477                                 { .binary = { 3, (unsigned char *)"a\0b" } },
478                         },
479                         {
480                                 SDB_TYPE_BINARY,
481                                 { .binary = { 3, (unsigned char *)"a\0a" } },
482                         },
483                         1,
484                 },
485                 {
486                         {
487                                 SDB_TYPE_BINARY,
488                                 { .binary = { 3, (unsigned char *)"a\0\0" } },
489                         },
490                         {
491                                 SDB_TYPE_BINARY,
492                                 { .binary = { 1, (unsigned char *)"a" } },
493                         },
494                         1,
495                 },
496                 /* type mismatches */
497                 {
498                         { SDB_TYPE_INTEGER, { .integer = 123 } },
499                         { SDB_TYPE_STRING, { .string = "123" } },
500                         0,
501                 },
502                 {
503                         { SDB_TYPE_INTEGER, { .integer = 120 } },
504                         { SDB_TYPE_STRING, { .string = "123" } },
505                         -1,
506                 },
507                 {
508                         { SDB_TYPE_STRING, { .string = "123" } },
509                         { SDB_TYPE_INTEGER, { .integer = 120 } },
510                         1,
511                 },
512                 {
513                         { SDB_TYPE_STRING, { .string = "12.3" } },
514                         { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
515                         0,
516                 },
517                 {
518                         { SDB_TYPE_STRING, { .string = "12.0" } },
519                         { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
520                         -1,
521                 },
522                 {
523                         { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
524                         { SDB_TYPE_STRING, { .string = "12.0" } },
525                         1,
526                 },
527         };
529         size_t i;
531         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
532                 int check = sdb_data_strcmp(&golden_data[i].d1, &golden_data[i].d2);
533                 check = check < 0 ? -1 : check > 0 ? 1 : 0;
534                 if (check != golden_data[i].expected) {
535                         char d1_str[64] = "", d2_str[64] = "";
536                         sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
537                                         SDB_DOUBLE_QUOTED);
538                         sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
539                                         SDB_DOUBLE_QUOTED);
540                         fail("sdb_data_strcmp(%s, %s) = %d; expected: %d",
541                                         d1_str, d2_str, check, golden_data[i].expected);
542                 }
543         }
545 END_TEST
547 START_TEST(test_expr_eval)
549         struct {
550                 sdb_data_t d1;
551                 sdb_data_t d2;
552                 sdb_data_t expected_add;
553                 sdb_data_t expected_sub;
554                 sdb_data_t expected_mul;
555                 sdb_data_t expected_div;
556                 sdb_data_t expected_mod;
557                 sdb_data_t expected_concat;
558         } golden_data[] = {
559                 {
560                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
561                         { SDB_TYPE_INTEGER, { .integer = 47 } },
562                         { SDB_TYPE_INTEGER, { .integer = 4758 } },
563                         { SDB_TYPE_INTEGER, { .integer = 4664 } },
564                         { SDB_TYPE_INTEGER, { .integer = 221417 } },
565                         { SDB_TYPE_INTEGER, { .integer = 100 } },
566                         { SDB_TYPE_INTEGER, { .integer = 11 } },
567                         SDB_DATA_INIT,
568                 },
569                 {
570                         { SDB_TYPE_DECIMAL, { .decimal = 35.0 } },
571                         { SDB_TYPE_DECIMAL, { .decimal = 17.5 } },
572                         { SDB_TYPE_DECIMAL, { .decimal = 52.5 } },
573                         { SDB_TYPE_DECIMAL, { .decimal = 17.5 } },
574                         { SDB_TYPE_DECIMAL, { .decimal = 612.5 } },
575                         { SDB_TYPE_DECIMAL, { .decimal = 2.0 } },
576                         { SDB_TYPE_DECIMAL, { .decimal = 0.0 } },
577                         SDB_DATA_INIT,
578                 },
579                 {
580                         { SDB_TYPE_STRING, { .string = NULL } },
581                         { SDB_TYPE_STRING, { .string = "" } },
582                         SDB_DATA_INIT,
583                         SDB_DATA_INIT,
584                         SDB_DATA_INIT,
585                         SDB_DATA_INIT,
586                         SDB_DATA_INIT,
587                         { SDB_TYPE_STRING, { .string = "" } },
588                 },
589                 {
590                         { SDB_TYPE_STRING, { .string = NULL } },
591                         { SDB_TYPE_STRING, { .string = NULL } },
592                         SDB_DATA_INIT,
593                         SDB_DATA_INIT,
594                         SDB_DATA_INIT,
595                         SDB_DATA_INIT,
596                         SDB_DATA_INIT,
597                         { SDB_TYPE_STRING, { .string = NULL } },
598                 },
599                 {
600                         { SDB_TYPE_STRING, { .string = "" } },
601                         { SDB_TYPE_STRING, { .string = NULL } },
602                         SDB_DATA_INIT,
603                         SDB_DATA_INIT,
604                         SDB_DATA_INIT,
605                         SDB_DATA_INIT,
606                         SDB_DATA_INIT,
607                         { SDB_TYPE_STRING, { .string = "" } },
608                 },
609                 {
610                         { SDB_TYPE_STRING, { .string = "a" } },
611                         { SDB_TYPE_STRING, { .string = "b" } },
612                         SDB_DATA_INIT,
613                         SDB_DATA_INIT,
614                         SDB_DATA_INIT,
615                         SDB_DATA_INIT,
616                         SDB_DATA_INIT,
617                         { SDB_TYPE_STRING, { .string = "ab" } },
618                 },
619                 {
620                         { SDB_TYPE_DATETIME, { .datetime = 47114711 } },
621                         { SDB_TYPE_DATETIME, { .datetime = 4711 } },
622                         { SDB_TYPE_DATETIME, { .datetime = 47119422 } },
623                         { SDB_TYPE_DATETIME, { .datetime = 47110000 } },
624                         { SDB_TYPE_DATETIME, { .datetime = 221957403521 } },
625                         { SDB_TYPE_DATETIME, { .datetime = 10001 } },
626                         { SDB_TYPE_DATETIME, { .datetime = 0 } },
627                         SDB_DATA_INIT,
628                 },
629                 {
630                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
631                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
632                         SDB_DATA_INIT,
633                         SDB_DATA_INIT,
634                         SDB_DATA_INIT,
635                         SDB_DATA_INIT,
636                         SDB_DATA_INIT,
637                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
638                 },
639                 {
640                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
641                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
642                         SDB_DATA_INIT,
643                         SDB_DATA_INIT,
644                         SDB_DATA_INIT,
645                         SDB_DATA_INIT,
646                         SDB_DATA_INIT,
647                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
648                 },
649                 {
650                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
651                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
652                         SDB_DATA_INIT,
653                         SDB_DATA_INIT,
654                         SDB_DATA_INIT,
655                         SDB_DATA_INIT,
656                         SDB_DATA_INIT,
657                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
658                 },
659                 {
660                         {
661                                 SDB_TYPE_BINARY,
662                                 { .binary = { 3, (unsigned char *)"a\0a" } },
663                         },
664                         {
665                                 SDB_TYPE_BINARY,
666                                 { .binary = { 3, (unsigned char *)"b\0b" } },
667                         },
668                         SDB_DATA_INIT,
669                         SDB_DATA_INIT,
670                         SDB_DATA_INIT,
671                         SDB_DATA_INIT,
672                         SDB_DATA_INIT,
673                         {
674                                 SDB_TYPE_BINARY,
675                                 { .binary = { 6, (unsigned char *)"a\0ab\0b" } },
676                         },
677                 },
678                 /* supported type-mismatches */
679                 {
680                         /* int * datetime */
681                         { SDB_TYPE_INTEGER,  { .integer  = 20 } },
682                         { SDB_TYPE_DATETIME, { .datetime = 2 } },
683                         SDB_DATA_INIT,
684                         SDB_DATA_INIT,
685                         { SDB_TYPE_DATETIME, { .datetime = 40 } },
686                         SDB_DATA_INIT,
687                         SDB_DATA_INIT,
688                         SDB_DATA_INIT,
689                 },
690                 {
691                         /* datetime * int, datetime / int, datetime % int */
692                         { SDB_TYPE_DATETIME, { .datetime = 20 } },
693                         { SDB_TYPE_INTEGER,  { .integer  = 2 } },
694                         SDB_DATA_INIT,
695                         SDB_DATA_INIT,
696                         { SDB_TYPE_DATETIME, { .datetime = 40 } },
697                         { SDB_TYPE_DATETIME, { .datetime = 10 } },
698                         { SDB_TYPE_DATETIME, { .datetime = 0 } },
699                         SDB_DATA_INIT,
700                 },
701                 {
702                         /* float * datetime */
703                         { SDB_TYPE_DECIMAL,  { .decimal  = 20.0 } },
704                         { SDB_TYPE_DATETIME, { .datetime = 2 } },
705                         SDB_DATA_INIT,
706                         SDB_DATA_INIT,
707                         { SDB_TYPE_DATETIME, { .datetime = 40 } },
708                         SDB_DATA_INIT,
709                         SDB_DATA_INIT,
710                         SDB_DATA_INIT,
711                 },
712                 {
713                         /* datetime * float, datetime / float, datetime % float */
714                         { SDB_TYPE_DATETIME, { .datetime = 20 } },
715                         { SDB_TYPE_DECIMAL,  { .decimal  = 2.0 } },
716                         SDB_DATA_INIT,
717                         SDB_DATA_INIT,
718                         { SDB_TYPE_DATETIME, { .datetime = 40 } },
719                         { SDB_TYPE_DATETIME, { .datetime = 10 } },
720                         { SDB_TYPE_DATETIME, { .datetime = 0 } },
721                         SDB_DATA_INIT,
722                 },
723         };
725         size_t i;
727         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
728                 struct {
729                         int op;
730                         sdb_data_t expected;
731                 } tests[] = {
732                         { SDB_DATA_ADD, golden_data[i].expected_add },
733                         { SDB_DATA_SUB, golden_data[i].expected_sub },
734                         { SDB_DATA_MUL, golden_data[i].expected_mul },
735                         { SDB_DATA_DIV, golden_data[i].expected_div },
736                         { SDB_DATA_MOD, golden_data[i].expected_mod },
737                         { SDB_DATA_CONCAT, golden_data[i].expected_concat },
738                 };
740                 size_t j;
741                 for (j = 0; j < SDB_STATIC_ARRAY_LEN(tests); ++j) {
742                         sdb_data_t res;
743                         int check;
745                         char d1_str[64] = "", d2_str[64] = "";
746                         sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
747                                         SDB_DOUBLE_QUOTED);
748                         sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
749                                         SDB_DOUBLE_QUOTED);
751                         check = sdb_data_expr_eval(tests[j].op,
752                                         &golden_data[i].d1, &golden_data[i].d2, &res);
753                         fail_unless((check == 0) == (tests[j].expected.type != 0),
754                                         "sdb_data_expr_eval(%s, %s, %s) = %d; expected: %d",
755                                         SDB_DATA_OP_TO_STRING(tests[j].op), d1_str, d2_str, check,
756                                         tests[j].expected.type == 0 ? -1 : 0);
757                         if (tests[j].expected.type == 0)
758                                 continue;
760                         check = sdb_data_cmp(&res, &tests[j].expected);
761                         if (check != 0) {
762                                 char res_str[64] = "", expected_str[64] = "";
763                                 sdb_data_format(&res, res_str, sizeof(res_str),
764                                                 SDB_DOUBLE_QUOTED);
765                                 sdb_data_format(&tests[j].expected, expected_str,
766                                                 sizeof(expected_str), SDB_DOUBLE_QUOTED);
767                                 fail("sdb_data_expr_eval(%s, %s, %s) evaluated to %s; "
768                                                 "expected: %s", SDB_DATA_OP_TO_STRING(tests[j].op),
769                                                 d1_str, d2_str, res_str, expected_str);
770                         }
772                         sdb_data_free_datum(&res);
773                 }
774         }
776 END_TEST
778 START_TEST(test_format)
780         struct {
781                 sdb_data_t datum;
782                 const char *expected;
783         } golden_data[] = {
784                 {
785                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
786                         "4711",
787                 },
788                 {
789                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
790                         "65536",
791                 },
792                 {
793                         { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
794                         "12.3",
795                 },
796                 {
797                         { SDB_TYPE_STRING, { .string = NULL } },
798                         "\"<NULL>\"",
799                 },
800                 {
801                         { SDB_TYPE_STRING, { .string = "this is a test" } },
802                         "\"this is a test\"",
803                 },
804                 {
805                         { SDB_TYPE_STRING, { .string = "special \\ \" characters" } },
806                         "\"special \\\\ \\\" characters\"",
807                 },
808                 {
809                         { SDB_TYPE_DATETIME, { .datetime= 471147114711471100 } },
810                         "\"1984-12-06 02:11:54 +0000\"",
811                 },
812                 {
813                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
814                         "\"<NULL>\"",
815                 },
816                 {
817                         {
818                                 SDB_TYPE_BINARY,
819                                 { .binary = { 12, (unsigned char *)"binary\0crap\x42" } },
820                         },
821                         "\"\\x62\\x69\\x6e\\x61\\x72\\x79\\x0\\x63\\x72\\x61\\x70\\x42\"",
822                 },
823         };
825         size_t i;
827         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
828                 sdb_data_t *datum = &golden_data[i].datum;
829                 char buf[sdb_data_strlen(datum) + 2];
830                 int check;
832                 memset(buf, (int)'A', sizeof(buf));
834                 check = sdb_data_format(datum, buf, sizeof(buf) - 1,
835                                 SDB_DOUBLE_QUOTED);
836                 fail_unless(check > 0,
837                                 "sdb_data_format(type=%s) = %d; expected: >0",
838                                 SDB_TYPE_TO_STRING(datum->type), check);
839                 fail_unless(! strcmp(buf, golden_data[i].expected),
840                                 "sdb_data_format(type=%s) used wrong format: %s; expected: %s",
841                                 SDB_TYPE_TO_STRING(datum->type), buf, golden_data[i].expected);
843                 fail_unless((size_t)check <= sizeof(buf) - 2,
844                                 "sdb_data_format(type=%s) wrote %d bytes; "
845                                 "expected <= %zu based on sdb_data_strlen()",
846                                 SDB_TYPE_TO_STRING(datum->type), check, sizeof(buf) - 2);
848                 fail_unless(buf[sizeof(buf) - 2] == '\0',
849                                 "sdb_data_format(type=%s) did not nul-terminate the buffer",
850                                 SDB_TYPE_TO_STRING(datum->type));
851                 fail_unless(buf[sizeof(buf) - 1] == 'A',
852                                 "sdb_data_format(type=%s) wrote past the end of the buffer",
853                                 SDB_TYPE_TO_STRING(datum->type));
854         }
856 END_TEST
858 START_TEST(test_parse)
860         struct {
861                 char *input;
862                 sdb_data_t result;
863                 int expected;
864         } golden_data[] = {
865                 { "4711",    { SDB_TYPE_INTEGER,  { .integer  = 4711 } },       0 },
866                 { "0x10",    { SDB_TYPE_INTEGER,  { .integer  = 16 } },         0 },
867                 { "010",     { SDB_TYPE_INTEGER,  { .integer  = 8 } },          0 },
868                 { "abc",     { SDB_TYPE_INTEGER,  { .integer  = 0 } },         -1 },
869                 { "1.2",     { SDB_TYPE_DECIMAL,  { .decimal  = 1.2 } },        0 },
870                 { "0x1p+16", { SDB_TYPE_DECIMAL,  { .decimal  = 65536.0 } },    0 },
871                 { "abc",     { SDB_TYPE_DECIMAL,  { .decimal  = 0.0 } },       -1 },
872                 { "abc",     { SDB_TYPE_STRING,   { .string   = "abc" } },      0 },
873                 { ".4",      { SDB_TYPE_DATETIME, { .datetime = 400000000 } },  0 },
874                 { "abc",     { SDB_TYPE_DATETIME, { .datetime = 0 } },         -1 },
875                 { "abc",     { SDB_TYPE_BINARY,
876                                          { .binary = { 3, (unsigned char *)"abc" } } }, 0 },
877         };
879         size_t i;
881         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
882                 sdb_data_t result;
883                 int type, check;
885                 memset(&result, 0, sizeof(result));
886                 type = golden_data[i].result.type;
887                 check = sdb_data_parse(golden_data[i].input, type, &result);
888                 fail_unless(check == golden_data[i].expected,
889                                 "sdb_data_parse(%s, %d, <d>) = %d; expected: %d",
890                                 golden_data[i].input, type, check, golden_data[i].expected);
892                 if (check)
893                         continue;
895                 fail_unless(sdb_data_cmp(&result, &golden_data[i].result) == 0,
896                                 "sdb_data_parse(%s, %d, <d>) did not create expected result",
897                                 golden_data[i].input, type);
899                 if (type == SDB_TYPE_STRING)
900                         fail_unless(golden_data[i].input == result.data.string,
901                                         "sdb_data_parse(%s, %d, <d>) modified input string",
902                                         golden_data[i].input, type);
903                 if (type == SDB_TYPE_BINARY)
904                         fail_unless(golden_data[i].input == (char *)result.data.binary.datum,
905                                         "sdb_data_parse(%s, %d, <d>) modified input string",
906                                         golden_data[i].input, type);
907         }
909 END_TEST
911 Suite *
912 core_data_suite(void)
914         Suite *s = suite_create("core::data");
915         TCase *tc;
917         tc = tcase_create("core");
918         tcase_add_test(tc, test_data);
919         tcase_add_test(tc, test_cmp);
920         tcase_add_test(tc, test_strcmp);
921         tcase_add_test(tc, test_expr_eval);
922         tcase_add_test(tc, test_format);
923         tcase_add_test(tc, test_parse);
924         suite_add_tcase(s, tc);
926         return s;
927 } /* core_data_suite */
929 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */