From 51dad49d8b479ecc537acad6499926387c2de129 Mon Sep 17 00:00:00 2001 From: paradust7 <102263465+paradust7@users.noreply.github.com> Date: Sat, 7 May 2022 02:21:41 -0700 Subject: [PATCH] Unit tests for irrArray (#103) --- examples/AutomatedTest/main.cpp | 10 ++ examples/AutomatedTest/test_array.cpp | 135 ++++++++++++++++++++++++++ examples/AutomatedTest/test_helper.h | 30 ++++++ examples/CMakeLists.txt | 2 + 4 files changed, 177 insertions(+) create mode 100644 examples/AutomatedTest/test_array.cpp create mode 100644 examples/AutomatedTest/test_helper.h diff --git a/examples/AutomatedTest/main.cpp b/examples/AutomatedTest/main.cpp index 0966892c..2f807226 100644 --- a/examples/AutomatedTest/main.cpp +++ b/examples/AutomatedTest/main.cpp @@ -1,3 +1,4 @@ +#include #include #include "exampleHelper.h" @@ -6,6 +7,8 @@ using namespace irr; static IrrlichtDevice *device = nullptr; static int test_fail = 0; +extern void test_irr_array(); + static video::E_DRIVER_TYPE chooseDriver(const char *arg_) { if (core::stringc(arg_) == "null") @@ -27,8 +30,15 @@ static inline void check(bool ok, const char *msg) } } +void run_unit_tests() { + std::cout << "Running unit tests:" << std::endl; + test_irr_array(); +} + int main(int argc, char *argv[]) { + run_unit_tests(); + SIrrlichtCreationParameters p; p.DriverType = chooseDriver(argc > 1 ? argv[1] : ""); p.WindowSize = core::dimension2du(640, 480); diff --git a/examples/AutomatedTest/test_array.cpp b/examples/AutomatedTest/test_array.cpp new file mode 100644 index 00000000..5ec55ee9 --- /dev/null +++ b/examples/AutomatedTest/test_array.cpp @@ -0,0 +1,135 @@ +#include "irrArray.h" +#include "test_helper.h" + +using namespace irr; +using core::array; + +static void test_basics() { + array v; + v.push_back(1); // 1 + v.push_front(2); // 2, 1 + v.insert(4, 0); // 4, 2, 1 + v.insert(3, 1); // 4, 3, 2, 1 + v.insert(0, 4); // 4, 3, 2, 1, 0 + UASSERTEQ(v.size(), 5); + UASSERTEQ(v[0], 4); + UASSERTEQ(v[1], 3); + UASSERTEQ(v[2], 2); + UASSERTEQ(v[3], 1); + UASSERTEQ(v[4], 0); + array w = v; + UASSERTEQ(w.size(), 5); + UASSERT(w == v); + w.clear(); + UASSERTEQ(w.size(), 0); + UASSERTEQ(w.allocated_size(), 0); + UASSERT(w.empty()); + w = v; + UASSERTEQ(w.size(), 5); + w.set_used(3); + UASSERTEQ(w.size(), 3); + UASSERTEQ(w[0], 4); + UASSERTEQ(w[1], 3); + UASSERTEQ(w[2], 2); + UASSERTEQ(w.getLast(), 2); + w.set_used(20); + UASSERTEQ(w.size(), 20); + w = v; + w.sort(); + UASSERTEQ(w.size(), 5); + UASSERTEQ(w[0], 0); + UASSERTEQ(w[1], 1); + UASSERTEQ(w[2], 2); + UASSERTEQ(w[3], 3); + UASSERTEQ(w[4], 4); + w.erase(0); + UASSERTEQ(w.size(), 4); + UASSERTEQ(w[0], 1); + UASSERTEQ(w[1], 2); + UASSERTEQ(w[2], 3); + UASSERTEQ(w[3], 4); + w.erase(1, 2); + UASSERTEQ(w.size(), 2); + UASSERTEQ(w[0], 1); + UASSERTEQ(w[1], 4); + w.swap(v); + UASSERTEQ(w.size(), 5); + UASSERTEQ(v.size(), 2); +} + +static void test_linear_searches() { + // Populate the array with 0, 1, 2, ..., 100, 100, 99, 98, 97, ..., 0 + array arr; + for (int i = 0; i <= 100; i++) + arr.push_back(i); + for (int i = 100; i >= 0; i--) + arr.push_back(i); + s32 end = arr.size() - 1; + for (int i = 0; i <= 100; i++) { + s32 index = arr.linear_reverse_search(i); + UASSERTEQ(index, end - i); + } + for (int i = 0; i <= 100; i++) { + s32 index = arr.linear_search(i); + UASSERTEQ(index, i); + } +} + +static void test_binary_searches() { + const auto& values = { 3, 5, 1, 2, 5, 10, 19, 9, 7, 1, 2, 5, 8, 15 }; + array arr; + for (int value : values) { + arr.push_back(value); + } + // Test the const form first, it uses a linear search without sorting + const array & carr = arr; + UASSERTEQ(carr.binary_search(20), -1); + UASSERTEQ(carr.binary_search(0), -1); + UASSERTEQ(carr.binary_search(1), 2); + + // Sorted: 1, 1, 2, 2, 3, 5, 5, 5, 7, 8, 9, 10, 15, 19 + UASSERTEQ(arr.binary_search(20), -1); + UASSERTEQ(arr.binary_search(0), -1); + + for (int value : values) { + s32 i = arr.binary_search(value); + UASSERTNE(i, -1); + UASSERTEQ(arr[i], value); + } + + s32 first, last; + first = arr.binary_search_multi(1, last); + UASSERTEQ(first, 0); + UASSERTEQ(last, 1); + + first = arr.binary_search_multi(2, last); + UASSERTEQ(first, 2); + UASSERTEQ(last, 3); + + first = arr.binary_search_multi(3, last); + UASSERTEQ(first, 4); + UASSERTEQ(last, 4); + + first = arr.binary_search_multi(4, last); + UASSERTEQ(first, -1); + + first = arr.binary_search_multi(5, last); + UASSERTEQ(first, 5); + UASSERTEQ(last, 7); + + first = arr.binary_search_multi(7, last); + UASSERTEQ(first, 8); + UASSERTEQ(last, 8); + + first = arr.binary_search_multi(19, last); + UASSERTEQ(first, 13); + UASSERTEQ(last, 13); +} + +void test_irr_array() +{ + test_basics(); + test_linear_searches(); + test_binary_searches(); + std::cout << " test_irr_array PASSED" << std::endl; +} diff --git a/examples/AutomatedTest/test_helper.h b/examples/AutomatedTest/test_helper.h new file mode 100644 index 00000000..9774cddb --- /dev/null +++ b/examples/AutomatedTest/test_helper.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +class TestFailedException : public std::exception { +}; + +// Asserts the comparison specified by CMP is true, or fails the current unit test +#define UASSERTCMP(CMP, actual, expected) do { \ + const auto &a = (actual); \ + const auto &e = (expected); \ + if (!CMP(a, e)) { \ + std::cout \ + << "Test assertion failed: " << #actual << " " << #CMP << " " \ + << #expected << std::endl \ + << " at " << __FILE__ << ":" << __LINE__ << std::endl \ + << " actual: " << a << std::endl << " expected: " \ + << e << std::endl; \ + throw TestFailedException(); \ + } \ +} while (0) + +#define CMPEQ(a, e) (a == e) +#define CMPTRUE(a, e) (a) +#define CMPNE(a, e) (a != e) + +#define UASSERTEQ(actual, expected) UASSERTCMP(CMPEQ, actual, expected) +#define UASSERTNE(actual, nexpected) UASSERTCMP(CMPNE, actual, nexpected) +#define UASSERT(actual) UASSERTCMP(CMPTRUE, actual, true) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 9aab740f..7f00e5e5 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,3 +1,5 @@ +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) set(IRREXAMPLES # removed