#include #include "test.h" #include "alloc.h" #include "resizable.h" struct splice_test_data { const int *old; size_t cut_start; size_t cut_len; const int *other; const int *want; }; static size_t getlen(const int *data) { size_t len = 0; for (; *data != 0; data++) { len++; } return len; } static void run_splice_test(testctx t, struct splice_test_data st) { struct apfl_allocator allocator = test_allocator(t); size_t len = getlen(st.old); int *mem = ALLOC_LIST(allocator, int, len); memcpy(mem, st.old, sizeof(int) * len); size_t cap = len; size_t other_len = getlen(st.other); if (!apfl_resizable_splice( allocator, sizeof(int), (void **)&mem, &len, &cap, st.cut_start, st.cut_len, st.other, other_len )) { test_fatalf(t, "splice failed!"); } size_t want_len = getlen(st.want); if (len != want_len) { test_fatalf(t, "Expected len=%d, got %d", (int)want_len, (int)len); } if (cap < want_len) { test_fatalf(t, "Expected cap>=%d, got %d", (int)want_len, (int)cap); } for (size_t i = 0; i < len; i++) { int have = mem[i]; int want = st.want[i]; if (have != want) { test_failf(t, "have(%d) != want(%d) at i=%d", have, want, (int)i); } } FREE_LIST(allocator, mem, cap); } TEST(splice_empty, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {0}, .cut_start = 0, .cut_len = 0, .other = (int[]) {0}, .want = (int[]) {0}, }); } TEST(splice_remove_single_begin, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 0}, .cut_start = 0, .cut_len = 1, .other = (int[]) {0}, .want = (int[]) {2, 3, 0}, }); } TEST(splice_remove_multiple_begin, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 0}, .cut_start = 0, .cut_len = 2, .other = (int[]) {0}, .want = (int[]) {3, 0}, }); } TEST(splice_remove_single_end, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 0}, .cut_start = 2, .cut_len = 1, .other = (int[]) {0}, .want = (int[]) {1, 2, 0}, }); } TEST(splice_remove_multiple_end, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 0}, .cut_start = 1, .cut_len = 2, .other = (int[]) {0}, .want = (int[]) {1, 0}, }); } TEST(splice_remove_single_mid, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 0}, .cut_start = 1, .cut_len = 1, .other = (int[]) {0}, .want = (int[]) {1, 3, 0}, }); } TEST(splice_replace_same_size_single_mid, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 0}, .cut_start = 1, .cut_len = 1, .other = (int[]) {42, 0}, .want = (int[]) {1, 42, 3, 0}, }); } TEST(splice_replace_larger_size_single_mid, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 0}, .cut_start = 1, .cut_len = 1, .other = (int[]) {10, 20, 30, 0}, .want = (int[]) {1, 10, 20, 30, 3, 0}, }); } TEST(splice_replace_smaller_size_single_mid, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 4, 0}, .cut_start = 1, .cut_len = 2, .other = (int[]) {10, 0}, .want = (int[]) {1, 10, 4, 0}, }); } TEST(splice_replace_same_size_single_begin, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 0}, .cut_start = 0, .cut_len = 1, .other = (int[]) {42, 0}, .want = (int[]) {42, 2, 3, 0}, }); } TEST(splice_replace_larger_size_single_begin, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 0}, .cut_start = 0, .cut_len = 1, .other = (int[]) {10, 20, 30, 0}, .want = (int[]) {10, 20, 30, 2, 3, 0}, }); } TEST(splice_replace_smaller_size_single_begin, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 4, 0}, .cut_start = 0, .cut_len = 2, .other = (int[]) {10, 0}, .want = (int[]) {10, 3, 4, 0}, }); } TEST(splice_replace_same_size_single_end, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 0}, .cut_start = 2, .cut_len = 1, .other = (int[]) {42, 0}, .want = (int[]) {1, 2, 42, 0}, }); } TEST(splice_replace_larger_size_single_end, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 0}, .cut_start = 2, .cut_len = 1, .other = (int[]) {10, 20, 30, 0}, .want = (int[]) {1, 2, 10, 20, 30, 0}, }); } TEST(splice_replace_smaller_size_single_end, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 4, 0}, .cut_start = 2, .cut_len = 2, .other = (int[]) {10, 0}, .want = (int[]) {1, 2, 10, 0}, }); } TEST(splice_remove_all, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 4, 0}, .cut_start = 0, .cut_len = 4, .other = (int[]) {0}, .want = (int[]) {0}, }); } TEST(splice_replace_all_same_size, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 4, 0}, .cut_start = 0, .cut_len = 4, .other = (int[]) {10, 20, 30, 40, 0}, .want = (int[]) {10, 20, 30, 40, 0}, }); } TEST(splice_replace_all_smaller_size, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 4, 0}, .cut_start = 0, .cut_len = 4, .other = (int[]) {10, 0}, .want = (int[]) {10, 0}, }); } TEST(splice_replace_all_larger_size, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 4, 0}, .cut_start = 0, .cut_len = 4, .other = (int[]) {10, 20, 30, 40, 50, 60, 0}, .want = (int[]) {10, 20, 30, 40, 50, 60, 0}, }); } TEST(splice_noop, t) { for (size_t i = 0; i < 4; i++) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 4, 0}, .cut_start = i, .cut_len = 0, .other = (int[]) {0}, .want = (int[]) {1, 2, 3, 4, 0}, }); } } TEST(splice_insert_begin, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 4, 0}, .cut_start = 0, .cut_len = 0, .other = (int[]) {10, 20, 30, 0}, .want = (int[]) {10, 20, 30, 1, 2, 3, 4, 0}, }); } TEST(splice_insert_mid, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 4, 0}, .cut_start = 1, .cut_len = 0, .other = (int[]) {10, 20, 30, 0}, .want = (int[]) {1, 10, 20, 30, 2, 3, 4, 0}, }); } TEST(splice_insert_end, t) { run_splice_test(t, (struct splice_test_data) { .old = (int[]) {1, 2, 3, 4, 0}, .cut_start = 4, .cut_len = 0, .other = (int[]) {10, 20, 30, 0}, .want = (int[]) {1, 2, 3, 4, 10, 20, 30, 0}, }); } TESTS_BEGIN ADDTEST(splice_empty), ADDTEST(splice_remove_single_begin), ADDTEST(splice_remove_multiple_begin), ADDTEST(splice_remove_single_end), ADDTEST(splice_remove_multiple_end), ADDTEST(splice_remove_single_mid), ADDTEST(splice_replace_same_size_single_mid), ADDTEST(splice_replace_larger_size_single_mid), ADDTEST(splice_replace_smaller_size_single_mid), ADDTEST(splice_replace_same_size_single_begin), ADDTEST(splice_replace_larger_size_single_begin), ADDTEST(splice_replace_smaller_size_single_begin), ADDTEST(splice_replace_same_size_single_end), ADDTEST(splice_replace_larger_size_single_end), ADDTEST(splice_replace_smaller_size_single_end), ADDTEST(splice_remove_all), ADDTEST(splice_replace_all_same_size), ADDTEST(splice_replace_all_smaller_size), ADDTEST(splice_replace_all_larger_size), ADDTEST(splice_noop), ADDTEST(splice_insert_begin), ADDTEST(splice_insert_mid), ADDTEST(splice_insert_end), TESTS_END