| /* See LICENSE file for copyright and license details. */ |
| #include <stdbool.h> |
| #include <stddef.h> |
| #include <stdint.h> |
| #include <stdio.h> |
| #include <string.h> |
| |
| #include "../gen/types.h" |
| #include "../grapheme.h" |
| #include "util.h" |
| |
| int |
| run_break_tests(size_t (*next_break)(const uint_least32_t *, size_t), |
| const struct break_test *test, size_t testlen, |
| const char *argv0) |
| { |
| size_t i, j, off, res, failed; |
| |
| /* character break test */ |
| for (i = 0, failed = 0; i < testlen; i++) { |
| for (j = 0, off = 0; off < test[i].cplen; off += res) { |
| res = next_break(test[i].cp + off, test[i].cplen - off); |
| |
| /* check if our resulting offset matches */ |
| if (j == test[i].lenlen || res != test[i].len[j++]) { |
| fprintf(stderr, |
| "%s: Failed conformance test %zu " |
| "\"%s\".\n", |
| argv0, i, test[i].descr); |
| fprintf(stderr, |
| "J=%zu: EXPECTED len %zu, got %zu\n", |
| j - 1, test[i].len[j - 1], res); |
| failed++; |
| break; |
| } |
| } |
| } |
| printf("%s: %zu/%zu conformance tests passed.\n", argv0, |
| testlen - failed, testlen); |
| |
| return (failed > 0) ? 1 : 0; |
| } |
| |
| int |
| run_unit_tests(int (*unit_test_callback)(const void *, size_t, const char *, |
| const char *), |
| const void *test, size_t testlen, const char *name, |
| const char *argv0) |
| { |
| size_t i, failed; |
| |
| for (i = 0, failed = 0; i < testlen; i++) { |
| failed += |
| (unit_test_callback(test, i, name, argv0) == 0) ? 0 : 1; |
| } |
| |
| printf("%s: %s: %zu/%zu unit tests passed.\n", argv0, name, |
| testlen - failed, testlen); |
| |
| return (failed > 0) ? 1 : 0; |
| } |
| |
| int |
| unit_test_callback_next_break(const struct unit_test_next_break *t, size_t off, |
| size_t (*next_break)(const uint_least32_t *, |
| size_t), |
| const char *name, const char *argv0) |
| { |
| const struct unit_test_next_break *test = t + off; |
| |
| size_t ret = next_break(test->input.src, test->input.srclen); |
| |
| if (ret != test->output.ret) { |
| goto err; |
| } |
| |
| return 0; |
| err: |
| fprintf(stderr, |
| "%s: %s: Failed unit test %zu \"%s\" " |
| "(returned %zu instead of %zu).\n", |
| argv0, name, off, test->description, ret, test->output.ret); |
| return 1; |
| } |
| |
| int |
| unit_test_callback_next_break_utf8(const struct unit_test_next_break_utf8 *t, |
| size_t off, |
| size_t (*next_break_utf8)(const char *, |
| size_t), |
| const char *name, const char *argv0) |
| { |
| const struct unit_test_next_break_utf8 *test = t + off; |
| |
| size_t ret = next_break_utf8(test->input.src, test->input.srclen); |
| |
| if (ret != test->output.ret) { |
| goto err; |
| } |
| |
| return 0; |
| err: |
| fprintf(stderr, |
| "%s: %s: Failed unit test %zu \"%s\" " |
| "(returned %zu instead of %zu).\n", |
| argv0, name, off, test->description, ret, test->output.ret); |
| return 1; |
| } |