Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Allow existing methods to be defined as steps

  • Loading branch information...
commit 63139f03383d17ec58c2774f8ca83148870fb1dd 1 parent 51930f0
@jnicklas authored
View
14 README.md
@@ -244,6 +244,20 @@ step "the value is the magic number"
end
```
+### Methods as steps
+
+You can mark an existing method as a step. This will make it available in your
+Turnip features. For example:
+
+``` ruby
+module MonsterSteps
+ def create_monster(name)
+ @monster = Monster.new(:name => name)
+ end
+ step :create_monster, "there is a monster called :name"
+end
+```
+
## Custom step placeholders
Do you want to be more specific in what to match in your step placeholders? Do
View
9 lib/turnip/define.rb
@@ -1,9 +1,12 @@
module Turnip
module Define
- def step(expression, &block)
- step = Turnip::StepDefinition.new(expression, &block)
+ def step(method_name=nil, expression, &block)
+ if method_name and block
+ raise ArgumentError, "can't specify both method name and a block for a step"
+ end
+ step = Turnip::StepDefinition.new(expression, method_name, caller.first, &block)
send(:define_method, "match: #{expression}") { |description| step.match(description) }
- send(:define_method, expression, &block)
+ send(:define_method, expression, &block) if block
end
end
end
View
14 lib/turnip/execute.rb
@@ -2,18 +2,22 @@ module Turnip
module Execute
def step(description, *extra_args)
extra_args.concat(description.extra_args) if description.respond_to?(:extra_args)
+
matches = methods.map do |method|
next unless method.to_s.start_with?("match: ")
send(method.to_s, description.to_s)
end.compact
- raise Turnip::Pending, description if matches.length == 0
+
+ if matches.length == 0
+ raise Turnip::Pending, description
+ end
+
if matches.length > 1
- msg = (matches.map do |match|
- " - \"#{match.expression}\" (#{match.block.source_location.join(':')})"
- end.unshift('Ambiguous step definitions').join("\r\n"))
+ msg = ['Ambiguous step definitions'].concat(matches.map(&:trace)).join("\r\n")
raise Turnip::Ambiguous, msg
end
- send(matches.first.expression, *(matches.first.params + extra_args))
+
+ send(matches.first.method_name, *(matches.first.params + extra_args))
end
end
end
View
12 lib/turnip/step_definition.rb
@@ -2,12 +2,20 @@ module Turnip
class StepDefinition
class Match < Struct.new(:step_definition, :params, :block)
def expression; step_definition.expression; end
+ def method_name; step_definition.method_name; end
+ def called_from; step_definition.called_from; end
+
+ def trace
+ trace = %{ - "#{expression}" (#{called_from})}
+ end
end
- attr_reader :expression, :block
+ attr_reader :expression, :block, :method_name, :called_from
- def initialize(expression, &block)
+ def initialize(expression, method_name=nil, called_from=nil, &block)
@expression = expression
+ @method_name = method_name || expression
+ @called_from = called_from
@block = block
end
View
16 spec/define_and_execute_spec.rb
@@ -19,6 +19,22 @@
obj.send("a :test step", "cool").should == "COOL"
end
+ it "can use an existing method as a step" do
+ mod.module_eval do
+ def a_test_step(test)
+ test.upcase
+ end
+ end
+ mod.step(:a_test_step, "a :test step")
+ obj.step("a cool step").should == "COOL"
+ end
+
+ it "raises an argument error when both method name and block given" do
+ expect do
+ mod.step(:a_test_step, "a :test step") { "foo" }
+ end.to raise_error(ArgumentError)
+ end
+
it "sends in extra arg from a builder step" do
mod.step("a :test step") { |test, foo| test.upcase + foo }
obj.step("a cool step", "foo").should == "COOLfoo"
Please sign in to comment.
Something went wrong with that request. Please try again.