remove dead action_buttons module (superseded by action_bar in Phase L)
Deletes src/action_buttons.{h,cpp} and tests/test_action_buttons.cpp;
removes the static library, test target, and reaper_reasampler link
entry from CMakeLists.txt; scrubs all dangling comment references.
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
// Standalone tests for reasampler::action_bar — no REAPER, no test framework. Same fast loop
|
||||
// as the sibling pure tests (action_buttons / mode_switch / prune_button): assert the
|
||||
// as the sibling pure tests (mode_switch / prune_button): assert the
|
||||
// task-grouped action-bar layout, overflow-on-narrow, and hit-testing directly.
|
||||
//
|
||||
// Covers (L2 brief §test cases, updated for L6 single-row face change):
|
||||
// * Layout: correct rects for each action button across representative panel widths; buttons
|
||||
// pack at a fixed width with intra-cluster + inter-cluster gaps.
|
||||
// * Overflow/hiding when the bar is too narrow (whole trailing buttons dropped, never
|
||||
// clipped; earlier frequent clusters survive; mirrors action_buttons suppression).
|
||||
// clipped; earlier frequent clusters survive).
|
||||
// * Label sub-rect correct — spans full button height (L6: keybinding sub-row removed from
|
||||
// the face; binding is in the hover tooltip instead).
|
||||
// * Task grouping reflected STRUCTURALLY: each slot carries its cluster; the flat index runs
|
||||
|
||||
@@ -1,236 +0,0 @@
|
||||
// Standalone tests for reasampler::action_buttons — no REAPER, no test framework.
|
||||
// Same fast loop as the sibling pure tests (mode_switch / tab_strip et al.): assert the
|
||||
// action-button strip layout + hit-testing and the label-format logic directly.
|
||||
//
|
||||
// Covers (M11 brief §test cases):
|
||||
// * Layout: N buttons in a strip — all fit (exact equal tiling), overflow on a narrow
|
||||
// panel (only the fitting count laid out, rest hidden, never clipped), zero-width edge.
|
||||
// * Hit-test: inside each button, outside the band, half-open boundary, the narrow-panel
|
||||
// overflow dead-zone, hit/layout agreement.
|
||||
// * Label format: bound ("name binding"), unbound marker, empty / whitespace-only SDK
|
||||
// return -> unbound, over-long binding truncation.
|
||||
|
||||
#include "../src/action_buttons.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace reasampler;
|
||||
|
||||
static int g_fail = 0;
|
||||
#define CHECK(cond) do { if(!(cond)) { \
|
||||
std::printf("FAIL line %d: %s\n", __LINE__, #cond); ++g_fail; } } while(0)
|
||||
|
||||
// --- Layout: all fit ----------------------------------------------------------
|
||||
|
||||
// Strip 300 wide at origin (0, 40), height 24, 3 buttons at min width 80: all fit
|
||||
// (300/80 = 3), tiled equally -> boundaries floor(i*300/3) = 0,100,200,300, widths 100.
|
||||
static void testAllButtonsFitEqualTiling() {
|
||||
ButtonStripRect s{0, 40, 300, 24};
|
||||
ButtonFit fit = computeButtonFit(s, 3, 80);
|
||||
CHECK(fit.visibleCount == 3);
|
||||
CHECK(fit.hiddenCount == 0);
|
||||
|
||||
auto rects = computeButtonRects(s, 3, 80);
|
||||
CHECK(rects.size() == 3);
|
||||
CHECK((rects[0] == ActionButtonRect{0, 0, 40, 100, 24}));
|
||||
CHECK((rects[1] == ActionButtonRect{1, 100, 40, 100, 24}));
|
||||
CHECK((rects[2] == ActionButtonRect{2, 200, 40, 100, 24}));
|
||||
// Abut exactly; last reaches strip right edge.
|
||||
CHECK(rects[1].x == rects[0].x + rects[0].width);
|
||||
CHECK(rects[2].x + rects[2].width == s.x + s.width);
|
||||
}
|
||||
|
||||
// Uneven width absorbed at boundaries: 100 wide / 3 -> edges 0,33,66,100 -> 33,33,34.
|
||||
static void testUnevenWidthTilesExactly() {
|
||||
ButtonStripRect s{7, 3, 100, 16};
|
||||
auto rects = computeButtonRects(s, 3, 30); // 100/30 = 3 fit
|
||||
CHECK(rects.size() == 3);
|
||||
CHECK(rects[0].width == 33);
|
||||
CHECK(rects[1].width == 33);
|
||||
CHECK(rects[2].width == 34);
|
||||
CHECK(rects.front().x == s.x);
|
||||
CHECK(rects.back().x + rects.back().width == s.x + s.width);
|
||||
}
|
||||
|
||||
// --- Layout: overflow on a narrow panel ---------------------------------------
|
||||
|
||||
// 5 buttons at min width 80 into a 200-wide strip: only 2 fit (200/80 = 2). The two
|
||||
// visible buttons share the FULL strip (100 each — never clipped, never below min), and
|
||||
// 3 are hidden (the overflow the shell degrades, not clipped garbage).
|
||||
static void testOverflowHidesExcessNotClipped() {
|
||||
ButtonStripRect s{0, 0, 200, 24};
|
||||
ButtonFit fit = computeButtonFit(s, 5, 80);
|
||||
CHECK(fit.visibleCount == 2);
|
||||
CHECK(fit.hiddenCount == 3);
|
||||
|
||||
auto rects = computeButtonRects(s, 5, 80);
|
||||
CHECK(rects.size() == 2);
|
||||
CHECK(rects[0].width == 100); // >= min width 80, shares full strip
|
||||
CHECK(rects[1].width == 100);
|
||||
CHECK(rects[1].x + rects[1].width == s.x + s.width);
|
||||
}
|
||||
|
||||
// A strip too narrow for even one min-width button lays out nothing (all hidden). The
|
||||
// shell draws an empty strip rather than a sub-minimum clipped button.
|
||||
static void testStripTooNarrowForAny() {
|
||||
ButtonStripRect s{0, 0, 50, 24};
|
||||
ButtonFit fit = computeButtonFit(s, 3, 80);
|
||||
CHECK(fit.visibleCount == 0);
|
||||
CHECK(fit.hiddenCount == 3);
|
||||
CHECK(computeButtonRects(s, 3, 80).empty());
|
||||
}
|
||||
|
||||
// --- Layout: degenerate --------------------------------------------------------
|
||||
|
||||
static void testLayoutDegenerate() {
|
||||
CHECK(computeButtonRects(ButtonStripRect{0, 0, 300, 24}, 0, 80).empty());
|
||||
CHECK(computeButtonRects(ButtonStripRect{0, 0, 300, 24}, -2, 80).empty());
|
||||
CHECK(computeButtonRects(ButtonStripRect{0, 0, 0, 24}, 3, 80).empty());
|
||||
CHECK(computeButtonRects(ButtonStripRect{0, 0, -5, 24}, 3, 80).empty());
|
||||
CHECK(computeButtonRects(ButtonStripRect{0, 0, 300, 24}, 3, 0).empty());
|
||||
CHECK(computeButtonRects(ButtonStripRect{0, 0, 300, 24}, 3, -10).empty());
|
||||
|
||||
ButtonFit fit = computeButtonFit(ButtonStripRect{0, 0, 0, 24}, 3, 80);
|
||||
CHECK(fit.visibleCount == 0 && fit.hiddenCount == 0);
|
||||
}
|
||||
|
||||
// A single button fills the whole strip.
|
||||
static void testSingleButtonFillsStrip() {
|
||||
ButtonStripRect s{5, 5, 120, 24};
|
||||
auto rects = computeButtonRects(s, 1, 80);
|
||||
CHECK(rects.size() == 1);
|
||||
CHECK((rects[0] == ActionButtonRect{0, 5, 5, 120, 24}));
|
||||
}
|
||||
|
||||
// --- Hit-test: hits -----------------------------------------------------------
|
||||
|
||||
static void testHitTestHitsEachButton() {
|
||||
ButtonStripRect s{0, 40, 300, 24}; // 3 buttons, 100 wide each
|
||||
CHECK(hitTestButton(0, 40, s, 3, 80) == 0); // top-left of button 0
|
||||
CHECK(hitTestButton(50, 51, s, 3, 80) == 0); // middle of button 0
|
||||
CHECK(hitTestButton(99, 63, s, 3, 80) == 0); // last pixel of button 0
|
||||
CHECK(hitTestButton(100, 50, s, 3, 80) == 1); // first pixel of button 1
|
||||
CHECK(hitTestButton(299, 40, s, 3, 80) == 2); // last column of button 2
|
||||
}
|
||||
|
||||
// The boundary pixel belongs to exactly ONE button (half-open): px==100 starts button 1.
|
||||
static void testHitTestBoundaryHalfOpen() {
|
||||
ButtonStripRect s{0, 0, 300, 24};
|
||||
CHECK(hitTestButton(99, 10, s, 3, 80) == 0);
|
||||
CHECK(hitTestButton(100, 10, s, 3, 80) == 1);
|
||||
CHECK(hitTestButton(199, 10, s, 3, 80) == 1);
|
||||
CHECK(hitTestButton(200, 10, s, 3, 80) == 2);
|
||||
}
|
||||
|
||||
// --- Hit-test: misses ---------------------------------------------------------
|
||||
|
||||
static void testHitTestMissesOutsideBand() {
|
||||
ButtonStripRect s{10, 40, 200, 24};
|
||||
CHECK(hitTestButton(9, 50, s, 3, 60) == -1); // left of strip
|
||||
CHECK(hitTestButton(210, 50, s, 3, 60) == -1); // right edge (== x+width, excluded)
|
||||
CHECK(hitTestButton(50, 39, s, 3, 60) == -1); // above the band
|
||||
CHECK(hitTestButton(50, 64, s, 3, 60) == -1); // below the band
|
||||
}
|
||||
|
||||
// On a narrow panel the visible buttons fill the whole strip, so there is no in-band
|
||||
// dead-zone; but when buttonCount is 0 or the strip too narrow, every in-band point
|
||||
// misses (the shell draws nothing and ignores the click).
|
||||
static void testHitTestOverflowDeadZone() {
|
||||
ButtonStripRect s{0, 0, 50, 24}; // too narrow for any 80-min button
|
||||
CHECK(hitTestButton(25, 10, s, 3, 80) == -1);
|
||||
CHECK(hitTestButton(0, 0, s, 0, 80) == -1); // no buttons
|
||||
}
|
||||
|
||||
static void testHitTestDegenerate() {
|
||||
ButtonStripRect s{0, 0, 300, 24};
|
||||
CHECK(hitTestButton(50, 10, s, 0, 80) == -1);
|
||||
CHECK(hitTestButton(50, 10, s, -2, 80) == -1);
|
||||
CHECK(hitTestButton(50, 10, ButtonStripRect{0, 0, 0, 24}, 3, 80) == -1);
|
||||
CHECK(hitTestButton(50, 10, ButtonStripRect{0, 0, 300, 0}, 3, 80) == -1);
|
||||
}
|
||||
|
||||
// Every point in the strip hit-tests to the button that DREW it (hit-test and layout
|
||||
// agree — the load-bearing consistency invariant), across an awkward width and count.
|
||||
static void testHitTestMatchesLayout() {
|
||||
ButtonStripRect s{4, 2, 173, 22};
|
||||
const int count = 4, minW = 40; // 173/40 = 4 fit
|
||||
auto rects = computeButtonRects(s, count, minW);
|
||||
for (int px = s.x; px < s.x + s.width; ++px) {
|
||||
const int b = hitTestButton(px, s.y + 1, s, count, minW);
|
||||
CHECK(b >= 0);
|
||||
const ActionButtonRect& r = rects[static_cast<std::size_t>(b)];
|
||||
CHECK(px >= r.x && px < r.x + r.width);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Label format -------------------------------------------------------------
|
||||
|
||||
static void testLabelBound() {
|
||||
CHECK(formatButtonLabel("Capture Item", "Ctrl+Shift+C") ==
|
||||
"Capture Item Ctrl+Shift+C");
|
||||
CHECK(formatButtonLabel("Insert", "F3") == "Insert F3");
|
||||
}
|
||||
|
||||
static void testLabelUnboundEmpty() {
|
||||
CHECK(formatButtonLabel("Capture Item", "") == "Capture Item (unbound)");
|
||||
}
|
||||
|
||||
// Whitespace-only SDK returns (spaces, tabs) collapse to the unbound marker — the
|
||||
// explicit blank-return handling the brief requires.
|
||||
static void testLabelUnboundBlank() {
|
||||
CHECK(formatButtonLabel("Capture Track", " ") == "Capture Track (unbound)");
|
||||
CHECK(formatButtonLabel("Insert", "\t") == "Insert (unbound)");
|
||||
CHECK(formatButtonLabel("Insert", " \t ") == "Insert (unbound)");
|
||||
}
|
||||
|
||||
// Leading/trailing whitespace on a real binding is trimmed before formatting.
|
||||
static void testLabelTrimsSurroundingBlanks() {
|
||||
CHECK(formatButtonLabel("Insert", " F3 ") == "Insert F3");
|
||||
}
|
||||
|
||||
// An over-long binding is truncated to kMaxBindingChars-1 chars + "~" so the label stays
|
||||
// bounded (a pathological multi-chord custom binding never blows the button budget).
|
||||
static void testLabelTruncatesLongBinding() {
|
||||
const std::string longB(40, 'X'); // 40 > kMaxBindingChars (24)
|
||||
const std::string label = formatButtonLabel("Cancel", longB);
|
||||
// "Cancel " (8) + 23 'X' + "~" (kMaxBindingChars total in the binding portion).
|
||||
const std::string expectedBinding =
|
||||
std::string(kMaxBindingChars - 1, 'X') + "~";
|
||||
CHECK(label == "Cancel " + expectedBinding);
|
||||
CHECK(static_cast<int>(expectedBinding.size()) == kMaxBindingChars);
|
||||
}
|
||||
|
||||
// A binding exactly at the limit is NOT truncated (boundary: <= kMaxBindingChars kept).
|
||||
static void testLabelAtLimitNotTruncated() {
|
||||
const std::string atLimit(kMaxBindingChars, 'Y');
|
||||
CHECK(formatButtonLabel("X", atLimit) == "X " + atLimit);
|
||||
}
|
||||
|
||||
int main() {
|
||||
testAllButtonsFitEqualTiling();
|
||||
testUnevenWidthTilesExactly();
|
||||
testOverflowHidesExcessNotClipped();
|
||||
testStripTooNarrowForAny();
|
||||
testLayoutDegenerate();
|
||||
testSingleButtonFillsStrip();
|
||||
|
||||
testHitTestHitsEachButton();
|
||||
testHitTestBoundaryHalfOpen();
|
||||
testHitTestMissesOutsideBand();
|
||||
testHitTestOverflowDeadZone();
|
||||
testHitTestDegenerate();
|
||||
testHitTestMatchesLayout();
|
||||
|
||||
testLabelBound();
|
||||
testLabelUnboundEmpty();
|
||||
testLabelUnboundBlank();
|
||||
testLabelTrimsSurroundingBlanks();
|
||||
testLabelTruncatesLongBinding();
|
||||
testLabelAtLimitNotTruncated();
|
||||
|
||||
if (g_fail == 0) std::printf("All tests passed.\n");
|
||||
return g_fail ? 1 : 0;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// Standalone tests for reasampler::drag_out — no REAPER, no test framework. Same fast loop
|
||||
// as the sibling pure tests (action_buttons / mode_switch et al.): assert the gesture-
|
||||
// as the sibling pure tests (mode_switch et al.): assert the gesture-
|
||||
// boundary decision and the path-list assembly directly.
|
||||
//
|
||||
// Covers (M11 drag-out brief §test cases):
|
||||
|
||||
Reference in New Issue
Block a user