capture: refuse the multi-track ranged item render, silence the track's children and receives for it, and gate every exact-bounds capture on its frame count
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
// Standalone tests for reasampler::track_topology — no REAPER, no framework.
|
||||
// Covers the direct-child walk over a flat I_FOLDERDEPTH delta list: the set a
|
||||
// ranged item render must silence so a folder parent's children stay out of the
|
||||
// capture.
|
||||
|
||||
#include "../src/core/capture/track_topology.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
|
||||
using namespace reasampler::capture;
|
||||
|
||||
static int g_fail = 0;
|
||||
#define CHECK(cond) do { if(!(cond)) { \
|
||||
std::printf("FAIL line %d: %s\n", __LINE__, #cond); ++g_fail; } } while(0)
|
||||
|
||||
static bool sameIndices(const std::vector<int>& got, const std::vector<int>& want) {
|
||||
return got == want;
|
||||
}
|
||||
|
||||
static void testFlatProjectHasNoChildren() {
|
||||
// No track opens a folder, so no track has children — including the one asked
|
||||
// about. A flat project must produce an empty silence set, not a stray one.
|
||||
const std::vector<int> depths{0, 0, 0};
|
||||
CHECK(sameIndices(directChildIndices(depths, 0), {}));
|
||||
CHECK(sameIndices(directChildIndices(depths, 1), {}));
|
||||
}
|
||||
|
||||
static void testFolderParentReturnsItsDirectChildren() {
|
||||
// 0: folder parent, 1: child, 2: last child (closes the folder), 3: unrelated.
|
||||
const std::vector<int> depths{1, 0, -1, 0};
|
||||
CHECK(sameIndices(directChildIndices(depths, 0), {1, 2}));
|
||||
// Track 3 sits outside the folder entirely and owns nothing.
|
||||
CHECK(sameIndices(directChildIndices(depths, 3), {}));
|
||||
}
|
||||
|
||||
static void testGrandchildrenAreExcluded() {
|
||||
// 0: outer folder, 1: inner folder (a direct child), 2: grandchild closing the
|
||||
// inner folder, 3: second direct child closing the outer. The grandchild reaches
|
||||
// track 0 only through track 1, so silencing track 1's send covers it — listing
|
||||
// it too would be redundant, and the walk must not.
|
||||
const std::vector<int> depths{1, 1, -1, -1};
|
||||
CHECK(sameIndices(directChildIndices(depths, 0), {1, 3}));
|
||||
// Asked about the inner folder, the grandchild IS the direct child.
|
||||
CHECK(sameIndices(directChildIndices(depths, 1), {2}));
|
||||
}
|
||||
|
||||
static void testMultiLevelCloseEndsTheOuterFolderToo() {
|
||||
// A -2 closes two folders at once (SDK: "last in the innermost and next-innermost
|
||||
// folders"), so track 3 is outside track 0's folder even though no track between
|
||||
// them closed it singly.
|
||||
const std::vector<int> depths{1, 1, -2, 0};
|
||||
CHECK(sameIndices(directChildIndices(depths, 0), {1}));
|
||||
CHECK(sameIndices(directChildIndices(depths, 1), {2}));
|
||||
}
|
||||
|
||||
static void testNonFolderAndOutOfRangeReturnEmpty() {
|
||||
const std::vector<int> depths{1, 0, -1};
|
||||
CHECK(sameIndices(directChildIndices(depths, 1), {})); // a plain child
|
||||
CHECK(sameIndices(directChildIndices(depths, 2), {})); // the folder's last track
|
||||
CHECK(sameIndices(directChildIndices(depths, -1), {})); // no such track
|
||||
CHECK(sameIndices(directChildIndices(depths, 3), {})); // past the end
|
||||
CHECK(sameIndices(directChildIndices({}, 0), {})); // empty project
|
||||
}
|
||||
|
||||
static void testUnterminatedFolderSwallowsTheRest() {
|
||||
// A folder that never closes owns every remaining track, which is how REAPER
|
||||
// reads the same list — the walk must not stop early and leave a child audible.
|
||||
const std::vector<int> depths{1, 0, 0};
|
||||
CHECK(sameIndices(directChildIndices(depths, 0), {1, 2}));
|
||||
}
|
||||
|
||||
int main() {
|
||||
testFlatProjectHasNoChildren();
|
||||
testFolderParentReturnsItsDirectChildren();
|
||||
testGrandchildrenAreExcluded();
|
||||
testMultiLevelCloseEndsTheOuterFolderToo();
|
||||
testNonFolderAndOutOfRangeReturnEmpty();
|
||||
testUnterminatedFolderSwallowsTheRest();
|
||||
|
||||
if (g_fail == 0) std::printf("track_topology: all tests passed\n");
|
||||
return g_fail == 0 ? 0 : 1;
|
||||
}
|
||||
Reference in New Issue
Block a user