summaryrefslogtreecommitdiff
path: root/lib/tests
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@gmail.com>2025-05-12 16:21:53 +0200
committerFelix Morgner <felix.morgner@gmail.com>2025-05-12 16:21:53 +0200
commita2c73b6ba3c9ea307b0b0eb94c9e769a1f31dc00 (patch)
tree4235e54f0557c76b1226367b8cd5e5f561d7662a /lib/tests
parent45ef4948db670224c7cc727507f84924bd826002 (diff)
downloadturns-a2c73b6ba3c9ea307b0b0eb94c9e769a1f31dc00.tar.xz
turns-a2c73b6ba3c9ea307b0b0eb94c9e769a1f31dc00.zip
lib: move C library to new directory
Diffstat (limited to 'lib/tests')
-rw-r--r--lib/tests/runtime_init.cpp21
-rw-r--r--lib/tests/turns-participant.cpp353
2 files changed, 374 insertions, 0 deletions
diff --git a/lib/tests/runtime_init.cpp b/lib/tests/runtime_init.cpp
new file mode 100644
index 0000000..189ef35
--- /dev/null
+++ b/lib/tests/runtime_init.cpp
@@ -0,0 +1,21 @@
+#include "turns-init.h"
+
+#include <catch2/reporters/catch_reporter_event_listener.hpp>
+#include <catch2/reporters/catch_reporter_registrars.hpp>
+
+namespace turns::core::tests
+{
+
+ struct glib_test_init : Catch::EventListenerBase
+ {
+ using Catch::EventListenerBase::EventListenerBase;
+
+ auto testRunStarting(Catch::TestRunInfo const &) -> void override
+ {
+ turns_init();
+ }
+ };
+
+ CATCH_REGISTER_LISTENER(glib_test_init);
+
+} // namespace turns::core::tests \ No newline at end of file
diff --git a/lib/tests/turns-participant.cpp b/lib/tests/turns-participant.cpp
new file mode 100644
index 0000000..89e60cf
--- /dev/null
+++ b/lib/tests/turns-participant.cpp
@@ -0,0 +1,353 @@
+#include "turns-participant.h"
+
+#include "turns-disposition.h"
+
+#include <catch2/catch_approx.hpp>
+#include <catch2/catch_test_macros.hpp>
+#include <catch2/generators/catch_generators.hpp>
+
+#include <glib-object.h>
+#include <glib.h>
+
+#include <string>
+
+namespace
+{
+ auto record_notification(TurnsParticipant const *, GParamSpec *, bool * out) -> void
+ {
+ *out = true;
+ }
+} // namespace
+
+SCENARIO("Creating a participant", "[lib][object][lifetime]")
+{
+ GIVEN("A participant constructed using turns_participant_new()")
+ {
+ g_autoptr(TurnsParticipant) instance = turns_participant_new();
+
+ THEN("it's name is empty")
+ {
+ auto name = turns_participant_get_name(instance);
+ REQUIRE(name);
+ REQUIRE(std::string{name}.empty());
+ }
+
+ THEN("it's priority is 0.0f")
+ {
+ REQUIRE(turns_participant_get_priority(instance) == Catch::Approx{0.0});
+ }
+
+ THEN("it's disposition is neutral")
+ {
+ REQUIRE(turns_participant_get_disposition(instance) == TURNS_DISPOSITION_NEUTRAL);
+ }
+ }
+
+ GIVEN("A participant constructed using turns_participant_new_with(...)")
+ {
+ auto name = "Test Participant";
+ auto priority = 12.4f;
+ auto disposition = TURNS_DISPOSITION_FRIENDLY;
+ g_autoptr(TurnsParticipant) instance = turns_participant_new_with(name, priority, disposition);
+
+ THEN("it's name is set")
+ {
+ REQUIRE(turns_participant_get_name(instance) == std::string{name});
+ }
+
+ THEN("it's priority is set")
+ {
+ REQUIRE(turns_participant_get_priority(instance) == Catch::Approx{priority});
+ }
+
+ THEN("it's disposition is")
+ {
+ REQUIRE(turns_participant_get_disposition(instance) == disposition);
+ }
+ }
+
+ GIVEN("A participant is constructed using turns_participant_new_with(nullptr, ...)")
+ {
+ auto instance = turns_participant_new_with(nullptr, 10.0f, TURNS_DISPOSITION_HOSTILE);
+
+ THEN("the instance is NULL")
+ {
+ REQUIRE(instance == nullptr);
+ }
+ }
+}
+
+SCENARIO("Modifying a participant", "[lib][object][data]")
+{
+ GIVEN("A default participant instance")
+ {
+ g_autoptr(TurnsParticipant) instance = turns_participant_new();
+
+ WHEN("a new new is set")
+ {
+ auto new_value = "Test Participant";
+
+ CHECK(std::string{turns_participant_get_name(instance)}.empty());
+ CHECK_FALSE(std::string{turns_participant_get_name(instance)} == new_value);
+ turns_participant_set_name(instance, new_value);
+
+ THEN("it's name is not empty")
+ {
+ REQUIRE_FALSE(std::string{turns_participant_get_name(instance)}.empty());
+ }
+
+ THEN("it's name has the new value")
+ {
+ REQUIRE(std::string{turns_participant_get_name(instance)} == new_value);
+ }
+ }
+
+ WHEN("a new priority is set")
+ {
+ auto new_value = GENERATE(-8.0f, 12.0f, 4.0f);
+
+ CHECK_FALSE(turns_participant_get_priority(instance) == new_value);
+ turns_participant_set_priority(instance, new_value);
+
+ THEN("it's priority has the new value")
+ {
+ REQUIRE(turns_participant_get_priority(instance) == Catch::Approx{new_value});
+ }
+ }
+
+ WHEN("a new disposition is set")
+ {
+ auto new_value = GENERATE(TURNS_DISPOSITION_FRIENDLY, TURNS_DISPOSITION_HOSTILE, TURNS_DISPOSITION_SECRET);
+
+ CHECK_FALSE(turns_participant_get_disposition(instance) == new_value);
+ turns_participant_set_disposition(instance, new_value);
+
+ THEN("it's disposition has the new value")
+ {
+ REQUIRE(turns_participant_get_disposition(instance) == new_value);
+ }
+ }
+
+ AND_GIVEN("a signal handler has been subscribed to the name property")
+ {
+ auto was_notified = false;
+ g_signal_connect(instance, "notify::name", G_CALLBACK(&record_notification), &was_notified);
+
+ WHEN("a new name is set using set_name")
+ {
+ auto new_value = "Test Participant";
+
+ CHECK_FALSE(std::string{turns_participant_get_name(instance)} == new_value);
+ turns_participant_set_name(instance, new_value);
+
+ THEN("a notification is issued")
+ {
+ REQUIRE(was_notified);
+ }
+ }
+
+ WHEN("the same name is set using set_name")
+ {
+ auto new_value = turns_participant_get_name(instance);
+
+ CHECK(std::string{turns_participant_get_name(instance)} == new_value);
+ turns_participant_set_name(instance, new_value);
+
+ THEN("no notification is issued")
+ {
+ REQUIRE_FALSE(was_notified);
+ }
+ }
+
+ WHEN("a new name is set using g_object_set")
+ {
+ auto new_value = "Test Participant";
+
+ CHECK_FALSE(std::string{turns_participant_get_name(instance)} == new_value);
+ g_object_set(G_OBJECT(instance), "name", new_value, nullptr);
+
+ THEN("a notification is issued")
+ {
+ REQUIRE(was_notified);
+ }
+ }
+
+ WHEN("the same name is set using g_object_set")
+ {
+ auto new_value = turns_participant_get_name(instance);
+
+ CHECK(std::string{turns_participant_get_name(instance)} == new_value);
+ g_object_set(G_OBJECT(instance), "name", new_value, nullptr);
+
+ THEN("no notification is issued")
+ {
+ REQUIRE_FALSE(was_notified);
+ }
+ }
+ }
+
+ AND_GIVEN("a signal handler has been subscribed to the priority property")
+ {
+ auto was_notified = false;
+ g_signal_connect(instance, "notify::priority", G_CALLBACK(&record_notification), &was_notified);
+
+ WHEN("a new priority is set using set_priority")
+ {
+ auto new_value = 17.15;
+
+ CHECK_FALSE(turns_participant_get_priority(instance) == new_value);
+ turns_participant_set_priority(instance, new_value);
+
+ THEN("a notification is issued")
+ {
+ REQUIRE(was_notified);
+ }
+ }
+
+ WHEN("the same priority is set using set_priority")
+ {
+ auto new_value = turns_participant_get_priority(instance);
+
+ CHECK(turns_participant_get_priority(instance) == new_value);
+ turns_participant_set_priority(instance, new_value);
+
+ THEN("no notification is issued")
+ {
+ REQUIRE_FALSE(was_notified);
+ }
+ }
+
+ WHEN("a new priority is set using g_object_set")
+ {
+ auto new_value = 17.15;
+
+ CHECK_FALSE(turns_participant_get_priority(instance) == new_value);
+ g_object_set(G_OBJECT(instance), "priority", new_value, nullptr);
+
+ THEN("a notification is issued")
+ {
+ REQUIRE(was_notified);
+ }
+ }
+
+ WHEN("the same priority is set using g_object_set")
+ {
+ auto new_value = turns_participant_get_priority(instance);
+
+ CHECK(turns_participant_get_priority(instance) == new_value);
+ g_object_set(G_OBJECT(instance), "priority", new_value, nullptr);
+
+ THEN("no notification is issued")
+ {
+ REQUIRE_FALSE(was_notified);
+ }
+ }
+ }
+
+ AND_GIVEN("a signal handler has been subscribed to the disposition property")
+ {
+ auto was_notified = false;
+ g_signal_connect(instance, "notify::disposition", G_CALLBACK(&record_notification), &was_notified);
+
+ WHEN("a new disposition is set using set_disposition")
+ {
+ auto new_value = TURNS_DISPOSITION_HOSTILE;
+
+ CHECK_FALSE(turns_participant_get_disposition(instance) == new_value);
+ turns_participant_set_disposition(instance, new_value);
+
+ THEN("a notification is issued")
+ {
+ REQUIRE(was_notified);
+ }
+ }
+
+ WHEN("the same disposition is set using set_disposition")
+ {
+ auto new_value = turns_participant_get_disposition(instance);
+
+ CHECK(turns_participant_get_disposition(instance) == new_value);
+ turns_participant_set_disposition(instance, new_value);
+
+ THEN("no notification is issued")
+ {
+ REQUIRE_FALSE(was_notified);
+ }
+ }
+
+ WHEN("a new disposition is set using g_object_set")
+ {
+ auto new_value = TURNS_DISPOSITION_HOSTILE;
+
+ CHECK_FALSE(turns_participant_get_disposition(instance) == new_value);
+ g_object_set(G_OBJECT(instance), "disposition", new_value, nullptr);
+
+ THEN("a notification is issued")
+ {
+ REQUIRE(was_notified);
+ }
+ }
+
+ WHEN("the same disposition is set using g_object_set")
+ {
+ auto new_value = turns_participant_get_disposition(instance);
+
+ CHECK(turns_participant_get_disposition(instance) == new_value);
+ g_object_set(G_OBJECT(instance), "disposition", new_value, nullptr);
+
+ THEN("no notification is issued")
+ {
+ REQUIRE_FALSE(was_notified);
+ }
+ }
+ }
+ }
+}
+
+SCENARIO("Reading a participant", "[lib][object][data]")
+{
+ GIVEN("A participant with a set name, priority, and disposition")
+ {
+ auto name = "Test Participant";
+ auto priority = 75.f;
+ auto disposition = TURNS_DISPOSITION_FRIENDLY;
+
+ g_autoptr(TurnsParticipant) instance = turns_participant_new_with(name, priority, disposition);
+
+ WHEN("reading the name via get_name and g_object_get")
+ {
+ auto getter_value = turns_participant_get_name(instance);
+ g_autofree auto property_value = decltype(turns_participant_get_name(instance)){};
+ g_object_get(instance, "name", &property_value, nullptr);
+
+ THEN("they both compare equal")
+ {
+ REQUIRE(std::string{getter_value} == property_value);
+ }
+ }
+
+ WHEN("reading the priority via get_priority and g_object_get")
+ {
+ auto getter_value = turns_participant_get_priority(instance);
+ auto property_value = decltype(turns_participant_get_priority(instance)){};
+ g_object_get(instance, "priority", &property_value, nullptr);
+
+ THEN("they both compare equal")
+ {
+ REQUIRE(getter_value == property_value);
+ }
+ }
+
+ WHEN("reading the disposition via get_disposition and g_object_get")
+ {
+ auto getter_value = turns_participant_get_disposition(instance);
+ auto property_value = decltype(turns_participant_get_disposition(instance)){};
+ g_object_get(instance, "disposition", &property_value, nullptr);
+
+ THEN("they both compare equal")
+ {
+ REQUIRE(getter_value == property_value);
+ }
+ }
+ }
+} \ No newline at end of file