require File.dirname(__FILE__) + '/../spec_helper' require 'cucumber' require 'cucumber/rb_support/rb_language' module Cucumber describe StepMother do before do @dsl = Object.new @dsl.extend(RbSupport::RbDsl) @step_mother = StepMother.new @step_mother.load_natural_language('en') @rb = @step_mother.load_programming_language('rb') @visitor = mock('Visitor') end it "should format step names" do @dsl.Given(/it (.*) in (.*)/) do |what, month| end @dsl.Given(/nope something else/) do |what, month| end format = @step_mother.step_match("it snows in april").format_args("[%s]") format.should == "it [snows] in [april]" end it "should raise Ambiguous error with guess hint when multiple step definitions match" do @dsl.Given(/Three (.*) mice/) {|disability|} @dsl.Given(/Three blind (.*)/) {|animal|} lambda do @step_mother.step_match("Three blind mice") end.should raise_error(Ambiguous, %{Ambiguous match of "Three blind mice": spec/cucumber/step_mother_spec.rb:29:in `/Three (.*) mice/' spec/cucumber/step_mother_spec.rb:30:in `/Three blind (.*)/' You can run again with --guess to make Cucumber be more smart about it }) end it "should not show --guess hint when --guess is used" do @step_mother.options = {:guess => true} @dsl.Given(/Three (.*) mice/) {|disability|} @dsl.Given(/Three cute (.*)/) {|animal|} lambda do @step_mother.step_match("Three cute mice") end.should raise_error(Ambiguous, %{Ambiguous match of "Three cute mice": spec/cucumber/step_mother_spec.rb:45:in `/Three (.*) mice/' spec/cucumber/step_mother_spec.rb:46:in `/Three cute (.*)/' }) end it "should not raise Ambiguous error when multiple step definitions match, but --guess is enabled" do @step_mother.options = {:guess => true} @dsl.Given(/Three (.*) mice/) {|disability|} @dsl.Given(/Three (.*)/) {|animal|} lambda do @step_mother.step_match("Three blind mice") end.should_not raise_error end it "should pick right step definition when --guess is enabled and equal number of capture groups" do @step_mother.options = {:guess => true} right = @dsl.Given(/Three (.*) mice/) {|disability|} wrong = @dsl.Given(/Three (.*)/) {|animal|} @step_mother.step_match("Three blind mice").step_definition.should == right end it "should pick right step definition when --guess is enabled and unequal number of capture groups" do @step_mother.options = {:guess => true} right = @dsl.Given(/Three (.*) mice ran (.*)/) {|disability|} wrong = @dsl.Given(/Three (.*)/) {|animal|} @step_mother.step_match("Three blind mice ran far").step_definition.should == right end it "should pick most specific step definition when --guess is enabled and unequal number of capture groups" do @step_mother.options = {:guess => true} general = @dsl.Given(/Three (.*) mice ran (.*)/) {|disability|} specific = @dsl.Given(/Three blind mice ran far/) {} more_specific = @dsl.Given(/^Three blind mice ran far$/) {} @step_mother.step_match("Three blind mice ran far").step_definition.should == more_specific end it "should raise Undefined error when no step definitions match" do lambda do @step_mother.step_match("Three blind mice") end.should raise_error(Undefined) end it "should raise Redundant error when same regexp is registered twice" do @dsl.Given(/Three (.*) mice/) {|disability|} lambda do @dsl.Given(/Three (.*) mice/) {|disability|} end.should raise_error(Redundant) end # http://railsforum.com/viewtopic.php?pid=93881 it "should not raise Redundant unless it's really redundant" do @dsl.Given(/^(.*) (.*) user named '(.*)'$/) {|a,b,c|} @dsl.Given(/^there is no (.*) user named '(.*)'$/) {|a,b|} end it "should raise an error if the world is nil" do @dsl.World do end begin @step_mother.before_and_after(nil) {} raise "Should fail" rescue RbSupport::NilWorld => e e.message.should == "World procs should never return nil" e.backtrace.should == ["spec/cucumber/step_mother_spec.rb:110:in `World'"] end end module ModuleOne end module ModuleTwo end class ClassOne end it "should implicitly extend world with modules" do @dsl.World(ModuleOne, ModuleTwo) @step_mother.begin_scenario class << @rb.current_world included_modules.index(ModuleOne).should_not == nil included_modules.index(ModuleTwo).should_not == nil end @rb.current_world.class.should == Object end it "should raise error when we try to register more than one World proc" do @dsl.World { Hash.new } lambda do @dsl.World { Array.new } end.should raise_error(RbSupport::MultipleWorld, %{You can only pass a proc to #World once, but it's happening in 2 places: spec/cucumber/step_mother_spec.rb:142:in `World' spec/cucumber/step_mother_spec.rb:144:in `World' Use Ruby modules instead to extend your worlds. See the Cucumber::StepMother#World RDoc or http://wiki.github.com/aslakhellesoy/cucumber/a-whole-new-world. }) end it "should find before hooks" do fish = @dsl.Before('@fish'){} meat = @dsl.Before('@meat'){} scenario = mock('Scenario') scenario.should_receive(:accept_hook?).with(fish).and_return(true) scenario.should_receive(:accept_hook?).with(meat).and_return(false) @step_mother.hooks_for(:before, scenario).should == [fish] end end end