musicality 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +30 -0
  3. data/lib/musicality/errors.rb +1 -0
  4. data/lib/musicality/notation/conversion/change_conversion.rb +63 -3
  5. data/lib/musicality/notation/conversion/note_time_converter.rb +23 -5
  6. data/lib/musicality/notation/conversion/score_conversion.rb +60 -0
  7. data/lib/musicality/notation/conversion/score_converter.rb +105 -0
  8. data/lib/musicality/notation/model/change.rb +98 -28
  9. data/lib/musicality/notation/model/part.rb +1 -1
  10. data/lib/musicality/notation/model/score.rb +4 -4
  11. data/lib/musicality/notation/packing/change_packing.rb +35 -25
  12. data/lib/musicality/notation/packing/score_packing.rb +2 -2
  13. data/lib/musicality/notation/util/function.rb +99 -0
  14. data/lib/musicality/notation/util/piecewise_function.rb +79 -99
  15. data/lib/musicality/notation/util/transition.rb +12 -0
  16. data/lib/musicality/notation/util/value_computer.rb +12 -152
  17. data/lib/musicality/performance/conversion/score_collator.rb +35 -20
  18. data/lib/musicality/performance/midi/part_sequencer.rb +2 -5
  19. data/lib/musicality/validatable.rb +6 -1
  20. data/lib/musicality/version.rb +1 -1
  21. data/lib/musicality.rb +4 -4
  22. data/musicality.gemspec +1 -0
  23. data/spec/notation/conversion/change_conversion_spec.rb +216 -9
  24. data/spec/notation/conversion/measure_note_map_spec.rb +2 -2
  25. data/spec/notation/conversion/note_time_converter_spec.rb +91 -9
  26. data/spec/notation/conversion/{measured_score_conversion_spec.rb → score_conversion_spec.rb} +44 -9
  27. data/spec/notation/conversion/score_converter_spec.rb +246 -0
  28. data/spec/notation/model/change_spec.rb +139 -36
  29. data/spec/notation/model/part_spec.rb +3 -3
  30. data/spec/notation/model/score_spec.rb +4 -4
  31. data/spec/notation/packing/change_packing_spec.rb +222 -71
  32. data/spec/notation/packing/part_packing_spec.rb +1 -1
  33. data/spec/notation/packing/score_packing_spec.rb +3 -2
  34. data/spec/notation/util/function_spec.rb +43 -0
  35. data/spec/notation/util/transition_spec.rb +51 -0
  36. data/spec/notation/util/value_computer_spec.rb +43 -87
  37. data/spec/performance/conversion/score_collator_spec.rb +46 -7
  38. data/spec/performance/midi/part_sequencer_spec.rb +2 -1
  39. metadata +29 -14
  40. data/lib/musicality/notation/conversion/measured_score_conversion.rb +0 -70
  41. data/lib/musicality/notation/conversion/measured_score_converter.rb +0 -95
  42. data/lib/musicality/notation/conversion/unmeasured_score_conversion.rb +0 -47
  43. data/lib/musicality/notation/conversion/unmeasured_score_converter.rb +0 -64
  44. data/spec/notation/conversion/measured_score_converter_spec.rb +0 -329
  45. data/spec/notation/conversion/unmeasured_score_conversion_spec.rb +0 -71
  46. data/spec/notation/conversion/unmeasured_score_converter_spec.rb +0 -116
@@ -1,329 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
3
- describe MeasuredScoreConverter do
4
- describe '#initialize' do
5
- context 'current score is invalid' do
6
- it 'should raise NotValidError' do
7
- score = Score::Measured.new(1, 120)
8
- expect { MeasuredScoreConverter.new(score) }.to raise_error(NotValidError)
9
- end
10
- end
11
- end
12
-
13
- describe '#convert_parts' do
14
- before :each do
15
- @changeA = Change::Immediate.new(Dynamics::PP)
16
- @changeB = Change::Gradual.new(Dynamics::F, 2)
17
- @score = Score::Measured.new(FOUR_FOUR, 120,
18
- parts: {"simple" => Part.new(Dynamics::MP, dynamic_changes: { 1 => @changeA, 3 => @changeB })}
19
- )
20
- end
21
-
22
- it 'should return Hash with original part names' do
23
- parts = MeasuredScoreConverter.new(@score).convert_parts
24
- parts.should be_a Hash
25
- parts.keys.sort.should eq(@score.parts.keys.sort)
26
- end
27
-
28
- it 'should convert part dynamic change offsets from measure-based to note-based' do
29
- parts = MeasuredScoreConverter.new(@score).convert_parts
30
- parts.should have_key("simple")
31
- part = parts["simple"]
32
- part.dynamic_changes.keys.sort.should eq([1,3])
33
- change = part.dynamic_changes[Rational(1,1)]
34
- change.value.should eq(@changeA.value)
35
- change.duration.should eq(0)
36
- change = part.dynamic_changes[Rational(3,1)]
37
- change.value.should eq(@changeB.value)
38
- change.duration.should eq(2)
39
-
40
- @score.start_meter = THREE_FOUR
41
- parts = MeasuredScoreConverter.new(@score).convert_parts
42
- parts.should have_key("simple")
43
- part = parts["simple"]
44
- part.dynamic_changes.keys.sort.should eq([Rational(3,4),Rational(9,4)])
45
- change = part.dynamic_changes[Rational(3,4)]
46
- change.value.should eq(@changeA.value)
47
- change.duration.should eq(0)
48
- change = part.dynamic_changes[Rational(9,4)]
49
- change.value.should eq(@changeB.value)
50
- change.duration.should eq(1.5)
51
- end
52
-
53
- context 'gradual changes with positive elapsed and/or remaining' do
54
- it 'should change elapsed and remaining so they reflect note-based offsets' do
55
- score = Score::Measured.new(THREE_FOUR,120, parts: {
56
- "abc" => Part.new(Dynamics::P, dynamic_changes: {
57
- 2 => Change::Gradual.new(Dynamics::F,2,1,3),
58
- 7 => Change::Gradual.new(Dynamics::F,1,4,5)
59
- })
60
- })
61
- converter = MeasuredScoreConverter.new(score)
62
- parts = converter.convert_parts
63
- dcs = parts["abc"].dynamic_changes
64
-
65
- dcs.keys.should eq([Rational(6,4), Rational(21,4)])
66
- dcs[Rational(3,2)].should eq(Change::Gradual.new(Dynamics::F,Rational(6,4),Rational(3,4),Rational(9,4)))
67
- dcs[Rational(21,4)].should eq(Change::Gradual.new(Dynamics::F,Rational(3,4),Rational(12,4),Rational(15,4)))
68
- end
69
- end
70
- end
71
-
72
- describe '#convert_program' do
73
- before :each do
74
- @prog = Program.new([0...4,2...5])
75
- @score = Score::Measured.new(FOUR_FOUR, 120, program: @prog)
76
- @converter = MeasuredScoreConverter.new(@score)
77
- end
78
-
79
- it 'shuld return Program with same number of segments' do
80
- prog = @converter.convert_program
81
- prog.should be_a Program
82
- prog.segments.size.should eq(@score.program.segments.size)
83
- end
84
-
85
- it 'should convert program segments offsets from measure-based to note-based' do
86
- prog = MeasuredScoreConverter.new(@score).convert_program
87
- prog.segments.size.should eq(2)
88
- prog.segments[0].first.should eq(0)
89
- prog.segments[0].last.should eq(4)
90
- prog.segments[1].first.should eq(2)
91
- prog.segments[1].last.should eq(5)
92
-
93
- @score.start_meter = THREE_FOUR
94
- prog = MeasuredScoreConverter.new(@score).convert_program
95
- prog.segments.size.should eq(2)
96
- prog.segments[0].first.should eq(0)
97
- prog.segments[0].last.should eq(3)
98
- prog.segments[1].first.should eq(1.5)
99
- prog.segments[1].last.should eq(3.75)
100
- end
101
- end
102
-
103
- describe '#convert_start_tempo' do
104
- it 'should return a converted tempo object, with same type as givn tempo class' do
105
- score = Score::Measured.new(SIX_EIGHT, 120)
106
- converter = MeasuredScoreConverter.new(score)
107
- tempo = converter.convert_start_tempo
108
- tempo.should eq(180)
109
- end
110
- end
111
-
112
- describe '#convert_tempo_changes' do
113
- context 'immediate tempo changes' do
114
- before :all do
115
- @score = Score::Measured.new(THREE_FOUR, 120,
116
- tempo_changes: { 1 => Change::Immediate.new(100),
117
- 2.5 => Change::Immediate.new(90)}
118
- )
119
- @tcs = MeasuredScoreConverter.new(@score).convert_tempo_changes
120
- end
121
-
122
- it 'should change offset from measure-based to note-based' do
123
- @tcs.keys.sort.should eq([0.75, 1.875])
124
- end
125
-
126
- it 'should change tempo value using Tempo::BPM.to_qnpm' do
127
- @tcs.entries.first[1].value.should eq(Tempo::BPM.to_qnpm(100,Rational(1,4)))
128
- @tcs.entries.last[1].value.should eq(Tempo::BPM.to_qnpm(90,Rational(1,4)))
129
- end
130
- end
131
-
132
- context 'gradual tempo changes' do
133
- context 'no meter changes within tempo change duration' do
134
- before :all do
135
- @score = Score::Measured.new(THREE_FOUR, 120,
136
- tempo_changes: { 2 => Change::Gradual.new(100,2) },
137
- meter_changes: { 1 => Change::Immediate.new(TWO_FOUR),
138
- 4 => Change::Immediate.new(SIX_EIGHT) }
139
- )
140
- @tcs = MeasuredScoreConverter.new(@score).convert_tempo_changes
141
- end
142
-
143
- it 'should change tempo change offset to note-based' do
144
- @tcs.keys.should eq([Rational(5,4)])
145
- end
146
-
147
- it 'should convert the tempo change' do
148
- @tcs[Rational(5,4)].value.should eq(Tempo::BPM.to_qnpm(100,Rational(1,4)))
149
- end
150
-
151
- it 'should convert change duration to note-based' do
152
- @tcs[Rational(5,4)].duration.should eq(1)
153
- end
154
- end
155
-
156
- context 'single meter change within tempo change duration' do
157
- before :all do
158
- @tc_moff, @mc_moff = 2, 4
159
- @tc = Change::Gradual.new(100,4)
160
- @score = Score::Measured.new(THREE_FOUR, 120,
161
- tempo_changes: { @tc_moff => @tc },
162
- meter_changes: { @mc_moff => Change::Immediate.new(SIX_EIGHT) }
163
- )
164
- @tcs = MeasuredScoreConverter.new(@score).convert_tempo_changes
165
- @mnoff_map = @score.measure_note_map
166
-
167
- mend = @tc_moff + @tc.impending + @tc.remaining
168
- @ndur = @mnoff_map[mend] - @mnoff_map[mend - @tc.total_duration]
169
- end
170
-
171
- it 'should split the one gradual change into two, durations adding to original total' do
172
- @tcs.size.should eq(2)
173
- @tcs.values.each {|x| x.should be_a Change::Gradual }
174
- end
175
-
176
- it 'should make each with same total duration' do
177
- @tcs.values.each {|x| x.total_duration.should eq(@ndur) }
178
- end
179
-
180
- it 'should make durations so they sum to make the total duration' do
181
- @tcs.values.map {|x| x.duration }.inject(0,:+).should eq(@ndur)
182
- end
183
-
184
- it 'should start first split change where original change would start' do
185
- @tcs.should have_key(@mnoff_map[@tc_moff])
186
- end
187
-
188
- it 'should stop first split, and start second split where inner meter change occurs' do
189
- pc1_start_noff = @mnoff_map[@tc_moff]
190
- pc1_end_noff = pc1_start_noff + @tcs[pc1_start_noff].duration
191
-
192
- pc2_start_noff = @mnoff_map[@mc_moff]
193
- @tcs.should have_key(pc2_start_noff)
194
- pc1_end_noff.should eq(pc2_start_noff)
195
- end
196
-
197
- it 'should stop second split change where original change would end' do
198
- pc2_start_noff = @mnoff_map[@mc_moff]
199
- pc2_end_noff = pc2_start_noff + @tcs[pc2_start_noff].duration
200
- pc2_end_noff.should eq(@mnoff_map[@tc_moff + @tc.duration])
201
- end
202
- end
203
-
204
- context 'two meter changes within tempo change duration' do
205
- before :all do
206
- @tc_moff, @mc1_moff, @mc2_moff = 2, 4, 5
207
- @tc = Change::Gradual.new(100,5)
208
- @score = Score::Measured.new(THREE_FOUR, 120,
209
- tempo_changes: { @tc_moff => @tc},
210
- meter_changes: { @mc1_moff => Change::Immediate.new(SIX_EIGHT),
211
- @mc2_moff => Change::Immediate.new(TWO_FOUR) }
212
- )
213
- @tcs = MeasuredScoreConverter.new(@score).convert_tempo_changes
214
- @mnoff_map = @score.measure_note_map
215
-
216
- mend = @tc_moff + @tc.impending + @tc.remaining
217
- @ndur = @mnoff_map[mend] - @mnoff_map[mend - @tc.total_duration]
218
- end
219
-
220
- it 'should split the one gradual change into three' do
221
- @tcs.size.should eq(3)
222
- @tcs.values.each {|x| x.should be_a Change::Gradual }
223
- end
224
-
225
- it 'should make each with same total duration' do
226
- @tcs.values.each {|x| x.total_duration.should eq(@ndur) }
227
- end
228
-
229
- it 'should make durations so they sum to make the total duration' do
230
- @tcs.values.map {|x| x.duration }.inject(0,:+).should eq(@ndur)
231
- end
232
-
233
- it 'should start first split change where original change would start' do
234
- @tcs.should have_key(@mnoff_map[@tc_moff])
235
- end
236
-
237
- it 'should stop first split, and start second split change where 1st meter change occurs' do
238
- pc1_start_noff = @mnoff_map[@tc_moff]
239
- pc1_end_noff = pc1_start_noff + @tcs[pc1_start_noff].duration
240
-
241
- pc2_start_noff = @mnoff_map[@mc1_moff]
242
- @tcs.should have_key(pc2_start_noff)
243
- pc1_end_noff.should eq(pc2_start_noff)
244
- end
245
-
246
- it 'should stop second split, and start third split change where 2st meter change occurs' do
247
- pc2_start_noff = @mnoff_map[@mc1_moff]
248
- pc2_end_noff = pc2_start_noff + @tcs[pc2_start_noff].duration
249
-
250
- pc3_start_noff = @mnoff_map[@mc2_moff]
251
- @tcs.should have_key(pc3_start_noff)
252
- pc2_end_noff.should eq(pc3_start_noff)
253
- end
254
-
255
- it 'should stop third split change where original change would end' do
256
- pc3_start_noff = @mnoff_map[@mc2_moff]
257
- pc3_end_noff = pc3_start_noff + @tcs[pc3_start_noff].duration
258
- pc3_end_noff.should eq(@mnoff_map[@tc_moff + @tc.duration])
259
- end
260
- end
261
- end
262
-
263
- context 'gradual tempo changes with positive elapsed and/or remaining' do
264
- context 'no meter change during tempo change' do
265
- it 'should simply change elapsed and remaining so they reflect note-based offsets' do
266
- score = Score::Measured.new(THREE_FOUR,120, tempo_changes: {
267
- 3 => Change::Gradual.new(100,5,2,3)
268
- })
269
- converter = MeasuredScoreConverter.new(score)
270
- tcs = converter.convert_tempo_changes
271
-
272
- tcs.keys.should eq([Rational(9,4)])
273
- tcs[Rational(9,4)].should eq(Change::Gradual.new(100,Rational(15,4),Rational(6,4),Rational(9,4)))
274
- end
275
- end
276
-
277
- context 'meter changes during tempo change' do
278
- it 'should split tempo change, converting and adjusting elapsed/remaining with each sub-change' do
279
- score = Score::Measured.new(THREE_FOUR,120,
280
- meter_changes: { 4 => Change::Immediate.new(SIX_EIGHT),
281
- 6 => Change::Immediate.new(TWO_FOUR) },
282
- tempo_changes: { 3 => Change::Gradual.new(100,5,2,3) }
283
- )
284
- converter = MeasuredScoreConverter.new(score)
285
- tcs = converter.convert_tempo_changes
286
-
287
- tcs.keys.should eq([Rational(9,4), Rational(12,4), Rational(18,4)])
288
- tcs[Rational(9,4)].should eq(Change::Gradual.new(100,0.75,1.5,4))
289
- tcs[Rational(12,4)].should eq(Change::Gradual.new(Tempo::BPM.to_qnpm(100,SIX_EIGHT.beat_duration),1.5,2.25,2.5))
290
- tcs[Rational(18,4)].should eq(Change::Gradual.new(Tempo::BPM.to_qnpm(100,TWO_FOUR.beat_duration),1,3.75,1.5))
291
- end
292
- end
293
- end
294
- end
295
-
296
- describe '#convert_score' do
297
- it 'should return an unmeasured score' do
298
- score = Score::Measured.new(FOUR_FOUR, 120)
299
- converter = MeasuredScoreConverter.new(score)
300
- converter.convert_score.should be_a Score::Unmeasured
301
- end
302
-
303
- it 'should use output from convert_start_tempo' do
304
- score = Score::Measured.new(FOUR_FOUR, 120)
305
- converter = MeasuredScoreConverter.new(score)
306
- nscore = converter.convert_score
307
- nscore.start_tempo.should eq(converter.convert_start_tempo)
308
- end
309
-
310
- it 'should use output from convert_program' do
311
- prog = Program.new([0...4,2...5])
312
- score = Score::Measured.new(FOUR_FOUR, 120, program: prog)
313
- converter = MeasuredScoreConverter.new(score)
314
- nscore = converter.convert_score
315
- nscore.program.should eq(converter.convert_program)
316
- end
317
-
318
- it 'should use output from convert_parts' do
319
- changeA = Change::Immediate.new(Dynamics::PP)
320
- changeB = Change::Gradual.new(Dynamics::F, 2)
321
- score = Score::Measured.new(FOUR_FOUR, 120,
322
- parts: {"simple" => Part.new(Dynamics::MP, dynamic_changes: { 1 => changeA, 3 => changeB })}
323
- )
324
- converter = MeasuredScoreConverter.new(score)
325
- nscore = converter.convert_score
326
- nscore.parts.should eq(converter.convert_parts)
327
- end
328
- end
329
- end
@@ -1,71 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
3
- describe Score::Unmeasured do
4
- before :all do
5
- @parts = {
6
- "piano" => Part.new(Dynamics::MP,
7
- notes: [Note.quarter(C4), Note.eighth(F3), Note.whole(C4), Note.half(D4)]*12,
8
- dynamic_changes: {
9
- 1 => Change::Immediate.new(Dynamics::MF),
10
- 5 => Change::Immediate.new(Dynamics::FF),
11
- 6 => Change::Gradual.new(Dynamics::MF,2),
12
- 14 => Change::Immediate.new(Dynamics::PP),
13
- }
14
- )
15
- }
16
- @prog = Program.new([0...3,4...7,1...20,17..."45/2".to_r])
17
- tcs = {
18
- 0 => Change::Immediate.new(120),
19
- 4 => Change::Gradual.new(60,2),
20
- 11 => Change::Immediate.new(110)
21
- }
22
- @score = Score::Unmeasured.new(120,
23
- parts: @parts,
24
- program: @prog,
25
- tempo_changes: tcs,
26
- )
27
- end
28
-
29
- describe '#note_offsets' do
30
- before(:all){ @noffs = @score.note_offsets }
31
-
32
- it 'should return an already-sorted array' do
33
- @noffs.should eq @noffs.sort
34
- end
35
-
36
- it 'should start with offset from start tempo/dynamic' do
37
- @noffs[0].should eq(0)
38
- end
39
-
40
- it 'should include offsets from tempo changes' do
41
- @score.tempo_changes.each do |noff,change|
42
- @noffs.should include(noff)
43
- @noffs.should include(noff + change.duration)
44
- end
45
- end
46
-
47
- it "should include offsets from each part's dynamic changes" do
48
- @score.parts.values.each do |part|
49
- part.dynamic_changes.each do |noff,change|
50
- @noffs.should include(noff)
51
- change.offsets(noff).each {|offset| @noffs.should include(offset) }
52
- end
53
- end
54
- end
55
-
56
- it 'should include offsets from program segments' do
57
- @score.program.segments.each do |seg|
58
- @noffs.should include(seg.first)
59
- @noffs.should include(seg.last)
60
- end
61
- end
62
- end
63
-
64
- describe '#to_timed' do
65
- it 'should use UnmeasuredScoreConverter#convert_score' do
66
- nscore1 = @score.to_timed(200)
67
- nscore2 = UnmeasuredScoreConverter.new(@score,200).convert_score
68
- nscore1.should eq(nscore2)
69
- end
70
- end
71
- end
@@ -1,116 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
3
- describe UnmeasuredScoreConverter do
4
- describe '#initialize' do
5
- context 'current score is invalid' do
6
- it 'should raise NotValidError' do
7
- score = Score::Unmeasured.new(-1)
8
- expect { UnmeasuredScoreConverter.new(score,200) }.to raise_error(NotValidError)
9
- end
10
- end
11
- end
12
-
13
- describe '#convert_parts' do
14
- before :each do
15
- @changeA = Change::Immediate.new(Dynamics::PP)
16
- @changeB = Change::Gradual.new(Dynamics::F, 2)
17
- @score = Score::Unmeasured.new(120,
18
- parts: {
19
- "normal" => Part.new(Dynamics::MP,
20
- dynamic_changes: { 1 => @changeA, 3 => @changeB },
21
- notes: "/4C2 /8D2 /8E2 /2C2".to_notes * 4),
22
- "empty" => Part.new(Dynamics::PP)
23
- }
24
- )
25
- @parts = UnmeasuredScoreConverter.new(@score,200).convert_parts
26
- end
27
-
28
- it 'should return Hash with original part names' do
29
- @parts.should be_a Hash
30
- @parts.keys.sort.should eq(@score.parts.keys.sort)
31
- end
32
-
33
- it 'should convert part dynamic change offsets from note-based to time-based' do
34
- part = @parts["normal"]
35
- part.dynamic_changes.keys.sort.should eq([2,6])
36
- change = part.dynamic_changes[2.0]
37
- change.value.should eq(@changeA.value)
38
- change.duration.should eq(0)
39
- change = part.dynamic_changes[6.0]
40
- change.value.should eq(@changeB.value)
41
- change.duration.should eq(4.0)
42
- end
43
-
44
- it 'should convert note durations to time durations' do
45
- part = @parts["normal"]
46
- part.notes.map {|x| x.duration }.should eq([0.5,0.25,0.25,1]*4)
47
- end
48
-
49
- context 'gradual changes with positive elapsed and/or remaining' do
50
- it 'should change elapsed and remaining so they reflect time-based duration' do
51
- score = Score::Unmeasured.new(120, parts: {
52
- "abc" => Part.new(Dynamics::P, dynamic_changes: {
53
- 2 => Change::Gradual.new(Dynamics::F,2,1,3),
54
- 7 => Change::Gradual.new(Dynamics::F,1,4,5)
55
- })
56
- })
57
- converter = UnmeasuredScoreConverter.new(score,200)
58
- parts = converter.convert_parts
59
- dcs = parts["abc"].dynamic_changes
60
-
61
- dcs.keys.should eq([4,14])
62
- dcs[4.0].should eq(Change::Gradual.new(Dynamics::F,4,2,6))
63
- dcs[14.0].should eq(Change::Gradual.new(Dynamics::F,2,8,10))
64
- end
65
- end
66
- end
67
-
68
- describe '#convert_program' do
69
- before :each do
70
- @prog = Program.new([0...4,2...5])
71
- @score = Score::Unmeasured.new(120, program: @prog)
72
- @converter = UnmeasuredScoreConverter.new(@score,200)
73
- @prog2 = @converter.convert_program
74
- end
75
-
76
- it 'should return Program with same number of segments' do
77
- @prog2.should be_a Program
78
- @prog2.segments.size.should eq(@prog.segments.size)
79
- end
80
-
81
- it 'should convert program segments offsets from note-based to time-based' do
82
- prog = @prog2
83
- prog.segments[0].first.should eq(0)
84
- prog.segments[0].last.should eq(8)
85
- prog.segments[1].first.should eq(4)
86
- prog.segments[1].last.should eq(10)
87
- end
88
- end
89
-
90
- describe '#convert_score' do
91
- it 'should return an timed score' do
92
- score = Score::Unmeasured.new(120)
93
- converter = UnmeasuredScoreConverter.new(score,200)
94
- converter.convert_score.should be_a Score::Timed
95
- end
96
-
97
- it 'should use output from convert_program' do
98
- prog = Program.new([0...4,2...5])
99
- score = Score::Unmeasured.new(120, program: prog)
100
- converter = UnmeasuredScoreConverter.new(score,200)
101
- nscore = converter.convert_score
102
- nscore.program.should eq(converter.convert_program)
103
- end
104
-
105
- it 'should use output from convert_parts' do
106
- changeA = Change::Immediate.new(Dynamics::PP)
107
- changeB = Change::Gradual.new(Dynamics::F, 2)
108
- score = Score::Unmeasured.new(120,
109
- parts: {"simple" => Part.new(Dynamics::MP, dynamic_changes: { 1 => changeA, 3 => changeB })}
110
- )
111
- converter = UnmeasuredScoreConverter.new(score,200)
112
- nscore = converter.convert_score
113
- nscore.parts.should eq(converter.convert_parts)
114
- end
115
- end
116
- end