Files
roro9stack/test/test_grid_model/test_grid_model.cpp
T
twislaandClaude Opus 5.5 e2326e113b Launcher: a grid of icons, with badges; the list stays as a Setting
The Launcher shows the Apps as a 4 x 3 grid of 32 x 32 icons, the
selected one's name under it (issue #9). The icons are the website's
own, doubled, and two drawn the same way for SSH and the Shell; they
are PNGs in assets/icons, turned into arrays by scripts/make_icons.py,
which CI checks. The selected tile is the website's: dark blue on cyan,
with notched corners.

- GridModel (lib/ui, host-tested) holds the selection and the scrolling.
- App::badge(): a dot on the tile for unread IRC messages, a Track
  recording, a Capture running, an SSH session open.
- Settings > Launcher: Grid or List.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0162FokPdvY2KsS4NBfwyWPk
2026-10-09 23:14:37 +02:00

98 lines
2.5 KiB
C++

#include <unity.h>
#include "grid_model.h"
using namespace roro;
void setUp() {}
void tearDown() {}
void test_empty_grid_has_no_selection() {
GridModel g(4, 3);
TEST_ASSERT_EQUAL(-1, g.selected());
g.right();
g.down();
TEST_ASSERT_EQUAL(-1, g.selected());
TEST_ASSERT_EQUAL(0, g.rows());
}
void test_left_and_right_go_through_every_item() {
GridModel g(4, 3);
g.setCount(11);
TEST_ASSERT_EQUAL(0, g.selected());
g.right();
TEST_ASSERT_EQUAL(1, g.selected());
g.select(3);
g.right(); // onto the next row
TEST_ASSERT_EQUAL(4, g.selected());
g.left();
TEST_ASSERT_EQUAL(3, g.selected());
g.select(10);
g.right(); // around
TEST_ASSERT_EQUAL(0, g.selected());
g.left();
TEST_ASSERT_EQUAL(10, g.selected());
}
void test_up_and_down_stay_in_the_column() {
GridModel g(4, 3);
g.setCount(11); // rows of 4, 4 and 3
g.select(1);
g.down();
TEST_ASSERT_EQUAL(5, g.selected());
g.down();
TEST_ASSERT_EQUAL(9, g.selected());
g.down(); // around
TEST_ASSERT_EQUAL(1, g.selected());
g.up();
TEST_ASSERT_EQUAL(9, g.selected());
}
void test_a_short_last_row_gives_its_last_item() {
GridModel g(4, 3);
g.setCount(11);
g.select(7); // the fourth column, which the last row doesn't have
g.down();
TEST_ASSERT_EQUAL(10, g.selected());
g.select(3);
g.up();
TEST_ASSERT_EQUAL(10, g.selected());
}
void test_rows_scroll_to_keep_the_selection_in_view() {
GridModel g(4, 3);
g.setCount(18); // 5 rows
TEST_ASSERT_EQUAL(5, g.rows());
TEST_ASSERT_EQUAL(0, g.firstVisibleRow());
g.select(12); // the fourth row
TEST_ASSERT_EQUAL(1, g.firstVisibleRow());
g.select(17);
TEST_ASSERT_EQUAL(2, g.firstVisibleRow());
g.select(5);
TEST_ASSERT_EQUAL(1, g.firstVisibleRow());
g.select(0);
TEST_ASSERT_EQUAL(0, g.firstVisibleRow());
}
void test_a_smaller_count_keeps_the_selection_inside() {
GridModel g(4, 3);
g.setCount(18);
g.select(17);
g.setCount(6);
TEST_ASSERT_EQUAL(5, g.selected());
TEST_ASSERT_EQUAL(0, g.firstVisibleRow());
g.setCount(0);
TEST_ASSERT_EQUAL(-1, g.selected());
}
int main() {
UNITY_BEGIN();
RUN_TEST(test_empty_grid_has_no_selection);
RUN_TEST(test_left_and_right_go_through_every_item);
RUN_TEST(test_up_and_down_stay_in_the_column);
RUN_TEST(test_a_short_last_row_gives_its_last_item);
RUN_TEST(test_rows_scroll_to_keep_the_selection_in_view);
RUN_TEST(test_a_smaller_count_keeps_the_selection_inside);
return UNITY_END();
}