[rspec-users] Another attempt for a succinct model validation DSL

David Chelimsky dchelimsky at gmail.com
Fri Jun 1 01:00:29 EDT 2007

On 6/1/07, nicholas a. evans <nick at ekenosen.net> wrote:
> On 5/31/07, David Chelimsky <dchelimsky at gmail.com> wrote:
> > On 5/31/07, nicholas a. evans <nick at ekenosen.net> wrote:
> > > So here's my latest thought-experiment: http://pastie.caboo.se/66478
> > > And also, a simpler multi-field version: http://pastie.caboo.se/66510
> > I took at a shot at something that feels more like the rest of RSpec.
> > It's admittedly more verbose than your examples, but I also think it
> > speaks well and aligns with everything else in rspec. WDYT?
> >
> > http://pastie.caboo.se/66679
> Oh!  I like it a *lot*.  Yes, it's more verbose on each example than I
> prefer (8 characters plus two indentation levels plus the length of
> the block variable).  But it does read more fluidly, and in many ways
> it looks much simpler.  My "default_params" is simply your input to
> "given".  My "columns" or "field_to_validate", is simply the
> argument(s) to "it_should_require_that".  Likewise, "as" reads more
> naturally than :msg (although I had been thinking of using
> "with_message", which feels a bit more readable).
> I have only one real objection/concern:
> "given User.new" would pass in an object that would get reused for
> each accept/reject line in the block.  I prefer the approach of
> creating a new/fresh object for each example.  Perhaps it could accept
> a Proc or a symbol representing a method name, searching first for an
> instance method in the behavior, and then a class method on the class
> being described.
> "given :new" would get a different object from User.new before each example.
> "given User.new" would reuse the same new User object for all of the examples.
> "given :user_with_full_access" would call "user_with_full_access"
> (defined in that behavior or on User) before each example.
> "given user_with_full_access" would reuse the same object for all examples.
> What do you think?  Is there a better way?

I put up a third version: http://pastie.caboo.se/66776


> A few more thoughts and questions:
> How about "it_should_validate_that" rather than
> "it_should_require_that"?

"validate" is fine.

> That feels more explicit and to-the-point,
> to me.  At that point, the ":behavior_type => :validation" becomes
> redundant.  "it_should_validate_that" could simply be available to all
> model behaviors.

Why not just stick it in a module and let the user decide where to
make it available? If you, as a user of this extension, wanted it
available to all model examples, you could do this:

Spec::Runner.configure do |config|
  config.include(ModelValidations, :behaviour_type => :model)

> What else could "given" be used for?  It seems like this could become
> a pattern/approach that could extend beyond model validations...  Have
> you thought about using it for anything else yet?

Not yet. I was just bouncing off  your proposal. Let's see how this
works in practice before we start creating conventions :)

> How could we specify a *default* rejection message (or error count,
> etc)?  Does "user.default_rejection_message = /the message/" (and so
> on) look reasonable?

That seems like you're telling the user to use a specific message
rather than generally expecting it, which is what I *think* you mean.
Am I missing it?

> I did like that the each example/assertion got its own entry in the
> specdoc with my approach...  Do you think that it is best to sum it up
> to the rule?  Either way, I presume that a failure should still run
> all of examples to give a full report, rather than stop at the first
> wrong one.

I think you can get all that. The #given method has a handle on the
object before it yields to the block, the should_reject and
should_accept methods can be configured to create examples at run
time. Make sense?

> My approach assumed that if you were only working with one field, we
> should only check for errors on that one field (it's okay if the
> object is otherwise invalid).  But if you are working with multiple
> fields, you should check to see if the entire object is valid, and
> check against all error messages.  Do you think that is a safe and
> reasonable convention?

This could get quite complicated. Which is probably why nobody has
tackled this in a generic way yet - at least that I've seen.

> Thanks for your thoughts... and your improvements on my thoughts.  :-)

My pleasure. I'm looking forward to seeing how this turns out.


> --
> Nick
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

More information about the rspec-users mailing list