Last active
January 15, 2016 11:42
-
-
Save nepalez/7a33e39d5fc3162c0ba2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "rspec" | |
require "mustermann" | |
require "delegate" | |
# Gem-speficic RSpec mocks and expectations | |
# | |
# @example | |
# allow(client) | |
# .to receive_request(:get, '/users/1') | |
# .where { |req| req[:query].include? "auth" => "foobar" } | |
# .and_return status: 200, body: { "id" => 1, "name" => "Andrew" } | |
# | |
# expect(client).to receive_request(:get, '/users/1').twice | |
# | |
# client.path("/users/1").get auth: "foobar" | |
# client.path("/users/1").get auth: "foobar" | |
# | |
module Evil::Client::RSpec | |
# Redefines stub to use client.connection instead of a client | |
# | |
# @param [Object] subject | |
# | |
# @return [undefined] | |
# | |
def allow(subject) | |
super coerce_evil_client(subject) | |
end | |
# Redefines stub to use client.connection instead of a client | |
# | |
# @param [Object] subject | |
# | |
# @return [undefined] | |
# | |
def expect(subject = nil, &block) | |
block ? super(&block) : super(coerce_evil_client(subject)) | |
end | |
# Provides gem-specific variant of `receive` mock matcher | |
# | |
# @param [#to_s] method The method of the request | |
# @param [#to_s] path The rails pattern for the request path | |
# | |
# @return [RSpec::Mocks::Matchers::Receive] | |
# | |
def receive_request(method, path = nil) | |
matcher = receive(:call).tap { |object| object.extend Receive } | |
matcher = matcher.where(&match_evil_method(method)) unless method == :any | |
matcher = matcher.where(&match_evil_path(path)) if path | |
matcher | |
end | |
private | |
def coerce_evil_client(subject) | |
subject.is_a?(Evil::Client) ? subject.connection : subject | |
end | |
def match_evil_method(method) | |
proc { |req| req[:method] == method.to_s } | |
end | |
def match_evil_path(path) | |
proc { |req| Mustermann.new(path, type: :rails) === req[:path].to_s } | |
end | |
# @private | |
module Receive | |
def where(&block) | |
with BlockMatcher.new(lazy_constraints << block) | |
end | |
private | |
def lazy_constraints | |
@lazy_constraints ||= [] | |
end | |
# @private | |
class BlockMatcher < SimpleDelegator | |
def initialize(procs) | |
matcher = proc do |req| | |
procs.inject(true) { |result, item| result && item[req] } | |
end | |
super(matcher) | |
end | |
def match?(subject) | |
call(subject) | |
end | |
end | |
end | |
end | |
RSpec.configure { |config| config.include(Evil::Client::RSpec) } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment