Parent

Files

Class/Module Index [+]

Quicksearch

ContextState

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.

Attributes

children[R]
examples[R]
parent[R]
parents[R]
state[R]
to_s[R]

Public Class Methods

new(mod, options=nil) click to toggle source
# File lib/mspec/runner/context.rb, line 15
def initialize(mod, options=nil)
  @to_s = mod.to_s
  if options.is_a? Hash
    @options = options
  else
    @to_s += "#{".:#".include?(options[0,1]) ? "" : " "}#{options}" if options
    @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

Public Instance Methods

adopt(parent) click to toggle source

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)

# File lib/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) click to toggle source

Records after(:each) and after(:all) blocks.

# File lib/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) click to toggle source

Records before(:each) and before(:all) blocks.

# File lib/mspec/runner/context.rb, line 116
def before(what, &block)
  return if MSpec.guarded?
  block ? @before[what].push(block) : @before[what]
end
child(child) click to toggle source

Add the ContextState instance child to the list of nested describe blocks.

# File lib/mspec/runner/context.rb, line 74
def child(child)
  @children << child
end
describe(&block) click to toggle source

Evaluates the block and resets the toplevel ContextState to parent.

# File lib/mspec/runner/context.rb, line 137
def describe(&block)
  @parsed = protect @to_s, block, false
  MSpec.register_current parent
  MSpec.register_shared self if shared?
end
description() click to toggle source

Returns a description string generated from self and all parents

# File lib/mspec/runner/context.rb, line 144
def description
  @description ||= parents.map { |p| p.to_s }.compact.join(" ")
end
filter_examples() click to toggle source

Removes filtered examples. Returns true if there are examples left to evaluate.

# File lib/mspec/runner/context.rb, line 184
def filter_examples
  @examples.reject! { |ex| ex.filtered? }
  not @examples.empty?
end
initialize_copy(other) click to toggle source

Remove caching when a ContextState is dup'd for shared specs.

# File lib/mspec/runner/context.rb, line 41
def initialize_copy(other)
  @pre  = {}
  @post = {}
end
it(desc, &block) click to toggle source

Creates an ExampleState instance for the block and stores it in a list of examples to evaluate unless the example is filtered.

# File lib/mspec/runner/context.rb, line 129
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) click to toggle source

Injects the before/after blocks and examples from the shared describe block into this ContextState instance.

# File lib/mspec/runner/context.rb, line 150
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
parent=(parent) click to toggle source

Set the parent (enclosing) ContextState for this state. Creates the parents list.

# File lib/mspec/runner/context.rb, line 54
def parent=(parent)
  @description = nil

  if shared?
    @parent = nil
  else
    @parent = parent
    parent.child self if parent

    @parents = [self]
    state = parent
    while state
      @parents.unshift state
      state = state.parent
    end
  end
end
post(what) click to toggle source

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.

# File lib/mspec/runner/context.rb, line 111
def post(what)
  @post[what] ||= parents.inject([]) { |l, s| l.unshift(*s.after(what)) }
end
pre(what) click to toggle source

Returns a list of all before(what) blocks from self and any parents.

# File lib/mspec/runner/context.rb, line 102
def pre(what)
  @pre[what] ||= parents.inject([]) { |l, s| l.push(*s.before(what)) }
end
process() click to toggle source

Evaluates the examples in a ContextState. Invokes the MSpec events for :enter, :before, :after, :leave.

# File lib/mspec/runner/context.rb, line 191
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|
        MSpec.repeat do
          @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
      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) click to toggle source

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.

# File lib/mspec/runner/context.rb, line 177
def protect(what, blocks, check=true)
  return true if check and MSpec.mode? :pretend
  Array(blocks).all? { |block| MSpec.protect what, &block }
end
shared?() click to toggle source

Returns true if this is a shared ContextState. Essentially, when created with: describe "Something", :shared => true { ... }

# File lib/mspec/runner/context.rb, line 48
def shared?
  return @options[:shared]
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.