Files
reasampler/tests/test_undo_intercept.cpp
daniel f6f09d983c Close the FX reclaim span when REAPER's own Undo/Redo is dispatched, so the switch's point mints first
Both command hooks intercept Edit: Undo (40029) and Edit: Redo (40030) and consume
nothing. Undo routes that never dispatch an action remain uncovered.
2026-08-09 13:40:28 -04:00

66 lines
2.6 KiB
C++

// Standalone tests for which dispatched action ids end the FX reclaim span — no REAPER,
// no test framework. The predicate is the whole of the interception's decision; the close
// it drives needs a DAW. What is assertable here: the id pair is exact, and it is scoped
// to the main sections, because command ids are per-section and the same integer under
// another section is an unrelated action.
#include "../src/shell/undo/undo_intercept.h"
#include <cstdio>
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)
namespace {
constexpr int kMainSection = 0;
constexpr int kMainAltSection = 100;
constexpr int kMidiEditor = 32060;
constexpr int kMediaExplorer = 32063;
void undoAndRedoInTheMainSectionAreIntercepted() {
CHECK(isMainUndoRedoCommand(kEditUndoCommand, kMainSection));
CHECK(isMainUndoRedoCommand(kEditRedoCommand, kMainSection));
// Main alt shares the main id space (reaper_plugin.h: "0/100=main/main alt"), so a
// Ctrl-Z fired while the alt section is active is the same action.
CHECK(isMainUndoRedoCommand(kEditUndoCommand, kMainAltSection));
CHECK(isMainUndoRedoCommand(kEditRedoCommand, kMainAltSection));
}
void everyOtherMainSectionActionIsLeftAlone() {
// Every action in the tree passes through this predicate; only these two ids may end
// the span, or an ordinary edit made mid-drain would split the switch's undo point.
CHECK(!isMainUndoRedoCommand(kEditUndoCommand - 1, kMainSection));
CHECK(!isMainUndoRedoCommand(kEditRedoCommand + 1, kMainSection));
CHECK(!isMainUndoRedoCommand(40012, kMainSection));
CHECK(!isMainUndoRedoCommand(0, kMainSection));
CHECK(!isMainUndoRedoCommand(-1, kMainSection));
}
void theSameIdsUnderAnotherSectionAreNotOurUndo() {
CHECK(!isMainUndoRedoCommand(kEditUndoCommand, kMidiEditor));
CHECK(!isMainUndoRedoCommand(kEditRedoCommand, kMidiEditor));
CHECK(!isMainUndoRedoCommand(kEditUndoCommand, kMediaExplorer));
// A hook that could not name its section (null KbdSectionInfo) is not assumed to be
// main — hookcommand covers the main section unconditionally anyway.
CHECK(!isMainUndoRedoCommand(kEditUndoCommand, -1));
}
} // namespace
int main() {
undoAndRedoInTheMainSectionAreIntercepted();
everyOtherMainSectionActionIsLeftAlone();
theSameIdsUnderAnotherSectionAreNotOurUndo();
if (g_fail) {
std::printf("%d check(s) failed\n", g_fail);
return 1;
}
std::printf("undo_intercept: all checks passed\n");
return 0;
}