description: "Write, build, and run C tests for the VoxelPic library. USE FOR: adding new C test cases, understanding the test data format, debugging test failures, or running the existing C test suite."
Testing the C Library
Test Suite Overview
There are three C test executables under test/, each registered with CTest:
| Executable | Tests | Data Files |
|---|---|---|
voxel_test | OcTree build round-trip | voxel_1.dat–voxel_5.dat |
color_test | Hue-codec encode/decode | (none — self-contained) |
image_test | Level encode/decode to image | image_7.dat–image_9.dat |
Building and Running
cmake -B build --preset debug # or release / debug-clang / release-clang
cmake --build build
ctest --test-dir build -V # -V for verbose output
All four CMake presets enable VOXELPIC_BUILD_TESTS. To run a single test:
ctest --test-dir build -R color_test -V
To build with AddressSanitizer (clang):
cmake -B build --preset release-clang -DVOXELPIC_SANITIZE=address
cmake --build build
ctest --test-dir build -V
Test Data Generation
Test data files are generated automatically by Python scripts as a
post-build step (defined in test/CMakeLists.txt):
test/voxel_test_gen.py→ producesvoxel_1.dat–voxel_5.dattest/image_test_gen.py→ producesimage_7.dat–image_9.dat
Both scripts use a fixed random seed for reproducibility, and skip generation if
the output file already exists. Delete the .dat files to force regeneration.
Binary Data Format
All test data files follow the same layout:
[int32 big-endian] octree level
[int32 big-endian] number of points/voxels (N)
repeated N times:
[float32 native] x
[float32 native] y
[float32 native] z
[uint8] r
[uint8] g
[uint8] b
voxel_test data files additionally contain an expected-output section after
the input section with the same [count][positions+colors] layout.
Read big-endian header integers with the read_be() helper from test/test.h.
Conventions for Writing a New C Test
File Structure
- Create
test/<name>_test.c. #include <voxelpic/voxelpic.h>and#include "test.h".- Link against
voxelpic::voxelpicintest/CMakeLists.txt. - Register with CTest via
add_test(...).
Pass / Fail Signalling
- Return 0 from
main()on success, 1 on assertion failure. - CTest treats any non-zero exit code as failure.
- Use
printf()to log diagnostics on failure (no external assertion library).
Comparison Pattern
Compare results element-by-element and print details on mismatch. Example:
for (size_t i = 0; i < cloud->size; ++i) {
if (voxelpicVec3Compare(&actual->positions[i], &expected->positions[i])) {
printf("Position mismatch at %zu\n", i);
return 1;
}
if (actual->colors[i].value != expected->colors[i].value) {
printf("Color mismatch at %zu\n", i);
return 1;
}
}
Resource Cleanup
Use goto end with a cleanup label to ensure all *New() allocations are
matched by *Free() calls, even on error paths:
int main(int argc, char *argv[]) {
int result = 1;
voxelpicOcTree *octree = voxelpicOcTreeNew(4, 9);
voxelpicPointCloud *cloud = voxelpicPointCloudNew(0);
// ... test logic ...
result = 0;
end:
voxelpicOcTreeFree(octree);
voxelpicPointCloudFree(cloud);
return result;
}
Test Data Files
If the test needs generated data, add a Python generator script and a
add_custom_command(TARGET ... POST_BUILD ...) in test/CMakeLists.txt
following the existing pattern. Use struct.pack(">i", ...) for big-endian
header integers and native byte order for floats and uint8 colour values.
CMakeLists.txt Registration
add_executable(<name>_test <name>_test.c)
target_link_libraries(<name>_test PRIVATE voxelpic::voxelpic)
add_test(NAME <name>_test COMMAND <name>_test [args...]
WORKING_DIRECTORY $<TARGET_FILE_DIR:<name>_test>)
Existing Test Details
voxel_test
Tests the full OcTree round-trip: loads a point cloud, builds an OcTree,
extracts the level back to a cloud, and compares with expected output. Also
verifies save/load I/O for both voxelpicPointCloud and voxelpicLevel.
color_test
Tests voxelpicValueToColor() / voxelpicColorToValue() round-trip across the
full [0, VPIC_MAX_ENCODE_VALUE] range, plus many smaller sub-ranges. Tests
both explicit-range and implicit-range (auto-detected min/max) modes.
image_test
Tests level-to-image encoding and image-to-level decoding. Builds an OcTree,
encodes a level into an RGBA image via voxelpicLevelEncode(), decodes it back
with voxelpicLevelDecode(), and compares the reconstructed cloud against the
original.