win 0.3.11 → 0.3.16
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/HISTORY +20 -0
- data/VERSION +1 -1
- data/lib/win/gui/dialog.rb +30 -30
- data/lib/win/gui/input.rb +0 -1
- data/lib/win/gui/message.rb +25 -2
- data/lib/win/library.rb +114 -70
- data/lib/win/system/info.rb +163 -0
- data/lib/win/system/version.rb +571 -0
- data/spec/spec_helper.rb +15 -3
- data/spec/win/error_spec.rb +2 -2
- data/spec/win/gui/message_spec.rb +23 -7
- data/spec/win/library_spec.rb +181 -155
- data/spec/win/system/info_spec.rb +47 -0
- data/spec/win/system/version_spec.rb +169 -0
- metadata +9 -3
data/spec/spec_helper.rb
CHANGED
@@ -61,14 +61,22 @@ def os
|
|
61
61
|
@os_flag ||= cygwin? ? `cmd /c ver` : `ver`
|
62
62
|
end
|
63
63
|
|
64
|
-
def
|
65
|
-
os =~ /Version
|
64
|
+
def os_2000?
|
65
|
+
os =~ /Version 5.0/
|
66
66
|
end
|
67
67
|
|
68
|
-
def
|
68
|
+
def os_xp?
|
69
69
|
os =~ /XP/
|
70
70
|
end
|
71
71
|
|
72
|
+
def os_vista?
|
73
|
+
os =~ /Version 6.0/
|
74
|
+
end
|
75
|
+
|
76
|
+
def os_7?
|
77
|
+
os =~ /Version 6.1/
|
78
|
+
end
|
79
|
+
|
72
80
|
module WinTest
|
73
81
|
|
74
82
|
KEY_DELAY = 0.001
|
@@ -96,6 +104,10 @@ module WinTest
|
|
96
104
|
def buffer
|
97
105
|
FFI::MemoryPointer.new(:char, 1024)
|
98
106
|
end
|
107
|
+
|
108
|
+
def pointer(type=:long, num=1)
|
109
|
+
FFI::MemoryPointer.new(type, num)
|
110
|
+
end
|
99
111
|
end
|
100
112
|
|
101
113
|
module WinTestApp
|
data/spec/win/error_spec.rb
CHANGED
@@ -69,7 +69,7 @@ module WinErrorTest
|
|
69
69
|
end
|
70
70
|
end # describe set_last_error
|
71
71
|
|
72
|
-
if
|
72
|
+
if os_xp? || os_vista? # This function works only on XP++
|
73
73
|
describe "#set_last_error_ex" do
|
74
74
|
spec{ use{ SetLastErrorEx(dw_err_code=0, dw_type=0) }}
|
75
75
|
spec{ use{ set_last_error_ex(dw_err_code=0, dw_type=0) }}
|
@@ -86,7 +86,7 @@ module WinErrorTest
|
|
86
86
|
end # describe set_last_error_ex
|
87
87
|
end
|
88
88
|
|
89
|
-
if
|
89
|
+
if os_vista? || os_7? # This function works only on Vista++
|
90
90
|
describe "#get_error_mode" do
|
91
91
|
spec{ use{ mode = GetErrorMode() }}
|
92
92
|
spec{ use{ mode = get_error_mode() }}
|
@@ -49,11 +49,27 @@ module WinGuiMessageTest
|
|
49
49
|
spec{ use{ success = PostMessage(handle = 0, msg = 0, w_param = 0, l_param = nil) }}
|
50
50
|
spec{ use{ success = post_message(handle = 0, msg = 0, w_param = 0, l_param = nil) }}
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
context 'places (posts) a message in the message queue associated with the thread that created the specified window' do
|
53
|
+
it 'with nil as last argument(lParam)' do
|
54
|
+
app = launch_test_app
|
55
|
+
post_message(app.handle, WM_SYSCOMMAND, SC_CLOSE, nil).should == true
|
56
|
+
sleep SLEEP_DELAY
|
57
|
+
window?(app.handle).should == false
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'with pointer as last argument(lParam)' do
|
61
|
+
app = launch_test_app
|
62
|
+
post_message(app.handle, WM_SYSCOMMAND, SC_CLOSE, FFI::MemoryPointer.new(:long)).should == true
|
63
|
+
sleep SLEEP_DELAY
|
64
|
+
window?(app.handle).should == false
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'with Fixnum as last argument(lParam)' do
|
68
|
+
app = launch_test_app
|
69
|
+
post_message(app.handle, WM_SYSCOMMAND, SC_CLOSE, 0).should == true
|
70
|
+
sleep SLEEP_DELAY
|
71
|
+
window?(app.handle).should == false
|
72
|
+
end
|
57
73
|
end
|
58
74
|
|
59
75
|
it 'places (posts) a message into current thread`s queue if first arg is 0' do
|
@@ -126,11 +142,11 @@ module WinGuiMessageTest
|
|
126
142
|
send_message_callback(not_a_handle, WM_USER, 0, nil){|*args|@data=args[2]}
|
127
143
|
sent.should == 0
|
128
144
|
get_last_error.should == "Invalid window handle."
|
129
|
-
|
145
|
+
end
|
130
146
|
end # describe send_message_callback
|
131
147
|
|
132
148
|
describe "#get_message" do
|
133
|
-
before(:all){clear_thread_queue; 2.times {post_message 0,0,0,nil}}
|
149
|
+
before(:all){clear_thread_queue; 2.times {post_message 0, 0, 0, nil}}
|
134
150
|
|
135
151
|
spec{ use{ res = GetMessage(msg, handle=0, msg_filter_min=0, msg_filter_max=0) }}
|
136
152
|
spec{ use{ message = get_message(msg, handle=0, msg_filter_min=0, msg_filter_max=0) }}
|
data/spec/win/library_spec.rb
CHANGED
@@ -13,8 +13,8 @@ module WinLibraryTest
|
|
13
13
|
def should_be symbol, api
|
14
14
|
case symbol
|
15
15
|
when :find_window
|
16
|
-
|
17
|
-
api.effective_function_name.should ==
|
16
|
+
api.dll.should include "user32" # The name of the DLL that exports the API function
|
17
|
+
api.effective_function_name.should == :FindWindowA # Actual function: 'GetUserName' ->'GetUserNameA' or 'GetUserNameW'
|
18
18
|
api.function_name.should == :FindWindow # The name of the function passed to the constructor
|
19
19
|
api.prototype.should == [:pointer, :pointer] # The prototype, returned as an array of characters
|
20
20
|
api.return_type.should == :ulong # The prototype, returned as an array of characters
|
@@ -43,13 +43,12 @@ module WinLibraryTest
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def redefined_methods
|
46
|
-
[:FindWindow, :IsWindow, :EnumWindows, :
|
46
|
+
[:FindWindow, :IsWindow, :EnumWindows, :GetUserName, :GetForegroundWindow, :keybd_event]
|
47
47
|
end
|
48
48
|
|
49
49
|
def hide_method(*names) # hide original method(s) if it is defined
|
50
50
|
names.map(&:to_s).each do |name|
|
51
51
|
MyLib.module_eval do
|
52
|
-
# + remove_const
|
53
52
|
aliases = generate_names(name).flatten + [name]
|
54
53
|
aliases.map(&:to_s).each do |ali|
|
55
54
|
if method_defined? ali
|
@@ -76,20 +75,162 @@ module WinLibraryTest
|
|
76
75
|
end
|
77
76
|
end
|
78
77
|
|
78
|
+
shared_examples_for 'defining macro with options' do
|
79
|
+
context 'basic behavior' do
|
80
|
+
it 'defines new instance methods with appropriate names' do
|
81
|
+
MyLib.function :FindWindow, 'PP', 'L', &@def_block
|
82
|
+
MyLib.respond_to?(:FindWindow).should be_true
|
83
|
+
respond_to?(:FindWindow).should be_true
|
84
|
+
MyLib.respond_to?(:find_window).should be_true
|
85
|
+
respond_to?(:find_window).should be_true
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'returns underlying Win32::API object' do
|
89
|
+
FWAPI = MyLib.function :FindWindow, 'PP', 'L', &@def_block
|
90
|
+
should_be :find_window, FWAPI
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'renaming and aliasing' do
|
95
|
+
it ':camel_name option overrides default CamelCase name for attached function but leaves snake_case intact' do
|
96
|
+
MyLib.function :FindWindow, 'PP', 'L', camel_name: 'MyOwnName', &@def_block
|
97
|
+
expect {find_window(nil, nil)}.to_not raise_error
|
98
|
+
expect {FindWindow(nil, nil)}.to raise_error NoMethodError
|
99
|
+
expect {MyOwnName(nil, nil)}.to_not raise_error
|
100
|
+
end
|
101
|
+
|
102
|
+
it ':snake_name option overrides default snake_case name for defined method but leaves CamelCase intact' do
|
103
|
+
MyLib.function :FindWindow, 'PP', 'L', snake_name: 'my_own_find', &@def_block
|
104
|
+
expect {find_window(nil, nil)}.to raise_error NoMethodError
|
105
|
+
expect {FindWindow(nil, nil)}.to_not raise_error
|
106
|
+
expect {my_own_find(nil, nil)}.to_not raise_error
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'both :snake_name and :camel_name option can be used in one declaration' do
|
110
|
+
MyLib.function :FindWindow, 'PP', 'L', camel_name: 'MyOwnName', snake_name: 'my_own_find', &@def_block
|
111
|
+
expect {find_window(nil, nil)}.to raise_error NoMethodError
|
112
|
+
expect {my_own_find(nil, nil)}.to_not raise_error
|
113
|
+
expect {FindWindow(nil, nil)}.to raise_error NoMethodError
|
114
|
+
expect {MyOwnName(nil, nil)}.to_not raise_error
|
115
|
+
end
|
116
|
+
|
117
|
+
it ':camel_only option means no snake_case method will be defined' do
|
118
|
+
MyLib.function :FindWindow, 'PP', 'L', camel_only: true, &@def_block
|
119
|
+
expect {find_window(nil, nil)}.to raise_error NoMethodError
|
120
|
+
expect {FindWindow(nil, nil)}.to_not raise_error
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'automatically adds Rubyesque alias to IsXxx API test function' do
|
124
|
+
MyLib.function 'IsWindow', 'L', 'B', &@def_block
|
125
|
+
respond_to?(:window?).should be_true
|
126
|
+
respond_to?(:is_window).should be_true
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'automatically adds Rubyesque alias to GetXxx API getter function' do
|
130
|
+
MyLib.function 'GetForegroundWindow', [], 'L', &@def_block
|
131
|
+
respond_to?(:get_foreground_window).should be_true
|
132
|
+
respond_to?(:foreground_window).should be_true
|
133
|
+
end
|
134
|
+
|
135
|
+
it ':alias option adds alias for defined snake_case method' do
|
136
|
+
MyLib.function( :FindWindow, 'PP', 'L', :alias => 'my_own_find', &@def_block)
|
137
|
+
expect {find_window(nil, nil)}.to_not raise_error
|
138
|
+
expect {my_own_find(nil, nil)}.to_not raise_error
|
139
|
+
end
|
140
|
+
|
141
|
+
it ':aliases option adds aliases for defined snake_case method' do
|
142
|
+
MyLib.function :FindWindow, 'PP', 'L', :aliases => ['my_own_find', 'my_own_find1'], &@def_block
|
143
|
+
expect {find_window(nil, nil)}.to_not raise_error
|
144
|
+
expect {my_own_find(nil, nil)}.to_not raise_error
|
145
|
+
expect {my_own_find1(nil, nil)}.to_not raise_error
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context ':boolean option converts result to boolean' do
|
150
|
+
before(:each) { MyLib.function :FindWindow, 'PP', 'L', :boolean => true, &@def_block }
|
151
|
+
|
152
|
+
it 'defines new instance method' do
|
153
|
+
respond_to?(:find_window).should be_true
|
154
|
+
respond_to?(:FindWindow).should be_true
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'defined snake_case method returns false/true instead of zero/non-zero' do
|
158
|
+
find_window(nil, nil).should == true
|
159
|
+
find_window(nil, IMPOSSIBLE).should == false
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'defined CamelCase method still returns zero/non-zero' do
|
163
|
+
FindWindow(nil, nil).should_not == true
|
164
|
+
FindWindow(nil, nil).should_not == 0
|
165
|
+
FindWindow(nil, IMPOSSIBLE).should == 0
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context 'defining API with :zeronil option converts zero result to nil' do
|
170
|
+
before(:each) {MyLib.function :FindWindow, 'PP', 'L', :zeronil => true, &@def_block}
|
171
|
+
|
172
|
+
it 'defines new instance method' do
|
173
|
+
respond_to?(:find_window).should be_true
|
174
|
+
respond_to?(:FindWindow).should be_true
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'defined CamelCase method still returns zero/non-zero' do
|
178
|
+
FindWindow(nil, nil).should_not == true
|
179
|
+
FindWindow(nil, nil).should_not == 0
|
180
|
+
FindWindow(nil, IMPOSSIBLE).should == 0
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'defined method returns nil (but NOT false) instead of zero' do
|
184
|
+
find_window(nil, IMPOSSIBLE).should_not == false
|
185
|
+
find_window(nil, IMPOSSIBLE).should == nil
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'defined method does not return true when result is non-zero' do
|
189
|
+
find_window(nil, nil).should_not == true
|
190
|
+
find_window(nil, nil).should_not == 0
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context 'using DLL other than default user32, kernel32 with :dll option' do
|
195
|
+
before(:each){ MyLib.function 'GetUserName', 'PP', 'I', :dll=> 'advapi32', &@def_block}
|
196
|
+
|
197
|
+
it 'defines new instance method with appropriate name' do
|
198
|
+
respond_to?(:GetUserName).should be_true
|
199
|
+
respond_to?(:get_user_name).should be_true
|
200
|
+
respond_to?(:user_name).should be_true
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'returns expected result' do
|
204
|
+
username = `echo %USERNAME%`.strip
|
205
|
+
name_ptr = FFI::MemoryPointer.from_string(" " * 128)
|
206
|
+
size_ptr = FFI::MemoryPointer.new(:long).write_int(name_ptr.size)
|
207
|
+
get_user_name(name_ptr, size_ptr)
|
208
|
+
name_ptr.read_string.strip.should == username
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
79
213
|
describe Win::Library, ' defines wrappers for Win32::API functions' do
|
80
214
|
|
81
215
|
before(:each) { hide_method *redefined_methods } # hide original methods if defined
|
82
216
|
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
217
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
218
|
+
describe '::attach_function - delegates to FFI::Library::attach_function' do
|
219
|
+
it 'can be used to attach same function with different signatures' do
|
220
|
+
MyLib.attach_function :send_one, :SendMessageA, [:ulong, :uint, :uint, :long], :int
|
221
|
+
MyLib.attach_function :send_two, :SendMessageA, [:ulong, :uint, :uint, :pointer], :int
|
222
|
+
respond_to?(:send_one).should be_true
|
223
|
+
respond_to?(:send_two).should be_true
|
224
|
+
MyLib.respond_to?(:send_one).should be_true
|
225
|
+
MyLib.respond_to?(:send_two).should be_true
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
describe '::function - attaches external API function and defines enhanced snake_case method on top of it' do
|
230
|
+
spec{ use{ MyLib.function(:FindWindow, 'PP', 'l', aliases: nil, boolean: nil, zeronil: nil, &any_block) }}
|
231
|
+
|
232
|
+
context 'defining enhanced API function without defenition block (using defaults)' do
|
233
|
+
it_should_behave_like 'defining macro with options'
|
93
234
|
|
94
235
|
it 'constructs argument prototype from uppercase string, enforces the args count' do
|
95
236
|
expect { MyLib.function :FindWindow, 'PP', 'L' }.to_not raise_error
|
@@ -101,13 +242,6 @@ module WinLibraryTest
|
|
101
242
|
should_count_args :find_window, :FindWindow, [nil, nil], [nil, IMPOSSIBLE, 'cmd']
|
102
243
|
end
|
103
244
|
|
104
|
-
it 'with :rename option, overrides snake_case name for defined method but leaves CamelCase intact' do
|
105
|
-
MyLib.function :FindWindow, 'PP', 'L', :rename=> 'my_own_find'
|
106
|
-
expect {find_window(nil, nil)}.to raise_error NoMethodError
|
107
|
-
expect {FindWindow(nil, nil)}.to_not raise_error
|
108
|
-
expect {my_own_find(nil, nil)}.to_not raise_error
|
109
|
-
end
|
110
|
-
|
111
245
|
it 'defined snake_case method returns expected value when called' do
|
112
246
|
MyLib.function :FindWindow, 'PP', 'L'
|
113
247
|
find_window(nil, nil).should_not == 0
|
@@ -130,123 +264,14 @@ module WinLibraryTest
|
|
130
264
|
# should_be :find_window, find_window(:api)
|
131
265
|
# end
|
132
266
|
|
133
|
-
it 'returns underlying Win32::API object' do
|
134
|
-
FWAPI = MyLib.function :FindWindow, 'PP', 'L'
|
135
|
-
should_be :find_window, FWAPI
|
136
|
-
end
|
137
267
|
end
|
138
268
|
|
139
|
-
context 'defining
|
140
|
-
|
141
|
-
|
142
|
-
expect {find_window(nil, nil)}.to_not raise_error
|
143
|
-
expect {my_own_find(nil, nil)}.to_not raise_error
|
269
|
+
context 'defining API function using explicit definition block' do
|
270
|
+
before(:each) do
|
271
|
+
@def_block = lambda{|api, *args| api.call(*args)} # Trivial define_block for shared examples
|
144
272
|
end
|
145
273
|
|
146
|
-
|
147
|
-
MyLib.function :FindWindow, 'PP', 'L', :aliases => ['my_own_find', 'my_own_find1']
|
148
|
-
expect {find_window(nil, nil)}.to_not raise_error
|
149
|
-
expect {my_own_find(nil, nil)}.to_not raise_error
|
150
|
-
expect {my_own_find1(nil, nil)}.to_not raise_error
|
151
|
-
end
|
152
|
-
|
153
|
-
it 'adds Rubyesque alias to IsXxx API test function' do
|
154
|
-
MyLib.function 'IsWindow', 'L', 'B'
|
155
|
-
respond_to?(:window?).should be_true
|
156
|
-
respond_to?(:is_window).should be_true
|
157
|
-
end
|
158
|
-
|
159
|
-
it 'adds Rubyesque alias to GetXxx API getter function' do
|
160
|
-
MyLib.function 'GetComputerName', 'PP', 'I', :dll=> 'kernel32'
|
161
|
-
respond_to?(:get_computer_name).should be_true
|
162
|
-
respond_to?(:computer_name).should be_true
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
context 'defining API with :boolean option converts result to boolean' do
|
167
|
-
before(:each) { MyLib.function :FindWindow, 'PP', 'L', :boolean => true }
|
168
|
-
|
169
|
-
it 'defines new instance method' do
|
170
|
-
respond_to?(:find_window).should be_true
|
171
|
-
respond_to?(:FindWindow).should be_true
|
172
|
-
end
|
173
|
-
|
174
|
-
it 'defined snake_case method returns false/true instead of zero/non-zero' do
|
175
|
-
find_window(nil, nil).should == true
|
176
|
-
find_window(nil, IMPOSSIBLE).should == false
|
177
|
-
end
|
178
|
-
|
179
|
-
it 'defined CamelCase method still returns zero/non-zero' do
|
180
|
-
FindWindow(nil, nil).should_not == true
|
181
|
-
FindWindow(nil, nil).should_not == 0
|
182
|
-
FindWindow(nil, IMPOSSIBLE).should == 0
|
183
|
-
end
|
184
|
-
|
185
|
-
it 'defined methods enforce the argument count' do
|
186
|
-
should_count_args :find_window, :FindWindow, [nil, nil], [nil, IMPOSSIBLE, 'cmd']
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
context 'defining API with :zeronil option converts zero result to nil' do
|
191
|
-
before(:each) {MyLib.function :FindWindow, 'PP', 'L', :zeronil => true}
|
192
|
-
|
193
|
-
it 'defines new instance method' do
|
194
|
-
respond_to?(:find_window).should be_true
|
195
|
-
respond_to?(:FindWindow).should be_true
|
196
|
-
end
|
197
|
-
|
198
|
-
it 'defined CamelCase method still returns zero/non-zero' do
|
199
|
-
FindWindow(nil, nil).should_not == true
|
200
|
-
FindWindow(nil, nil).should_not == 0
|
201
|
-
FindWindow(nil, IMPOSSIBLE).should == 0
|
202
|
-
end
|
203
|
-
|
204
|
-
it 'defined method returns nil (but NOT false) instead of zero' do
|
205
|
-
find_window(nil, IMPOSSIBLE).should_not == false
|
206
|
-
find_window(nil, IMPOSSIBLE).should == nil
|
207
|
-
end
|
208
|
-
|
209
|
-
it 'defined method does not return true when result is non-zero' do
|
210
|
-
find_window(nil, nil).should_not == true
|
211
|
-
find_window(nil, nil).should_not == 0
|
212
|
-
end
|
213
|
-
|
214
|
-
it 'defined methods enforce the argument count' do
|
215
|
-
should_count_args :find_window, :FindWindow, [nil, nil], [nil, IMPOSSIBLE, 'cmd']
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
context 'using DLL other than default user32 with :dll option' do
|
220
|
-
before(:each) {MyLib.function 'GetComputerName', 'PP', 'I', :dll=> 'kernel32'}
|
221
|
-
|
222
|
-
it 'defines new instance method with appropriate name' do
|
223
|
-
respond_to?(:GetComputerName).should be_true
|
224
|
-
respond_to?(:get_computer_name).should be_true
|
225
|
-
respond_to?(:computer_name).should be_true
|
226
|
-
end
|
227
|
-
|
228
|
-
it 'returns expected result' do
|
229
|
-
MyLib.function 'GetComputerName', ['P', 'P'], 'I', :dll=> 'kernel32'
|
230
|
-
hostname = `hostname`.strip.upcase
|
231
|
-
name = " " * 128
|
232
|
-
get_computer_name(name, "128")
|
233
|
-
name.unpack("A*").first.should == hostname
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
context 'trying to define an invalid API function' do
|
238
|
-
it 'raises error when trying to define function with a wrong function name' do
|
239
|
-
expect { MyLib.function 'FindWindowImpossible', 'PP', 'L' }.
|
240
|
-
to raise_error( /Function 'FindWindowImpossible' not found/ )
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
context 'defining API function using definition block' do
|
245
|
-
it 'defines new instance method' do
|
246
|
-
MyLib.function( :FindWindow, 'PP', 'L' ){|api, *args|}
|
247
|
-
respond_to?(:find_window).should be_true
|
248
|
-
respond_to?(:FindWindow).should be_true
|
249
|
-
end
|
274
|
+
it_should_behave_like 'defining macro with options'
|
250
275
|
|
251
276
|
it 'does not enforce argument count outside of block' do
|
252
277
|
MyLib.function( :FindWindow, 'PP', 'L' ){|api, *args|}
|
@@ -269,24 +294,12 @@ module WinLibraryTest
|
|
269
294
|
@args.should == [1, 2, 3]
|
270
295
|
should_be :find_window, @api
|
271
296
|
end
|
297
|
+
end
|
272
298
|
|
273
|
-
|
274
|
-
|
275
|
-
expect {
|
276
|
-
|
277
|
-
end
|
278
|
-
|
279
|
-
it 'adds alias for defined method with :alias option' do
|
280
|
-
MyLib.function( :FindWindow, 'PP', 'L', :alias => 'my_own_find' ){|api, *args|}
|
281
|
-
expect {find_window(nil, nil)}.to_not raise_error
|
282
|
-
expect {my_own_find(nil, nil)}.to_not raise_error
|
283
|
-
end
|
284
|
-
|
285
|
-
it 'adds aliases for defined method with :aliases option' do
|
286
|
-
MyLib.function( :FindWindow, 'PP', 'L', :aliases => ['my_own_find', 'my_own_find1'] ) {|api, *args|}
|
287
|
-
expect {find_window(nil, nil)}.to_not raise_error
|
288
|
-
expect {my_own_find(nil, nil)}.to_not raise_error
|
289
|
-
expect {my_own_find1(nil, nil)}.to_not raise_error
|
299
|
+
context 'trying to define an invalid API function' do
|
300
|
+
it 'raises error when trying to define function with a wrong function name' do
|
301
|
+
expect { MyLib.function 'FindWindowImpossible', 'PP', 'L' }.
|
302
|
+
to raise_error( /Function 'FindWindowImpossible' not found/ )
|
290
303
|
end
|
291
304
|
end
|
292
305
|
|
@@ -316,22 +329,35 @@ module WinLibraryTest
|
|
316
329
|
should_count_args :GetForegroundWindow, :get_foreground_window, :foreground_window, [], [nil, 0, 123]
|
317
330
|
end
|
318
331
|
end
|
332
|
+
|
333
|
+
context 'defining API function that has snake_case name' do
|
334
|
+
it 'should define original function in (generated) CamelCase' do
|
335
|
+
MyLib.function :keybd_event, [:char, :char, :ulong, :ulong], :void
|
336
|
+
expect {KeybdEvent(Win::Gui::Input::VK_CONTROL, 0, Win::Gui::Input::KEYEVENTF_KEYDOWN, 0)}.to_not raise_error
|
337
|
+
expect {keybd_event(Win::Gui::Input::VK_CONTROL, 0, Win::Gui::Input::KEYEVENTF_KEYUP, 0)}.to_not raise_error
|
338
|
+
end
|
339
|
+
end
|
319
340
|
end
|
320
341
|
|
321
342
|
context '::callback defining API callback TYPES' do
|
322
|
-
it '#callback macro
|
343
|
+
it '#callback macro defines a valid callback TYPE' do
|
323
344
|
expect { MyLib.callback :MyEnumWindowsProc, [:HWND, :long], :bool}.to_not raise_error
|
324
345
|
end
|
325
346
|
|
326
|
-
it '
|
347
|
+
it 'pre-definsed callback type can be used to define API functions (expecting callback)' do
|
327
348
|
expect {MyLib.function :EnumWindows, [:MyEnumWindowsProc, :long], :long}.to_not raise_error
|
349
|
+
expect {MyLib.function :EnumWindows, [:UndefinedProc, :long], :long}.to raise_error TypeError
|
350
|
+
end
|
351
|
+
|
352
|
+
it 'API function expecting callback accept lambdas representing callback' do
|
353
|
+
MyLib.function :EnumWindows, [:MyEnumWindowsProc, :long], :long
|
328
354
|
expect { enum_windows(lambda{|handle, message| true }, 0) }.to_not raise_error
|
329
355
|
end
|
330
356
|
end
|
331
357
|
|
332
|
-
context '::try_function
|
333
|
-
if
|
334
|
-
it '
|
358
|
+
context '::try_function - possibly defines API functions that are platform-specific' do
|
359
|
+
if os_xp?
|
360
|
+
it 'silently fails to define function not present on current platform' do
|
335
361
|
expect {MyLib.function :GetErrorMode, [], :UINT}.to raise_error /Function 'GetErrorMode' not found/
|
336
362
|
expect {MyLib.try_function :GetErrorMode, [], :UINT}.to_not raise_error
|
337
363
|
expect { GetErrorMode() }.to raise_error /undefined method `GetErrorMode'/
|