class RSpec::Matchers::BuiltIn::YieldProbe

@private Object that is yielded to `expect` when one of the yield matchers is used. Provides information about the yield behavior of the object-under-test.

Attributes

num_yields[RW]
yielded_args[RW]

Public Class Methods

new(block) click to toggle source
# File lib/rspec/matchers/built_in/yield.rb, line 22
def initialize(block)
  @block = block
  @used = false
  self.num_yields = 0
  self.yielded_args = []
end
probe(block) click to toggle source
# File lib/rspec/matchers/built_in/yield.rb, line 11
def self.probe(block)
  probe = new(block)
  return probe unless probe.has_block?
  probe.assert_valid_expect_block!
  block.call(probe)
  probe.assert_used!
  probe
end

Public Instance Methods

assert_used!() click to toggle source
# File lib/rspec/matchers/built_in/yield.rb, line 65
def assert_used!
  return if @used
  raise 'You must pass the argument yielded to your expect block on '                  'to the method-under-test as a block. It acts as a probe that '                  'allows the matcher to detect whether or not the method-under-test '                  'yields, and, if so, how many times, and what the yielded arguments '                  'are.'
end
assert_valid_expect_block!() click to toggle source
# File lib/rspec/matchers/built_in/yield.rb, line 75
def assert_valid_expect_block!
  block_signature = RSpec::Support::BlockSignature.new(@block)
  return if RSpec::Support::StrictSignatureVerifier.new(block_signature, [self]).valid?
  raise 'Your expect block must accept an argument to be used with this '                    'matcher. Pass the argument as a block on to the method you are testing.'
end
has_block?() click to toggle source
# File lib/rspec/matchers/built_in/yield.rb, line 29
def has_block?
  Proc === @block
end
single_yield_args() click to toggle source
# File lib/rspec/matchers/built_in/yield.rb, line 44
def single_yield_args
  yielded_args.first
end
successive_yield_args() click to toggle source
# File lib/rspec/matchers/built_in/yield.rb, line 59
def successive_yield_args
  yielded_args.map do |arg_array|
    arg_array.size == 1 ? arg_array.first : arg_array
  end
end
to_proc() click to toggle source
# File lib/rspec/matchers/built_in/yield.rb, line 33
def to_proc
  @used = true

  probe = self
  Proc.new do |*args|
    probe.num_yields += 1
    probe.yielded_args << args
    nil # to indicate the block does not return a meaningful value
  end
end
yielded_once?(matcher_name) click to toggle source
# File lib/rspec/matchers/built_in/yield.rb, line 48
def yielded_once?(matcher_name)
  case num_yields
  when 1 then true
  when 0 then false
  else
    raise "The #{matcher_name} matcher is not designed to be used with a "                    'method that yields multiple times. Use the yield_successive_args '                    'matcher for that case.'
  end
end