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_upcoming).with(:given, 'a context')
302
mock_listener1.should_receive(:step_succeeded).with(:given, 'a context')
303
mock_listener1.should_receive(:step_upcoming).with(:when, 'an event')
304
mock_listener1.should_receive(:step_succeeded).with(:when, 'an event')
305
mock_listener1.should_receive(:step_upcoming).with(:then, 'an outcome')
306
mock_listener1.should_receive(:step_succeeded).with(:then, 'an outcome')
308
mock_listener2.should_receive(:step_upcoming).with(:given, 'a context')
309
mock_listener2.should_receive(:step_succeeded).with(:given, 'a context')
310
mock_listener2.should_receive(:step_upcoming).with(:when, 'an event')
311
mock_listener2.should_receive(:step_succeeded).with(:when, 'an event')
312
mock_listener2.should_receive(:step_upcoming).with(:then, 'an outcome')
313
mock_listener2.should_receive(:step_succeeded).with(:then, 'an outcome')
316
world.instance_eval do
317
Given 'a context' do end
318
When 'an event' do end
319
Then 'an outcome' do end
325
it 'should tell listeners but not execute the step in dry-run mode' do
327
Runner.stub!(:dry_run).and_return(true)
328
mock_listener = mock('listener')
329
World.add_listener(mock_listener)
330
$step_invoked = false
334
mock_listener.should_receive(:step_upcoming).with(:given, 'a context')
335
mock_listener.should_receive(:step_succeeded).with(:given, 'a context')
338
world.instance_eval do
345
$step_invoked.should be(false)
348
it 'should suppress listeners while it runs a GivenScenario' do
350
$scenario_ran = false
352
scenario = ScenarioBuilder.new.name('a scenario').to_scenario do
356
Then 'outcome' do end
359
given_scenario = GivenScenario.new('a scenario')
360
Runner::StoryRunner.should_receive(:scenario_from_current_story).
361
with('a scenario').and_return(scenario)
364
listener = mock('listener')
365
World.add_listener(listener)
368
listener.should_receive(:found_scenario).with(:'given scenario', 'a scenario')
369
listener.should_receive(:step_succeeded).never.with(:given, 'given')
370
listener.should_receive(:step_succeeded).never.with(:when, 'event')
371
listener.should_receive(:step_succeeded).never.with(:then, 'outcome')
374
world.GivenScenario 'a scenario'
377
$scenario_ran.should be_true
380
it 'should interpret GivenScenario... And... as multiple givens' do
385
scenario = ScenarioBuilder.new.name('a scenario').to_scenario do
388
Runner::StoryRunner.should_receive(:scenario_from_current_story).
389
with('a scenario').and_return(scenario)
392
world.instance_eval do
393
GivenScenario 'a scenario'
400
$steps.should == [1,2]
401
World.step_mother.find(:given, 'step 2').should_not be_nil
404
it 'should provide rspec matchers' do
409
world.instance_eval do
410
'hello'.should match(/^hello$/)
414
it "should use assigned matchers" do
417
World.should_receive(:use).with(steps = Object.new)