launchpad 0.0.2 → 0.1.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.
- data/README.rdoc +55 -8
- data/Rakefile +2 -1
- data/examples/color_picker.rb +99 -0
- data/examples/colors.rb +9 -8
- data/examples/doodle.rb +68 -0
- data/examples/drawing_board.rb +25 -0
- data/examples/feedback.rb +31 -2
- data/examples/reset.rb +6 -0
- data/examples/setup.rb +3 -1
- data/launchpad.gemspec +24 -4
- data/lib/launchpad.rb +2 -167
- data/lib/launchpad/device.rb +244 -0
- data/lib/launchpad/errors.rb +37 -0
- data/lib/launchpad/interaction.rb +89 -0
- data/lib/launchpad/midi_codes.rb +44 -0
- data/lib/launchpad/version.rb +2 -2
- data/test/helper.rb +37 -1
- data/test/test_device.rb +429 -0
- data/test/test_interaction.rb +183 -0
- metadata +38 -4
- data/test/test_launchpad-gem.rb +0 -7
data/test/test_device.rb
ADDED
@@ -0,0 +1,429 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestDevice < Test::Unit::TestCase
|
4
|
+
|
5
|
+
CONTROL_BUTTONS = {
|
6
|
+
:up => 0x68,
|
7
|
+
:down => 0x69,
|
8
|
+
:left => 0x6A,
|
9
|
+
:right => 0x6B,
|
10
|
+
:session => 0x6C,
|
11
|
+
:user1 => 0x6D,
|
12
|
+
:user2 => 0x6E,
|
13
|
+
:mixer => 0x6F
|
14
|
+
}
|
15
|
+
SCENE_BUTTONS = {
|
16
|
+
:scene1 => 0x08,
|
17
|
+
:scene2 => 0x18,
|
18
|
+
:scene3 => 0x28,
|
19
|
+
:scene4 => 0x38,
|
20
|
+
:scene5 => 0x48,
|
21
|
+
:scene6 => 0x58,
|
22
|
+
:scene7 => 0x68,
|
23
|
+
:scene8 => 0x78
|
24
|
+
}
|
25
|
+
COLORS = {
|
26
|
+
nil => 0, 0 => 0, :off => 0,
|
27
|
+
1 => 1, :lo => 1, :low => 1,
|
28
|
+
2 => 2, :med => 2, :medium => 2,
|
29
|
+
3 => 3, :hi => 3, :high => 3
|
30
|
+
}
|
31
|
+
STATES = {
|
32
|
+
:down => 127,
|
33
|
+
:up => 0
|
34
|
+
}
|
35
|
+
|
36
|
+
def expects_output(device, *args)
|
37
|
+
device.instance_variable_get('@output').expects(:write).with([{:message => args, :timestamp => 0}])
|
38
|
+
end
|
39
|
+
|
40
|
+
def stub_input(device, *args)
|
41
|
+
device.instance_variable_get('@input').stubs(:read).returns(args)
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'initializer' do
|
45
|
+
|
46
|
+
should 'try to initialize both input and output when not specified' do
|
47
|
+
Portmidi.expects(:input_devices).returns(mock_devices)
|
48
|
+
Portmidi.expects(:output_devices).returns(mock_devices)
|
49
|
+
d = Launchpad::Device.new
|
50
|
+
assert_not_nil d.instance_variable_get('@input')
|
51
|
+
assert_not_nil d.instance_variable_get('@output')
|
52
|
+
end
|
53
|
+
|
54
|
+
should 'not try to initialize input when set to false' do
|
55
|
+
Portmidi.expects(:input_devices).never
|
56
|
+
d = Launchpad::Device.new(:input => false)
|
57
|
+
assert_nil d.instance_variable_get('@input')
|
58
|
+
assert_not_nil d.instance_variable_get('@output')
|
59
|
+
end
|
60
|
+
|
61
|
+
should 'not try to initialize output when set to false' do
|
62
|
+
Portmidi.expects(:output_devices).never
|
63
|
+
d = Launchpad::Device.new(:output => false)
|
64
|
+
assert_not_nil d.instance_variable_get('@input')
|
65
|
+
assert_nil d.instance_variable_get('@output')
|
66
|
+
end
|
67
|
+
|
68
|
+
should 'not try to initialize any of both when set to false' do
|
69
|
+
Portmidi.expects(:input_devices).never
|
70
|
+
Portmidi.expects(:output_devices).never
|
71
|
+
d = Launchpad::Device.new(:input => false, :output => false)
|
72
|
+
assert_nil d.instance_variable_get('@input')
|
73
|
+
assert_nil d.instance_variable_get('@output')
|
74
|
+
end
|
75
|
+
|
76
|
+
should 'initialize the correct input output devices' do
|
77
|
+
Portmidi.stubs(:input_devices).returns(mock_devices(:id => 4, :name => 'Launchpad Name'))
|
78
|
+
Portmidi.stubs(:output_devices).returns(mock_devices(:id => 5, :name => 'Launchpad Name'))
|
79
|
+
d = Launchpad::Device.new(:device_name => 'Launchpad Name')
|
80
|
+
assert_equal Portmidi::Input, (input = d.instance_variable_get('@input')).class
|
81
|
+
assert_equal 4, input.device_id
|
82
|
+
assert_equal Portmidi::Output, (output = d.instance_variable_get('@output')).class
|
83
|
+
assert_equal 5, output.device_id
|
84
|
+
end
|
85
|
+
|
86
|
+
should 'raise NoSuchDeviceError when requested input device does not exist' do
|
87
|
+
assert_raise Launchpad::NoSuchDeviceError do
|
88
|
+
Portmidi.stubs(:input_devices).returns(mock_devices(:name => 'Launchpad Input'))
|
89
|
+
Launchpad::Device.new
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
should 'raise NoSuchDeviceError when requested output device does not exist' do
|
94
|
+
assert_raise Launchpad::NoSuchDeviceError do
|
95
|
+
Portmidi.stubs(:output_devices).returns(mock_devices(:name => 'Launchpad Output'))
|
96
|
+
Launchpad::Device.new
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
should 'raise DeviceBusyError when requested input device is busy' do
|
101
|
+
assert_raise Launchpad::DeviceBusyError do
|
102
|
+
Portmidi::Input.stubs(:new).raises(RuntimeError)
|
103
|
+
Launchpad::Device.new
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
should 'raise DeviceBusyError when requested output device is busy' do
|
108
|
+
assert_raise Launchpad::DeviceBusyError do
|
109
|
+
Portmidi::Output.stubs(:new).raises(RuntimeError)
|
110
|
+
Launchpad::Device.new
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
{
|
117
|
+
:reset => [0xB0, 0x00, 0x00],
|
118
|
+
:flashing_on => [0xB0, 0x00, 0x20],
|
119
|
+
:flashing_off => [0xB0, 0x00, 0x21],
|
120
|
+
:flashing_auto => [0xB0, 0x00, 0x28]
|
121
|
+
}.each do |method, codes|
|
122
|
+
context method do
|
123
|
+
|
124
|
+
should 'raise NoOutputAllowedError when not initialized with output' do
|
125
|
+
assert_raise Launchpad::NoOutputAllowedError do
|
126
|
+
Launchpad::Device.new(:output => false).send(method)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
should "send #{codes.inspect}" do
|
131
|
+
d = Launchpad::Device.new
|
132
|
+
expects_output(d, *codes)
|
133
|
+
d.send(method)
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'test_leds' do
|
140
|
+
|
141
|
+
should 'raise NoOutputAllowedError when not initialized with output' do
|
142
|
+
assert_raise Launchpad::NoOutputAllowedError do
|
143
|
+
Launchpad::Device.new(:output => false).test_leds
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'initialized with output' do
|
148
|
+
|
149
|
+
setup do
|
150
|
+
@device = Launchpad::Device.new(:input => false)
|
151
|
+
end
|
152
|
+
|
153
|
+
should 'return nil' do
|
154
|
+
assert_nil @device.test_leds
|
155
|
+
end
|
156
|
+
|
157
|
+
COLORS.merge(nil => 3).each do |name, value|
|
158
|
+
if value == 0
|
159
|
+
should "send 0xB0, 0x00, 0x00 when given #{name}" do
|
160
|
+
expects_output(@device, 0xB0, 0x00, 0x00)
|
161
|
+
@device.test_leds(value)
|
162
|
+
end
|
163
|
+
else
|
164
|
+
should "send 0xB0, 0x00, 0x7C + #{value} when given #{name}" do
|
165
|
+
d = Launchpad::Device.new
|
166
|
+
expects_output(@device, 0xB0, 0x00, 0x7C + value)
|
167
|
+
value.nil? ? @device.test_leds : @device.test_leds(value)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
context 'change' do
|
177
|
+
|
178
|
+
should 'raise NoOutputAllowedError when not initialized with output' do
|
179
|
+
assert_raise Launchpad::NoOutputAllowedError do
|
180
|
+
Launchpad::Device.new(:output => false).change(:up)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'initialized with output' do
|
185
|
+
|
186
|
+
setup do
|
187
|
+
@device = Launchpad::Device.new(:input => false)
|
188
|
+
end
|
189
|
+
|
190
|
+
should 'return nil' do
|
191
|
+
assert_nil @device.change(:up)
|
192
|
+
end
|
193
|
+
|
194
|
+
context 'control buttons' do
|
195
|
+
CONTROL_BUTTONS.each do |type, value|
|
196
|
+
should "send 0xB0, #{value}, 12 when given #{type}" do
|
197
|
+
expects_output(@device, 0xB0, value, 12)
|
198
|
+
@device.change(type)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
context 'scene buttons' do
|
204
|
+
SCENE_BUTTONS.each do |type, value|
|
205
|
+
should "send 0x90, #{value}, 12 when given #{type}" do
|
206
|
+
expects_output(@device, 0x90, value, 12)
|
207
|
+
@device.change(type)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
context 'grid buttons' do
|
213
|
+
8.times do |x|
|
214
|
+
8.times do |y|
|
215
|
+
should "send 0x90, #{16 * y + x}, 12 when given :grid, :x => #{x}, :y => #{y}" do
|
216
|
+
expects_output(@device, 0x90, 16 * y + x, 12)
|
217
|
+
@device.change(:grid, :x => x, :y => y)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
should 'raise NoValidGridCoordinatesError if x is not specified' do
|
223
|
+
assert_raise Launchpad::NoValidGridCoordinatesError do
|
224
|
+
@device.change(:grid, :y => 1)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
should 'raise NoValidGridCoordinatesError if x is below 0' do
|
229
|
+
assert_raise Launchpad::NoValidGridCoordinatesError do
|
230
|
+
@device.change(:grid, :x => -1, :y => 1)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
should 'raise NoValidGridCoordinatesError if x is above 7' do
|
235
|
+
assert_raise Launchpad::NoValidGridCoordinatesError do
|
236
|
+
@device.change(:grid, :x => 8, :y => 1)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
should 'raise NoValidGridCoordinatesError if y is not specified' do
|
241
|
+
assert_raise Launchpad::NoValidGridCoordinatesError do
|
242
|
+
@device.change(:grid, :x => 1)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
should 'raise NoValidGridCoordinatesError if y is below 0' do
|
247
|
+
assert_raise Launchpad::NoValidGridCoordinatesError do
|
248
|
+
@device.change(:grid, :x => 1, :y => -1)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
should 'raise NoValidGridCoordinatesError if y is above 7' do
|
253
|
+
assert_raise Launchpad::NoValidGridCoordinatesError do
|
254
|
+
@device.change(:grid, :x => 1, :y => 8)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
259
|
+
|
260
|
+
context 'colors' do
|
261
|
+
COLORS.each do |red_key, red_value|
|
262
|
+
COLORS.each do |green_key, green_value|
|
263
|
+
should "send 0x90, 0, #{16 * green_value + red_value + 12} when given :red => #{red_key}, :green => #{green_key}" do
|
264
|
+
expects_output(@device, 0x90, 0, 16 * green_value + red_value + 12)
|
265
|
+
@device.change(:grid, :x => 0, :y => 0, :red => red_key, :green => green_key)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
should 'raise NoValidBrightnessError if red is below 0' do
|
271
|
+
assert_raise Launchpad::NoValidBrightnessError do
|
272
|
+
@device.change(:grid, :x => 0, :y => 0, :red => -1)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
should 'raise NoValidBrightnessError if red is above 3' do
|
277
|
+
assert_raise Launchpad::NoValidBrightnessError do
|
278
|
+
@device.change(:grid, :x => 0, :y => 0, :red => 4)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
should 'raise NoValidBrightnessError if red is an unknown symbol' do
|
283
|
+
assert_raise Launchpad::NoValidBrightnessError do
|
284
|
+
@device.change(:grid, :x => 0, :y => 0, :red => :unknown)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
should 'raise NoValidBrightnessError if green is below 0' do
|
289
|
+
assert_raise Launchpad::NoValidBrightnessError do
|
290
|
+
@device.change(:grid, :x => 0, :y => 0, :green => -1)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
should 'raise NoValidBrightnessError if green is above 3' do
|
295
|
+
assert_raise Launchpad::NoValidBrightnessError do
|
296
|
+
@device.change(:grid, :x => 0, :y => 0, :green => 4)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
should 'raise NoValidBrightnessError if green is an unknown symbol' do
|
301
|
+
assert_raise Launchpad::NoValidBrightnessError do
|
302
|
+
@device.change(:grid, :x => 0, :y => 0, :green => :unknown)
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
end
|
307
|
+
|
308
|
+
context 'mode' do
|
309
|
+
|
310
|
+
should 'send color + 12 when nothing given' do
|
311
|
+
expects_output(@device, 0x90, 0, 12)
|
312
|
+
@device.change(:grid, :x => 0, :y => 0, :red => 0, :green => 0)
|
313
|
+
end
|
314
|
+
|
315
|
+
should 'send color + 12 when given :normal' do
|
316
|
+
expects_output(@device, 0x90, 0, 12)
|
317
|
+
@device.change(:grid, :x => 0, :y => 0, :red => 0, :green => 0, :mode => :normal)
|
318
|
+
end
|
319
|
+
|
320
|
+
should 'send color + 8 when given :flashing' do
|
321
|
+
expects_output(@device, 0x90, 0, 8)
|
322
|
+
@device.change(:grid, :x => 0, :y => 0, :red => 0, :green => 0, :mode => :flashing)
|
323
|
+
end
|
324
|
+
|
325
|
+
should 'send color when given :buffering' do
|
326
|
+
expects_output(@device, 0x90, 0, 0)
|
327
|
+
@device.change(:grid, :x => 0, :y => 0, :red => 0, :green => 0, :mode => :buffering)
|
328
|
+
end
|
329
|
+
|
330
|
+
end
|
331
|
+
|
332
|
+
end
|
333
|
+
|
334
|
+
end
|
335
|
+
|
336
|
+
context 'change_all' do
|
337
|
+
|
338
|
+
should 'raise NoOutputAllowedError when not initialized with output' do
|
339
|
+
assert_raise Launchpad::NoOutputAllowedError do
|
340
|
+
Launchpad::Device.new(:output => false).change_all
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
context 'initialized with output' do
|
345
|
+
|
346
|
+
setup do
|
347
|
+
@device = Launchpad::Device.new(:input => false)
|
348
|
+
end
|
349
|
+
|
350
|
+
should 'return nil' do
|
351
|
+
assert_nil @device.change_all([0])
|
352
|
+
end
|
353
|
+
|
354
|
+
should 'fill colors with 0, set grid 0,0 to 0 and flush colors' do
|
355
|
+
expects_output(@device, 0x90, 0, 0)
|
356
|
+
20.times {|i| expects_output(@device, 0x92, 17, 17)}
|
357
|
+
20.times {|i| expects_output(@device, 0x92, 12, 12)}
|
358
|
+
@device.change_all([5] * 40)
|
359
|
+
end
|
360
|
+
|
361
|
+
should 'cut off exceeding colors, set grid 0,0 to 0 and flush colors' do
|
362
|
+
expects_output(@device, 0x90, 0, 0)
|
363
|
+
40.times {|i| expects_output(@device, 0x92, 17, 17)}
|
364
|
+
@device.change_all([5] * 100)
|
365
|
+
end
|
366
|
+
|
367
|
+
end
|
368
|
+
|
369
|
+
end
|
370
|
+
|
371
|
+
context 'read_pending_actions' do
|
372
|
+
|
373
|
+
should 'raise NoInputAllowedError when not initialized with input' do
|
374
|
+
assert_raise Launchpad::NoInputAllowedError do
|
375
|
+
Launchpad::Device.new(:input => false).read_pending_actions
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
context 'initialized with input' do
|
380
|
+
|
381
|
+
setup do
|
382
|
+
@device = Launchpad::Device.new(:output => false)
|
383
|
+
end
|
384
|
+
|
385
|
+
context 'control buttons' do
|
386
|
+
CONTROL_BUTTONS.each do |type, value|
|
387
|
+
STATES.each do |state, velocity|
|
388
|
+
should "build proper action for control button #{type}, #{state}" do
|
389
|
+
stub_input(@device, {:timestamp => 0, :message => [0xB0, value, velocity]})
|
390
|
+
assert_equal [{:timestamp => 0, :state => state, :type => type}], @device.read_pending_actions
|
391
|
+
end
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
context 'scene buttons' do
|
397
|
+
SCENE_BUTTONS.each do |type, value|
|
398
|
+
STATES.each do |state, velocity|
|
399
|
+
should "build proper action for scene button #{type}, #{state}" do
|
400
|
+
stub_input(@device, {:timestamp => 0, :message => [0x90, value, velocity]})
|
401
|
+
assert_equal [{:timestamp => 0, :state => state, :type => type}], @device.read_pending_actions
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
context 'grid buttons' do
|
408
|
+
8.times do |x|
|
409
|
+
8.times do |y|
|
410
|
+
STATES.each do |state, velocity|
|
411
|
+
should "build proper action for grid button #{x},#{y}, #{state}" do
|
412
|
+
stub_input(@device, {:timestamp => 0, :message => [0x90, 16 * y + x, velocity]})
|
413
|
+
assert_equal [{:timestamp => 0, :state => state, :type => :grid, :x => x, :y => y}], @device.read_pending_actions
|
414
|
+
end
|
415
|
+
end
|
416
|
+
end
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
should 'build proper actions for multiple pending actions' do
|
421
|
+
stub_input(@device, {:timestamp => 1, :message => [0x90, 0, 127]}, {:timestamp => 2, :message => [0xB0, 0x68, 0]})
|
422
|
+
assert_equal [{:timestamp => 1, :state => :down, :type => :grid, :x => 0, :y => 0}, {:timestamp => 2, :state => :up, :type => :up}], @device.read_pending_actions
|
423
|
+
end
|
424
|
+
|
425
|
+
end
|
426
|
+
|
427
|
+
end
|
428
|
+
|
429
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class BreakError < StandardError; end
|
4
|
+
|
5
|
+
class TestInteraction < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context 'initializer' do
|
8
|
+
|
9
|
+
should 'create device if not given' do
|
10
|
+
Launchpad::Device.expects(:new).with(:input => true, :output => true).returns('device')
|
11
|
+
assert_equal 'device', Launchpad::Interaction.new.device
|
12
|
+
end
|
13
|
+
|
14
|
+
should 'create device with given device_name' do
|
15
|
+
Launchpad::Device.expects(:new).with(:device_name => 'device', :input => true, :output => true).returns('device')
|
16
|
+
assert_equal 'device', Launchpad::Interaction.new(:device_name => 'device').device
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'initialize device if given' do
|
20
|
+
assert_equal 'device', Launchpad::Interaction.new(:device => 'device').device
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'not be active' do
|
24
|
+
assert !Launchpad::Interaction.new.active
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'start' do
|
30
|
+
|
31
|
+
# this is kinda greybox tested, since I couldn't come up with another way to test a loop [thomas, 2009-11-11]
|
32
|
+
|
33
|
+
setup do
|
34
|
+
@interaction = Launchpad::Interaction.new(:device => @device = Launchpad::Device.new)
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'up until read_pending_actions' do
|
38
|
+
|
39
|
+
setup do
|
40
|
+
@device.stubs(:read_pending_actions).raises(BreakError)
|
41
|
+
end
|
42
|
+
|
43
|
+
should 'set active to true' do
|
44
|
+
begin
|
45
|
+
@interaction.start
|
46
|
+
fail 'should raise BreakError'
|
47
|
+
rescue BreakError
|
48
|
+
assert @interaction.active
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
should 'raise CommunicationError when Portmidi::DeviceError occurs' do
|
55
|
+
@device.stubs(:read_pending_actions).raises(Portmidi::DeviceError.new(0))
|
56
|
+
assert_raise Launchpad::CommunicationError do
|
57
|
+
@interaction.start
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
should 'call respond_to_action with actions from respond_to_action' do
|
62
|
+
begin
|
63
|
+
@interaction.stubs(:sleep).raises(BreakError)
|
64
|
+
@device.stubs(:read_pending_actions).returns(['message1', 'message2'])
|
65
|
+
@interaction.expects(:respond_to_action).with('message1').once
|
66
|
+
@interaction.expects(:respond_to_action).with('message2').once
|
67
|
+
@interaction.start
|
68
|
+
fail 'should raise BreakError'
|
69
|
+
rescue BreakError
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'sleep' do
|
74
|
+
|
75
|
+
setup do
|
76
|
+
@device.stubs(:read_pending_actions).returns([])
|
77
|
+
end
|
78
|
+
|
79
|
+
should 'sleep with default latency of 0.001 when none given' do
|
80
|
+
begin
|
81
|
+
@interaction.expects(:sleep).with(0.001).raises(BreakError)
|
82
|
+
@interaction.start
|
83
|
+
fail 'should raise BreakError'
|
84
|
+
rescue BreakError
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
should 'sleep with given latency' do
|
89
|
+
begin
|
90
|
+
@interaction = Launchpad::Interaction.new(:latency => 4, :device => @device)
|
91
|
+
@interaction.expects(:sleep).with(4).raises(BreakError)
|
92
|
+
@interaction.start
|
93
|
+
fail 'should raise BreakError'
|
94
|
+
rescue BreakError
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
should 'sleep with absolute value of given negative latency' do
|
99
|
+
begin
|
100
|
+
@interaction = Launchpad::Interaction.new(:latency => -3.1, :device => @device)
|
101
|
+
@interaction.expects(:sleep).with(3.1).raises(BreakError)
|
102
|
+
@interaction.start
|
103
|
+
fail 'should raise BreakError'
|
104
|
+
rescue BreakError
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
should 'not sleep when latency is <= 0' # TODO don't know how to test this [thomas, 2009-11-11]
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
should 'reset the device after the loop' # TODO don't know how to test this [thomas, 2009-11-11]
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'stop' do
|
117
|
+
|
118
|
+
should 'set active to false' do
|
119
|
+
i = Launchpad::Interaction.new
|
120
|
+
i.instance_variable_set('@active', true)
|
121
|
+
assert i.active
|
122
|
+
i.stop
|
123
|
+
assert !i.active
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'response_to/no_response_to/respond_to' do
|
129
|
+
|
130
|
+
setup do
|
131
|
+
@interaction = Launchpad::Interaction.new
|
132
|
+
end
|
133
|
+
|
134
|
+
should 'call responses that match, and not others' do
|
135
|
+
@interaction.response_to(:mixer, :down) {|i, a| @mixer_down = true}
|
136
|
+
@interaction.response_to(:all, :down) {|i, a| @all_down = true}
|
137
|
+
@interaction.response_to(:all, :up) {|i, a| @all_up = true}
|
138
|
+
@interaction.response_to(:grid, :down) {|i, a| @grid_down = true}
|
139
|
+
@interaction.respond_to(:mixer, :down)
|
140
|
+
assert @mixer_down
|
141
|
+
assert @all_down
|
142
|
+
assert !@all_up
|
143
|
+
assert !@grid_down
|
144
|
+
end
|
145
|
+
|
146
|
+
should 'not call responses when they are deregistered' do
|
147
|
+
@interaction.response_to(:mixer, :down) {|i, a| @mixer_down = true}
|
148
|
+
@interaction.response_to(:mixer, :up) {|i, a| @mixer_up = true}
|
149
|
+
@interaction.response_to(:all, :both) {|i, a| @all_down = a[:state] == :down}
|
150
|
+
@interaction.no_response_to(:mixer, :down)
|
151
|
+
@interaction.respond_to(:mixer, :down)
|
152
|
+
assert !@mixer_down
|
153
|
+
assert !@mixer_up
|
154
|
+
assert @all_down
|
155
|
+
@interaction.respond_to(:mixer, :up)
|
156
|
+
assert !@mixer_down
|
157
|
+
assert @mixer_up
|
158
|
+
assert !@all_down
|
159
|
+
end
|
160
|
+
|
161
|
+
should 'not call responses registered for both when removing for one of both states' do
|
162
|
+
@interaction.response_to(:mixer, :both) {|i, a| @mixer = true}
|
163
|
+
@interaction.no_response_to(:mixer, :down)
|
164
|
+
@interaction.respond_to(:mixer, :down)
|
165
|
+
assert !@mixer
|
166
|
+
@interaction.respond_to(:mixer, :up)
|
167
|
+
assert @mixer
|
168
|
+
end
|
169
|
+
|
170
|
+
should 'remove other responses when adding a new exclusive response' do
|
171
|
+
@interaction.response_to(:mixer, :both) {|i, a| @mixer = true}
|
172
|
+
@interaction.response_to(:mixer, :down, :exclusive => true) {|i, a| @exclusive_mixer = true}
|
173
|
+
@interaction.respond_to(:mixer, :down)
|
174
|
+
assert !@mixer
|
175
|
+
assert @exclusive_mixer
|
176
|
+
@interaction.respond_to(:mixer, :up)
|
177
|
+
assert @mixer
|
178
|
+
assert @exclusive_mixer
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|