Files
2026-07-30 13:18:41 +02:00

159 lines
5.4 KiB
C

#include "../../src/tomlc17.c"
static void failed(const char *msg) {
printf("FAILED: %s\n", msg);
exit(1);
}
#define CHECK(x) \
if (x) \
; \
else \
failed(#x)
static void test_named_scalars(void) {
printf("Running test_named_scalars...\n");
const char *doc = "title = \"hi\"\n"
"[owner]\n"
"name = \"Alice\"\n"
"[[pkg]]\n"
"n = 1\n"
"nums = [1, 2, 3]\n"
"inl = { a = 1, b = 2 }\n";
toml_result_t r = toml_parse_named(doc, (int)strlen(doc), "a.toml");
CHECK(r.ok);
CHECK(r.toptab.source && 0 == strcmp(r.toptab.source, "a.toml"));
toml_datum_t title = toml_get(r.toptab, "title");
CHECK(title.type == TOML_STRING);
CHECK(title.source && 0 == strcmp(title.source, "a.toml"));
toml_datum_t owner = toml_get(r.toptab, "owner");
CHECK(owner.type == TOML_TABLE);
CHECK(owner.source && 0 == strcmp(owner.source, "a.toml"));
toml_datum_t oname = toml_get(owner, "name");
CHECK(oname.source && 0 == strcmp(oname.source, "a.toml"));
toml_datum_t pkg = toml_get(r.toptab, "pkg");
CHECK(pkg.type == TOML_ARRAY && pkg.u.arr.size == 1);
CHECK(pkg.u.arr.elem[0].source &&
0 == strcmp(pkg.u.arr.elem[0].source, "a.toml"));
// inline array: datum and elements carry source
toml_datum_t nums = toml_get(pkg.u.arr.elem[0], "nums");
CHECK(nums.type == TOML_ARRAY && nums.u.arr.size == 3);
CHECK(nums.source && 0 == strcmp(nums.source, "a.toml"));
CHECK(nums.u.arr.elem[1].source &&
0 == strcmp(nums.u.arr.elem[1].source, "a.toml"));
// inline table: datum and values carry source
toml_datum_t inl = toml_get(pkg.u.arr.elem[0], "inl");
CHECK(inl.type == TOML_TABLE && inl.u.tab.size == 2);
CHECK(inl.source && 0 == strcmp(inl.source, "a.toml"));
toml_datum_t inl_a = toml_get(inl, "a");
CHECK(inl_a.type == TOML_INT64);
CHECK(inl_a.source && 0 == strcmp(inl_a.source, "a.toml"));
// interned: same pointer across datums of one document
CHECK(title.source == oname.source);
toml_free(r);
}
static void test_null_name(void) {
printf("Running test_null_name...\n");
const char *doc = "x = 1\n";
toml_result_t r1 = toml_parse_named(doc, (int)strlen(doc), NULL);
CHECK(r1.ok);
CHECK(r1.toptab.source == NULL);
CHECK(toml_get(r1.toptab, "x").source == NULL);
toml_free(r1);
toml_result_t r2 = toml_parse(doc, (int)strlen(doc));
CHECK(r2.ok);
CHECK(toml_get(r2.toptab, "x").source == NULL);
toml_free(r2);
}
static void test_file_ex(void) {
printf("Running test_file_ex...\n");
const char *path = "src_test_tmp.toml";
FILE *fp = fopen(path, "w");
CHECK(fp != NULL);
fputs("k = 42\n", fp);
fclose(fp);
toml_result_t r = toml_parse_file_ex(path);
CHECK(r.ok);
CHECK(r.toptab.source && 0 == strcmp(r.toptab.source, path));
CHECK(toml_get(r.toptab, "k").source &&
0 == strcmp(toml_get(r.toptab, "k").source, path));
toml_free(r);
remove(path);
}
static void test_merge_sources(void) {
printf("Running test_merge_sources...\n");
const char *a = "title = \"A\"\n"
"[owner]\n"
"name = \"Alice\"\n";
const char *b = "version = \"1\"\n"
"[owner]\n"
"org = \"ACME\"\n";
toml_result_t rA = toml_parse_named(a, (int)strlen(a), "a.toml");
toml_result_t rB = toml_parse_named(b, (int)strlen(b), "b.toml");
toml_result_t m = toml_merge(&rA, &rB);
CHECK(m.ok);
// free inputs first: merged result must be self-contained
toml_free(rA);
toml_free(rB);
CHECK(0 == strcmp(toml_get(m.toptab, "title").source, "a.toml"));
CHECK(0 == strcmp(toml_get(m.toptab, "version").source, "b.toml"));
toml_datum_t owner = toml_get(m.toptab, "owner");
toml_datum_t name = toml_get(owner, "name"); // from A
toml_datum_t org = toml_get(owner, "org"); // from B
CHECK(0 == strcmp(name.source, "a.toml"));
CHECK(0 == strcmp(org.source, "b.toml"));
// dedup: same-origin datums share a pointer
CHECK(toml_get(m.toptab, "title").source == name.source);
toml_free(m);
}
static void test_merge_array_of_tables_source(void) {
printf("Running test_merge_array_of_tables_source...\n");
const char *a = "[[pkg]]\n"
"name = \"left\"\n";
const char *b = "[[pkg]]\n"
"name = \"right\"\n";
toml_result_t rA = toml_parse_named(a, (int)strlen(a), "a.toml");
toml_result_t rB = toml_parse_named(b, (int)strlen(b), "b.toml");
toml_result_t m = toml_merge(&rA, &rB);
CHECK(m.ok);
// free inputs first: merged result must be self-contained
toml_free(rA);
toml_free(rB);
toml_datum_t pkg = toml_get(m.toptab, "pkg");
CHECK(pkg.type == TOML_ARRAY && pkg.u.arr.size == 2);
// append semantics: A's element first, B's element appended
CHECK(0 == strcmp(pkg.u.arr.elem[0].source, "a.toml"));
CHECK(0 == strcmp(pkg.u.arr.elem[1].source, "b.toml"));
CHECK(0 == strcmp(toml_get(pkg.u.arr.elem[0], "name").source, "a.toml"));
CHECK(0 == strcmp(toml_get(pkg.u.arr.elem[1], "name").source, "b.toml"));
toml_free(m);
}
int main(void) {
test_named_scalars();
test_null_name();
test_file_ex();
test_merge_sources();
test_merge_array_of_tables_source();
printf("OK\n");
return 0;
}