9d52d2279f2622fdf845999a9de5bc0a22fa3b0a
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");
146 }
147 END_TEST
149 START_TEST(test_cmp)
150 {
151 struct {
152 sdb_data_t d1;
153 sdb_data_t d2;
154 int expected;
155 } golden_data[] = {
156 /* same data as for the sdb_data_cmp test; in case the types match,
157 * both functions should behave the same (except for some loss in
158 * precision, e.g. when formatting datetime values) */
159 {
160 { SDB_TYPE_INTEGER, { .integer = 47 } },
161 { SDB_TYPE_INTEGER, { .integer = 4711 } },
162 -1,
163 },
164 {
165 { SDB_TYPE_INTEGER, { .integer = 4711 } },
166 { SDB_TYPE_INTEGER, { .integer = 4711 } },
167 0,
168 },
169 {
170 { SDB_TYPE_INTEGER, { .integer = 4711 } },
171 { SDB_TYPE_INTEGER, { .integer = 47 } },
172 1,
173 },
174 {
175 { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
176 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
177 -1,
178 },
179 {
180 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
181 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
182 0,
183 },
184 {
185 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
186 { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
187 1,
188 },
189 {
190 { SDB_TYPE_STRING, { .string = NULL } },
191 { SDB_TYPE_STRING, { .string = "" } },
192 -1,
193 },
194 {
195 { SDB_TYPE_STRING, { .string = NULL } },
196 { SDB_TYPE_STRING, { .string = NULL } },
197 0,
198 },
199 {
200 { SDB_TYPE_STRING, { .string = "" } },
201 { SDB_TYPE_STRING, { .string = NULL } },
202 1,
203 },
204 {
205 { SDB_TYPE_STRING, { .string = "a" } },
206 { SDB_TYPE_STRING, { .string = "b" } },
207 -1,
208 },
209 {
210 { SDB_TYPE_STRING, { .string = "a" } },
211 { SDB_TYPE_STRING, { .string = "ab" } },
212 -1,
213 },
214 {
215 { SDB_TYPE_STRING, { .string = "a" } },
216 { SDB_TYPE_STRING, { .string = "a" } },
217 0,
218 },
219 {
220 { SDB_TYPE_STRING, { .string = "b" } },
221 { SDB_TYPE_STRING, { .string = "a" } },
222 1,
223 },
224 {
225 { SDB_TYPE_STRING, { .string = "ab" } },
226 { SDB_TYPE_STRING, { .string = "a" } },
227 1,
228 },
229 {
230 { SDB_TYPE_DATETIME, { .datetime = 471047114711471100 } },
231 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
232 -1,
233 },
234 {
235 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
236 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
237 0,
238 },
239 {
240 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
241 { SDB_TYPE_DATETIME, { .datetime = 471047114711471100 } },
242 1,
243 },
244 {
245 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
246 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
247 -1,
248 },
249 {
250 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
251 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
252 0,
253 },
254 {
255 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
256 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
257 1,
258 },
259 {
260 {
261 SDB_TYPE_BINARY,
262 { .binary = { 3, (unsigned char *)"a\0a" } },
263 },
264 {
265 SDB_TYPE_BINARY,
266 { .binary = { 3, (unsigned char *)"a\0b" } },
267 },
268 -1,
269 },
270 {
271 {
272 SDB_TYPE_BINARY,
273 { .binary = { 1, (unsigned char *)"a" } },
274 },
275 {
276 SDB_TYPE_BINARY,
277 { .binary = { 3, (unsigned char *)"a\0\0" } },
278 },
279 -1,
280 },
281 {
282 {
283 SDB_TYPE_BINARY,
284 { .binary = { 3, (unsigned char *)"a\0a" } },
285 },
286 {
287 SDB_TYPE_BINARY,
288 { .binary = { 3, (unsigned char *)"a\0a" } },
289 },
290 0,
291 },
292 {
293 {
294 SDB_TYPE_BINARY,
295 { .binary = { 3, (unsigned char *)"a\0b" } },
296 },
297 {
298 SDB_TYPE_BINARY,
299 { .binary = { 3, (unsigned char *)"a\0a" } },
300 },
301 1,
302 },
303 {
304 {
305 SDB_TYPE_BINARY,
306 { .binary = { 3, (unsigned char *)"a\0\0" } },
307 },
308 {
309 SDB_TYPE_BINARY,
310 { .binary = { 1, (unsigned char *)"a" } },
311 },
312 1,
313 },
314 /* type mismatches */
315 {
316 { SDB_TYPE_INTEGER, { .integer = 123 } },
317 { SDB_TYPE_STRING, { .string = "123" } },
318 0,
319 },
320 {
321 { SDB_TYPE_INTEGER, { .integer = 120 } },
322 { SDB_TYPE_STRING, { .string = "123" } },
323 -1,
324 },
325 {
326 { SDB_TYPE_STRING, { .string = "123" } },
327 { SDB_TYPE_INTEGER, { .integer = 120 } },
328 1,
329 },
330 {
331 { SDB_TYPE_STRING, { .string = "12.3" } },
332 { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
333 0,
334 },
335 {
336 { SDB_TYPE_STRING, { .string = "12.0" } },
337 { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
338 -1,
339 },
340 {
341 { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
342 { SDB_TYPE_STRING, { .string = "12.0" } },
343 1,
344 },
345 };
347 size_t i;
349 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
350 int check = sdb_data_strcmp(&golden_data[i].d1, &golden_data[i].d2);
351 check = check < 0 ? -1 : check > 0 ? 1 : 0;
352 if (check != golden_data[i].expected) {
353 char d1_str[64] = "", d2_str[64] = "";
354 sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
355 SDB_DOUBLE_QUOTED);
356 sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
357 SDB_DOUBLE_QUOTED);
358 fail("sdb_data_strcmp(%s, %s) = %d; expected: %d",
359 d1_str, d2_str, check, golden_data[i].expected);
360 }
361 }
362 }
363 END_TEST
365 START_TEST(test_strcmp)
366 {
367 struct {
368 sdb_data_t d1;
369 sdb_data_t d2;
370 int expected;
371 } golden_data[] = {
372 {
373 { SDB_TYPE_INTEGER, { .integer = 47 } },
374 { SDB_TYPE_INTEGER, { .integer = 4711 } },
375 -1,
376 },
377 {
378 { SDB_TYPE_INTEGER, { .integer = 4711 } },
379 { SDB_TYPE_INTEGER, { .integer = 4711 } },
380 0,
381 },
382 {
383 { SDB_TYPE_INTEGER, { .integer = 4711 } },
384 { SDB_TYPE_INTEGER, { .integer = 47 } },
385 1,
386 },
387 {
388 { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
389 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
390 -1,
391 },
392 {
393 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
394 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
395 0,
396 },
397 {
398 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
399 { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
400 1,
401 },
402 {
403 { SDB_TYPE_STRING, { .string = NULL } },
404 { SDB_TYPE_STRING, { .string = "" } },
405 -1,
406 },
407 {
408 { SDB_TYPE_STRING, { .string = NULL } },
409 { SDB_TYPE_STRING, { .string = NULL } },
410 0,
411 },
412 {
413 { SDB_TYPE_STRING, { .string = "" } },
414 { SDB_TYPE_STRING, { .string = NULL } },
415 1,
416 },
417 {
418 { SDB_TYPE_STRING, { .string = "a" } },
419 { SDB_TYPE_STRING, { .string = "b" } },
420 -1,
421 },
422 {
423 { SDB_TYPE_STRING, { .string = "a" } },
424 { SDB_TYPE_STRING, { .string = "ab" } },
425 -1,
426 },
427 {
428 { SDB_TYPE_STRING, { .string = "a" } },
429 { SDB_TYPE_STRING, { .string = "a" } },
430 0,
431 },
432 {
433 { SDB_TYPE_STRING, { .string = "b" } },
434 { SDB_TYPE_STRING, { .string = "a" } },
435 1,
436 },
437 {
438 { SDB_TYPE_STRING, { .string = "ab" } },
439 { SDB_TYPE_STRING, { .string = "a" } },
440 1,
441 },
442 {
443 { SDB_TYPE_DATETIME, { .datetime = 471147114711471000 } },
444 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
445 -1,
446 },
447 {
448 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
449 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
450 0,
451 },
452 {
453 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
454 { SDB_TYPE_DATETIME, { .datetime = 471147114711471000 } },
455 1,
456 },
457 {
458 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
459 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
460 -1,
461 },
462 {
463 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
464 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
465 0,
466 },
467 {
468 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
469 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
470 1,
471 },
472 {
473 {
474 SDB_TYPE_BINARY,
475 { .binary = { 3, (unsigned char *)"a\0a" } },
476 },
477 {
478 SDB_TYPE_BINARY,
479 { .binary = { 3, (unsigned char *)"a\0b" } },
480 },
481 -1,
482 },
483 {
484 {
485 SDB_TYPE_BINARY,
486 { .binary = { 1, (unsigned char *)"a" } },
487 },
488 {
489 SDB_TYPE_BINARY,
490 { .binary = { 3, (unsigned char *)"a\0\0" } },
491 },
492 -1,
493 },
494 {
495 {
496 SDB_TYPE_BINARY,
497 { .binary = { 3, (unsigned char *)"a\0a" } },
498 },
499 {
500 SDB_TYPE_BINARY,
501 { .binary = { 3, (unsigned char *)"a\0a" } },
502 },
503 0,
504 },
505 {
506 {
507 SDB_TYPE_BINARY,
508 { .binary = { 3, (unsigned char *)"a\0b" } },
509 },
510 {
511 SDB_TYPE_BINARY,
512 { .binary = { 3, (unsigned char *)"a\0a" } },
513 },
514 1,
515 },
516 {
517 {
518 SDB_TYPE_BINARY,
519 { .binary = { 3, (unsigned char *)"a\0\0" } },
520 },
521 {
522 SDB_TYPE_BINARY,
523 { .binary = { 1, (unsigned char *)"a" } },
524 },
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_cmp(&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_cmp(%s, %s) = %d; expected: %d",
541 d1_str, d2_str, check, golden_data[i].expected);
542 }
543 }
544 }
545 END_TEST
547 START_TEST(test_expr_eval)
548 {
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 }
775 }
776 END_TEST
778 START_TEST(test_format)
779 {
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 }
855 }
856 END_TEST
858 START_TEST(test_parse)
859 {
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 }
908 }
909 END_TEST
911 Suite *
912 core_data_suite(void)
913 {
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 : */