summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt13
-rw-r--r--app/schemas/ch.arknet.Turns.gschema.xml25
-rw-r--r--cmake/Modules/GlibMkenums.cmake8
-rw-r--r--core/include/turns/turns-participant.h27
-rw-r--r--lib/.gitignore (renamed from core/.gitignore)0
-rw-r--r--lib/CMakeLists.txt88
-rw-r--r--lib/src/turns-disposition.h (renamed from core/include/turns/turns-disposition.h)0
-rw-r--r--lib/src/turns-enums.c.in (renamed from core/src/turns-enums.c.in)4
-rw-r--r--lib/src/turns-enums.h.in (renamed from core/include/turns/turns-enums.h.in)7
-rw-r--r--lib/src/turns-init.cpp17
-rw-r--r--lib/src/turns-init.h12
-rw-r--r--lib/src/turns-participant.cpp (renamed from core/src/turns-participant.cpp)50
-rw-r--r--lib/src/turns-participant.h84
-rw-r--r--lib/tests/runtime_init.cpp21
-rw-r--r--lib/tests/turns-participant.cpp353
15 files changed, 647 insertions, 62 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 84ead94..a6db0f4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -67,6 +67,7 @@ FetchContent_MakeAvailable("Catch2" "nlohmann_json")
pkg_check_modules("giomm" IMPORTED_TARGET REQUIRED "giomm-2.68>=${GLIB_MINIMUM_VERSION}")
pkg_check_modules("glibmm" IMPORTED_TARGET REQUIRED "glibmm-2.68>=${GLIB_MINIMUM_VERSION}")
pkg_check_modules("gtkmm" IMPORTED_TARGET REQUIRED "gtkmm-4.0>=${GTK4_MINIMUM_VERSION}")
+pkg_check_modules("gobject" IMPORTED_TARGET REQUIRED "gobject-2.0>=${GLIB_MINIMUM_VERSION}")
add_subdirectory("deps/libadwaitamm" EXCLUDE_FROM_ALL SYSTEM)
@@ -74,11 +75,13 @@ include("Catch")
# Targets
-add_subdirectory("app")
-add_subdirectory("core")
-add_subdirectory("lang")
-add_subdirectory("style")
-add_subdirectory("ui")
+add_subdirectory("lib")
+
+# add_subdirectory("app")
+# add_subdirectory("core")
+# add_subdirectory("lang")
+# add_subdirectory("style")
+# add_subdirectory("ui")
# License
diff --git a/app/schemas/ch.arknet.Turns.gschema.xml b/app/schemas/ch.arknet.Turns.gschema.xml
new file mode 100644
index 0000000..d764608
--- /dev/null
+++ b/app/schemas/ch.arknet.Turns.gschema.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schemalist>
+ <schema path="/ch/arknet/Turns/" id="ch.arknet.Turns">
+ <key name="disposition-color-friendly" type="s">
+ <default>'#33d17a'</default>
+ <summary>Friendly Disposition Color</summary>
+ <description>The color used to shade friendly participants.</description>
+ </key>
+ <key name="disposition-color-hostile" type="s">
+ <default>'#e01b24'</default>
+ <summary>Hostile Disposition Color</summary>
+ <description>The color used to shade hostile participants.</description>
+ </key>
+ <key name="disposition-color-secret" type="s">
+ <default>'#9141ac'</default>
+ <summary>Secret Disposition Color</summary>
+ <description>The color used to shade secret participants.</description>
+ </key>
+ <key name="skip-defeated" type="b">
+ <default>false</default>
+ <summary>Skip Defeated Participants</summary>
+ <description>Whether or not defeated participants shall be skipped while stepping through the turn order.</description>
+ </key>
+ </schema>
+</schemalist> \ No newline at end of file
diff --git a/cmake/Modules/GlibMkenums.cmake b/cmake/Modules/GlibMkenums.cmake
index b7caf10..58ae4ee 100644
--- a/cmake/Modules/GlibMkenums.cmake
+++ b/cmake/Modules/GlibMkenums.cmake
@@ -7,7 +7,6 @@ find_program(GLIB_MKENUMS_BIN
function(target_add_glib_enums TARGET)
set(SINGLE_VALUE_ARGS
- "HEADER_OUTPUT_DIR"
"HEADER_TEMPLATE"
"OUTPUT_NAME"
"SOURCE_TEMPLATE"
@@ -25,10 +24,6 @@ function(target_add_glib_enums TARGET)
message(FATAL_ERROR "Target '${TARGET}' does not exist")
endif()
- if(NOT _HEADER_OUTPUT_DIR)
- message(FATAL_ERROR "Missing header output dir")
- endif()
-
if(NOT _HEADERS)
message(FATAL_ERROR "Missing enum headers")
endif()
@@ -42,7 +37,7 @@ function(target_add_glib_enums TARGET)
endif()
set(SOURCE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/${_OUTPUT_NAME}.c")
- set(HEADER_FILE "${CMAKE_CURRENT_SOURCE_DIR}/include/${_HEADER_OUTPUT_DIR}/${_OUTPUT_NAME}.h")
+ set(HEADER_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/${_OUTPUT_NAME}.h")
add_custom_command(OUTPUT
${SOURCE_FILE}
@@ -80,5 +75,4 @@ function(target_add_glib_enums TARGET)
"${CMAKE_CURRENT_BINARY_DIR}"
)
-
endfunction()
diff --git a/core/include/turns/turns-participant.h b/core/include/turns/turns-participant.h
deleted file mode 100644
index 001de6b..0000000
--- a/core/include/turns/turns-participant.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef TURNS_PARTICIPANT_H
-#define TURNS_PARTICIPANT_H
-
-#include "turns/turns-disposition.h"
-
-#include <glib-object.h>
-#include <glib.h>
-#include <glibconfig.h>
-
-G_BEGIN_DECLS
-
-#define TURNS_TYPE_PARTICIPANT turns_participant_get_type()
-G_DECLARE_FINAL_TYPE(TurnsParticipant, turns_participant, TURNS, PARTICIPANT, GObject)
-
-TurnsParticipant * turns_participant_new(gchar const * name, gfloat priority, TurnsDisposition disposition) G_GNUC_WARN_UNUSED_RESULT;
-
-gchar const * turns_participant_get_name(TurnsParticipant const * self);
-gfloat turns_participant_get_priority(TurnsParticipant const * self);
-TurnsDisposition turns_participant_get_disposition(TurnsParticipant const * self);
-
-void turns_participant_set_name(TurnsParticipant * self, gchar const * value);
-void turns_participant_set_priority(TurnsParticipant * self, gfloat value);
-void turns_participant_set_disposition(TurnsParticipant * self, TurnsDisposition value);
-
-G_END_DECLS
-
-#endif \ No newline at end of file
diff --git a/core/.gitignore b/lib/.gitignore
index 0050be3..0050be3 100644
--- a/core/.gitignore
+++ b/lib/.gitignore
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
new file mode 100644
index 0000000..8e507ec
--- /dev/null
+++ b/lib/CMakeLists.txt
@@ -0,0 +1,88 @@
+# Library
+
+set(HEADERS
+ "src/turns-disposition.h"
+ "src/turns-init.h"
+ "src/turns-participant.h"
+)
+
+set(SOURCES
+ "src/turns-init.cpp"
+ "src/turns-participant.cpp"
+)
+
+add_library("lib"
+ ${SOURCES}
+)
+
+add_library("turns::lib" ALIAS "lib")
+
+target_sources("lib" PUBLIC
+ FILE_SET HEADERS
+ BASE_DIRS "src"
+ FILES
+ ${HEADERS}
+)
+
+target_compile_options("lib" PUBLIC
+ "$<$<CXX_COMPILER_ID:GNU,Clang>:-Wall>"
+ "$<$<CXX_COMPILER_ID:GNU,Clang>:-Wextra>"
+ "$<$<CXX_COMPILER_ID:GNU,Clang>:-Werror>"
+ "$<$<CXX_COMPILER_ID:GNU,Clang>:-pedantic-errors>"
+)
+
+target_include_directories("lib" PUBLIC
+ "src"
+)
+
+target_link_libraries("lib" PUBLIC
+ "PkgConfig::gobject"
+)
+
+target_compile_definitions("lib" PUBLIC
+ "$<$<NOT:$<BOOL:TURNS_USE_INSTALLED_SCHEMA_FILES>>:TURNS_SETTINGS_SCHEMA_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\">"
+)
+
+set_target_properties("lib" PROPERTIES
+ OUTPUT_NAME "turns"
+)
+
+target_add_glib_enums("lib"
+ HEADER_TEMPLATE "src/turns-enums.h.in"
+ SOURCE_TEMPLATE "src/turns-enums.c.in"
+ OUTPUT_NAME "turns-enums"
+ HEADERS ${HEADERS}
+)
+
+enable_coverage("lib")
+
+install(TARGETS "lib"
+ FILE_SET HEADERS
+)
+
+# Tests
+
+add_executable("lib-tests"
+ "tests/runtime_init.cpp"
+ "tests/turns-participant.cpp"
+)
+
+target_link_libraries("lib-tests" PRIVATE
+ "Catch2::Catch2WithMain"
+
+ "turns::lib"
+)
+
+target_link_options("lib-tests" PRIVATE
+ "$<$<AND:$<CXX_COMPILER_ID:GNU,Clang>,$<CONFIG:Debug>>:--coverage>"
+)
+
+# file(GLOB_RECURSE TEST_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/tests" CONFIGURE_DEPENDS "*.trns")
+
+# target_add_glib_resources("core-tests"
+# PREFIX "/ch/arknet/Turns/core-tests/"
+# WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/tests"
+# CSS_FILES ${TEST_FILES}
+# )
+
+catch_discover_tests("lib-tests") \ No newline at end of file
diff --git a/core/include/turns/turns-disposition.h b/lib/src/turns-disposition.h
index c5bb174..c5bb174 100644
--- a/core/include/turns/turns-disposition.h
+++ b/lib/src/turns-disposition.h
diff --git a/core/src/turns-enums.c.in b/lib/src/turns-enums.c.in
index adef39b..2f75d77 100644
--- a/core/src/turns-enums.c.in
+++ b/lib/src/turns-enums.c.in
@@ -1,10 +1,10 @@
/*** BEGIN file-header ***/
-#include "turns/turns-enums.h"
+#include "turns-enums.h"
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@basename@" */
-#include "turns/@basename@"
+#include "@basename@"
/*** END file-production ***/
/*** BEGIN value-header ***/
diff --git a/core/include/turns/turns-enums.h.in b/lib/src/turns-enums.h.in
index 10bb3f1..de93e31 100644
--- a/core/include/turns/turns-enums.h.in
+++ b/lib/src/turns-enums.h.in
@@ -1,5 +1,6 @@
/*** BEGIN file-header ***/
-#pragma once
+#ifndef TURNS_ENUMS_H
+#define TURNS_ENUMS_H
#include <glib.h>
#include <glib-object.h>
@@ -19,4 +20,6 @@ GType @enum_name@_get_type (void) G_GNUC_CONST;
/*** BEGIN file-tail ***/
G_END_DECLS
-/*** END file-tail ***/ \ No newline at end of file
+
+#endif
+/*** END file-tail ***/
diff --git a/lib/src/turns-init.cpp b/lib/src/turns-init.cpp
new file mode 100644
index 0000000..544dc14
--- /dev/null
+++ b/lib/src/turns-init.cpp
@@ -0,0 +1,17 @@
+#include "turns-init.h"
+
+#include "turns-enums.h"
+#include "turns-participant.h"
+
+#include <glib-object.h>
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+auto turns_init() -> void
+{
+ g_type_ensure(TURNS_TYPE_PARTICIPANT);
+ g_type_ensure(TURNS_TYPE_DISPOSITION);
+}
+
+G_END_DECLS \ No newline at end of file
diff --git a/lib/src/turns-init.h b/lib/src/turns-init.h
new file mode 100644
index 0000000..a6e2013
--- /dev/null
+++ b/lib/src/turns-init.h
@@ -0,0 +1,12 @@
+#ifndef TURNS_INIT_H
+#define TURNS_INIT_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+void turns_init(void);
+
+G_END_DECLS
+
+#endif
diff --git a/core/src/turns-participant.cpp b/lib/src/turns-participant.cpp
index 91f1696..a820f3f 100644
--- a/core/src/turns-participant.cpp
+++ b/lib/src/turns-participant.cpp
@@ -1,7 +1,7 @@
-#include "turns/turns-participant.h"
+#include "turns-participant.h"
-#include "turns/turns-disposition.h"
-#include "turns/turns-enums.h"
+#include "turns-disposition.h"
+#include "turns-enums.h"
#include <glib-object.h>
#include <glib.h>
@@ -22,6 +22,8 @@ struct _TurnsParticipant
TurnsDisposition disposition;
};
+G_DEFINE_TYPE(TurnsParticipant, turns_participant, G_TYPE_OBJECT)
+
G_END_DECLS
namespace
@@ -36,6 +38,15 @@ namespace
auto static constinit properties = std::array<GParamSpec *, static_cast<std::size_t>(property::N_PROPERTIES)>{};
+ auto finalize(GObject * self)
+ {
+ auto participant = TURNS_PARTICIPANT(self);
+
+ g_free(participant->name);
+
+ G_OBJECT_CLASS(turns_participant_parent_class)->finalize(self);
+ }
+
auto get_property(GObject * self, guint id, GValue * value, GParamSpec * specification) -> void
{
auto participant = TURNS_PARTICIPANT(self);
@@ -43,13 +54,13 @@ namespace
switch (static_cast<property>(id))
{
case property::Name:
- g_value_set_string(value, participant->name);
+ g_value_set_string(value, turns_participant_get_name(participant));
return;
case property::Priority:
- g_value_set_float(value, participant->priority);
+ g_value_set_float(value, turns_participant_get_priority(participant));
return;
case property::Disposition:
- g_value_set_enum(value, static_cast<gint>(participant->disposition));
+ g_value_set_enum(value, turns_participant_get_disposition(participant));
return;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(self, id, specification);
@@ -63,14 +74,11 @@ namespace
switch (static_cast<property>(id))
{
case property::Name:
- g_set_str(&participant->name, g_value_get_string(value));
- return;
+ return turns_participant_set_name(participant, g_value_get_string(value));
case property::Priority:
- participant->priority = g_value_get_float(value);
- return;
+ return turns_participant_set_priority(participant, g_value_get_float(value));
case property::Disposition:
- participant->disposition = static_cast<TurnsDisposition>(g_value_get_enum(value));
- return;
+ return turns_participant_set_disposition(participant, static_cast<TurnsDisposition>(g_value_get_enum(value)));
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(self, id, specification);
}
@@ -79,8 +87,6 @@ namespace
G_BEGIN_DECLS
-G_DEFINE_TYPE(TurnsParticipant, turns_participant, G_TYPE_OBJECT)
-
static void turns_participant_class_init(TurnsParticipantClass * klass)
{
GObjectClass * object_class = G_OBJECT_CLASS(klass);
@@ -89,13 +95,14 @@ static void turns_participant_class_init(TurnsParticipantClass * klass)
object_class->get_property = get_property;
object_class->set_property = set_property;
+ object_class->finalize = finalize;
properties[static_cast<std::size_t>(property::Name)] =
g_param_spec_string("name",
"Name",
"The Name of the participant",
"",
- static_cast<GParamFlags>(G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+ static_cast<GParamFlags>(G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY));
properties[static_cast<std::size_t>(property::Priority)] =
g_param_spec_float("priority",
@@ -104,15 +111,15 @@ static void turns_participant_class_init(TurnsParticipantClass * klass)
-std::numeric_limits<float>::infinity(),
+std::numeric_limits<float>::infinity(),
0.0f,
- static_cast<GParamFlags>(G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+ static_cast<GParamFlags>(G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY));
properties[static_cast<std::size_t>(property::Disposition)] =
g_param_spec_enum("disposition",
"Disposition",
"Disposition of the participant toward the players",
turns_disposition_get_type(),
- TURNS_DISPOSITION_HOSTILE,
- static_cast<GParamFlags>(G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+ TURNS_DISPOSITION_NEUTRAL,
+ static_cast<GParamFlags>(G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY));
g_object_class_install_properties(object_class, static_cast<guint>(property::N_PROPERTIES), properties.data());
}
@@ -122,7 +129,12 @@ static void turns_participant_init(TurnsParticipant * self)
(void)self;
}
-TurnsParticipant * turns_participant_new(gchar const * name, gfloat priority, TurnsDisposition disposition)
+TurnsParticipant * turns_participant_new()
+{
+ return static_cast<TurnsParticipant *>(g_object_new(TURNS_TYPE_PARTICIPANT, nullptr));
+}
+
+TurnsParticipant * turns_participant_new_with(gchar const * name, gfloat priority, TurnsDisposition disposition)
{
g_return_val_if_fail(name != nullptr, nullptr);
diff --git a/lib/src/turns-participant.h b/lib/src/turns-participant.h
new file mode 100644
index 0000000..502de32
--- /dev/null
+++ b/lib/src/turns-participant.h
@@ -0,0 +1,84 @@
+#ifndef TURNS_PARTICIPANT_H
+#define TURNS_PARTICIPANT_H
+
+#include "turns-disposition.h"
+
+#include <glib-object.h>
+#include <glib.h>
+#include <glibconfig.h>
+
+G_BEGIN_DECLS
+
+#define TURNS_TYPE_PARTICIPANT turns_participant_get_type()
+G_DECLARE_FINAL_TYPE(TurnsParticipant, turns_participant, TURNS, PARTICIPANT, GObject)
+
+/**
+ * @brief Construct a new Participant.
+ *
+ * This functions constructs a default initialized instance, meaning:
+ * - @p name is the empty string
+ * - @p priority is 0.0f
+ * - @p disposition is Disposition.Neutral.
+ */
+TurnsParticipant * turns_participant_new() G_GNUC_WARN_UNUSED_RESULT;
+
+/**
+ * @brief Construct a new Participant with the given values.
+ *
+ * @param name The name of the new instance. The value *must not* be NULL.
+ * @param priority The priority of the new instance.
+ * @param disposition The disposition of the new instance.
+ */
+TurnsParticipant * turns_participant_new_with(gchar const * name, gfloat priority, TurnsDisposition disposition) G_GNUC_WARN_UNUSED_RESULT;
+
+/**
+ * @brief Get the name of a participant.
+ *
+ * @param self A Participant instance. The value *must not* be NULL.
+ * @return The name of the instance. The data is owned by the instance.
+ */
+gchar const * turns_participant_get_name(TurnsParticipant const * self);
+
+/**
+ * @brief Get the priority of a participant.
+ *
+ * @param self A Participant instance. The value *must not* be NULL.
+ * @return The priority of the instance.
+ */
+gfloat turns_participant_get_priority(TurnsParticipant const * self);
+
+/**
+ * @brief Get the disposition of a participant.
+ *
+ * @param self A Participant instance. The value *must not* be NULL.
+ * @return The disposition of the instance.
+ */
+TurnsDisposition turns_participant_get_disposition(TurnsParticipant const * self);
+
+/**
+ * @brief Set the name of a participant.
+ *
+ * @param self A Participant instance. The value *must not* be NULL.
+ * @param value The new name. The data is owned by the caller of the method.
+ */
+void turns_participant_set_name(TurnsParticipant * self, gchar const * value);
+
+/**
+ * @brief Set the priority of a participant.
+ *
+ * @param self A Participant instance. The value *must not* be NULL.
+ * @param value The new priority.
+ */
+void turns_participant_set_priority(TurnsParticipant * self, gfloat value);
+
+/**
+ * @brief Set the disposition of a participant.
+ *
+ * @param self A Participant instance. The value *must not* be NULL.
+ * @param value The new disposition.
+ */
+void turns_participant_set_disposition(TurnsParticipant * self, TurnsDisposition value);
+
+G_END_DECLS
+
+#endif \ No newline at end of file
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