commit 818e19c53dc9d8cf303ea4f1848c35c2079c4916 from: Evan Burkey date: Sun Mar 15 05:54:12 2026 UTC Switch to CTest with per-test executables and add GitHub Actions CI commit - 1c83e9394bf7c14ba4ae8712b7098eaca1fe5565 commit + 818e19c53dc9d8cf303ea4f1848c35c2079c4916 blob - /dev/null blob + 204be0351f085dca9246573d3e45ec31a3f174ae (mode 644) --- /dev/null +++ .github/workflows/test.yml @@ -0,0 +1,19 @@ +name: test + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Configure + run: cmake -B build -DCMAKE_BUILD_TYPE=Debug + - name: Build + run: cmake --build build + - name: Test + run: ctest --test-dir build --output-on-failure blob - d5ae533261580ca5f19961bf19ee3f3bb29dbf22 blob + 1d16a6a5d88ce0401a3ae2cd93fe48a2590a197c --- CMakeLists.txt +++ CMakeLists.txt @@ -4,8 +4,32 @@ project(spitwad C) set(CMAKE_C_STANDARD 99) add_library(spitwad STATIC spitwad.c) +target_include_directories(spitwad PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + if(${CMAKE_PROJECT_NAME} STREQUAL spitwad) - add_executable(test test.c) - target_link_libraries(test PRIVATE spitwad) - FILE(COPY DOOM1.WAD DESTINATION ${CMAKE_BINARY_DIR}) + enable_testing() + + set(TESTS + test_create + test_serialize + test_name_truncation + test_empty_lump + test_error + ) + + foreach(t ${TESTS}) + add_executable(${t} tests/${t}.c) + target_link_libraries(${t} PRIVATE spitwad) + add_test(NAME ${t} COMMAND ${t}) + endforeach() + + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/DOOM1.WAD) + set(DOOM_TESTS test_load_file test_round_trip) + foreach(t ${DOOM_TESTS}) + add_executable(${t} tests/${t}.c) + target_link_libraries(${t} PRIVATE spitwad) + add_test(NAME ${t} COMMAND ${t}) + endforeach() + file(COPY DOOM1.WAD DESTINATION ${CMAKE_BINARY_DIR}) + endif() endif() blob - 3d90a01631e5ac9e00e5677382b7bd65581fd2ef (mode 644) blob + /dev/null --- test.c +++ /dev/null @@ -1,195 +0,0 @@ -#include -#include -#include -#include - -#include "spitwad.h" - -void assert_doom1_wad(struct WAD *wad) { - assert(wad->type == IWAD); - assert(wad->num_lumps == 1264); - const struct Lump *first = wad_get_lump(wad, 0); - assert(first != NULL); - assert(first->size == 10752); - assert(strcmp(first->name, "PLAYPAL") == 0); -} - -void test_load_file() { - struct WAD wad; - assert(wad_load_file(&wad, "DOOM1.WAD") == 0); - assert_doom1_wad(&wad); - wad_destroy(&wad); -} - -void test_round_trip() { - struct WAD orig; - assert(wad_load_file(&orig, "DOOM1.WAD") == 0); - assert(wad_write_file(&orig, "TEST.WAD") == 0); - - struct WAD copy; - assert(wad_load_file(©, "TEST.WAD") == 0); - assert_doom1_wad(©); - - assert(orig.num_lumps == copy.num_lumps); - for (uint32_t i = 0; i < orig.num_lumps; i++) { - const struct Lump *a = wad_get_lump(&orig, i); - const struct Lump *b = wad_get_lump(©, i); - assert(strcmp(a->name, b->name) == 0); - assert(a->size == b->size); - if (a->size > 0) - assert(memcmp(a->data, b->data, a->size) == 0); - } - - wad_destroy(&orig); - wad_destroy(©); - remove("TEST.WAD"); -} - -void test_create_and_manipulate() { - struct WAD wad; - assert(wad_init(&wad, PWAD) == 0); - assert(wad.type == PWAD); - assert(wad_num_lumps(&wad) == 0); - - const unsigned char data1[] = "hello world"; - const unsigned char data2[] = {0xDE, 0xAD, 0xBE, 0xEF}; - const unsigned char data3[] = "test data here"; - - assert(wad_add_lump(&wad, "GREETING", data1, sizeof(data1)) == 0); - assert(wad_add_lump(&wad, "DEADBEEF", data2, sizeof(data2)) == 0); - assert(wad_add_lump(&wad, "TESTDATA", data3, sizeof(data3)) == 0); - assert(wad_num_lumps(&wad) == 3); - - // Find by name - const struct Lump *found = wad_find_lump(&wad, "DEADBEEF"); - assert(found != NULL); - assert(found->size == 4); - assert(memcmp(found->data, data2, 4) == 0); - - // Get by index - const struct Lump *first = wad_get_lump(&wad, 0); - assert(first != NULL); - assert(strcmp(first->name, "GREETING") == 0); - - // Remove by name - assert(wad_remove_lump(&wad, "DEADBEEF") == 0); - assert(wad_num_lumps(&wad) == 2); - assert(wad_find_lump(&wad, "DEADBEEF") == NULL); - assert(strcmp(wad_get_lump(&wad, 1)->name, "TESTDATA") == 0); - - // Remove by index - assert(wad_remove_lump_at(&wad, 0) == 0); - assert(wad_num_lumps(&wad) == 1); - assert(strcmp(wad_get_lump(&wad, 0)->name, "TESTDATA") == 0); - - wad_destroy(&wad); -} - -void test_write_and_reload() { - struct WAD wad; - assert(wad_init(&wad, PWAD) == 0); - - const unsigned char data1[] = "first lump data"; - const unsigned char data2[] = {1, 2, 3, 4, 5, 6, 7, 8}; - assert(wad_add_lump(&wad, "FIRST", data1, sizeof(data1)) == 0); - assert(wad_add_lump(&wad, "SECOND", data2, sizeof(data2)) == 0); - - // Write to buffer - unsigned char *buf = NULL; - size_t buf_sz = 0; - assert(wad_write_data(&wad, &buf, &buf_sz) == 0); - assert(buf != NULL); - assert(buf_sz > 0); - - // Reload from buffer - struct WAD wad2; - assert(wad_load_data(&wad2, buf, buf_sz) == 0); - assert(wad2.type == PWAD); - assert(wad_num_lumps(&wad2) == 2); - - const struct Lump *l1 = wad_get_lump(&wad2, 0); - assert(strcmp(l1->name, "FIRST") == 0); - assert(l1->size == sizeof(data1)); - assert(memcmp(l1->data, data1, sizeof(data1)) == 0); - - const struct Lump *l2 = wad_get_lump(&wad2, 1); - assert(strcmp(l2->name, "SECOND") == 0); - assert(l2->size == sizeof(data2)); - assert(memcmp(l2->data, data2, sizeof(data2)) == 0); - - free(buf); - wad_destroy(&wad); - wad_destroy(&wad2); - - // Also test file round-trip - assert(wad_init(&wad, PWAD) == 0); - assert(wad_add_lump(&wad, "FIRST", data1, sizeof(data1)) == 0); - assert(wad_add_lump(&wad, "SECOND", data2, sizeof(data2)) == 0); - assert(wad_write_file(&wad, "TEST2.WAD") == 0); - - struct WAD wad3; - assert(wad_load_file(&wad3, "TEST2.WAD") == 0); - assert(wad_num_lumps(&wad3) == 2); - assert(memcmp(wad_get_lump(&wad3, 0)->data, data1, sizeof(data1)) == 0); - - wad_destroy(&wad); - wad_destroy(&wad3); - remove("TEST2.WAD"); -} - -void test_name_truncation() { - struct WAD wad; - assert(wad_init(&wad, PWAD) == 0); - assert(wad_add_lump(&wad, "LONGERNAME", (const unsigned char *)"x", 1) == 0); - const struct Lump *l = wad_get_lump(&wad, 0); - assert(strlen(l->name) == 8); - assert(strcmp(l->name, "LONGERNA") == 0); - wad_destroy(&wad); -} - -void test_empty_lump() { - struct WAD wad; - assert(wad_init(&wad, PWAD) == 0); - assert(wad_add_lump(&wad, "EMPTY", NULL, 0) == 0); - const struct Lump *l = wad_get_lump(&wad, 0); - assert(l->size == 0); - assert(l->data == NULL); - - unsigned char *buf = NULL; - size_t sz = 0; - assert(wad_write_data(&wad, &buf, &sz) == 0); - - struct WAD wad2; - assert(wad_load_data(&wad2, buf, sz) == 0); - assert(wad_get_lump(&wad2, 0)->size == 0); - - free(buf); - wad_destroy(&wad); - wad_destroy(&wad2); -} - -void test_error_cases() { - assert(wad_init(NULL, PWAD) != 0); - assert(wad_load_file(NULL, "foo") != 0); - assert(wad_load_data(NULL, NULL, 0) != 0); - - struct WAD wad; - assert(wad_load_data(&wad, (const unsigned char *)"short", 5) != 0); - assert(wad_load_data(&wad, (const unsigned char *)"NOPE01234567", 12) != 0); - - assert(wad_find_lump(NULL, "X") == NULL); - assert(wad_get_lump(NULL, 0) == NULL); - assert(wad_num_lumps(NULL) == 0); -} - -int main() { - test_load_file(); - test_round_trip(); - test_create_and_manipulate(); - test_write_and_reload(); - test_name_truncation(); - test_empty_lump(); - test_error_cases(); - printf("All tests passed.\n"); - return 0; -} blob - /dev/null blob + 0573f9fab2e6c87f509b8ccc50c2527b838e4adb (mode 644) --- /dev/null +++ tests/test_create.c @@ -0,0 +1,40 @@ +#include +#include +#include "spitwad.h" + +int main() { + struct WAD wad; + assert(wad_init(&wad, PWAD) == 0); + assert(wad.type == PWAD); + assert(wad_num_lumps(&wad) == 0); + + const unsigned char data1[] = "hello world"; + const unsigned char data2[] = {0xDE, 0xAD, 0xBE, 0xEF}; + const unsigned char data3[] = "test data here"; + + assert(wad_add_lump(&wad, "GREETING", data1, sizeof(data1)) == 0); + assert(wad_add_lump(&wad, "DEADBEEF", data2, sizeof(data2)) == 0); + assert(wad_add_lump(&wad, "TESTDATA", data3, sizeof(data3)) == 0); + assert(wad_num_lumps(&wad) == 3); + + const struct Lump *found = wad_find_lump(&wad, "DEADBEEF"); + assert(found != NULL); + assert(found->size == 4); + assert(memcmp(found->data, data2, 4) == 0); + + const struct Lump *first = wad_get_lump(&wad, 0); + assert(first != NULL); + assert(strcmp(first->name, "GREETING") == 0); + + assert(wad_remove_lump(&wad, "DEADBEEF") == 0); + assert(wad_num_lumps(&wad) == 2); + assert(wad_find_lump(&wad, "DEADBEEF") == NULL); + assert(strcmp(wad_get_lump(&wad, 1)->name, "TESTDATA") == 0); + + assert(wad_remove_lump_at(&wad, 0) == 0); + assert(wad_num_lumps(&wad) == 1); + assert(strcmp(wad_get_lump(&wad, 0)->name, "TESTDATA") == 0); + + wad_destroy(&wad); + return 0; +} blob - /dev/null blob + 95abd323439bd2ade7c4c609262f754bacf28302 (mode 644) --- /dev/null +++ tests/test_empty_lump.c @@ -0,0 +1,25 @@ +#include +#include +#include "spitwad.h" + +int main() { + struct WAD wad; + assert(wad_init(&wad, PWAD) == 0); + assert(wad_add_lump(&wad, "EMPTY", NULL, 0) == 0); + const struct Lump *l = wad_get_lump(&wad, 0); + assert(l->size == 0); + assert(l->data == NULL); + + unsigned char *buf = NULL; + size_t sz = 0; + assert(wad_write_data(&wad, &buf, &sz) == 0); + + struct WAD wad2; + assert(wad_load_data(&wad2, buf, sz) == 0); + assert(wad_get_lump(&wad2, 0)->size == 0); + + free(buf); + wad_destroy(&wad); + wad_destroy(&wad2); + return 0; +} blob - /dev/null blob + 87ce5fffbb11bc31b0ee3a6e6978fb8998cd6a8b (mode 644) --- /dev/null +++ tests/test_error.c @@ -0,0 +1,17 @@ +#include +#include "spitwad.h" + +int main() { + assert(wad_init(NULL, PWAD) != 0); + assert(wad_load_file(NULL, "foo") != 0); + assert(wad_load_data(NULL, NULL, 0) != 0); + + struct WAD wad; + assert(wad_load_data(&wad, (const unsigned char *)"short", 5) != 0); + assert(wad_load_data(&wad, (const unsigned char *)"NOPE01234567", 12) != 0); + + assert(wad_find_lump(NULL, "X") == NULL); + assert(wad_get_lump(NULL, 0) == NULL); + assert(wad_num_lumps(NULL) == 0); + return 0; +} blob - /dev/null blob + f54ae05facb146fa7388aa9dffbadf03d39b94ae (mode 644) --- /dev/null +++ tests/test_load_file.c @@ -0,0 +1,16 @@ +#include +#include +#include "spitwad.h" + +int main() { + struct WAD wad; + assert(wad_load_file(&wad, "DOOM1.WAD") == 0); + assert(wad.type == IWAD); + assert(wad.num_lumps == 1264); + const struct Lump *first = wad_get_lump(&wad, 0); + assert(first != NULL); + assert(first->size == 10752); + assert(strcmp(first->name, "PLAYPAL") == 0); + wad_destroy(&wad); + return 0; +} blob - /dev/null blob + c781e5aabaa98ae74f3567cd8918c41da0fcb4c2 (mode 644) --- /dev/null +++ tests/test_name_truncation.c @@ -0,0 +1,14 @@ +#include +#include +#include "spitwad.h" + +int main() { + struct WAD wad; + assert(wad_init(&wad, PWAD) == 0); + assert(wad_add_lump(&wad, "LONGERNAME", (const unsigned char *)"x", 1) == 0); + const struct Lump *l = wad_get_lump(&wad, 0); + assert(strlen(l->name) == 8); + assert(strcmp(l->name, "LONGERNA") == 0); + wad_destroy(&wad); + return 0; +} blob - /dev/null blob + 42bd1e4b69a9d784148b3eccfb91b4a2d23592d6 (mode 644) --- /dev/null +++ tests/test_round_trip.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include "spitwad.h" + +int main() { + struct WAD orig; + assert(wad_load_file(&orig, "DOOM1.WAD") == 0); + assert(wad_write_file(&orig, "TEST.WAD") == 0); + + struct WAD copy; + assert(wad_load_file(©, "TEST.WAD") == 0); + assert(copy.type == IWAD); + assert(orig.num_lumps == copy.num_lumps); + + for (uint32_t i = 0; i < orig.num_lumps; i++) { + const struct Lump *a = wad_get_lump(&orig, i); + const struct Lump *b = wad_get_lump(©, i); + assert(strcmp(a->name, b->name) == 0); + assert(a->size == b->size); + if (a->size > 0) + assert(memcmp(a->data, b->data, a->size) == 0); + } + + wad_destroy(&orig); + wad_destroy(©); + remove("TEST.WAD"); + return 0; +} blob - /dev/null blob + 3a9ac34faca67c2f6c7c3c161ede9fbed844f529 (mode 644) --- /dev/null +++ tests/test_serialize.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include "spitwad.h" + +int main() { + struct WAD wad; + assert(wad_init(&wad, PWAD) == 0); + + const unsigned char data1[] = "first lump data"; + const unsigned char data2[] = {1, 2, 3, 4, 5, 6, 7, 8}; + assert(wad_add_lump(&wad, "FIRST", data1, sizeof(data1)) == 0); + assert(wad_add_lump(&wad, "SECOND", data2, sizeof(data2)) == 0); + + // Write to buffer and reload + unsigned char *buf = NULL; + size_t buf_sz = 0; + assert(wad_write_data(&wad, &buf, &buf_sz) == 0); + assert(buf != NULL); + assert(buf_sz > 0); + + struct WAD wad2; + assert(wad_load_data(&wad2, buf, buf_sz) == 0); + assert(wad2.type == PWAD); + assert(wad_num_lumps(&wad2) == 2); + + const struct Lump *l1 = wad_get_lump(&wad2, 0); + assert(strcmp(l1->name, "FIRST") == 0); + assert(l1->size == sizeof(data1)); + assert(memcmp(l1->data, data1, sizeof(data1)) == 0); + + const struct Lump *l2 = wad_get_lump(&wad2, 1); + assert(strcmp(l2->name, "SECOND") == 0); + assert(l2->size == sizeof(data2)); + assert(memcmp(l2->data, data2, sizeof(data2)) == 0); + + free(buf); + wad_destroy(&wad); + wad_destroy(&wad2); + + // File round-trip + assert(wad_init(&wad, PWAD) == 0); + assert(wad_add_lump(&wad, "FIRST", data1, sizeof(data1)) == 0); + assert(wad_add_lump(&wad, "SECOND", data2, sizeof(data2)) == 0); + assert(wad_write_file(&wad, "TEST2.WAD") == 0); + + struct WAD wad3; + assert(wad_load_file(&wad3, "TEST2.WAD") == 0); + assert(wad_num_lumps(&wad3) == 2); + assert(memcmp(wad_get_lump(&wad3, 0)->data, data1, sizeof(data1)) == 0); + + wad_destroy(&wad); + wad_destroy(&wad3); + remove("TEST2.WAD"); + return 0; +}