Updated to latest rspec
[gitorious:georgyos-clone.git] / vendor / plugins / rspec / spec / spec / story / world_spec.rb
1 require File.dirname(__FILE__) + '/story_helper'
2
3 require 'spec/story'
4
5 module Spec
6   module Story
7     describe World do
8       before :each do
9         World.listeners.clear
10       end
11
12       after :each do
13         World.listeners.clear
14         World.step_mother.clear
15       end
16
17       it 'should create an object that mixes in a World' do
18         # when
19         obj = World::create
20
21         # then
22         obj.should be_kind_of(World)
23       end
24
25       it 'should create a World from any object type' do
26         # when
27         obj = World::create String
28
29         # then
30         obj.should be_kind_of(String)
31         obj.should be_kind_of(World)
32       end
33
34       it 'should pass arguments to #new when creating an object of a specified type that mixes in a world' do
35         # given
36         Thing = Struct.new(:name, :age)
37
38         # when
39         obj = World::create Thing, "David", "I'm not telling"
40
41         # then
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)
46       end
47
48       def ensure_world_executes_step(&block)
49         # given
50         obj = World::create
51         $step_ran = false
52
53         # when
54         obj.instance_eval(&block)
55
56         # then
57         $step_ran.should be_true
58       end
59
60       it 'should execute a Given, When or Then step' do
61         ensure_world_executes_step do
62           Given 'a given' do
63             $step_ran = true
64           end
65         end
66
67         ensure_world_executes_step do
68           When 'an event' do
69             $step_ran = true
70           end
71         end
72
73         ensure_world_executes_step do
74           Then 'an outcome' do
75             $step_ran = true
76           end
77         end
78       end
79
80       it 'should interpret Given... And... as multiple givens' do
81         # given
82         world = World.create
83         $steps = []
84
85         # when
86         world.instance_eval do
87           Given 'step 1' do
88             $steps << 1
89           end
90           And 'step 2' do
91             $steps << 2
92           end
93         end
94
95         # then
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
99       end
100
101       it 'should interpret When... And... as multiple events' do
102         # given
103         world = World.create
104         $steps = []
105
106         # when
107         world.instance_eval do
108           When 'step 1' do
109             $steps << 1
110           end
111           And 'step 2' do
112             $steps << 2
113           end
114         end
115
116         # then
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
120       end
121
122       it 'should interpret Then... And... as multiple outcomes' do
123         # given
124         world = World.create
125         $steps = []
126
127         # when
128         world.instance_eval do
129           Then 'step 1' do
130             $steps << 1
131           end
132           And 'step 2' do
133             $steps << 2
134           end
135         end
136
137         # then
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
141       end
142
143       it 'should reuse a given across scenarios' do
144         # given
145         $num_invoked = 0
146         a_world = World::create
147         a_world.instance_eval do
148           Given 'a given' do
149             $num_invoked += 1
150           end
151         end
152         another_world = World::create
153
154         # when
155         another_world.instance_eval do
156           Given 'a given' # without a body
157         end
158
159         # then
160         $num_invoked.should == 2
161       end
162
163       it 'should reuse an event across scenarios' do
164         # given
165         $num_invoked = 0
166         a_world = World::create
167         a_world.instance_eval do
168           When 'an event' do
169             $num_invoked += 1
170           end
171         end
172
173         another_world = World::create
174
175         # when
176         another_world.instance_eval do
177           When 'an event' # without a body
178         end
179
180         # then
181         $num_invoked.should == 2
182       end
183
184       it 'should reuse an outcome across scenarios' do
185         # given
186         $num_invoked = 0
187         a_world = World::create
188         a_world.instance_eval do
189           Then 'an outcome' do
190             $num_invoked += 1
191           end
192         end
193
194         another_world = World::create
195
196         # when
197         another_world.instance_eval do
198           Then 'an outcome' # without a body
199         end
200
201         # then
202         $num_invoked.should == 2
203       end
204
205       it 'should preserve instance variables between steps within a scenario' do
206         # given
207         world = World::create
208         $first = nil
209         $second = nil
210
211         # when
212         world.instance_eval do
213           Given 'given' do
214             @first = 'first'
215           end
216           When 'event' do
217             @second = @first # from given
218           end
219           Then 'outcome' do
220             $first = @first # from given
221             $second = @second # from event
222           end
223         end
224
225         # then
226         $first.should == 'first'
227         $second.should == 'first'
228       end
229
230       it 'should invoke a reused step in the new object instance' do
231         # given
232         $instances = []
233         $debug = true
234         world1 = World.create
235         world1.instance_eval do
236           Given 'a given' do
237             $instances << self.__id__
238           end
239         end
240         world2 = World.create
241
242         # when
243         world2.instance_eval do
244           Given 'a given' # reused
245           Then 'an outcome' do
246             $instances << __id__
247           end
248         end
249         $debug = false
250         # then
251         $instances.should == [ world1.__id__, world2.__id__, world2.__id__ ]
252       end
253
254       def ensure_world_collects_error(expected_error, &block)
255         # given
256         world = World.create
257         # $error = nil
258
259         # when
260         world.start_collecting_errors
261         world.instance_eval(&block)
262
263         # then
264         world.should have(1).errors
265         world.errors[0].should be_kind_of(expected_error)
266       end
267
268       it 'should collect a failure from a Given step' do
269         ensure_world_collects_error RuntimeError do
270           Given 'a given' do
271             raise RuntimeError, "oops"
272           end
273         end
274       end
275
276       it 'should collect a failure from a When step' do
277         ensure_world_collects_error RuntimeError do
278           When 'an event' do
279             raise RuntimeError, "oops"
280           end
281         end
282       end
283
284       it 'should collect a failure from a Then step' do
285         ensure_world_collects_error RuntimeError do
286           Then 'an outcome' do
287             raise RuntimeError, "oops"
288           end
289         end
290       end
291
292       it 'should inform listeners when it runs a Given, When or Then step' do
293         # given
294         world = World.create
295         mock_listener1 = mock('listener1')
296         mock_listener2 = mock('listener2')
297         World.add_listener(mock_listener1)
298         World.add_listener(mock_listener2)
299
300         # expect
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')
307
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')
314
315         # when
316         world.instance_eval do
317           Given 'a context' do end
318           When 'an event' do end
319           Then 'an outcome' do end
320         end
321
322         # then
323       end
324
325       it 'should tell listeners but not execute the step in dry-run mode' do
326         # given
327         World.stub!(:dry_run).and_return(true)
328         mock_listener = mock('listener')
329         World.add_listener(mock_listener)
330         $step_invoked = false
331         world = World.create
332
333         # expect
334         mock_listener.should_receive(:step_upcoming).with(:given, 'a context')
335         mock_listener.should_receive(:step_succeeded).with(:given, 'a context')
336
337         # when
338         world.instance_eval do
339           Given 'a context' do
340             $step_invoked = true
341           end
342         end
343
344         # then
345         $step_invoked.should be(false)
346       end
347
348       it 'should suppress listeners while it runs a GivenScenario' do
349         # given
350         $scenario_ran = false
351
352         scenario = ScenarioBuilder.new.name('a scenario').to_scenario do
353           $scenario_ran = true
354           Given 'given' do end
355           When 'event' do end
356           Then 'outcome' do end
357         end
358
359         given_scenario = GivenScenario.new('a scenario')
360         Runner::StoryRunner.should_receive(:scenario_from_current_story).
361           with('a scenario').and_return(scenario)
362
363         world = World.create
364         listener = mock('listener')
365         World.add_listener(listener)
366
367         # expect
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')
372
373         # when
374         world.GivenScenario 'a scenario'
375
376         # then
377         $scenario_ran.should be_true
378       end
379
380       it 'should interpret GivenScenario... And... as multiple givens' do
381         # given
382         world = World.create
383         $steps = []
384
385         scenario = ScenarioBuilder.new.name('a scenario').to_scenario do
386           $steps << 1
387         end
388         Runner::StoryRunner.should_receive(:scenario_from_current_story).
389           with('a scenario').and_return(scenario)
390
391         # when
392         world.instance_eval do
393           GivenScenario 'a scenario'
394           And 'step 2' do
395             $steps << 2
396           end
397         end
398
399         # then
400         $steps.should == [1,2]
401         World.step_mother.find(:given, 'step 2').should_not be_nil
402       end
403
404       it 'should provide rspec matchers' do
405         # given
406         world = World.create
407
408         # then
409         world.instance_eval do
410           'hello'.should match(/^hello$/)
411         end
412       end
413
414       it "should use assigned matchers" do
415         world = World.create
416
417         World.should_receive(:use).with(steps = Object.new)
418
419         World.use(steps)
420       end
421     end
422   end
423 end