130 lines
5.4 KiB
C++
130 lines
5.4 KiB
C++
// Standalone tests for reasampler::instrument::ui::embed_strip — no VST3, no REAPER, no framework.
|
|
// Same fast assert loop as the sibling pure tests: assert the embedded TCP/MCP strip's
|
|
// layout math + key-span mapping + level fill directly.
|
|
//
|
|
// Covers: layoutEmbed splitting a normal area into keymap + level band, a tiny area
|
|
// (band yields to the keymap minimum, no inversion), and a zero area (all empty);
|
|
// keySpanRect mapping the 128-key span linearly, tiling adjacent spans seamlessly,
|
|
// resolving a single-key span (the root marker), and clamping out-of-range/inverted notes;
|
|
// levelFillRect clamping 0..1 and its endpoints.
|
|
|
|
#include "../src/core/instrument/ui/embed_strip.h"
|
|
|
|
#include <cstdio>
|
|
|
|
using namespace reasampler;
|
|
using namespace reasampler::instrument::ui;
|
|
|
|
static int g_fail = 0;
|
|
#define CHECK(cond) do { if(!(cond)) { \
|
|
std::printf("FAIL line %d: %s\n", __LINE__, #cond); ++g_fail; } } while(0)
|
|
|
|
// --- layoutEmbed --------------------------------------------------------------
|
|
|
|
static void testLayoutNormalArea() {
|
|
// A comfortable inline strip: keymap band on top, thin level band pinned to the bottom.
|
|
const EmbedLayout L = layoutEmbed(300, 40);
|
|
CHECK(L.keymap.x == 0 && L.keymap.y == 0 && L.keymap.right() == 300);
|
|
CHECK(L.levelBand.x == 0 && L.levelBand.right() == 300);
|
|
// Level band is the fixed height at the very bottom; keymap fills the rest, contiguous.
|
|
CHECK(L.levelBand.height == kEmbedLevelBandHeight);
|
|
CHECK(L.levelBand.bottom() == 40);
|
|
CHECK(L.keymap.bottom() == L.levelBand.y);
|
|
CHECK(L.keymap.height == 40 - kEmbedLevelBandHeight);
|
|
}
|
|
|
|
static void testLayoutTinyAreaKeepsKeymap() {
|
|
// A very short area: the level band must yield so the keymap keeps its minimum, and no
|
|
// rect inverts.
|
|
const EmbedLayout L = layoutEmbed(300, 8);
|
|
CHECK(L.keymap.height >= 0);
|
|
CHECK(L.levelBand.height >= 0);
|
|
CHECK(L.keymap.bottom() == L.levelBand.y);
|
|
CHECK(L.levelBand.bottom() == 8);
|
|
// The keymap is not starved below its floor when the area allows it.
|
|
CHECK(L.keymap.height >= kEmbedKeymapMinHeight || 8 < kEmbedKeymapMinHeight);
|
|
}
|
|
|
|
static void testLayoutZeroArea() {
|
|
const EmbedLayout L = layoutEmbed(0, 0);
|
|
CHECK(L.keymap.width <= 0 && L.keymap.height <= 0);
|
|
CHECK(L.levelBand.width <= 0 && L.levelBand.height <= 0);
|
|
// Negative dimensions clamp to a zero-area, non-inverted rect.
|
|
const EmbedLayout N = layoutEmbed(-50, -50);
|
|
CHECK(N.keymap.right() >= N.keymap.x && N.keymap.bottom() >= N.keymap.y);
|
|
}
|
|
|
|
// --- keySpanRect --------------------------------------------------------------
|
|
|
|
static void testKeySpanFullKeyboard() {
|
|
// The loaded capture responds across the whole keyboard, so its span is the whole band.
|
|
const EmbedLayout L = layoutEmbed(256, 40);
|
|
const Rect r = keySpanRect(L, 0, 127);
|
|
CHECK(r.x == L.keymap.x);
|
|
CHECK(r.right() == L.keymap.right());
|
|
CHECK(r.y == L.keymap.y && r.bottom() == L.keymap.bottom());
|
|
}
|
|
|
|
static void testAdjacentSpansTileSeamlessly() {
|
|
// 256px band, 128 keys -> 2px/key. Spans 0..59 and 60..127 must abut with no gap or
|
|
// overlap: the low span's right == the high span's left.
|
|
const EmbedLayout L = layoutEmbed(256, 40);
|
|
const Rect lo = keySpanRect(L, 0, 59);
|
|
const Rect hi = keySpanRect(L, 60, 127);
|
|
CHECK(lo.x == L.keymap.x);
|
|
CHECK(hi.right() == L.keymap.right());
|
|
CHECK(lo.right() == hi.x); // seamless tile — the load-bearing assertion
|
|
CHECK(lo.right() == L.keymap.x + 60 * 2); // 60 keys * 2px
|
|
}
|
|
|
|
static void testSingleKeySpanIsTheRootMarker() {
|
|
// low == high is the root marker: exactly one key wide, inside the band.
|
|
const EmbedLayout L = layoutEmbed(256, 40);
|
|
const Rect root = keySpanRect(L, 60, 60);
|
|
CHECK(root.x == L.keymap.x + 60 * 2);
|
|
CHECK(root.width == 2);
|
|
CHECK(root.y == L.keymap.y && root.bottom() == L.keymap.bottom());
|
|
}
|
|
|
|
static void testKeySpanClampsBadNotes() {
|
|
const EmbedLayout L = layoutEmbed(256, 40);
|
|
// Out-of-range notes clamp into the band; an inverted span (low > high) collapses to a
|
|
// zero-or-positive-width rect, never inverts.
|
|
const Rect over = keySpanRect(L, -10, 200);
|
|
CHECK(over.x == L.keymap.x && over.right() == L.keymap.right());
|
|
const Rect inv = keySpanRect(L, 100, 20);
|
|
CHECK(inv.right() >= inv.x);
|
|
}
|
|
|
|
// --- levelFillRect ------------------------------------------------------------
|
|
|
|
static void testLevelFillClamps() {
|
|
const EmbedLayout L = layoutEmbed(200, 40);
|
|
// Zero / negative -> empty.
|
|
CHECK(levelFillRect(L, 0.0).width <= 0);
|
|
CHECK(levelFillRect(L, -1.0).width <= 0);
|
|
// Full / over-full -> the whole band width.
|
|
CHECK(levelFillRect(L, 1.0).width == L.levelBand.width);
|
|
CHECK(levelFillRect(L, 5.0).width == L.levelBand.width);
|
|
// Half -> ~half the band, pinned to the band's left and vertical extent.
|
|
const Rect half = levelFillRect(L, 0.5);
|
|
CHECK(half.x == L.levelBand.x);
|
|
CHECK(half.y == L.levelBand.y && half.bottom() == L.levelBand.bottom());
|
|
CHECK(half.width == L.levelBand.width / 2);
|
|
}
|
|
|
|
int main() {
|
|
testLayoutNormalArea();
|
|
testLayoutTinyAreaKeepsKeymap();
|
|
testLayoutZeroArea();
|
|
testKeySpanFullKeyboard();
|
|
testAdjacentSpansTileSeamlessly();
|
|
testSingleKeySpanIsTheRootMarker();
|
|
testKeySpanClampsBadNotes();
|
|
testLevelFillClamps();
|
|
|
|
if (g_fail == 0) std::printf("embed_strip: all tests passed\n");
|
|
else std::printf("embed_strip: %d FAILED\n", g_fail);
|
|
return g_fail == 0 ? 0 : 1;
|
|
}
|