Class: ContextState
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
-
#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.
-
#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. - #replace_parent(parent) ⇒ Object
-
#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/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/mspec/runner/context.rb', line 13 def children @children end |
#examples ⇒ Object (readonly)
Returns the value of attribute examples.
13 14 15 |
# File 'lib/mspec/runner/context.rb', line 13 def examples @examples end |
#parent ⇒ Object
Returns the value of attribute parent.
13 14 15 |
# File 'lib/mspec/runner/context.rb', line 13 def parent @parent end |
#parents ⇒ Object (readonly)
Returns the value of attribute parents.
13 14 15 |
# File 'lib/mspec/runner/context.rb', line 13 def parents @parents end |
#state ⇒ Object (readonly)
Returns the value of attribute state.
13 14 15 |
# File 'lib/mspec/runner/context.rb', line 13 def state @state end |
#to_s ⇒ Object (readonly)
Returns the value of attribute to_s.
13 14 15 |
# File 'lib/mspec/runner/context.rb', line 13 def to_s @to_s end |
Instance Method Details
#after(what, &block) ⇒ Object
Records after(:each) and after(:all) blocks.
93 94 95 96 |
# File 'lib/mspec/runner/context.rb', line 93 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.
87 88 89 90 |
# File 'lib/mspec/runner/context.rb', line 87 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.
68 69 70 |
# File 'lib/mspec/runner/context.rb', line 68 def child(child) @children << child end |
#describe(&block) ⇒ Object
Evaluates the block and resets the toplevel ContextState
to #parent.
108 109 110 111 112 |
# File 'lib/mspec/runner/context.rb', line 108 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
115 116 117 |
# File 'lib/mspec/runner/context.rb', line 115 def description @description ||= parents.map { |p| p.to_s }.join(" ") end |
#filter_examples ⇒ Object
Removes filtered examples. Returns true if there are examples left to evaluate.
154 155 156 157 |
# File 'lib/mspec/runner/context.rb', line 154 def filter_examples @examples.reject! { |ex| ex.filtered? } not @examples.empty? 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.
100 101 102 103 104 105 |
# File 'lib/mspec/runner/context.rb', line 100 def it(desc, &block) 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.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/mspec/runner/context.rb', line 121 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.examples.each { |ex| ex.context = self; @examples << ex } 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 } # There is a potential race here if mspec ever implements concurrency # in process. Right now, the only way to run specs concurrently is # with multiple processes, so we ignore this for the sake of simplicity. state.children.each do |child| child.replace_parent self @children << child 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.
82 83 84 |
# File 'lib/mspec/runner/context.rb', line 82 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.
73 74 75 |
# File 'lib/mspec/runner/context.rb', line 73 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.
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/mspec/runner/context.rb', line 161 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.
147 148 149 150 |
# File 'lib/mspec/runner/context.rb', line 147 def protect(what, blocks, check=true) return true if check and MSpec.mode? :pretend Array(blocks).all? { |block| MSpec.protect what, &block } end |
#replace_parent(parent) ⇒ Object
60 61 62 63 64 |
# File 'lib/mspec/runner/context.rb', line 60 def replace_parent(parent) @parents[0] = parent children.each { |child| child.replace_parent parent } end |
#shared? ⇒ Boolean
Returns true if this is a shared ContextState
. Essentially, when created with: describe “Something”, :shared => true { … }
42 43 44 |
# File 'lib/mspec/runner/context.rb', line 42 def shared? return @options[:shared] end |