From 0860347e4b91cfe0c6598a46dcc0d7dbdd25d345 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Thu, 4 Jun 2026 12:49:29 +0200 Subject: [PATCH 1/2] Restart unit tests with Doctest --- CMakeLists.txt | 15 ++---- cmake/Doctest.cmake | 20 ++++++++ tests/{unit => legacy}/README.md | 0 .../addresconversions_test.cpp | 0 .../example_code/blink/blink.wasm | Bin .../example_code/blink/blink.wast | 0 .../example_code/blink/blink_wasm.h | 0 .../example_code/dimmer/dimmer.wasm | Bin .../example_code/dimmer/dimmer.wast | 0 .../example_code/dimmer/dimmer_wasm.h | 0 .../example_code/fac/fac.wasm | Bin .../example_code/fac/fac.wast | 0 .../example_code/fac/fac_wasm.h | 0 tests/{unit => legacy}/freeingmodule_test.cpp | 0 .../instantiatemodule_test.cpp | 0 tests/{unit => legacy}/serialisation_test.cpp | 0 .../shared/callstackbuilder.cpp | 0 .../shared/callstackbuilder.h | 0 .../{unit => legacy}/shared/serialisation.cpp | 0 tests/{unit => legacy}/shared/serialisation.h | 0 tests/unit/leb128.cpp | 42 ++++++++++++++++ tests/unit/virtualaddresses.cpp | 45 ++++++++++++++++++ 22 files changed, 111 insertions(+), 11 deletions(-) create mode 100644 cmake/Doctest.cmake rename tests/{unit => legacy}/README.md (100%) rename tests/{unit => legacy}/addresconversions_test.cpp (100%) rename tests/{unit => legacy}/example_code/blink/blink.wasm (100%) rename tests/{unit => legacy}/example_code/blink/blink.wast (100%) rename tests/{unit => legacy}/example_code/blink/blink_wasm.h (100%) rename tests/{unit => legacy}/example_code/dimmer/dimmer.wasm (100%) rename tests/{unit => legacy}/example_code/dimmer/dimmer.wast (100%) rename tests/{unit => legacy}/example_code/dimmer/dimmer_wasm.h (100%) rename tests/{unit => legacy}/example_code/fac/fac.wasm (100%) rename tests/{unit => legacy}/example_code/fac/fac.wast (100%) rename tests/{unit => legacy}/example_code/fac/fac_wasm.h (100%) rename tests/{unit => legacy}/freeingmodule_test.cpp (100%) rename tests/{unit => legacy}/instantiatemodule_test.cpp (100%) rename tests/{unit => legacy}/serialisation_test.cpp (100%) rename tests/{unit => legacy}/shared/callstackbuilder.cpp (100%) rename tests/{unit => legacy}/shared/callstackbuilder.h (100%) rename tests/{unit => legacy}/shared/serialisation.cpp (100%) rename tests/{unit => legacy}/shared/serialisation.h (100%) create mode 100644 tests/unit/leb128.cpp create mode 100644 tests/unit/virtualaddresses.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 65e6facb5..2227e6b82 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,8 @@ endif (BUILD_ESP) project(WARDuino VERSION 0.6.1) +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") + set(WARDUINO_VERSION_STRING "${PROJECT_VERSION}") configure_file(src/config.h.in include/warduino/config.h) @@ -104,16 +106,7 @@ if (BUILD_UNITTEST) endif (CMAKE_COMPILER_IS_GNUCXX) - include(FetchContent) - FetchContent_Declare( - googletest - GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-1.12.1 - ) - - # For Windows: Prevent overriding the parent project's compiler/linker settings - set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) - FetchContent_MakeAvailable(googletest) + include(Doctest) set(PATH_TO_UNIT_TEST ${PROJECT_SOURCE_DIR}/tests/unit) @@ -129,7 +122,7 @@ if (BUILD_UNITTEST) get_filename_component(TEST_NAME ${TEST_FILE} NAME_WE) message(DEBUG "Add executable for " ${TEST_FILE}) add_executable(${TEST_NAME} ${TEST_FILE} ${SOURCE_FILES} ${SHARED_SRC}) - target_link_libraries(${TEST_NAME} gtest_main) + target_link_libraries(${TEST_NAME} PRIVATE doctest::doctest) target_include_directories(${TEST_NAME} PRIVATE ${EXTERNAL_LIB_HEADERS} "${PROJECT_BINARY_DIR}/include") add_test(${TEST_NAME} ${TEST_NAME}) endforeach () diff --git a/cmake/Doctest.cmake b/cmake/Doctest.cmake new file mode 100644 index 000000000..2ffe46d30 --- /dev/null +++ b/cmake/Doctest.cmake @@ -0,0 +1,20 @@ +include_guard(GLOBAL) + +find_package(doctest CONFIG QUIET) + +if (NOT doctest_FOUND) + include(FetchContent) + + FetchContent_Declare( + doctest + GIT_REPOSITORY https://github.com/doctest/doctest.git + GIT_TAG v2.4.12 + ) + + FetchContent_MakeAvailable(doctest) +endif () + +if (NOT TARGET doctest::doctest) + message(FATAL_ERROR "Doctest target doctest::doctest was not found") +endif () + diff --git a/tests/unit/README.md b/tests/legacy/README.md similarity index 100% rename from tests/unit/README.md rename to tests/legacy/README.md diff --git a/tests/unit/addresconversions_test.cpp b/tests/legacy/addresconversions_test.cpp similarity index 100% rename from tests/unit/addresconversions_test.cpp rename to tests/legacy/addresconversions_test.cpp diff --git a/tests/unit/example_code/blink/blink.wasm b/tests/legacy/example_code/blink/blink.wasm similarity index 100% rename from tests/unit/example_code/blink/blink.wasm rename to tests/legacy/example_code/blink/blink.wasm diff --git a/tests/unit/example_code/blink/blink.wast b/tests/legacy/example_code/blink/blink.wast similarity index 100% rename from tests/unit/example_code/blink/blink.wast rename to tests/legacy/example_code/blink/blink.wast diff --git a/tests/unit/example_code/blink/blink_wasm.h b/tests/legacy/example_code/blink/blink_wasm.h similarity index 100% rename from tests/unit/example_code/blink/blink_wasm.h rename to tests/legacy/example_code/blink/blink_wasm.h diff --git a/tests/unit/example_code/dimmer/dimmer.wasm b/tests/legacy/example_code/dimmer/dimmer.wasm similarity index 100% rename from tests/unit/example_code/dimmer/dimmer.wasm rename to tests/legacy/example_code/dimmer/dimmer.wasm diff --git a/tests/unit/example_code/dimmer/dimmer.wast b/tests/legacy/example_code/dimmer/dimmer.wast similarity index 100% rename from tests/unit/example_code/dimmer/dimmer.wast rename to tests/legacy/example_code/dimmer/dimmer.wast diff --git a/tests/unit/example_code/dimmer/dimmer_wasm.h b/tests/legacy/example_code/dimmer/dimmer_wasm.h similarity index 100% rename from tests/unit/example_code/dimmer/dimmer_wasm.h rename to tests/legacy/example_code/dimmer/dimmer_wasm.h diff --git a/tests/unit/example_code/fac/fac.wasm b/tests/legacy/example_code/fac/fac.wasm similarity index 100% rename from tests/unit/example_code/fac/fac.wasm rename to tests/legacy/example_code/fac/fac.wasm diff --git a/tests/unit/example_code/fac/fac.wast b/tests/legacy/example_code/fac/fac.wast similarity index 100% rename from tests/unit/example_code/fac/fac.wast rename to tests/legacy/example_code/fac/fac.wast diff --git a/tests/unit/example_code/fac/fac_wasm.h b/tests/legacy/example_code/fac/fac_wasm.h similarity index 100% rename from tests/unit/example_code/fac/fac_wasm.h rename to tests/legacy/example_code/fac/fac_wasm.h diff --git a/tests/unit/freeingmodule_test.cpp b/tests/legacy/freeingmodule_test.cpp similarity index 100% rename from tests/unit/freeingmodule_test.cpp rename to tests/legacy/freeingmodule_test.cpp diff --git a/tests/unit/instantiatemodule_test.cpp b/tests/legacy/instantiatemodule_test.cpp similarity index 100% rename from tests/unit/instantiatemodule_test.cpp rename to tests/legacy/instantiatemodule_test.cpp diff --git a/tests/unit/serialisation_test.cpp b/tests/legacy/serialisation_test.cpp similarity index 100% rename from tests/unit/serialisation_test.cpp rename to tests/legacy/serialisation_test.cpp diff --git a/tests/unit/shared/callstackbuilder.cpp b/tests/legacy/shared/callstackbuilder.cpp similarity index 100% rename from tests/unit/shared/callstackbuilder.cpp rename to tests/legacy/shared/callstackbuilder.cpp diff --git a/tests/unit/shared/callstackbuilder.h b/tests/legacy/shared/callstackbuilder.h similarity index 100% rename from tests/unit/shared/callstackbuilder.h rename to tests/legacy/shared/callstackbuilder.h diff --git a/tests/unit/shared/serialisation.cpp b/tests/legacy/shared/serialisation.cpp similarity index 100% rename from tests/unit/shared/serialisation.cpp rename to tests/legacy/shared/serialisation.cpp diff --git a/tests/unit/shared/serialisation.h b/tests/legacy/shared/serialisation.h similarity index 100% rename from tests/unit/shared/serialisation.h rename to tests/legacy/shared/serialisation.h diff --git a/tests/unit/leb128.cpp b/tests/unit/leb128.cpp new file mode 100644 index 000000000..40963d85c --- /dev/null +++ b/tests/unit/leb128.cpp @@ -0,0 +1,42 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include + +#include "../../src/Utils/util.h" + +TEST_CASE("Test: leb128 unsigned encoding") { + SUBCASE("Decodes single-byte values") { + uint8_t bytes[] = {0x00, 0x7f}; + uint8_t *pos = bytes; + + CHECK(read_LEB(&pos, 32) == 0); + CHECK(pos == bytes + 1); + + CHECK(read_LEB(&pos, 32) == 127); + CHECK(pos == bytes + 2); + } + + SUBCASE("Decodes multi-byte values") { + uint8_t bytes[] = {0x80, 0x01, 0xe5, 0x8e, 0x26}; + uint8_t *pos = bytes; + + CHECK(read_LEB(&pos, 32) == 128); + CHECK(pos == bytes + 2); + + // Example from the LEB128 specification: 624485 -> E5 8E 26 + CHECK(read_LEB(&pos, 32) == 624485); + CHECK(pos == bytes + 5); + } +} + +TEST_CASE("Test: leb128 signed encoding") { + SUBCASE("Decodes single-byte values") { + uint8_t bytes[] = {0x00, 0x7f}; + uint8_t *pos = bytes; + + CHECK(read_LEB_signed(&pos, 32) == 0); + CHECK(pos == bytes + 1); + + CHECK(read_LEB_signed(&pos, 32) == -1); + CHECK(pos == bytes + 2); + } +} \ No newline at end of file diff --git a/tests/unit/virtualaddresses.cpp b/tests/unit/virtualaddresses.cpp new file mode 100644 index 000000000..9282bcd24 --- /dev/null +++ b/tests/unit/virtualaddresses.cpp @@ -0,0 +1,45 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include + +#include "../../src/Utils/util.h" + +TEST_CASE("Test: to virtual address conversion") { + uint8_t wasm_bytes[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee}; + Module module{}; + module.bytes = wasm_bytes; + module.byte_count = sizeof(wasm_bytes); + + SUBCASE("Start of module maps to zero") { + CHECK(toVirtualAddress(module.bytes, &module) == 0); + } + + SUBCASE("Middle byte maps to its offset") { + CHECK(toVirtualAddress(module.bytes + 3, &module) == 3); + } + + SUBCASE("End pointer maps to byte_count") { + CHECK(toVirtualAddress(module.bytes + module.byte_count, &module) == + module.byte_count); + } +} + +TEST_CASE("Test: to physical address conversion") { + uint8_t wasm_bytes[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee}; + Module module{}; + module.bytes = wasm_bytes; + module.byte_count = sizeof(wasm_bytes); + + SUBCASE("Virtual zero maps to start pointer") { + CHECK(toPhysicalAddress(0, &module) == module.bytes); + } + + SUBCASE("Virtual middle offset maps to expected physical pointer") { + CHECK(toPhysicalAddress(2, &module) == module.bytes + 2); + } + + SUBCASE("Last valid virtual offset maps to final byte") { + CHECK(toPhysicalAddress(module.byte_count - 1, &module) == + module.bytes + module.byte_count - 1); + } + +} From fb2d2fa0fdec86e66a220a2a0f443a7209b96214 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Thu, 4 Jun 2026 16:39:41 +0200 Subject: [PATCH 2/2] Add test for float parsing in debugger --- tests/unit/{leb128.cpp => parsing.cpp} | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) rename tests/unit/{leb128.cpp => parsing.cpp} (65%) diff --git a/tests/unit/leb128.cpp b/tests/unit/parsing.cpp similarity index 65% rename from tests/unit/leb128.cpp rename to tests/unit/parsing.cpp index 40963d85c..988a3d4d5 100644 --- a/tests/unit/leb128.cpp +++ b/tests/unit/parsing.cpp @@ -1,6 +1,8 @@ #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include +#include + #include "../../src/Utils/util.h" TEST_CASE("Test: leb128 unsigned encoding") { @@ -39,4 +41,25 @@ TEST_CASE("Test: leb128 signed encoding") { CHECK(read_LEB_signed(&pos, 32) == -1); CHECK(pos == bytes + 2); } +} + + +TEST_CASE("Test: wasm args parsing") { + uint32_t params[] = {F32, F32}; + uint32_t results[] = {I32}; + Type function_type = {FUNC, 2, params, 1, results, 0}; + + // 01 00 80 7f -> NaN (0x7f800001), 00 00 80 7f -> +Infinity + uint8_t data[] = {0x01, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x80, 0x7f}; + + StackValue *args = readWasmArgs(function_type, data); + + REQUIRE(args != nullptr); + CHECK(args[0].value_type == F32); + CHECK(std::isnan(args[0].value.f32)); + + CHECK(args[1].value_type == F32); + CHECK(std::isinf(args[1].value.f32)); + + delete[] args; } \ No newline at end of file