@@ -19,9 +19,19 @@ def fixture(root):
|
||||
music['staves'][0]['measures'].append(copy.deepcopy(first))
|
||||
music['staves'][0]['measures'].extend({**copy.deepcopy(first), 'ending_sustain': True} for _ in range(3))
|
||||
music['metadata']['song_id'] = 'fixture'
|
||||
pages = [dict(path=f'{i + 1}.png', sha256='0' * 64, first_measure=i + 1, measure_count=1 if i == 0 else 4,
|
||||
start_beat=generator.model.rational(i * 4), end_beat=generator.model.rational(4 if i == 0 else 20)) for i in range(2)]
|
||||
bundle = dict(music=music, presentation=dict(width=976, height=484, pages=pages), performance=generator.performance.timing(music))
|
||||
|
||||
def system(first, count, y):
|
||||
return dict(first_measure=first, measure_count=count, start_beat=generator.model.rational((first - 1) * 4),
|
||||
end_beat=generator.model.rational((first + count - 1) * 4),
|
||||
labels=[dict(measure=m, bounds=[30 + 40 * (m - first), y, 42 + 40 * (m - first), y + 12]) for m in range(first, first + count)])
|
||||
|
||||
def page(index, systems):
|
||||
return dict(path=f'{index}.png', sha256='0' * 64, first_measure=systems[0]['first_measure'],
|
||||
measure_count=sum(s['measure_count'] for s in systems), start_beat=systems[0]['start_beat'], end_beat=systems[-1]['end_beat'], systems=systems)
|
||||
|
||||
pages = [page(1, [system(1, 1, 70), system(2, 1, 290)]), page(2, [system(3, 3, 70)])]
|
||||
playback = [pages[0], page(3, [system(2, 1, 70), system(3, 3, 290)]), pages[1]]
|
||||
bundle = dict(music=music, presentation=dict(width=976, height=484, pages=pages, playback_pages=playback), performance=generator.performance.timing(music))
|
||||
(root / 'score.json').write_text(json.dumps(bundle))
|
||||
entries = []
|
||||
# Constant PCM makes accents, recorded count-in and the silent click tail observable.
|
||||
@@ -79,6 +89,28 @@ class PerformanceTests(unittest.TestCase):
|
||||
bundle['presentation']['pages'][1]['start_beat'] = generator.model.rational(3)
|
||||
with self.assertRaisesRegex(ValueError, 'timing'):
|
||||
generator.performance.validate_pages(bundle['music'], bundle['presentation']['pages'])
|
||||
def test_playback_metadata_rejects_missing_views_wrong_pairs_and_bad_labels(self):
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
root = pathlib.Path(temporary)
|
||||
fixture(root)
|
||||
bundle = json.loads((root / 'score.json').read_text())
|
||||
pages = bundle['presentation']['pages']
|
||||
playback = bundle['presentation']['playback_pages']
|
||||
generator.performance.validate_views(bundle['music'], pages, playback)
|
||||
for fault in ('missing', 'pair', 'bounds', 'label', 'timing'):
|
||||
altered = copy.deepcopy(playback)
|
||||
if fault == 'missing':
|
||||
altered.pop()
|
||||
elif fault == 'pair':
|
||||
altered[1] = copy.deepcopy(altered[0])
|
||||
elif fault == 'bounds':
|
||||
altered[0]['systems'][0]['labels'][0]['bounds'][0] = -1
|
||||
elif fault == 'label':
|
||||
altered[0]['systems'][0]['labels'][0]['measure'] = 2
|
||||
else:
|
||||
altered[1]['start_beat'] = generator.model.rational(3)
|
||||
with self.subTest(fault=fault), self.assertRaises(ValueError):
|
||||
generator.performance.validate_views(bundle['music'], pages, altered)
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
Reference in New Issue
Block a user