module RSpec::Mocks::MessageExpectation::ImplementationDetails

@private Contains the parts of ‘MessageExpectation` that aren’t part of rspec-mocks’ public API. The class is very big and could really use some collaborators it delegates to for this stuff but for now this was the simplest way to split the public from private stuff to make it easier to publish the docs for the APIs we want published.

Attributes

@private

Public Class Methods

rubocop:disable Metrics/ParameterLists

# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 422
def initialize(error_generator, expectation_ordering, expected_from, method_double,
               type=:expectation, opts={}, &implementation_block)
  @type = type
  @error_generator = error_generator
  @error_generator.opts = error_generator.opts.merge(opts)
  @expected_from = expected_from
  @method_double = method_double
  @orig_object = @method_double.object
  @message = @method_double.method_name
  @actual_received_count = 0
  @actual_received_count_write_mutex = Support::Mutex.new
  @expected_received_count = type == :expectation ? 1 : :any
  @argument_list_matcher = ArgumentListMatcher::MATCH_ALL
  @order_group = expectation_ordering
  @order_group.register(self) unless type == :stub
  @expectation_type = type
  @ordered = false
  @at_least = @at_most = @exactly = nil

  self.invoking_internals = false

  # Initialized to nil so that we don't allocate an array for every
  # mock or stub. See also comment in `and_yield`.
  @args_to_yield = nil
  @eval_context = nil
  @yield_receiver_to_implementation_block = false

  @implementation = Implementation.new
  self.inner_implementation_action = implementation_block
end

Public Instance Methods

# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 601
def actual_received_count_matters?
  @at_least || @at_most || @exactly
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 588
def additional_expected_calls
  return 0 if @expectation_type == :stub || !@exactly
  @expected_received_count - 1
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 545
def advise(*args)
  similar_messages << args
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 458
def and_yield_receiver_to_implementation
  @yield_receiver_to_implementation_block = true
  self
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 500
def called_max_times?
  @expected_received_count != :any &&
    !@at_least &&
    @expected_received_count > 0 &&
    @actual_received_count >= @expected_received_count
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 577
def description_for(verb)
  @error_generator.describe_expectation(
    verb, @message, @expected_received_count,
    @actual_received_count, expected_args
  )
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 520
def ensure_expected_ordering_received!
  @order_group.verify_invocation_order(self) if @ordered
  true
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 571
def expectation_count_type
  return :at_least if @at_least
  return :at_most if @at_most
  nil
end

rubocop:enable Metrics/ParameterLists

# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 454
def expected_args
  @argument_list_matcher.expected_args
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 516
def expected_messages_received?
  ignoring_args? || matches_exact_count? || matches_at_least_count? || matches_at_most_count?
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 553
def generate_error
  if similar_messages.empty?
    @error_generator.raise_expectation_error(
      @message, @expected_received_count, @argument_list_matcher,
      @actual_received_count, expectation_count_type, expected_args,
      @expected_from, exception_source_id
    )
  else
    @error_generator.raise_similar_message_args_error(
      self, @similar_messages, @expected_from
    )
  end
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 525
def ignoring_args?
  @expected_received_count == :any
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 605
def increase_actual_received_count!
  @actual_received_count_write_mutex.synchronize do
    @actual_received_count += 1
  end
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 477
def invoke(parent_stub, *args, &block)
  if invoking_internals
    safe_invoke_without_incrementing_received_count(parent_stub, *args, &block)
  else
    invoke_incrementing_actual_calls_by(1, true, parent_stub, *args, &block)
  end
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 491
def invoke_without_incrementing_received_count(parent_stub, *args, &block)
  invoke_incrementing_actual_calls_by(0, true, parent_stub, *args, &block)
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 467
def matches?(message, *args)
  @message == message && @argument_list_matcher.args_match?(*args)
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 529
def matches_at_least_count?
  @at_least && @actual_received_count >= @expected_received_count
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 533
def matches_at_most_count?
  @at_most && @actual_received_count <= @expected_received_count
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 537
def matches_exact_count?
  @expected_received_count == @actual_received_count
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 507
def matches_name_but_not_args(message, *args)
  @message == message && !@argument_list_matcher.args_match?(*args)
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 496
def negative?
  @expected_received_count == 0 && !@at_least
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 597
def negative_expectation_for?(message)
  @message == message && negative?
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 593
def ordered?
  @ordered
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 584
def raise_out_of_order_error
  @error_generator.raise_out_of_order_error @message
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 567
def raise_unexpected_message_args_error(args_for_multiple_calls)
  @error_generator.raise_unexpected_message_args_error(self, args_for_multiple_calls, exception_source_id)
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 472
def safe_invoke(parent_stub, *args, &block)
  invoke_incrementing_actual_calls_by(1, false, parent_stub, *args, &block)
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 486
def safe_invoke_without_incrementing_received_count(parent_stub, *args, &block)
  invoke_incrementing_actual_calls_by(0, false, parent_stub, *args, &block)
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 541
def similar_messages
  @similar_messages ||= []
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 549
def unadvise(args)
  similar_messages.delete_if { |message| args.include?(message) }
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 511
def verify_messages_received
  return if expected_messages_received?
  generate_error
end
# File rspec-mocks/lib/rspec/mocks/message_expectation.rb, line 463
def yield_receiver_to_implementation_block?
  @yield_receiver_to_implementation_block
end