spec/win/window_spec.rb in win-0.0.4 vs spec/win/window_spec.rb in win-0.0.6
- old
+ new
@@ -7,11 +7,15 @@
include Win::Window
def launch_test_app
system TEST_APP_START
sleep TEST_SLEEP_DELAY until (handle = find_window(nil, TEST_WIN_TITLE))
+
@launched_test_app = Window.new handle
+# app = "Test app" #need to get rid of Window for JRuby
+# class << app; self; end.send( :define_method, :handle, &lambda {handle})
+# @launched_test_app = app
end
def close_test_app(app = @launched_test_app)
while app and app.respond_to? :handle and find_window(nil, TEST_WIN_TITLE)
post_message(app.handle, WM_SYSCOMMAND, SC_CLOSE, 0)
@@ -28,12 +32,34 @@
Window.new find_window_ex(self.handle, 0, TEST_TEXTAREA_CLASS, nil)
end
yield app
close_test_app
- end
+ end
+ def commands_should_show_window *cmds, tests
+ cmds.each do |cmd|
+ test_app do |app|
+ show_window(app.handle, cmd)
+ tests.each{|test, result| send(test.to_sym, app.handle).should == result}
+
+ hide_window(app.handle) # hiding window first
+ show_window(app.handle, cmd)
+ tests.each{|test, result| send(test.to_sym, app.handle).should == result}
+
+ show_window(app.handle, SW_MAXIMIZE) # now maximizing window
+ show_window(app.handle, cmd)
+ tests.each{|test, result| send(test.to_sym, app.handle).should == result}
+
+ show_window(app.handle, SW_MINIMIZE) # now minimizing window
+ show_window(app.handle, cmd)
+ tests.each{|test, result| send(test.to_sym, app.handle).should == result}
+ end
+ end
+ end
+
+
describe Win::Window, ' defines a set user32 API functions related to Window manipulation' do
describe '#window?' do
spec{ use{ IsWindow(any_handle) }}
spec{ use{ is_window(any_handle) }}
spec{ use{ window?(any_handle) }}
@@ -55,11 +81,11 @@
end
window?(@app_handle).should == false
window?(@ta_handle).should == false
end
end
-
+
describe '#window_visible?' do
spec{ use{ IsWindowVisible(any_handle) }}
spec{ use{ is_window_visible(any_handle) }}
spec{ use{ window_visible?(any_handle) }}
spec{ use{ visible?(any_handle) }}
@@ -103,11 +129,11 @@
it 'returns true if the window is minimized, false otherwise' do
test_app do |app|
iconic?(app.handle).should == false
minimized?(app.handle).should == false
show_window(app.handle, SW_MINIMIZE)
- iconic?(app.handle).should == true
+ iconic?(app.handle).should == true # !
minimized?(app.handle).should == true
end
end
end
@@ -269,13 +295,13 @@
spec{ use{ class_name = class_name_w(any_handle)}}
it 'returns correct window class name' do
test_app do |app|
get_class_name(app.handle).should == TEST_WIN_CLASS
- get_class_name_w(app.handle).should == TEST_WIN_CLASS
+ get_class_name_w(app.handle).should == TEST_WIN_CLASS #!!!! nil?
+ class_name_w(app.handle).should == TEST_WIN_CLASS #!!!!!!! nil?
class_name(app.handle).should == TEST_WIN_CLASS
- class_name_w(app.handle).should == TEST_WIN_CLASS
end
end
end
describe '#get_window_thread_process_id' do
@@ -311,7 +337,208 @@
get_window_rect(app.handle).should == TEST_WIN_RECT
end
end
end
+ describe '#show_window ', 'LI', 'I' do
+ spec{ use{ was_visible = show_window(handle = any_handle, cmd = SW_SHOWNA) }}
+
+ it 'was_visible = hide_window(handle = any_handle) # derived method (not a separate API function)' do
+ test_app do |app|
+ use{ @was_visible = hide_window(app.handle) }
+ @was_visible.should == true
+ visible?(app.handle).should == false
+ hide_window(app.handle).should == false
+ visible?(app.handle).should == false
+ end
+ end
+
+ it 'returns true if the window was PREVIOUSLY visible, false otherwise' do
+ test_app do |app|
+ show_window(app.handle, SW_HIDE).should == true
+ show_window(app.handle, SW_HIDE).should == false
+ end
+ end
+
+ it 'hides window with SW_HIDE command ' do
+ test_app do |app|
+ show_window(app.handle, SW_HIDE)
+ visible?(app.handle).should == false
+ end
+ end
+
+ it 'shows hidden window with SW_SHOW command' do
+ test_app do |app|
+ hide_window(app.handle)
+ show_window(app.handle, SW_SHOW)
+ visible?(app.handle).should == true
+ end
+ end
+
+ it 'SW_MAXIMIZE, SW_SHOWMAXIMIZED maximize window and activate it' do
+ commands_should_show_window SW_MAXIMIZE, SW_SHOWMAXIMIZED,
+ :minimized? => false, :maximized? => true, :visible? => true, :foreground? => true
+ end
+
+ it 'SW_MINIMIZE minimizes window and activates the next top-level window in the Z order' do
+ commands_should_show_window SW_MINIMIZE,
+ :minimized? => true, :maximized? => false, :visible? => true, :foreground? => false
+ end
+
+ it 'SW_SHOWMINNOACTIVE, SW_SHOWMINIMIZED displays the window as a minimized foreground window' do
+ commands_should_show_window SW_SHOWMINNOACTIVE, SW_SHOWMINIMIZED, #!
+ :minimized? => true, :maximized? => false, :visible? => true, :foreground? => true
+ end
+
+ it 'SW_SHOWNORMAL, SW_RESTORE, SW_SHOWNOACTIVATE activate/display a window(if min/maximized it is restored' do
+ commands_should_show_window SW_SHOWNORMAL, SW_RESTORE, SW_SHOWNOACTIVATE,
+ :minimized? => false, :maximized? => false, :visible? => true, :foreground? => true
+ end
+
+ it 'SW_SHOWNA displays the window in its current size and position (similar to SW_SHOW, but window is not activated)'
+ it 'SW_SHOWDEFAULT sets the show state based on the SW_ value specified in the STARTUPINFO structure passed to the CreateProcess function by the program that started the application'
+ it 'SW_FORCEMINIMIZE minimizes a window, even if the thread that owns the window is not responding - only Win2000/XP'
+ end
+
+ describe '#enum_windows' do
+ before(:all){@app = launch_test_app}
+ after(:all){close_test_app}
+
+ spec{ use{ handles = enum_windows(value = 13) }}
+ spec{ use{ enum_windows do |handle, message|
+ end }}
+
+ it 'iterates through all the top-level windows, passing each top level window handle and value to a given block' do
+ enum_windows(13) do |handle, message|
+ handle.should be_an Integer
+ handle.should be > 0
+ message.should == 13
+ end
+ end
+
+ it 'returns an array of top-level window handles if block is not given' do
+ enum = enum_windows(13)
+ enum.should be_a_kind_of Array
+ enum.should_not be_empty
+ enum.should have_at_least(50).elements # typical number of top windows in WinXP system?
+ enum.each do |handle|
+ handle.should be_an Integer
+ handle.should be > 0
+ end
+ enum.any?{|handle| handle == @app.handle}.should == true
+ end
+
+ it 'returned array that contains handle of launched test app' do
+ enum = enum_windows(13)
+ enum.any?{|handle| handle == @app.handle}.should == true
+ end
+
+ it 'defaults message to 0 if it is omitted from method call' do
+ enum_windows do |handle, message|
+ message.should == 0
+ end
+ end
+ end
+
+ describe '#enum_child_windows' do
+ before(:all){@app = launch_test_app}
+ after(:all){close_test_app}
+
+ spec{ use{ enum_child_windows(parent = any_handle, value = 13) }}
+
+ it 'return an array of child window handles if block is not given' do
+ enum = enum_child_windows(@app.handle, 13)
+ enum.should be_a_kind_of Array
+ enum.should have(2).elements
+ class_name(enum.first).should == TEST_STATUSBAR_CLASS
+ class_name(enum.last).should == TEST_TEXTAREA_CLASS
+ end
+
+ it 'loops through all children of given window, passing each found window handle and a message to a given block' do
+ enum = []
+ enum_child_windows(@app.handle, 13) do |handle, message|
+ enum << handle
+ message.should == 13
+ end
+ enum.should have(2).elements
+ class_name(enum.first).should == TEST_STATUSBAR_CLASS
+ class_name(enum.last).should == TEST_TEXTAREA_CLASS
+ end
+
+ it 'breaks loop if given block returns false' do
+ enum = []
+ enum_child_windows(@app.handle) do |handle, message|
+ enum << handle
+ false
+ end
+ enum.should have(1).element
+ class_name(enum.first).should == TEST_STATUSBAR_CLASS
+ end
+
+ it 'defaults message to 0 if it is omitted from method call' do
+ enum_child_windows(@app.handle) do |handle, message|
+ message.should == 0
+ end
+ end
+ end
+
+ describe '#keydb_event' do
+ spec{ use{ keybd_event(vkey = 0, bscan = 0, flags = 0, extra_info = 0) }}
+
+ it 'synthesizes a numeric keystrokes, emulating keyboard driver' do
+ test_app do |app|
+ text = '123 456'
+ text.upcase.each_byte do |b| # upcase needed since user32 keybd_event expects upper case chars
+ keybd_event(b.ord, 0, KEYEVENTF_KEYDOWN, 0)
+ sleep TEST_KEY_DELAY
+ keybd_event(b.ord, 0, KEYEVENTF_KEYUP, 0)
+ sleep TEST_KEY_DELAY
+ end
+ app.textarea.text.should =~ Regexp.new(text)
+ 7.times {keystroke(VK_CONTROL, 'Z'.ord)} # dirty hack!
+ end
+ end
+ end
+
+ describe '#post_message' do
+ spec{ use{ success = post_message(handle = 0, msg = 0, w_param = 0, l_param = 0) }}
+ # handle (L) - Handle to the window whose window procedure will receive the message.
+ # If this parameter is HWND_BROADCAST, the message is sent to all top-level windows in the system, including disabled or
+ # invisible unowned windows, overlapped windows, and pop-up windows; but the message is not sent to child windows.
+ # msg (L) - Specifies the message to be posted.
+ # w_param (L) - Specifies additional message-specific information.
+ # l_param (L) - Specifies additional message-specific information.
+ # returns (L) - Nonzero if success, zero if function failed. To get extended error information, call GetLastError.
+
+ it 'places (posts) a message in the message queue associated with the thread that created the specified window'
+ it 'returns without waiting for the thread to process the message'
+ end
+
+ describe '#send_message' do
+ spec{ use{ success = send_message(handle = 0, msg = 0, w_param = 1024, l_param = "\x0"*1024) }}
+ # handle (L) - Handle to the window whose window procedure is to receive the message. The following values have special meanings.
+ # HWND_BROADCAST - The message is posted to all top-level windows in the system, including disabled or invisible unowned windows,
+ # overlapped windows, and pop-up windows. The message is not posted to child windows.
+ # NULL - The function behaves like a call to PostThreadMessage with the dwThreadId parameter set to the identifier of the current thread.
+ # msg (L) - Specifies the message to be posted.
+ # w_param (L) - Specifies additional message-specific information.
+ # l_param (L) - Specifies additional message-specific information.
+ # return (L) - Nonzero if success, zero if function failed. To get extended error information, call GetLastError.
+
+ it 'sends the specified message to a window or windows'
+ it 'calls the window procedure and does not return until the window procedure has processed the message'
+ end
+
+ describe '#get_dlg_item' do
+ spec{ use{ control_handle = get_dlg_item(handle = 0, item_id = 1) }}
+ # handle (L) - Handle of the dialog box that contains the control.
+ # item_id (I) - Specifies the identifier of the control to be retrieved.
+ # Returns (L) - handle of the specified control if success or nil for invalid dialog box handle or a nonexistent control.
+ # To get extended error information, call GetLastError.
+ # You can use the GetDlgItem function with any parent-child window pair, not just with dialog boxes. As long as the handle
+ # parameter specifies a parent window and the child window has a unique id (as specified by the hMenu parameter in the
+ # CreateWindow or CreateWindowEx function that created the child window), GetDlgItem returns a valid handle to the child window.
+
+ it 'returns handle to correctly specified control'
+ end
end
end
\ No newline at end of file