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