On 3 Aug 2010, at 12:50 PM, David C. wrote:
Pushed:
Pass parameters given to #it_should_behave_like on to the shared exam… · rspec/rspec-core@8430361 · GitHub
Raise error when passing params to shared example groups in Ruby 1.8.6. · rspec/rspec-core@3cea7b8 · GitHub
Awesomeness!
Please do let me know if this works with what you’ve got.
In general, yes, this is a massive improvement! I’ve realised some
things that never occurred to me before, though. Maybe you have some
thoughts…
I’ve put everything on a Gist[1] (which needs a few tweaks here and
there, but I think it’s a reasonably example). Notes:
-
DomainLib is my holding module for everything I’ve extracted out of
the project source. Anything inside that is generic, analogous to eg
ActiveRecord (eg Entity ↔ AR::Base)
-
I’ve only pasted the specs, and only the contract-based ones at that
(the implementation is not very interesting, nor is the interaction
spec).
-
I don’t like the word contract any more, at least not here. It needs
a better name, probably something that would fit if you wrote a similar
spec for ActiveRecord’s has_many.
Some things I ran into:
First, I found that you can’t use the block variables in local helper
methods. Because Ruby methods aren’t closures, I’ve had to replace
methods like:
def entity_dot_new_collection_member(*args)
entity.send(:“new_#{item_name}”, *args)
end
with:
define_method :entity_dot_new_collection_member do |*args|
entity.send(:“new_#{item_name}”, *args)
end
Not a big deal, but it’s not as readable as it was before. (Not that it
was exactly large-print Winnie the Pooh to start with, given the
abstract nature of the shared examples.)
Second, you can’t refer to described_class
in the descriptions. I
don’t know why I though you’d be able to, but it would be nice if it
worked (You can see the place where my failed attempt was, where I
left <described_class>.)
Finally, I realised something when I added another example. I should
say though, that all this time, I was only using the shared examples
with one collection on the entity, and I added another a few minutes ago
just for fun, and it just worked… I like But it raised a point
about things that are common to all shared examples, and parameters to
individual uses. In my example case, entity_class
and entity
are
relevant to both of the “collection” shared example groups, but
collection_name
, item_name
, class_name
are parameters to the
shared examples individually.
With the current setup, there’s no way to require that a host group
provides eg entity_class
. And also, if it’s defined as a let
in the
host, you can’t use it in the descriptions in the shared example group
(which you couldn’t before, of course).
So I think this solves 90% of the problems I had before, and is
certainly a workable solution to the specs I’m trying to write. I’d
love to hear your thoughts on the rest though.
The issue of the evaluation order is still up for grabs, but this now supports params to shared groups in Ruby >= 1.8.7.
Well, I deliberately didn’t check what order you ended up using!
Whatever it is works for me now, although I guess future experiments
could change that…
Cheers!
Ash
[1] entity_contract.rb · GitHub
–
http://www.patchspace.co.uk/
http://www.linkedin.com/in/ashleymoran