#include #include "fgc/ui/Scroll.h" #include using namespace fgc; TEST_CASE("scrollMax is zero when the content fits") { CHECK(scrollMax(10, 20) == 0); CHECK(scrollMax(20, 20) == 0); CHECK(scrollMax(21, 20) == 1); CHECK(scrollMax(100, 20) == 80); } TEST_CASE("an unmeasured view pins to the top") { // First frame after an overlay opens: reflect() has not run yet, so every // height is 0. Scrolling must be a no-op rather than a guess. CHECK(scrollMax(500, 0) == 0); CHECK(scrollClamp(42, 500, 0) == 0); CHECK(scrollBy(0, 1, 500, 0) == 0); CHECK(scrollPage(0, 1, 500, 0) == 0); CHECK(scrollMax(500, -3) == 0); } TEST_CASE("scrollClamp pulls a stale position back into range") { // The pane was scrolled to the bottom of a long dump, then the dump was // replaced by a shorter one: the view must not stay parked past the end. CHECK(scrollClamp(80, 100, 20) == 80); CHECK(scrollClamp(80, 30, 20) == 10); CHECK(scrollClamp(80, 10, 20) == 0); CHECK(scrollClamp(-5, 100, 20) == 0); } TEST_CASE("scrollBy steps one line and stops at the ends") { CHECK(scrollBy(0, 1, 100, 20) == 1); CHECK(scrollBy(5, -1, 100, 20) == 4); CHECK(scrollBy(0, -1, 100, 20) == 0); // already at the top CHECK(scrollBy(80, 1, 100, 20) == 80); // already at the bottom } TEST_CASE("scrollPage keeps two lines of overlap") { CHECK(scrollPage(0, 1, 100, 20) == 18); CHECK(scrollPage(18, -1, 100, 20) == 0); // PgDn then PgUp returns exactly where it started, away from the ends. CHECK(scrollPage(scrollPage(30, 1, 200, 20), -1, 200, 20) == 30); } TEST_CASE("scrollPage still advances in a one-line pane") { // view_h - 2 would be negative; the step floor keeps the keys usable. CHECK(scrollPage(0, 1, 100, 1) == 1); CHECK(scrollPage(0, 1, 100, 2) == 1); } TEST_CASE("gridRowsPerColumn keeps short grids compact") { // Under the column cap the grid looks exactly as it did before: 18 per column. CHECK(gridRowsPerColumn(0, 3, 18) == 18); CHECK(gridRowsPerColumn(1, 3, 18) == 18); CHECK(gridRowsPerColumn(30, 3, 18) == 18); CHECK(gridRowsPerColumn(54, 3, 18) == 18); // exactly 3 full columns } TEST_CASE("gridRowsPerColumn grows downward past the column cap") { // Past the cap the grid must get taller, not wider, or it runs off the // right edge where vertical scrolling cannot reach it. CHECK(gridRowsPerColumn(55, 3, 18) == 19); CHECK(gridRowsPerColumn(200, 3, 18) == 67); // Never more than max_cols columns. for (std::size_t n : std::initializer_list{55, 100, 200, 999}) { const std::size_t rows = gridRowsPerColumn(n, 3, 18); CHECK((n + rows - 1) / rows <= 3); } } TEST_CASE("gridRowsPerColumn tolerates degenerate parameters") { CHECK(gridRowsPerColumn(10, 0, 18) == 18); // max_cols 0 => treated as 1 CHECK(gridRowsPerColumn(100, 0, 1) == 100); CHECK(gridRowsPerColumn(10, 3, 0) >= 1); }