test_note_parser.py
1 # The MIT License (MIT) 2 # 3 # Copyright (c) 2019 Kevin J. Walters 4 # 5 # Permission is hereby granted, free of charge, to any person obtaining a copy 6 # of this software and associated documentation files (the "Software"), to deal 7 # in the Software without restriction, including without limitation the rights 8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 # copies of the Software, and to permit persons to whom the Software is 10 # furnished to do so, subject to the following conditions: 11 # 12 # The above copyright notice and this permission notice shall be included in 13 # all copies or substantial portions of the Software. 14 # 15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 # THE SOFTWARE. 22 23 import unittest 24 from unittest.mock import Mock, MagicMock, call 25 26 import random 27 import os 28 29 verbose = int(os.getenv("TESTVERBOSE", "2")) 30 31 # adafruit_midi had an import usb_midi 32 import sys 33 34 # sys.modules['usb_midi'] = MagicMock() 35 36 # Borrowing the dhalbert/tannewt technique from adafruit/Adafruit_CircuitPython_Motor 37 sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) 38 39 from adafruit_midi.midi_message import note_parser 40 41 42 class Test_note_parser(unittest.TestCase): 43 def text_int_passthru(self): 44 self.assertEqual(note_parser(0), 0) 45 self.assertEqual(note_parser(70), 70) 46 self.assertEqual(note_parser(127), 127) 47 48 # it does not range check so these should pass 49 self.assertEqual(note_parser(-303), -303) 50 self.assertEqual(note_parser(808), 808) 51 52 def test_good_text(self): 53 note_prefix = { 54 "Cb": 11, 55 "C": 12, 56 "C#": 13, 57 "Db": 13, 58 "D": 14, 59 "D#": 15, 60 "Eb": 15, 61 "E": 16, 62 "Fb": 16, 63 "E#": 17, 64 "F": 17, 65 "F#": 18, 66 "Gb": 18, 67 "G": 19, 68 "G#": 20, 69 "Ab": 20, 70 "A": 21, 71 "A#": 22, 72 "Bb": 22, 73 "B": 23, 74 "B#": 24, 75 } 76 77 # test from Cb0 to B#8 78 for prefix, base_value in note_prefix.items(): 79 for octave in range(9): 80 note = prefix + str(octave) 81 expected_value = base_value + octave * 12 # 12 semitones in octave 82 self.assertEqual(note_parser(note), expected_value) 83 84 # re-test with simple C4/A4 tests to catch any bugs in above 85 self.assertEqual(note_parser("C4"), 60) 86 self.assertEqual(note_parser("A4"), 69) 87 88 def test_bad_text(self): 89 90 for text_note in ["H", "H4", "asdfasdfasdf", "000", "999"]: 91 with self.assertRaises(ValueError): 92 note_parser(text_note) 93 94 95 if __name__ == "__main__": 96 unittest.main(verbosity=verbose)