rename view_model -> view_mode_model; add shell-expands-FX test and parse-site comments
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Standalone tests for reasampler::view_model — no REAPER, no test framework.
|
||||
// Standalone tests for reasampler::ViewModeModel — no REAPER, no test framework.
|
||||
// Mirror of test_bank_model: iterate the hard logic outside the DAW.
|
||||
//
|
||||
// Covers (PLAN.md D1 test cases):
|
||||
@@ -10,8 +10,9 @@
|
||||
// 4. show-both leaf never appears in a park op-list and is visible in all modes.
|
||||
// 5. Unknown/stale GUID tolerated (ignore-and-prune, no crash).
|
||||
// 6. JSON round-trip lossless: modes + membership + show-both + snapshots + active.
|
||||
// 7. planToggle park path: fxOffline is empty (shell-expands-FX contract).
|
||||
|
||||
#include "../src/view_model.h"
|
||||
#include "../src/view_mode_model.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
@@ -53,7 +54,7 @@ static int flagValue(const TrackPlan& p, Flag f) {
|
||||
// -- 1. N-mode proven --------------------------------------------------------
|
||||
|
||||
static void testNModeRegistryAndMembership() {
|
||||
ViewModel vm;
|
||||
ViewModeModel vm;
|
||||
// Seeded: Arrange + Design.
|
||||
CHECK(vm.modes().size() == 2);
|
||||
CHECK(vm.modes().contains(kArrangeModeId));
|
||||
@@ -105,7 +106,7 @@ static void testNModeRegistryAndMembership() {
|
||||
// -- 2. Parent derivation ----------------------------------------------------
|
||||
|
||||
static void testParentDerivationMultiMode() {
|
||||
ViewModel vm;
|
||||
ViewModeModel vm;
|
||||
// Folder {F} holds two leaves: {L1} in Arrange (untagged default), {L2} in Design.
|
||||
FolderTree tree;
|
||||
tree.nodes.push_back(FolderNode{"{F}", "", /*isParent=*/true});
|
||||
@@ -131,7 +132,7 @@ static void testParentDerivationMultiMode() {
|
||||
nested.nodes.push_back(FolderNode{"{G}", "", true});
|
||||
nested.nodes.push_back(FolderNode{"{F2}", "{G}", true});
|
||||
nested.nodes.push_back(FolderNode{"{L3}", "{F2}", false});
|
||||
ViewModel vm2;
|
||||
ViewModeModel vm2;
|
||||
vm2.membership().tag("{L3}", kDesignModeId);
|
||||
auto d2 = vm2.visibleTracks(nested, kDesignModeId);
|
||||
CHECK(visibleHas(d2, "{L3}"));
|
||||
@@ -189,7 +190,7 @@ static void testRestoreRoundTripSnapshotValues() {
|
||||
|
||||
// End-to-end via planToggle: a leaf tagged Design, snapshotted, parked while in
|
||||
// Arrange, then restored when we toggle back to Design.
|
||||
ViewModel vm;
|
||||
ViewModeModel vm;
|
||||
FolderTree tree;
|
||||
tree.nodes.push_back(FolderNode{"{DES}", "", false});
|
||||
vm.membership().tag("{DES}", kDesignModeId);
|
||||
@@ -214,7 +215,7 @@ static void testRestoreRoundTripSnapshotValues() {
|
||||
// -- 4. show-both leaf --------------------------------------------------------
|
||||
|
||||
static void testShowBothNeverParkedVisibleEverywhere() {
|
||||
ViewModel vm;
|
||||
ViewModeModel vm;
|
||||
CHECK(vm.modes().add(Mode{"mixdown", "Mixdown", 2}));
|
||||
|
||||
FolderTree tree;
|
||||
@@ -243,7 +244,7 @@ static void testShowBothNeverParkedVisibleEverywhere() {
|
||||
// -- 5. Unknown/stale GUID tolerated -----------------------------------------
|
||||
|
||||
static void testStaleGuidTolerated() {
|
||||
ViewModel vm;
|
||||
ViewModeModel vm;
|
||||
// Tag two leaves, but the tree only knows one — the other GUID is stale (its
|
||||
// track was deleted / restructured while parked).
|
||||
vm.membership().tag("{LIVE}", kDesignModeId);
|
||||
@@ -273,7 +274,7 @@ static void testStaleGuidTolerated() {
|
||||
// -- 6. JSON round-trip lossless ---------------------------------------------
|
||||
|
||||
static void testJsonRoundTrip() {
|
||||
ViewModel vm;
|
||||
ViewModeModel vm;
|
||||
// Modes: seeded pair + a third; also an out-of-order ordinal to prove sorting
|
||||
// survives round-trip.
|
||||
CHECK(vm.modes().add(Mode{"print", "Print \"stem\"\n", 5}));
|
||||
@@ -301,7 +302,7 @@ static void testJsonRoundTrip() {
|
||||
CHECK(vm.setActiveMode("mixdown"));
|
||||
|
||||
std::string json = vm.serialize();
|
||||
auto back = ViewModel::deserialize(json);
|
||||
auto back = ViewModeModel::deserialize(json);
|
||||
CHECK(back.has_value());
|
||||
CHECK(back && *back == vm);
|
||||
// String form is stable across a second round-trip.
|
||||
@@ -323,14 +324,14 @@ static void testJsonRoundTrip() {
|
||||
}
|
||||
|
||||
static void testEmptyModelRoundTrip() {
|
||||
ViewModel vm; // default: Arrange + Design seeded, active = Arrange, no members
|
||||
ViewModeModel vm; // default: Arrange + Design seeded, active = Arrange, no members
|
||||
std::string json = vm.serialize();
|
||||
auto back = ViewModel::deserialize(json);
|
||||
auto back = ViewModeModel::deserialize(json);
|
||||
CHECK(back.has_value());
|
||||
CHECK(back && *back == vm);
|
||||
|
||||
// Lenient empty root ⇒ a default-seeded model.
|
||||
auto empty = ViewModel::deserialize("{}");
|
||||
auto empty = ViewModeModel::deserialize("{}");
|
||||
CHECK(empty.has_value());
|
||||
CHECK(empty && empty->modes().size() == 2);
|
||||
CHECK(empty && empty->activeModeId() == kArrangeModeId);
|
||||
@@ -352,11 +353,36 @@ static void testMalformedJson() {
|
||||
"{\"modes\":[]}trailing", // trailing garbage
|
||||
};
|
||||
for (const char* j : bad) {
|
||||
auto r = ViewModel::deserialize(j);
|
||||
auto r = ViewModeModel::deserialize(j);
|
||||
CHECK(!r.has_value());
|
||||
}
|
||||
}
|
||||
|
||||
// -- 7. planToggle park path: fxOffline is empty (shell-expands-FX contract) --
|
||||
//
|
||||
// planToggle calls makeParkPlan(guid, /*fxCount=*/0) for each inactive leaf.
|
||||
// The D2 shell is responsible for expanding per-FX offline ops using
|
||||
// TrackFX_GetCount — the pure model has no access to REAPER FX counts at plan
|
||||
// time. This test pins that contract so a regression that passes a non-zero
|
||||
// count (and emits FX ops prematurely) is caught immediately.
|
||||
// The direct makeParkPlan(guid, 3) path (non-zero fxCount) is covered by
|
||||
// testRestoreRoundTripSnapshotValues above.
|
||||
|
||||
static void testPlanToggleParkHasEmptyFxOffline() {
|
||||
ViewModeModel vm;
|
||||
FolderTree tree;
|
||||
tree.nodes.push_back(FolderNode{"{LEAF}", "", false});
|
||||
vm.membership().tag("{LEAF}", kDesignModeId);
|
||||
|
||||
// Toggle to Arrange: {LEAF} is inactive ⇒ park plan emitted.
|
||||
auto plan = vm.planToggle(tree, kArrangeModeId);
|
||||
CHECK(plan.park.size() == 1);
|
||||
// The park plan must have an empty fxOffline — the shell expands FX ops.
|
||||
CHECK(plan.park[0].fxOffline.empty());
|
||||
// Scalar flags must still be present (the four park zeros).
|
||||
CHECK(plan.park[0].flags.size() == 4);
|
||||
}
|
||||
|
||||
int main() {
|
||||
testNModeRegistryAndMembership();
|
||||
testParentDerivationMultiMode();
|
||||
@@ -366,6 +392,7 @@ int main() {
|
||||
testJsonRoundTrip();
|
||||
testEmptyModelRoundTrip();
|
||||
testMalformedJson();
|
||||
testPlanToggleParkHasEmptyFxOffline();
|
||||
|
||||
if (g_fail == 0) std::printf("All tests passed.\n");
|
||||
return g_fail ? 1 : 0;
|
||||
Reference in New Issue
Block a user