Skip to content

Instantly share code, notes, and snippets.

@awinograd
Forked from ssimeonov/delegate_matcher.rb
Last active May 27, 2020 11:14
Show Gist options
  • Select an option

  • Save awinograd/6158961 to your computer and use it in GitHub Desktop.

Select an option

Save awinograd/6158961 to your computer and use it in GitHub Desktop.
# RSpec matcher to spec delegations.
# Forked from https://gist.github.com/ssimeonov/5942729 with fixes
# for arity + custom prefix.
#
# Usage:
#
# describe Post do
# it { should delegate(:name).to(:author).with_prefix } # post.author_name
# it { should delegate(:name).to(:author).with_prefix(:any) } # post.any_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 ? :"#{@prefix}_#{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 [0,-1].include?(@delegator.method(@to).arity)
raise "#{@delegator}'s' #{@to} method does not have zero or -1 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| @prefix = prefix || @to }
def receiver_double(method)
double('receiver').tap do |receiver|
receiver.stub(method).and_return :called
end
end
end
@awinograd

Copy link
Copy Markdown
Author

@hrieke i suggest taking a look at @dwhelan's gem.

Unfortunately this gist is a fork of many before it so I can't give away full ownership of the code

@hrieke

hrieke commented May 20, 2020

Copy link
Copy Markdown

Okay, I've gone and asked the others as well. I'll let you know if I hear back from any of them.
The problem is that even Declan Whelan's code has your code in it, which technically you, and those you forked from own. Toss in US copyright law, is enough to make this mountain boy curse in yiddish.

@awinograd

awinograd commented May 20, 2020

Copy link
Copy Markdown
Author

Any code of mine in this gist is covered by MIT license

@hrieke

hrieke commented May 20, 2020

Copy link
Copy Markdown

Awesome. Thank you so much. I'll update the others with your note and hopefully they all do the same.

@dwhelan

dwhelan commented May 26, 2020

Copy link
Copy Markdown

Henry, happy to help if I can. Is there anything specific you would like from me?

@hrieke

hrieke commented May 27, 2020

Copy link
Copy Markdown

Hello Declan,
Thank you for your offer of assistance, but everyone that I have asked to assign a license to their code has (looking at you txus...).
Have a great summer, both of you.

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