"""Cheap valid notes for renderer/packaging tests; never a production fallback. Learned decoding and authored-repertoire tests separately use the real path. """ from fractions import Fraction as F from pathlib import Path from unittest.mock import patch from generator import production,vocabulary,harmonic_time from generator.solo import types,placement,profiles,decoder,learned,harmonic def compose(analysis,measures,part,end,*,initial=None,start=F(),**kwargs): import dataclasses spans=tuple(dataclasses.replace(s,start=s.start+start,end=s.end+start) for s in harmonic_time.read({'measures':measures},initial=initial)) h=harmonic.Harmony(spans);notes=[] for s in h.spans: a,b=max(start,s.start),min(end,s.end) if a>=b or s.chord=='N.C.':continue number=next(n for n in range(55,72) if n%12 in s.roles.basic) from generator.solo import expressions chord=expressions.parsed_chord(s.chord) from generator import harmony pitch=next(expressions.degree_pitch(chord,d,x,number) for d,x in harmony.degrees(chord).items() if expressions.degree_pitch(chord,d,x,number).number()==number) notes.append(types.Note(a,b,pitch,event_id=str(a))) placed=placement.place(tuple(notes),analysis.tempo)[1] if notes else () return types.Solo(part,spans,(types.Phrase('fixture',start,end,placed,'test','test','handoff'),),analysis.tempo,end,profile=profiles.for_part(part),start=start) def install(test): resources=vocabulary.load();predictor=learned.Model.load(Path(__file__).resolve().parents[1]/'data/models/solo.json') tree=production.generate_tree def serial(*args,**kwargs): kwargs['jobs']=1 return tree(*args,**kwargs) test.enterContext(patch('generator.production.generate_tree',side_effect=serial)) test.enterContext(patch('generator.vocabulary.load',return_value=resources)) test.enterContext(patch('generator.production.repertoire.lookup',return_value=None)) test.enterContext(patch('generator.production._solo_model',return_value=predictor)) test.enterContext(patch('generator.production._resource_key',return_value={'model':'synthetic infrastructure fixture'})) test.enterContext(patch('generator.solo.composer.compose',side_effect=compose))