diff options
Diffstat (limited to 'domain')
| -rw-r--r-- | domain/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | domain/include/turns/domain/turn_order.hpp | 6 | ||||
| -rw-r--r-- | domain/src/turn_order.cpp | 21 | ||||
| -rw-r--r-- | domain/tests/participant.cpp | 12 | ||||
| -rw-r--r-- | domain/tests/turn_order.cpp | 141 |
5 files changed, 166 insertions, 15 deletions
diff --git a/domain/CMakeLists.txt b/domain/CMakeLists.txt index 066f638..b33ae96 100644 --- a/domain/CMakeLists.txt +++ b/domain/CMakeLists.txt @@ -37,6 +37,7 @@ target_link_options("domain" PRIVATE add_executable("domain-tests" "tests/participant.cpp" + "tests/turn_order.cpp" ) target_link_libraries("domain-tests" diff --git a/domain/include/turns/domain/turn_order.hpp b/domain/include/turns/domain/turn_order.hpp index cb51af6..d231436 100644 --- a/domain/include/turns/domain/turn_order.hpp +++ b/domain/include/turns/domain/turn_order.hpp @@ -15,14 +15,16 @@ namespace turns::domain using super = Gio::ListStore<participant>; using super::super; - using super::append; using super::remove; auto static create() -> Glib::RefPtr<turn_order>; + auto append(Glib::RefPtr<participant> item) -> void; auto append(Glib::ustring const & name, float priority) -> void; auto remove(Glib::RefPtr<participant> item) -> void; - auto sort() -> void; + + private: + using super::sort; }; } // namespace turns::domain diff --git a/domain/src/turn_order.cpp b/domain/src/turn_order.cpp index 454e27a..eddd468 100644 --- a/domain/src/turn_order.cpp +++ b/domain/src/turn_order.cpp @@ -23,6 +23,10 @@ namespace turns::domain } return -1; }; + + auto constexpr equal_comparator = [](auto lhs, auto rhs) { + return (lhs->get_name() == rhs->get_name()) && (lhs->get_priority() && rhs->get_priority()); + }; } // namespace auto turn_order::create() -> Glib::RefPtr<turn_order> @@ -30,11 +34,19 @@ namespace turns::domain return Glib::make_refptr_for_instance(new turn_order{}); } + auto turn_order::append(Glib::RefPtr<participant> item) -> void + { + if (auto [found, index] = find(item, equal_comparator); !found) + { + insert_sorted(item, comparator); + } + } + auto turn_order::append(Glib::ustring const & name, float priority) -> void { auto participant = participant::create(name, priority); - participant->property_priority().signal_changed().connect([this] { sort(); }); - insert_sorted(participant, comparator); + participant->property_priority().signal_changed().connect([this] { sort(comparator); }); + append(participant); } auto turn_order::remove(Glib::RefPtr<participant> item) -> void @@ -45,9 +57,4 @@ namespace turns::domain } } - auto turn_order::sort() -> void - { - super::sort(comparator); - } - } // namespace turns::domain
\ No newline at end of file diff --git a/domain/tests/participant.cpp b/domain/tests/participant.cpp index e9e7c46..268b395 100644 --- a/domain/tests/participant.cpp +++ b/domain/tests/participant.cpp @@ -22,24 +22,24 @@ namespace turns::domain::tests SECTION("the name can be read") { - REQUIRE(instance.property_name() == constructed_name); + REQUIRE(instance.get_name() == constructed_name); } SECTION("the name can be changed") { - instance.property_name() = "replaced"; - REQUIRE(instance.property_name() == "replaced"); + instance.set_name("replaced"); + REQUIRE(instance.get_name() == "replaced"); } SECTION("the priority can be read") { - REQUIRE(instance.property_priority() == constructed_priority); + REQUIRE(instance.get_priority() == constructed_priority); } SECTION("the priority can be changed") { - instance.property_priority() = 8; - REQUIRE(instance.property_priority() == 8); + instance.set_priority(8); + REQUIRE(instance.get_priority() == 8); } SECTION("can be compared with another participant") diff --git a/domain/tests/turn_order.cpp b/domain/tests/turn_order.cpp new file mode 100644 index 0000000..7172ffc --- /dev/null +++ b/domain/tests/turn_order.cpp @@ -0,0 +1,141 @@ +#include "turns/domain/turn_order.hpp" + +#include "turns/domain/participant.hpp" + +#include <catch2/catch_test_macros.hpp> + +#include <compare> + +#include <glibmm/init.h> + +namespace turns::domain::tests +{ + + TEST_CASE("A freshly constructed turn order") + { + auto instance = turn_order{}; + + SECTION("can be created") + { + REQUIRE(turn_order::create()); + } + + SECTION("has 0 items") + { + REQUIRE(instance.get_n_items() == 0); + } + + SECTION("accepts a new participant in form of a refptr") + { + instance.append(participant::create("Honey Bunches of Oats", 12)); + REQUIRE(instance.get_n_items() == 1); + } + + SECTION("accepts a new participant in form of components") + { + instance.append("River along the Field", 14); + REQUIRE(instance.get_n_items() == 1); + } + + SECTION("does nothing when trying to remove an item by refptr if no items were added beforehand") + { + instance.remove(participant::create("Patch in the Forest", 3)); + REQUIRE(instance.get_n_items() == 0); + } + + SECTION("does nothing when trying to remove an item by index if no items were added beforehand") + { + instance.remove(5); + REQUIRE(instance.get_n_items() == 0); + } + + SECTION("allows the removal of an item by refptr if the same item was added beforehand") + { + auto item = participant::create("Blank Canvas", 23); + instance.append(item); + instance.remove(item); + REQUIRE(instance.get_n_items() == 0); + } + + SECTION("does nothing when trying to remove an item by refptr that was not added beforehand") + { + auto item = participant::create("Blank Canvas", 23); + instance.append(item); + instance.remove(participant::create("Spell of Rain", 6)); + REQUIRE(instance.get_n_items() == 1); + } + + SECTION("automatically sorts appended refptrs in descending order of priority") + { + SECTION("when appending the higher one last") + { + instance.append(participant::create("Snow on the Field", 2)); + instance.append(participant::create("Bees behind the Cottage", 8)); + REQUIRE(instance.get_item(0)->get_name() == "Bees behind the Cottage"); + } + + SECTION("when appending the higher one first") + { + instance.append(participant::create("Bees behind the Cottage", 8)); + instance.append(participant::create("Snow on the Field", 2)); + REQUIRE(instance.get_item(0)->get_name() == "Bees behind the Cottage"); + } + + SECTION("keeping the insertion order when appending items with equal priority") + { + instance.append(participant::create("Snow on the Field", 8)); + instance.append(participant::create("Bees behind the Cottage", 8)); + REQUIRE(instance.get_item(0)->get_name() == "Snow on the Field"); + } + } + + SECTION("automatically sorts elements appended by components in descending order of priority") + { + SECTION("when appending the higher one last") + { + instance.append("Tree Blossom", 6); + instance.append("Fish in the River", 12); + REQUIRE(instance.get_item(0)->get_name() == "Fish in the River"); + } + + SECTION("when appending the higher one first") + { + instance.append("Fish in the River", 12); + instance.append("Tree Blossom", 6); + REQUIRE(instance.get_item(0)->get_name() == "Fish in the River"); + } + + SECTION("keeping the insertion order when appending items with equal priority") + { + instance.append("Fish in the River", 6); + instance.append("Tree Blossom", 6); + REQUIRE(instance.get_item(0)->get_name() == "Fish in the River"); + } + } + + SECTION("does not accept the same item twice by the same refptr") + { + auto item = participant::create("Angelic Berry", 9); + instance.append(item); + instance.append(item); + REQUIRE(instance.get_n_items() == 1); + } + + SECTION("does not accept the same item twice by different refptrs") + { + auto item_one = participant::create("Misty Meadow", 14.2); + auto item_two = participant::create("Misty Meadow", 14.2); + instance.append(item_one); + instance.append(item_two); + REQUIRE(instance.get_n_items() == 1); + } + + SECTION("does not accept the same item twice by components") + { + instance.append("Frozen Apple Tree", 2.1); + instance.append("Frozen Apple Tree", 2.1); + REQUIRE(instance.get_n_items() == 1); + } + } + +} // namespace turns::domain::tests
\ No newline at end of file |
