#include "turns/core/participant.hpp" #include "turns/core/disposition.hpp" #include #include #include #include namespace turns::core::tests { TEST_CASE("Constructing a participant", "[core][construction]") { auto constexpr name = "Participant #1"; auto constexpr priority = 17; auto constexpr disposition = disposition::friendly; auto json = nlohmann::json::parse(R"( { "name": "Participant #1", "priority": 17, "disposition": 1, "is-active": false, "is-defeated": false } )"); SECTION("Can be constructed using default ctor") { auto instance = Participant{}; REQUIRE(instance.property_name() == ""); REQUIRE(instance.property_priority() == 0); REQUIRE(instance.property_disposition() == disposition::neutral); REQUIRE(!instance.property_is_active()); REQUIRE(!instance.property_is_defeated()); } SECTION("Can be constructed using ctor") { auto instance = Participant{name, priority, disposition}; REQUIRE(instance.property_name() == name); REQUIRE(instance.property_priority() == priority); REQUIRE(instance.property_disposition() == disposition); REQUIRE(!instance.property_is_active()); REQUIRE(!instance.property_is_defeated()); } SECTION("Can be constructed using factory") { auto instance = Participant::create(name, priority, disposition); REQUIRE(instance->property_name() == name); REQUIRE(instance->property_priority() == priority); REQUIRE(instance->property_disposition() == disposition); REQUIRE(!instance->property_is_active()); REQUIRE(!instance->property_is_defeated()); } SECTION("Can be constructed using JSON factory", "[json]") { auto instance = Participant::create(json); REQUIRE(instance->property_name() == name); REQUIRE(instance->property_priority() == priority); REQUIRE(instance->property_disposition() == disposition); REQUIRE(!instance->property_is_active()); REQUIRE(!instance->property_is_defeated()); } } TEST_CASE("Setting properties on participant", "[core][properties]") { auto constexpr name = "Participant #2"; auto constexpr priority = 10; auto constexpr disposition = disposition::hostile; auto instance = Participant{name, priority, disposition}; SECTION("Setting '::disposition' via proxy changes the 'disposition' value") { auto old = instance.property_disposition().get_value(); instance.property_disposition() = static_cast(static_cast(disposition) - 1); REQUIRE(instance.property_disposition() != old); } SECTION("Setting '::disposition' via glib changes the 'disposition' value") { auto old = instance.property_disposition().get_value(); instance.set_property("disposition", static_cast(static_cast(disposition) - 1)); REQUIRE(instance.property_disposition() != old); } SECTION("Setting '::is-active' via proxy changes the 'is_active' value") { auto old = instance.property_is_active().get_value(); instance.property_is_active() = !old; REQUIRE(instance.property_is_active() != old); } SECTION("Setting '::is-active' via glib changes the 'is_active' value") { auto old = instance.property_is_active().get_value(); instance.set_property("is-active", !old); REQUIRE(instance.property_is_active() != old); } SECTION("Setting '::is-defeated' via proxy changes the 'is_defeated' value") { auto old = instance.property_is_defeated().get_value(); instance.property_is_defeated() = !old; REQUIRE(instance.property_is_defeated() != old); } SECTION("Setting '::is-defeated' via glib changes the 'is_defeated' value") { auto old = instance.property_is_defeated().get_value(); instance.set_property("is-defeated", !old); REQUIRE(instance.property_is_defeated() != old); } SECTION("Setting '::name' via proxy changes the 'name' value") { auto old = instance.property_name().get_value(); instance.property_name() = old + " Changed"; REQUIRE(instance.property_name().get_value() != old); } SECTION("Setting '::name' via glib changes the 'name' value") { auto old = instance.property_name().get_value(); instance.set_property("name", old + " Changed"); REQUIRE(instance.property_name().get_value() != old); } SECTION("Setting '::priority' via proxy changes the 'priority' value") { auto old = instance.property_priority().get_value(); instance.property_priority() = old + 1; REQUIRE(instance.property_priority() != old); } SECTION("Setting '::priority' via glib changes the 'priority' value") { auto old = instance.property_priority().get_value(); instance.set_property("priority", old + 1); REQUIRE(instance.property_priority() != old); } } TEST_CASE("A freshly constructed participant") { auto constexpr constructed_name = "Vana Thistletop"; auto constexpr constructed_priority = 17; auto constexpr constructed_disposition = disposition::friendly; auto instance = Participant{constructed_name, constructed_priority, constructed_disposition}; SECTION("can be created") { REQUIRE(Participant::create(constructed_name, constructed_priority, constructed_disposition)); } SECTION("allows access to its disposition") { SECTION("allowing to get it") { REQUIRE(instance.property_disposition() == constructed_disposition); } SECTION("allowing to get it via a constant object") { auto const & cref = instance; REQUIRE(cref.property_disposition() == constructed_disposition); } SECTION("allowing to set it") { instance.property_disposition() = disposition::hostile; REQUIRE(instance.property_disposition() == disposition::hostile); } } SECTION("allows access to its name") { SECTION("allowing to get it") { REQUIRE(instance.property_name() == constructed_name); } SECTION("allowing to get it via a constant object") { auto const & cref = instance; REQUIRE(cref.property_name() == constructed_name); } SECTION("allowing to set it") { instance.property_name() = "replaced"; REQUIRE(instance.property_name() == "replaced"); } } SECTION("allows access to its priority") { SECTION("allowing to get it") { REQUIRE(instance.property_priority() == constructed_priority); } SECTION("allowing to get it via a constant object") { auto const & cref = instance; REQUIRE(cref.property_priority() == constructed_priority); } SECTION("allowing to set it") { instance.property_priority() = 4; REQUIRE(instance.property_priority() == 4); } } SECTION("can be compared with another participant") { auto equivalent_instance = Participant{"Equivalent", constructed_priority, constructed_disposition}; auto lesser_instance = Participant{"Lesser", constructed_priority - 1, constructed_disposition}; auto greater_instance = Participant{"Greater", constructed_priority + 1, constructed_disposition}; SECTION("yielding std::partial_ordering::equivalent for itself") { REQUIRE((instance <=> equivalent_instance) == std::partial_ordering::equivalent); } SECTION("yielding std::partial_ordering::equivalent for an equivalent participant") { REQUIRE((instance <=> equivalent_instance) == std::partial_ordering::equivalent); } SECTION("yielding std::partial_ordering::greater for a lesser participant") { REQUIRE((instance <=> lesser_instance) == std::partial_ordering::greater); } SECTION("yielding std::partial_ordering::less for a greater participant") { REQUIRE((instance <=> greater_instance) == std::partial_ordering::less); } } } TEST_CASE("Serializing a participant") { auto instance = Participant::create("Participant #0", 17.2, disposition::friendly); auto serialized = instance->serialize(); SECTION("the active state is serialized correctly") { REQUIRE_FALSE(serialized.at("is-active")); } SECTION("the disposition is serialized correctly") { REQUIRE(serialized.at("disposition") == disposition::friendly); } SECTION("the name is serialized correctly") { REQUIRE(serialized.at("name") == "Participant #0"); } SECTION("the priority is serialized correctly") { REQUIRE(serialized.at("priority") == Catch::Approx{17.2}); } } TEST_CASE("De-Serializing a participant") { auto serialized = nlohmann::json::parse(R"( { "name": "Participant #1", "priority": -2.3, "disposition": 2, "is-active": true } )"); auto instance = Participant::create(serialized); SECTION("the active state is de-serialized correctly") { REQUIRE(instance->property_is_active()); } SECTION("the disposition is de-serialized correctly") { REQUIRE(instance->property_disposition() == disposition::hostile); } SECTION("the name is de-serialized correctly") { REQUIRE(instance->property_name() == "Participant #1"); } SECTION("the priority is de-serialized correctly") { REQUIRE(instance->property_priority() == Catch::Approx{-2.3}); } } } // namespace turns::core::tests