rtmidi 0.2.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,438 @@
1
+ require 'spec_helper'
2
+
3
+ # Stub out the system code and record what was done
4
+ class RtMidi::Build::Compiler
5
+
6
+ def platform
7
+ @options[:platform]
8
+ end
9
+
10
+ def cd(dir)
11
+ @current_dir = dir
12
+ end
13
+
14
+ def can_run(cmd)
15
+ # simulate the compiler executables being on the path given a @context set in the tests below
16
+ case @options[:compiler]
17
+ when :gcc then cmd == 'gcc' or cmd == 'g++'
18
+ when :cl then cmd == 'cl.exe'
19
+ when false
20
+ end
21
+ end
22
+
23
+ def run(cmd)
24
+ (@commands ||= []) << cmd
25
+ end
26
+
27
+ def linux_package_exists(pkg)
28
+ pkg == @options[:library]
29
+ end
30
+
31
+ def linux_library(pkg)
32
+ "lib#{@options[:library]}"
33
+ end
34
+
35
+ attr_reader :current_dir, :commands
36
+
37
+ def command
38
+ @commands.last
39
+ end
40
+ end
41
+
42
+
43
+ describe RtMidi::Build::Compiler do
44
+
45
+ def compiler_for(platform, compiler, library=nil)
46
+ RtMidi::Build::Compiler.new(ext_dir, rtmidi_dir, platform: platform, compiler: compiler, library: library)
47
+ end
48
+
49
+ let(:ext_dir) { '/ext_dir' }
50
+ let(:rtmidi_dir) { '/rtmidi_dir' }
51
+
52
+ let(:osx_compiler) { compiler_for :osx, :gcc }
53
+ let(:windows_gcc_compiler) { compiler_for :windows, :gcc }
54
+ let(:windows_cl_compiler) { compiler_for :windows, :cl }
55
+ let(:linux_jack_compiler) { compiler_for :linux, :gcc, :jack }
56
+ let(:linux_alsa_compiler) { compiler_for :linux, :gcc, :alsa }
57
+
58
+ let(:gcc_compilers) { [osx_compiler, windows_gcc_compiler, linux_jack_compiler, linux_alsa_compiler] }
59
+ let(:cl_compiler) { windows_cl_compiler }
60
+ let(:compilers) { [osx_compiler, windows_gcc_compiler, windows_cl_compiler, linux_jack_compiler, linux_alsa_compiler] }
61
+
62
+
63
+ describe '.new' do
64
+ it 'fails for unrecognized platforms' do
65
+ ->{ compiler_for(:commodore64, :gcc) }.should raise_error 'Unsupported platform commodore64'
66
+ end
67
+
68
+ context 'on osx' do
69
+ it 'fails if gcc/g++ is not available' do
70
+ ->{ compiler_for(:osx, nil) }.should raise_error 'Cannot find gcc/g++ compiler'
71
+ end
72
+ end
73
+
74
+ context 'on linux' do
75
+ it 'fails if gcc/g++ is not available' do
76
+ ->{ compiler_for(:linux, nil) }.should raise_error 'Cannot find gcc/g++ compiler'
77
+ end
78
+
79
+ it 'fails if neither JACK or ALSA is available' do
80
+ ->{ compiler_for(:linux, :gcc) }.should raise_error 'Neither JACK or ALSA detected using pkg-config. Please install one of them first.'
81
+ end
82
+ end
83
+
84
+ context 'on windows' do
85
+ it 'fails if neither gcc/g++ or cl.exe is available' do
86
+ ->{ compiler_for(:windows, nil) }.should raise_error 'Cannot find gcc/g++ or cl.exe compiler'
87
+ end
88
+ end
89
+ end
90
+
91
+
92
+ describe '#compile_rtmidi' do
93
+
94
+ it 'changes the current director to the rtmidi_dir' do
95
+ for compiler in compilers
96
+ compiler.compile_rtmidi
97
+ compiler.current_dir.should == rtmidi_dir
98
+ end
99
+ end
100
+
101
+ it 'runs a single command' do
102
+ for compiler in compilers
103
+ compiler.compile_rtmidi
104
+ compiler.commands.length.should == 1
105
+ end
106
+ end
107
+
108
+ context 'with gcc' do
109
+ it 'runs g++' do
110
+ for compiler in gcc_compilers
111
+ compiler.compile_rtmidi
112
+ compiler.command[0..2].should == 'g++'
113
+ end
114
+ end
115
+
116
+ it 'includes the subfolder named include' do
117
+ for compiler in gcc_compilers
118
+ compiler.compile_rtmidi
119
+ compiler.command.should =~ /-Iinclude/
120
+ end
121
+ end
122
+
123
+ it 'compiles RtMidi.cpp' do
124
+ for compiler in gcc_compilers
125
+ compiler.compile_rtmidi
126
+ compiler.command.should =~ /-c\s+RtMidi\.cpp/
127
+ end
128
+ end
129
+
130
+ it 'outputs RtMidi.o' do
131
+ for compiler in gcc_compilers
132
+ compiler.compile_rtmidi
133
+ compiler.command.should =~ /-o\s+RtMidi\.o/
134
+ end
135
+ end
136
+
137
+ context 'on osx' do
138
+ it 'predefines __MACOSX_CORE__' do
139
+ osx_compiler.compile_rtmidi
140
+ osx_compiler.command.should =~ /-D__MACOSX_CORE__/
141
+ end
142
+ end
143
+
144
+ context 'on windows' do
145
+ it 'predefines __WINDOWS_MM__' do
146
+ windows_gcc_compiler.compile_rtmidi
147
+ windows_gcc_compiler.command.should =~ /-D__WINDOWS_MM__/
148
+ end
149
+ end
150
+
151
+ context 'on linux' do
152
+ context 'with ALSA' do
153
+ it 'predefines __LINUX_ALSA__' do
154
+ linux_alsa_compiler.compile_rtmidi
155
+ linux_alsa_compiler.command.should =~ /-D__LINUX_ALSA__/
156
+ end
157
+ end
158
+
159
+ context 'with JACK' do
160
+ it 'predefines __UNIX_JACK__' do
161
+ linux_jack_compiler.compile_rtmidi
162
+ linux_jack_compiler.command.should =~ /-D__UNIX_JACK__/
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ context 'with cl.exe' do
169
+ it 'runs cl' do
170
+ cl_compiler.compile_rtmidi
171
+ cl_compiler.command[0..1].should == 'cl'
172
+ end
173
+
174
+ it 'includes the subfolder named include' do
175
+ cl_compiler.compile_rtmidi
176
+ cl_compiler.command.should =~ /\/Iinclude/
177
+ end
178
+
179
+ it 'compiles RtMidi.cpp' do
180
+ cl_compiler.compile_rtmidi
181
+ cl_compiler.command.should =~ /\/c\s+RtMidi\.cpp/
182
+ end
183
+
184
+ it 'outputs RtMidi.obj' do
185
+ cl_compiler.compile_rtmidi
186
+ cl_compiler.command.should =~ /\/FoRtMidi.obj/
187
+ end
188
+
189
+ it 'predefines __WINDOWS_MM__' do
190
+ cl_compiler.compile_rtmidi
191
+ cl_compiler.command.should =~ /\/D__WINDOWS_MM__/
192
+ end
193
+ end
194
+ end
195
+
196
+
197
+ describe '#compile_ruby_rtmidi_wrapper' do
198
+
199
+ it 'changes the current director to the ext_dir' do
200
+ for compiler in compilers
201
+ compiler.compile_ruby_rtmidi_wrapper
202
+ compiler.current_dir.should == ext_dir
203
+ end
204
+ end
205
+
206
+ it 'runs a single command' do
207
+ for compiler in compilers
208
+ compiler.compile_ruby_rtmidi_wrapper
209
+ compiler.commands.length.should == 1
210
+ end
211
+ end
212
+
213
+ context 'with gcc' do
214
+ it 'runs g++' do
215
+ for compiler in gcc_compilers
216
+ compiler.compile_ruby_rtmidi_wrapper
217
+ compiler.command[0..2].should == 'g++'
218
+ end
219
+ end
220
+
221
+ it 'includes the rtmidi_dir' do
222
+ for compiler in gcc_compilers
223
+ compiler.compile_ruby_rtmidi_wrapper
224
+ compiler.command.should =~ /\s-I#{rtmidi_dir}\b/
225
+ end
226
+ end
227
+
228
+ it 'compiles ruby-rtmidi.cpp' do
229
+ for compiler in gcc_compilers
230
+ compiler.compile_ruby_rtmidi_wrapper
231
+ compiler.command.should =~ /\s-c\s+ruby-rtmidi\.cpp\b/
232
+ end
233
+ end
234
+
235
+ it 'outputs ruby-rtmidi.o' do
236
+ for compiler in gcc_compilers
237
+ compiler.compile_ruby_rtmidi_wrapper
238
+ compiler.command.should =~ /\s-o\s+ruby-rtmidi\.o\b/
239
+ end
240
+ end
241
+ end
242
+
243
+ context 'with cl.exe' do
244
+ it 'runs cl' do
245
+ cl_compiler.compile_ruby_rtmidi_wrapper
246
+ cl_compiler.command[0..1].should == 'cl'
247
+ end
248
+
249
+ it 'includes the rtmidi_dir' do
250
+ cl_compiler.compile_ruby_rtmidi_wrapper
251
+ cl_compiler.command.should =~ /\s\/I#{rtmidi_dir}\b/
252
+ end
253
+
254
+ it 'compiles ruby-rtmidi.cpp' do
255
+ cl_compiler.compile_ruby_rtmidi_wrapper
256
+ cl_compiler.command.should =~ /\s\/c\s+ruby-rtmidi\.cpp\b/
257
+ end
258
+
259
+ it 'outputs ruby-rtmidi.obj' do
260
+ cl_compiler.compile_ruby_rtmidi_wrapper
261
+ cl_compiler.command.should =~ /\s\/Foruby-rtmidi\.obj\b/
262
+ end
263
+
264
+ it 'predefines __RUBY_RTMIDI_DLL__' do
265
+ cl_compiler.compile_ruby_rtmidi_wrapper
266
+ cl_compiler.command.should =~ /\s\/D__RUBY_RTMIDI_DLL__\b/
267
+ end
268
+ end
269
+ end
270
+
271
+
272
+ describe '#create_shared_library' do
273
+
274
+ it 'changes the current director to the ext_dir' do
275
+ for compiler in compilers
276
+ compiler.create_shared_library
277
+ compiler.current_dir.should == ext_dir
278
+ end
279
+ end
280
+
281
+ it 'runs a single command' do
282
+ for compiler in compilers
283
+ compiler.create_shared_library
284
+ compiler.commands.length.should == 1
285
+ end
286
+ end
287
+
288
+ context 'with gcc' do
289
+ it 'runs g++' do
290
+ for compiler in gcc_compilers
291
+ compiler.create_shared_library
292
+ compiler.command[0..2].should == 'g++'
293
+ end
294
+ end
295
+
296
+ it 'includes the rtmidi_dir' do
297
+ for compiler in gcc_compilers
298
+ compiler.create_shared_library
299
+ compiler.command.should =~ /\s-I#{rtmidi_dir}\b/
300
+ end
301
+ end
302
+
303
+ it 'includes the rtmidi_dir/include folder' do
304
+ for compiler in gcc_compilers
305
+ compiler.create_shared_library
306
+ compiler.command.should =~ /\s-I#{rtmidi_dir}\/include\b/
307
+ end
308
+ end
309
+
310
+ it 'creates a shared library' do
311
+ for compiler in gcc_compilers
312
+ compiler.create_shared_library
313
+ compiler.command.should =~ /\s-shared\b/
314
+ end
315
+ end
316
+
317
+ it 'uses the output from the previous compilation steps' do
318
+ for compiler in gcc_compilers
319
+ compiler.create_shared_library
320
+ compiler.command.should =~ /\sruby-rtmidi\.o\s+#{rtmidi_dir}\/RtMidi\.o\b/
321
+ end
322
+ end
323
+
324
+ it 'outputs ruby-rtmidi.so' do
325
+ for compiler in gcc_compilers
326
+ compiler.create_shared_library
327
+ compiler.command.should =~ /\s-o\s+ruby-rtmidi\.so\b/
328
+ end
329
+ end
330
+
331
+ context 'on osx' do
332
+ it 'predefines __MACOSX_CORE__' do
333
+ osx_compiler.create_shared_library
334
+ osx_compiler.command.should =~ /\s-D__MACOSX_CORE__\b/
335
+ end
336
+
337
+ it 'includes the system libs: -framework CoreMIDI -framework CoreAudio -framework CoreFoundation' do
338
+ osx_compiler.create_shared_library
339
+ osx_compiler.command.should =~ /\s-framework\s+CoreMIDI\s+-framework\s+CoreAudio\s+-framework\s+CoreFoundation\b/
340
+ end
341
+ end
342
+
343
+ context 'on windows' do
344
+ it 'predefines __WINDOWS_MM__' do
345
+ windows_gcc_compiler.create_shared_library
346
+ windows_gcc_compiler.command.should =~ /\s-D__WINDOWS_MM__\b/
347
+ end
348
+
349
+ it 'includes the system lib winmm' do
350
+ windows_gcc_compiler.create_shared_library
351
+ windows_gcc_compiler.command.should =~ /\s-lwinmm\b/
352
+ end
353
+ end
354
+
355
+ context 'on linux' do
356
+ context 'with ALSA' do
357
+ it 'predefines __LINUX_ALSA__' do
358
+ linux_alsa_compiler.create_shared_library
359
+ linux_alsa_compiler.command.should =~ /\s-D__LINUX_ALSA__\b/
360
+ end
361
+
362
+ it 'includes the system lib for alsa' do
363
+ linux_alsa_compiler.create_shared_library
364
+ linux_alsa_compiler.command.should =~ /\slibalsa\b/
365
+ end
366
+ end
367
+
368
+ context 'with JACK' do
369
+ it 'predefines __UNIX_JACK__' do
370
+ linux_jack_compiler.create_shared_library
371
+ linux_jack_compiler.command.should =~ /\s-D__UNIX_JACK__\b/
372
+ end
373
+
374
+ it 'includes the system lib for jack' do
375
+ linux_jack_compiler.create_shared_library
376
+ linux_jack_compiler.command.should =~ /\slibjack\b/
377
+ end
378
+ end
379
+ end
380
+ end
381
+
382
+ context 'with cl.exe' do
383
+ it 'runs cl' do
384
+ cl_compiler.create_shared_library
385
+ cl_compiler.command[0..1].should == 'cl'
386
+ end
387
+
388
+ it 'includes the subfolder named include' do
389
+ cl_compiler.create_shared_library
390
+ cl_compiler.command.should =~ /\s\/I#{rtmidi_dir}\b/
391
+ end
392
+
393
+ it 'includes the rtmidi_dir/include folder' do
394
+ cl_compiler.create_shared_library
395
+ cl_compiler.command.should =~ /\s\/I#{rtmidi_dir}\/include\b/
396
+ end
397
+
398
+ it 'uses the output from the previous compilation steps' do
399
+ cl_compiler.create_shared_library
400
+ cl_compiler.command.should =~ /\sruby-rtmidi\.obj\s+#{rtmidi_dir}\/RtMidi\.obj\b/
401
+ end
402
+
403
+ it 'creates a DLL' do
404
+ cl_compiler.create_shared_library
405
+ cl_compiler.command.should =~ /\s\/LD\b/
406
+ end
407
+
408
+ it 'predefines __WINDOWS_MM__' do
409
+ cl_compiler.create_shared_library
410
+ cl_compiler.command.should =~ /\s\/D__WINDOWS_MM__\b/
411
+ end
412
+
413
+ it 'includes the system lib winmm' do
414
+ cl_compiler.create_shared_library
415
+ cl_compiler.command.should =~ /\bwinmm\.lib\b/
416
+ end
417
+ end
418
+ end
419
+
420
+
421
+ describe '#compile' do
422
+ it 'runs #compile_rtmidi, #compile_ruby_rtmidi_wrapper, and #create_shared_library' do
423
+ for compiler in compilers
424
+ compiler.compile
425
+ commands = compiler.commands.dup
426
+
427
+ compiler.commands.clear
428
+ compiler.compile_rtmidi
429
+ compiler.compile_ruby_rtmidi_wrapper
430
+ compiler.create_shared_library
431
+
432
+ commands.length.should == 3
433
+ commands.should == compiler.commands
434
+ end
435
+ end
436
+ end
437
+
438
+ end
@@ -0,0 +1,130 @@
1
+ require 'spec_helper'
2
+
3
+ describe RtMidi::Build::System do
4
+
5
+ class SystemIncluder
6
+ include RtMidi::Build::System
7
+ end
8
+
9
+ subject { SystemIncluder.new }
10
+
11
+ def stub_osx
12
+ RbConfig::CONFIG['host_os'] = 'darwin12.4.0'
13
+ end
14
+
15
+ def stub_windows
16
+ RbConfig::CONFIG['host_os'] = 'mswin'
17
+ end
18
+
19
+ def stub_mingw
20
+ RbConfig::CONFIG['host_os'] = 'mingw32'
21
+ end
22
+
23
+ def stub_linux
24
+ RbConfig::CONFIG['host_os'] = 'linux'
25
+ end
26
+
27
+
28
+ describe '#platform' do
29
+ it 'returns :osx on OS X' do
30
+ stub_osx
31
+ subject.platform.should == :osx
32
+ end
33
+
34
+ it 'returns :windows on Windows' do
35
+ stub_windows
36
+ subject.platform.should == :windows
37
+ end
38
+
39
+ it 'returns :windows under MinGW on Windows' do
40
+ stub_mingw
41
+ subject.platform.should == :windows
42
+ end
43
+
44
+ it 'returns :linux on Linux' do
45
+ stub_linux
46
+ subject.platform.should == :linux
47
+ end
48
+ end
49
+
50
+ describe '#osx?' do
51
+ it 'returns true on OS X' do
52
+ stub_osx
53
+ subject.osx?.should be_true
54
+ end
55
+
56
+ it 'returns false otherwise' do
57
+ [->{stub_windows}, ->{stub_mingw}, ->{stub_linux}].each do |stubber|
58
+ stubber.call
59
+ subject.osx?.should be_false
60
+ end
61
+ end
62
+ end
63
+
64
+ describe '#windows?' do
65
+ it 'returns true on Windows' do
66
+ [->{stub_windows}, ->{stub_mingw}].each do |stubber|
67
+ stubber.call
68
+ subject.windows?.should be_true
69
+ end
70
+ end
71
+
72
+ it 'returns false otherwise' do
73
+ [->{stub_osx}, ->{stub_linux}].each do |stubber|
74
+ stubber.call
75
+ subject.windows?.should be_false
76
+ end
77
+ end
78
+ end
79
+
80
+ describe '#linux?' do
81
+ it 'returns true on Linux' do
82
+ stub_linux
83
+ subject.linux?.should be_true
84
+ end
85
+
86
+ it 'returns false otherwise' do
87
+ [->{stub_osx}, ->{stub_windows}, ->{stub_mingw}].each do |stubber|
88
+ stubber.call
89
+ subject.linux?.should be_false
90
+ end
91
+ end
92
+ end
93
+
94
+ describe 'cd' do
95
+ it 'calls Dir.chdir' do
96
+ s = subject
97
+ s.stub(:puts) # suppress output
98
+ Dir.stub(:chdir).with 'foo'
99
+ s.cd 'foo'
100
+ end
101
+ end
102
+
103
+ describe 'can_run' do
104
+ it 'calls find_executable' do
105
+ s = subject
106
+ s.stub(:find_executable).with 'foo'
107
+ s.can_run 'foo'
108
+ end
109
+ end
110
+
111
+ describe 'run' do
112
+ it 'calls system() to run the command' do
113
+ s = subject
114
+ s.stub(:puts) # suppress output
115
+ s.stub(:system).with('foo').and_return true
116
+ s.run 'foo'
117
+ end
118
+
119
+ it 'calls exits with $?.exitstatus when system() returns false' do
120
+ s = subject
121
+ s.stub(:puts) # suppress output
122
+ s.stub(:system).with('foo').and_return false
123
+ allow_message_expectations_on_nil
124
+ $?.stub(:exitstatus).and_return :status
125
+ s.stub(:exit).with :status
126
+ s.run 'foo'
127
+ end
128
+ end
129
+
130
+ end