"""General, independently authored capabilities; no optional reference inputs.""" import copy,dataclasses,unittest from fractions import Fraction as F from unittest.mock import patch from generator import vocabulary,model from generator.scales import selection,timeline from generator.solo import analysis,construction,harmonic,profiles,types,scoring,composer,routes,placement from tests import solo_fixtures as fixtures,rhythm_fixtures,scale_fixtures def builder(symbols=('C7','FM7','Dm7','G7'),seed='independent',count=8): source=fixtures.song(count=count,chords=symbols);a=analysis.analyze(source);ms=source['staves'][0]['measures'] end=sum(model.fraction(m['duration']) for m in ms) cs=selection.select(timeline.read(source['staves'][0]),timeline.Solo(F(),end,'test'),scale_fixtures.library()) return construction.Builder(a,ms,harmonic.Harmony(cs,profiles.Instrument(reference=60)),fixtures.library(),rhythm_fixtures.library(),end,seed) class PhraseConstruction(unittest.TestCase): def test_complete_candidates_have_varied_functions_and_joint_expression(self): b=builder();values=[b.propose(F(),(),i) for i in range(64)];values=[p for p in values if p] self.assertTrue(values) self.assertIn('open',{p.ending for p in values}) self.assertTrue(any(p.destination and p.destination.duration>=2 for p in values)) self.assertTrue(any(p.expressions for p in values)) for p in values: self.assertTrue(b.harmony.evaluate(p.notes,until=p.end,complete=True,expressions=p.expressions).valid) self.assertEqual(p.score,p.evaluation.total) self.assertTrue(all(p.start<=n.start