Skip to content

Instantly share code, notes, and snippets.

@ssimeonov
Forked from txus/delegate_matcher.rb
Last active May 21, 2020 13:56
Show Gist options
  • Save ssimeonov/5942729 to your computer and use it in GitHub Desktop.
Save ssimeonov/5942729 to your computer and use it in GitHub Desktop.
# RSpec matcher to spec delegations.
# Forked from https://gist.github.com/txus/807456 with added bug fixes
#
# Usage:
#
# describe Post do
# it { should delegate(:name).to(:author).with_prefix } # post.author_name
# it { should delegate(:month).to(:created_at) }
# it { should delegate(:year).to(:created_at) }
# it { should delegate(:something).to(:'@instance_var') }
# end
RSpec::Matchers.define :delegate do |method|
match do |delegator|
@method = @prefix ? :"#{@to}_#{method}" : method
@delegator = delegator
if @to.to_s[0] == '@'
# Delegation to an instance variable
old_value = @delegator.instance_variable_get(@to)
begin
@delegator.instance_variable_set(@to, receiver_double(method))
@delegator.send(@method) == :called
ensure
@delegator.instance_variable_set(@to, old_value)
end
elsif @delegator.respond_to?(@to, true)
unless @delegator.method(@to).arity == 0
raise "#{@delegator}'s' #{@to} method does not have zero arity (it expects parameters)"
end
@delegator.stub(@to).and_return receiver_double(method)
@delegator.send(@method) == :called
else
raise "#{@delegator} does not respond to #{@to}"
end
end
description do
"delegate :#{@method} to its #{@to}#{@prefix ? ' with prefix' : ''}"
end
failure_message_for_should do |text|
"expected #{@delegator} to delegate :#{@method} to its #{@to}#{@prefix ? ' with prefix' : ''}"
end
failure_message_for_should_not do |text|
"expected #{@delegator} not to delegate :#{@method} to its #{@to}#{@prefix ? ' with prefix' : ''}"
end
chain(:to) { |receiver| @to = receiver }
chain(:with_prefix) { @prefix = true }
def receiver_double(method)
double('receiver').tap do |receiver|
receiver.stub(method).and_return :called
end
end
end
@hrieke
Copy link

hrieke commented May 21, 2020

Awesome and thank you very much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment