musicality 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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