diff options
author | Thomas Voss <mail@thomasvoss.com> | 2024-05-15 00:43:54 +0200 |
---|---|---|
committer | Thomas Voss <mail@thomasvoss.com> | 2024-05-15 00:45:17 +0200 |
commit | 5498793a56b19da99b7b6856c953933e50b8d572 (patch) | |
tree | 708166215910ef89e9d4133a805f6e12b3ba4ab3 /test/_norm-test.h | |
parent | d7ba894d2af0e0c5a8d5db9cbadd7ea9a277100b (diff) |
Add ucsnorm_nfkd()
Diffstat (limited to 'test/_norm-test.h')
-rw-r--r-- | test/_norm-test.h | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/test/_norm-test.h b/test/_norm-test.h new file mode 100644 index 0000000..68209f1 --- /dev/null +++ b/test/_norm-test.h @@ -0,0 +1,107 @@ +#if !defined(NORMTYPE) +# error "NORMTYPE must be defined" +#endif + +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> + +#include <alloc.h> +#include <dynarr.h> +#include <errors.h> +#include <macros.h> +#include <mbstring.h> +#include <rune.h> +#include <unicode/string.h> + +#define TESTFILE "norm.in" +#define FUNC CONCAT(ucsnorm_, NORMTYPE) + +static bool test(struct u8view, int); + +int +main(int, char **argv) +{ + int rv; + size_t n; + ssize_t nr; + char *line; + FILE *fp; + + rv = EXIT_SUCCESS; + line = nullptr; + mlib_setprogname(argv[0]); + + if ((fp = fopen(TESTFILE, "r")) == nullptr) + err("fopen: %s:", TESTFILE); + + for (int id = 1; (nr = getline(&line, &n, fp)) > 0; id++) { + if (line[nr - 1] == '\n') + line[--nr] = '\0'; + + if (!test((struct u8view){line, (size_t)nr}, id)) { + rv = EXIT_FAILURE; + break; + } + } + if (ferror(fp)) + err("getline: %s:", TESTFILE); + + free(line); + fclose(fp); + return rv; +} + +bool +test(struct u8view sv, int id) +{ + bool rv = true; + arena a = mkarena(0); + struct arena_ctx ctx = {.a = &a}; + + dynarr(struct u8view) columns = { + .alloc = alloc_arena, + .ctx = &ctx, + }; + + struct u8view column; + while (ucscut(&column, &sv, U";", 1) != MBEND) { + dynarr(char8_t) s = { + .alloc = alloc_arena, + .ctx = &ctx, + }; + + rune _; + struct u8view cp; + do { + rune ch; + _ = ucscut(&cp, &column, U" ", 1); + sscanf(cp.p, "%" SCNxRUNE, &ch); + char8_t buf[U8_LEN_MAX]; + int w = rtoucs(buf, sizeof(buf), ch); + DAEXTEND(&s, buf, w); + } while (_ != MBEND); + + DAPUSH(&columns, ((struct u8view){s.buf, s.len})); + } + + for (size_t i = 0; i < 5; i++) { + size_t base; + if (streq(STR(NORMTYPE), "nfkd")) + base = 4; + else + base = i < 3 ? 2 : 4; + struct u8view normd = {}; + normd.p = FUNC(&normd.len, columns.buf[i], alloc_arena, &ctx); + if (!ucseq(columns.buf[base], normd)) { + warn("case %d: expected c%zu to be ā%.*sā but got ā%.*sā", id, + i + 1, SV_PRI_ARGS(columns.buf[base]), SV_PRI_ARGS(normd)); + rv = false; + goto out; + } + } + +out: + arena_free(&a); + return rv; +} |