win32-autogui 0.2.0
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/.gitattributes +1 -0
- data/.gitignore +10 -0
- data/.yardopts +6 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +60 -0
- data/HISTORY.markdown +11 -0
- data/LICENSE +20 -0
- data/README.markdown +265 -0
- data/Rakefile +55 -0
- data/TODO.markdown +9 -0
- data/VERSION +1 -0
- data/config/cucumber.yml +7 -0
- data/examples/quicknote/.gitignore +8 -0
- data/examples/quicknote/FormAboutU.dfm +44 -0
- data/examples/quicknote/FormAboutU.pas +36 -0
- data/examples/quicknote/FormMainU.dfm +110 -0
- data/examples/quicknote/FormMainU.pas +268 -0
- data/examples/quicknote/FormSplashU.dfm +32 -0
- data/examples/quicknote/FormSplashU.pas +52 -0
- data/examples/quicknote/LICENSE +20 -0
- data/examples/quicknote/README.markdown +28 -0
- data/examples/quicknote/Rakefile +12 -0
- data/examples/quicknote/TODO.markdown +15 -0
- data/examples/quicknote/dcu/.gitignore +1 -0
- data/examples/quicknote/exe/.gitignore +0 -0
- data/examples/quicknote/exe/quicknote.exe +0 -0
- data/examples/quicknote/lib/quicknote.rb +140 -0
- data/examples/quicknote/quicknote.cfg +37 -0
- data/examples/quicknote/quicknote.dof +158 -0
- data/examples/quicknote/quicknote.dpr +16 -0
- data/examples/quicknote/quicknote.res +0 -0
- data/examples/quicknote/spec/quicknote/form_about_spec.rb +50 -0
- data/examples/quicknote/spec/quicknote/form_main_spec.rb +274 -0
- data/examples/quicknote/spec/quicknote/form_splash_spec.rb +44 -0
- data/examples/quicknote/spec/spec.opts +2 -0
- data/examples/quicknote/spec/spec_helper.rb +34 -0
- data/examples/quicknote/spec/watchr.rb +143 -0
- data/examples/skeleton/.gitignore +8 -0
- data/examples/skeleton/LICENSE +20 -0
- data/examples/skeleton/README.markdown +62 -0
- data/examples/skeleton/Rakefile +21 -0
- data/examples/skeleton/TODO.markdown +9 -0
- data/examples/skeleton/config/cucumber.yml +7 -0
- data/examples/skeleton/dcu/.gitignore +1 -0
- data/examples/skeleton/exe/.gitignore +1 -0
- data/examples/skeleton/features/basic.feature +6 -0
- data/examples/skeleton/features/step_definitions/.gitignore +0 -0
- data/examples/skeleton/features/step_definitions/application_steps.rb +43 -0
- data/examples/skeleton/features/support/env.rb +5 -0
- data/examples/skeleton/lib/myapp.rb +73 -0
- data/examples/skeleton/spec/myapp/form_about_spec.rb +50 -0
- data/examples/skeleton/spec/myapp/form_main_spec.rb +60 -0
- data/examples/skeleton/spec/spec.opts +2 -0
- data/examples/skeleton/spec/spec_helper.rb +29 -0
- data/examples/skeleton/spec/watchr.rb +143 -0
- data/features/automating_an_application.feature +11 -0
- data/features/step_definitions/.gitignore +0 -0
- data/features/step_definitions/calculator_steps.rb +37 -0
- data/features/support/env.rb +4 -0
- data/lib/win32/autogui.rb +27 -0
- data/lib/win32/autogui/application.rb +249 -0
- data/lib/win32/autogui/input.rb +238 -0
- data/lib/win32/autogui/window.rb +191 -0
- data/lib/win32/autogui/windows/window.rb +22 -0
- data/spec/applications/calculator.rb +34 -0
- data/spec/auto_gui/application_spec.rb +132 -0
- data/spec/basic_gem/basic_gem_spec.rb +13 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/watchr.rb +144 -0
- data/win32-autogui.gemspec +43 -0
- metadata +329 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
program quicknote;
|
2
|
+
|
3
|
+
uses
|
4
|
+
Forms,
|
5
|
+
FormMainU in 'FormMainU.pas' {FormMain},
|
6
|
+
FormAboutU in 'FormAboutU.pas' {FormAbout},
|
7
|
+
FormSplashU in 'FormSplashU.pas' {FormSplash};
|
8
|
+
|
9
|
+
{$R *.res}
|
10
|
+
|
11
|
+
begin
|
12
|
+
Application.Initialize;
|
13
|
+
Application.Title := 'QuickNote';
|
14
|
+
Application.CreateForm(TFormMain, FormMain);
|
15
|
+
Application.Run;
|
16
|
+
end.
|
Binary file
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
include Autogui::Input
|
4
|
+
|
5
|
+
describe "FormAbout" do
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
@application = Quicknote.new
|
9
|
+
end
|
10
|
+
|
11
|
+
after(:all) do
|
12
|
+
@application.close(:wait_for_close => true) if @application.running?
|
13
|
+
@application.should_not be_running
|
14
|
+
end
|
15
|
+
|
16
|
+
before(:each) do
|
17
|
+
@application.dialog_about.should be_nil
|
18
|
+
@application.set_focus
|
19
|
+
keystroke(VK_MENU, VK_H, VK_A)
|
20
|
+
@dialog_about = @application.dialog_about
|
21
|
+
@dialog_about.should_not be_nil
|
22
|
+
@dialog_about.is_window?.should == true
|
23
|
+
end
|
24
|
+
|
25
|
+
after(:each) do
|
26
|
+
@dialog_about.close if @dialog_about.is_window?
|
27
|
+
@dialog_about.is_window?.should == false
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should open with the hotkey combination VK_MENU, VK_H, VK_A" do
|
31
|
+
@dialog_about.is_window?.should == true
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should close by hitting return" do
|
35
|
+
@dialog_about.set_focus
|
36
|
+
keystroke(VK_RETURN)
|
37
|
+
@application.dialog_about.should be_nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should have the title 'About QuickNote'" do
|
41
|
+
@dialog_about.title.should == "About QuickNote"
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should have an 'OK' button" do
|
45
|
+
button = @dialog_about.children.find {|w| w.window_class == 'TButton'}
|
46
|
+
button.should_not be_nil
|
47
|
+
button.text.should match(/^OK$/)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,274 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
include Autogui::Input
|
4
|
+
|
5
|
+
describe "FormMain" do
|
6
|
+
before(:all) do
|
7
|
+
@debug = false
|
8
|
+
@verbose = true
|
9
|
+
@application = Quicknote.new
|
10
|
+
FileUtils.rm_rf(current_dir)
|
11
|
+
puts "FormMain before(:all)" if @debug
|
12
|
+
puts "application:\n#{@application.inspect}\n" if @debug && @verbose
|
13
|
+
puts "application.combined_text:\n #{@application.combined_text}\n" if @debug && @verbose
|
14
|
+
end
|
15
|
+
before(:each) do
|
16
|
+
@application = Quicknote.new unless @application.running?
|
17
|
+
@application.should be_running
|
18
|
+
@application.set_focus
|
19
|
+
puts "FormMain before(:each)" if @debug
|
20
|
+
end
|
21
|
+
after(:all) do
|
22
|
+
if @application.running?
|
23
|
+
@application.file_exit
|
24
|
+
# still running? force it to close
|
25
|
+
@application.close(:wait_for_close => true)
|
26
|
+
@application.should_not be_running
|
27
|
+
end
|
28
|
+
puts "FormMain after(:all)" if @debug
|
29
|
+
end
|
30
|
+
after(:each) do
|
31
|
+
if @application.running?
|
32
|
+
keystroke(VK_N) if @application.message_dialog_confirm || @application.dialog_overwrite_confirm
|
33
|
+
keystroke(VK_ESCAPE) if @application.error_dialog
|
34
|
+
end
|
35
|
+
puts "FormMain after(:each)" if @debug
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "after startup" do
|
39
|
+
it "should have the title 'QuickNote - untitled.txt'" do
|
40
|
+
@application.main_window.title.should == "QuickNote - untitled.txt"
|
41
|
+
end
|
42
|
+
it "should have no text" do
|
43
|
+
@application.edit_window.text.should == ''
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "editing text" do
|
48
|
+
after(:each) do
|
49
|
+
@application.file_new(:save => false)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should add the '+' modified flag to the title" do
|
53
|
+
@application.main_window.title.should == "QuickNote - untitled.txt"
|
54
|
+
type_in("hello")
|
55
|
+
@application.main_window.title.should == "QuickNote - +untitled.txt"
|
56
|
+
end
|
57
|
+
it "should change the text" do
|
58
|
+
@application.edit_window.text.should == ''
|
59
|
+
type_in("hello")
|
60
|
+
@application.edit_window.text.should == 'hello'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "file open (VK_MENU, VK_F, VK_O)" do
|
65
|
+
before(:each) do
|
66
|
+
@filename = "input_file.txt"
|
67
|
+
@file_contents = create_file(@filename, "the quick brown fox")
|
68
|
+
@application.file_new(:save => false)
|
69
|
+
end
|
70
|
+
after(:each) do
|
71
|
+
keystroke(VK_N) if @application.message_dialog_confirm
|
72
|
+
keystroke(VK_ESCAPE) if @application.file_open_dialog
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should prompt to save with modified text" do
|
76
|
+
type_in("foobar")
|
77
|
+
@application.main_window.title.should match(/\+/)
|
78
|
+
keystroke(VK_MENU, VK_F, VK_O)
|
79
|
+
@application.message_dialog_confirm.should_not be_nil
|
80
|
+
end
|
81
|
+
it "should not prompt to save with unmodified text" do
|
82
|
+
@application.main_window.title.should_not match(/\+/)
|
83
|
+
keystroke(VK_MENU, VK_F, VK_O)
|
84
|
+
@application.message_dialog_confirm.should be_nil
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "succeeding" do
|
88
|
+
it "should add the filename to the title" do
|
89
|
+
@application.main_window.title.should == "QuickNote - untitled.txt"
|
90
|
+
@application.file_open(fullpath(@filename), :save => false)
|
91
|
+
@application.main_window.title.should == "QuickNote - #{fullpath(@filename)}"
|
92
|
+
end
|
93
|
+
it "should load the text" do
|
94
|
+
@application.file_open(fullpath(@filename), :save => false)
|
95
|
+
@application.edit_window.text.should == 'the quick brown fox'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "failing" do
|
100
|
+
it "should show an error dialog with message 'Cannot open file'" do
|
101
|
+
type_in("foobar")
|
102
|
+
@application.file_open(fullpath("a_bogus_filename.txt"), :save => false)
|
103
|
+
@application.error_dialog.should_not be_nil
|
104
|
+
@application.error_dialog.combined_text.should match(/Cannot open file/)
|
105
|
+
end
|
106
|
+
it "should keep existing text" do
|
107
|
+
type_in("foobar")
|
108
|
+
@application.file_open(fullpath("a_bogus_filename.txt"), :save => false)
|
109
|
+
@application.error_dialog.should_not be_nil
|
110
|
+
@application.edit_window.text.should == 'foobar'
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "file new (VK_MENU, VK_F, VK_N)" do
|
116
|
+
it "should prompt to save modified text" do
|
117
|
+
type_in("hello")
|
118
|
+
@application.main_window.title.should match(/\+/)
|
119
|
+
keystroke(VK_MENU, VK_F, VK_N)
|
120
|
+
@application.message_dialog_confirm.should_not be_nil
|
121
|
+
end
|
122
|
+
it "should not prompt to save with unmodified text" do
|
123
|
+
@application.file_new(:save => false)
|
124
|
+
@application.main_window.title.should_not match(/\+/)
|
125
|
+
keystroke(VK_MENU, VK_F, VK_N)
|
126
|
+
@application.message_dialog_confirm.should be_nil
|
127
|
+
end
|
128
|
+
it "should add the filename 'untitled.txt' to the title" do
|
129
|
+
filename = "input_file.txt"
|
130
|
+
file_contents = create_file(filename, "the quick brown fox")
|
131
|
+
@application.file_open(filename, :save => false)
|
132
|
+
@application.main_window.title.downcase.should == "QuickNote - #{fullpath(filename)}".downcase
|
133
|
+
@application.file_new(:save => false)
|
134
|
+
@application.main_window.title.should == "QuickNote - untitled.txt"
|
135
|
+
end
|
136
|
+
it "should remove the '+' modified flag from the title" do
|
137
|
+
type_in("hello")
|
138
|
+
@application.main_window.title.should match(/\+/)
|
139
|
+
@application.file_new(:save => false)
|
140
|
+
@application.main_window.title.should_not match(/\+/)
|
141
|
+
end
|
142
|
+
it "should clear the existing text" do
|
143
|
+
type_in("hello")
|
144
|
+
@application.edit_window.text.should match(/hello/)
|
145
|
+
@application.file_new(:save => false)
|
146
|
+
@application.edit_window.text.should == ''
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "file save (VK_MENU, VK_F, VK_S)" do
|
151
|
+
before(:each) do
|
152
|
+
@filename = "input_file.txt"
|
153
|
+
@file_contents = create_file(@filename, "original content")
|
154
|
+
@application.file_open(fullpath(@filename), :save => false)
|
155
|
+
@application.main_window.title.downcase.should == "QuickNote - #{fullpath(@filename)}".downcase
|
156
|
+
@application.edit_window.text.should == "original content"
|
157
|
+
@application.set_focus
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should do nothing unless modified text" do
|
161
|
+
append_to_file(@filename, "sneak in extra content that shouldn't be here")
|
162
|
+
contents = get_file_content(@filename)
|
163
|
+
contents.should match(/extra content/)
|
164
|
+
@application.file_save
|
165
|
+
contents.should match(/extra content/)
|
166
|
+
@application.edit_window.text.should_not match(/extra content/)
|
167
|
+
end
|
168
|
+
|
169
|
+
describe "succeeding" do
|
170
|
+
it "should remove the '+' modified flag from the title" do
|
171
|
+
type_in("anything")
|
172
|
+
@application.main_window.title.should == "QuickNote - +#{fullpath(@filename)}"
|
173
|
+
@application.file_save
|
174
|
+
@application.main_window.title.should == "QuickNote - #{fullpath(@filename)}"
|
175
|
+
end
|
176
|
+
it "should save the text" do
|
177
|
+
type_in("foobar")
|
178
|
+
@application.edit_window.text.should == "foobar" + "original content"
|
179
|
+
@application.file_save
|
180
|
+
get_file_content(@filename).should == "foobar" + "original content"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe "failing" do
|
185
|
+
before(:each) do
|
186
|
+
# set read-only to cause save failure
|
187
|
+
in_current_dir do
|
188
|
+
`attrib +R #{@filename}`
|
189
|
+
end
|
190
|
+
end
|
191
|
+
after(:each) do
|
192
|
+
# cleanup read-only file
|
193
|
+
FileUtils.rm_rf(current_dir)
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should show an error dialog with message 'Cannot create file'" do
|
197
|
+
type_in("anything")
|
198
|
+
@application.file_save
|
199
|
+
@application.error_dialog.should_not be_nil
|
200
|
+
@application.error_dialog.combined_text.should match(/Cannot create file/)
|
201
|
+
end
|
202
|
+
it "should keep the '+' modified flag on the title" do
|
203
|
+
type_in("anything")
|
204
|
+
@application.file_save
|
205
|
+
@application.main_window.title.should == "QuickNote - +#{fullpath(@filename)}"
|
206
|
+
end
|
207
|
+
it "should keep existing text" do
|
208
|
+
type_in("anything")
|
209
|
+
@application.file_save
|
210
|
+
@application.edit_window.text.should == "anything" + "original content"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe "file save as (VK_MENU, VK_F, VK_A)" do
|
216
|
+
before(:each) do
|
217
|
+
@filename = "original.txt"
|
218
|
+
@file_contents = create_file(@filename, "original content")
|
219
|
+
@saveas_filename = "newfile.txt"
|
220
|
+
create_file(@saveas_filename, "")
|
221
|
+
@application.file_open(fullpath(@filename), :save => false)
|
222
|
+
end
|
223
|
+
after(:each) do
|
224
|
+
keystroke(VK_N) if @application.dialog_overwrite_confirm
|
225
|
+
keystroke(VK_ESCAPE) if @application.file_save_as_dialog
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should prompt for filename" do
|
229
|
+
keystroke(VK_MENU, VK_F, VK_A)
|
230
|
+
@application.file_save_as_dialog.should_not be_nil
|
231
|
+
end
|
232
|
+
it "should confirm file overwrites" do
|
233
|
+
type_in("anything")
|
234
|
+
keystroke(VK_MENU, VK_F, VK_A)
|
235
|
+
@application.clipboard.text = fullpath(@saveas_filename)
|
236
|
+
keystroke(VK_CONTROL, VK_V)
|
237
|
+
keystroke(VK_RETURN)
|
238
|
+
File.exists?(fullpath(@saveas_filename)).should be_true
|
239
|
+
@application.dialog_overwrite_confirm.should_not be_nil
|
240
|
+
end
|
241
|
+
it "should remove the '+' modified flag from the title" do
|
242
|
+
type_in("anything")
|
243
|
+
@application.main_window.title.should match(/\+/)
|
244
|
+
@application.file_save_as(fullpath(@saveas_filename), :overwrite => true)
|
245
|
+
@application.main_window.title.should_not match(/\+/)
|
246
|
+
end
|
247
|
+
it "should add the filename to the title" do
|
248
|
+
@application.file_save_as(fullpath(@saveas_filename), :overwrite => true)
|
249
|
+
@application.main_window.title.downcase.should == "QuickNote - #{fullpath(@saveas_filename)}".downcase
|
250
|
+
end
|
251
|
+
it "should save the text" do
|
252
|
+
get_file_content(@saveas_filename).should == ''
|
253
|
+
@application.file_save_as(fullpath(@saveas_filename), :overwrite => true)
|
254
|
+
get_file_content(@saveas_filename).should match(/original content/)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
describe "file exit (VK_MENU, VK_F, VK_X)" do
|
259
|
+
it "should prompt and save with modified text" do
|
260
|
+
type_in("anything")
|
261
|
+
keystroke(VK_MENU, VK_F, VK_X)
|
262
|
+
@application.message_dialog_confirm.should_not be_nil
|
263
|
+
@application.main_window.is_window?.should == true
|
264
|
+
@application.should be_running
|
265
|
+
end
|
266
|
+
it "should not prompt to save with unmodified text" do
|
267
|
+
keystroke(VK_MENU, VK_F, VK_X)
|
268
|
+
@application.message_dialog_confirm.should be_nil
|
269
|
+
@application.main_window.is_window?.should == false
|
270
|
+
@application.should_not be_running
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
include Autogui::Input
|
4
|
+
|
5
|
+
describe "FormSplash" do
|
6
|
+
after(:all) do
|
7
|
+
if @application.running?
|
8
|
+
@application.splash.wait_for_close if @application.splash
|
9
|
+
@application.file_exit
|
10
|
+
# still running? force it to close
|
11
|
+
@application.close(:wait_for_close => true)
|
12
|
+
@application.should_not be_running
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "startup with no command line parameters" do
|
17
|
+
before(:all) do
|
18
|
+
# --nosplash is the default, turn it back on
|
19
|
+
@application = Quicknote.new :parameters => ''
|
20
|
+
@application.should be_running
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should show" do
|
24
|
+
@application.splash.should_not be_nil
|
25
|
+
end
|
26
|
+
it "should close within 5 seconds" do
|
27
|
+
@application.splash.should_not be_nil
|
28
|
+
seconds = 5
|
29
|
+
timeout(seconds) do
|
30
|
+
@application.splash.wait_for_close
|
31
|
+
end
|
32
|
+
@application.splash.should be_nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "startup with '--nosplash' command line parameter" do
|
37
|
+
it "should not show" do
|
38
|
+
@application = Quicknote.new :parameters => '--nosplash'
|
39
|
+
@application.should be_running
|
40
|
+
@application.splash.should be_nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('..', __FILE__) unless
|
2
|
+
$LOAD_PATH.include? File.expand_path('..', __FILE__)
|
3
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) unless
|
4
|
+
$LOAD_PATH.include? File.expand_path('../../lib', __FILE__)
|
5
|
+
|
6
|
+
# use development version of win32/autogui
|
7
|
+
# remove these lines in production code
|
8
|
+
$LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__) unless
|
9
|
+
$LOAD_PATH.include? File.expand_path('../../../../lib', __FILE__)
|
10
|
+
|
11
|
+
require 'rubygems'
|
12
|
+
require 'win32/autogui'
|
13
|
+
require 'quicknote'
|
14
|
+
require 'spec'
|
15
|
+
require 'spec/autorun'
|
16
|
+
require 'aruba/api'
|
17
|
+
|
18
|
+
# aruba helper, returns full path to files in the aruba tmp folder
|
19
|
+
def fullpath(filename)
|
20
|
+
path = File.expand_path(File.join(current_dir, filename))
|
21
|
+
path = `cygpath -w #{path}`.chomp if path.match(/^\/cygdrive/) # cygwin?
|
22
|
+
path
|
23
|
+
end
|
24
|
+
|
25
|
+
# return the contents of "filename" in the aruba tmp folder
|
26
|
+
def get_file_content(filename)
|
27
|
+
in_current_dir do
|
28
|
+
IO.read(filename)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Spec::Runner.configure do |config|
|
33
|
+
config.include Aruba::Api
|
34
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# Watchr: Autotest like functionality
|
2
|
+
#
|
3
|
+
# gem install watchr
|
4
|
+
#
|
5
|
+
# Run me with:
|
6
|
+
#
|
7
|
+
# $ watchr spec/watchr.rb
|
8
|
+
|
9
|
+
require 'term/ansicolor'
|
10
|
+
|
11
|
+
$c = Term::ANSIColor
|
12
|
+
|
13
|
+
def getch
|
14
|
+
state = `stty -g`
|
15
|
+
begin
|
16
|
+
`stty raw -echo cbreak`
|
17
|
+
$stdin.getc
|
18
|
+
ensure
|
19
|
+
`stty #{state}`
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# --------------------------------------------------
|
24
|
+
# Convenience Methods
|
25
|
+
# --------------------------------------------------
|
26
|
+
def all_feature_files
|
27
|
+
Dir['features/*.feature']
|
28
|
+
end
|
29
|
+
|
30
|
+
def all_spec_files
|
31
|
+
files = Dir['spec/**/*_spec\.rb']
|
32
|
+
end
|
33
|
+
|
34
|
+
def run(cmd)
|
35
|
+
|
36
|
+
pid = fork do
|
37
|
+
puts "\n"
|
38
|
+
print $c.cyan, cmd, $c.clear, "\n"
|
39
|
+
exec(cmd)
|
40
|
+
end
|
41
|
+
Signal.trap('INT') do
|
42
|
+
puts "sending KILL to pid: #{pid}"
|
43
|
+
Process.kill("KILL", pid)
|
44
|
+
end
|
45
|
+
Process.waitpid(pid)
|
46
|
+
|
47
|
+
prompt
|
48
|
+
end
|
49
|
+
|
50
|
+
def run_all
|
51
|
+
run_all_specs
|
52
|
+
run_default_cucumber
|
53
|
+
end
|
54
|
+
|
55
|
+
# allow cucumber rerun.txt smarts
|
56
|
+
def run_default_cucumber
|
57
|
+
cmd = "cucumber"
|
58
|
+
run(cmd)
|
59
|
+
end
|
60
|
+
|
61
|
+
def run_all_features
|
62
|
+
cmd = "cucumber #{all_feature_files.join(' ')}"
|
63
|
+
run(cmd)
|
64
|
+
end
|
65
|
+
|
66
|
+
def run_feature(feature)
|
67
|
+
cmd = "cucumber #{feature}"
|
68
|
+
$last_feature = feature
|
69
|
+
run(cmd)
|
70
|
+
end
|
71
|
+
|
72
|
+
def run_last_feature
|
73
|
+
run_feature($last_feature) if $last_feature
|
74
|
+
end
|
75
|
+
|
76
|
+
def run_default_spec
|
77
|
+
cmd = "spec _1.3.1_ --color --format s ./spec"
|
78
|
+
run(cmd)
|
79
|
+
end
|
80
|
+
|
81
|
+
def run_all_specs
|
82
|
+
cmd = "spec _1.3.1_ --color --format s #{all_spec_files.join(' ')}"
|
83
|
+
p cmd
|
84
|
+
run(cmd)
|
85
|
+
end
|
86
|
+
|
87
|
+
def run_spec(spec)
|
88
|
+
cmd = "spec _1.3.1_ --color --format s #{spec}"
|
89
|
+
$last_spec = spec
|
90
|
+
run(cmd)
|
91
|
+
end
|
92
|
+
|
93
|
+
def run_last_spec
|
94
|
+
run_spec($last_spec) if $last_spec
|
95
|
+
end
|
96
|
+
|
97
|
+
def prompt
|
98
|
+
puts "Ctrl-\\ for menu, Ctrl-C to quit"
|
99
|
+
end
|
100
|
+
|
101
|
+
# init
|
102
|
+
$last_feature = nil
|
103
|
+
prompt
|
104
|
+
|
105
|
+
# --------------------------------------------------
|
106
|
+
# Watchr Rules
|
107
|
+
# --------------------------------------------------
|
108
|
+
watch( '^features/(.*)\.feature' ) { run_default_cucumber }
|
109
|
+
|
110
|
+
#watch( '^bin/(.*)' ) { run_default_cucumber }
|
111
|
+
watch( '^lib/(.*)' ) { run_default_cucumber }
|
112
|
+
|
113
|
+
watch( '^features/step_definitions/(.*)\.rb' ) { run_default_cucumber }
|
114
|
+
watch( '^features/support/(.*)\.rb' ) { run_default_cucumber }
|
115
|
+
|
116
|
+
watch( '^spec/(.*)_spec\.rb' ) { |m| run_spec(m[0]) }
|
117
|
+
# specify just the lib files that have specs
|
118
|
+
# TODO: This can be determined automatically from the spec file naming convention
|
119
|
+
watch( '^lib/(.*)' ) { run_default_spec }
|
120
|
+
|
121
|
+
# --------------------------------------------------
|
122
|
+
# Signal Handling
|
123
|
+
# --------------------------------------------------
|
124
|
+
|
125
|
+
# Ctrl-\
|
126
|
+
Signal.trap('QUIT') do
|
127
|
+
|
128
|
+
puts "\n\nMENU: a = all , f = features s = specs, l = last feature (#{$last_feature ? $last_feature : 'none'}), q = quit\n\n"
|
129
|
+
c = getch
|
130
|
+
puts c.chr
|
131
|
+
if c.chr == "a"
|
132
|
+
run_all
|
133
|
+
elsif c.chr == "f"
|
134
|
+
run_default_cucumber
|
135
|
+
elsif c.chr == "s"
|
136
|
+
run_all_specs
|
137
|
+
elsif c.chr == "q"
|
138
|
+
abort("exiting\n")
|
139
|
+
elsif c.chr == "l"
|
140
|
+
run_last_feature
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|