Skip to content

Instantly share code, notes, and snippets.

@nepalez
Created January 14, 2016 15:43
Show Gist options
  • Save nepalez/ac049b788c369e8d98a3 to your computer and use it in GitHub Desktop.
Save nepalez/ac049b788c369e8d98a3 to your computer and use it in GitHub Desktop.
require "rspec"
require "mustermann"
# Checks whether client condition has received given request
#
# @example
# allow(client)
# .to receive_request(:get, "example.com/users/:id/bills")
# .and_return({ id: 1, price: 100, currency: "RUR" })
#
# expect(client)
# .to receive_request(:get, "example.com/users/:id/bills")
# .exactly(1).times
#
# client.path(:users, 1, :bills).get
# # => { id: 1, price: 100, currency: "RUR" }
#
RSpec::Matchers.define :receive_request do |method, path = nil|
# List of constraints for the request
#
# @return [Array<Proc>]
#
def constraints
@constraints ||= check_arguments
end
# A constraint to check whether a request satisfies given method and path
#
# @return [Proc]
#
def check_arguments
proc { |req| check_method[req] && check_path[req] }
end
# Checks whether a request satisfies path constraint
#
# @reurn [Boolean]
#
def check_path
return proc { |_| true } unless path
pattern = Mustermann.new(path, type: :rails)
proc { |req| pattern == req[:path].to_s }
end
# Checks whether a request satisfies method constraint
#
# @return [Boolean]
#
def check_method
return proc { |_| true } if method == :any
proc { |req| req[:method] == method.to_s }
end
# The resulting receive matcher for the client's connection
#
# @return [RSpec::Mocks::Matchers::Receive]
#
def satisfy_condition
@satisfy_condition ||= receive(:call).with(&constraints)
end
match do |client|
expect(client.connection).to satisfy_condition
end
match_when_negated do |client|
expect(client.connection).not_to satisfy_condition
end
chain :where do |&block|
@constraints = proc { |req| constraints[req] && block[req] }
end
chain :and_call_original do
@satisfy_condition = satisfy_condition.and_call_original
end
chain :and_wrap_original do |&block|
@satisfy_condition = satisfy_condition.and_wrap_original(&block)
end
chain :and_raise do |*args|
@satisfy_condition = satisfy_condition.and_raise(*args)
end
chain :and_return do |*args, &block|
@satisfy_condition = satisfy_condition.and_return(*args, &block)
end
chain :and_throw do |*args|
@satisfy_condition = satisfy_condition.and_throw(*args)
end
chain :and_yield do |*args|
@satisfy_condition = satisfy_condition.and_yield(*args)
end
chain :at_least do |value|
@satisfy_condition = satisfy_condition.at_least(value)
end
chain :at_most do |value|
@satisfy_condition = satisfy_condition.at_most(value)
end
chain :exactly do |value|
@satisfy_condition = satisfy_condition.exactly(value)
end
chain :never do
@satisfy_condition = satisfy_condition.never
end
chain :once do
@satisfy_condition = satisfy_condition.once
end
chain :ordered do
@satisfy_condition = satisfy_condition.ordered
end
chain :thrice do
@satisfy_condition = satisfy_condition.thrice
end
chain :times do
@satisfy_condition = satisfy_condition.times
end
chain :time do
@satisfy_condition = satisfy_condition.times
end
chain :twice do
@satisfy_condition = satisfy_condition.twice
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment