From 2a10eaae094e48a157d55ec886aaa07b0d0be6c9 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Mon, 28 Oct 2024 23:52:48 +0100 Subject: Some work on test framework & option --- asl/tests/format_tests.cpp | 40 ++++++++++----------- asl/tests/option_tests.cpp | 87 +++++++++++++++++++++++++++++++++++++--------- asl/tests/test_types.hpp | 30 ++++++++++++++++ 3 files changed, 121 insertions(+), 36 deletions(-) (limited to 'asl/tests') diff --git a/asl/tests/format_tests.cpp b/asl/tests/format_tests.cpp index 6e2430d..f4ca2cf 100644 --- a/asl/tests/format_tests.cpp +++ b/asl/tests/format_tests.cpp @@ -1,4 +1,5 @@ #include "asl/format.hpp" +#include "asl/testing/testing.hpp" #include #include @@ -33,74 +34,73 @@ public: } }; -int main2() +ASL_TEST(Format) { StringSink sink; - // @Todo Use the testing framework + // @Todo Introduce ASL_TEST_ASSERT_EQ, or ASL_TEST_ASSERT_STREQ + // @Todo Don't use strcmp for string comparison asl::format(&sink, "Hello, world!"); - assert(strcmp(sink.cstr(), "Hello, world!") == 0); + ASL_TEST_ASSERT(strcmp(sink.cstr(), "Hello, world!") == 0); sink.reset(); asl::format(&sink, ""); - assert(strcmp(sink.cstr(), "") == 0); + ASL_TEST_ASSERT(strcmp(sink.cstr(), "") == 0); sink.reset(); asl::format(&sink, "Hello, {}!", "world"); - assert(strcmp(sink.cstr(), "Hello, world!") == 0); + ASL_TEST_ASSERT(strcmp(sink.cstr(), "Hello, world!") == 0); sink.reset(); asl::format(&sink, "Hello, {}! {}", "world"); - assert(strcmp(sink.cstr(), "Hello, world! ") == 0); + ASL_TEST_ASSERT(strcmp(sink.cstr(), "Hello, world! ") == 0); sink.reset(); asl::format(&sink, "Hello, pup!", "world"); - assert(strcmp(sink.cstr(), "Hello, pup!") == 0); + ASL_TEST_ASSERT(strcmp(sink.cstr(), "Hello, pup!") == 0); sink.reset(); asl::format(&sink, "{}", "CHEESE"); - assert(strcmp(sink.cstr(), "CHEESE") == 0); + ASL_TEST_ASSERT(strcmp(sink.cstr(), "CHEESE") == 0); sink.reset(); asl::format(&sink, "{ ", "CHEESE"); - assert(strcmp(sink.cstr(), " ") == 0); + ASL_TEST_ASSERT(strcmp(sink.cstr(), " ") == 0); sink.reset(); asl::format(&sink, "{", "CHEESE"); - assert(strcmp(sink.cstr(), "") == 0); + ASL_TEST_ASSERT(strcmp(sink.cstr(), "") == 0); sink.reset(); asl::format(&sink, "a{{b"); - assert(strcmp(sink.cstr(), "a{b") == 0); + ASL_TEST_ASSERT(strcmp(sink.cstr(), "a{b") == 0); sink.reset(); asl::format(&sink, "{{{}}} }", "CHEESE"); - assert(strcmp(sink.cstr(), "{CHEESE} }") == 0); + ASL_TEST_ASSERT(strcmp(sink.cstr(), "{CHEESE} }") == 0); sink.reset(); asl::format(&sink, "{} {} {}", 0, 1, 2); - assert(strcmp(sink.cstr(), "0 1 2") == 0); + ASL_TEST_ASSERT(strcmp(sink.cstr(), "0 1 2") == 0); sink.reset(); asl::format(&sink, "{} {} {}", 10, 11, 12); - assert(strcmp(sink.cstr(), "10 11 12") == 0); + ASL_TEST_ASSERT(strcmp(sink.cstr(), "10 11 12") == 0); sink.reset(); asl::format(&sink, "{} {} {}", 100, 101, 102); - assert(strcmp(sink.cstr(), "100 101 102") == 0); + ASL_TEST_ASSERT(strcmp(sink.cstr(), "100 101 102") == 0); sink.reset(); asl::format(&sink, "{} {} {}", 1000, 1001, 1002); - assert(strcmp(sink.cstr(), "1000 1001 1002") == 0); + ASL_TEST_ASSERT(strcmp(sink.cstr(), "1000 1001 1002") == 0); sink.reset(); asl::format(&sink, "{} {} {} {}", -1, -23, -456, -7890); - assert(strcmp(sink.cstr(), "-1 -23 -456 -7890") == 0); + ASL_TEST_ASSERT(strcmp(sink.cstr(), "-1 -23 -456 -7890") == 0); sink.reset(); asl::format(&sink, "{} {}", true, false); - assert(strcmp(sink.cstr(), "true false") == 0); - - return 0; + ASL_TEST_ASSERT(strcmp(sink.cstr(), "true false") == 0); } diff --git a/asl/tests/option_tests.cpp b/asl/tests/option_tests.cpp index e423cc9..e7fff8b 100644 --- a/asl/tests/option_tests.cpp +++ b/asl/tests/option_tests.cpp @@ -24,35 +24,90 @@ static_assert(asl::move_assignable>); static_assert(asl::move_assignable>); static_assert(!asl::move_assignable>); -ASL_TEST(Option_cheese) +ASL_TEST(make_null) { asl::option a; - asl::option b; + asl::option b = asl::nullopt; - a = ASL_MOVE(b); + ASL_TEST_EXPECT(!a.has_value()); + ASL_TEST_EXPECT(!b.has_value()); } -ASL_TEST(Option_cheese2) +ASL_TEST(make_value) { - asl::option a; - asl::option b; + asl::option a = 48; - a = ASL_MOVE(b); + ASL_TEST_EXPECT(a.has_value()); } -ASL_TEST(Option_cheese3) +ASL_TEST(reset) { - asl::option a; - asl::option b; + asl::option b = 48; + ASL_TEST_EXPECT(b.has_value()); + + b.reset(); + ASL_TEST_EXPECT(!b.has_value()); +} + +ASL_TEST(call_destructor) +{ + bool destroyed = false; + + { + DestructorObserver obs(&destroyed); + + asl::option opt(ASL_MOVE(obs)); + ASL_TEST_EXPECT(!destroyed); + + asl::option opt2 = ASL_MOVE(opt); + ASL_TEST_EXPECT(!destroyed); + } - a = ASL_MOVE(b); - asl::testing::report_failure("OH NO", __FILE__, __LINE__); + ASL_TEST_EXPECT(destroyed); } -ASL_TEST(Option_cheese4) +ASL_TEST(call_destructor_on_reset) { - asl::option a; - asl::option b; + bool destroyed = false; + + asl::option opt(&destroyed); + ASL_TEST_EXPECT(!destroyed); + + opt.reset(); + ASL_TEST_EXPECT(destroyed); +} + +ASL_TEST(value) +{ + asl::option a = 1; + asl::option b = 2; + asl::option c = a; + + ASL_TEST_EXPECT(a.value() == 1); + ASL_TEST_EXPECT(b.value() == 2); + ASL_TEST_EXPECT(c.value() == 1); - a = ASL_MOVE(b); + c = b; + ASL_TEST_EXPECT(c.value() == 2); +} + +ASL_TEST(value_move) +{ + bool destroyed = false; + + asl::option opt(&destroyed); + ASL_TEST_EXPECT(!destroyed); + + { + auto x = ASL_MOVE(opt).value(); + ASL_TEST_EXPECT(!destroyed); + } + + ASL_TEST_EXPECT(destroyed); +} + +ASL_TEST(deduction_guide) +{ + asl::option opt(45); + ASL_TEST_EXPECT(opt.value() == 45); } diff --git a/asl/tests/test_types.hpp b/asl/tests/test_types.hpp index da1faa6..cabc084 100644 --- a/asl/tests/test_types.hpp +++ b/asl/tests/test_types.hpp @@ -1,5 +1,7 @@ #pragma once +#include "asl/utility.hpp" + struct DefaultConstructible { DefaultConstructible() {} }; struct TriviallyDefaultConstructible { TriviallyDefaultConstructible() = default; }; struct NonDefaultConstructible { NonDefaultConstructible() = delete; }; @@ -23,3 +25,31 @@ struct NonMoveAssignable { NonMoveAssignable& operator=(NonMoveAssignable&&) = d struct TriviallyDestructible { ~TriviallyDestructible() = default; }; struct HasDestructor { ~HasDestructor() {} }; +struct DestructorObserver +{ + bool* destroyed; + + explicit DestructorObserver(bool* destroyed_) : destroyed{destroyed_} {} + + DestructorObserver(DestructorObserver&& other) + : destroyed{asl::exchange(other.destroyed, nullptr)} + {} + + DestructorObserver& operator=(DestructorObserver&& other) + { + if (this != &other) + { + destroyed = asl::exchange(other.destroyed, nullptr); + } + return *this; + } + + ~DestructorObserver() + { + if (destroyed != nullptr) + { + *destroyed = true; + } + } +}; + -- cgit