diff --git a/lib/cucumber/rb_support/rb_dsl.rb b/lib/cucumber/rb_support/rb_dsl.rb
index d6889ca76f..ff0b2b407f 100644
--- a/lib/cucumber/rb_support/rb_dsl.rb
+++ b/lib/cucumber/rb_support/rb_dsl.rb
@@ -23,8 +23,8 @@ def register_rb_transform(regexp, proc)
@rb_language.register_rb_transform(regexp, proc)
end
- def register_rb_step_definition(regexp, proc)
- @rb_language.register_rb_step_definition(regexp, proc)
+ def register_rb_step_definition(regexp, proc_or_sym, options = {})
+ @rb_language.register_rb_step_definition(regexp, proc_or_sym, options)
end
end
@@ -98,12 +98,19 @@ def AfterConfiguration(&proc)
# also to the i18n translations whenever a feature of a
# new language is loaded.
#
- # The +&proc+ gets executed in the context of a World
- # object, which is defined by #World. A new World
- # object is created for each scenario and is shared across
- # step definitions within that scenario.
- def register_rb_step_definition(regexp, &proc)
- RbDsl.register_rb_step_definition(regexp, proc)
+ # If provided, the +symbol+ is sent to the World object
+ # as defined by #World. A new World object is created
+ # for each scenario and is shared across step definitions within
+ # that scenario. If the +options+ hash contains an :on
+ # key, the value for this is assumed to be a proc. This proc
+ # will be executed in the context of the World object
+ # and then sent the +symbol+.
+ #
+ # If no +symbol+ if provided then the +&proc+ gets executed in
+ # the context of the World object.
+ def register_rb_step_definition(regexp, symbol = nil, options = {}, &proc)
+ proc_or_sym = symbol || proc
+ RbDsl.register_rb_step_definition(regexp, proc_or_sym, options)
end
end
end
diff --git a/lib/cucumber/rb_support/rb_language.rb b/lib/cucumber/rb_support/rb_language.rb
index bb59050f52..bce857783d 100644
--- a/lib/cucumber/rb_support/rb_language.rb
+++ b/lib/cucumber/rb_support/rb_language.rb
@@ -124,8 +124,8 @@ def register_rb_transform(regexp, proc)
add_transform(RbTransform.new(self, regexp, proc))
end
- def register_rb_step_definition(regexp, proc)
- step_definition = RbStepDefinition.new(self, regexp, proc)
+ def register_rb_step_definition(regexp, proc_or_sym, options)
+ step_definition = RbStepDefinition.new(self, regexp, proc_or_sym, options)
@step_definitions << step_definition
step_definition
end
diff --git a/lib/cucumber/rb_support/rb_step_definition.rb b/lib/cucumber/rb_support/rb_step_definition.rb
index 72d4e4bf2c..cc2e168a70 100644
--- a/lib/cucumber/rb_support/rb_step_definition.rb
+++ b/lib/cucumber/rb_support/rb_step_definition.rb
@@ -19,18 +19,25 @@ class RbStepDefinition
class MissingProc < StandardError
def message
- "Step definitions must always have a proc"
+ "Step definitions must always have a proc or symbol"
end
end
- def initialize(rb_language, regexp, proc)
- raise MissingProc if proc.nil?
+ def initialize(rb_language, regexp, proc_or_sym, options)
+ raise MissingProc if proc_or_sym.nil?
if String === regexp
p = Regexp.escape(regexp)
p = p.gsub(/\\\$\w+/, '(.*)') # Replace $var with (.*)
regexp = Regexp.new("^#{p}$")
end
- @rb_language, @regexp, @proc = rb_language, regexp, proc
+ @rb_language, @regexp, @proc = rb_language, regexp, proc_or_sym
+ if @proc.kind_of? Symbol
+ @proc = lambda do |*args|
+ target = options[:on] ? instance_exec(&options[:on]) : self
+ target.send(proc_or_sym, *args)
+ end
+ end
+
@rb_language.available_step_definition(regexp_source, file_colon_line)
end
@@ -71,7 +78,12 @@ def backtrace_line
end
def file_colon_line
- @proc.file_colon_line
+ case @proc
+ when Proc
+ @proc.file_colon_line
+ when Symbol
+ ":#{@proc}"
+ end
end
def file
diff --git a/spec/cucumber/rb_support/rb_step_definition_spec.rb b/spec/cucumber/rb_support/rb_step_definition_spec.rb
index 805bc63d9c..2825c50c22 100644
--- a/spec/cucumber/rb_support/rb_step_definition_spec.rb
+++ b/spec/cucumber/rb_support/rb_step_definition_spec.rb
@@ -44,6 +44,22 @@ module RbSupport
$inside.should == 'inside'
end
+ it "should call a method on the world when specified with a symbol" do
+ rb.current_world.should_receive(:with_symbol)
+ dsl.Given /With symbol/, :with_symbol
+
+ support_code.step_match("With symbol").invoke(nil)
+ end
+
+ it "should call a method on a specified object" do
+ target = double('target')
+ target.should_receive(:with_symbol)
+ rb.current_world.stub!(:target).and_return(target)
+ dsl.Given /With symbol on block/, :with_symbol, :on => lambda { target }
+
+ support_code.step_match("With symbol on block").invoke(nil)
+ end
+
it "should raise Undefined when inside step is not defined" do
dsl.Given /Outside/ do
step 'Inside'
@@ -91,7 +107,7 @@ module RbSupport
end
it "should have a JSON representation of the signature" do
- RbStepDefinition.new(rb, /I CAN HAZ (\d+) CUKES/i, lambda{}).to_hash.should == {'source' => "I CAN HAZ (\\d+) CUKES", 'flags' => 'i'}
+ RbStepDefinition.new(rb, /I CAN HAZ (\d+) CUKES/i, lambda{}, {}).to_hash.should == {'source' => "I CAN HAZ (\\d+) CUKES", 'flags' => 'i'}
end
end
end
diff --git a/spec/cucumber/step_match_spec.rb b/spec/cucumber/step_match_spec.rb
index a6c24fe314..fdfacf4ae9 100644
--- a/spec/cucumber/step_match_spec.rb
+++ b/spec/cucumber/step_match_spec.rb
@@ -12,7 +12,7 @@ module Cucumber
end
def stepdef(regexp)
- RbSupport::RbStepDefinition.new(@rb_language, regexp, lambda{})
+ RbSupport::RbStepDefinition.new(@rb_language, regexp, lambda{}, {})
end
def step_match(regexp, name)
@@ -66,4 +66,4 @@ def step_match(regexp, name)
m.format_args("%s").should == "running 5 times 10 meters"
end
end
-end
\ No newline at end of file
+end