Code

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