rtmidi 0.2.2 → 0.3

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