musicality 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog.md +30 -0
- data/lib/musicality/errors.rb +1 -0
- data/lib/musicality/notation/conversion/change_conversion.rb +63 -3
- data/lib/musicality/notation/conversion/note_time_converter.rb +23 -5
- data/lib/musicality/notation/conversion/score_conversion.rb +60 -0
- data/lib/musicality/notation/conversion/score_converter.rb +105 -0
- data/lib/musicality/notation/model/change.rb +98 -28
- data/lib/musicality/notation/model/part.rb +1 -1
- data/lib/musicality/notation/model/score.rb +4 -4
- data/lib/musicality/notation/packing/change_packing.rb +35 -25
- data/lib/musicality/notation/packing/score_packing.rb +2 -2
- data/lib/musicality/notation/util/function.rb +99 -0
- data/lib/musicality/notation/util/piecewise_function.rb +79 -99
- data/lib/musicality/notation/util/transition.rb +12 -0
- data/lib/musicality/notation/util/value_computer.rb +12 -152
- data/lib/musicality/performance/conversion/score_collator.rb +35 -20
- data/lib/musicality/performance/midi/part_sequencer.rb +2 -5
- data/lib/musicality/validatable.rb +6 -1
- data/lib/musicality/version.rb +1 -1
- data/lib/musicality.rb +4 -4
- data/musicality.gemspec +1 -0
- data/spec/notation/conversion/change_conversion_spec.rb +216 -9
- data/spec/notation/conversion/measure_note_map_spec.rb +2 -2
- data/spec/notation/conversion/note_time_converter_spec.rb +91 -9
- data/spec/notation/conversion/{measured_score_conversion_spec.rb → score_conversion_spec.rb} +44 -9
- data/spec/notation/conversion/score_converter_spec.rb +246 -0
- data/spec/notation/model/change_spec.rb +139 -36
- data/spec/notation/model/part_spec.rb +3 -3
- data/spec/notation/model/score_spec.rb +4 -4
- data/spec/notation/packing/change_packing_spec.rb +222 -71
- data/spec/notation/packing/part_packing_spec.rb +1 -1
- data/spec/notation/packing/score_packing_spec.rb +3 -2
- data/spec/notation/util/function_spec.rb +43 -0
- data/spec/notation/util/transition_spec.rb +51 -0
- data/spec/notation/util/value_computer_spec.rb +43 -87
- data/spec/performance/conversion/score_collator_spec.rb +46 -7
- data/spec/performance/midi/part_sequencer_spec.rb +2 -1
- metadata +29 -14
- data/lib/musicality/notation/conversion/measured_score_conversion.rb +0 -70
- data/lib/musicality/notation/conversion/measured_score_converter.rb +0 -95
- data/lib/musicality/notation/conversion/unmeasured_score_conversion.rb +0 -47
- data/lib/musicality/notation/conversion/unmeasured_score_converter.rb +0 -64
- data/spec/notation/conversion/measured_score_converter_spec.rb +0 -329
- data/spec/notation/conversion/unmeasured_score_conversion_spec.rb +0 -71
- data/spec/notation/conversion/unmeasured_score_converter_spec.rb +0 -116
@@ -11,90 +11,154 @@ describe Change::Immediate do
|
|
11
11
|
@p.should be_a Hash
|
12
12
|
end
|
13
13
|
|
14
|
-
it 'should have "type" and "
|
14
|
+
it 'should have "type" and "end_value" keys' do
|
15
15
|
@p.should have_key("type")
|
16
|
-
@p.should have_key("
|
16
|
+
@p.should have_key("end_value")
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'should assign "Immediate" to "type" key' do
|
20
20
|
@p["type"].should eq("Immediate")
|
21
21
|
end
|
22
22
|
|
23
|
-
it 'should assign
|
24
|
-
@p["
|
23
|
+
it 'should assign end_value to "end_value" key' do
|
24
|
+
@p["end_value"].should eq(@c.end_value)
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'given :with method' do
|
28
|
+
it 'should send the :with method to end_value' do
|
29
|
+
p = @c.pack(:with => :to_s)
|
30
|
+
p["end_value"].should be_a String
|
31
|
+
p["end_value"].to_f.should eq(@c.end_value)
|
32
|
+
end
|
25
33
|
end
|
26
34
|
end
|
27
35
|
end
|
28
36
|
|
29
37
|
describe Change::Gradual do
|
30
38
|
describe '#pack' do
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@p = @c.pack
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'should return a Hash' do
|
38
|
-
@p.should be_a Hash
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'should have "type", "value", and "impending" keys' do
|
42
|
-
@p.should have_key("type")
|
43
|
-
@p.should have_key("value")
|
44
|
-
@p.should have_key("impending")
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'should assign "Gradual" to "type" key' do
|
48
|
-
@p["type"].should eq("Gradual")
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'should assign value to "value" key' do
|
52
|
-
@p["value"].should eq(@c.value)
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'should assign impending to "impending" key' do
|
56
|
-
@p["impending"].should eq(@c.impending)
|
57
|
-
end
|
39
|
+
before :all do
|
40
|
+
@c = Change::Gradual.linear(200,2.5)
|
41
|
+
@p = @c.pack
|
58
42
|
end
|
59
43
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
44
|
+
it 'should return a Hash' do
|
45
|
+
@p.should be_a Hash
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should have "type", "end_value", "duration", "transition", and keys' do
|
49
|
+
@p.keys.sort.should eq(["duration","end_value","transition","type"])
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should assign "Gradual" to "type" key' do
|
53
|
+
@p["type"].should eq("Gradual")
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should assign end_value to "end_value" key' do
|
57
|
+
@p["end_value"].should eq(@c.end_value)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should assign duration to "duration" key' do
|
61
|
+
@p["duration"].should eq(@c.duration)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should assign start value to "start_value" key' do
|
65
|
+
@p["start_value"].should eq(@c.start_value)
|
69
66
|
end
|
70
67
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
68
|
+
it 'should assign transition to "transition" key' do
|
69
|
+
@p["transition"].should eq(@c.transition)
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'given :with method' do
|
73
|
+
it 'should send the :with method to end_value' do
|
74
|
+
p = @c.pack(:with => :to_s)
|
75
|
+
p["end_value"].should be_a String
|
76
|
+
p["end_value"].to_f.should eq(@c.end_value)
|
75
77
|
end
|
76
|
-
|
77
|
-
|
78
|
-
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'given start value' do
|
81
|
+
it 'should assign start_value to "start_value" ' do
|
82
|
+
c = Change::Gradual.linear(200,2.5,start_value: 20)
|
83
|
+
p = c.pack
|
84
|
+
p.should have_key("start_value")
|
85
|
+
p["start_value"].should eq(c.start_value)
|
79
86
|
end
|
80
87
|
|
81
|
-
|
82
|
-
|
88
|
+
context 'given :with method' do
|
89
|
+
it 'should send the :with method to end_value' do
|
90
|
+
c = Change::Gradual.linear(200,2.5,start_value: 20)
|
91
|
+
p = c.pack(:with => :to_s)
|
92
|
+
p["start_value"].should be_a String
|
93
|
+
p["start_value"].to_f.should eq(c.start_value)
|
94
|
+
end
|
83
95
|
end
|
84
96
|
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe Change::Gradual::Trimmed do
|
101
|
+
describe '#pack' do
|
102
|
+
before :all do
|
103
|
+
@c = Change::Gradual::Trimmed.linear(200,2.5,preceding:1,remaining:0.5)
|
104
|
+
@p = @c.pack
|
105
|
+
end
|
85
106
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
107
|
+
it 'should return a Hash' do
|
108
|
+
@p.should be_a Hash
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should have "type", "end_value", "duration", "transition", "preceding", "remaining" keys' do
|
112
|
+
@p.keys.sort.should eq(["duration","end_value","preceding","remaining","transition","type"])
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should assign "Gradual::Trimmed" to "type" key' do
|
116
|
+
@p["type"].should eq("Gradual::Trimmed")
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should assign end_value to "end_value" key' do
|
120
|
+
@p["end_value"].should eq(@c.end_value)
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'should assign duration to "duration" key' do
|
124
|
+
@p["duration"].should eq(@c.duration)
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should assign transition to "transition" key' do
|
128
|
+
@p["transition"].should eq(@c.transition)
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should assign preceding to "preceding" key' do
|
132
|
+
@p["preceding"].should eq(@c.preceding)
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'should assign remaining to "remaining" key' do
|
136
|
+
@p["remaining"].should eq(@c.remaining)
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'given :with method' do
|
140
|
+
it 'should send the :with method to end_value' do
|
141
|
+
p = @c.pack(:with => :to_s)
|
142
|
+
p["end_value"].should be_a String
|
143
|
+
p["end_value"].to_f.should eq(@c.end_value)
|
90
144
|
end
|
91
|
-
|
92
|
-
|
93
|
-
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'given start value' do
|
148
|
+
it 'should assign start_value to "start_value" ' do
|
149
|
+
c = Change::Gradual.linear(200,2.5,start_value: 20).trim(0.5,0.5)
|
150
|
+
p = c.pack
|
151
|
+
p.should have_key("start_value")
|
152
|
+
p["start_value"].should eq(c.start_value)
|
94
153
|
end
|
95
154
|
|
96
|
-
|
97
|
-
|
155
|
+
context 'given :with method' do
|
156
|
+
it 'should send the :with method to end_value' do
|
157
|
+
c = Change::Gradual.linear(200,2.5,start_value: 20).trim(0.5,0.5)
|
158
|
+
p = c.pack(:with => :to_s)
|
159
|
+
p["start_value"].should be_a String
|
160
|
+
p["start_value"].to_f.should eq(c.start_value)
|
161
|
+
end
|
98
162
|
end
|
99
163
|
end
|
100
164
|
end
|
@@ -113,18 +177,25 @@ describe Change do
|
|
113
177
|
@c2.should be_a Change::Immediate
|
114
178
|
end
|
115
179
|
|
116
|
-
it 'should successfully unpack the change
|
117
|
-
@c2.
|
180
|
+
it 'should successfully unpack the change end_value' do
|
181
|
+
@c2.end_value.should eq @c.end_value
|
118
182
|
end
|
119
183
|
|
120
|
-
|
121
|
-
|
184
|
+
context 'pack/unpack using :with method' do
|
185
|
+
it 'should use given :with method to convert end_value' do
|
186
|
+
c = Change::Immediate.new(0.5)
|
187
|
+
h = c.pack(:with => :to_s)
|
188
|
+
c2 = Change.unpack(h)
|
189
|
+
c2.end_value.should be_a String
|
190
|
+
c3 = Change.unpack(h, :with => :to_f)
|
191
|
+
c3.end_value.should be_a Float
|
192
|
+
end
|
122
193
|
end
|
123
194
|
end
|
124
195
|
|
125
196
|
context 'given a packed gradual change' do
|
126
197
|
before :all do
|
127
|
-
@c = Change::Gradual.
|
198
|
+
@c = Change::Gradual.sigmoid(0.3,1.5)
|
128
199
|
@a = @c.pack
|
129
200
|
@c2 = Change.unpack(@a)
|
130
201
|
end
|
@@ -133,21 +204,101 @@ describe Change do
|
|
133
204
|
@c2.should be_a Change::Gradual
|
134
205
|
end
|
135
206
|
|
136
|
-
it 'should
|
137
|
-
@c2.
|
207
|
+
it 'should unpack the end_value' do
|
208
|
+
@c2.end_value.should eq @c.end_value
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'should unpack the change duration' do
|
212
|
+
@c2.duration.should eq @c.duration
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'should unpack the change transition' do
|
216
|
+
@c2.transition.should eq @c.transition
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'should unpack the change start_value' do
|
220
|
+
@c2.start_value.should eq @c.start_value
|
138
221
|
end
|
139
222
|
|
140
|
-
|
141
|
-
|
223
|
+
context 'pack/unpack using :with method' do
|
224
|
+
it 'should use given :with method to convert end_value' do
|
225
|
+
c = Change::Gradual.linear(0.5,2)
|
226
|
+
h = c.pack(:with => :to_s)
|
227
|
+
c2 = Change.unpack(h)
|
228
|
+
c2.end_value.should be_a String
|
229
|
+
c3 = Change.unpack(h, :with => :to_f)
|
230
|
+
c3.end_value.should be_a Float
|
231
|
+
end
|
232
|
+
|
233
|
+
context 'when change start_value is not nil' do
|
234
|
+
it 'should use given :with method to convert start_value' do
|
235
|
+
c = Change::Gradual.linear(0.5,2,start_value: 0.1)
|
236
|
+
h = c.pack(:with => :to_s)
|
237
|
+
c2 = Change.unpack(h)
|
238
|
+
c2.start_value.should be_a String
|
239
|
+
c3 = Change.unpack(h, :with => :to_f)
|
240
|
+
c3.start_value.should be_a Float
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
context 'given a packed gradual (trimmed) change' do
|
247
|
+
before :all do
|
248
|
+
@c = Change::Gradual::Trimmed.sigmoid(0.3,1.5,preceding:0.1,remaining:0.1)
|
249
|
+
@a = @c.pack
|
250
|
+
@c2 = Change.unpack(@a)
|
142
251
|
end
|
143
252
|
|
144
|
-
it 'should
|
145
|
-
@c2.
|
253
|
+
it 'should return a Change::Gradual' do
|
254
|
+
@c2.should be_a Change::Gradual
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'should successfully unpack the end_value' do
|
258
|
+
@c2.end_value.should eq @c.end_value
|
259
|
+
end
|
260
|
+
|
261
|
+
it 'should successfully unpack the change duration' do
|
262
|
+
@c2.duration.should eq @c.duration
|
146
263
|
end
|
147
264
|
|
265
|
+
it 'should successfully unpack the change transition' do
|
266
|
+
@c2.transition.should eq @c.transition
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'should unpack the change start_value' do
|
270
|
+
@c2.start_value.should eq @c.start_value
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'should successfully unpack the change preceding' do
|
274
|
+
@c2.preceding.should eq @c.preceding
|
275
|
+
end
|
276
|
+
|
148
277
|
it 'should successfully unpack the change remaining' do
|
149
278
|
@c2.remaining.should eq @c.remaining
|
150
|
-
end
|
151
|
-
|
279
|
+
end
|
280
|
+
|
281
|
+
context 'pack/unpack using :with method' do
|
282
|
+
it 'should use given :with method to convert end_value' do
|
283
|
+
c = Change::Gradual.linear(0.5,2).trim(0.4,0.3)
|
284
|
+
h = c.pack(:with => :to_s)
|
285
|
+
c2 = Change.unpack(h)
|
286
|
+
c2.end_value.should be_a String
|
287
|
+
c3 = Change.unpack(h, :with => :to_f)
|
288
|
+
c3.end_value.should be_a Float
|
289
|
+
end
|
290
|
+
|
291
|
+
context 'when change start_value is not nil' do
|
292
|
+
it 'should use given :with method to convert start_value' do
|
293
|
+
c = Change::Gradual.linear(0.5,2,start_value: 0.1).trim(0.4,0.3)
|
294
|
+
h = c.pack(:with => :to_s)
|
295
|
+
c2 = Change.unpack(h)
|
296
|
+
c2.start_value.should be_a String
|
297
|
+
c3 = Change.unpack(h, :with => :to_f)
|
298
|
+
c3.start_value.should be_a Float
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
152
303
|
end
|
153
304
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
2
|
|
3
3
|
measured_score = Score::Measured.new(FOUR_FOUR,120) do |s|
|
4
|
+
s.meter_changes[1] = Change::Immediate.new(THREE_FOUR)
|
4
5
|
s.program = Program.new([0...2, 0...2,2...4,0...2])
|
5
6
|
s.parts["lead"] = Part.new(Dynamics::MF) do |p|
|
6
7
|
riff = "/6Bb3 /4 /12Db4= /6Db4= /36Db4 /36Eb4 /36Db4 /6Ab3 /12Db4 \
|
@@ -58,9 +59,9 @@ describe Score::Measured do
|
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
61
|
-
it 'should pack meter change values as strings' do
|
62
|
+
it 'should pack meter change end values as strings' do
|
62
63
|
@h['meter_changes'].each do |offset,packed_v|
|
63
|
-
packed_v[
|
64
|
+
packed_v["end_value"].should be_a String
|
64
65
|
end
|
65
66
|
end
|
66
67
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Function::Constant do
|
4
|
+
it 'should always return the same value' do
|
5
|
+
f = Function::Constant.new(20)
|
6
|
+
f.at(0).should eq(20)
|
7
|
+
f.at(-1000).should eq(20)
|
8
|
+
f.at(1000).should eq(20)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe Function::Linear do
|
13
|
+
it 'should evaluate along the line going between the two initial points' do
|
14
|
+
f = Function::Linear.new([5,10],[7,11])
|
15
|
+
f.at(4).should eq(9.5)
|
16
|
+
f.at(5).should eq(10)
|
17
|
+
f.at(6).should eq(10.5)
|
18
|
+
f.at(7).should eq(11)
|
19
|
+
f.at(8).should eq(11.5)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe Function::Sigmoid do
|
24
|
+
it 'should evaluate along the line going between the two initial points' do
|
25
|
+
f = Function::Sigmoid.new([5,10],[7,11])
|
26
|
+
f.at(4).should be < 10
|
27
|
+
f.at(5).should eq(10)
|
28
|
+
f.at(6).should eq(10.5)
|
29
|
+
f.at(7).should eq(11)
|
30
|
+
f.at(8).should be > 11
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '.find_y0' do
|
34
|
+
it 'should return the starting y-value for the given sigmoid domain' do
|
35
|
+
x0, x1 = 3, 6
|
36
|
+
y0, y1 = 5, 10
|
37
|
+
f = Function::Sigmoid.new([x0,y0],[x1,y1])
|
38
|
+
pt = [4,f.at(4)]
|
39
|
+
y0_ = Function::Sigmoid.find_y0(x0..x1, pt, y1)
|
40
|
+
y0_.should eq(y0)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Transition do
|
4
|
+
describe '#initialize' do
|
5
|
+
context 'zero-length domain' do
|
6
|
+
it 'should create one piece' do
|
7
|
+
t = Transition.new(Function::Constant.new(3),5..5)
|
8
|
+
t.pieces.size.should eq(1)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'positive-length domain' do
|
13
|
+
it 'should create two pieces' do
|
14
|
+
t = Transition.new(Function::Linear.new([0,0],[2,1]),3..5)
|
15
|
+
t.pieces.size.should eq(2)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#at' do
|
21
|
+
before :all do
|
22
|
+
@f = Function::Linear.new([0,0],[2,1])
|
23
|
+
@d = 3..5
|
24
|
+
@t = Transition.new(@f,@d)
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'given value before transition domain starts' do
|
28
|
+
it 'should raise DomainError' do
|
29
|
+
expect { @t.at(@d.first - 1e-5) }.to raise_error(DomainError)
|
30
|
+
expect { @t.at(@d.first - 1e5) }.to raise_error(DomainError)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'given value in transition domain' do
|
35
|
+
it 'should not raise DomainError' do
|
36
|
+
@d.entries.each {|x| expect { @t.at(x) }.to_not raise_error }
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should calculate return value using the transition function' do
|
40
|
+
@d.entries.each {|x| @t.at(x).should eq(@f.at(x)) }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'given value after transition domain' do
|
45
|
+
it 'should return same value as at the end of transition domain' do
|
46
|
+
@t.at(@d.last + 1e-5).should eq(@t.at(@d.last))
|
47
|
+
@t.at(@d.last + 1e5).should eq(@t.at(@d.last))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
2
|
|
3
3
|
describe ValueComputer do
|
4
|
-
describe '#
|
4
|
+
describe '#at' do
|
5
5
|
before :all do
|
6
|
-
@
|
7
|
-
@
|
6
|
+
@immed_change = Change::Immediate.new(0.6)
|
7
|
+
@lin_change = Change::Gradual.linear(0.6, 1.0)
|
8
|
+
@sigm_change = Change::Gradual.sigmoid(0.6, 1.0)
|
8
9
|
end
|
9
10
|
|
10
11
|
context "constant value" do
|
@@ -13,134 +14,89 @@ describe ValueComputer do
|
|
13
14
|
end
|
14
15
|
|
15
16
|
it "should always return default value if no changes are given" do
|
16
|
-
[ValueComputer
|
17
|
-
@comp.
|
17
|
+
[ValueComputer::DOMAIN_MIN, -1000, 0, 1, 5, 100, 10000, ValueComputer::DOMAIN_MAX].each do |offset|
|
18
|
+
@comp.at(offset).should eq(0.5)
|
18
19
|
end
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
22
23
|
context "one change, no transition" do
|
23
24
|
before :each do
|
24
|
-
@comp = ValueComputer.new 0.5, 1.0 => @
|
25
|
+
@comp = ValueComputer.new 0.5, 1.0 => @immed_change
|
25
26
|
end
|
26
27
|
|
27
28
|
it "should be the default value just before the first change" do
|
28
|
-
@comp.
|
29
|
+
@comp.at(0.999).should eq(0.5)
|
29
30
|
end
|
30
31
|
|
31
32
|
it "should transition to the second value immediately" do
|
32
|
-
@comp.
|
33
|
+
@comp.at(1.0).should eq(0.6)
|
33
34
|
end
|
34
35
|
|
35
36
|
it "should be the first value for all time before" do
|
36
|
-
@comp.
|
37
|
+
@comp.at(ValueComputer::DOMAIN_MIN).should eq(0.5)
|
37
38
|
end
|
38
39
|
|
39
40
|
it "should be at the second value for all time after" do
|
40
|
-
@comp.
|
41
|
+
@comp.at(ValueComputer::DOMAIN_MAX).should eq(0.6)
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
44
45
|
context "one change, linear transition" do
|
45
46
|
before :each do
|
46
|
-
@comp = ValueComputer.new 0.2, 1.0 => @
|
47
|
+
@comp = ValueComputer.new 0.2, 1.0 => @lin_change
|
47
48
|
end
|
48
49
|
|
49
50
|
it "should be the first (starting) value just before the second value" do
|
50
|
-
@comp.
|
51
|
+
@comp.at(0.999).should eq(0.2)
|
51
52
|
end
|
52
53
|
|
53
54
|
it "should be the first (starting) value exactly at the second value" do
|
54
|
-
@comp.
|
55
|
+
@comp.at(1.0).should eq(0.2)
|
55
56
|
end
|
56
57
|
|
57
58
|
it "should be 1/4 to the second value after 1/4 transition duration has elapsed" do
|
58
|
-
@comp.
|
59
|
+
@comp.at(Rational(5,4).to_f).should eq(0.3)
|
59
60
|
end
|
60
61
|
|
61
62
|
it "should be 1/2 to the second value after 1/2 transition duration has elapsed" do
|
62
|
-
@comp.
|
63
|
+
@comp.at(Rational(6,4).to_f).should eq(0.4)
|
63
64
|
end
|
64
65
|
|
65
66
|
it "should be 3/4 to the second value after 3/4 transition duration has elapsed" do
|
66
|
-
@comp.
|
67
|
+
@comp.at(Rational(7,4).to_f).should eq(0.5)
|
67
68
|
end
|
68
69
|
|
69
70
|
it "should be at the second value after transition duration has elapsed" do
|
70
|
-
@comp.
|
71
|
+
@comp.at(Rational(8,4).to_f).should eq(0.6)
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
# comp.value_at(case_hash[:offset] - 0.0001).should eq(case_hash[:start_value])
|
100
|
-
# end
|
101
|
-
# end
|
102
|
-
#
|
103
|
-
# it "should be very nearly the first (starting) value exactly at the value change offset" do
|
104
|
-
# @computers.each do |case_hash, comp|
|
105
|
-
# comp.value_at(case_hash[:offset]).should be_within(0.0001).of(case_hash[:start_value])
|
106
|
-
# end
|
107
|
-
# end
|
108
|
-
#
|
109
|
-
# it "should be within 1% of start/end difference away from the start value after 1/4 transition duration has elapsed" do
|
110
|
-
# @computers.each do |case_hash, comp|
|
111
|
-
# test_offset = case_hash[:offset] + (case_hash[:duration] * 0.25)
|
112
|
-
# start_value = case_hash[:start_value]
|
113
|
-
# end_value = case_hash[:end_value]
|
114
|
-
# tolerance = 0.01 * (end_value - start_value)
|
115
|
-
# comp.value_at(test_offset).should be_within(tolerance).of(start_value)
|
116
|
-
# end
|
117
|
-
# end
|
118
|
-
#
|
119
|
-
# it "should be half way to the end value after half way through transition" do
|
120
|
-
# @computers.each do |case_hash, comp|
|
121
|
-
# test_offset = case_hash[:offset] + (case_hash[:duration] * 0.5)
|
122
|
-
# start_value = case_hash[:start_value]
|
123
|
-
# expected_value = start_value + (case_hash[:end_value] - start_value) * 0.5
|
124
|
-
# comp.value_at(test_offset).should be_within(0.0001).of(expected_value)
|
125
|
-
# end
|
126
|
-
# end
|
127
|
-
#
|
128
|
-
# it "should be within 1% of start/end difference away from the end value after 3/4 transition duration has elapsed" do
|
129
|
-
# @computers.each do |case_hash, comp|
|
130
|
-
# test_offset = case_hash[:offset] + (case_hash[:duration] * 0.75)
|
131
|
-
# start_value = case_hash[:start_value]
|
132
|
-
# end_value = case_hash[:end_value]
|
133
|
-
# tolerance = 0.01 * (end_value - start_value)
|
134
|
-
# comp.value_at(test_offset).should be_within(tolerance).of(end_value)
|
135
|
-
# end
|
136
|
-
# end
|
137
|
-
#
|
138
|
-
# it "should be at the second value after transition duration has elapsed" do
|
139
|
-
# @computers.each do |case_hash, comp|
|
140
|
-
# comp.value_at(case_hash[:offset] + case_hash[:duration]).should eq(case_hash[:end_value])
|
141
|
-
# end
|
142
|
-
# end
|
143
|
-
# end
|
75
|
+
context "one change, sigmoid transition" do
|
76
|
+
before :each do
|
77
|
+
@comp = ValueComputer.new 0.2, 1.0 => @sigm_change
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should be the first (starting) value just before the second value" do
|
81
|
+
@comp.at(0.999).should eq(0.2)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should be the first (starting) value exactly at the second value" do
|
85
|
+
@comp.at(1.0).should eq(0.2)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should be 1/2 to the second value after 1/2 transition duration has elapsed" do
|
89
|
+
@comp.at(1.5).should be_within(1e-5).of(0.4)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should be at the second value exactly where transition duration has elapsed" do
|
93
|
+
@comp.at(2).should eq(0.6)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should be at the second value just after transition duration has elapsed" do
|
97
|
+
@comp.at(2.001).should eq(0.6)
|
98
|
+
end
|
99
|
+
end
|
144
100
|
end
|
145
101
|
end
|
146
102
|
|