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})
|
||||
target_include_directories(psemek-util PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
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