Skip to content

Commit 83d3a2a

Browse files
author
Kevin J Walters
committed
Adding unit tests specific to note_parser.
Fixing bug with note_parser - A/B were in wrong octave!! #3
1 parent 27ada48 commit 83d3a2a

2 files changed

Lines changed: 96 additions & 3 deletions

File tree

adafruit_midi/midi_message.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@
4646
# represent all of the sixteen channels
4747
ALL_CHANNELS = -1
4848

49-
# From C3
50-
# Semitones A B C D E F G
51-
NOTE_OFFSET = [9, 11, 12, 14, 16, 17, 19]
49+
# From C3 - A and B are above G
50+
# Semitones A B C D E F G
51+
NOTE_OFFSET = [21, 23, 12, 14, 16, 17, 19]
5252

5353
# pylint: disable=no-else-return
5454
def channel_filter(channel, channel_spec):

tests/test_note_parser.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
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+
verbose = int(os.getenv('TESTVERBOSE', '2'))
29+
30+
# adafruit_midi has an import usb_midi
31+
import sys
32+
sys.modules['usb_midi'] = MagicMock()
33+
34+
# Borrowing the dhalbert/tannewt technique from adafruit/Adafruit_CircuitPython_Motor
35+
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
36+
37+
from adafruit_midi.midi_message import note_parser
38+
39+
40+
class Test_note_parser(unittest.TestCase):
41+
def text_int_passthru(self):
42+
self.assertEqual(note_parser(0), 0)
43+
self.assertEqual(note_parser(70), 70)
44+
self.assertEqual(note_parser(127), 127)
45+
46+
# it does not range check so these should pass
47+
self.assertEqual(note_parser(-303), -303)
48+
self.assertEqual(note_parser(808), 808)
49+
50+
def test_good_text(self):
51+
note_prefix = { "Cb": 11,
52+
"C" : 12,
53+
"C#": 13,
54+
"Db": 13,
55+
"D" : 14,
56+
"D#": 15,
57+
"Eb": 15,
58+
"E" : 16,
59+
"Fb": 16,
60+
"E#": 17,
61+
"F" : 17,
62+
"F#": 18,
63+
"Gb": 18,
64+
"G" : 19,
65+
"G#": 20,
66+
"Ab": 20,
67+
"A" : 21,
68+
"A#": 22,
69+
"Bb": 22,
70+
"B" : 23,
71+
"B#": 24,
72+
}
73+
74+
# test from Cb0 to B#8
75+
for prefix, base_value in note_prefix.items():
76+
for octave in range(9):
77+
note = prefix + str(octave)
78+
expected_value = base_value + octave * 12 # 12 semitones in octave
79+
self.assertEqual(note_parser(note), expected_value)
80+
81+
# re-test with simple C4/A4 tests to catch any bugs in above
82+
self.assertEqual(note_parser("C4"), 60)
83+
self.assertEqual(note_parser("A4"), 69)
84+
85+
def test_bad_text(self):
86+
87+
for text_note in ["H", "H4", "asdfasdfasdf", "000", "999"]:
88+
with self.assertRaises(ValueError):
89+
note_parser(text_note)
90+
91+
92+
if __name__ == '__main__':
93+
unittest.main(verbosity=verbose)

0 commit comments

Comments
 (0)