cucumber 0.3.95 → 0.3.96

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/History.txt +21 -0
  2. data/Manifest.txt +9 -3
  3. data/examples/sinatra/features/support/env.rb +1 -3
  4. data/features/cucumber_cli.feature +1 -0
  5. data/features/drb_server_integration.feature +56 -3
  6. data/features/junit_formatter.feature +23 -12
  7. data/features/step_definitions/cucumber_steps.rb +13 -2
  8. data/features/support/env.rb +19 -3
  9. data/lib/cucumber/ast/feature_element.rb +1 -1
  10. data/lib/cucumber/ast/step.rb +1 -1
  11. data/lib/cucumber/ast/step_invocation.rb +3 -2
  12. data/lib/cucumber/cli/configuration.rb +9 -25
  13. data/lib/cucumber/cli/drb_client.rb +7 -3
  14. data/lib/cucumber/cli/language_help_formatter.rb +4 -4
  15. data/lib/cucumber/cli/main.rb +26 -46
  16. data/lib/cucumber/cli/options.rb +3 -0
  17. data/lib/cucumber/constantize.rb +28 -0
  18. data/lib/cucumber/feature_file.rb +3 -3
  19. data/lib/cucumber/formatter/junit.rb +13 -9
  20. data/lib/cucumber/formatter/pretty.rb +2 -2
  21. data/lib/cucumber/language_support/hook_methods.rb +9 -0
  22. data/lib/cucumber/language_support/language_methods.rb +47 -0
  23. data/lib/cucumber/language_support/step_definition_methods.rb +44 -0
  24. data/lib/cucumber/parser/natural_language.rb +72 -0
  25. data/lib/cucumber/rb_support/rb_dsl.rb +73 -0
  26. data/lib/cucumber/rb_support/rb_hook.rb +19 -0
  27. data/lib/cucumber/rb_support/rb_language.rb +129 -0
  28. data/lib/cucumber/rb_support/rb_step_definition.rb +56 -0
  29. data/lib/cucumber/step_match.rb +2 -2
  30. data/lib/cucumber/step_mother.rb +87 -206
  31. data/lib/cucumber/version.rb +1 -1
  32. data/lib/cucumber/webrat/element_locator.rb +7 -7
  33. data/lib/cucumber/world.rb +28 -8
  34. data/rails_generators/cucumber/templates/cucumber_environment.rb +2 -2
  35. data/rails_generators/cucumber/templates/spork_env.rb +0 -2
  36. data/rails_generators/cucumber/templates/webrat_steps.rb +17 -0
  37. data/spec/cucumber/ast/background_spec.rb +8 -5
  38. data/spec/cucumber/ast/feature_factory.rb +4 -5
  39. data/spec/cucumber/ast/feature_spec.rb +7 -1
  40. data/spec/cucumber/ast/scenario_outline_spec.rb +10 -6
  41. data/spec/cucumber/ast/scenario_spec.rb +8 -3
  42. data/spec/cucumber/ast/step_collection_spec.rb +2 -2
  43. data/spec/cucumber/cli/configuration_spec.rb +15 -0
  44. data/spec/cucumber/cli/drb_client_spec.rb +35 -1
  45. data/spec/cucumber/cli/main_spec.rb +5 -4
  46. data/spec/cucumber/cli/options_spec.rb +6 -0
  47. data/spec/cucumber/parser/feature_parser_spec.rb +6 -5
  48. data/spec/cucumber/parser/table_parser_spec.rb +1 -1
  49. data/spec/cucumber/step_definition_spec.rb +26 -25
  50. data/spec/cucumber/step_mother_spec.rb +46 -41
  51. data/spec/cucumber/world/pending_spec.rb +4 -5
  52. metadata +11 -5
  53. data/lib/cucumber/cli/rb_step_def_loader.rb +0 -14
  54. data/lib/cucumber/parser/i18n/language.rb +0 -87
  55. data/lib/cucumber/step_definition.rb +0 -122
@@ -2,7 +2,7 @@ module Cucumber #:nodoc:
2
2
  class VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 3
5
- TINY = 95
5
+ TINY = 96
6
6
  PATCH = nil # Set to nil for official release
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PATCH].compact.join('.')
@@ -1,15 +1,15 @@
1
1
  module Webrat
2
2
  class Element
3
- # Returns an Array of Array of String where each String is the
4
- # a "cell" in the table-like structure represented by this Element.
3
+ # Returns an Array of Array of String where each String is a
4
+ # "cell" in the table-like structure represented by this Element.
5
5
  #
6
- # Supported elements are table, dl, ol and ul. The return value depends
7
- # on the type of the element:
6
+ # Supported elements are table, dl, ol and ul. Different conversion
7
+ # strategies are used depending on the kind of element:
8
8
  #
9
- # * table : Each tr is a row. The innerHTML of each tr or th becomes cells. The number
9
+ # * table : Each tr becomes a row. The innerHTML of each td or th inside becomes a cell. The number
10
10
  # of columns is determined by the number of cells in the first row.
11
- # * dl : Each dt creates a row with 2 cells. The innerHTML of the dt itself and the next dd become cells.
12
- # * ul or ol : Each ul creates a row with one cell, the innerHTML of the ul.
11
+ # * dl : Each dt becomes a row with 2 cells. The innerHTML of the dt itself and the next dd become cells.
12
+ # * ul or ol : Each li becomes a row with one cell, the innerHTML of the li.
13
13
  #
14
14
  def to_table
15
15
  case element.name
@@ -7,23 +7,43 @@ module Cucumber
7
7
  end
8
8
  end
9
9
 
10
- attr_writer :__cucumber_step_mother, :__cucumber_visitor, :__cucumber_current_step
10
+ attr_writer :__cucumber_step_mother
11
11
 
12
12
  # Call a step from within a step definition
13
13
  def __cucumber_invoke(name, multiline_argument=nil) #:nodoc:
14
14
  begin
15
15
  step_match = @__cucumber_step_mother.step_match(name)
16
- step_match.invoke(self, multiline_argument)
16
+ step_match.invoke(multiline_argument)
17
17
  rescue Exception => e
18
18
  e.nested! if Undefined === e
19
- @__cucumber_current_step.exception = e if @__cucumber_current_step
20
19
  raise e
21
20
  end
22
21
  end
23
-
24
- def table(text, file=nil, line_offset=0)
25
- @table_parser ||= Parser::TableParser.new
26
- @table_parser.parse_or_fail(text.strip, file, line_offset)
22
+
23
+ # Returns a Cucumber::Ast::Table for +text_or_table+, which can either
24
+ # be a String:
25
+ #
26
+ # table(%{
27
+ # | account | description | amount |
28
+ # | INT-100 | Taxi | 114 |
29
+ # | CUC-101 | Peeler | 22 |
30
+ # })
31
+ #
32
+ # or a 2D Array:
33
+ #
34
+ # table([
35
+ # %w{ account description amount },
36
+ # %w{ INT-100 Taxi 114 },
37
+ # %w{ CUC-101 Peeler 22 }
38
+ # ])
39
+ #
40
+ def table(text_or_table, file=nil, line_offset=0)
41
+ if Array === text_or_table
42
+ Ast::Table.new(text_or_table)
43
+ else
44
+ @table_parser ||= Parser::TableParser.new
45
+ @table_parser.parse_or_fail(text_or_table.strip, file, line_offset)
46
+ end
27
47
  end
28
48
 
29
49
  # Output +announcement+ alongside the formatted output.
@@ -34,7 +54,7 @@ module Cucumber
34
54
  # step. This is because the step itself will not be printed until
35
55
  # after it has run, so it can be coloured according to its status.
36
56
  def announce(announcement)
37
- @__cucumber_visitor.announce(announcement)
57
+ @__cucumber_step_mother.announce(announcement)
38
58
  end
39
59
 
40
60
  def pending(message = "TODO")
@@ -16,11 +16,11 @@ config.action_controller.allow_forgery_protection = false
16
16
  config.action_mailer.delivery_method = :test
17
17
 
18
18
  config.gem 'cucumber', :lib => false, :version => '>=<%= cucumber_version %>' unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber'))
19
- config.gem 'webrat', :lib => false, :version => '>=0.4.4' unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat'))
19
+ config.gem 'webrat', :lib => false, :version => '>=0.5.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat'))
20
20
  <% if framework == :rspec -%>
21
21
  config.gem 'rspec', :lib => false, :version => '>=1.2.6' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec'))
22
22
  config.gem 'rspec-rails', :lib => 'spec/rails', :version => '>=1.2.6' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec-rails'))
23
23
  <% end %>
24
24
  <% if spork? -%>
25
- config.gem 'spork', :lib => false, :version => '>=0.5.7' unless File.directory?(File.join(Rails.root, 'vendor/plugins/spork'))
25
+ config.gem 'spork', :lib => false, :version => '>=0.5.9' unless File.directory?(File.join(Rails.root, 'vendor/plugins/spork'))
26
26
  <% end %>
@@ -18,14 +18,12 @@ Spork.prefork do
18
18
 
19
19
  # Comment out the next line if you don't want Cucumber Unicode support
20
20
  require 'cucumber/formatter/unicode'
21
-
22
21
  require 'spec/rails'
23
22
  require 'cucumber/rails/rspec'
24
23
  end
25
24
 
26
25
  Spork.each_run do
27
26
  # This code will be run each time you run your specs.
28
- require 'cucumber/rails/world'
29
27
 
30
28
  # Comment out the next line if you don't want transactions to
31
29
  # open/roll back around each scenario
@@ -27,6 +27,23 @@ When /^I fill in "([^\"]*)" with "([^\"]*)"$/ do |field, value|
27
27
  fill_in(field, :with => value)
28
28
  end
29
29
 
30
+ # Use this to fill in an entire form with data from a table. Example:
31
+ #
32
+ # When I fill in the following:
33
+ # | Account Number | 5002 |
34
+ # | Expiry date | 2009-11-01 |
35
+ # | Note | Nice guy |
36
+ # | Wants Email? | |
37
+ #
38
+ # TODO: Add support for checkbox, select og option
39
+ # based on naming conventions.
40
+ #
41
+ When /^I fill in the following:$/ do |fields|
42
+ fields.rows_hash.each do |name, value|
43
+ When %{I fill in "#{name}" with "#{value}"}
44
+ end
45
+ end
46
+
30
47
  When /^I select "([^\"]*)" from "([^\"]*)"$/ do |value, field|
31
48
  select(value, :from => field)
32
49
  end
@@ -1,18 +1,22 @@
1
1
  require File.dirname(__FILE__) + '/../../spec_helper'
2
2
  require 'cucumber/ast'
3
+ require 'cucumber/rb_support/rb_language'
3
4
 
4
5
  module Cucumber
5
6
  module Ast
6
7
  describe Background do
7
8
 
8
9
  before do
9
- @step_mother = Object.new
10
- @step_mother.extend(StepMother)
10
+ extend(RbSupport::RbDsl)
11
+ @step_mother = StepMother.new
12
+ @step_mother.load_natural_language('en')
13
+ @step_mother.load_programming_language('rb')
14
+
11
15
  $x = $y = nil
12
- @step_mother.Before do
16
+ Before do
13
17
  $x = 2
14
18
  end
15
- @step_mother.Given /y is (\d+)/ do |n|
19
+ Given /y is (\d+)/ do |n|
16
20
  $y = $x * n.to_i
17
21
  end
18
22
  @visitor = Visitor.new(@step_mother)
@@ -40,7 +44,6 @@ module Cucumber
40
44
  name="",
41
45
  steps=[])
42
46
  background.feature = @feature
43
-
44
47
  @visitor.visit_background(background)
45
48
  $x.should == 2
46
49
  $y.should == 10
@@ -10,14 +10,13 @@ module Cucumber
10
10
  end
11
11
  end
12
12
 
13
- def create_feature(step_mother)
14
- step_mother.extend(StepMother)
15
- step_mother.Given /^a (.*) step with an inline arg:$/ do |what, table|
13
+ def create_feature(dsl)
14
+ dsl.Given /^a (.*) step with an inline arg:$/ do |what, table|
16
15
  end
17
- step_mother.Given /^a (.*) step$/ do |what|
16
+ dsl.Given /^a (.*) step$/ do |what|
18
17
  flunk if what == 'failing'
19
18
  end
20
- step_mother.World do
19
+ dsl.World do
21
20
  MyWorld.new
22
21
  end
23
22
 
@@ -7,7 +7,13 @@ module Cucumber
7
7
  include FeatureFactory
8
8
 
9
9
  it "should convert to sexp" do
10
- feature = create_feature(Object.new)
10
+ step_mother = StepMother.new
11
+ step_mother.load_natural_language('en')
12
+ step_mother.load_programming_language('rb')
13
+ dsl = Object.new
14
+ dsl.extend RbSupport::RbDsl
15
+
16
+ feature = create_feature(dsl)
11
17
  feature.to_sexp.should ==
12
18
  [:feature,
13
19
  "features/pretty_printing.feature",
@@ -2,24 +2,28 @@ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
  require 'cucumber/step_mother'
3
3
  require 'cucumber/ast'
4
4
  require 'cucumber/core_ext/string'
5
+ require 'cucumber/rb_support/rb_language'
5
6
 
6
7
  module Cucumber
7
8
  module Ast
8
9
  describe ScenarioOutline do
9
10
  before do
10
- @step_mother = Object.new
11
- @step_mother.extend(StepMother)
11
+ @step_mother = StepMother.new
12
+ @step_mother.load_programming_language('rb')
13
+ @step_mother.load_natural_language('en')
14
+ @dsl = Object.new
15
+ @dsl.extend(RbSupport::RbDsl)
12
16
 
13
- @step_mother.Given(/^there are (\d+) cucumbers$/) do |n|
17
+ @dsl.Given(/^there are (\d+) cucumbers$/) do |n|
14
18
  @initial = n.to_i
15
19
  end
16
- @step_mother.When(/^I eat (\d+) cucumbers$/) do |n|
20
+ @dsl.When(/^I eat (\d+) cucumbers$/) do |n|
17
21
  @eaten = n.to_i
18
22
  end
19
- @step_mother.Then(/^I should have (\d+) cucumbers$/) do |n|
23
+ @dsl.Then(/^I should have (\d+) cucumbers$/) do |n|
20
24
  (@initial - @eaten).should == n.to_i
21
25
  end
22
- @step_mother.Then(/^I should have (\d+) cucumbers in my belly$/) do |n|
26
+ @dsl.Then(/^I should have (\d+) cucumbers in my belly$/) do |n|
23
27
  @eaten.should == n.to_i
24
28
  end
25
29
 
@@ -1,15 +1,20 @@
1
1
  require File.dirname(__FILE__) + '/../../spec_helper'
2
2
  require 'cucumber/step_mother'
3
3
  require 'cucumber/ast'
4
+ require 'cucumber/rb_support/rb_language'
4
5
 
5
6
  module Cucumber
6
7
  module Ast
7
8
  describe Scenario do
8
9
  before do
9
- @step_mother = Object.new
10
- @step_mother.extend(StepMother)
10
+ @step_mother = StepMother.new
11
+ @step_mother.load_natural_language('en')
12
+ @step_mother.load_programming_language('rb')
13
+ @dsl = Object.new
14
+ @dsl.extend(RbSupport::RbDsl)
15
+
11
16
  $x = $y = nil
12
- @step_mother.Given /y is (\d+)/ do |n|
17
+ @dsl.Given /y is (\d+)/ do |n|
13
18
  $y = n.to_i
14
19
  end
15
20
  @visitor = Visitor.new(@step_mother)
@@ -6,8 +6,8 @@ module Cucumber
6
6
  it "should convert And to Given in snippets" do
7
7
  s1 = Step.new(1, 'Given', 'cukes')
8
8
  s2 = Step.new(2, 'And', 'turnips')
9
- s1.stub!(:language).and_return(Parser::I18n::Language['en'])
10
- s2.stub!(:language).and_return(Parser::I18n::Language['en'])
9
+ s1.stub!(:language).and_return(Parser::NaturalLanguage.get(nil, 'en'))
10
+ s2.stub!(:language).and_return(Parser::NaturalLanguage.get(nil, 'en'))
11
11
  c = StepCollection.new([s1, s2])
12
12
  actual_keywords = c.step_invocations.map{|i| i.actual_keyword}
13
13
  actual_keywords.should == %w{Given Given}
@@ -13,6 +13,7 @@ module Cli
13
13
 
14
14
  def given_the_following_files(*files)
15
15
  File.stub!(:directory?).and_return(true)
16
+ File.stub!(:file?).and_return(true)
16
17
  Dir.stub!(:[]).and_return(files)
17
18
  end
18
19
 
@@ -114,6 +115,20 @@ module Cli
114
115
  end
115
116
  end
116
117
 
118
+ describe "#drb_port" do
119
+ it "is nil when not configured" do
120
+ config.parse!([])
121
+ config.drb_port.should be_nil
122
+ end
123
+
124
+ it "is numeric when configured" do
125
+ config.parse!(%w{features --port 1000})
126
+ config.drb_port.should == 1000
127
+ end
128
+
129
+
130
+ end
131
+
117
132
  it "uses the default profile when no profile is defined" do
118
133
  given_cucumber_yml_defined_as({'default' => '--require some_file'})
119
134
 
@@ -23,7 +23,7 @@ module Cucumber
23
23
  DRbClient.run(@args, @error_stream, @out_stream)
24
24
  end
25
25
 
26
- it "runs the fearures on the DRb server" do
26
+ it "runs the features on the DRb server" do
27
27
  @drb_object.should_receive(:run).with(@args, @error_stream, @out_stream)
28
28
  DRbClient.run(@args, @error_stream, @out_stream)
29
29
  end
@@ -38,6 +38,40 @@ module Cucumber
38
38
  DRbClient.run(@args, @error_stream, @out_stream).should == 'foo'
39
39
  end
40
40
 
41
+ context "with $CUCUMBER_DRB set" do
42
+ before do
43
+ @original_env = ENV['CUCUMBER_DRB']
44
+ ENV['CUCUMBER_DRB'] = '90000'
45
+ end
46
+ after do
47
+ ENV['CUCUMBER_DRB'] = @original_env
48
+ end
49
+ it "connects to specified DRb server" do
50
+ DRbObject.should_receive(:new_with_uri).with("druby://127.0.0.1:90000")
51
+ DRbClient.run(@args, @error_stream, @out_stream)
52
+ end
53
+ end
54
+
55
+ context "with provided drb_port" do
56
+ before do
57
+ @args = @args + ['--port', '8000']
58
+ end
59
+ it "connects to specified drb port" do
60
+ DRbObject.should_receive(:new_with_uri).with("druby://127.0.0.1:8000")
61
+ DRbClient.run(@args, @error_stream, @out_stream, 8000)
62
+ end
63
+ it "prefers configuration to environment" do
64
+ original = ENV['CUCUMBER_DRB'] = original
65
+ begin
66
+ ENV['CUCUMBER_DRB'] = "4000"
67
+ DRbObject.should_receive(:new_with_uri).with("druby://127.0.0.1:8000")
68
+ DRbClient.run(@args, @error_stream, @out_stream, 8000)
69
+ ensure
70
+ ENV['CUCUMBER_DRB'] = original
71
+ end
72
+ end
73
+ end
74
+
41
75
  end
42
76
  end
43
77
  end
@@ -29,7 +29,7 @@ module Cucumber
29
29
 
30
30
  FeatureFile.stub!(:new).and_return(mock("feature file", :parse => @empty_feature))
31
31
 
32
- @cli.execute!(Object.new.extend(StepMother))
32
+ @cli.execute!(StepMother.new)
33
33
 
34
34
  @out.string.should include('example.feature')
35
35
  end
@@ -80,7 +80,7 @@ module Cucumber
80
80
  Object.should_receive(:const_get).with('ZooModule').and_return(mock_module)
81
81
  mock_module.should_receive(:const_get).with('MonkeyFormatterClass').and_return(mock('formatter class', :new => f))
82
82
 
83
- cli.execute!(Object.new.extend(StepMother))
83
+ cli.execute!(StepMother.new)
84
84
  end
85
85
 
86
86
  end
@@ -93,7 +93,7 @@ module Cucumber
93
93
  configuration.stub!(:parse!).and_raise(exception_klass.new("error message"))
94
94
 
95
95
  main = Main.new('', out = StringIO.new, error = StringIO.new)
96
- main.execute!(Object.new.extend(StepMother)).should be_true
96
+ main.execute!(StepMother.new).should be_true
97
97
  error.string.should == "error message\n"
98
98
  end
99
99
  end
@@ -111,7 +111,8 @@ module Cucumber
111
111
  end
112
112
 
113
113
  it "delegates the execution to the DRB client passing the args and streams" do
114
- DRbClient.should_receive(:run).with(@args, @err, @out).and_return(true)
114
+ @configuration.stub :drb_port => 1450
115
+ DRbClient.should_receive(:run).with(@args, @err, @out, 1450).and_return(true)
115
116
  @cli.execute!(@step_mother)
116
117
  end
117
118
 
@@ -68,6 +68,12 @@ module Cli
68
68
  end
69
69
  end
70
70
 
71
+ context "--port PORT" do
72
+ it "sets the drb_port to the provided option" do
73
+ after_parsing('--port 4500') { options[:drb_port].should == '4500' }
74
+ end
75
+ end
76
+
71
77
  context '-f FORMAT or --format FORMAT' do
72
78
  it "defaults the output for the formatter to the output stream (STDOUT)" do
73
79
  after_parsing('-f pretty') { options[:formats].should == [['pretty', output_stream]] }
@@ -1,11 +1,12 @@
1
1
  require File.dirname(__FILE__) + '/../../spec_helper'
2
- require 'cucumber/parser/i18n/language'
2
+ require 'cucumber/parser/natural_language'
3
3
 
4
4
  module Cucumber
5
5
  module Parser
6
6
  describe Feature do
7
7
  before do
8
- @parser = I18n::Language['en'].parser
8
+ @step_mother = StepMother.new
9
+ @parser = NaturalLanguage.get(@step_mother, 'en').parser
9
10
  end
10
11
 
11
12
  def parse(text)
@@ -13,11 +14,11 @@ module Cucumber
13
14
  end
14
15
 
15
16
  def parse_file(file)
16
- FeatureFile.new(File.dirname(__FILE__) + "/../treetop_parser/" + file).parse
17
+ FeatureFile.new(File.dirname(__FILE__) + "/../treetop_parser/" + file).parse(@step_mother, {})
17
18
  end
18
19
 
19
20
  def parse_example_file(file)
20
- FeatureFile.new(File.dirname(__FILE__) + "/../../../examples/" + file).parse
21
+ FeatureFile.new(File.dirname(__FILE__) + "/../../../examples/" + file).parse(@step_mother, {})
21
22
  end
22
23
 
23
24
  describe "Comments" do
@@ -354,7 +355,7 @@ Given I am a step
354
355
  it "should filter outline tables" do
355
356
  ff = FeatureFile.new(
356
357
  File.dirname(__FILE__) + '/../../../examples/self_test/features/outline_sample.feature:12')
357
- f = ff.parse({:lang => 'en'})
358
+ f = ff.parse(@step_mother, {:lang => 'en'})
358
359
  f.to_sexp.should ==
359
360
  [:feature,
360
361
  "./spec/cucumber/parser/../../../examples/self_test/features/outline_sample.feature",