326 lines
8.3 KiB
C
326 lines
8.3 KiB
C
|
|
#include <string.h>
|
||
|
|
|
||
|
|
#include "test.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)
|
||
|
|
{
|
||
|
|
size_t len = getlen(st.old);
|
||
|
|
int *mem = must_alloc(t, sizeof(int) * len);
|
||
|
|
memcpy(mem, st.old, sizeof(int) * len);
|
||
|
|
size_t cap = len;
|
||
|
|
|
||
|
|
size_t other_len = getlen(st.other);
|
||
|
|
|
||
|
|
if (!apfl_resizable_splice(
|
||
|
|
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(mem);
|
||
|
|
}
|
||
|
|
|
||
|
|
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
|