class RSpec::Matchers::BuiltIn::Compound::NestedEvaluator

Normally, we evaluate the matching sequentially. For an expression like ‘expect(x).to foo.and bar`, this becomes:

expect(x).to foo
expect(x).to bar

For block expectations, we need to nest them instead, so that ‘expect { x }.to foo.and bar` becomes:

expect {
  expect { x }.to foo
}.to bar

This is necessary so that the ‘expect` block is only executed once.

Public Class Methods

# File rspec-expectations/lib/rspec/matchers/built_in/compound.rb, line 236
def self.matcher_expects_call_stack_jump?(matcher)
  matcher.expects_call_stack_jump?
rescue NoMethodError
  false
end
# File rspec-expectations/lib/rspec/matchers/built_in/compound.rb, line 160
def initialize(actual, matcher_1, matcher_2)
  @actual        = actual
  @matcher_1     = matcher_1
  @matcher_2     = matcher_2
  @match_results = {}

  inner, outer = order_block_matchers

  @match_results[outer] = outer.matches?(Proc.new do |*args|
    @match_results[inner] = inner.matches?(inner_matcher_block(args))
  end)
end

Public Instance Methods

# File rspec-expectations/lib/rspec/matchers/built_in/compound.rb, line 173
def matcher_matches?(matcher)
  @match_results.fetch(matcher) do
    raise ArgumentError, "Your #{matcher.description} has no match " \
     "results, this can occur when an unexpected call stack or " \
     "local jump occurs. Perhaps one of your matchers needs to " \
     "declare `expects_call_stack_jump?` as `true`?"
  end
end