cucumber 0.1.9 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/History.txt +31 -1
  2. data/Manifest.txt +15 -0
  3. data/bin/cucumber +2 -1
  4. data/config/hoe.rb +2 -1
  5. data/examples/calculator_ruby_features/features/addition.rb +1 -1
  6. data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +1 -0
  7. data/examples/i18n/de/Rakefile +6 -0
  8. data/examples/i18n/de/features/addition.feature +17 -0
  9. data/examples/i18n/de/features/division.feature +10 -0
  10. data/examples/i18n/de/features/step_definitons/calculator_steps.rb +30 -0
  11. data/examples/i18n/de/lib/calculator.rb +14 -0
  12. data/examples/i18n/en/Rakefile +1 -0
  13. data/examples/i18n/lt/Rakefile +6 -0
  14. data/examples/i18n/lt/features/addition.feature +17 -0
  15. data/examples/i18n/lt/features/division.feature +10 -0
  16. data/examples/i18n/lt/features/step_definitons/calculator_steps.rb +31 -0
  17. data/examples/i18n/lt/lib/calculator.rb +14 -0
  18. data/examples/test_unit/Rakefile +6 -0
  19. data/examples/test_unit/features/step_definitions/test_unit_steps.rb +26 -0
  20. data/examples/test_unit/features/test_unit.feature +9 -0
  21. data/examples/tickets/features/tickets.feature +4 -2
  22. data/lib/autotest/discover.rb +1 -1
  23. data/lib/cucumber.rb +3 -3
  24. data/lib/cucumber/cli.rb +16 -6
  25. data/lib/cucumber/core_ext/proc.rb +31 -16
  26. data/lib/cucumber/executor.rb +35 -15
  27. data/lib/cucumber/formatters/ansicolor.rb +11 -13
  28. data/lib/cucumber/languages.yml +13 -1
  29. data/lib/cucumber/platform.rb +12 -0
  30. data/lib/cucumber/step_mother.rb +7 -1
  31. data/lib/cucumber/tree/feature.rb +3 -1
  32. data/lib/cucumber/tree/scenario.rb +17 -1
  33. data/lib/cucumber/treetop_parser/feature_de.rb +8 -8
  34. data/lib/cucumber/treetop_parser/feature_lt.rb +1591 -0
  35. data/lib/cucumber/version.rb +1 -1
  36. data/rails_generators/cucumber/templates/webrat_steps.rb +49 -0
  37. data/rails_generators/feature/templates/feature.erb +3 -3
  38. data/spec/cucumber/cli_spec.rb +33 -1
  39. data/spec/cucumber/executor_spec.rb +104 -28
  40. data/spec/cucumber/step_mother_spec.rb +7 -7
  41. data/spec/cucumber/tree/feature_spec.rb +31 -0
  42. data/spec/cucumber/tree/row_scenario_spec.rb +30 -0
  43. data/spec/spec_helper.rb +1 -0
  44. metadata +22 -7
@@ -2,7 +2,7 @@ module Cucumber #:nodoc:
2
2
  class VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- TINY = 9
5
+ TINY = 10
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -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 keep track of <%= plural_name %>
3
- A <%= singular_name %> mechanic
4
- Should be able to manage several <%= plural_name %>
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
@@ -5,7 +5,7 @@ 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 = {})
@@ -227,6 +227,38 @@ Defined profiles in cucumber.yml:
227
227
  cli.execute!(stub('step mother'), mock_executor, stub('features'))
228
228
  end
229
229
 
230
+ describe "example.feature:line file arguments" do
231
+
232
+ it "should extract line numbers" do
233
+ cli = CLI.new
234
+ cli.parse_options!(%w{example.feature:10})
235
+
236
+ cli.options[:lines_for_features]['example.feature'].should == [10]
237
+ end
238
+
239
+ it "should remove line numbers" do
240
+ cli = CLI.new
241
+ cli.parse_options!(%w{example.feature:10})
242
+
243
+ cli.paths.should == ["example.feature"]
244
+ end
245
+
246
+ it "should support multiple feature:line numbers" do
247
+ cli = CLI.new
248
+ cli.parse_options!(%w{example.feature:11 another_example.feature:12})
249
+
250
+ cli.options[:lines_for_features].should == {'another_example.feature' => [12], 'example.feature' => [11]}
251
+ end
252
+
253
+ it "should accept multiple line numbers for a single feature" do
254
+ cli = CLI.new
255
+ cli.parse_options!(%w{example.feature:11:12})
256
+
257
+ cli.options[:lines_for_features].should == {'example.feature' => [11, 12]}
258
+ end
259
+
260
+ end
261
+
230
262
  it "should search for all features in the specified directory" do
231
263
  cli = CLI.new
232
264
 
@@ -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__}:32:in `Then /I should owe (\\d*) cucumbers/'
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
- # it "should allow calling of other steps from steps" do
44
- # @executor.register_step_proc("call me please") { @x = 1 }
45
- # @executor.register_step_proc("I will call you") { @executor.register_step_proc("call me please") }
46
- # @executor.register_step_proc(/I should owe (\d*) cucumbers/) { |n| @n.should == -n.to_i }
47
- # @feature.accept(@executor)
48
- # @formatters.each { |formatter| formatter.dump }
49
- # @io.string.should == "...\n"
50
- # end
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
- @scenario = Tree::Scenario.new(nil, 'test', 1)
143
- @executor.line=5
144
- @executor.visit_regular_scenario(@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
- @scenario.should_receive(:accept)
149
-
150
- @executor.visit_row_scenario(mock_row_scenario(:name => 'test', :at_line? => true, :accept => nil))
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).should_receive(:accept)
155
-
156
- @executor.visit_row_scenario(mock_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 "caching visited scenarios" do
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
- def mock_scenario(stubs = {})
178
- @scenario ||= stub("scenario", {
179
- :row? => false,
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
@@ -50,13 +50,6 @@ module Cucumber
50
50
  end
51
51
  end
52
52
 
53
- it "should mark a step as pending if it does not have a proc" do
54
- m = StepMother.new
55
- m.register_step_proc /I have no body/
56
- regexp, args, proc = m.regexp_args_proc "I have no body"
57
- proc.should == StepMother::PENDING
58
- end
59
-
60
53
  it "should report that a step has a definition if the step is registered" do
61
54
  m = StepMother.new
62
55
  m.register_step_proc /I am a real step definition/ do end
@@ -69,6 +62,13 @@ module Cucumber
69
62
 
70
63
  m.has_step_definition?('I am a step without a definition').should be_false
71
64
  end
65
+
66
+ it "should explain to the programmer that step definitions always need a proc" do
67
+ m = StepMother.new
68
+ lambda do
69
+ m.register_step_proc(/no milk today/)
70
+ end.should raise_error(MissingProc, "Step definitions must always have a proc")
71
+ end
72
72
 
73
73
  end
74
74
  end
@@ -3,10 +3,41 @@ require File.dirname(__FILE__) + '/../../spec_helper'
3
3
  module Cucumber
4
4
  module Tree
5
5
  describe Feature do
6
+
6
7
  it "should have padding_length 2 when alone" do
7
8
  feature = Feature.new('header')
8
9
  feature.padding_length.should == 2
9
10
  end
11
+
12
+ describe "creating a Scenario" do
13
+
14
+ it "should create a new scenario for a feature" do
15
+ feature = Feature.new('header')
16
+
17
+ Scenario.should_receive(:new).with(feature, 'test scenario', "19")
18
+
19
+ feature.Scenario('test scenario') {}
20
+ end
21
+
22
+ end
23
+
24
+ describe "creating a Table" do
25
+
26
+ it "should set the table header of the template scenario" do
27
+ feature = Feature.new('header')
28
+ mock_scenario = mock("scenario", :update_table_column_widths => nil)
29
+ Scenario.stub!(:new).and_return(mock_scenario)
30
+ feature.add_scenario('scenario', 5)
31
+
32
+ mock_scenario.should_receive(:table_header=).with(["input_1", "input_2"])
33
+
34
+ feature.Table do |t|
35
+ t | "input_1" | "input_2" | t
36
+ t | 1 | 2 | t
37
+ end
38
+ end
39
+
40
+ end
10
41
  end
11
42
  end
12
43
  end
@@ -4,6 +4,10 @@ module Cucumber
4
4
  module Tree
5
5
  describe RowScenario do
6
6
 
7
+ def mock_scenario(stubs = {})
8
+ mock('scenario', {:update_table_column_widths => nil, :steps => []}.merge(stubs))
9
+ end
10
+
7
11
  describe "pending?" do
8
12
  before :each do
9
13
  @scenario = Scenario.new(nil, '', 1)
@@ -18,8 +22,34 @@ module Cucumber
18
22
  @scenario.create_step('Given', 'a long step', 1)
19
23
  @row_scenario.should_not be_pending
20
24
  end
25
+ end
26
+
27
+ describe "generating row steps" do
28
+
29
+ it "should cache unbound steps" do
30
+ row_scenario = RowScenario.new(mock('feature'), mock_scenario, [], 1)
31
+
32
+ row_scenario.steps.should equal(row_scenario.steps)
33
+ end
21
34
 
35
+ it "should cache bound steps" do
36
+ mock_step = mock('step', :arity => 1)
37
+ row_scenario = RowScenario.new(mock('feature'), mock_scenario(:steps => [mock_step]), [], 1)
38
+
39
+ row_scenario.steps.should equal(row_scenario.steps)
40
+ end
41
+
42
+ it "should regenerate row steps when scenario template steps have been matched" do
43
+ mock_step = mock('step', :arity => 0)
44
+ row_scenario = RowScenario.new(mock('feature'), mock_scenario(:steps => [mock_step]), [], 1)
45
+ unbound_steps = row_scenario.steps
46
+ mock_step.stub!(:arity => 1)
47
+
48
+ unbound_steps.should_not equal(row_scenario.steps)
49
+ end
50
+
22
51
  end
52
+
23
53
  end
24
54
  end
25
55
  end
@@ -2,6 +2,7 @@ require 'rubygems'
2
2
  gem 'rspec'
3
3
  require 'spec'
4
4
 
5
+ $KCODE='u'
5
6
  $:.unshift(File.dirname(__FILE__) + '/../lib')
6
7
  require 'cucumber'
7
8
  require 'cucumber/treetop_parser/feature_en'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cucumber
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Aslak Helles\xC3\xB8y"
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-12 00:00:00 +01:00
12
+ date: 2008-11-25 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -33,24 +33,24 @@ dependencies:
33
33
  version: 1.2.4
34
34
  version:
35
35
  - !ruby/object:Gem::Dependency
36
- name: rspec
36
+ name: diff-lcs
37
37
  type: :runtime
38
38
  version_requirement:
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
41
  - - ">="
42
42
  - !ruby/object:Gem::Version
43
- version: 1.1.5
43
+ version: 1.1.2
44
44
  version:
45
45
  - !ruby/object:Gem::Dependency
46
- name: diff-lcs
47
- type: :runtime
46
+ name: rspec
47
+ type: :development
48
48
  version_requirement:
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: 1.1.2
53
+ version: 1.1.11
54
54
  version:
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: hoe
@@ -109,6 +109,11 @@ files:
109
109
  - examples/i18n/da/features/step_definitons/kalkulator_steps.rb
110
110
  - examples/i18n/da/features/summering.feature
111
111
  - examples/i18n/da/lib/kalkulator.rb
112
+ - examples/i18n/de/Rakefile
113
+ - examples/i18n/de/features/addition.feature
114
+ - examples/i18n/de/features/division.feature
115
+ - examples/i18n/de/features/step_definitons/calculator_steps.rb
116
+ - examples/i18n/de/lib/calculator.rb
112
117
  - examples/i18n/en/Rakefile
113
118
  - examples/i18n/en/features/addition.feature
114
119
  - examples/i18n/en/features/division.feature
@@ -141,6 +146,11 @@ files:
141
146
  - examples/i18n/ja/features/division.feature
142
147
  - examples/i18n/ja/features/step_definitons/calculator_steps.rb
143
148
  - examples/i18n/ja/lib/calculator.rb
149
+ - examples/i18n/lt/Rakefile
150
+ - examples/i18n/lt/features/addition.feature
151
+ - examples/i18n/lt/features/division.feature
152
+ - examples/i18n/lt/features/step_definitons/calculator_steps.rb
153
+ - examples/i18n/lt/lib/calculator.rb
144
154
  - examples/i18n/no/Rakefile
145
155
  - examples/i18n/no/features/step_definitons/kalkulator_steps.rb
146
156
  - examples/i18n/no/features/summering.feature
@@ -171,6 +181,9 @@ files:
171
181
  - examples/selenium/Rakefile
172
182
  - examples/selenium/features/search.feature
173
183
  - examples/selenium/features/step_definitons/stories_steps.rb
184
+ - examples/test_unit/Rakefile
185
+ - examples/test_unit/features/step_definitions/test_unit_steps.rb
186
+ - examples/test_unit/features/test_unit.feature
174
187
  - examples/tickets/Rakefile
175
188
  - examples/tickets/cucumber.yml
176
189
  - examples/tickets/features/step_definitons/tickets_steps.rb
@@ -213,6 +226,7 @@ files:
213
226
  - lib/cucumber/languages.yml
214
227
  - lib/cucumber/model.rb
215
228
  - lib/cucumber/model/table.rb
229
+ - lib/cucumber/platform.rb
216
230
  - lib/cucumber/rails/rspec.rb
217
231
  - lib/cucumber/rails/world.rb
218
232
  - lib/cucumber/rake/task.rb
@@ -239,6 +253,7 @@ files:
239
253
  - lib/cucumber/treetop_parser/feature_id.rb
240
254
  - lib/cucumber/treetop_parser/feature_it.rb
241
255
  - lib/cucumber/treetop_parser/feature_ja.rb
256
+ - lib/cucumber/treetop_parser/feature_lt.rb
242
257
  - lib/cucumber/treetop_parser/feature_nl.rb
243
258
  - lib/cucumber/treetop_parser/feature_no.rb
244
259
  - lib/cucumber/treetop_parser/feature_parser.rb