summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@gmail.com>2024-07-16 00:35:35 +0200
committerFelix Morgner <felix.morgner@gmail.com>2024-07-16 00:35:35 +0200
commit5845e43c503f306a653754303573af421207e90c (patch)
tree1ef94c028e5ba304dde3ab0e0cc263c9378fb823
parent4ca57dcae2291a09dcd84ccf056a65a2cf906c46 (diff)
downloadturns-5845e43c503f306a653754303573af421207e90c.tar.xz
turns-5845e43c503f306a653754303573af421207e90c.zip
domain: add disposition type
-rw-r--r--domain/CMakeLists.txt2
-rw-r--r--domain/include/turns/domain/disposition.hpp44
-rw-r--r--domain/src/disposition.cpp64
-rw-r--r--domain/tests/disposition.cpp125
4 files changed, 235 insertions, 0 deletions
diff --git a/domain/CMakeLists.txt b/domain/CMakeLists.txt
index b33ae96..58a7900 100644
--- a/domain/CMakeLists.txt
+++ b/domain/CMakeLists.txt
@@ -1,6 +1,7 @@
# Library
add_library("domain"
+ "src/disposition.cpp"
"src/participant.cpp"
"src/turn_order.cpp"
)
@@ -36,6 +37,7 @@ target_link_options("domain" PRIVATE
# Tests
add_executable("domain-tests"
+ "tests/disposition.cpp"
"tests/participant.cpp"
"tests/turn_order.cpp"
)
diff --git a/domain/include/turns/domain/disposition.hpp b/domain/include/turns/domain/disposition.hpp
new file mode 100644
index 0000000..32f3aca
--- /dev/null
+++ b/domain/include/turns/domain/disposition.hpp
@@ -0,0 +1,44 @@
+#ifndef TURNS_DOMAIN_PARTICIPANT_HPP
+#define TURNS_DOMAIN_PARTICIPANT_HPP
+
+#include <compare>
+#include <cstdint>
+
+#include <glibmm/object.h>
+#include <glibmm/property.h>
+#include <glibmm/refptr.h>
+#include <glibmm/ustring.h>
+
+namespace turns::domain
+{
+
+ struct disposition : Glib::Object
+ {
+ enum struct values : std::uint8_t
+ {
+ neutral,
+ friendly,
+ hostile,
+ secret,
+ };
+
+ auto static create(values value) -> Glib::RefPtr<disposition>;
+
+ disposition(values value);
+
+ auto operator<=>(disposition const & other) const -> std::strong_ordering;
+
+ auto property_value() -> Glib::PropertyProxy<values>;
+ auto property_value() const -> Glib::PropertyProxy_ReadOnly<values>;
+ auto get_value() const -> values;
+ auto set_value(values value) -> void;
+
+ auto get_presentation_name() const -> Glib::ustring;
+
+ private:
+ Glib::Property<values> m_value;
+ };
+
+} // namespace turns::domain
+
+#endif \ No newline at end of file
diff --git a/domain/src/disposition.cpp b/domain/src/disposition.cpp
new file mode 100644
index 0000000..887d70f
--- /dev/null
+++ b/domain/src/disposition.cpp
@@ -0,0 +1,64 @@
+#include "turns/domain/disposition.hpp"
+
+#include <typeinfo>
+
+#include <glibmm/i18n.h>
+#include <glibmm/refptr.h>
+
+namespace turns::domain
+{
+
+ auto disposition::create(values value) -> Glib::RefPtr<disposition>
+ {
+ return Glib::make_refptr_for_instance(new disposition(value));
+ }
+
+ disposition::disposition(values value)
+ : Glib::ObjectBase{typeid(disposition)}
+ , m_value{*this, "value", value}
+ {
+ }
+
+ auto disposition::operator<=>(disposition const & other) const -> std::strong_ordering
+ {
+ return get_value() <=> other.get_value();
+ }
+
+ auto disposition::property_value() -> Glib::PropertyProxy<values>
+ {
+ return m_value.get_proxy();
+ }
+
+ auto disposition::property_value() const -> Glib::PropertyProxy_ReadOnly<values>
+ {
+ return m_value.get_proxy();
+ }
+
+ auto disposition::get_value() const -> values
+ {
+ return m_value;
+ }
+
+ auto disposition::set_value(values value) -> void
+ {
+ m_value = value;
+ }
+
+ auto disposition::get_presentation_name() const -> Glib::ustring
+ {
+ switch (get_value())
+ {
+ case values::neutral:
+ return _("Neutral");
+ case values::friendly:
+ return _("Friendly");
+ case values::hostile:
+ return _("Hostile");
+ case values::secret:
+ return _("Secret");
+ }
+
+ return _("Unknown disposition value");
+ }
+
+} // namespace turns::domain \ No newline at end of file
diff --git a/domain/tests/disposition.cpp b/domain/tests/disposition.cpp
new file mode 100644
index 0000000..487bc5f
--- /dev/null
+++ b/domain/tests/disposition.cpp
@@ -0,0 +1,125 @@
+#include "turns/domain/disposition.hpp"
+
+#include <catch2/catch_test_macros.hpp>
+#include <catch2/generators/catch_generators.hpp>
+
+#include <compare>
+#include <format>
+#include <limits>
+#include <utility>
+
+#include <glibmm/i18n.h>
+#include <glibmm/init.h>
+
+namespace turns::domain::tests
+{
+
+ TEST_CASE("A freshly constructed disposition", "[disposition]")
+ {
+ auto constexpr constructed_value = disposition::values::friendly;
+ auto instance = disposition{constructed_value};
+
+ SECTION("can be created")
+ {
+ REQUIRE(disposition::create(constructed_value));
+ }
+
+ SECTION("allows access to its value via the associated accessors")
+ {
+ SECTION("allowing to get it")
+ {
+ REQUIRE(instance.get_value() == constructed_value);
+ }
+
+ SECTION("allowing to get it via a constant object")
+ {
+ auto const & cref = instance;
+ REQUIRE(cref.get_value() == constructed_value);
+ }
+
+ SECTION("allowing to set it")
+ {
+ instance.set_value(disposition::values::hostile);
+ REQUIRE(instance.get_value() == disposition::values::hostile);
+ }
+ }
+
+ SECTION("allows access to its value via the associated property")
+ {
+ SECTION("allowing to get it")
+ {
+ REQUIRE(instance.property_value() == constructed_value);
+ }
+
+ SECTION("allowing to get it via a constant object")
+ {
+ auto const & cref = instance;
+ REQUIRE(cref.property_value() == constructed_value);
+ }
+
+ SECTION("allowing to set it")
+ {
+ instance.property_value() = disposition::values::hostile;
+ REQUIRE(instance.get_value() == disposition::values::hostile);
+ }
+ }
+
+ SECTION("allows access to its name via the associated accessors")
+ {
+ SECTION("allowing to get it")
+ {
+ REQUIRE(instance.get_presentation_name() == _("Friendly"));
+ }
+
+ SECTION("allowing to get it via a constant object")
+ {
+ auto const & cref = instance;
+ REQUIRE(cref.get_presentation_name() == _("Friendly"));
+ }
+ }
+
+ SECTION("can be compared with another disposition")
+ {
+ auto equal_instance = disposition{disposition::values::friendly};
+ auto lesser_instance = disposition{disposition::values::neutral};
+ auto greater_instance = disposition{disposition::values::hostile};
+
+ SECTION("yielding std::partial_ordering::equivalent for itself")
+ {
+ REQUIRE((instance <=> instance) == std::strong_ordering::equal);
+ }
+
+ SECTION("yielding std::partial_ordering::equivalent for an equivalent participant")
+ {
+ REQUIRE((instance <=> equal_instance) == std::strong_ordering::equal);
+ }
+
+ SECTION("yielding std::partial_ordering::greater for a lesser participant")
+ {
+ REQUIRE((instance <=> lesser_instance) == std::strong_ordering::greater);
+ }
+
+ SECTION("yielding std::partial_ordering::less for a greater participant")
+ {
+ REQUIRE((instance <=> greater_instance) == std::strong_ordering::less);
+ }
+ }
+ }
+
+ TEST_CASE("disposition::get_presentation_name returns the correct string", "[disposition]")
+ {
+ auto [value, name] =
+ GENERATE(std::pair{disposition::values::neutral, _("Neutral")},
+ std::pair{disposition::values::friendly, _("Friendly")},
+ std::pair{disposition::values::hostile, _("Hostile")},
+ std::pair{disposition::values::secret, _("Secret")},
+ std::pair{static_cast<disposition::values>(std::numeric_limits<std::underlying_type_t<disposition::values>>::max()),
+ _("Unknown disposition value")});
+
+ SECTION(std::format("the presentation name for '{}' is '{}'", static_cast<std::underlying_type_t<disposition::values>>(value), name))
+ {
+ REQUIRE(disposition{value}.get_presentation_name() == name);
+ }
+ }
+
+} // namespace turns::domain::tests \ No newline at end of file