aslakhellesoy-cucumber 0.1.9 → 0.1.10
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.txt +36 -3
- data/Manifest.txt +15 -0
- data/bin/cucumber +2 -1
- data/config/hoe.rb +2 -1
- data/examples/calculator_ruby_features/features/addition.rb +1 -1
- data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +1 -0
- data/examples/i18n/de/Rakefile +6 -0
- data/examples/i18n/de/features/addition.feature +17 -0
- data/examples/i18n/de/features/division.feature +10 -0
- data/examples/i18n/de/features/step_definitons/calculator_steps.rb +30 -0
- data/examples/i18n/de/lib/calculator.rb +14 -0
- data/examples/i18n/en/Rakefile +1 -0
- data/examples/i18n/lt/Rakefile +6 -0
- data/examples/i18n/lt/features/addition.feature +17 -0
- data/examples/i18n/lt/features/division.feature +10 -0
- data/examples/i18n/lt/features/step_definitons/calculator_steps.rb +31 -0
- data/examples/i18n/lt/lib/calculator.rb +14 -0
- data/examples/test_unit/Rakefile +6 -0
- data/examples/test_unit/features/step_definitions/test_unit_steps.rb +26 -0
- data/examples/test_unit/features/test_unit.feature +9 -0
- data/examples/tickets/features/tickets.feature +4 -2
- data/lib/autotest/discover.rb +1 -1
- data/lib/cucumber.rb +3 -3
- data/lib/cucumber/cli.rb +51 -17
- data/lib/cucumber/core_ext/proc.rb +31 -16
- data/lib/cucumber/executor.rb +35 -15
- data/lib/cucumber/formatters/ansicolor.rb +11 -13
- data/lib/cucumber/languages.yml +24 -1
- data/lib/cucumber/platform.rb +12 -0
- data/lib/cucumber/step_mother.rb +7 -1
- data/lib/cucumber/tree/feature.rb +3 -1
- data/lib/cucumber/tree/scenario.rb +17 -1
- data/lib/cucumber/treetop_parser/feature_de.rb +8 -8
- data/lib/cucumber/treetop_parser/feature_lt.rb +1591 -0
- data/rails_generators/cucumber/templates/webrat_steps.rb +49 -0
- data/rails_generators/feature/templates/feature.erb +3 -3
- data/spec/cucumber/cli_spec.rb +172 -2
- data/spec/cucumber/executor_spec.rb +104 -28
- data/spec/cucumber/step_mother_spec.rb +7 -7
- data/spec/cucumber/tree/feature_spec.rb +31 -0
- data/spec/cucumber/tree/row_scenario_spec.rb +30 -0
- data/spec/spec_helper.rb +1 -0
- metadata +21 -6
@@ -1,6 +1,8 @@
|
|
1
1
|
# Commonly used webrat steps
|
2
2
|
# http://github.com/brynary/webrat
|
3
3
|
|
4
|
+
require 'webrat' if !defined?(Webrat) # Because some people have it installed as a Gem
|
5
|
+
|
4
6
|
When /^I press "(.*)"$/ do |button|
|
5
7
|
clicks_button(button)
|
6
8
|
end
|
@@ -17,6 +19,53 @@ When /^I select "(.*)" from "(.*)"$/ do |value, field|
|
|
17
19
|
selects(value, :from => field)
|
18
20
|
end
|
19
21
|
|
22
|
+
# Use this step in conjunction with Rail's datetime_select helper. For example:
|
23
|
+
# When I select "December 25, 2008 10:00" as the date and time
|
24
|
+
When /^I select "(.*)" as the date and time$/ do |time|
|
25
|
+
selects_datetime(time)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Use this step when using multiple datetime_select helpers on a page or
|
29
|
+
# you want to specify which datetime to select. Given the following view:
|
30
|
+
# <%= f.label :preferred %><br />
|
31
|
+
# <%= f.datetime_select :preferred %>
|
32
|
+
# <%= f.label :alternative %><br />
|
33
|
+
# <%= f.datetime_select :alternative %>
|
34
|
+
# The following steps would fill out the form:
|
35
|
+
# When I select "November 23, 2004 11:20" as the "Preferred" data and time
|
36
|
+
# And I select "November 25, 2004 10:30" as the "Alternative" data and time
|
37
|
+
When /^I select "(.*)" as the "(.*)" date and time$/ do |datetime, datetime_label|
|
38
|
+
selects_datetime(datetime, :from => datetime_label)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Use this step in conjuction with Rail's time_select helper. For example:
|
42
|
+
# When I select "2:20PM" as the time
|
43
|
+
# Note: Rail's default time helper provides 24-hour time-- not 12 hour time. Webrat
|
44
|
+
# will convert the 2:20PM to 14:20 and then select it.
|
45
|
+
When /^I select "(.*)" as the time$/ do |time|
|
46
|
+
selects_time(time)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Use this step when using multiple time_select helpers on a page or you want to
|
50
|
+
# specify the name of the time on the form. For example:
|
51
|
+
# When I select "7:30AM" as the "Gym" time
|
52
|
+
When /^I select "(.*)" as the "(.*)" time$/ do |time, time_label|
|
53
|
+
selects_time(time, :from => time_label)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Use this step in conjuction with Rail's date_select helper. For example:
|
57
|
+
# When I select "February 20, 1981" as the date
|
58
|
+
When /^I select "(.*)" as the date$/ do |date|
|
59
|
+
selects_date(date)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Use this step when using multiple date_select helpers on one page or
|
63
|
+
# you want to specify the name of the date on the form. For example:
|
64
|
+
# When I select "April 26, 1982" as the "Date of Birth" date
|
65
|
+
When /^I select "(.*)" as the "(.*)" date$/ do |date, date_label|
|
66
|
+
selects_date(date, :from => date_label)
|
67
|
+
end
|
68
|
+
|
20
69
|
When /^I check "(.*)"$/ do |field|
|
21
70
|
checks(field)
|
22
71
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Feature: Manage <%= plural_name %>
|
2
|
-
In order to
|
3
|
-
|
4
|
-
|
2
|
+
In order to [goal]
|
3
|
+
[stakeholder]
|
4
|
+
wants [behaviour]
|
5
5
|
|
6
6
|
Scenario: Register new <%= singular_name %>
|
7
7
|
Given I am on the new <%= singular_name %> page
|
data/spec/cucumber/cli_spec.rb
CHANGED
@@ -5,13 +5,17 @@ module Cucumber
|
|
5
5
|
describe CLI do
|
6
6
|
|
7
7
|
def mock_executor(stubs = {})
|
8
|
-
stub('executor', {:visit_features => nil, :failed => false, :formatters= => nil}.merge(stubs))
|
8
|
+
stub('executor', {:visit_features => nil, :lines_for_features= => nil, :failed => false, :formatters= => nil}.merge(stubs))
|
9
9
|
end
|
10
10
|
|
11
11
|
def mock_broadcaster(stubs = {})
|
12
12
|
stub(Broadcaster, {:register => nil}.merge(stubs))
|
13
13
|
end
|
14
14
|
|
15
|
+
def mock_features(stubs ={})
|
16
|
+
stub('features', {:<< => nil}.merge(stubs))
|
17
|
+
end
|
18
|
+
|
15
19
|
before(:each) do
|
16
20
|
Kernel.stub!(:exit)
|
17
21
|
end
|
@@ -101,6 +105,40 @@ Defined profiles in cucumber.yml:
|
|
101
105
|
cli.options[:source].should be_false
|
102
106
|
end
|
103
107
|
|
108
|
+
it "should accept --verbose option" do
|
109
|
+
cli = CLI.new
|
110
|
+
cli.parse_options!(%w{--verbose})
|
111
|
+
|
112
|
+
cli.options[:verbose].should be_true
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "verbose mode" do
|
116
|
+
|
117
|
+
before(:each) do
|
118
|
+
@out = StringIO.new
|
119
|
+
@cli = CLI.new(@out)
|
120
|
+
@cli.stub!(:require)
|
121
|
+
Dir.stub!(:[])
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should show ruby files required" do
|
125
|
+
@cli.parse_options!(%w{--verbose --require example.rb})
|
126
|
+
@cli.execute!(stub('step mother'), mock_executor, mock_features)
|
127
|
+
|
128
|
+
@out.string.should include('example.rb')
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should show feature files parsed" do
|
132
|
+
TreetopParser::FeatureParser.stub!(:new).and_return(mock("feature parser", :parse_feature => nil))
|
133
|
+
|
134
|
+
@cli.parse_options!(%w{--verbose example.feature})
|
135
|
+
@cli.execute!(stub('step mother'), mock_executor, mock_features)
|
136
|
+
|
137
|
+
@out.string.should include('example.feature')
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
104
142
|
it "should accept --out option" do
|
105
143
|
cli = CLI.new
|
106
144
|
File.should_receive(:open).with('jalla.txt', 'w')
|
@@ -180,6 +218,106 @@ Defined profiles in cucumber.yml:
|
|
180
218
|
cli.execute!(stub('step mother'), mock_executor, stub('features'))
|
181
219
|
end
|
182
220
|
|
221
|
+
describe "external formatter" do
|
222
|
+
|
223
|
+
describe "exists and valid constructor" do
|
224
|
+
|
225
|
+
before(:each) do
|
226
|
+
@mock_formatter_class = mock('formatter class')
|
227
|
+
Kernel.stub!(:const_get).and_return(@mock_formatter_class)
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should create the formatter" do
|
231
|
+
cli = CLI.new
|
232
|
+
mock_formatter = mock('magical formatter')
|
233
|
+
cli.parse_options!(%w{--format magical})
|
234
|
+
|
235
|
+
@mock_formatter_class.should_receive(:new)
|
236
|
+
|
237
|
+
cli.execute!(stub('step mother'), mock_executor, stub('features'))
|
238
|
+
end
|
239
|
+
|
240
|
+
it "should register the formatter with broadcaster" do
|
241
|
+
cli = CLI.new
|
242
|
+
broadcaster = Broadcaster.new
|
243
|
+
mock_formatter = mock('magical formatter')
|
244
|
+
Broadcaster.stub!(:new).and_return(broadcaster, stub("output broadcaster", :register => nil))
|
245
|
+
@mock_formatter_class.stub!(:new).and_return(mock_formatter)
|
246
|
+
cli.parse_options!(%w{--format magical})
|
247
|
+
|
248
|
+
broadcaster.should_receive(:register).with(mock_formatter)
|
249
|
+
|
250
|
+
cli.execute!(stub('step mother'), mock_executor, stub('features'))
|
251
|
+
end
|
252
|
+
|
253
|
+
end
|
254
|
+
|
255
|
+
describe "exists but invalid constructor" do
|
256
|
+
|
257
|
+
before(:each) do
|
258
|
+
@out = StringIO.new
|
259
|
+
@error = StringIO.new
|
260
|
+
@cli = CLI.new(@out, @error)
|
261
|
+
|
262
|
+
mock_formatter_class = stub('formatter class')
|
263
|
+
mock_formatter_class.stub!(:new).and_raise("No such method")
|
264
|
+
Kernel.stub!(:const_get).and_return(mock_formatter_class)
|
265
|
+
|
266
|
+
@cli.parse_options!(%w{--format exists_but_evil})
|
267
|
+
end
|
268
|
+
|
269
|
+
it "should show exception" do
|
270
|
+
Kernel.stub!(:exit)
|
271
|
+
|
272
|
+
@cli.execute!(stub('step mother'), mock_executor, stub('features'))
|
273
|
+
|
274
|
+
@error.string.should include("No such method")
|
275
|
+
end
|
276
|
+
|
277
|
+
it "should exit" do
|
278
|
+
Kernel.should_receive(:exit)
|
279
|
+
|
280
|
+
@cli.execute!(stub('step mother'), mock_executor, stub('features'))
|
281
|
+
end
|
282
|
+
|
283
|
+
end
|
284
|
+
|
285
|
+
describe "non-existent" do
|
286
|
+
|
287
|
+
before(:each) do
|
288
|
+
@out = StringIO.new
|
289
|
+
@error = StringIO.new
|
290
|
+
@cli = CLI.new(@out, @error)
|
291
|
+
|
292
|
+
@cli.parse_options!(%w{--format invalid})
|
293
|
+
end
|
294
|
+
|
295
|
+
it "should display a format error" do
|
296
|
+
Kernel.stub!(:exit)
|
297
|
+
|
298
|
+
@cli.execute!(stub('step mother'), mock_executor, stub('features'))
|
299
|
+
|
300
|
+
@error.string.should include("Invalid format: invalid\n")
|
301
|
+
end
|
302
|
+
|
303
|
+
it "should display --help" do
|
304
|
+
Kernel.stub!(:exit)
|
305
|
+
|
306
|
+
@cli.execute!(stub('step mother'), mock_executor, stub('features'))
|
307
|
+
|
308
|
+
@out.string.should include("Usage: cucumber")
|
309
|
+
end
|
310
|
+
|
311
|
+
it "should exit" do
|
312
|
+
Kernel.should_receive(:exit)
|
313
|
+
|
314
|
+
@cli.execute!(stub('step mother'), mock_executor, stub('features'))
|
315
|
+
end
|
316
|
+
|
317
|
+
end
|
318
|
+
|
319
|
+
end
|
320
|
+
|
183
321
|
it "should accept multiple --scenario options" do
|
184
322
|
cli = CLI.new
|
185
323
|
cli.parse_options!(['--scenario', "User logs in", '--scenario', "User signs up"])
|
@@ -227,6 +365,38 @@ Defined profiles in cucumber.yml:
|
|
227
365
|
cli.execute!(stub('step mother'), mock_executor, stub('features'))
|
228
366
|
end
|
229
367
|
|
368
|
+
describe "example.feature:line file arguments" do
|
369
|
+
|
370
|
+
it "should extract line numbers" do
|
371
|
+
cli = CLI.new
|
372
|
+
cli.parse_options!(%w{example.feature:10})
|
373
|
+
|
374
|
+
cli.options[:lines_for_features]['example.feature'].should == [10]
|
375
|
+
end
|
376
|
+
|
377
|
+
it "should remove line numbers" do
|
378
|
+
cli = CLI.new
|
379
|
+
cli.parse_options!(%w{example.feature:10})
|
380
|
+
|
381
|
+
cli.paths.should == ["example.feature"]
|
382
|
+
end
|
383
|
+
|
384
|
+
it "should support multiple feature:line numbers" do
|
385
|
+
cli = CLI.new
|
386
|
+
cli.parse_options!(%w{example.feature:11 another_example.feature:12})
|
387
|
+
|
388
|
+
cli.options[:lines_for_features].should == {'another_example.feature' => [12], 'example.feature' => [11]}
|
389
|
+
end
|
390
|
+
|
391
|
+
it "should accept multiple line numbers for a single feature" do
|
392
|
+
cli = CLI.new
|
393
|
+
cli.parse_options!(%w{example.feature:11:12})
|
394
|
+
|
395
|
+
cli.options[:lines_for_features].should == {'example.feature' => [11, 12]}
|
396
|
+
end
|
397
|
+
|
398
|
+
end
|
399
|
+
|
230
400
|
it "should search for all features in the specified directory" do
|
231
401
|
cli = CLI.new
|
232
402
|
|
@@ -235,7 +405,7 @@ Defined profiles in cucumber.yml:
|
|
235
405
|
|
236
406
|
Dir.should_receive(:[]).with("feature_directory/**/*.feature").any_number_of_times.and_return([])
|
237
407
|
|
238
|
-
cli.execute!(stub('step mother'), mock_executor,
|
408
|
+
cli.execute!(stub('step mother'), mock_executor, mock_features)
|
239
409
|
end
|
240
410
|
|
241
411
|
end
|
@@ -3,6 +3,17 @@ require 'stringio'
|
|
3
3
|
|
4
4
|
module Cucumber
|
5
5
|
describe Executor do
|
6
|
+
|
7
|
+
def mock_scenario(stubs = {})
|
8
|
+
@scenario ||= stub("scenario", {
|
9
|
+
:row? => false,
|
10
|
+
:name => 'test',
|
11
|
+
:accept => nil,
|
12
|
+
:steps => [],
|
13
|
+
:pending? => true
|
14
|
+
}.merge(stubs))
|
15
|
+
end
|
16
|
+
|
6
17
|
before do # TODO: Way more setup and duplication of lib code. Use lib code!
|
7
18
|
@io = StringIO.new
|
8
19
|
@step_mother = StepMother.new
|
@@ -35,19 +46,47 @@ module Cucumber
|
|
35
46
|
|
36
47
|
1)
|
37
48
|
dang
|
38
|
-
#{__FILE__}:
|
49
|
+
#{__FILE__}:43:in `Then /I should owe (\\d*) cucumbers/'
|
39
50
|
#{@feature_file}:9:in `Then I should owe 7 cucumbers'
|
40
51
|
})
|
41
52
|
end
|
42
53
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
54
|
+
describe "creating a world" do
|
55
|
+
module DoitExtension
|
56
|
+
def doit
|
57
|
+
"dunit"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
module BeatitExtension
|
62
|
+
def beatit
|
63
|
+
"beatenit"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should yield an Object to the world proc" do
|
68
|
+
@executor.register_world_proc do |world|
|
69
|
+
world.extend(DoitExtension)
|
70
|
+
end
|
71
|
+
@executor.register_world_proc do |world|
|
72
|
+
world.extend(BeatitExtension)
|
73
|
+
end
|
74
|
+
world = @executor.create_world
|
75
|
+
world.doit.should == "dunit"
|
76
|
+
world.beatit.should == "beatenit"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "visiting feature" do
|
81
|
+
|
82
|
+
it "should set the feature file being visited" do
|
83
|
+
mock_feature = mock('feature', :file => 'womble.feature', :scenarios => [])
|
84
|
+
@executor.visit_feature(mock_feature)
|
85
|
+
|
86
|
+
@executor.instance_variable_get('@feature_file').should == 'womble.feature'
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
51
90
|
|
52
91
|
describe "visiting steps" do
|
53
92
|
def make_regex(a,b,c)
|
@@ -139,21 +178,22 @@ dang
|
|
139
178
|
describe "without having first run the matching regular scenario" do
|
140
179
|
|
141
180
|
before(:each) do
|
142
|
-
@
|
143
|
-
@executor.
|
144
|
-
@executor.visit_regular_scenario(@
|
181
|
+
@regular_scenario = Tree::Scenario.new(nil, 'test', 1)
|
182
|
+
@executor.lines_for_features = Hash.new([5])
|
183
|
+
@executor.visit_regular_scenario(@regular_scenario)
|
145
184
|
end
|
146
185
|
|
147
186
|
it "should run the regular scenario before the row scenario" do
|
148
|
-
@
|
149
|
-
|
150
|
-
|
187
|
+
@regular_scenario.should_receive(:accept)
|
188
|
+
row_scenario = mock_row_scenario(:name => 'test', :at_line? => true)
|
189
|
+
row_scenario.should_receive(:accept)
|
190
|
+
@executor.visit_row_scenario(row_scenario)
|
151
191
|
end
|
152
192
|
|
153
193
|
it "should run the row scenario after running the regular scenario" do
|
154
|
-
mock_row_scenario(:at_line? => true)
|
155
|
-
|
156
|
-
@executor.visit_row_scenario(
|
194
|
+
row_scenario = mock_row_scenario(:at_line? => true)
|
195
|
+
row_scenario.should_receive(:accept)
|
196
|
+
@executor.visit_row_scenario(row_scenario)
|
157
197
|
end
|
158
198
|
|
159
199
|
end
|
@@ -172,18 +212,53 @@ dang
|
|
172
212
|
end
|
173
213
|
end
|
174
214
|
|
175
|
-
describe "
|
215
|
+
describe "visiting scenarios" do
|
216
|
+
|
217
|
+
it "should check if a scenario is at the specified line number" do
|
218
|
+
mock_scenario = mock('scenario', :null_object => true)
|
219
|
+
@executor.lines_for_features = Hash.new([1])
|
176
220
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
:name => 'test',
|
181
|
-
:accept => nil,
|
182
|
-
:steps => [],
|
183
|
-
:pending? => true
|
184
|
-
}.merge(stubs))
|
221
|
+
mock_scenario.should_receive(:at_line?).with(1)
|
222
|
+
|
223
|
+
@executor.visit_scenario(mock_scenario)
|
185
224
|
end
|
186
|
-
|
225
|
+
|
226
|
+
describe "with specific features and lines" do
|
227
|
+
|
228
|
+
it "should check if a scenario is at the specified feature line number" do
|
229
|
+
@executor.instance_variable_set('@feature_file', 'sell_cucumbers.feature')
|
230
|
+
@executor.lines_for_features = {'sell_cucumbers.feature' => [11]}
|
231
|
+
|
232
|
+
mock_scenario.should_receive(:at_line?).with(11).and_return(false)
|
233
|
+
|
234
|
+
@executor.visit_scenario(mock_scenario)
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should not check feature line numbers if --line is already set" do
|
238
|
+
@executor.instance_variable_set('@feature_file', 'sell_cucumbers.feature')
|
239
|
+
@executor.lines_for_features = {'sell_cucumbers.feature' => [11]}
|
240
|
+
@executor.lines_for_features = Hash.new([5])
|
241
|
+
|
242
|
+
mock_scenario.should_not_receive(:at_line?).with(11).and_return(false)
|
243
|
+
|
244
|
+
@executor.visit_scenario(mock_scenario)
|
245
|
+
end
|
246
|
+
|
247
|
+
it "should not check feature line numbers if the current feature file does not have lines specified" do
|
248
|
+
@executor.instance_variable_set('@feature_file', 'beetlejuice.feature')
|
249
|
+
@executor.lines_for_features = {'sell_cucumbers.feature' => [11]}
|
250
|
+
|
251
|
+
mock_scenario.should_not_receive(:at_line?).with(11).and_return(false)
|
252
|
+
|
253
|
+
@executor.visit_scenario(mock_scenario)
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
259
|
+
|
260
|
+
describe "caching visited scenarios" do
|
261
|
+
|
187
262
|
it "should reset cache after each feature visit" do
|
188
263
|
Tree::Scenario.stub!(:new).and_return(mock_scenario)
|
189
264
|
|
@@ -218,5 +293,6 @@ dang
|
|
218
293
|
@executor.visit_features(@features)
|
219
294
|
end
|
220
295
|
end
|
296
|
+
|
221
297
|
end
|
222
298
|
end
|