Add util tests
This commit is contained in:
parent
c6a8590b2c
commit
eda0701887
4 changed files with 432 additions and 0 deletions
|
|
@ -6,3 +6,5 @@ file(GLOB_RECURSE PSEMEK_UTIL_SOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "so
|
||||||
add_library(psemek-util ${PSEMEK_UTIL_HEADERS} ${PSEMEK_UTIL_SOURCES})
|
add_library(psemek-util ${PSEMEK_UTIL_HEADERS} ${PSEMEK_UTIL_SOURCES})
|
||||||
target_include_directories(psemek-util PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
target_include_directories(psemek-util PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||||
target_link_libraries(psemek-util PUBLIC psemek-log ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(psemek-util PUBLIC psemek-log ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
|
||||||
|
psemek_glob_tests(psemek-util tests)
|
||||||
|
|
|
||||||
123
libs/util/tests/array.cpp
Normal file
123
libs/util/tests/array.cpp
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
#include <psemek/test/test.hpp>
|
||||||
|
|
||||||
|
#include <psemek/util/array.hpp>
|
||||||
|
|
||||||
|
using namespace psemek::util;
|
||||||
|
|
||||||
|
test_case(util_array_empty)
|
||||||
|
{
|
||||||
|
array<int, 1> a;
|
||||||
|
expect_equal(a.size(), 0);
|
||||||
|
expect(a.empty());
|
||||||
|
|
||||||
|
array<int, 2> b;
|
||||||
|
expect_equal(b.size(), 0);
|
||||||
|
expect(b.empty());
|
||||||
|
|
||||||
|
array<int, 3> c;
|
||||||
|
expect_equal(c.size(), 0);
|
||||||
|
expect(c.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_array_size)
|
||||||
|
{
|
||||||
|
array<int, 1> a({16});
|
||||||
|
expect(!a.empty());
|
||||||
|
expect_equal(a.size(), 16);
|
||||||
|
expect_equal(a.width(), 16);
|
||||||
|
|
||||||
|
array<int, 2> b({8, 16});
|
||||||
|
expect(!b.empty());
|
||||||
|
expect_equal(b.size(), 8 * 16);
|
||||||
|
expect_equal(b.width(), 8);
|
||||||
|
expect_equal(b.height(), 16);
|
||||||
|
|
||||||
|
array<int, 3> c({4, 8, 16});
|
||||||
|
expect(!c.empty());
|
||||||
|
expect_equal(c.size(), 4 * 8 * 16);
|
||||||
|
expect_equal(c.width(), 4);
|
||||||
|
expect_equal(c.height(), 8);
|
||||||
|
expect_equal(c.depth(), 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_array_init)
|
||||||
|
{
|
||||||
|
array<int, 2> a({16, 16}, 42);
|
||||||
|
for (std::size_t i = 0; i < a.width(); ++i)
|
||||||
|
for (std::size_t j = 0; j < a.height(); ++j)
|
||||||
|
expect_equal(a(i, j), 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_array_release)
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[]> p(new int[256]);
|
||||||
|
auto q = p.get();
|
||||||
|
|
||||||
|
array<int, 2> a({16, 16}, std::move(p));
|
||||||
|
expect_equal(a.size(), 256);
|
||||||
|
expect_equal(a.width(), 16);
|
||||||
|
expect_equal(a.height(), 16);
|
||||||
|
expect_equal_ptr(a.data(), q);
|
||||||
|
|
||||||
|
p = a.release();
|
||||||
|
expect_equal(a.size(), 0);
|
||||||
|
expect(a.empty());
|
||||||
|
expect_equal_ptr(a.data(), nullptr);
|
||||||
|
expect_equal_ptr(p.get(), q);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_array_move)
|
||||||
|
{
|
||||||
|
array<int, 2> a({16, 16}, 42);
|
||||||
|
|
||||||
|
auto p = a.data();
|
||||||
|
|
||||||
|
array<int, 2> b(std::move(a));
|
||||||
|
expect(a.empty());
|
||||||
|
expect_equal(a.size(), 0);
|
||||||
|
expect(!b.empty());
|
||||||
|
expect_equal(b.size(), 256);
|
||||||
|
expect_equal_ptr(b.data(), p);
|
||||||
|
|
||||||
|
array<int, 2> c;
|
||||||
|
c = std::move(b);
|
||||||
|
expect(b.empty());
|
||||||
|
expect_equal(b.size(), 0);
|
||||||
|
expect(!c.empty());
|
||||||
|
expect_equal(c.size(), 256);
|
||||||
|
expect_equal_ptr(c.data(), p);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_array_copy)
|
||||||
|
{
|
||||||
|
array<int, 2> a({16, 16}, 42);
|
||||||
|
|
||||||
|
array<int, 2> b(a.copy());
|
||||||
|
expect(!a.empty());
|
||||||
|
expect(!b.empty());
|
||||||
|
expect_equal(a.size(), b.size());
|
||||||
|
expect_equal(a.size(), 256);
|
||||||
|
expect_different_ptr(a.data(), b.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_array_lifetime)
|
||||||
|
{
|
||||||
|
std::weak_ptr<int> p;
|
||||||
|
|
||||||
|
{
|
||||||
|
array<std::shared_ptr<int>, 2> a({16, 16}, std::make_shared<int>(42));
|
||||||
|
p = a(0, 0);
|
||||||
|
for (std::size_t i = 0; i < a.width(); ++i)
|
||||||
|
{
|
||||||
|
for (std::size_t j = 0; j < a.height(); ++j)
|
||||||
|
{
|
||||||
|
expect(a(i, j));
|
||||||
|
expect_equal(*a(i, j), 42);
|
||||||
|
expect_equal(a(i, j).use_count(), a.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(!p.lock());
|
||||||
|
expect_equal(p.use_count(), 0);
|
||||||
|
}
|
||||||
98
libs/util/tests/blob.cpp
Normal file
98
libs/util/tests/blob.cpp
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
#include <psemek/test/test.hpp>
|
||||||
|
|
||||||
|
#include <psemek/util/blob.hpp>
|
||||||
|
|
||||||
|
using namespace psemek::util;
|
||||||
|
|
||||||
|
test_case(util_blob_empty)
|
||||||
|
{
|
||||||
|
blob b;
|
||||||
|
expect(!b);
|
||||||
|
expect_equal(b.size(), 0);
|
||||||
|
expect_equal_ptr(b.data(), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_blob_alloc)
|
||||||
|
{
|
||||||
|
blob b(16);
|
||||||
|
expect(b);
|
||||||
|
expect_equal(b.size(), 16);
|
||||||
|
expect_different_ptr(b.data(), nullptr);
|
||||||
|
|
||||||
|
for (int i = 0; i < b.size(); ++i)
|
||||||
|
b[i] = static_cast<char>(i);
|
||||||
|
|
||||||
|
for (int i = 0; i < b.size(); ++i)
|
||||||
|
expect_equal((int)b[i], i);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_blob_release)
|
||||||
|
{
|
||||||
|
blob b;
|
||||||
|
expect(!b);
|
||||||
|
expect_equal(b.size(), 0);
|
||||||
|
expect_equal_ptr(b.data(), nullptr);
|
||||||
|
|
||||||
|
std::unique_ptr<char[]> p(new char[16]);
|
||||||
|
auto q = p.get();
|
||||||
|
|
||||||
|
b = blob(16, std::move(p));
|
||||||
|
expect(b);
|
||||||
|
expect_equal(b.size(), 16);
|
||||||
|
expect_equal_ptr(b.data(), q);
|
||||||
|
|
||||||
|
p = b.release();
|
||||||
|
|
||||||
|
expect(!b);
|
||||||
|
expect_equal(b.size(), 0);
|
||||||
|
expect_equal_ptr(b.data(), nullptr);
|
||||||
|
expect_equal(p.get(), q);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_blob_copy)
|
||||||
|
{
|
||||||
|
blob b(16);
|
||||||
|
expect(b);
|
||||||
|
expect_equal(b.size(), 16);
|
||||||
|
expect_different_ptr(b.data(), nullptr);
|
||||||
|
|
||||||
|
blob c(b);
|
||||||
|
expect(c);
|
||||||
|
expect_equal(c.size(), 16);
|
||||||
|
expect_different_ptr(c.data(), nullptr);
|
||||||
|
|
||||||
|
blob d;
|
||||||
|
expect(!d);
|
||||||
|
expect_equal(d.size(), 0);
|
||||||
|
expect_equal_ptr(d.data(), nullptr);
|
||||||
|
|
||||||
|
d = c;
|
||||||
|
expect(d);
|
||||||
|
expect_equal(d.size(), 16);
|
||||||
|
expect_different_ptr(d.data(), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_blob_move)
|
||||||
|
{
|
||||||
|
blob b(16);
|
||||||
|
expect(b);
|
||||||
|
expect_equal(b.size(), 16);
|
||||||
|
expect_different_ptr(b.data(), nullptr);
|
||||||
|
|
||||||
|
auto p = b.data();
|
||||||
|
|
||||||
|
blob c(std::move(b));
|
||||||
|
expect(c);
|
||||||
|
expect_equal(c.size(), 16);
|
||||||
|
expect_equal_ptr(c.data(), p);
|
||||||
|
|
||||||
|
blob d;
|
||||||
|
expect(!d);
|
||||||
|
expect_equal(d.size(), 0);
|
||||||
|
expect_equal_ptr(d.data(), nullptr);
|
||||||
|
|
||||||
|
d = std::move(c);
|
||||||
|
expect(d);
|
||||||
|
expect_equal(d.size(), 16);
|
||||||
|
expect_equal_ptr(d.data(), p);
|
||||||
|
}
|
||||||
209
libs/util/tests/function.cpp
Normal file
209
libs/util/tests/function.cpp
Normal file
|
|
@ -0,0 +1,209 @@
|
||||||
|
#include <psemek/test/test.hpp>
|
||||||
|
|
||||||
|
#include <psemek/util/function.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
using namespace psemek::util;
|
||||||
|
|
||||||
|
test_case(util_function_empty_call)
|
||||||
|
{
|
||||||
|
function<void()> f;
|
||||||
|
expect_throw(f(), std::bad_function_call);
|
||||||
|
}
|
||||||
|
|
||||||
|
using heavy = std::array<int, 256>;
|
||||||
|
|
||||||
|
static void util_function_assign_test(bool light)
|
||||||
|
{
|
||||||
|
function<void()> f;
|
||||||
|
expect(!f);
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
if (light)
|
||||||
|
f = [&counter]{ ++counter; };
|
||||||
|
else
|
||||||
|
f = [&counter, h = heavy{}]{ ++counter; };
|
||||||
|
expect(f);
|
||||||
|
|
||||||
|
expect_equal(counter, 0);
|
||||||
|
f();
|
||||||
|
expect_equal(counter, 1);
|
||||||
|
f();
|
||||||
|
expect_equal(counter, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void util_function_move_test(bool light)
|
||||||
|
{
|
||||||
|
function<void()> f;
|
||||||
|
expect(!f);
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
if (light)
|
||||||
|
f = [&counter]{ ++counter; };
|
||||||
|
else
|
||||||
|
f = [&counter, h = heavy{}]{ ++counter; };
|
||||||
|
expect(f);
|
||||||
|
|
||||||
|
function<void()> g;
|
||||||
|
expect(!g);
|
||||||
|
|
||||||
|
g = std::move(f);
|
||||||
|
expect(!f);
|
||||||
|
expect(g);
|
||||||
|
|
||||||
|
expect_equal(counter, 0);
|
||||||
|
g();
|
||||||
|
expect_equal(counter, 1);
|
||||||
|
g();
|
||||||
|
expect_equal(counter, 2);
|
||||||
|
|
||||||
|
function<void()> h = std::move(g);
|
||||||
|
expect(!f);
|
||||||
|
expect(!g);
|
||||||
|
expect(h);
|
||||||
|
|
||||||
|
expect_equal(counter, 2);
|
||||||
|
h();
|
||||||
|
expect_equal(counter, 3);
|
||||||
|
h();
|
||||||
|
expect_equal(counter, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void util_function_destroy_test(bool light)
|
||||||
|
{
|
||||||
|
std::shared_ptr<int> p = std::make_shared<int>(0);
|
||||||
|
|
||||||
|
auto wp = std::weak_ptr(p);
|
||||||
|
|
||||||
|
{
|
||||||
|
function<void()> f, g;
|
||||||
|
expect(!f);
|
||||||
|
expect(!g);
|
||||||
|
|
||||||
|
if (light)
|
||||||
|
{
|
||||||
|
f = [p]{ ++*p; };
|
||||||
|
g = [p]{ --*p; };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
f = [p, h = heavy{}]{ ++*p; };
|
||||||
|
g = [p, h = heavy{}]{ --*p; };
|
||||||
|
}
|
||||||
|
expect(f);
|
||||||
|
expect(g);
|
||||||
|
expect(p);
|
||||||
|
expect_equal(p.use_count(), 3);
|
||||||
|
expect_equal(*p, 0);
|
||||||
|
|
||||||
|
p.reset();
|
||||||
|
expect(wp.lock());
|
||||||
|
expect_equal(wp.use_count(), 2);
|
||||||
|
|
||||||
|
expect_equal(*wp.lock(), 0);
|
||||||
|
f();
|
||||||
|
expect_equal(*wp.lock(), 1);
|
||||||
|
f();
|
||||||
|
expect_equal(*wp.lock(), 2);
|
||||||
|
g();
|
||||||
|
expect_equal(*wp.lock(), 1);
|
||||||
|
g();
|
||||||
|
expect_equal(*wp.lock(), 0);
|
||||||
|
|
||||||
|
f.reset();
|
||||||
|
expect(!f);
|
||||||
|
expect(wp.lock());
|
||||||
|
expect_equal(wp.use_count(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(!wp.lock());
|
||||||
|
expect_equal(wp.use_count(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
struct fake_exception
|
||||||
|
: std::exception
|
||||||
|
{
|
||||||
|
char const * what() const noexcept { return "fake"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Heavy>
|
||||||
|
struct throw_on_move
|
||||||
|
{
|
||||||
|
Heavy heavy;
|
||||||
|
|
||||||
|
throw_on_move() = default;
|
||||||
|
throw_on_move(throw_on_move &&)
|
||||||
|
{
|
||||||
|
throw fake_exception{};
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()()
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void util_function_guarantee_test(bool light)
|
||||||
|
{
|
||||||
|
function<void()> f;
|
||||||
|
expect(!f);
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
f = [&counter]{ ++counter; };
|
||||||
|
expect(f);
|
||||||
|
expect_equal(counter, 0);
|
||||||
|
|
||||||
|
if (light)
|
||||||
|
expect_throw(f = throw_on_move<int>{}, fake_exception);
|
||||||
|
else
|
||||||
|
expect_throw(f = throw_on_move<heavy>{}, fake_exception);
|
||||||
|
|
||||||
|
expect(f);
|
||||||
|
expect_equal(counter, 0);
|
||||||
|
f();
|
||||||
|
expect_equal(counter, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_function_light_assign)
|
||||||
|
{
|
||||||
|
util_function_assign_test(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_function_light_move)
|
||||||
|
{
|
||||||
|
util_function_move_test(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_function_light_destroy)
|
||||||
|
{
|
||||||
|
util_function_destroy_test(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_function_light_guarantee)
|
||||||
|
{
|
||||||
|
util_function_guarantee_test(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_function_heavy_assign)
|
||||||
|
{
|
||||||
|
util_function_assign_test(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_function_heavy_move)
|
||||||
|
{
|
||||||
|
util_function_move_test(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_function_heavy_destroy)
|
||||||
|
{
|
||||||
|
util_function_destroy_test(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_case(util_function_heavy_guarantee)
|
||||||
|
{
|
||||||
|
util_function_guarantee_test(false);
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue