diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/src/turns-turn-order.c | 17 | ||||
| -rw-r--r-- | lib/src/turns-turn-order.h | 8 | ||||
| -rw-r--r-- | lib/src/turnsmm/turn-order.cpp | 6 | ||||
| -rw-r--r-- | lib/src/turnsmm/turn-order.hpp | 1 | ||||
| -rw-r--r-- | lib/tests/turns-turn-order.cpp | 72 | ||||
| -rw-r--r-- | lib/tests/turnsmm/turn-order.cpp | 150 |
6 files changed, 222 insertions, 32 deletions
diff --git a/lib/src/turns-turn-order.c b/lib/src/turns-turn-order.c index 5d6f99b..9a08d2e 100644 --- a/lib/src/turns-turn-order.c +++ b/lib/src/turns-turn-order.c @@ -230,6 +230,23 @@ void turns_turn_order_clear(TurnsTurnOrder * self) g_list_model_items_changed(G_LIST_MODEL(self), 0, old_size, 0); } +void turns_turn_order_remove_at(TurnsTurnOrder * self, guint position) +{ + g_return_if_fail(TURNS_IS_TURN_ORDER(self)); + + auto element = g_slist_nth(self->participants, position); + + if (!element) + { + return; + } + + g_object_unref(element->data); + self->participants = g_slist_delete_link(self->participants, element); + + g_list_model_items_changed(G_LIST_MODEL(self), position, 1, 0); +} + gsize turns_turn_order_get_participant_count(TurnsTurnOrder const * self) { g_return_val_if_fail(TURNS_IS_TURN_ORDER((TurnsTurnOrder *)self), 0); diff --git a/lib/src/turns-turn-order.h b/lib/src/turns-turn-order.h index a69700f..91220b9 100644 --- a/lib/src/turns-turn-order.h +++ b/lib/src/turns-turn-order.h @@ -67,6 +67,14 @@ void turns_turn_order_add(TurnsTurnOrder * self, TurnsParticipant * participant) void turns_turn_order_clear(TurnsTurnOrder * self); /** + * turns_turn_order_remove_at: + * @self: a turn order + * + * Removes the participant at the given position. + */ +void turns_turn_order_remove_at(TurnsTurnOrder * self, guint position); + +/** * turns_turn_order_get_participant_count: * @self: a turn order. * diff --git a/lib/src/turnsmm/turn-order.cpp b/lib/src/turnsmm/turn-order.cpp index 35694b2..3767817 100644 --- a/lib/src/turnsmm/turn-order.cpp +++ b/lib/src/turnsmm/turn-order.cpp @@ -21,6 +21,7 @@ #include <giomm/listmodel.h> #include <glib-object.h> +#include <glib.h> #include <bit> #include <cstddef> @@ -98,6 +99,11 @@ namespace Turns return turns_turn_order_clear(Glib::unwrap(this)); } + auto TurnOrder::remove_at(guint position) noexcept -> void + { + return turns_turn_order_remove_at(unwrap(this), position); + } + auto TurnOrder::get_participant_count() const noexcept -> std::size_t { return turns_turn_order_get_participant_count(unwrap(this)); diff --git a/lib/src/turnsmm/turn-order.hpp b/lib/src/turnsmm/turn-order.hpp index 64f72aa..fe8c756 100644 --- a/lib/src/turnsmm/turn-order.hpp +++ b/lib/src/turnsmm/turn-order.hpp @@ -51,6 +51,7 @@ namespace Turns auto add(Glib::RefPtr<Participant> const & participant) noexcept -> void; auto clear() noexcept -> void; + auto remove_at(guint position) noexcept -> void; [[nodiscard]] auto get_participant_count() const noexcept -> std::size_t; [[nodiscard]] auto get_running() const noexcept -> bool; diff --git a/lib/tests/turns-turn-order.cpp b/lib/tests/turns-turn-order.cpp index ab119e1..2e11b52 100644 --- a/lib/tests/turns-turn-order.cpp +++ b/lib/tests/turns-turn-order.cpp @@ -11,6 +11,20 @@ #include <gio/gio.h> #include <glib-object.h> +#include <glib.h> + +#include <optional> +#include <tuple> + +namespace +{ + auto list_model_notification = std::optional<std::tuple<guint, guint, guint>>{}; + + auto on_list_model_notification(GListModel *, guint position, guint removed, guint added, void *) -> void + { + list_model_notification = std::tuple{position, removed, added}; + } +} // namespace SCENARIO("Creating a turn order", "[lib][object][lifetime]") { @@ -58,6 +72,8 @@ SCENARIO("Modifying a turn order", "[lib][object][data]") g_autoptr(TurnsTurnOrder) instance = turns_turn_order_new(); CHECK(turns_turn_order_get_participant_count(instance) == 0); + g_signal_connect(instance, "items-changed", reinterpret_cast<GCallback>(on_list_model_notification), nullptr); + WHEN("a participant is added") { g_autoptr(TurnsParticipant) participant = turns_participant_new_with("Test Participant", 10.0f, TURNS_PARTICIPANT_DISPOSITION_FRIENDLY); @@ -89,6 +105,7 @@ SCENARIO("Modifying a turn order", "[lib][object][data]") AND_WHEN("calling clear") { + list_model_notification.reset(); turns_turn_order_clear(instance); THEN("its participant count is 0") @@ -111,6 +128,61 @@ SCENARIO("Modifying a turn order", "[lib][object][data]") REQUIRE(g_list_model_get_item(G_LIST_MODEL(instance), 0) == nullptr); REQUIRE(g_list_model_get_object(G_LIST_MODEL(instance), 0) == nullptr); } + + THEN("the items-changed notification is emitted") + { + REQUIRE(list_model_notification.has_value()); + } + + THEN("all items got deleted at position 0 and none were added") + { + auto [position, removed, added] = *list_model_notification; + + REQUIRE(position == 0); + REQUIRE(removed == 1); + REQUIRE(added == 0); + } + } + + AND_WHEN("removing the first element") + { + list_model_notification.reset(); + turns_turn_order_remove_at(instance, 0); + + THEN("its participant count is 0") + { + REQUIRE(turns_turn_order_get_participant_count(instance) == 0); + } + + THEN("the items-changed notification is emitted") + { + REQUIRE(list_model_notification.has_value()); + } + + THEN("1 item got deleted at position 0 and none were added") + { + auto [position, removed, added] = *list_model_notification; + + REQUIRE(position == 0); + REQUIRE(removed == 1); + REQUIRE(added == 0); + } + + AND_WHEN("removing the first element again") + { + list_model_notification.reset(); + turns_turn_order_remove_at(instance, 0); + + THEN("its participant count is 0") + { + REQUIRE(turns_turn_order_get_participant_count(instance) == 0); + } + + THEN("the items-changed notification is not emitted") + { + REQUIRE(!list_model_notification.has_value()); + } + } } } } diff --git a/lib/tests/turnsmm/turn-order.cpp b/lib/tests/turnsmm/turn-order.cpp index ff8738f..eeee1c6 100644 --- a/lib/tests/turnsmm/turn-order.cpp +++ b/lib/tests/turnsmm/turn-order.cpp @@ -9,9 +9,24 @@ #include <catch2/catch_test_macros.hpp> +#include <giomm/listmodel.h> + +#include <glib.h> + #include <cstddef> +#include <optional> #include <tuple> +namespace +{ + auto list_model_notification = std::optional<std::tuple<guint, guint, guint>>{}; + + auto on_list_model_notification(guint position, guint removed, guint added) -> void + { + list_model_notification = std::tuple{position, removed, added}; + } +} // namespace + SCENARIO("Creating a turn order", "[lib][object][lifetime]") { GIVEN("A turn order constructed using the default constructor") @@ -22,33 +37,39 @@ SCENARIO("Creating a turn order", "[lib][object][lifetime]") { REQUIRE(instance.get_participant_count() == 0uz); REQUIRE(instance.get_property<std::size_t>("participant-count") == 0); + REQUIRE_FALSE(list_model_notification.has_value()); } THEN("its running state is false") { REQUIRE_FALSE(instance.get_running()); REQUIRE_FALSE(instance.get_property<std::size_t>("running")); + REQUIRE_FALSE(list_model_notification.has_value()); } THEN("its item count is 0") { REQUIRE(instance.get_n_items() == 0); + REQUIRE_FALSE(list_model_notification.has_value()); } THEN("its item type is Turns.Participant") { REQUIRE(instance.get_item_type() == Turns::Participant::get_type()); + REQUIRE_FALSE(list_model_notification.has_value()); } THEN("its first item is NULL") { REQUIRE(instance.get_object(0) == nullptr); REQUIRE(instance.get_typed_object<Turns::Participant>(0) == nullptr); + REQUIRE_FALSE(list_model_notification.has_value()); } THEN("its sort mode is descending") { REQUIRE(instance.get_sort_mode() == Turns::TurnOrder::SortMode::Descending); + REQUIRE_FALSE(list_model_notification.has_value()); } } } @@ -58,11 +79,13 @@ SCENARIO("Modifying a turn order", "[lib][object][data]") GIVEN("An empty turn order") { auto instance = Turns::TurnOrder{}; + instance.signal_items_changed().connect(&on_list_model_notification); CHECK(instance.get_participant_count() == 0); WHEN("a participant is added") { auto participant = Turns::Participant::create("Test Participant", 10.0f, Turns::Participant::Disposition::Friendly); + list_model_notification.reset(); instance.add(participant); THEN("its participant count is 1") @@ -93,8 +116,23 @@ SCENARIO("Modifying a turn order", "[lib][object][data]") REQUIRE(instance.get_sort_mode() == Turns::TurnOrder::SortMode::Descending); } + THEN("the items-changed signal is emitted") + { + REQUIRE(list_model_notification.has_value()); + } + + THEN("1 item was added at position 0 and 0 were removed") + { + auto [position, removed, added] = *list_model_notification; + + REQUIRE(position == 0); + REQUIRE(removed == 0); + REQUIRE(added == 1); + } + AND_WHEN("calling clear") { + list_model_notification.reset(); instance.clear(); THEN("its participant count is 0") @@ -124,6 +162,61 @@ SCENARIO("Modifying a turn order", "[lib][object][data]") { REQUIRE(instance.get_sort_mode() == Turns::TurnOrder::SortMode::Descending); } + + THEN("the items-changed signal is emitted") + { + REQUIRE(list_model_notification.has_value()); + } + + THEN("1 item was removed at position 0 and 0 were added") + { + auto [position, removed, added] = *list_model_notification; + + REQUIRE(position == 0); + REQUIRE(removed == 1); + REQUIRE(added == 0); + } + } + + AND_WHEN("removing the first element") + { + list_model_notification.reset(); + instance.remove_at(0); + + THEN("its participant count is 0") + { + REQUIRE(instance.get_participant_count() == 0); + } + + THEN("the items-changed notification is emitted") + { + REQUIRE(list_model_notification.has_value()); + } + + THEN("1 item got deleted at position 0 and none were added") + { + auto [position, removed, added] = *list_model_notification; + + REQUIRE(position == 0); + REQUIRE(removed == 1); + REQUIRE(added == 0); + } + + AND_WHEN("removing the first element again") + { + list_model_notification.reset(); + instance.remove_at(0); + + THEN("its participant count is 0") + { + REQUIRE(instance.get_participant_count() == 0); + } + + THEN("the items-changed notification is not emitted") + { + REQUIRE(!list_model_notification.has_value()); + } + } } } } @@ -140,6 +233,8 @@ SCENARIO("Sorting a turn order") instance.add(participant_a); instance.add(participant_b); + instance.signal_items_changed().connect(&on_list_model_notification); + THEN("B is the first and A the second element") { auto first = instance.get_typed_object<Turns::Participant>(0); @@ -193,6 +288,7 @@ SCENARIO("Sorting a turn order") WHEN("the sort mode is changed to ascending") { + list_model_notification.reset(); instance.set_sort_mode(Turns::TurnOrder::SortMode::Ascending); THEN("A is the first and B the second element") @@ -203,46 +299,36 @@ SCENARIO("Sorting a turn order") REQUIRE(first == participant_a); REQUIRE(second == participant_b); } - } - - WHEN("a signal handler is registered for the 'items-changed' signal") - { - auto notified = false; - auto data = std::tuple{0u, 0u, 0u}; - auto callback = [&](auto position, auto removed, auto added) { - notified = true, data = std::tie(position, removed, added); - }; - instance.signal_items_changed().connect(callback); - AND_WHEN("the sort mode is changed to ascending") + THEN("the items-changed signal is emitted") { - instance.set_sort_mode(Turns::TurnOrder::SortMode::Ascending); - - THEN("the signal is notified") - { - REQUIRE(notified); - } + REQUIRE(list_model_notification.has_value()); + } - THEN("all items were removed and added again at position 0") - { - auto [position, removed, added] = data; + THEN("2 items were removed at position 2 and 2 were added") + { + auto [position, removed, added] = *list_model_notification; - REQUIRE(position == 0); - REQUIRE(removed == 2); - REQUIRE(added == 2); - } + REQUIRE(position == 0); + REQUIRE(removed == 2); + REQUIRE(added == 2); } + } - AND_WHEN("the sort mode is set to the current value") - { - auto current_sort_mode = instance.get_sort_mode(); - instance.set_sort_mode(current_sort_mode); + WHEN("the sort mode is set to the current value") + { + auto current_sort_mode = instance.get_sort_mode(); + list_model_notification.reset(); + instance.set_sort_mode(current_sort_mode); - THEN("the signal is not notified") - { - REQUIRE_FALSE(notified); - } + THEN("the items-changed signal is not emitted") + { + REQUIRE_FALSE(list_model_notification.has_value()); } } + + WHEN("a signal handler is registered for the 'items-changed' signal") + { + } } }
\ No newline at end of file |
