Skip to content

Instantly share code, notes, and snippets.

@txus
Created February 2, 2011 09:19
Show Gist options
  • Select an option

  • Save txus/807456 to your computer and use it in GitHub Desktop.

Select an option

Save txus/807456 to your computer and use it in GitHub Desktop.
RSpec matcher for delegations
# RSpec matcher to spec delegations.
#
# 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) }
# end
RSpec::Matchers.define :delegate do |method|
match do |delegator|
@method = @prefix ? :"#{@to}_#{method}" : method
@delegator = delegator
begin
@delegator.send(@to)
rescue NoMethodError
raise "#{@delegator} does not respond to #{@to}!"
end
@delegator.stub(@to).and_return double('receiver')
@delegator.send(@to).stub(method).and_return :called
@delegator.send(@method) == :called
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 }
end
@fbjork

fbjork commented Feb 3, 2011

Copy link
Copy Markdown

Been looking for something like this, awesome work!

However, I get this error when I try to run this matcher:
it { should delegate(:name).to(:profile)}
error:
id is required for non-singleton resources

any idea what's going?

@txus

txus commented Feb 5, 2011

Copy link
Copy Markdown
Author

I'm afraid it has nothing to do with the delegator... Could you provide a full backtrace and maybe also the code for your model?

@jsnrth

jsnrth commented Jun 10, 2011

Copy link
Copy Markdown

Exactly what I needed – thanks! -j

@isaacbowen

Copy link
Copy Markdown

Thanks!

@pcreux

pcreux commented Dec 1, 2011

Copy link
Copy Markdown

Cool thanks!

@tshchik

tshchik commented Mar 18, 2012

Copy link
Copy Markdown

Thanks!

@cveneziani

Copy link
Copy Markdown

Awesome! Very useful.

@dankozlowski

Copy link
Copy Markdown

You should try to get this into Shoulda!

@ssimeonov

Copy link
Copy Markdown

This is cool but there are three small problems with this implementation:

  1. It does not work in the case of delegating to instance variables, e.g., delegate :foo, to: :'@my_var'
  2. Validating that the delegation target exists by using @delegator.send(@to) is an unexpected behavior from the standpoint of the user of the matcher. If there are any side effects from that call, the test outcome could be affected.
  3. The rescue block won't catch arity-related errors.

All three issues are fixed in my fork: https://gist.github.com/ssimeonov/5942729

@bparanj

bparanj commented Nov 3, 2015

Copy link
Copy Markdown

This fails if the method is a setter with error:

 Failure/Error: it{ should delegate(:name=).to(:sku_description)}

@bparanj

bparanj commented Nov 3, 2015

Copy link
Copy Markdown

My fork has updated this gist to RSpec 3.3 version: https://gist.github.com/bparanj/4579700adca0b64e7ca0

@nelantone

Copy link
Copy Markdown

Hahah! @txus ! Te veo hasta en la sopa :).

@hrieke

hrieke commented May 20, 2020

Copy link
Copy Markdown

Hello,

Do you have a license that you would like to release this code under?
I spoke with Alec Winograd about his fork-of-Simeon's-fork (yep, 2 down), he's added an MIT License to his modifications.
I have also asked Simeon if he'd like to add a license to his modification, but it would be absolutely wonderful if you could assign a license to your code. [Edit] Simeon Simeonov has replied, and selected the MIT License for his modifications as well. [/Edit]

Thank you, hope all is well.

@julienbourdeau

Copy link
Copy Markdown

I'm using this for now but thanks for the original work 👏 ❤️

➡️ https://gist.github.com/purp/fe5f79e878b609560724d6b03242a5df

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