John Feminella
John Feminella

Reputation: 311536

How do I transform a Ruby block and apply it as an argument to another block?

I'm reducing the verbosity on a lot of related specs with a small shortcut method I wrote:

def association_spec_for(kind, field)
  it { expect(subject).to send(kind, field) }
end

This gets used like this:

describe Student do
  association_spec_for :have_many, :courses
  association_spec_for :have_one, :transcript
end

Now I'd like to expand the way association_spec_for works, so that I can do this while still leaving the original use cases intact:

association_spec_for(:foo, :bar) do |a|
  a.baz(:blerp).bloop(:bleep => :blarg)
end

and have it turn into this:

it { expect(subject).to send(:foo, :bar).baz(:blerp).bloop(:bleep => :blarg) }

                                      # |----------------------------------|
                                      #    This part came from the block
                                      #      that was passed to a_s_f.

What's the best way to make that happen?

Upvotes: 0

Views: 39

Answers (1)

sawa
sawa

Reputation: 168101

def association_spec_for(kind, field, &pr)
  it{expect(subject).to pr ? pr.call(send(kind, field)) : send(kind, field)}
end

Upvotes: 1

Related Questions