diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2024-07-16 00:35:35 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2024-07-16 00:35:35 +0200 |
| commit | 5845e43c503f306a653754303573af421207e90c (patch) | |
| tree | 1ef94c028e5ba304dde3ab0e0cc263c9378fb823 | |
| parent | 4ca57dcae2291a09dcd84ccf056a65a2cf906c46 (diff) | |
| download | turns-5845e43c503f306a653754303573af421207e90c.tar.xz turns-5845e43c503f306a653754303573af421207e90c.zip | |
domain: add disposition type
| -rw-r--r-- | domain/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | domain/include/turns/domain/disposition.hpp | 44 | ||||
| -rw-r--r-- | domain/src/disposition.cpp | 64 | ||||
| -rw-r--r-- | domain/tests/disposition.cpp | 125 |
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 |
