Training Model

This commit is contained in:
khodowany
2026-10-05 19:44:33 -05:00
parent db7966a430
commit e7180e557b
6603 changed files with 8919 additions and 523063 deletions
+3 -78
View File
@@ -32,86 +32,11 @@ import tests.arrangement_fixtures
import generator.score
import generator.theme
import tests.musicxml_roundtrip
import tests.rhythm_fixtures
import tests.test_musicxml
class ScoreBundleTests(unittest.TestCase):
def setUp(self):
tests.production_fixtures.install(self)
def test_real_asset_regeneration_removes_pages_and_rolls_back_font_failure(self):
from generator import resources
# Validation now belongs to the catalog-consuming worker, not a redundant
# parent parse. Exercise its real content keys/importer in this rollback test.
self.enterContext(unittest.mock.patch('generator.production._solo_libraries',side_effect=lambda directory,keys,cache=None:resources.load(directory,cache_dir=cache)))
self.enterContext(unittest.mock.patch('generator.rhythm.load_library', return_value=tests.rhythm_fixtures.library()))
with tempfile.TemporaryDirectory() as temporary:
root = pathlib.Path(temporary)
data, output = root / 'data', root / 'output'
(data / 'songs').mkdir(parents=True)
shutil.copytree(pathlib.Path('data/scales'), data / 'scales')
shutil.copytree(pathlib.Path('data/sequences/2_4'), data / 'sequences/2_4')
source = data / 'songs/fixture.xml'
source.write_text(tests.test_musicxml.xml_score(tests.test_musicxml.xml_note()))
args = argparse.Namespace(data_dir=data, output_dir=output, static_assets_dir=pathlib.Path('package/assets'), check=False)
generator.__main__.generate_assets(args)
original = {p.relative_to(output): p.read_bytes() for p in output.rglob('*') if p.is_file()}
self.assertTrue(list(output.rglob('*.png')))
(data / 'rhythms' / 'drafts').mkdir(parents=True)
for path in ('rhythms/0001.xml', 'rhythms/drafts/0002.xml'):
(data / path).write_text('<unfinished')
generator.__main__.generate_assets(args)
self.assertEqual(original, {p.relative_to(output): p.read_bytes() for p in output.rglob('*') if p.is_file()})
sequence = data / 'sequences/2_4/0001.xml'
saved = sequence.read_bytes()
sequence.write_text('<unfinished')
with self.assertRaisesRegex(ValueError, '0001.xml'):
generator.__main__.generate_assets(args)
self.assertEqual(original, {p.relative_to(output): p.read_bytes() for p in output.rglob('*') if p.is_file()})
sequence.write_bytes(saved)
scale = data / 'scales/major_scale_modes/0002.xml'
previous = scale.read_bytes()
scale.write_text('<unfinished')
with self.assertRaisesRegex(ValueError, '0002.xml'):
generator.__main__.generate_assets(args)
self.assertEqual(original, {p.relative_to(output): p.read_bytes() for p in output.rglob('*') if p.is_file()})
scale.write_bytes(previous)
misplaced = data / '0001.xml'
misplaced.write_text(tests.test_musicxml.xml_score(tests.test_musicxml.xml_note()))
with self.assertRaisesRegex(ValueError, 'belong directly under'):
generator.__main__.generate_assets(args)
misplaced.unlink()
with unittest.mock.patch('generator.playback.compile_tree', side_effect=ValueError('invalid generated audio')):
with self.assertRaisesRegex(ValueError, 'audio'):
generator.__main__.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(tests.test_musicxml.xml_score(tests.test_musicxml.xml_note() + '<barline><repeat direction="backward"/></barline>'))
with self.assertRaisesRegex(ValueError, 'write the music out'):
generator.__main__.generate_assets(args)
self.assertEqual(original, {p.relative_to(output): p.read_bytes() for p in output.rglob('*') if p.is_file()})
dense = ''.join(tests.test_musicxml.xml_note('G', 1, '64th') for _ in range(64))
source.write_text(tests.test_musicxml.xml_score(dense, divisions=16))
with self.assertRaisesRegex(generator.engraving.types.EngravingError, r'songs/fixture_electric.json: measure 3 .*complete measure exceeds'):
generator.__main__.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(tests.test_musicxml.xml_score(tests.test_musicxml.xml_note(extra='<accidental smufl="unavailableGlyph">other</accidental>')))
with self.assertRaisesRegex(generator.engraving.types.EngravingError, 'unavailableGlyph'):
generator.__main__.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(tests.test_musicxml.xml_score(tests.test_musicxml.xml_note()))
renamed = data / 'songs/renamed.xml'
source.rename(renamed)
source = renamed
legacy_output = output / 'obsolete'
legacy_output.mkdir()
(legacy_output / 'electric.json').write_text('{}')
generator.__main__.generate_assets(args)
self.assertFalse(legacy_output.exists())
self.assertFalse(list((output / 'songs').glob('fixture*')))
self.assertEqual(len(list((output / 'songs').glob('renamed_*.json'))), 3)
source.unlink()
generator.__main__.generate_assets(args)
self.assertFalse(list(output.rglob('*.png')))
self.assertFalse(list(output.rglob('*.json')))
def round_trip(self, document):
with tempfile.TemporaryDirectory() as temporary:
path = pathlib.Path(temporary) / 'roundtrip.xml'
@@ -132,7 +57,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, generator.pitch.concert_document(source), generator.arrange.generate.arrange_document(source, 'vocal', rhythms=tests.rhythm_fixtures.library())):
for document in (source, generator.pitch.concert_document(source), generator.arrange.generate.arrange_document(source, 'vocal')):
generator.model.validate_document(document)
restored = self.round_trip(document)
generator.model.validate_document(restored)
@@ -193,9 +118,9 @@ class ScoreBundleTests(unittest.TestCase):
tests.test_musicxml.parse(tests.test_musicxml.xml_score(tests.test_musicxml.xml_note(), attributes='<clef><sign>TAB</sign></clef>'))
for part in ('vocal', 'acoustic', 'electric'):
with self.assertRaisesRegex(ValueError, 'pitched'):
tests.arrangement_fixtures.section_document(source, part, rhythms=tests.rhythm_fixtures.library())
tests.arrangement_fixtures.section_document(source, part)
with self.assertRaisesRegex(ValueError, 'pitched'):
generator.arrange.generate.arrange_document(source, part, rhythms=tests.rhythm_fixtures.library())
generator.arrange.generate.arrange_document(source, part)
def test_percussion_instrument_definitions_round_trip_and_are_audited(self):
tree = xml.etree.ElementTree.fromstring(tests.test_musicxml.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')