diff --git a/midisnake/events.py b/midisnake/events.py index e238cdb..9649904 100644 --- a/midisnake/events.py +++ b/midisnake/events.py @@ -240,7 +240,7 @@ class PolyphonicAftertouch(Event): Attributes: event_name (str): Name of Event indicator_byte (int): Byte that indicates the MIDI Event type - pressure (int): Polyphonic Pressure, between 0 and 16383 + pressure (int): Polyphonic Pressure, between 0 and 127 channel_number (int): MIDI Channel number raw_data (int): Initial data from MIDI file """ diff --git a/tests/test_events.py b/tests/test_events.py index 14b19d8..a7e91b8 100644 --- a/tests/test_events.py +++ b/tests/test_events.py @@ -26,7 +26,6 @@ from midisnake.events import NoteOff, NoteOn, PolyphonicAftertouch, PitchBend from midisnake.errors import LengthError - logger = logging.getLogger(__name__) logger.info("test_events tests started") @@ -43,6 +42,7 @@ def test_validate(self): 0x800000) ) logger.info("NoteOn .valid test passed") + def test_constructor(self): logger.info("Starting NoteOn constructor tests") # Test constructor of generic version @@ -64,23 +64,28 @@ def test_constructor(self): msg="NoteOn did not raise LengthError when given value 0x123001929391923919" ) as exc: NoteOn(0x123001929391923919) - logger.exception(exc) + logger.exception(exc) + raise exc + with self.assertRaises(LengthError, msg="NoteOn did not raise LengthError when given value 0x1" ) as exc: NoteOn(0x1) - logger.exception(exc) + logger.exception(exc) + raise exc # Test validation exceptions with self.assertRaises(ValueError, msg="NoteOn given invalid data did not raise ValueError. Value was 0x290011" ) as exc: NoteOn(0x290011) - logger.exception(exc) + logger.exception(exc) + raise exc with self.assertRaises(ValueError, msg="NoteOn given invalid data but did not raise ValueError. Value was 0x999999" ) as exc: NoteOn(0x899999) - logger.exception(exc) + logger.exception(exc) + raise exc # --- Parsing Testing --- # logger.info("Starting NoteOn constructor parsing test") @@ -97,11 +102,11 @@ def test_constructor(self): } try: self.assertEqual(vars(obj), match_val, "When testing constructor of NoteOn with channel value: {}, " - "parsing failed".format(channel)) + "parsing failed".format(channel)) except Exception as exc: logger.exception(exc) - for note_number in range(0,128): + for note_number in range(0, 128): note_names = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] event_data = 0x900000 + (note_number << 8) logger.debug("Testing constructor with value {:x}".format(event_data)) @@ -115,11 +120,12 @@ def test_constructor(self): obj = NoteOn(event_data) try: self.assertEqual(vars(obj), match_val, "When testing constructor of NoteOn with note value: {}, " - "parsing failed".format(note_number)) + "parsing failed".format(note_number)) except Exception as exc: logger.exception(exc) + raise exc - for velocity in range(0,128): + for velocity in range(0, 128): event_data = 0x900000 + (velocity) logger.debug("Testing constructor with value {:x}".format(event_data)) match_val = { @@ -132,9 +138,13 @@ def test_constructor(self): obj = NoteOn(event_data) try: self.assertEqual(vars(obj), match_val, "When testing constructor of NoteOn with velocity value: {}, " - "parsing failed".format(velocity)) + "parsing failed".format(velocity)) except Exception as exc: logger.exception(exc) + raise exc + + def tearDown(self): + logger.info("Finished testing NoteOn constructor tests") class TestNoteOff(TestCase): @@ -148,6 +158,7 @@ def test_validate(self): 0x900000) ) logger.info("NoteOn .valid test passed") + def test_constructor(self): logger.info("Starting NoteOff constructor tests") # Test constructor of generic version @@ -169,12 +180,14 @@ def test_constructor(self): msg="NoteOff did not raise LengthError when given value 0x123001929391923919" ) as exc: NoteOff(0x123001929391923919) - logger.exception(exc) + logger.exception(exc) + raise exc with self.assertRaises(LengthError, msg="NoteOff did not raise LengthError when given value 0x1" ) as exc: NoteOff(0x1) - logger.exception(exc) + logger.exception(exc) + raise exc # Test validation exceptions with self.assertRaises(ValueError, msg="NoteOff given invalid data did not raise ValueError. Value was 0x290011" @@ -185,7 +198,8 @@ def test_constructor(self): msg="NoteOff given invalid data but did not raise ValueError. Value was 0x999999" ) as exc: NoteOff(0x999999) - logger.exception(exc) + logger.exception(exc) + raise exc # --- Parsing Testing --- # logger.info("Starting NoteOff constructor parsing test") @@ -202,11 +216,12 @@ def test_constructor(self): } try: self.assertEqual(vars(obj), match_val, "When testing constructor of NoteOff with channel value: {}, " - "parsing failed".format(channel)) + "parsing failed".format(channel)) except Exception as exc: logger.exception(exc) + raise exc - for note_number in range(0,128): + for note_number in range(0, 128): note_names = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] event_data = 0x800000 + (note_number << 8) logger.debug("Testing constructor with value {:x}".format(event_data)) @@ -220,11 +235,12 @@ def test_constructor(self): obj = NoteOff(event_data) try: self.assertEqual(vars(obj), match_val, "When testing constructor of NoteOff with note value: {}, " - "parsing failed".format(note_number)) + "parsing failed".format(note_number)) except Exception as exc: logger.exception(exc) + raise exc - for velocity in range(0,128): + for velocity in range(0, 128): event_data = 0x800000 + (velocity) logger.debug("Testing constructor with value {:x}".format(event_data)) match_val = { @@ -237,8 +253,133 @@ def test_constructor(self): obj = NoteOff(event_data) try: self.assertEqual(vars(obj), match_val, "When testing constructor of NoteOff with velocity value: {}, " - "parsing failed".format(velocity)) + "parsing failed".format(velocity)) + except Exception as exc: + logger.exception(exc) + raise exc + + def tearDown(self): + logger.info("Finished testing NoteOn constructor tests") + + +class TestPolyphonicAftertouch(TestCase): + def setUp(self): + logger.info("Starting Polyphonic Aftertouch tests") + + def test_validate(self): + logger.info("Starting Polyphonic Aftertouch .valid function tests") + test_val = PolyphonicAftertouch.valid(0xA00000) + self.assertTrue(test_val, + "Generic MIDI PolyphonicAftertouch message failed validation. Value was 0x{:X}".format( + 0xA00000)) + test_val = PolyphonicAftertouch.valid(0xB00000) + self.assertFalse(test_val, + "Generic MIDI Polyphonic Aftertouch message shouldn't " + "have validated, but did. Value was 0x{:x}".format( + 0xB00000) + ) + logger.info("Polyphonic Aftertouch .valid test passed") + + def test_constructor(self): + logger.info("Starting PolyphonicAftertouch constructor tests") + # Test constructor of generic version + test_val = PolyphonicAftertouch(0xA00000) + match_val = { + 'channel_number': 0, + 'note_name': 'C', + 'note_number': 0, + 'pressure': 0, + 'raw_data': 10485760 + } + self.assertEqual(vars(test_val), + match_val, + "MIDI PolyphonicAftertouch constructed from value 0x{:X} is incorrect".format(0xA00000) + ) + # --- Exception Testing --- # + logger.info("Starting PolyphonicAftertouch constructor exception tests") + # Test Length Exceptions + with self.assertRaises(LengthError, + msg="PolyphonicAftertouch did not raise LengthError when given value 0x123001929391923919" + ) as exc: + PolyphonicAftertouch(0x123001929391923919) + logger.exception(exc) + raise exc + with self.assertRaises(LengthError, + msg="PolyphonicAftertouch did not raise LengthError when given value 0x1" + ) as exc: + PolyphonicAftertouch(0x1) + logger.exception(exc) + raise exc + # Test validation exceptions + with self.assertRaises(ValueError, + msg="PolyphonicAftertouch given invalid data did not raise ValueError. Value was 0x290011" + ) as exc: + PolyphonicAftertouch(0x290011) + logger.exception(exc) + raise exc + with self.assertRaises(ValueError, + msg="PolyphonicAftertouch given invalid data but did not raise ValueError. Value was 0x999999" + ) as exc: + PolyphonicAftertouch(0x999999) + logger.exception(exc) + raise exc + + # --- Parsing Testing --- # + logger.info("Starting PolyphonicAftertouch constructor parsing test") + for channel in range(0, 9): + channel_num = 0xA00000 + (channel << 16) + logger.debug("Testing constructor with value {:x}".format(channel_num)) + obj = PolyphonicAftertouch(channel_num) + match_val = { + 'channel_number': channel, + 'note_name': 'C', + 'note_number': 0, + 'pressure': 0, + 'raw_data': channel_num + } + try: + self.assertEqual(vars(obj), match_val, + "When testing constructor of PolyphonicAftertouch with channel value: {}, " + "parsing failed".format(channel)) except Exception as exc: logger.exception(exc) + raise exc + for note_number in range(0, 128): + note_names = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] + event_data = 0xA00000 + (note_number << 8) + logger.debug("Testing constructor with value {:x}".format(event_data)) + match_val = { + 'channel_number': 0, + 'note_name': note_names[note_number % 12], + 'note_number': note_number, + 'pressure': 0, + 'raw_data': event_data + } + obj = PolyphonicAftertouch(event_data) + try: + self.assertEqual(vars(obj), match_val, + "When testing constructor of PolyphonicAftertouch with note value: {}, " + "parsing failed".format(note_number)) + except Exception as exc: + logger.exception(exc) + raise exc + for pressure in range(0, 128): + event_data = 0xA00000 + (pressure) + logger.debug("Testing constructor with value {:x}".format(event_data)) + match_val = { + 'channel_number': 0, + 'note_name': 'C', + 'note_number': 0, + 'pressure': pressure, + 'raw_data': event_data + } + obj = PolyphonicAftertouch(event_data) + try: + self.assertEqual(vars(obj), match_val, + "When testing constructor of PolyphonicAftertouch with pressure value: {}, " + "parsing failed".format(pressure)) + except Exception as exc: + logger.exception(exc) + raise exc diff --git a/tox.ini b/tox.ini index ef52d11..a39ed2e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py33, py34, py35, py36, py37 +envlist = py33, py34, py35, py36 [testenv]