Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 79 additions & 47 deletions Src/Tests/Any.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Created by Arthur on 08/10/2025.
//

#include <gtest/gtest.h>
#include <catch2/catch_test_macros.hpp>

#include <Concerto/Core/Any/Any.hpp>
#include <Concerto/Core/TypeInfo/TypeInfo.hpp>
Expand All @@ -19,55 +19,87 @@ namespace CCT_ANONYMOUS_NAMESPACE
std::array<char, 64> buf{}; // ensure > small buffer
};

TEST(Any, SmallValue)
SCENARIO("Any")
{
auto a = Any::Make<int>(42);
ASSERT_TRUE(a.HasValue());
ASSERT_TRUE(a.Is<int>());
ASSERT_FALSE(a.Is<float>());
EXPECT_EQ(a.As<int>(), 42);

a.Reset();
EXPECT_FALSE(a.HasValue());
}
GIVEN("An Any holding a small value (int 42)")
{
auto a = Any::Make<int>(42);

TEST(Any, LargeValue)
{
Big b(99);
auto a = Any::Make<Big>(b);
ASSERT_TRUE(a.HasValue());
ASSERT_TRUE(a.Is<Big>());
auto v = a.As<Big>();
EXPECT_EQ(v.x, 99);
}
THEN("It has a value, is of type int, and returns the correct value")
{
REQUIRE(a.HasValue());
REQUIRE(a.Is<int>());
REQUIRE_FALSE(a.Is<float>());
CHECK(a.As<int>() == 42);
}

TEST(Any, Pointer)
{
int v = 5;
auto a = Any::Make<int*>(&v);
ASSERT_TRUE(a.HasValue());
ASSERT_TRUE(a.Is<int*>());
int* p = a.As<int*>();
*p = 11;
EXPECT_EQ(v, 11);
}
WHEN("Reset() is called")
{
a.Reset();
THEN("It has no value") { CHECK_FALSE(a.HasValue()); }
}
}

TEST(Any, Reference)
{
int v = 7;
auto a = Any::Make<int&>(v);
ASSERT_TRUE(a.HasValue());
ASSERT_TRUE(a.Is<int&>());
int& r = a.As<int&>();
r = 15;
EXPECT_EQ(v, 15);
}
GIVEN("An Any holding a large value (Big with x=99)")
{
Big b(99);
auto a = Any::Make<Big>(b);

TEST(Any, WrongCastThrows)
{
auto a = Any::Make<int>(3);
ASSERT_TRUE(a.Is<int>());
EXPECT_THROW((void)a.As<float>(), std::bad_cast);
}
}
THEN("It has a value, is of type Big, and x is 99")
{
REQUIRE(a.HasValue());
REQUIRE(a.Is<Big>());
CHECK(a.As<Big>().x == 99);
}
}

GIVEN("An Any holding a pointer to int")
{
int v = 5;
auto a = Any::Make<int*>(&v);

THEN("It has a value and is of type int*")
{
REQUIRE(a.HasValue());
REQUIRE(a.Is<int*>());
}

WHEN("The pointer is dereferenced and modified")
{
int* p = a.As<int*>();
*p = 11;
THEN("The original value is modified") { CHECK(v == 11); }
}
}

GIVEN("An Any holding a reference to int")
{
int v = 7;
auto a = Any::Make<int&>(v);

THEN("It has a value and is of type int&")
{
REQUIRE(a.HasValue());
REQUIRE(a.Is<int&>());
}

WHEN("The reference is modified")
{
int& r = a.As<int&>();
r = 15;
THEN("The original value is modified") { CHECK(v == 15); }
}
}

GIVEN("An Any holding an int")
{
auto a = Any::Make<int>(3);
REQUIRE(a.Is<int>());

WHEN("Cast to float")
{
THEN("It throws std::bad_cast") { CHECK_THROWS_AS((void)a.As<float>(), std::bad_cast); }
}
}
}
} // namespace CCT_ANONYMOUS_NAMESPACE
55 changes: 34 additions & 21 deletions Src/Tests/Cast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#include <string_view>

#include <gtest/gtest.h>
#include <catch2/catch_test_macros.hpp>

#include <Concerto/Core/Cast.hpp>

Expand All @@ -30,29 +30,42 @@ namespace CCT_ANONYMOUS_NAMESPACE
}
};

TEST(CastTest, ValidCast) {
Derived derived;
Base& base = derived;
SCENARIO("Cast")
{
GIVEN("A Derived object referenced as Base&")
{
Derived derived;
Base& base = derived;

Derived& casted = Cast<Derived&>(base);

EXPECT_EQ(casted.Speak(), DerivedStr);
}

TEST(CastTest, RvalueCast) {
Derived derived;
Base&& base = std::move(derived);
WHEN("Cast to Derived&")
{
Derived& casted = Cast<Derived&>(base);
THEN("The cast succeeds and Speak() returns DerivedStr") { CHECK(casted.Speak() == DerivedStr); }
}
}

Derived&& casted = Cast<Derived&&>(std::move(base));
GIVEN("A Derived object as Base&&")
{
Derived derived;
Base&& base = std::move(derived);

EXPECT_EQ(casted.Speak(), DerivedStr);
}
WHEN("Cast to Derived&&")
{
Derived&& casted = Cast<Derived&&>(std::move(base));
THEN("The cast succeeds") { CHECK(casted.Speak() == DerivedStr); }
}
}

TEST(CastTest, ConstReferenceCast) {
const Derived derived;
const Base& base = derived;
auto& casted = Cast<const Derived&>(base);
GIVEN("A const Derived object as const Base&")
{
const Derived derived;
const Base& base = derived;

EXPECT_EQ(casted.Speak(), DerivedStr);
WHEN("Cast to const Derived&")
{
auto& casted = Cast<const Derived&>(base);
THEN("The cast succeeds") { CHECK(casted.Speak() == DerivedStr); }
}
}
}
}
} // namespace CCT_ANONYMOUS_NAMESPACE
19 changes: 11 additions & 8 deletions Src/Tests/DeferredExit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Created by arthur on 23/02/2023.
//

#include <gtest/gtest.h>
#include <catch2/catch_test_macros.hpp>

#include "Concerto/Core/DeferredExit/DeferredExit.hpp"
#include "Concerto/Core/Types/Types.hpp"
Expand All @@ -11,15 +11,18 @@ namespace CCT_ANONYMOUS_NAMESPACE
{
using namespace cct;

TEST(DeferredExit, General)
SCENARIO("DeferredExit")
{
Int32 i = 0;
GIVEN("A DeferredExit with a callback that sets i = 42")
{
DeferredExit _([&]()
Int32 i = 0;
{
i = 42;
});
DeferredExit _([&]()
{
i = 42;
});
}
THEN("The callback is invoked when the DeferredExit goes out of scope") { REQUIRE(i == 42); }
}
ASSERT_EQ(i, 42);
}
}// namespace CCT_ANONYMOUS_NAMESPACE
} // namespace CCT_ANONYMOUS_NAMESPACE
115 changes: 73 additions & 42 deletions Src/Tests/DynLib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Created by arthur on 02/06/2024.
//

#include <gtest/gtest.h>
#include <catch2/catch_test_macros.hpp>
#include <Concerto/Core/DynLib/DynLib.hpp>

#ifdef CCT_PLATFORM_POSIX
Expand All @@ -13,51 +13,82 @@

namespace CCT_ANONYMOUS_NAMESPACE
{
TEST(DynLib, Invoke)
SCENARIO("DynLib - Invoke")
{
cct::DynLib lib;
bool res = lib.Load(PREFIX"concerto-core-dummy");
EXPECT_TRUE(res);

lib.Invoke<void>("Dummy");
const cct::FunctionRef func = lib.GetFunction<void>("Dummy");
ASSERT_EQ(func.operator bool(), true);
{
const int value = lib.Invoke<int>("DummyInt");
ASSERT_EQ(value, 42);
}
GIVEN("A DynLib loaded with the dummy library")
{
const int* globalValue = lib.GetValue<int>("GlobalInt");
if (globalValue == nullptr)
FAIL();
ASSERT_EQ(globalValue != nullptr, true);
ASSERT_EQ(*globalValue, 42);
}
{
const int* notExisting = lib.GetValue<int>("NotExisting");
ASSERT_EQ(notExisting, nullptr);
}
{
const int value = lib.Invoke<int>("Increment", 5);
ASSERT_EQ(value, 5 + 1);
}
{
ASSERT_THROW(lib.Invoke<int>("NotExisting", 5), std::runtime_error);
}
cct::DynLib lib;
REQUIRE(lib.Load(PREFIX "concerto-core-dummy"));

WHEN("Dummy() is invoked")
{
lib.Invoke<void>("Dummy");
const cct::FunctionRef func = lib.GetFunction<void>("Dummy");
THEN("The function handle is valid") { CHECK(func.operator bool() == true); }
}

res = lib.Unload();
ASSERT_EQ(res, true);
WHEN("DummyInt() is invoked")
{
THEN("It returns 42") { CHECK(lib.Invoke<int>("DummyInt") == 42); }
}

WHEN("GlobalInt is retrieved")
{
const int* globalValue = lib.GetValue<int>("GlobalInt");
THEN("The pointer is valid and the value is 42")
{
REQUIRE(globalValue != nullptr);
CHECK(*globalValue == 42);
}
}

WHEN("A non-existing value is retrieved")
{
const int* notExisting = lib.GetValue<int>("NotExisting");
THEN("It returns nullptr") { CHECK(notExisting == nullptr); }
}

WHEN("Increment(5) is invoked")
{
THEN("It returns 6") { CHECK(lib.Invoke<int>("Increment", 5) == 6); }
}

WHEN("A non-existing function is invoked")
{
THEN("It throws std::runtime_error") { CHECK_THROWS_AS(lib.Invoke<int>("NotExisting", 5), std::runtime_error); }
}

WHEN("The library is unloaded")
{
bool res = lib.Unload();
THEN("Unload returns true") { CHECK(res == true); }
}
}
}

TEST(DynLib, Loading)
SCENARIO("DynLib - Loading")
{
cct::DynLib lib;
EXPECT_FALSE(lib.Unload());
bool res = lib.Load(PREFIX"not-exist");
EXPECT_FALSE(res);
EXPECT_EQ(lib.GetSymbol("foo"), nullptr);

res = lib.Load(PREFIX"concerto-core-dummy");
EXPECT_TRUE(res);
GIVEN("An empty DynLib")
{
cct::DynLib lib;

THEN("Unload on an empty library returns false") { CHECK_FALSE(lib.Unload()); }

WHEN("A non-existing library is loaded")
{
bool res = lib.Load(PREFIX "not-exist");
THEN("Load returns false and GetSymbol returns nullptr")
{
CHECK_FALSE(res);
CHECK(lib.GetSymbol("foo") == nullptr);
}
}

WHEN("The dummy library is loaded")
{
bool res = lib.Load(PREFIX "concerto-core-dummy");
THEN("Load returns true") { CHECK(res); }
}
}
}
} // namespace CCT_ANONYMOUS_NAMESPACE
} // namespace CCT_ANONYMOUS_NAMESPACE
Loading
Loading