Public Access
- ToastQueue compared times unsigned: a Toast stamped a few ms after the main loop read the clock looked expired, so Toasts were skipped or shown late and bursts chained wrongly - Notifier now beeps and flashes when each Toast appears instead of when the Notification arrives, so a burst alerts once per Toast Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
109 lines
3.7 KiB
C++
109 lines
3.7 KiB
C++
#include <unity.h>
|
|
|
|
#include <string>
|
|
|
|
#include "toast_queue.h"
|
|
|
|
using namespace roro;
|
|
|
|
void setUp() {}
|
|
void tearDown() {}
|
|
|
|
void test_nothing_shown_when_empty() {
|
|
ToastQueue q(3000);
|
|
TEST_ASSERT_NULL(q.current(0));
|
|
}
|
|
|
|
void test_toast_is_shown_for_its_duration() {
|
|
ToastQueue q(3000);
|
|
q.push("hello", NotificationLevel::Info, 1000);
|
|
TEST_ASSERT_NOT_NULL(q.current(1000));
|
|
TEST_ASSERT_EQUAL_STRING("hello", q.current(3999)->text.c_str());
|
|
TEST_ASSERT_NULL(q.current(4000));
|
|
}
|
|
|
|
void test_queued_toasts_follow_each_other() {
|
|
ToastQueue q(3000);
|
|
q.push("one", NotificationLevel::Info, 0);
|
|
q.push("two", NotificationLevel::Info, 100);
|
|
TEST_ASSERT_EQUAL_STRING("one", q.current(2999)->text.c_str());
|
|
TEST_ASSERT_EQUAL_STRING("two", q.current(3000)->text.c_str());
|
|
TEST_ASSERT_EQUAL_STRING("two", q.current(5999)->text.c_str());
|
|
TEST_ASSERT_NULL(q.current(6000));
|
|
}
|
|
|
|
void test_a_toast_queued_later_gets_its_full_duration() {
|
|
ToastQueue q(3000);
|
|
q.push("one", NotificationLevel::Info, 0);
|
|
TEST_ASSERT_NULL(q.current(10000));
|
|
q.push("two", NotificationLevel::Info, 20000);
|
|
TEST_ASSERT_NOT_NULL(q.current(22999));
|
|
}
|
|
|
|
void test_flood_keeps_the_visible_toast_and_drops_the_oldest_waiting() {
|
|
ToastQueue q(3000, 2);
|
|
q.push("a", NotificationLevel::Info, 0);
|
|
q.push("b", NotificationLevel::Info, 0);
|
|
q.push("c", NotificationLevel::Info, 0);
|
|
TEST_ASSERT_EQUAL_STRING("a", q.current(0)->text.c_str());
|
|
TEST_ASSERT_EQUAL_STRING("c", q.current(3000)->text.c_str());
|
|
}
|
|
|
|
void test_dismiss_shows_the_next_one_immediately() {
|
|
ToastQueue q(3000);
|
|
q.push("one", NotificationLevel::Info, 0);
|
|
q.push("two", NotificationLevel::Info, 0);
|
|
q.dismiss(500);
|
|
TEST_ASSERT_EQUAL_STRING("two", q.current(500)->text.c_str());
|
|
}
|
|
|
|
void test_reports_when_a_new_toast_appears() {
|
|
ToastQueue q(3000);
|
|
q.push("one", NotificationLevel::Info, 0);
|
|
TEST_ASSERT_TRUE(q.takeChanged());
|
|
TEST_ASSERT_FALSE(q.takeChanged());
|
|
q.current(3000); // expires
|
|
TEST_ASSERT_TRUE(q.takeChanged());
|
|
}
|
|
|
|
void test_asking_with_a_slightly_older_time_does_not_expire_the_toast() {
|
|
// The main loop reads the time once, then a Notification pushed later in the same pass is
|
|
// stamped a few ms after it.
|
|
ToastQueue q(3000);
|
|
q.push("late", NotificationLevel::Info, 1005);
|
|
TEST_ASSERT_NOT_NULL(q.current(1000));
|
|
TEST_ASSERT_EQUAL_STRING("late", q.current(1000)->text.c_str());
|
|
}
|
|
|
|
void test_burst_shows_each_toast_in_turn() {
|
|
ToastQueue q(3000);
|
|
for (int i = 1; i <= 3; i++) q.push(std::to_string(i), NotificationLevel::Info, 1002);
|
|
TEST_ASSERT_EQUAL_STRING("1", q.current(1000)->text.c_str());
|
|
TEST_ASSERT_EQUAL_STRING("2", q.current(4002)->text.c_str());
|
|
TEST_ASSERT_EQUAL_STRING("3", q.current(7002)->text.c_str());
|
|
TEST_ASSERT_NULL(q.current(10002));
|
|
}
|
|
|
|
void test_each_toast_has_its_own_id() {
|
|
ToastQueue q(3000);
|
|
q.push("a", NotificationLevel::Info, 0);
|
|
q.push("a", NotificationLevel::Info, 0); // same text, still a different Toast
|
|
uint32_t first = q.current(0)->id;
|
|
TEST_ASSERT_NOT_EQUAL(first, q.current(3000)->id);
|
|
}
|
|
|
|
int main() {
|
|
UNITY_BEGIN();
|
|
RUN_TEST(test_nothing_shown_when_empty);
|
|
RUN_TEST(test_toast_is_shown_for_its_duration);
|
|
RUN_TEST(test_queued_toasts_follow_each_other);
|
|
RUN_TEST(test_a_toast_queued_later_gets_its_full_duration);
|
|
RUN_TEST(test_flood_keeps_the_visible_toast_and_drops_the_oldest_waiting);
|
|
RUN_TEST(test_dismiss_shows_the_next_one_immediately);
|
|
RUN_TEST(test_reports_when_a_new_toast_appears);
|
|
RUN_TEST(test_asking_with_a_slightly_older_time_does_not_expire_the_toast);
|
|
RUN_TEST(test_burst_shows_each_toast_in_turn);
|
|
RUN_TEST(test_each_toast_has_its_own_id);
|
|
return UNITY_END();
|
|
}
|