Class: ContextState
- Defined in:
- lib/extensions/mspec/mspec/runner/context.rb
Overview
Holds the state of the describe
block that is being evaluated. Every example (i.e. it
block) is evaluated in a context, which may include state set up in before :each
or before :all
blocks.
– A note on naming: this is named ContextState rather than DescribeState because describe
is the keyword in the DSL for refering to the context in which an example is evaluated, just as it
refers to the example itself. ++
Instance Attribute Summary collapse
-
#children ⇒ Object
readonly
Returns the value of attribute children.
-
#examples ⇒ Object
readonly
Returns the value of attribute examples.
-
#parent ⇒ Object
Returns the value of attribute parent.
-
#parents ⇒ Object
readonly
Returns the value of attribute parents.
-
#state ⇒ Object
readonly
Returns the value of attribute state.
-
#to_s ⇒ Object
readonly
Returns the value of attribute to_s.
Instance Method Summary collapse
-
#adopt(parent) ⇒ Object
Adds a nested ContextState in a shared ContextState to a containing ContextState.
-
#after(what, &block) ⇒ Object
Records after(:each) and after(:all) blocks.
-
#before(what, &block) ⇒ Object
Records before(:each) and before(:all) blocks.
-
#child(child) ⇒ Object
Add the ContextState instance
child
to the list of nested describe blocks. -
#describe(&block) ⇒ Object
Evaluates the block and resets the toplevel
ContextState
to #parent. -
#description ⇒ Object
Returns a description string generated from self and all parents.
-
#filter_examples ⇒ Object
Removes filtered examples.
-
#initialize(mod, options = nil) ⇒ ContextState
constructor
A new instance of ContextState.
-
#initialize_copy(other) ⇒ Object
Remove caching when a ContextState is dup’d for shared specs.
-
#it(desc, &block) ⇒ Object
Creates an ExampleState instance for the block and stores it in a list of examples to evaluate unless the example is filtered.
-
#it_should_behave_like(desc) ⇒ Object
Injects the before/after blocks and examples from the shared describe block into this
ContextState
instance. -
#post(what) ⇒ Object
Returns a list of all after(
what
) blocks from self and any parents. -
#pre(what) ⇒ Object
Returns a list of all before(
what
) blocks from self and any parents. -
#process ⇒ Object
Evaluates the examples in a
ContextState
. -
#protect(what, blocks, check = true) ⇒ Object
Evaluates each block in
blocks
using theMSpec.protect
method so that exceptions are handled and tallied. -
#shared? ⇒ Boolean
Returns true if this is a shared
ContextState
.
Constructor Details
#initialize(mod, options = nil) ⇒ ContextState
Returns a new instance of ContextState.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 15 def initialize(mod, =nil) @to_s = mod.to_s if .is_a? Hash @options = else @to_s += "#{".:#".include?([0,1]) ? "" : " "}#{}" if @options = { } end @options[:shared] ||= false @parsed = false @before = { :all => [], :each => [] } @after = { :all => [], :each => [] } @pre = {} @post = {} @examples = [] @parent = nil @parents = [self] @children = [] @mock_verify = Proc.new { Mock.verify_count } @mock_cleanup = Proc.new { Mock.cleanup } @expectation_missing = Proc.new { raise SpecExpectationNotFoundError } end |
Instance Attribute Details
#children ⇒ Object (readonly)
Returns the value of attribute children.
13 14 15 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 13 def children @children end |
#examples ⇒ Object (readonly)
Returns the value of attribute examples.
13 14 15 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 13 def examples @examples end |
#parent ⇒ Object
Returns the value of attribute parent.
13 14 15 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 13 def parent @parent end |
#parents ⇒ Object (readonly)
Returns the value of attribute parents.
13 14 15 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 13 def parents @parents end |
#state ⇒ Object (readonly)
Returns the value of attribute state.
13 14 15 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 13 def state @state end |
Instance Method Details
#adopt(parent) ⇒ Object
Adds a nested ContextState in a shared ContextState to a containing ContextState.
Normal adoption is from the parent’s perspective. But adopt is a good verb and it’s reasonable for the child to adopt the parent as well. In this case, manipulating state from inside the child avoids needlessly exposing the state to manipulate it externally in the dup. (See #it_should_behave_like)
86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 86 def adopt(parent) self.parent = parent @examples = @examples.map do |example| example = example.dup example.context = self example end children = @children @children = [] children.each { |child| child.dup.adopt self } end |
#after(what, &block) ⇒ Object
Records after(:each) and after(:all) blocks.
122 123 124 125 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 122 def after(what, &block) return if MSpec.guarded? block ? @after[what].unshift(block) : @after[what] end |
#before(what, &block) ⇒ Object
Records before(:each) and before(:all) blocks.
116 117 118 119 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 116 def before(what, &block) return if MSpec.guarded? block ? @before[what].push(block) : @before[what] end |
#child(child) ⇒ Object
Add the ContextState instance child
to the list of nested describe blocks.
74 75 76 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 74 def child(child) @children << child end |
#describe(&block) ⇒ Object
Evaluates the block and resets the toplevel ContextState
to #parent.
140 141 142 143 144 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 140 def describe(&block) @parsed = protect @to_s, block, false MSpec.register_current parent MSpec.register_shared self if shared? end |
#description ⇒ Object
Returns a description string generated from self and all parents
147 148 149 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 147 def description @description ||= parents.map { |p| p.to_s }.compact.join(" ") end |
#filter_examples ⇒ Object
Removes filtered examples. Returns true if there are examples left to evaluate.
187 188 189 190 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 187 def filter_examples @examples.reject! { |ex| ex.filtered? } not @examples.empty? end |
#initialize_copy(other) ⇒ Object
Remove caching when a ContextState is dup’d for shared specs.
41 42 43 44 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 41 def initialize_copy(other) @pre = {} @post = {} end |
#it(desc, &block) ⇒ Object
Creates an ExampleState instance for the block and stores it in a list of examples to evaluate unless the example is filtered.
129 130 131 132 133 134 135 136 137 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 129 def it(desc, &block) #RHO puts "- it \"#{desc}\"" #RHO example = ExampleState.new(self, desc, block) MSpec.actions :add, example return if MSpec.guarded? @examples << example end |
#it_should_behave_like(desc) ⇒ Object
Injects the before/after blocks and examples from the shared describe block into this ContextState
instance.
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 153 def it_should_behave_like(desc) return if MSpec.guarded? unless state = MSpec.retrieve_shared(desc) raise Exception, "Unable to find shared 'describe' for #{desc}" end state.before(:all).each { |b| before :all, &b } state.before(:each).each { |b| before :each, &b } state.after(:each).each { |b| after :each, &b } state.after(:all).each { |b| after :all, &b } state.examples.each do |example| example = example.dup example.context = self @examples << example end state.children.each do |child| child.dup.adopt self end end |
#post(what) ⇒ Object
Returns a list of all after(what
) blocks from self and any parents. The list is in reverse order. In other words, the blocks defined in inner describes are in the list before those defined in outer describes, and in a particular describe block those defined later are in the list before those defined earlier.
111 112 113 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 111 def post(what) @post[what] ||= parents.inject([]) { |l, s| l.unshift(*s.after(what)) } end |
#pre(what) ⇒ Object
Returns a list of all before(what
) blocks from self and any parents.
102 103 104 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 102 def pre(what) @pre[what] ||= parents.inject([]) { |l, s| l.push(*s.before(what)) } end |
#process ⇒ Object
Evaluates the examples in a ContextState
. Invokes the MSpec events for :enter, :before, :after, :leave.
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 194 def process MSpec.register_current self if @parsed and filter_examples MSpec.shuffle @examples if MSpec.randomize? MSpec.actions :enter, description if protect "before :all", pre(:all) @examples.each do |state| @state = state example = state.example MSpec.actions :before, state if protect "before :each", pre(:each) MSpec.clear_expectations if example passed = protect nil, example MSpec.actions :example, state, example #protect nil, @expectation_missing unless MSpec.expectation? or not passed end protect "after :each", post(:each) protect "Mock.verify_count", @mock_verify end protect "Mock.cleanup", @mock_cleanup MSpec.actions :after, state @state = nil end protect "after :all", post(:all) else protect "Mock.cleanup", @mock_cleanup end MSpec.actions :leave end MSpec.register_current nil children.each { |child| child.process } end |
#protect(what, blocks, check = true) ⇒ Object
Evaluates each block in blocks
using the MSpec.protect
method so that exceptions are handled and tallied. Returns true and does NOT evaluate any blocks if check
is true and MSpec.mode?(:pretend)
is true.
180 181 182 183 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 180 def protect(what, blocks, check=true) return true if check and MSpec.mode? :pretend Array(blocks).all? { |block| MSpec.protect what, &block } end |
#shared? ⇒ Boolean
Returns true if this is a shared ContextState
. Essentially, when created with: describe “Something”, :shared => true { … }
48 49 50 |
# File 'lib/extensions/mspec/mspec/runner/context.rb', line 48 def shared? return @options[:shared] end |