// Standalone tests for reasampler::tail_control — no REAPER, no framework. Covers // the pure pieces behind the docked panel's tail-mode toggle: the cycle order // (None -> Auto -> Manual -> None), the manual-length clamp to the 8 s cap, and the // toggle label text. The drawing / click hit-testing is DAW-verified in bank_panel. #include "../src/tail_control.h" #include #include 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) // --- cycleTailMode: the toggle order ------------------------------------------ static void testCycleOrderIsNoneAutoManualNone() { // None -> Auto -> Manual -> None, wrapping. The click handler relies on exactly // this order; a reorder (e.g. skipping Manual) would fail here. CHECK(cycleTailMode(TailMode::None) == TailMode::Auto); CHECK(cycleTailMode(TailMode::Auto) == TailMode::Manual); CHECK(cycleTailMode(TailMode::Manual) == TailMode::None); } static void testCycleThreeStepsReturnsToStart() { // Three cycles from any state land back on that state (a full lap of the 3-cycle). TailMode m = TailMode::None; m = cycleTailMode(m); m = cycleTailMode(m); m = cycleTailMode(m); CHECK(m == TailMode::None); } // --- clampManualMs: the runaway guard ----------------------------------------- static void testManualClampInRangeIsUnchanged() { // A value inside [0, kMaxTailMs] passes through untouched. CHECK(clampManualMs(kDefaultManualTailMs) == kDefaultManualTailMs); CHECK(clampManualMs(0.0) == 0.0); CHECK(clampManualMs(kMaxTailMs) == kMaxTailMs); } static void testManualClampCapsAtEightSeconds() { // Over the 8 s cap clamps to kMaxTailMs; negative floors to 0. This mirrors the // clamp in tailRenderSettingsFor, so the panel and the render agree on the bound. CHECK(clampManualMs(kMaxTailMs + 5000.0) == kMaxTailMs); CHECK(clampManualMs(-100.0) == 0.0); } // --- tailToggleLabel: the exact strings the panel draws ----------------------- static void testLabelStringsPerMode() { TailSetting off; off.mode = TailMode::None; TailSetting autoM; autoM.mode = TailMode::Auto; TailSetting man; man.mode = TailMode::Manual; CHECK(tailToggleLabel(off) == "Tail: Off"); CHECK(tailToggleLabel(autoM) == "Tail: Auto"); CHECK(tailToggleLabel(man) == "Tail: Manual"); } static void testDefaultSettingIsOff() { // The zero-value setting is None (Off) with the 2 s manual default — the safe // default the panel starts in so captures stay exact-bounds until opt-in. TailSetting s; CHECK(s.mode == TailMode::None); CHECK(s.manualMs == kDefaultManualTailMs); CHECK(tailToggleLabel(s) == "Tail: Off"); } int main() { testCycleOrderIsNoneAutoManualNone(); testCycleThreeStepsReturnsToStart(); testManualClampInRangeIsUnchanged(); testManualClampCapsAtEightSeconds(); testLabelStringsPerMode(); testDefaultSettingIsOff(); if (g_fail == 0) std::printf("tail_control: all tests passed\n"); else std::printf("tail_control: %d CHECK(s) FAILED\n", g_fail); return g_fail == 0 ? 0 : 1; }