Tab Generation
ci / checks (push) Successful in 1h19m14s

This commit is contained in:
khodowany
2026-09-20 16:20:43 -05:00
parent 68ded4d8c8
commit cf7c0c010c
423 changed files with 1422 additions and 1332 deletions
+15 -13
View File
@@ -18,7 +18,7 @@ from generator.musicxml import load_musicxml
from generator.musicxml_writer import write_musicxml
from generator.practice.generate import practice_document
from generator.score import load_json
from generator.transposition import transpose_document
from generator.pitch import concert_document
from tests.test_musicxml import notes, parse, xml_note, xml_score
class ScoreBundleTests(unittest.TestCase):
@@ -27,7 +27,8 @@ class ScoreBundleTests(unittest.TestCase):
root = Path(temporary)
data, output = root / 'data', root / 'output'
(data / 'songs').mkdir(parents=True)
source = data / '001.xml'
(data / 'practice').mkdir()
source = data / 'practice/001.xml'
source.write_text(xml_score(xml_note()))
args = argparse.Namespace(data_dir=data, output_dir=output, static_assets_dir=Path('package/assets'), check=False)
generate_assets(args)
@@ -48,12 +49,12 @@ class ScoreBundleTests(unittest.TestCase):
generate_assets(args)
self.assertEqual(original, {p.relative_to(output): p.read_bytes() for p in output.rglob('*') if p.is_file()})
source.write_text(xml_score(xml_note()))
renamed = data / '127.xml'
renamed = data / 'practice/127.xml'
source.rename(renamed)
source = renamed
generate_assets(args)
self.assertFalse((output / 'practice/001').exists())
self.assertEqual(len(list((output / 'practice/127').glob('*.json'))), 12)
self.assertEqual(len(list((output / 'practice/127').glob('*.json'))), 3)
source.unlink()
generate_assets(args)
self.assertFalse(list(output.rglob('*.png')))
@@ -72,7 +73,7 @@ class ScoreBundleTests(unittest.TestCase):
measure = source['staves'][0]['measures'][0]
self.assertEqual([v['id'] for v in measure['voices']], ['1', '2'])
self.assertNotIn('tie_from', measure['voices'][1]['notes'][0]['pitches'][0])
for document in (source, practice_document(source), transpose_document(source, 'D'), arrange_document(source, 'vocal')):
for document in (source, concert_document(source), arrange_document(source, 'vocal')):
validate_document(document)
restored = self.round_trip(document)
validate_document(restored)
@@ -95,7 +96,8 @@ class ScoreBundleTests(unittest.TestCase):
self.assertEqual(restored['staves'][0]['measures'][1]['barlines'], {'right': 'light-heavy'})
def test_microtones_remain_exact_after_transposition_and_export(self):
source = parse(xml_score(xml_note(alter='0.5', extra='<accidental>quarter-sharp</accidental>')))
transposed = transpose_document(source, 'D')
source['staves'][0]['measures'][0]['transpose'] = {'diatonic': 1, 'chromatic': 2, 'octave_change': 0}
transposed = concert_document(source)
self.assertEqual(pitch_number(notes(transposed)[0]['pitches'][0]), Fraction(125, 2))
restored = self.round_trip(transposed)
self.assertEqual(notes(restored)[0]['pitches'], notes(transposed)[0]['pitches'])
@@ -131,13 +133,13 @@ class ScoreBundleTests(unittest.TestCase):
source = parse(xml_score(percussion, attributes='<clef><sign>percussion</sign></clef>'))
restored = self.round_trip(source)
self.assertEqual(notes(restored)[0]['pitches'], notes(source)[0]['pitches'])
tab = parse(xml_score(xml_note(extra='<notations><technical><string>2</string><fret>1</fret></technical></notations>'), attributes='<clef><sign>TAB</sign><line>5</line></clef><staff-details><staff-lines>6</staff-lines></staff-details>'))
self.assertEqual(notes(self.round_trip(tab))[0]['pitches'], notes(tab)[0]['pitches'])
for document in (source, tab):
validate_document(practice_document(document))
for part in ('vocal', 'acoustic', 'electric'):
with self.assertRaisesRegex(ValueError, 'conversion is not qualified'):
arrange_document(document, part)
with self.assertRaisesRegex(ValueError, 'authored TAB'):
parse(xml_score(xml_note(), attributes='<clef><sign>TAB</sign></clef>'))
for part in ('vocal', 'acoustic', 'electric'):
with self.assertRaisesRegex(ValueError, 'pitched'):
practice_document(source, part)
with self.assertRaisesRegex(ValueError, 'pitched'):
arrange_document(source, part)
def test_percussion_instrument_definitions_round_trip_and_are_audited(self):
tree = ElementTree.fromstring(xml_score('<note><unpitched><display-step>C</display-step><display-octave>5</display-octave></unpitched><duration>4</duration><instrument id="drum"/><type>whole</type></note>', attributes='<clef><sign>percussion</sign></clef>'))
definition = tree.find('part-list/score-part')