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

nicholas a. evans nick at ekenosen.net
Mon Jun 4 18:45:43 EDT 2007

On 6/4/07, Joseph Method <tristil at gmail.com> wrote:
> This looks right. One thing: I think validation_for inserts behaviors
> into the example. I mean, that's how I think it should be implemented.
> The question is, how many are there in the first example? How about 3?
>  That is:
> - Person validates :firstname (not nil, "foo" okay, not "bar")
> - Person validates :firstname should reject "" with 'can't be blank' message
> - Person "should reject a super long firstname"

As I intended it each "it_should_reject" or "it_should_accept"
generates a new example (and returns the matcher used in that example,
so that the matcher can be modified via "with", etc).  If you want to
have multiple expectations per example string, then you are free to do
so, using the normal rspec matchers.  For example:

validation_for(:firstname) do
  it "should validate :firstname (not nil, "foo" okay, not "bar")" do
    @it.should reject nil
    @it.should accept "foo"
    @it.should reject "bar"

I *strongly* prefer the one assertion/expectation per
test/spec/example style, so I really don't intend to ever do that or
have need for something to simplify it.  And I recommend against it.

Also, I believe that the generated spec strings should be simpler and
smaller when using this syntax.  I don't need to or want to mention
which fields are being validated on each line (I can do that in the
behavior string if necessary). For example,
http://pastie.caboo.se/67605 should generate the following specdoc:

Person firstname
- should reject nil
- should reject "" with "can't be blank"
- should accept "foo"
- should accept "bar"
- should reject a super long firstname

Person validation to ensure that Oingo Boingo isn't used
- should accept "Nicholas", "Evans"
- should accept "David", "Chelimsky"
- should reject "Oingo", "Boingo"
- should reject "Danny", "Elfman"

FWIW, these names are rejected out of *respect*.  Our humble Person
model is not deserving of them.  They are represented with the
MusicalGenius model.  ;-)

> The .because("should reject a super long firstname") syntax in my
> example would be equivalent to the third example.

My thought: I don't like the "because" syntax as you stated it above
because it goes outside of the rspec syntax, but it is actually a
character longer than doing it the rspec way:

it "should fooooo" { @it.should reject(foo) }
it_should_reject(foo).because("should fooooo")

We might use it instead to append an explanation to the generated
example string: 'should reject foo with "bar" because blatz'.  But
then I have to wonder, why not just have a more descriptive error
message that could do the job?  If your error message isn't enough to
make sense to your developers and analysts reading the specs, then it
must be *really* confusing to the users!  So consider me opposed to
the "because" syntax.  But if you want it, it should be *very* easy
for you to add.  ;-)


More information about the rspec-users mailing list