// Standalone tests for reasampler::vst::note_entry — no VST3, no REAPER, no framework. // Assert the S12 direct-numeric-entry parse for a zone's low/high/root MIDI note. // // Covers: plain decimal integers (with +/- sign + surrounding whitespace); note names under the // C4==60 convention (C-1==0, sharps + flats, negative octaves); out-of-range values CLAMPING to // [0,127] rather than rejecting; empty / whitespace-only / unparseable input returning nullopt; // the integer path taking precedence over the note-name path for a leading digit. #include "../src/vst/note_entry.h" #include using namespace reasampler::vst; 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 void testPlainIntegers() { CHECK(parseNoteEntry("60") == 60); CHECK(parseNoteEntry("0") == 0); CHECK(parseNoteEntry("127") == 127); CHECK(parseNoteEntry(" 64 ") == 64); // surrounding whitespace ignored CHECK(parseNoteEntry("+5") == 5); } static void testIntegerClamps() { CHECK(parseNoteEntry("200") == 127); // over-range clamps to the ceiling CHECK(parseNoteEntry("-10") == 0); // under-range clamps to the floor CHECK(parseNoteEntry("99999") == 127); } static void testNoteNames() { // C4 == 60 (MIDI 0 == C-1). CHECK(parseNoteEntry("C4") == 60); CHECK(parseNoteEntry("c4") == 60); // case-insensitive CHECK(parseNoteEntry("A4") == 69); // A4 = 69 (concert A) CHECK(parseNoteEntry("C-1") == 0); // lowest MIDI note CHECK(parseNoteEntry("G9") == 127); // G9 = 127 } static void testAccidentals() { CHECK(parseNoteEntry("C#4") == 61); CHECK(parseNoteEntry("Db4") == 61); // enharmonic of C#4 CHECK(parseNoteEntry("F#3") == 54); CHECK(parseNoteEntry("Bb3") == 58); // Bb3 = 58 } static void testNoteNameClamps() { CHECK(parseNoteEntry("C10") == 127); // above the range clamps CHECK(parseNoteEntry("C-5") == 0); // below the range clamps } static void testRejects() { CHECK(parseNoteEntry("") == std::nullopt); CHECK(parseNoteEntry(" ") == std::nullopt); CHECK(parseNoteEntry("hello") == std::nullopt); CHECK(parseNoteEntry("C") == std::nullopt); // a bare letter with no octave is ambiguous CHECK(parseNoteEntry("H4") == std::nullopt); // H is not a note letter CHECK(parseNoteEntry("+") == std::nullopt); } int main() { testPlainIntegers(); testIntegerClamps(); testNoteNames(); testAccidentals(); testNoteNameClamps(); testRejects(); if (g_fail == 0) std::printf("note_entry: all tests passed\n"); return g_fail != 0; }