12944fceb147a13acfd3b7e0f073253a5cf4c89f
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");
108 }
109 END_TEST
111 START_TEST(test_cmp)
112 {
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 }
324 }
325 END_TEST
327 START_TEST(test_strcmp)
328 {
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 }
506 }
507 END_TEST
509 START_TEST(test_expr_eval)
510 {
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 }
737 }
738 END_TEST
740 START_TEST(test_format)
741 {
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 }
817 }
818 END_TEST
820 START_TEST(test_parse)
821 {
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 }
870 }
871 END_TEST
873 Suite *
874 core_data_suite(void)
875 {
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 : */