Skip to content

Instantly share code, notes, and snippets.

@PedroAlvesV
Last active March 11, 2020 07:59
Show Gist options
  • Save PedroAlvesV/6e2c052e95d9de500fd97a989cebd432 to your computer and use it in GitHub Desktop.
Save PedroAlvesV/6e2c052e95d9de500fd97a989cebd432 to your computer and use it in GitHub Desktop.
unit tests for LuaMidi
local lu = require('luaunit')
math.randomseed(os.time())
local LuaMidi = require('LuaMidi')
local MIN = {
PITCH = 0x00,
VELOCITY = 0,
REPETITION = 1,
CHANNEL = 1,
TIMESTAMP = 0,
BYTE = 0x00,
}
local MAX = {
PITCH = 0x7F,
VELOCITY = 100,
CHANNEL = 16,
BYTE = 0xFF,
PCNUM = 0x7F,
}
local TYPES = {
NUM = 0,
TAB = {},
STR = "",
BOOL = true,
FUNC = function() end,
}
TestNoteEvent = {}
function TestNoteEvent:testConstructorValid()
local NoteEvent = LuaMidi.NoteEvent
local p = {math.random(MIN.PITCH, MAX.PITCH)}
local durations = {1, 2, "d2", 4, "d4", 8, "8t", "d8", 16, "T"}
local dur = durations[math.random(1, #durations)]
if dur == "T" then dur = dur..math.random(MIN.BYTE, 0xFF) end
local rest = durations[math.random(1, #durations)]
if rest == "T" then rest = rest..math.random(MIN.BYTE, 0xFF) end
local vel = math.random(MIN.VELOCITY, MAX.VELOCITY)
local seq = true
local rep = math.random(MIN.REPETITION, 10)
local ch = math.random(MIN.CHANNEL, MAX.CHANNEL)
local evt = NoteEvent.new({
pitch = p,
duration = dur,
rest = rest,
velocity = vel,
sequential = seq,
repetition = rep,
channel = ch,
})
-- TEST ATTRIBUTION
lu.assertEquals(evt:get_pitch(), p)
lu.assertEquals(evt:get_duration(), dur)
lu.assertEquals(evt:get_rest(), rest)
lu.assertEquals(evt:get_velocity(), vel)
lu.assertEquals(evt:get_sequential(), seq)
lu.assertEquals(evt:get_repetition(), rep)
lu.assertEquals(evt:get_channel(), ch)
p = {
math.random(MIN.PITCH, MAX.PITCH),
math.random(MIN.PITCH, MAX.PITCH),
}
evt = NoteEvent.new({pitch = p})
lu.assertEquals(evt:get_pitch(), p)
-- TEST MIN
lu.assertEquals(NoteEvent.new({pitch = MIN.PITCH}):get_pitch(), {MIN.PITCH})
dur = "T0"
rest = "T0"
seq = false
evt = NoteEvent.new({
pitch = p,
duration = dur,
rest = rest,
velocity = MIN.VELOCITY,
sequential = seq,
repetition = MIN.REPETITION,
channel = MIN.CHANNEL,
})
lu.assertEquals(evt:get_duration(), dur)
lu.assertEquals(evt:get_rest(), rest)
lu.assertEquals(evt:get_velocity(), MIN.VELOCITY)
lu.assertEquals(evt:get_sequential(), seq)
lu.assertEquals(evt:get_repetition(), MIN.REPETITION)
lu.assertEquals(evt:get_channel(), MIN.CHANNEL)
-- TEST MAX
lu.assertEquals(NoteEvent.new({pitch = MAX.PITCH}):get_pitch(), {MAX.PITCH})
seq = true
evt = NoteEvent.new({
pitch = p,
velocity = MAX.VELOCITY,
sequential = seq,
channel = MAX.CHANNEL,
})
lu.assertEquals(evt:get_velocity(), MAX.VELOCITY)
lu.assertEquals(evt:get_sequential(), seq)
lu.assertEquals(evt:get_channel(), MAX.CHANNEL)
end
function TestNoteEvent:testConstructorInvalid()
local NoteEvent = LuaMidi.NoteEvent
-- TEST LOWER THAN BOUNDARY
lu.assertErrorMsgContains("Invalid 'pitch' value", NoteEvent.new, {pitch = MIN.PITCH-1})
vel = MIN.VELOCITY-1
rep = MIN.REPETITION-1
ch = MIN.CHANNEL-1
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteEvent.new, {pitch = MIN.PITCH, velocity=vel})
lu.assertErrorMsgContains("'repetition' must be a positive integer", NoteEvent.new, {pitch = MIN.PITCH, repetition=rep})
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteEvent.new, {pitch = MIN.PITCH, channel=ch})
-- TEST HIGHER THAN BOUNDARY
lu.assertErrorMsgContains("Invalid 'pitch' value", NoteEvent.new, {pitch = MAX.PITCH+1})
vel = MAX.VELOCITY+1
ch = MAX.CHANNEL+1
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteEvent.new, {pitch = MIN.PITCH, velocity=vel})
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteEvent.new, {pitch = MIN.PITCH, channel=ch})
-- TEST EMPTY PARAMETER
lu.assertErrorMsgContains("attempt to index a nil value (local 'fields')", NoteEvent.new, nil)
-- TEST INVALID TYPES
lu.assertErrorMsgContains("'pitch' must be a string, a number or an array", NoteEvent.new, {
pitch = TYPES.BOOL
})
lu.assertErrorMsgContains("'pitch' must be a string, a number or an array", NoteEvent.new, {
pitch = TYPES.FUNC
})
lu.assertErrorMsgContains("'duration' must be a string or a number", NoteEvent.new, {
pitch = MIN.PITCH, duration = TYPES.TAB
})
lu.assertErrorMsgContains("'duration' must be a string or a number", NoteEvent.new, {
pitch = MIN.PITCH, duration = TYPES.BOOL
})
lu.assertErrorMsgContains("'duration' must be a string or a number", NoteEvent.new, {
pitch = MIN.PITCH, duration = TYPES.FUNC
})
lu.assertErrorMsgContains("'rest' must be a string or a number", NoteEvent.new, {
pitch = MIN.PITCH, rest = TYPES.TAB
})
lu.assertErrorMsgContains("'rest' must be a string or a number", NoteEvent.new, {
pitch = MIN.PITCH, rest = TYPES.BOOL
})
lu.assertErrorMsgContains("'rest' must be a string or a number", NoteEvent.new, {
pitch = MIN.PITCH, rest = TYPES.FUNC
})
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteEvent.new, {
pitch = MIN.PITCH, velocity = TYPES.TAB
})
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteEvent.new, {
pitch = MIN.PITCH, velocity = TYPES.STR
})
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteEvent.new, {
pitch = MIN.PITCH, velocity = TYPES.BOOL
})
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteEvent.new, {
pitch = MIN.PITCH, velocity = TYPES.FUNC
})
lu.assertErrorMsgContains("'sequential' must be a boolean", NoteEvent.new, {
pitch = MIN.PITCH, sequential = TYPES.NUM
})
lu.assertErrorMsgContains("'sequential' must be a boolean", NoteEvent.new, {
pitch = MIN.PITCH, sequential = TYPES.TAB
})
lu.assertErrorMsgContains("'sequential' must be a boolean", NoteEvent.new, {
pitch = MIN.PITCH, sequential = TYPES.STR
})
lu.assertErrorMsgContains("'sequential' must be a boolean", NoteEvent.new, {
pitch = MIN.PITCH, sequential = TYPES.FUNC
})
lu.assertErrorMsgContains("'repetition' must be a positive integer", NoteEvent.new, {
pitch = MIN.PITCH, repetition = TYPES.TAB
})
lu.assertErrorMsgContains("'repetition' must be a positive integer", NoteEvent.new, {
pitch = MIN.PITCH, repetition = TYPES.STR
})
lu.assertErrorMsgContains("'repetition' must be a positive integer", NoteEvent.new, {
pitch = MIN.PITCH, repetition = TYPES.BOOL
})
lu.assertErrorMsgContains("'repetition' must be a positive integer", NoteEvent.new, {
pitch = MIN.PITCH, repetition = TYPES.FUNC
})
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteEvent.new, {
pitch = MIN.PITCH, channel = TYPES.TAB
})
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteEvent.new, {
pitch = MIN.PITCH, channel = TYPES.STR
})
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteEvent.new, {
pitch = MIN.PITCH, channel = TYPES.BOOL
})
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteEvent.new, {
pitch = MIN.PITCH, channel = TYPES.FUNC
})
end
function TestNoteEvent:testSettersValid()
local NoteEvent = LuaMidi.NoteEvent
local p = {math.random(MIN.PITCH, MAX.PITCH)}
local durations = {1, 2, "d2", 4, "d4", 8, "8t", "d8", 16, "T"}
local dur = durations[math.random(1, #durations)]
if dur == "T" then dur = dur..math.random(MIN.BYTE, 0xFF) end
local rest = durations[math.random(1, #durations)]
if rest == "T" then rest = rest..math.random(MIN.BYTE, 0xFF) end
local vel = math.random(MIN.VELOCITY, MAX.VELOCITY)
local seq = false
local rep = math.random(MIN.REPETITION, 10)
local ch = math.random(MIN.CHANNEL, MAX.CHANNEL)
local evt = NoteEvent.new({pitch = MIN.PITCH})
evt:set_pitch(p):set_duration(dur):set_rest(rest):set_velocity(vel):set_sequential(seq):set_repetition(rep):set_channel(ch)
lu.assertEquals(evt:get_pitch(), p)
lu.assertEquals(evt:get_duration(), dur)
lu.assertEquals(evt:get_rest(), rest)
lu.assertEquals(evt:get_velocity(), vel)
lu.assertEquals(evt:get_sequential(), seq)
lu.assertEquals(evt:get_repetition(), rep)
lu.assertEquals(evt:get_channel(), ch)
p = {
math.random(MIN.PITCH, MAX.PITCH),
math.random(MIN.PITCH, MAX.PITCH),
}
evt:set_pitch(p)
lu.assertEquals(evt:get_pitch(), p)
-- TEST MIN
lu.assertEquals(evt:set_pitch({MIN.PITCH}):get_pitch(), {MIN.PITCH})
dur = "T0"
rest = "T0"
vel = MIN.VELOCITY
seq = false
rep = MIN.REPETITION
ch = MIN.CHANNEL
lu.assertEquals(evt:set_duration(dur):get_duration(), dur)
lu.assertEquals(evt:set_rest(rest):get_rest(), rest)
lu.assertEquals(evt:set_velocity(vel):get_velocity(), vel)
lu.assertEquals(evt:set_sequential(seq):get_sequential(), seq)
lu.assertEquals(evt:set_repetition(rep):get_repetition(), rep)
lu.assertEquals(evt:set_channel(ch):get_channel(), ch)
-- TEST MAX
lu.assertEquals(evt:set_pitch({MAX.PITCH}):get_pitch(), {MAX.PITCH})
vel = MAX.VELOCITY
seq = true
ch = MAX.CHANNEL
lu.assertEquals(evt:set_velocity(vel):get_velocity(), vel)
lu.assertEquals(evt:set_sequential(seq):get_sequential(), seq)
lu.assertEquals(evt:set_channel(ch):get_channel(), ch)
end
function TestNoteEvent:testSettersInvalid()
local NoteEvent = LuaMidi.NoteEvent
local evt = NoteEvent.new({pitch = MIN.PITCH})
-- TEST LOWER THAN BOUNDARY
lu.assertErrorMsgContains("Invalid 'pitch' value", NoteEvent.set_pitch, evt, {MIN.PITCH-1})
evt = NoteEvent.new({pitch = MIN.PITCH}) -- cleaning object for tests in other setters
vel = MIN.VELOCITY-1
rep = MIN.REPETITION-1
ch = MIN.CHANNEL-1
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteEvent.set_velocity, evt, vel)
lu.assertErrorMsgContains("'repetition' must be a positive integer", NoteEvent.set_repetition, evt, rep)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteEvent.set_channel, evt, ch)
-- TEST HIGHER THAN BOUNDARY
lu.assertErrorMsgContains("Invalid 'pitch' value", NoteEvent.set_pitch, evt, {MAX.PITCH+1})
evt = NoteEvent.new({pitch = MIN.PITCH}) -- cleaning object for tests in other setters
vel = MAX.VELOCITY+1
ch = MAX.CHANNEL+1
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteEvent.set_velocity, evt, vel)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteEvent.set_channel, evt, ch)
-- TEST EMPTY PARAMETER
evt = NoteEvent.new({pitch = MIN.PITCH}) -- cleaning object for tests in other setters
lu.assertErrorMsgContains("'pitch' must be a string, a number or an array", NoteEvent.set_pitch, evt, nil)
lu.assertErrorMsgContains("'duration' must be a string or a number", NoteEvent.set_duration, evt, nil)
lu.assertErrorMsgContains("'rest' must be a string or a number", NoteEvent.set_rest, evt, nil)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteEvent.set_velocity, evt, nil)
lu.assertErrorMsgContains("'sequential' must be a boolean", NoteEvent.set_sequential, evt, nil)
lu.assertErrorMsgContains("'repetition' must be a positive integer", NoteEvent.set_repetition, evt, nil)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteEvent.set_channel, evt, nil)
-- TEST INVALID TYPES
evt = NoteEvent.new({pitch = MIN.PITCH}) -- cleaning object for tests in other setters
lu.assertErrorMsgContains("'pitch' must be a string, a number or an array",
NoteEvent.set_pitch, evt, TYPES.BOOL)
lu.assertErrorMsgContains("'pitch' must be a string, a number or an array",
NoteEvent.set_pitch, evt, TYPES.FUNC)
lu.assertErrorMsgContains("'duration' must be a string or a number",
NoteEvent.set_duration, evt, TYPES.TAB)
lu.assertErrorMsgContains("'duration' must be a string or a number",
NoteEvent.set_duration, evt, TYPES.BOOL)
lu.assertErrorMsgContains("'duration' must be a string or a number",
NoteEvent.set_duration, evt, TYPES.FUNC)
lu.assertErrorMsgContains("'rest' must be a string or a number",
NoteEvent.set_rest, evt, TYPES.TAB)
lu.assertErrorMsgContains("'rest' must be a string or a number",
NoteEvent.set_rest, evt, TYPES.BOOL)
lu.assertErrorMsgContains("'rest' must be a string or a number",
NoteEvent.set_rest, evt, TYPES.FUNC)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100",
NoteEvent.set_velocity, evt, TYPES.TAB)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100",
NoteEvent.set_velocity, evt, TYPES.STR)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100",
NoteEvent.set_velocity, evt, TYPES.BOOL)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100",
NoteEvent.set_velocity, evt, TYPES.FUNC)
lu.assertErrorMsgContains("'sequential' must be a boolean",
NoteEvent.set_sequential, evt, TYPES.NUM)
lu.assertErrorMsgContains("'sequential' must be a boolean",
NoteEvent.set_sequential, evt, TYPES.TAB)
lu.assertErrorMsgContains("'sequential' must be a boolean",
NoteEvent.set_sequential, evt, TYPES.STR)
lu.assertErrorMsgContains("'sequential' must be a boolean",
NoteEvent.set_sequential, evt, TYPES.FUNC)
lu.assertErrorMsgContains("'repetition' must be a positive integer",
NoteEvent.set_repetition, evt, TYPES.TAB)
lu.assertErrorMsgContains("'repetition' must be a positive integer",
NoteEvent.set_repetition, evt, TYPES.STR)
lu.assertErrorMsgContains("'repetition' must be a positive integer",
NoteEvent.set_repetition, evt, TYPES.BOOL)
lu.assertErrorMsgContains("'repetition' must be a positive integer",
NoteEvent.set_repetition, evt, TYPES.FUNC)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16",
NoteEvent.set_channel, evt, TYPES.TAB)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16",
NoteEvent.set_channel, evt, TYPES.STR)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16",
NoteEvent.set_channel, evt, TYPES.BOOL)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16",
NoteEvent.set_channel, evt, TYPES.FUNC)
end
TestNoteOff = {}
function TestNoteOff:testConstructorValid()
local NoteOffEvent = LuaMidi.NoteOffEvent
local p = math.random(MIN.PITCH, MAX.PITCH)
local ch = math.random(MIN.CHANNEL, MAX.CHANNEL)
local t = math.random(MIN.TIMESTAMP, 0xFF)
local vel = math.random(MIN.VELOCITY, MAX.VELOCITY)
local evt = NoteOffEvent.new({
pitch = p,
channel = ch,
timestamp = t,
velocity = vel,
})
lu.assertEquals(evt:get_pitch(), p)
lu.assertEquals(evt:get_channel(), ch)
lu.assertEquals(evt:get_timestamp(), t)
lu.assertEquals(evt:get_velocity(), vel)
p = math.random(MIN.PITCH, MAX.PITCH)
evt = NoteOffEvent.new({pitch = p})
lu.assertEquals(evt:get_pitch(), p)
-- TEST MIN
lu.assertEquals(NoteOffEvent.new({pitch = MIN.PITCH}):get_pitch(), MIN.PITCH)
ch = MIN.CHANNEL
t = MIN.TIMESTAMP
vel = MIN.VELOCITY
evt = NoteOffEvent.new({
pitch = p,
channel = ch,
timestamp = t,
velocity = vel,
})
lu.assertEquals(evt:get_channel(), ch)
lu.assertEquals(evt:get_timestamp(), t)
lu.assertEquals(evt:get_velocity(), vel)
-- TEST MAX
lu.assertEquals(NoteOffEvent.new({pitch = MAX.PITCH}):get_pitch(), MAX.PITCH)
ch = MAX.CHANNEL
vel = MAX.VELOCITY
evt = NoteOffEvent.new({
pitch = p,
channel = ch,
velocity = vel,
})
lu.assertEquals(evt:get_channel(), ch)
lu.assertEquals(evt:get_velocity(), vel)
end
function TestNoteOff:testConstructorInvalid()
local NoteOffEvent = LuaMidi.NoteOffEvent
-- TEST LOWER THAN BOUNDARY
lu.assertErrorMsgContains("Invalid 'pitch' value", NoteOffEvent.new, {pitch = MIN.PITCH-1})
ch = MIN.CHANNEL-1
t = MIN.TIMESTAMP-1
vel = MIN.VELOCITY-1
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOffEvent.new, {pitch = MIN.PITCH, channel=ch})
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks", NoteOffEvent.new, {pitch = MIN.PITCH, timestamp=t})
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOffEvent.new, {pitch = MIN.PITCH, velocity=vel})
-- TEST HIGHER THAN BOUNDARY
lu.assertErrorMsgContains("Invalid 'pitch' value", NoteOffEvent.new, {pitch = MAX.PITCH+1})
ch = MAX.CHANNEL+1
vel = MAX.VELOCITY+1
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOffEvent.new, {pitch = MIN.PITCH, channel=ch})
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOffEvent.new, {pitch = MIN.PITCH, velocity=vel})
-- TEST EMPTY PARAMETER
lu.assertErrorMsgContains("attempt to index a nil value (local 'fields')", NoteOffEvent.new, nil)
-- TEST INVALID TYPES
lu.assertErrorMsgContains("'pitch' must be a string or a number", NoteOffEvent.new, {pitch = TYPES.TAB})
lu.assertErrorMsgContains("'pitch' must be a string or a number", NoteOffEvent.new, {pitch = TYPES.BOOL})
lu.assertErrorMsgContains("'pitch' must be a string or a number", NoteOffEvent.new, {pitch = TYPES.FUNC})
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks",
NoteOffEvent.new, {pitch = MIN.PITCH, timestamp = TYPES.TAB}
)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks",
NoteOffEvent.new, {pitch = MIN.PITCH, timestamp = TYPES.STR}
)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks",
NoteOffEvent.new, {pitch = MIN.PITCH, timestamp = TYPES.BOOL}
)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks",
NoteOffEvent.new, {pitch = MIN.PITCH, timestamp = TYPES.FUNC}
)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOffEvent.new, {
pitch = MIN.PITCH, velocity = TYPES.TAB
})
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOffEvent.new, {
pitch = MIN.PITCH, velocity = TYPES.STR
})
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOffEvent.new, {
pitch = MIN.PITCH, velocity = TYPES.BOOL
})
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOffEvent.new, {
pitch = MIN.PITCH, velocity = TYPES.FUNC
})
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOffEvent.new, {
pitch = MIN.PITCH, channel = TYPES.TAB
})
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOffEvent.new, {
pitch = MIN.PITCH, channel = TYPES.STR
})
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOffEvent.new, {
pitch = MIN.PITCH, channel = TYPES.BOOL
})
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOffEvent.new, {
pitch = MIN.PITCH, channel = TYPES.FUNC
})
end
function TestNoteOff:testSettersValid()
local NoteOffEvent = LuaMidi.NoteOffEvent
local p = math.random(MIN.PITCH, MAX.PITCH)
local ch = math.random(MIN.CHANNEL, MAX.CHANNEL)
local t = math.random(MIN.TIMESTAMP, 0xFF)
local vel = math.random(MIN.VELOCITY, MAX.VELOCITY)
local evt = NoteOffEvent.new({pitch = MIN.PITCH})
evt:set_pitch(p):set_channel(ch):set_timestamp(t):set_velocity(vel)
lu.assertEquals(evt:get_pitch(), p)
lu.assertEquals(evt:get_channel(), ch)
lu.assertEquals(evt:get_timestamp(), t)
lu.assertEquals(evt:get_velocity(), vel)
end
function TestNoteOff:testSettersInvalid()
local NoteOffEvent = LuaMidi.NoteOffEvent
local evt = NoteOffEvent.new({pitch = MIN.PITCH})
-- TEST LOWER THAN BOUNDARY
lu.assertErrorMsgContains("Invalid 'pitch' value", NoteOffEvent.set_pitch, evt, MIN.PITCH-1)
evt = NoteOffEvent.new({pitch = MIN.PITCH}) -- cleaning object for tests in other setters
ch = MIN.CHANNEL-1
t = MIN.TIMESTAMP-1
vel = MIN.VELOCITY-1
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOffEvent.set_channel, evt, ch)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks", NoteOffEvent.set_timestamp, evt, t)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOffEvent.set_velocity, evt, vel)
-- TEST HIGHER THAN BOUNDARY
lu.assertErrorMsgContains("Invalid 'pitch' value", NoteOffEvent.set_pitch, evt, MAX.PITCH+1)
evt = NoteOffEvent.new({pitch = MIN.PITCH}) -- cleaning object for tests in other setters
ch = MAX.CHANNEL+1
vel = MAX.VELOCITY+1
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOffEvent.set_channel, evt, ch)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOffEvent.set_velocity, evt, vel)
-- TEST EMPTY PARAMETER
evt = NoteOffEvent.new({pitch = MIN.PITCH}) -- cleaning object for tests in other setters
lu.assertErrorMsgContains("'pitch' must be a string or a number", NoteOffEvent.set_pitch, evt, nil)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOffEvent.set_channel, evt, nil)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks", NoteOffEvent.set_timestamp, evt, nil)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOffEvent.set_velocity, evt, nil)
-- TEST INVALID TYPES
evt = NoteOffEvent.new({pitch = MIN.PITCH}) -- cleaning object for tests in other setters
lu.assertErrorMsgContains("'pitch' must be a string or a number", NoteOffEvent.set_pitch, evt, TYPES.TAB)
lu.assertErrorMsgContains("'pitch' must be a string or a number", NoteOffEvent.set_pitch, evt, TYPES.BOOL)
lu.assertErrorMsgContains("'pitch' must be a string or a number", NoteOffEvent.set_pitch, evt, TYPES.FUNC)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks",
NoteOffEvent.set_timestamp, evt, TYPES.TAB)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks",
NoteOffEvent.set_timestamp, evt, TYPES.STR)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks",
NoteOffEvent.set_timestamp, evt, TYPES.BOOL)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks",
NoteOffEvent.set_timestamp, evt, TYPES.FUNC)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100",
NoteOffEvent.set_velocity, evt, TYPES.TAB)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100",
NoteOffEvent.set_velocity, evt, TYPES.STR)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100",
NoteOffEvent.set_velocity, evt, TYPES.BOOL)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100",
NoteOffEvent.set_velocity, evt, TYPES.FUNC)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16",
NoteOffEvent.set_channel, evt, TYPES.TAB)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16",
NoteOffEvent.set_channel, evt, TYPES.STR)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16",
NoteOffEvent.set_channel, evt, TYPES.BOOL)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16",
NoteOffEvent.set_channel, evt, TYPES.FUNC)
end
TestNoteOn = {}
function TestNoteOn:testConstructorValid()
local NoteOnEvent = LuaMidi.NoteOnEvent
local p = math.random(MIN.PITCH, MAX.PITCH)
local ch = math.random(MIN.CHANNEL, MAX.CHANNEL)
local t = math.random(MIN.TIMESTAMP, 0xFF)
local vel = math.random(MIN.VELOCITY, MAX.VELOCITY)
local evt = NoteOnEvent.new({
pitch = p,
channel = ch,
timestamp = t,
velocity = vel,
})
lu.assertEquals(evt:get_pitch(), p)
lu.assertEquals(evt:get_channel(), ch)
lu.assertEquals(evt:get_timestamp(), t)
lu.assertEquals(evt:get_velocity(), vel)
end
function TestNoteOn:testConstructorInvalid()
local NoteOnEvent = LuaMidi.NoteOnEvent
-- TEST LOWER THAN BOUNDARY
lu.assertErrorMsgContains("Invalid 'pitch' value", NoteOnEvent.new, {pitch = MIN.PITCH-1})
ch = MIN.CHANNEL-1
t = MIN.TIMESTAMP-1
vel = MIN.VELOCITY-1
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOnEvent.new, {pitch = MIN.PITCH, channel=ch})
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks", NoteOnEvent.new, {pitch = MIN.PITCH, timestamp=t})
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOnEvent.new, {pitch = MIN.PITCH, velocity=vel})
-- TEST HIGHER THAN BOUNDARY
lu.assertErrorMsgContains("Invalid 'pitch' value", NoteOnEvent.new, {pitch = MAX.PITCH+1})
ch = MAX.CHANNEL+1
vel = MAX.VELOCITY+1
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOnEvent.new, {pitch = MIN.PITCH, channel=ch})
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOnEvent.new, {pitch = MIN.PITCH, velocity=vel})
-- TEST INVALID TYPES
lu.assertErrorMsgContains("'pitch' must be a string or a number", NoteOnEvent.new, {pitch = TYPES.TAB})
lu.assertErrorMsgContains("'pitch' must be a string or a number", NoteOnEvent.new, {pitch = TYPES.BOOL})
lu.assertErrorMsgContains("'pitch' must be a string or a number", NoteOnEvent.new, {pitch = TYPES.FUNC})
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks",
NoteOnEvent.new, {pitch = MIN.PITCH, timestamp = TYPES.TAB}
)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks",
NoteOnEvent.new, {pitch = MIN.PITCH, timestamp = TYPES.STR}
)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks",
NoteOnEvent.new, {pitch = MIN.PITCH, timestamp = TYPES.BOOL}
)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks",
NoteOnEvent.new, {pitch = MIN.PITCH, timestamp = TYPES.FUNC}
)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOnEvent.new, {
pitch = MIN.PITCH, velocity = TYPES.TAB
})
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOnEvent.new, {
pitch = MIN.PITCH, velocity = TYPES.STR
})
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOnEvent.new, {
pitch = MIN.PITCH, velocity = TYPES.BOOL
})
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOnEvent.new, {
pitch = MIN.PITCH, velocity = TYPES.FUNC
})
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOnEvent.new, {
pitch = MIN.PITCH, channel = TYPES.TAB
})
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOnEvent.new, {
pitch = MIN.PITCH, channel = TYPES.STR
})
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOnEvent.new, {
pitch = MIN.PITCH, channel = TYPES.BOOL
})
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOnEvent.new, {
pitch = MIN.PITCH, channel = TYPES.FUNC
})
end
function TestNoteOn:testSettersValid()
local NoteOnEvent = LuaMidi.NoteOnEvent
local p = math.random(MIN.PITCH, MAX.PITCH)
local ch = math.random(MIN.CHANNEL, MAX.CHANNEL)
local t = math.random(MIN.TIMESTAMP, 0xFF)
local vel = math.random(MIN.VELOCITY, MAX.VELOCITY)
local evt = NoteOnEvent.new({pitch = MIN.PITCH})
evt:set_pitch(p):set_channel(ch):set_timestamp(t):set_velocity(vel)
lu.assertEquals(evt:get_pitch(), p)
lu.assertEquals(evt:get_channel(), ch)
lu.assertEquals(evt:get_timestamp(), t)
lu.assertEquals(evt:get_velocity(), vel)
end
function TestNoteOn:testSettersInvalid()
local NoteOnEvent = LuaMidi.NoteOnEvent
local evt = NoteOnEvent.new({pitch = MIN.PITCH})
-- TEST LOWER THAN BOUNDARY
lu.assertErrorMsgContains("Invalid 'pitch' value", NoteOnEvent.set_pitch, evt, MIN.PITCH-1)
evt = NoteOnEvent.new({pitch = MIN.PITCH}) -- cleaning object for tests in other setters
ch = MIN.CHANNEL-1
t = MIN.TIMESTAMP-1
vel = MIN.VELOCITY-1
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOnEvent.set_channel, evt, ch)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks", NoteOnEvent.set_timestamp, evt, t)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOnEvent.set_velocity, evt, vel)
-- TEST HIGHER THAN BOUNDARY
lu.assertErrorMsgContains("Invalid 'pitch' value", NoteOnEvent.set_pitch, evt, MAX.PITCH+1)
evt = NoteOnEvent.new({pitch = MIN.PITCH}) -- cleaning object for tests in other setters
ch = MAX.CHANNEL+1
vel = MAX.VELOCITY+1
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOnEvent.set_channel, evt, ch)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOnEvent.set_velocity, evt, vel)
-- TEST EMPTY PARAMETER
evt = NoteOnEvent.new({pitch = MIN.PITCH}) -- cleaning object for tests in other setters
lu.assertErrorMsgContains("'pitch' must be a string or a number", NoteOnEvent.set_pitch, evt, nil)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16", NoteOnEvent.set_channel, evt, nil)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks", NoteOnEvent.set_timestamp, evt, nil)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100", NoteOnEvent.set_velocity, evt, nil)
-- TEST INVALID TYPES
evt = NoteOnEvent.new({pitch = MIN.PITCH}) -- cleaning object for tests in other setters
lu.assertErrorMsgContains("'pitch' must be a string or a number", NoteOnEvent.set_pitch, evt, TYPES.TAB)
lu.assertErrorMsgContains("'pitch' must be a string or a number", NoteOnEvent.set_pitch, evt, TYPES.BOOL)
lu.assertErrorMsgContains("'pitch' must be a string or a number", NoteOnEvent.set_pitch, evt, TYPES.FUNC)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks",
NoteOnEvent.set_timestamp, evt, TYPES.TAB)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks",
NoteOnEvent.set_timestamp, evt, TYPES.STR)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks",
NoteOnEvent.set_timestamp, evt, TYPES.BOOL)
lu.assertErrorMsgContains("'timestamp' must be a positive integer representing the explicit number of ticks",
NoteOnEvent.set_timestamp, evt, TYPES.FUNC)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100",
NoteOnEvent.set_velocity, evt, TYPES.TAB)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100",
NoteOnEvent.set_velocity, evt, TYPES.STR)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100",
NoteOnEvent.set_velocity, evt, TYPES.BOOL)
lu.assertErrorMsgContains("'velocity' must be an integer from 0 to 100",
NoteOnEvent.set_velocity, evt, TYPES.FUNC)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16",
NoteOnEvent.set_channel, evt, TYPES.TAB)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16",
NoteOnEvent.set_channel, evt, TYPES.STR)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16",
NoteOnEvent.set_channel, evt, TYPES.BOOL)
lu.assertErrorMsgContains("'channel' must be an integer from 1 to 16",
NoteOnEvent.set_channel, evt, TYPES.FUNC)
end
TestArbitraryEvent = {}
function TestArbitraryEvent:testConstructorValid()
local ArbitraryEvent = LuaMidi.ArbitraryEvent
local data, evt = {}
for i=1, math.random(1, 10) do
data[#data+1] = math.random(MIN.BYTE, MAX.BYTE)
end
evt = ArbitraryEvent.new({data = data})
lu.assertEquals(evt:get_data(), data)
end
function TestArbitraryEvent:testConstructorInvalid()
local ArbitraryEvent = LuaMidi.ArbitraryEvent
lu.assertErrorMsgContains("attempt to index a nil value (local 'fields')", ArbitraryEvent.new, nil)
lu.assertErrorMsgContains("attempt to index a number value (local 'fields')", ArbitraryEvent.new, TYPES.NUM)
lu.assertErrorMsgContains("'data' field must be an array", ArbitraryEvent.new, TYPES.TAB)
lu.assertErrorMsgContains("'data' field must be an array", ArbitraryEvent.new, TYPES.STR)
lu.assertErrorMsgContains("attempt to index a boolean value (local 'fields')", ArbitraryEvent.new, TYPES.BOOL)
lu.assertErrorMsgContains("attempt to index a function value (local 'fields')", ArbitraryEvent.new, TYPES.FUNC)
lu.assertErrorMsgContains("'data' field must be an array", ArbitraryEvent.new, {data=TYPES.NUM})
lu.assertErrorMsgContains("'data' field must be an array", ArbitraryEvent.new, {data=TYPES.STR})
lu.assertErrorMsgContains("'data' field must be an array", ArbitraryEvent.new, {data=TYPES.BOOL})
lu.assertErrorMsgContains("'data' field must be an array", ArbitraryEvent.new, {data=TYPES.FUNC})
lu.assertErrorMsgContains("'data' must be an array of bytes", ArbitraryEvent.new, {data={TYPES.TAB}})
lu.assertErrorMsgContains("'data' must be an array of bytes", ArbitraryEvent.new, {data={TYPES.STR}})
lu.assertErrorMsgContains("'data' must be an array of bytes", ArbitraryEvent.new, {data={TYPES.BOOL}})
lu.assertErrorMsgContains("'data' must be an array of bytes", ArbitraryEvent.new, {data={TYPES.FUNC}})
lu.assertErrorMsgContains("'data' field can't be empty", ArbitraryEvent.new, {data={}})
lu.assertErrorMsgContains("Invalid byte", ArbitraryEvent.new, {data={MIN.BYTE-1}})
lu.assertErrorMsgContains("Invalid byte", ArbitraryEvent.new, {data={MAX.BYTE+1}})
end
TestProgramChangeEvent = {}
function TestProgramChangeEvent:testConstructorValid()
local ProgramChangeEvent = LuaMidi.ProgramChangeEvent
local pcnumber = math.random(MIN.BYTE, MAX.PCNUM)
lu.assertEquals(ProgramChangeEvent.new(pcnumber):get_value(), pcnumber)
lu.assertEquals(ProgramChangeEvent.new(MIN.BYTE):get_value(), MIN.BYTE)
lu.assertEquals(ProgramChangeEvent.new(MAX.PCNUM):get_value(), MAX.PCNUM)
end
function TestProgramChangeEvent:testConstructorInvalid()
local ProgramChangeEvent = LuaMidi.ProgramChangeEvent
lu.assertErrorMsgContains("'pcnumber' must be an integer from 0 to 127", ProgramChangeEvent.new, nil)
lu.assertErrorMsgContains("'pcnumber' must be an integer from 0 to 127", ProgramChangeEvent.new, TYPES.TAB)
lu.assertErrorMsgContains("'pcnumber' must be an integer from 0 to 127", ProgramChangeEvent.new, TYPES.STR)
lu.assertErrorMsgContains("'pcnumber' must be an integer from 0 to 127", ProgramChangeEvent.new, TYPES.BOOL)
lu.assertErrorMsgContains("'pcnumber' must be an integer from 0 to 127", ProgramChangeEvent.new, TYPES.FUNC)
lu.assertErrorMsgContains("'pcnumber' must be an integer from 0 to 127", ProgramChangeEvent.new, MIN.BYTE-1)
lu.assertErrorMsgContains("'pcnumber' must be an integer from 0 to 127", ProgramChangeEvent.new, MAX.PCNUM+1)
end
function TestProgramChangeEvent:testSettersValid()
local ProgramChangeEvent = LuaMidi.ProgramChangeEvent
local pcnumber = math.random(MIN.BYTE, MAX.PCNUM)
lu.assertEquals(ProgramChangeEvent.new(0x00):set_value(pcnumber):get_value(), pcnumber)
lu.assertEquals(ProgramChangeEvent.new(pcnumber):set_value(MIN.BYTE):get_value(), MIN.BYTE)
lu.assertEquals(ProgramChangeEvent.new(pcnumber):set_value(MAX.PCNUM):get_value(), MAX.PCNUM)
end
function TestProgramChangeEvent:testSettersInvalid()
local ProgramChangeEvent = LuaMidi.ProgramChangeEvent
local evt = ProgramChangeEvent.new(math.random(MIN.BYTE, MAX.PCNUM))
lu.assertErrorMsgContains("'value' must be an integer from 0 to 127",
ProgramChangeEvent.set_value, evt, nil)
lu.assertErrorMsgContains("'value' must be an integer from 0 to 127",
ProgramChangeEvent.set_value, evt, TYPES.TAB)
lu.assertErrorMsgContains("'value' must be an integer from 0 to 127",
ProgramChangeEvent.set_value, evt, TYPES.STR)
lu.assertErrorMsgContains("'value' must be an integer from 0 to 127",
ProgramChangeEvent.set_value, evt, TYPES.BOOL)
lu.assertErrorMsgContains("'value' must be an integer from 0 to 127",
ProgramChangeEvent.set_value, evt, TYPES.FUNC)
lu.assertErrorMsgContains("'value' must be an integer from 0 to 127",
ProgramChangeEvent.set_value, evt, MIN.BYTE-1)
lu.assertErrorMsgContains("'value' must be an integer from 0 to 127",
ProgramChangeEvent.set_value, evt, MAX.PCNUM+1)
end
os.exit(lu.LuaUnit.run())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment