@@ -30,6 +30,45 @@ class EngravingTests(unittest.TestCase):
|
||||
actual = rasterize_page(layout.pages[0], self.fonts)
|
||||
with Image.open('tests/fixtures/notation-python.png') as expected:
|
||||
self.assertIsNone(ImageChops.difference(actual, expected.convert('RGB')).getbbox())
|
||||
def test_accidental_work_is_bounded_by_local_event_count(self):
|
||||
class Unscannable(list):
|
||||
def __iter__(self):
|
||||
raise AssertionError('whole-score event scan')
|
||||
class Counted(list):
|
||||
visited = 0
|
||||
def __iter__(self):
|
||||
for value in super().__iter__():
|
||||
Counted.visited += 1
|
||||
yield value
|
||||
for count in (100, 200, 400):
|
||||
content = ''.join(xml_note(duration=1, kind='quarter', alter=i % 2) for i in range(4))
|
||||
extra = ''.join(f'<measure number="{i + 1}">{content}</measure>' for i in range(1, count))
|
||||
document = parse(xml_score(content).replace('</part></score-partwise>', extra + '</part></score-partwise>'))
|
||||
index = ScoreIndex(document)
|
||||
expected = index.accidentals
|
||||
index.events = Unscannable(index.events)
|
||||
index.events_by_onset = {time: Counted(events) for time, events in index.events_by_onset.items()}
|
||||
Counted.visited = 0
|
||||
self.assertEqual(index.accidental_state(), expected)
|
||||
self.assertEqual(Counted.visited, count * 4)
|
||||
def test_indexed_columns_preserve_sustains_and_timed_annotations(self):
|
||||
from generator.engraving.layout import column
|
||||
class Unscannable(list):
|
||||
def __iter__(self):
|
||||
raise AssertionError('whole-score scan from column layout')
|
||||
content = xml_note(extra='<voice>held</voice>') + '<backup><duration>4</duration></backup>'
|
||||
content += ''.join(xml_note('G', 1, 'quarter', extra='<voice>moving</voice>') for _ in range(4))
|
||||
content += '<harmony><root><root-step>F</root-step></root><kind>major</kind><offset>-2</offset></harmony>'
|
||||
content += '<direction><direction-type><metronome><beat-unit>quarter</beat-unit><per-minute>90</per-minute></metronome></direction-type><offset>-2</offset></direction>'
|
||||
index = ScoreIndex(parse(xml_score(content)))
|
||||
expected = column(index, Fraction(2), Fraction(2), Fraction(4), self.fonts, Style())
|
||||
index.events = Unscannable(index.events)
|
||||
index.measures = Unscannable(index.measures)
|
||||
actual = column(index, Fraction(2), Fraction(2), Fraction(4), self.fonts, Style())
|
||||
self.assertEqual(actual, expected)
|
||||
self.assertEqual(len(index.events_at(Fraction(2), include_sustained=True)), 2)
|
||||
self.assertTrue(any(p.role == 'harmony' for p in actual[0]))
|
||||
self.assertEqual(len(index.events_at(Fraction(4), include_sustained=True)), 0)
|
||||
def test_every_written_note_and_rest_value(self):
|
||||
for kind in NOTE_TYPES:
|
||||
for dots in (0, 1, 3):
|
||||
|
||||
Reference in New Issue
Block a user