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.
- 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
|
|