changelog shortlog tags changeset manifest revisions annotate raw

vendor/plugins/rspec/lib/spec/story/world.rb

changeset 15: 64acf98d15f4
author: moriq@moriq.com
date: Mon Mar 10 10:12:58 2008 +0900 (16 years ago)
permissions: -rw-r--r--
description: add plugins rspec
1require 'rubygems'
2require 'spec/expectations'
3require 'spec/matchers'
4require 'spec/example/pending'
5
6module Spec
7 module Story
8=begin
9 A World represents the actual instance a scenario will run in.
10
11 The runner ensures any instance variables and methods defined anywhere
12 in a story block are available to all the scenarios. This includes
13 variables that are created or referenced inside Given, When and Then
14 blocks.
15=end
16 module World
17 include ::Spec::Example::Pending
18 include ::Spec::Matchers
19 # store steps and listeners in the singleton metaclass.
20 # This serves both to keep them out of the way of runtime Worlds
21 # and to make them available to all instances.
22 class << self
23 def create(cls = Object, *args)
24 cls.new(*args).extend(World)
25 end
26
27 def listeners
28 @listeners ||= []
29 end
30
31 def add_listener(listener)
32 listeners() << listener
33 end
34
35 def step_mother
36 @step_mother ||= StepMother.new
37 end
38
39 def use(steps)
40 step_mother.use(steps)
41 end
42
43 def step_names
44 @step_names ||= []
45 end
46
47 def run_given_scenario_with_suspended_listeners(world, type, name, scenario)
48 current_listeners = Array.new(listeners)
49 begin
50 listeners.each { |l| l.found_scenario(type, name) }
51 @listeners.clear
52 scenario.perform(world, name) unless ::Spec::Story::Runner.dry_run
53 ensure
54 @listeners.replace(current_listeners)
55 end
56 end
57
58 def store_and_call(world, type, name, *args, &block)
59 if block_given?
60 step_mother.store(type, Step.new(name, &block))
61 end
62 step = step_mother.find(type, name)
63
64 step_name = step.name
65 step_names << step_name
66
67 # It's important to have access to the parsed args here, so
68 # we can give them to the listeners. The HTML reporter needs
69 # the args so it can style them. See the generated output in
70 # story_server/prototype/rspec_stories.html (generated by rake stories)
71 args = step.parse_args(name) if args.empty?
72 begin
73 listeners.each { |l| l.step_upcoming(type, step_name, *args) }
74 step.perform(world, *args) unless ::Spec::Story::Runner.dry_run
75 listeners.each { |l| l.step_succeeded(type, step_name, *args) }
76 rescue Exception => e
77 case e
78 when Spec::Example::ExamplePendingError
79 @listeners.each { |l| l.step_pending(type, step_name, *args) }
80 else
81 @listeners.each { |l| l.step_failed(type, step_name, *args) }
82 end
83 errors << e
84 end
85 end
86
87 def errors
88 @errors ||= []
89 end
90 end # end of class << self
91
92 def start_collecting_errors
93 errors.clear
94 end
95
96 def errors
97 World.errors
98 end
99
100 def GivenScenario(name)
101 World.run_given_scenario_with_suspended_listeners(self, :'given scenario', name, GivenScenario.new(name))
102 @__previous_step = :given
103 end
104
105 def Given(name, *args, &block)
106 World.store_and_call self, :given, name, *args, &block
107 @__previous_step = :given
108 end
109
110 def When(name, *args, &block)
111 World.store_and_call self, :when, name, *args, &block
112 @__previous_step = :when
113 end
114
115 def Then(name, *args, &block)
116 World.store_and_call self, :then, name, *args, &block
117 @__previous_step = :then
118 end
119
120 def And(name, *args, &block)
121 World.store_and_call self, @__previous_step, name, *args, &block
122 end
123 end
124 end
125end