Mercurial > libjeffpc
changeset 665:590bbd1d3fe5
int: add basic tests for __str2uXX and str2uXX functions
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Fri, 08 Feb 2019 17:21:55 -0500 |
parents | da3cc572a748 |
children | 7590cd6dee22 |
files | tests/.hgignore tests/CMakeLists.txt tests/test_str2uint.c |
diffstat | 3 files changed, 231 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/tests/.hgignore Wed Feb 13 10:23:49 2019 -0500 +++ b/tests/.hgignore Fri Feb 08 17:21:55 2019 -0500 @@ -37,6 +37,7 @@ test_sexpr_parser test_sexpr_eval test_sexpr_iter +test_str2uint test_tree_bst test_tree_rb test_urldecode
--- a/tests/CMakeLists.txt Wed Feb 13 10:23:49 2019 -0500 +++ b/tests/CMakeLists.txt Fri Feb 08 17:21:55 2019 -0500 @@ -63,6 +63,7 @@ build_test_bin_and_run(padding) build_test_bin_and_run(sexpr_eval) build_test_bin_and_run(sexpr_iter) +build_test_bin_and_run(str2uint) build_test_bin_and_run(tree_bst) build_test_bin_and_run(tree_rb) build_test_bin_and_run(urldecode)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test_str2uint.c Fri Feb 08 17:21:55 2019 -0500 @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2019 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <jeffpc/int.h> +#include <jeffpc/types.h> +#include <jeffpc/error.h> + +#include "test.c" + +struct res { + int ret; + uint64_t out; +}; + +struct run { + const char *in; + struct res out[3][3]; /* out[base][size] */ +}; + +#define B8 0 +#define B10 1 +#define B16 2 + +static const int bases[] = { + [B8] = 8, + [B10] = 10, + [B16] = 16, +}; + +#define SZ16 0 +#define SZ32 1 +#define SZ64 2 + +static const int sizes[] = { + [SZ16] = 16, + [SZ32] = 32, + [SZ64] = 64, +}; + +#define ENT(v_s16, v_s32, v_s64, r_s16, r_s32, r_s64) \ + { \ + [SZ16] = { .ret = (r_s16), .out = (v_s16), }, \ + [SZ32] = { .ret = (r_s32), .out = (v_s32), }, \ + [SZ64] = { .ret = (r_s64), .out = (v_s64), }, \ + } + +static const struct run runs[] = { + { + .in = "", + .out[B8] = ENT(0, 0, 0, -EINVAL, -EINVAL, -EINVAL), + .out[B10] = ENT(0, 0, 0, -EINVAL, -EINVAL, -EINVAL), + .out[B16] = ENT(0, 0, 0, -EINVAL, -EINVAL, -EINVAL), + }, + { + .in = "0", + .out[B8] = ENT(0, 0, 0, 0, 0, 0), + .out[B10] = ENT(0, 0, 0, 0, 0, 0), + .out[B16] = ENT(0, 0, 0, 0, 0, 0), + }, + { + .in = "00", + .out[B8] = ENT(0, 0, 0, 0, 0, 0), + .out[B10] = ENT(0, 0, 0, 0, 0, 0), + .out[B16] = ENT(0, 0, 0, 0, 0, 0), + }, + { + .in = "0x0", + /* FIXME: base 8 & 10 should return -EINVAL */ + .out[B8] = ENT(0, 0, 0, 0, 0, 0), + .out[B10] = ENT(0, 0, 0, 0, 0, 0), + .out[B16] = ENT(0, 0, 0, 0, 0, 0), + }, + { + .in = "5", + .out[B8] = ENT(5, 5, 5, 0, 0, 0), + .out[B10] = ENT(5, 5, 5, 0, 0, 0), + .out[B16] = ENT(5, 5, 5, 0, 0, 0), + }, + { + .in = "8", + .out[B8] = ENT(0, 0, 0, -EINVAL, -EINVAL, -EINVAL), + .out[B10] = ENT(8, 8, 8, 0, 0, 0), + .out[B16] = ENT(8, 8, 8, 0, 0, 0), + }, + { + .in = "0x8", + /* FIXME: base 8 & 10 should return -EINVAL */ + .out[B8] = ENT(0, 0, 0, 0, 0, 0), + .out[B10] = ENT(0, 0, 0, 0, 0, 0), + .out[B16] = ENT(8, 8, 8, 0, 0, 0), + }, + { + .in = "A", + .out[B8] = ENT(0, 0, 0, -EINVAL, -EINVAL, -EINVAL), + .out[B10] = ENT(0, 0, 0, -EINVAL, -EINVAL, -EINVAL), + .out[B16] = ENT(0xa, 0xa, 0xa, 0, 0, 0), + }, + { + .in = "a", + .out[B8] = ENT(0, 0, 0, -EINVAL, -EINVAL, -EINVAL), + .out[B10] = ENT(0, 0, 0, -EINVAL, -EINVAL, -EINVAL), + .out[B16] = ENT(0xa, 0xa, 0xa, 0, 0, 0), + }, + { + .in = "0XA", + /* FIXME: base 8 & 10 should return -EINVAL */ + .out[B8] = ENT(0, 0, 0, 0, 0, 0), + .out[B10] = ENT(0, 0, 0, 0, 0, 0), + .out[B16] = ENT(0xa, 0xa, 0xa, 0, 0, 0), + }, + { + .in = "0Xa", + /* FIXME: base 8 & 10 should return -EINVAL */ + .out[B8] = ENT(0, 0, 0, 0, 0, 0), + .out[B10] = ENT(0, 0, 0, 0, 0, 0), + .out[B16] = ENT(0xa, 0xa, 0xa, 0, 0, 0), + }, + { + .in = "0xA", + /* FIXME: base 8 & 10 should return -EINVAL */ + .out[B8] = ENT(0, 0, 0, 0, 0, 0), + .out[B10] = ENT(0, 0, 0, 0, 0, 0), + .out[B16] = ENT(0xa, 0xa, 0xa, 0, 0, 0), + }, + { + .in = "0xa", + /* FIXME: base 8 & 10 should return -EINVAL */ + .out[B8] = ENT(0, 0, 0, 0, 0, 0), + .out[B10] = ENT(0, 0, 0, 0, 0, 0), + .out[B16] = ENT(0xa, 0xa, 0xa, 0, 0, 0), + }, + /* + * FIXME: more test cases + * - check values > max for type + * - check inputs starting with '-' ? + * - check inputs with leading garbage + * - check inputs with trailing garbage + */ +}; + +#define TEST(i, bidx, szidx, expr, type) \ + do { \ + const char *in = runs[i].in; \ + const struct res *res = &runs[i].out[bidx][szidx]; \ + const int base = bases[bidx]; \ + const int size = sizes[szidx]; \ + type tmp; \ + uint64_t out; \ + int ret; \ + \ + fprintf(stderr, "%2d: ... %s -> ", (i), #expr); \ + \ + ret = (expr); \ + out = tmp; \ + \ + /* print the result we got */ \ + if (ret) { \ + fprintf(stderr, "ret=%d", ret); \ + } else { \ + static const char *fmts[] = { \ + [B8] = "%#0*"PRIo64, \ + [B10] = "%#0*"PRIu64, \ + [B16] = "%#0*"PRIx64, \ + }; \ + int width = 2 * size / 8; \ + \ + if (base == 8) \ + width++; /* extra leading 0 */ \ + else if (base == 16) \ + width += 2; /* leading 0x */ \ + \ + fprintf(stderr, "out="); \ + fprintf(stderr, fmts[bidx], width, out); \ + } \ + fprintf(stderr, "..."); \ + \ + check_rets(res->ret, ret, "__str2u%d", base); \ + \ + if (!ret) \ + ASSERT3U(out, ==, res->out); \ + \ + fprintf(stderr, "ok.\n"); \ + } while (0) + +void test(void) +{ + int i; + + for (i = 0; i < ARRAY_LEN(runs); i++) { + fprintf(stderr, "%2d: in='%s'...\n", i, runs[i].in); + + /* test simple base 10 parsing */ + TEST(i, B10, SZ16, str2u16(in, &tmp), uint16_t); + TEST(i, B10, SZ32, str2u32(in, &tmp), uint32_t); + TEST(i, B10, SZ64, str2u64(in, &tmp), uint64_t); + + /* test underlying function with all bases */ + TEST(i, B8, SZ16, __str2u16(in, &tmp, 8), uint16_t); + TEST(i, B8, SZ32, __str2u32(in, &tmp, 8), uint32_t); + TEST(i, B8, SZ64, __str2u64(in, &tmp, 8), uint64_t); + + TEST(i, B10, SZ16, __str2u16(in, &tmp, 10), uint16_t); + TEST(i, B10, SZ32, __str2u32(in, &tmp, 10), uint32_t); + TEST(i, B10, SZ64, __str2u64(in, &tmp, 10), uint64_t); + + TEST(i, B16, SZ16, __str2u16(in, &tmp, 16), uint16_t); + TEST(i, B16, SZ32, __str2u32(in, &tmp, 16), uint32_t); + TEST(i, B16, SZ64, __str2u64(in, &tmp, 16), uint64_t); + } +}