@@ -11,7 +11,7 @@ from xml.etree import ElementTree
|
||||
|
||||
from generator.arrange.generate import arrange_document
|
||||
from generator.__main__ import generate_assets
|
||||
from generator.engraving import ENGINE_NAME, ENGINE_VERSION, EngravingError, Fonts, Style, check_page, engrave_tree, layout_score
|
||||
from generator.engraving import ENGINE_NAME, EngravingError, Fonts, Style, check_page, engrave_tree, layout_score
|
||||
from tests.musicxml_roundtrip import audit_roundtrip
|
||||
from generator.model import fraction, pitch_number, rational, validate_document
|
||||
from generator.musicxml import load_musicxml
|
||||
@@ -34,8 +34,16 @@ class ScoreBundleTests(unittest.TestCase):
|
||||
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/001.xml', 'rhythms/drafts/002.xml'):
|
||||
(data / path).write_text('<unfinished')
|
||||
generate_assets(args)
|
||||
self.assertEqual(original, {p.relative_to(output): p.read_bytes() for p in output.rglob('*') if p.is_file()})
|
||||
misplaced = data / '001.xml'
|
||||
misplaced.write_text(xml_score(xml_note()))
|
||||
with self.assertRaisesRegex(ValueError, 'belong directly under'):
|
||||
generate_assets(args)
|
||||
misplaced.unlink()
|
||||
with patch('generator.__main__.compile_tree', side_effect=ValueError('invalid generated audio')):
|
||||
with self.assertRaisesRegex(ValueError, 'audio'):
|
||||
generate_assets(args)
|
||||
@@ -64,6 +72,12 @@ class ScoreBundleTests(unittest.TestCase):
|
||||
path = Path(temporary) / 'roundtrip.xml'
|
||||
write_musicxml(path, document)
|
||||
return load_musicxml(path)
|
||||
def test_score_structure_is_validated_without_schema_labels(self):
|
||||
document = parse(xml_score(xml_note()))
|
||||
self.assertEqual(set(document), {'metadata', 'staves'})
|
||||
for malformed in (None, [], {}, {'metadata': {}, 'staves': []}, {**document, 'staves': None}, {**document, 'staves': [{}]}):
|
||||
with self.subTest(document=malformed), self.assertRaises(ValueError):
|
||||
validate_document(malformed)
|
||||
def test_multiple_voices_keep_independent_ties_and_transformations(self):
|
||||
def half(action):
|
||||
return xml_note(duration=2, kind='half', extra=f'<voice>1</voice><tie type="{action}"/>')
|
||||
@@ -159,7 +173,7 @@ class ScoreBundleTests(unittest.TestCase):
|
||||
with self.assertRaisesRegex(ValueError, 'unknown score instrument'):
|
||||
validate_document(source)
|
||||
def test_catalog_roundtrip_preserves_written_pitch_and_rhythm(self):
|
||||
for path in Path('data').rglob('*.xml'):
|
||||
for path in sorted(path for category in ('practice', 'songs') for path in (Path('data') / category).glob('*.xml')):
|
||||
with self.subTest(path=path):
|
||||
source = load_musicxml(path)
|
||||
restored = self.round_trip(source)
|
||||
@@ -231,7 +245,7 @@ class ScoreBundleTests(unittest.TestCase):
|
||||
page = assets / 'page.png'
|
||||
page.write_bytes(data)
|
||||
document = load_musicxml(Path('tests/fixtures/engraving.xml'))
|
||||
bundle = {'schema_version': 3, 'music': {k: v for k, v in document.items() if k != 'schema_version'}, 'presentation': {'engine': ENGINE_NAME, 'engine_version': ENGINE_VERSION, 'width': 976, 'height': 484, 'pages': [{'path': 'page.png', 'sha256': hashlib.sha256(data).hexdigest()}]}}
|
||||
bundle = {'music': document, 'presentation': {'engine': ENGINE_NAME, 'width': 976, 'height': 484, 'pages': [{'path': 'page.png', 'sha256': hashlib.sha256(data).hexdigest()}]}}
|
||||
path = assets / 'score.json'
|
||||
path.write_text(json.dumps(bundle))
|
||||
self.assertEqual(load_json(path), document)
|
||||
@@ -255,7 +269,7 @@ class ScoreBundleTests(unittest.TestCase):
|
||||
write_json(root / 'fixture.json', document)
|
||||
engrave_tree(root, Path('package/assets/fonts/petaluma'))
|
||||
bundle = json.loads((root / 'fixture.json').read_text())
|
||||
self.assertEqual(bundle['music'], {k: v for k, v in document.items() if k != 'schema_version'})
|
||||
self.assertEqual(bundle['music'], document)
|
||||
self.assertEqual(len(bundle['presentation']['pages']), 1)
|
||||
page = root / bundle['presentation']['pages'][0]['path']
|
||||
with Image.open(page) as actual, Image.open('tests/fixtures/engraving-python.png') as expected:
|
||||
|
||||
Reference in New Issue
Block a user