2017-06-09 02:53:25 -04:00
|
|
|
import unittest
|
|
|
|
|
|
|
|
|
|
from scale_generator import Scale
|
|
|
|
|
|
|
|
|
|
|
2018-12-21 15:18:14 -05:00
|
|
|
# Tests adapted from `problem-specifications//canonical-data.json` @ v2.0.0
|
2018-02-20 23:43:08 +08:00
|
|
|
|
2017-06-09 02:53:25 -04:00
|
|
|
class ScaleGeneratorTest(unittest.TestCase):
|
|
|
|
|
|
2018-02-20 23:43:08 +08:00
|
|
|
# Test chromatic scales
|
|
|
|
|
def test_chromatic_scale_with_sharps(self):
|
|
|
|
|
expected = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#',
|
|
|
|
|
'G', 'G#', 'A', 'A#', 'B']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('C').chromatic(), expected)
|
2018-02-20 23:43:08 +08:00
|
|
|
|
|
|
|
|
def test_chromatic_scale_with_flats(self):
|
|
|
|
|
expected = ['F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B',
|
|
|
|
|
'C', 'Db', 'D', 'Eb', 'E']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('F').chromatic(), expected)
|
2018-02-20 23:43:08 +08:00
|
|
|
|
|
|
|
|
# Test scales with specified intervals
|
|
|
|
|
def test_simple_major_scale(self):
|
2017-06-09 02:53:25 -04:00
|
|
|
expected = ['C', 'D', 'E', 'F', 'G', 'A', 'B']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('C').interval('MMmMMMm'), expected)
|
2017-06-09 02:53:25 -04:00
|
|
|
|
2018-02-20 23:43:08 +08:00
|
|
|
def test_major_scale_with_sharps(self):
|
2017-06-09 02:53:25 -04:00
|
|
|
expected = ['G', 'A', 'B', 'C', 'D', 'E', 'F#']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('G').interval('MMmMMMm'), expected)
|
2018-02-20 23:43:08 +08:00
|
|
|
|
|
|
|
|
def test_major_scale_with_flats(self):
|
|
|
|
|
expected = ['F', 'G', 'A', 'Bb', 'C', 'D', 'E']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('F').interval('MMmMMMm'), expected)
|
2017-06-09 02:53:25 -04:00
|
|
|
|
2018-02-20 23:43:08 +08:00
|
|
|
def test_minor_scale_with_sharps(self):
|
2017-06-09 02:53:25 -04:00
|
|
|
expected = ['F#', 'G#', 'A', 'B', 'C#', 'D', 'E']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('f#').interval('MmMMmMM'), expected)
|
2017-06-09 02:53:25 -04:00
|
|
|
|
2018-02-20 23:43:08 +08:00
|
|
|
def test_minor_scale_with_flats(self):
|
2017-06-09 02:53:25 -04:00
|
|
|
expected = ['Bb', 'C', 'Db', 'Eb', 'F', 'Gb', 'Ab']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('bb').interval('MmMMmMM'), expected)
|
2017-06-09 02:53:25 -04:00
|
|
|
|
|
|
|
|
def test_dorian_mode(self):
|
|
|
|
|
expected = ['D', 'E', 'F', 'G', 'A', 'B', 'C']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('d').interval('MmMMMmM'), expected)
|
2017-06-09 02:53:25 -04:00
|
|
|
|
|
|
|
|
def test_mixolydian_mode(self):
|
|
|
|
|
expected = ['Eb', 'F', 'G', 'Ab', 'Bb', 'C', 'Db']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('Eb').interval('MMmMMmM'), expected)
|
2017-06-09 02:53:25 -04:00
|
|
|
|
|
|
|
|
def test_lydian_mode(self):
|
|
|
|
|
expected = ['A', 'B', 'C#', 'D#', 'E', 'F#', 'G#']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('a').interval('MMMmMMm'), expected)
|
2017-06-09 02:53:25 -04:00
|
|
|
|
|
|
|
|
def test_phrygian_mode(self):
|
|
|
|
|
expected = ['E', 'F', 'G', 'A', 'B', 'C', 'D']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('e').interval('mMMMmMM'), expected)
|
2017-06-09 02:53:25 -04:00
|
|
|
|
|
|
|
|
def test_locrian_mode(self):
|
|
|
|
|
expected = ['G', 'Ab', 'Bb', 'C', 'Db', 'Eb', 'F']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('g').interval('mMMmMMM'), expected)
|
2017-06-09 02:53:25 -04:00
|
|
|
|
|
|
|
|
def test_harmonic_minor(self):
|
|
|
|
|
expected = ['D', 'E', 'F', 'G', 'A', 'Bb', 'Db']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('d').interval('MmMMmAm'), expected)
|
2017-06-09 02:53:25 -04:00
|
|
|
|
|
|
|
|
def test_octatonic(self):
|
|
|
|
|
expected = ['C', 'D', 'D#', 'F', 'F#', 'G#', 'A', 'B']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('C').interval('MmMmMmMm'), expected)
|
2017-06-09 02:53:25 -04:00
|
|
|
|
|
|
|
|
def test_hexatonic(self):
|
|
|
|
|
expected = ['Db', 'Eb', 'F', 'G', 'A', 'B']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('Db').interval('MMMMMM'), expected)
|
2017-06-09 02:53:25 -04:00
|
|
|
|
|
|
|
|
def test_pentatonic(self):
|
|
|
|
|
expected = ['A', 'B', 'C#', 'E', 'F#']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('A').interval('MMAMA'), expected)
|
2017-06-09 02:53:25 -04:00
|
|
|
|
|
|
|
|
def test_enigmatic(self):
|
|
|
|
|
expected = ['G', 'G#', 'B', 'C#', 'D#', 'F', 'F#']
|
2018-12-21 15:18:14 -05:00
|
|
|
self.assertEqual(Scale('G').interval('mAMMMmm'), expected)
|
2017-08-20 12:51:32 -06:00
|
|
|
|
2017-12-12 18:11:43 +00:00
|
|
|
# Utility functions
|
|
|
|
|
def setUp(self):
|
|
|
|
|
try:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex
|
2017-12-12 18:11:43 +00:00
|
|
|
except AttributeError:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex = self.assertRaisesRegexp
|
2017-12-12 18:11:43 +00:00
|
|
|
|
|
|
|
|
def assertRaisesWithMessage(self, exception):
|
|
|
|
|
return self.assertRaisesRegex(exception, r".+")
|
|
|
|
|
|
2017-06-09 02:53:25 -04:00
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
unittest.main()
|