class RSpec::Mocks::Matchers::ReceiveMessageChain

@private

def description

def description
  "receive message chain #{formatted_chain}"
end

def formatted_chain

def formatted_chain
  @formatted_chain ||= @chain.map do |part|
    if Hash === part
      part.keys.first.to_s
    else
      part.to_s
    end
  end.join(".")
end

def initialize(chain, &block)

def initialize(chain, &block)
  @chain = chain
  @block = block
  @recorded_customizations  = []
end

def matcher_name

def matcher_name
  "receive_message_chain"
end

def replay_customizations(chain)

def replay_customizations(chain)
  @recorded_customizations.each do |customization|
    customization.playback_onto(chain)
  end
end

def setup_allowance(subject, &block)

def setup_allowance(subject, &block)
  chain = StubChain.stub_chain_on(subject, *@chain, &(@block || block))
  replay_customizations(chain)
end

def setup_any_instance_allowance(subject, &block)

def setup_any_instance_allowance(subject, &block)
  proxy = ::RSpec::Mocks.space.any_instance_proxy_for(subject)
  chain = proxy.stub_chain(*@chain, &(@block || block))
  replay_customizations(chain)
end

def setup_any_instance_expectation(subject, &block)

def setup_any_instance_expectation(subject, &block)
  proxy = ::RSpec::Mocks.space.any_instance_proxy_for(subject)
  chain = proxy.expect_chain(*@chain, &(@block || block))
  replay_customizations(chain)
end

def setup_expectation(subject, &block)

def setup_expectation(subject, &block)
  chain = ExpectChain.expect_chain_on(subject, *@chain, &(@block || block))
  replay_customizations(chain)
end

def setup_negative_expectation(*_args)

def setup_negative_expectation(*_args)
  raise NegationUnsupportedError,
        "`expect(...).not_to receive_message_chain` is not supported " \
        "since it doesn't really make sense. What would it even mean?"
end