1+ #include < boost/test/unit_test.hpp>
2+ #include < boost/test/data/test_case.hpp>
3+ #include " luatest.hpp"
4+
5+ BOOST_AUTO_TEST_SUITE (MidiScriptTests)
6+
7+ namespace bdata = boost::unit_test::data;
8+ using JuceCounterpart = std::function<juce::MidiMessage()>;
9+
10+ struct LuaMidiTestCase {
11+ std::string luaMethodCall;
12+ JuceCounterpart juceCounterpart;
13+ bool shouldCheckTheSecondByte = true ;
14+ bool shouldCheckThirdByte = true ;
15+
16+ friend std::ostream& operator << (std::ostream& os, const LuaMidiTestCase& testCase)
17+ {
18+ os << " { luaMethodCall: \" " << testCase.luaMethodCall << " \" , ... } " ;
19+ return os;
20+ }
21+ };
22+
23+ BOOST_DATA_TEST_CASE (
24+ luaSimpleBindigs,
25+ bdata::make (std::initializer_list<LuaMidiTestCase> {
26+ { .luaMethodCall = " return midi.controller(1, 7, 120)" ,
27+ .juceCounterpart = []() -> juce::MidiMessage { return juce::MidiMessage::controllerEvent (1 , 7 , 120 ); } },
28+
29+ { .luaMethodCall = " return midi.noteon(1, 60, 100)" ,
30+ .juceCounterpart = []() -> juce::MidiMessage { return juce::MidiMessage::noteOn (1 , 60 , (uint8_t ) 100 ); } },
31+
32+ { .luaMethodCall = " return midi.noteoff(1, 60)" ,
33+ .juceCounterpart = []() -> juce::MidiMessage { return juce::MidiMessage::noteOff (1 , 60 ); } },
34+
35+ { .luaMethodCall = " return midi.program(1, 5)" ,
36+ .juceCounterpart = []() -> juce::MidiMessage { return juce::MidiMessage::programChange (1 , 5 ); },
37+ .shouldCheckThirdByte = false },
38+
39+ { .luaMethodCall = " return midi.pitch(1, 8192)" ,
40+ .juceCounterpart = []() -> juce::MidiMessage { return juce::MidiMessage::pitchWheel (1 , 8192 ); } },
41+
42+ { .luaMethodCall = " return midi.aftertouch(1, 60, 64)" ,
43+ .juceCounterpart = []() -> juce::MidiMessage { return juce::MidiMessage::aftertouchChange (1 , 60 , 64 ); } },
44+
45+ { .luaMethodCall = " return midi.channelpressure(1, 45)" ,
46+ .juceCounterpart = []() -> juce::MidiMessage { return juce::MidiMessage::channelPressureChange (1 , 45 ); },
47+ .shouldCheckThirdByte = false },
48+
49+ { .luaMethodCall = " return midi.allnotesoff(1)" ,
50+ .juceCounterpart = []() -> juce::MidiMessage { return juce::MidiMessage::allNotesOff (1 ); } },
51+
52+ { .luaMethodCall = " return midi.allsoundsoff(1)" ,
53+ .juceCounterpart = []() -> juce::MidiMessage { return juce::MidiMessage::allSoundOff (1 ); } },
54+
55+ { .luaMethodCall = " return midi.allcontrollersoff(1)" ,
56+ .juceCounterpart = []() -> juce::MidiMessage { return juce::MidiMessage::allControllersOff (1 ); } },
57+
58+ { .luaMethodCall = " return midi.clock()" ,
59+ .juceCounterpart = []() -> juce::MidiMessage { return juce::MidiMessage::midiClock (); },
60+ .shouldCheckTheSecondByte = false ,
61+ .shouldCheckThirdByte = false },
62+
63+ { .luaMethodCall = " return midi.start()" ,
64+ .juceCounterpart = []() -> juce::MidiMessage { return juce::MidiMessage::midiStart (); },
65+ .shouldCheckTheSecondByte = false ,
66+ .shouldCheckThirdByte = false },
67+
68+ { .luaMethodCall = " return midi.stop()" ,
69+ .juceCounterpart = []() -> juce::MidiMessage { return juce::MidiMessage::midiStop (); },
70+ .shouldCheckTheSecondByte = false ,
71+ .shouldCheckThirdByte = false },
72+
73+ { .luaMethodCall = " return midi.continue()" ,
74+ .juceCounterpart = []() -> juce::MidiMessage { return juce::MidiMessage::midiContinue (); },
75+ .shouldCheckTheSecondByte = false ,
76+ .shouldCheckThirdByte = false },
77+ }),
78+ testData)
79+ {
80+ LuaFixture fix;
81+ sol::state_view lua (fix.luaState ());
82+ lua.script (" midi = require('el.midi')" );
83+
84+ int64_t packed = lua.script (testData.luaMethodCall );
85+
86+ auto expected = testData.juceCounterpart ();
87+ BOOST_CHECK_EQUAL (uint8_t (packed), expected.getRawData ()[0 ]);
88+ if (testData.shouldCheckTheSecondByte ) {
89+ BOOST_CHECK_EQUAL (uint8_t (packed >> 8 ), expected.getRawData ()[1 ]);
90+ } else {
91+ BOOST_CHECK_EQUAL (uint8_t (packed >> 8 ), 0 );
92+ }
93+ if (testData.shouldCheckThirdByte ) {
94+ BOOST_CHECK_EQUAL (uint8_t (packed >> 16 ), expected.getRawData ()[2 ]);
95+ } else {
96+ BOOST_CHECK_EQUAL (uint8_t (packed >> 16 ), 0 );
97+ }
98+ }
99+
100+ BOOST_AUTO_TEST_CASE (test_tohertz)
101+ {
102+ LuaFixture fix;
103+ sol::state_view lua (fix.luaState ());
104+ lua.script (" midi = require('el.midi')" );
105+
106+ for (int note = 0 ; note <= 127 ; ++note) {
107+ std::string script = " return midi.tohertz(" + std::to_string (note) + " )" ;
108+ double luaFreq = lua.script (script);
109+
110+ double juceFreq = juce::MidiMessage::getMidiNoteInHertz (note);
111+
112+ BOOST_CHECK_CLOSE (luaFreq, juceFreq, 0.001 );
113+ }
114+ }
115+
116+ BOOST_AUTO_TEST_CASE (test_clamp)
117+ {
118+ LuaFixture fix;
119+ sol::state_view lua (fix.luaState ());
120+
121+ lua.script (" midi = require('el.midi')" );
122+
123+ int64_t resultNormal = lua.script (" return midi.clamp(64)" );
124+ BOOST_CHECK_EQUAL (resultNormal, 64.0 );
125+
126+ int64_t resultMin = lua.script (" return midi.clamp(0)" );
127+ BOOST_CHECK_EQUAL (resultMin, 0 );
128+
129+ int64_t resultMax = lua.script (" return midi.clamp(127)" );
130+ BOOST_CHECK_EQUAL (resultMax, 127 );
131+
132+ int64_t resultUnder = lua.script (" return midi.clamp(-50)" );
133+ BOOST_CHECK_EQUAL (resultUnder, 0 );
134+
135+ int64_t resultOver = lua.script (" return midi.clamp(200)" );
136+ BOOST_CHECK_EQUAL (resultOver, 127 );
137+ }
138+ BOOST_AUTO_TEST_SUITE_END ()
0 commit comments