win 0.1.27 → 0.3.1
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/.document +5 -5
- data/.gitignore +21 -21
- data/LICENSE +20 -20
- data/README.rdoc +175 -175
- data/Rakefile +58 -58
- data/VERSION +1 -1
- data/features/support/env.rb +4 -4
- data/features/win.feature +9 -9
- data/lib/win/dde.rb +1234 -1234
- data/lib/win/error.rb +1223 -1223
- data/lib/win/extensions.rb +41 -41
- data/lib/win/gui.rb +16 -16
- data/lib/win/gui/dialog.rb +50 -50
- data/lib/win/gui/input.rb +319 -319
- data/lib/win/gui/message.rb +807 -807
- data/lib/win/gui/window.rb +679 -679
- data/lib/win/library.rb +463 -463
- data/spec/spec.opts +2 -2
- data/spec/spec_helper.rb +140 -135
- data/spec/test_apps/locknote/LockNote.exe +0 -0
- data/spec/win/dde_spec.rb +528 -528
- data/spec/win/error_spec.rb +112 -112
- data/spec/win/extensions_spec.rb +73 -73
- data/spec/win/gui/dialog_spec.rb +43 -43
- data/spec/win/gui/input_spec.rb +101 -101
- data/spec/win/gui/message_spec.rb +236 -236
- data/spec/win/gui/window_spec.rb +549 -548
- data/spec/win/library_spec.rb +341 -341
- data/win.gemspec +87 -87
- metadata +34 -17
data/spec/win/library_spec.rb
CHANGED
@@ -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
|