win 0.1.27 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,342 +1,342 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
- require 'win/library'
3
-
4
- module WinLibraryTest
5
-
6
- include WinTest
7
-
8
- module MyLib # namespace for defined functions
9
- include Win::Library
10
- end
11
- include MyLib
12
-
13
- def should_be symbol, api
14
- case symbol
15
- when :find_window
16
- #api.dll_name.should == 'user32' # The name of the DLL that exports the API function
17
- api.effective_function_name.should == 'FindWindowA' # Actual function returned by the constructor: 'GetUserName' ->'GetUserNameA' or 'GetUserNameW'
18
- api.function_name.should == :FindWindow # The name of the function passed to the constructor
19
- api.prototype.should == [:pointer, :pointer] # The prototype, returned as an array of characters
20
- api.return_type.should == :ulong # The prototype, returned as an array of characters
21
- end
22
- end
23
-
24
- def should_count_args(*methods, rights, wrongs)
25
- rights = [rights].flatten
26
- wrongs = [wrongs].flatten
27
- methods.each do |method|
28
- (0..8).each do |n|
29
- if n == rights.size
30
- expect {send method, *rights}.to_not raise_error
31
- else
32
- args = (1..n).map {wrongs[rand(wrongs.size)]}
33
- expect {send method, *args}.
34
- to raise_error "wrong number of arguments (#{args.size} for #{rights.size})"
35
- end
36
- end
37
- end
38
- end
39
-
40
- def any_handle
41
- MyLib.function :FindWindow, 'PP', 'L' unless respond_to? :find_window
42
- find_window(nil, nil)
43
- end
44
-
45
- def redefined_methods
46
- [:FindWindow, :IsWindow, :EnumWindows, :GetComputerName, :GetForegroundWindow]
47
- end
48
-
49
- def hide_method(*names) # hide original method(s) if it is defined
50
- names.map(&:to_s).each do |name|
51
- MyLib.module_eval do
52
- # + remove_const
53
- aliases = generate_names(name).flatten + [name]
54
- aliases.map(&:to_s).each do |ali|
55
- if method_defined? ali
56
- alias_method "original_#{ali}".to_sym, ali
57
- remove_method ali
58
- end
59
- end
60
- end
61
- end
62
- end
63
-
64
- def restore_method(*names) # restore original method if it was hidden
65
- names.map(&:to_s).each do |name|
66
- MyLib.module_eval do
67
- aliases = generate_names(name).flatten + [name]
68
- aliases.map(&:to_s).each do |ali|
69
- temp = "original_#{ali}".to_sym
70
- if method_defined? temp
71
- alias_method ali, temp
72
- remove_method temp
73
- end
74
- end
75
- end
76
- end
77
- end
78
-
79
- describe Win::Library, ' defines wrappers for Win32::API functions' do
80
-
81
- before(:each) { hide_method *redefined_methods } # hide original methods if defined
82
- after(:each) { restore_method *redefined_methods } # restore original methods if hidden
83
- context '::function' do
84
- context 'defining enhanced API function method' do
85
- spec{ use{ MyLib.function(:FindWindow, 'PP', 'l', rename: nil, aliases: nil, boolean: nil, zeronil: nil, &any_block) }}
86
-
87
- it 'defines new instance methods with appropriate names' do
88
- MyLib.function :FindWindow, 'PP', 'L'
89
- respond_to?(:FindWindow).should be_true
90
- respond_to?(:find_window).should be_true
91
- end
92
-
93
- it 'constructs argument prototype from uppercase string, enforces the args count' do
94
- expect { MyLib.function :FindWindow, 'PP', 'L' }.to_not raise_error
95
- should_count_args :find_window, :FindWindow, [nil, nil], [nil, TEST_IMPOSSIBLE, 'cmd']
96
- end
97
-
98
- it 'constructs argument prototype from (mixed) array, enforces the args count' do
99
- expect { MyLib.function :FindWindow, [:pointer, 'P'], 'L' }.to_not raise_error
100
- should_count_args :find_window, :FindWindow, [nil, nil], [nil, TEST_IMPOSSIBLE, 'cmd']
101
- end
102
-
103
- it 'with :rename option, overrides snake_case name for defined method but leaves CamelCase intact' do
104
- MyLib.function :FindWindow, 'PP', 'L', :rename=> 'my_own_find'
105
- expect {find_window(nil, nil)}.to raise_error NoMethodError
106
- expect {FindWindow(nil, nil)}.to_not raise_error
107
- expect {my_own_find(nil, nil)}.to_not raise_error
108
- end
109
-
110
- it 'defined snake_case method returns expected value when called' do
111
- MyLib.function :FindWindow, 'PP', 'L'
112
- find_window(nil, nil).should_not == 0
113
- find_window(nil, TEST_IMPOSSIBLE).should == 0
114
- find_window(TEST_IMPOSSIBLE, nil).should == 0
115
- find_window(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE).should == 0
116
- end
117
-
118
- it 'defined CamelCase method returns expected value when called' do
119
- MyLib.function :FindWindow, 'PP', 'L'
120
- FindWindow(nil, nil).should_not == 0
121
- FindWindow(nil, TEST_IMPOSSIBLE).should == 0
122
- FindWindow(TEST_IMPOSSIBLE, nil).should == 0
123
- FindWindow(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE).should == 0
124
- end
125
-
126
- # it 'returns underlying Win32::API object if defined method is called with (:api) argument ' do
127
- # MyLib.function :FindWindow, 'PP', 'L'
128
- # expect {find_window(:api)}.to_not raise_error
129
- # should_be :find_window, find_window(:api)
130
- # end
131
-
132
- it 'returns underlying Win32::API object' do
133
- FWAPI = MyLib.function :FindWindow, 'PP', 'L'
134
- should_be :find_window, FWAPI
135
- end
136
- end
137
-
138
- context 'defining aliases' do
139
- it 'adds alias for defined method with :alias option' do
140
- MyLib.function( :FindWindow, 'PP', 'L', :alias => 'my_own_find')
141
- expect {find_window(nil, nil)}.to_not raise_error
142
- expect {my_own_find(nil, nil)}.to_not raise_error
143
- end
144
-
145
- it 'adds aliases for defined method with :aliases option' do
146
- MyLib.function :FindWindow, 'PP', 'L', :aliases => ['my_own_find', 'my_own_find1']
147
- expect {find_window(nil, nil)}.to_not raise_error
148
- expect {my_own_find(nil, nil)}.to_not raise_error
149
- expect {my_own_find1(nil, nil)}.to_not raise_error
150
- end
151
-
152
- it 'adds Rubyesque alias to IsXxx API test function' do
153
- MyLib.function 'IsWindow', 'L', 'B'
154
- respond_to?(:window?).should be_true
155
- respond_to?(:is_window).should be_true
156
- end
157
-
158
- it 'adds Rubyesque alias to GetXxx API getter function' do
159
- MyLib.function 'GetComputerName', 'PP', 'I', :dll=> 'kernel32'
160
- respond_to?(:get_computer_name).should be_true
161
- respond_to?(:computer_name).should be_true
162
- end
163
- end
164
-
165
- context 'defining API with :boolean option converts result to boolean' do
166
- before(:each) { MyLib.function :FindWindow, 'PP', 'L', :boolean => true }
167
-
168
- it 'defines new instance method' do
169
- respond_to?(:find_window).should be_true
170
- respond_to?(:FindWindow).should be_true
171
- end
172
-
173
- it 'defined snake_case method returns false/true instead of zero/non-zero' do
174
- find_window(nil, nil).should == true
175
- find_window(nil, TEST_IMPOSSIBLE).should == false
176
- end
177
-
178
- it 'defined CamelCase method still returns zero/non-zero' do
179
- FindWindow(nil, nil).should_not == true
180
- FindWindow(nil, nil).should_not == 0
181
- FindWindow(nil, TEST_IMPOSSIBLE).should == 0
182
- end
183
-
184
- it 'defined methods enforce the argument count' do
185
- should_count_args :find_window, :FindWindow, [nil, nil], [nil, TEST_IMPOSSIBLE, 'cmd']
186
- end
187
- end
188
-
189
- context 'defining API with :zeronil option converts zero result to nil' do
190
- before(:each) {MyLib.function :FindWindow, 'PP', 'L', :zeronil => true}
191
-
192
- it 'defines new instance method' do
193
- respond_to?(:find_window).should be_true
194
- respond_to?(:FindWindow).should be_true
195
- end
196
-
197
- it 'defined CamelCase method still returns zero/non-zero' do
198
- FindWindow(nil, nil).should_not == true
199
- FindWindow(nil, nil).should_not == 0
200
- FindWindow(nil, TEST_IMPOSSIBLE).should == 0
201
- end
202
-
203
- it 'defined method returns nil (but NOT false) instead of zero' do
204
- find_window(nil, TEST_IMPOSSIBLE).should_not == false
205
- find_window(nil, TEST_IMPOSSIBLE).should == nil
206
- end
207
-
208
- it 'defined method does not return true when result is non-zero' do
209
- find_window(nil, nil).should_not == true
210
- find_window(nil, nil).should_not == 0
211
- end
212
-
213
- it 'defined methods enforce the argument count' do
214
- should_count_args :find_window, :FindWindow, [nil, nil], [nil, TEST_IMPOSSIBLE, 'cmd']
215
- end
216
- end
217
-
218
- context 'using DLL other than default user32 with :dll option' do
219
- before(:each) {MyLib.function 'GetComputerName', 'PP', 'I', :dll=> 'kernel32'}
220
-
221
- it 'defines new instance method with appropriate name' do
222
- respond_to?(:GetComputerName).should be_true
223
- respond_to?(:get_computer_name).should be_true
224
- respond_to?(:computer_name).should be_true
225
- end
226
-
227
- it 'returns expected result' do
228
- MyLib.function 'GetComputerName', ['P', 'P'], 'I', :dll=> 'kernel32'
229
- hostname = `hostname`.strip.upcase
230
- name = " " * 128
231
- get_computer_name(name, "128")
232
- name.unpack("A*").first.should == hostname
233
- end
234
- end
235
-
236
- context 'trying to define an invalid API function' do
237
- it 'raises error when trying to define function with a wrong function name' do
238
- expect { MyLib.function 'FindWindowImpossible', 'PP', 'L' }.
239
- to raise_error( /Function 'FindWindowImpossible' not found/ )
240
- end
241
- end
242
-
243
- context 'defining API function using definition block' do
244
- it 'defines new instance method' do
245
- MyLib.function( :FindWindow, 'PP', 'L' ){|api, *args|}
246
- respond_to?(:find_window).should be_true
247
- respond_to?(:FindWindow).should be_true
248
- end
249
-
250
- it 'does not enforce argument count outside of block' do
251
- MyLib.function( :FindWindow, 'PP', 'L' ){|api, *args|}
252
- expect { find_window }.to_not raise_error
253
- expect { find_window(nil) }.to_not raise_error
254
- expect { find_window(nil, 'Str', 1) }.to_not raise_error
255
- end
256
-
257
- it 'returns block return value when defined method is called' do
258
- MyLib.function( :FindWindow, 'PP', 'L' ){|api, *args| 'Value'}
259
- find_window(nil).should == 'Value'
260
- end
261
-
262
- it 'passes arguments and underlying Win32::API object to the block' do
263
- MyLib.function( :FindWindow, 'PP', 'L' ) do |api, *args|
264
- @api = api
265
- @args = args
266
- end
267
- expect {find_window(1, 2, 3) }.to_not raise_error
268
- @args.should == [1, 2, 3]
269
- should_be :find_window, @api
270
- end
271
-
272
- it ':rename option overrides standard name for defined method' do
273
- MyLib.function( :FindWindow, 'PP', 'L', :rename => 'my_own_find' ){|api, *args|}
274
- expect {find_window(nil, nil, nil)}.to raise_error
275
- expect {my_own_find(nil, nil)}.to_not raise_error
276
- end
277
-
278
- it 'adds alias for defined method with :alias option' do
279
- MyLib.function( :FindWindow, 'PP', 'L', :alias => 'my_own_find' ){|api, *args|}
280
- expect {find_window(nil, nil)}.to_not raise_error
281
- expect {my_own_find(nil, nil)}.to_not raise_error
282
- end
283
-
284
- it 'adds aliases for defined method with :aliases option' do
285
- MyLib.function( :FindWindow, 'PP', 'L', :aliases => ['my_own_find', 'my_own_find1'] ) {|api, *args|}
286
- expect {find_window(nil, nil)}.to_not raise_error
287
- expect {my_own_find(nil, nil)}.to_not raise_error
288
- expect {my_own_find1(nil, nil)}.to_not raise_error
289
- end
290
- end
291
-
292
- context 'calling defined methods with attached block to preprocess the API function results' do
293
- it 'defined method yields raw result to block attached to its invocation' do
294
- MyLib.function :FindWindow, 'PP', 'L', zeronil: true
295
- find_window(nil, TEST_IMPOSSIBLE) {|result| result.should == 0 }
296
- end
297
-
298
- it 'defined method returns result of block attached to its invocation' do
299
- MyLib.function :FindWindow, 'PP', 'L', zeronil: true
300
- return_value = find_window(nil, TEST_IMPOSSIBLE) {|result| 'Value'}
301
- return_value.should == 'Value'
302
- end
303
-
304
- it 'defined method transforms result of block before returning it' do
305
- MyLib.function :FindWindow, 'PP', 'L', zeronil: true
306
- return_value = find_window(nil, TEST_IMPOSSIBLE) {|result| 0 }
307
- return_value.should_not == 0
308
- return_value.should == nil
309
- end
310
- end
311
-
312
- context 'defining API function without arguments - f(VOID)' do
313
- it 'should enforce argument count to 0, NOT 1' do
314
- MyLib.function :GetForegroundWindow, [], 'L', zeronil: true
315
- should_count_args :GetForegroundWindow, :get_foreground_window, :foreground_window, [], [nil, 0, 123]
316
- end
317
- end
318
- end
319
-
320
- context '::callback defining API callback TYPES' do
321
- it '#callback macro creates a valid callback definition' do
322
- expect { MyLib.callback :MyEnumWindowsProc, [:HWND, :long], :bool}.to_not raise_error
323
- end
324
-
325
- it 'created callback definition can be used to define API function expecting callback' do
326
- expect {MyLib.function :EnumWindows, [:MyEnumWindowsProc, :long], :long}.to_not raise_error
327
- expect { enum_windows(lambda{|handle, message| true }, 0) }.to_not raise_error
328
- end
329
- end
330
-
331
- context '::try_function to define API function that are platform-specific' do
332
- if xp?
333
- it 'should silently fail to define function not present on current platform' do
334
- expect {MyLib.function :GetErrorMode, [], :UINT}.to raise_error /Function 'GetErrorMode' not found/
335
- expect {MyLib.try_function :GetErrorMode, [], :UINT}.to_not raise_error
336
- expect { GetErrorMode() }.to raise_error /undefined method `GetErrorMode'/
337
- expect { get_error_mode() }.to raise_error /undefined method `get_error_mode'/
338
- end
339
- end
340
- end
341
- end
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'win/library'
3
+
4
+ module WinLibraryTest
5
+
6
+ include WinTest
7
+
8
+ module MyLib # namespace for defined functions
9
+ include Win::Library
10
+ end
11
+ include MyLib
12
+
13
+ def should_be symbol, api
14
+ case symbol
15
+ when :find_window
16
+ #api.dll_name.should == 'user32' # The name of the DLL that exports the API function
17
+ api.effective_function_name.should == 'FindWindowA' # Actual function returned by the constructor: 'GetUserName' ->'GetUserNameA' or 'GetUserNameW'
18
+ api.function_name.should == :FindWindow # The name of the function passed to the constructor
19
+ api.prototype.should == [:pointer, :pointer] # The prototype, returned as an array of characters
20
+ api.return_type.should == :ulong # The prototype, returned as an array of characters
21
+ end
22
+ end
23
+
24
+ def should_count_args(*methods, rights, wrongs)
25
+ rights = [rights].flatten
26
+ wrongs = [wrongs].flatten
27
+ methods.each do |method|
28
+ (0..8).each do |n|
29
+ if n == rights.size
30
+ expect {send method, *rights}.to_not raise_error
31
+ else
32
+ args = (1..n).map {wrongs[rand(wrongs.size)]}
33
+ expect {send method, *args}.
34
+ to raise_error "wrong number of arguments (#{args.size} for #{rights.size})"
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def any_handle
41
+ MyLib.function :FindWindow, 'PP', 'L' unless respond_to? :find_window
42
+ find_window(nil, nil)
43
+ end
44
+
45
+ def redefined_methods
46
+ [:FindWindow, :IsWindow, :EnumWindows, :GetComputerName, :GetForegroundWindow]
47
+ end
48
+
49
+ def hide_method(*names) # hide original method(s) if it is defined
50
+ names.map(&:to_s).each do |name|
51
+ MyLib.module_eval do
52
+ # + remove_const
53
+ aliases = generate_names(name).flatten + [name]
54
+ aliases.map(&:to_s).each do |ali|
55
+ if method_defined? ali
56
+ alias_method "original_#{ali}".to_sym, ali
57
+ remove_method ali
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ def restore_method(*names) # restore original method if it was hidden
65
+ names.map(&:to_s).each do |name|
66
+ MyLib.module_eval do
67
+ aliases = generate_names(name).flatten + [name]
68
+ aliases.map(&:to_s).each do |ali|
69
+ temp = "original_#{ali}".to_sym
70
+ if method_defined? temp
71
+ alias_method ali, temp
72
+ remove_method temp
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ describe Win::Library, ' defines wrappers for Win32::API functions' do
80
+
81
+ before(:each) { hide_method *redefined_methods } # hide original methods if defined
82
+ after(:each) { restore_method *redefined_methods } # restore original methods if hidden
83
+ context '::function' do
84
+ context 'defining enhanced API function method' do
85
+ spec{ use{ MyLib.function(:FindWindow, 'PP', 'l', rename: nil, aliases: nil, boolean: nil, zeronil: nil, &any_block) }}
86
+
87
+ it 'defines new instance methods with appropriate names' do
88
+ MyLib.function :FindWindow, 'PP', 'L'
89
+ respond_to?(:FindWindow).should be_true
90
+ respond_to?(:find_window).should be_true
91
+ end
92
+
93
+ it 'constructs argument prototype from uppercase string, enforces the args count' do
94
+ expect { MyLib.function :FindWindow, 'PP', 'L' }.to_not raise_error
95
+ should_count_args :find_window, :FindWindow, [nil, nil], [nil, TEST_IMPOSSIBLE, 'cmd']
96
+ end
97
+
98
+ it 'constructs argument prototype from (mixed) array, enforces the args count' do
99
+ expect { MyLib.function :FindWindow, [:pointer, 'P'], 'L' }.to_not raise_error
100
+ should_count_args :find_window, :FindWindow, [nil, nil], [nil, TEST_IMPOSSIBLE, 'cmd']
101
+ end
102
+
103
+ it 'with :rename option, overrides snake_case name for defined method but leaves CamelCase intact' do
104
+ MyLib.function :FindWindow, 'PP', 'L', :rename=> 'my_own_find'
105
+ expect {find_window(nil, nil)}.to raise_error NoMethodError
106
+ expect {FindWindow(nil, nil)}.to_not raise_error
107
+ expect {my_own_find(nil, nil)}.to_not raise_error
108
+ end
109
+
110
+ it 'defined snake_case method returns expected value when called' do
111
+ MyLib.function :FindWindow, 'PP', 'L'
112
+ find_window(nil, nil).should_not == 0
113
+ find_window(nil, TEST_IMPOSSIBLE).should == 0
114
+ find_window(TEST_IMPOSSIBLE, nil).should == 0
115
+ find_window(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE).should == 0
116
+ end
117
+
118
+ it 'defined CamelCase method returns expected value when called' do
119
+ MyLib.function :FindWindow, 'PP', 'L'
120
+ FindWindow(nil, nil).should_not == 0
121
+ FindWindow(nil, TEST_IMPOSSIBLE).should == 0
122
+ FindWindow(TEST_IMPOSSIBLE, nil).should == 0
123
+ FindWindow(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE).should == 0
124
+ end
125
+
126
+ # it 'returns underlying Win32::API object if defined method is called with (:api) argument ' do
127
+ # MyLib.function :FindWindow, 'PP', 'L'
128
+ # expect {find_window(:api)}.to_not raise_error
129
+ # should_be :find_window, find_window(:api)
130
+ # end
131
+
132
+ it 'returns underlying Win32::API object' do
133
+ FWAPI = MyLib.function :FindWindow, 'PP', 'L'
134
+ should_be :find_window, FWAPI
135
+ end
136
+ end
137
+
138
+ context 'defining aliases' do
139
+ it 'adds alias for defined method with :alias option' do
140
+ MyLib.function( :FindWindow, 'PP', 'L', :alias => 'my_own_find')
141
+ expect {find_window(nil, nil)}.to_not raise_error
142
+ expect {my_own_find(nil, nil)}.to_not raise_error
143
+ end
144
+
145
+ it 'adds aliases for defined method with :aliases option' do
146
+ MyLib.function :FindWindow, 'PP', 'L', :aliases => ['my_own_find', 'my_own_find1']
147
+ expect {find_window(nil, nil)}.to_not raise_error
148
+ expect {my_own_find(nil, nil)}.to_not raise_error
149
+ expect {my_own_find1(nil, nil)}.to_not raise_error
150
+ end
151
+
152
+ it 'adds Rubyesque alias to IsXxx API test function' do
153
+ MyLib.function 'IsWindow', 'L', 'B'
154
+ respond_to?(:window?).should be_true
155
+ respond_to?(:is_window).should be_true
156
+ end
157
+
158
+ it 'adds Rubyesque alias to GetXxx API getter function' do
159
+ MyLib.function 'GetComputerName', 'PP', 'I', :dll=> 'kernel32'
160
+ respond_to?(:get_computer_name).should be_true
161
+ respond_to?(:computer_name).should be_true
162
+ end
163
+ end
164
+
165
+ context 'defining API with :boolean option converts result to boolean' do
166
+ before(:each) { MyLib.function :FindWindow, 'PP', 'L', :boolean => true }
167
+
168
+ it 'defines new instance method' do
169
+ respond_to?(:find_window).should be_true
170
+ respond_to?(:FindWindow).should be_true
171
+ end
172
+
173
+ it 'defined snake_case method returns false/true instead of zero/non-zero' do
174
+ find_window(nil, nil).should == true
175
+ find_window(nil, TEST_IMPOSSIBLE).should == false
176
+ end
177
+
178
+ it 'defined CamelCase method still returns zero/non-zero' do
179
+ FindWindow(nil, nil).should_not == true
180
+ FindWindow(nil, nil).should_not == 0
181
+ FindWindow(nil, TEST_IMPOSSIBLE).should == 0
182
+ end
183
+
184
+ it 'defined methods enforce the argument count' do
185
+ should_count_args :find_window, :FindWindow, [nil, nil], [nil, TEST_IMPOSSIBLE, 'cmd']
186
+ end
187
+ end
188
+
189
+ context 'defining API with :zeronil option converts zero result to nil' do
190
+ before(:each) {MyLib.function :FindWindow, 'PP', 'L', :zeronil => true}
191
+
192
+ it 'defines new instance method' do
193
+ respond_to?(:find_window).should be_true
194
+ respond_to?(:FindWindow).should be_true
195
+ end
196
+
197
+ it 'defined CamelCase method still returns zero/non-zero' do
198
+ FindWindow(nil, nil).should_not == true
199
+ FindWindow(nil, nil).should_not == 0
200
+ FindWindow(nil, TEST_IMPOSSIBLE).should == 0
201
+ end
202
+
203
+ it 'defined method returns nil (but NOT false) instead of zero' do
204
+ find_window(nil, TEST_IMPOSSIBLE).should_not == false
205
+ find_window(nil, TEST_IMPOSSIBLE).should == nil
206
+ end
207
+
208
+ it 'defined method does not return true when result is non-zero' do
209
+ find_window(nil, nil).should_not == true
210
+ find_window(nil, nil).should_not == 0
211
+ end
212
+
213
+ it 'defined methods enforce the argument count' do
214
+ should_count_args :find_window, :FindWindow, [nil, nil], [nil, TEST_IMPOSSIBLE, 'cmd']
215
+ end
216
+ end
217
+
218
+ context 'using DLL other than default user32 with :dll option' do
219
+ before(:each) {MyLib.function 'GetComputerName', 'PP', 'I', :dll=> 'kernel32'}
220
+
221
+ it 'defines new instance method with appropriate name' do
222
+ respond_to?(:GetComputerName).should be_true
223
+ respond_to?(:get_computer_name).should be_true
224
+ respond_to?(:computer_name).should be_true
225
+ end
226
+
227
+ it 'returns expected result' do
228
+ MyLib.function 'GetComputerName', ['P', 'P'], 'I', :dll=> 'kernel32'
229
+ hostname = `hostname`.strip.upcase
230
+ name = " " * 128
231
+ get_computer_name(name, "128")
232
+ name.unpack("A*").first.should == hostname
233
+ end
234
+ end
235
+
236
+ context 'trying to define an invalid API function' do
237
+ it 'raises error when trying to define function with a wrong function name' do
238
+ expect { MyLib.function 'FindWindowImpossible', 'PP', 'L' }.
239
+ to raise_error( /Function 'FindWindowImpossible' not found/ )
240
+ end
241
+ end
242
+
243
+ context 'defining API function using definition block' do
244
+ it 'defines new instance method' do
245
+ MyLib.function( :FindWindow, 'PP', 'L' ){|api, *args|}
246
+ respond_to?(:find_window).should be_true
247
+ respond_to?(:FindWindow).should be_true
248
+ end
249
+
250
+ it 'does not enforce argument count outside of block' do
251
+ MyLib.function( :FindWindow, 'PP', 'L' ){|api, *args|}
252
+ expect { find_window }.to_not raise_error
253
+ expect { find_window(nil) }.to_not raise_error
254
+ expect { find_window(nil, 'Str', 1) }.to_not raise_error
255
+ end
256
+
257
+ it 'returns block return value when defined method is called' do
258
+ MyLib.function( :FindWindow, 'PP', 'L' ){|api, *args| 'Value'}
259
+ find_window(nil).should == 'Value'
260
+ end
261
+
262
+ it 'passes arguments and underlying Win32::API object to the block' do
263
+ MyLib.function( :FindWindow, 'PP', 'L' ) do |api, *args|
264
+ @api = api
265
+ @args = args
266
+ end
267
+ expect {find_window(1, 2, 3) }.to_not raise_error
268
+ @args.should == [1, 2, 3]
269
+ should_be :find_window, @api
270
+ end
271
+
272
+ it ':rename option overrides standard name for defined method' do
273
+ MyLib.function( :FindWindow, 'PP', 'L', :rename => 'my_own_find' ){|api, *args|}
274
+ expect {find_window(nil, nil, nil)}.to raise_error
275
+ expect {my_own_find(nil, nil)}.to_not raise_error
276
+ end
277
+
278
+ it 'adds alias for defined method with :alias option' do
279
+ MyLib.function( :FindWindow, 'PP', 'L', :alias => 'my_own_find' ){|api, *args|}
280
+ expect {find_window(nil, nil)}.to_not raise_error
281
+ expect {my_own_find(nil, nil)}.to_not raise_error
282
+ end
283
+
284
+ it 'adds aliases for defined method with :aliases option' do
285
+ MyLib.function( :FindWindow, 'PP', 'L', :aliases => ['my_own_find', 'my_own_find1'] ) {|api, *args|}
286
+ expect {find_window(nil, nil)}.to_not raise_error
287
+ expect {my_own_find(nil, nil)}.to_not raise_error
288
+ expect {my_own_find1(nil, nil)}.to_not raise_error
289
+ end
290
+ end
291
+
292
+ context 'calling defined methods with attached block to preprocess the API function results' do
293
+ it 'defined method yields raw result to block attached to its invocation' do
294
+ MyLib.function :FindWindow, 'PP', 'L', zeronil: true
295
+ find_window(nil, TEST_IMPOSSIBLE) {|result| result.should == 0 }
296
+ end
297
+
298
+ it 'defined method returns result of block attached to its invocation' do
299
+ MyLib.function :FindWindow, 'PP', 'L', zeronil: true
300
+ return_value = find_window(nil, TEST_IMPOSSIBLE) {|result| 'Value'}
301
+ return_value.should == 'Value'
302
+ end
303
+
304
+ it 'defined method transforms result of block before returning it' do
305
+ MyLib.function :FindWindow, 'PP', 'L', zeronil: true
306
+ return_value = find_window(nil, TEST_IMPOSSIBLE) {|result| 0 }
307
+ return_value.should_not == 0
308
+ return_value.should == nil
309
+ end
310
+ end
311
+
312
+ context 'defining API function without arguments - f(VOID)' do
313
+ it 'should enforce argument count to 0, NOT 1' do
314
+ MyLib.function :GetForegroundWindow, [], 'L', zeronil: true
315
+ should_count_args :GetForegroundWindow, :get_foreground_window, :foreground_window, [], [nil, 0, 123]
316
+ end
317
+ end
318
+ end
319
+
320
+ context '::callback defining API callback TYPES' do
321
+ it '#callback macro creates a valid callback definition' do
322
+ expect { MyLib.callback :MyEnumWindowsProc, [:HWND, :long], :bool}.to_not raise_error
323
+ end
324
+
325
+ it 'created callback definition can be used to define API function expecting callback' do
326
+ expect {MyLib.function :EnumWindows, [:MyEnumWindowsProc, :long], :long}.to_not raise_error
327
+ expect { enum_windows(lambda{|handle, message| true }, 0) }.to_not raise_error
328
+ end
329
+ end
330
+
331
+ context '::try_function to define API function that are platform-specific' do
332
+ if xp?
333
+ it 'should silently fail to define function not present on current platform' do
334
+ expect {MyLib.function :GetErrorMode, [], :UINT}.to raise_error /Function 'GetErrorMode' not found/
335
+ expect {MyLib.try_function :GetErrorMode, [], :UINT}.to_not raise_error
336
+ expect { GetErrorMode() }.to raise_error /undefined method `GetErrorMode'/
337
+ expect { get_error_mode() }.to raise_error /undefined method `get_error_mode'/
338
+ end
339
+ end
340
+ end
341
+ end
342
342
  end