1 require File.dirname(__FILE__) + '/story_helper'
14 World.step_mother.clear
17 it 'should create an object that mixes in a World' do
22 obj.should be_kind_of(World)
25 it 'should create a World from any object type' do
27 obj = World::create String
30 obj.should be_kind_of(String)
31 obj.should be_kind_of(World)
34 it 'should pass arguments to #new when creating an object of a specified type that mixes in a world' do
36 Thing = Struct.new(:name, :age)
39 obj = World::create Thing, "David", "I'm not telling"
42 obj.should be_an_instance_of(Thing)
43 obj.name.should == "David"
44 obj.age.should == "I'm not telling"
45 obj.should be_kind_of(World)
48 def ensure_world_executes_step(&block)
54 obj.instance_eval(&block)
57 $step_ran.should be_true
60 it 'should execute a Given, When or Then step' do
61 ensure_world_executes_step do
67 ensure_world_executes_step do
73 ensure_world_executes_step do
80 it 'should interpret Given... And... as multiple givens' do
86 world.instance_eval do
96 $steps.should == [1,2]
97 World.step_mother.find(:given, 'step 1').should_not be_nil
98 World.step_mother.find(:given, 'step 2').should_not be_nil
101 it 'should interpret When... And... as multiple events' do
107 world.instance_eval do
117 $steps.should == [1,2]
118 World.step_mother.find(:when, 'step 1').should_not be_nil
119 World.step_mother.find(:when, 'step 2').should_not be_nil
122 it 'should interpret Then... And... as multiple outcomes' do
128 world.instance_eval do
138 $steps.should == [1,2]
139 World.step_mother.find(:then, 'step 1').should_not be_nil
140 World.step_mother.find(:then, 'step 2').should_not be_nil
143 it 'should reuse a given across scenarios' do
146 a_world = World::create
147 a_world.instance_eval do
152 another_world = World::create
155 another_world.instance_eval do
156 Given 'a given' # without a body
160 $num_invoked.should == 2
163 it 'should reuse an event across scenarios' do
166 a_world = World::create
167 a_world.instance_eval do
173 another_world = World::create
176 another_world.instance_eval do
177 When 'an event' # without a body
181 $num_invoked.should == 2
184 it 'should reuse an outcome across scenarios' do
187 a_world = World::create
188 a_world.instance_eval do
194 another_world = World::create
197 another_world.instance_eval do
198 Then 'an outcome' # without a body
202 $num_invoked.should == 2
205 it 'should preserve instance variables between steps within a scenario' do
207 world = World::create
212 world.instance_eval do
217 @second = @first # from given
220 $first = @first # from given
221 $second = @second # from event
226 $first.should == 'first'
227 $second.should == 'first'
230 it 'should invoke a reused step in the new object instance' do
234 world1 = World.create
235 world1.instance_eval do
237 $instances << self.__id__
240 world2 = World.create
243 world2.instance_eval do
244 Given 'a given' # reused
251 $instances.should == [ world1.__id__, world2.__id__, world2.__id__ ]
254 def ensure_world_collects_error(expected_error, &block)
260 world.start_collecting_errors
261 world.instance_eval(&block)
264 world.should have(1).errors
265 world.errors[0].should be_kind_of(expected_error)
268 it 'should collect a failure from a Given step' do
269 ensure_world_collects_error RuntimeError do
271 raise RuntimeError, "oops"
276 it 'should collect a failure from a When step' do
277 ensure_world_collects_error RuntimeError do
279 raise RuntimeError, "oops"
284 it 'should collect a failure from a Then step' do
285 ensure_world_collects_error RuntimeError do
287 raise RuntimeError, "oops"
292 it 'should inform listeners when it runs a Given, When or Then step' do
295 mock_listener1 = mock('listener1')
296 mock_listener2 = mock('listener2')
297 World.add_listener(mock_listener1)
298 World.add_listener(mock_listener2)
301 mock_listener1.should_receive(:step_succeeded).with(:given, 'a context')
302 mock_listener1.should_receive(:step_succeeded).with(:when, 'an event')
303 mock_listener1.should_receive(:step_succeeded).with(:then, 'an outcome')
305 mock_listener2.should_receive(:step_succeeded).with(:given, 'a context')
306 mock_listener2.should_receive(:step_succeeded).with(:when, 'an event')
307 mock_listener2.should_receive(:step_succeeded).with(:then, 'an outcome')
310 world.instance_eval do
311 Given 'a context' do end
312 When 'an event' do end
313 Then 'an outcome' do end
319 it 'should tell listeners but not execute the step in dry-run mode' do
321 Runner.stub!(:dry_run).and_return(true)
322 mock_listener = mock('listener')
323 World.add_listener(mock_listener)
324 $step_invoked = false
328 mock_listener.should_receive(:step_succeeded).with(:given, 'a context')
331 world.instance_eval do
338 $step_invoked.should be(false)
341 it 'should suppress listeners while it runs a GivenScenario' do
343 $scenario_ran = false
345 scenario = ScenarioBuilder.new.name('a scenario').to_scenario do
349 Then 'outcome' do end
352 given_scenario = GivenScenario.new('a scenario')
353 Runner::StoryRunner.should_receive(:scenario_from_current_story).
354 with('a scenario').and_return(scenario)
357 listener = mock('listener')
358 World.add_listener(listener)
361 listener.should_receive(:found_scenario).with(:'given scenario', 'a scenario')
362 listener.should_receive(:step_succeeded).never.with(:given, 'given')
363 listener.should_receive(:step_succeeded).never.with(:when, 'event')
364 listener.should_receive(:step_succeeded).never.with(:then, 'outcome')
367 world.GivenScenario 'a scenario'
370 $scenario_ran.should be_true
373 it 'should interpret GivenScenario... And... as multiple givens' do
378 scenario = ScenarioBuilder.new.name('a scenario').to_scenario do
381 Runner::StoryRunner.should_receive(:scenario_from_current_story).
382 with('a scenario').and_return(scenario)
385 world.instance_eval do
386 GivenScenario 'a scenario'
393 $steps.should == [1,2]
394 World.step_mother.find(:given, 'step 2').should_not be_nil
397 it 'should provide rspec matchers' do
402 world.instance_eval do
403 'hello'.should match(/^hello$/)
407 it "should use assigned matchers" do
410 World.should_receive(:use).with(steps = Object.new)