Forum: RSpec custom, nested HTML matchers in RSpec

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Phlip (Guest)
on 2009-03-09 09:12
(Received via mailing list)
Zach D. wrote:

 >> response.body.should be_xml_with do
 >>  form :action => '/users' do
 >>    fieldset do
 >>      legend "Personal Information"
 >>      label "First name"
 >>      input :type => 'text', :name => 'user[first_name]'
 >>    end
 >>  end
 >> end

 > I like this a lot.

Boom: http://gist.github.com/76136

   it 'should have a form with a fieldset' do
     render '/users/new'

     response.body.should be_html_with{
       form :action => '/users' do
         fieldset do
           legend 'Personal Information'
           label 'First name'
           input :type => 'text', :name => 'user[first_name]'
         end
       end
     }
   end

I think I never got around to writing that because I just always assumed
someone
already had. I have to watch that about myself!

Only one feature is missing: At fault time, the matcher naturally prints
out a
diagnostic containing two snips of HTML - the specification's reference,
and
your page's sample. (Both, of course, are restricted to the fault's
context -
not the whole page.) But...

The samples are not indented! The specification's reference is all run
together,
and your page's sample is (unfortunately!) exactly the way your View
system
generated it. I have a question out to Nokogiri about this...

--
   Phlip
   http://www.zeroplayer.com/
Phlip (Guest)
on 2009-03-10 18:27
(Received via mailing list)
> http://gist.github.com/76136

>     response.body.should be_html_with{
>       form :action => '/users' do
>         fieldset do
>           legend 'Personal Information'
>           label 'First name'
>           input :type => 'text', :name => 'user[first_name]'
>         end
>       end
>     }

Has anyone tried this? is it useful?
David C. (Guest)
on 2009-03-10 19:02
(Received via mailing list)
On Mon, Mar 9, 2009 at 6:20 PM, Phlip <removed_email_address@domain.invalid> 
wrote:
>>    }
>
> Has anyone tried this? is it useful?

I haven't tried it yet, but it does seem very useful. The project I'm
focused on right now is all json all the time, so I don't personally
have a real world case for this at the moment. Anybody doing an app w/
html views willing to try this out?
Pat N. (Guest)
on 2009-03-10 19:06
(Received via mailing list)
>
> Has anyone tried this? is it useful?
>

It looks interesting, though it could be confused for trying to exactly
mimic the actual markup, not just specify interesting parts.
David C. (Guest)
on 2009-03-10 20:09
(Received via mailing list)
On Mon, Mar 9, 2009 at 6:49 PM, Pat N. <removed_email_address@domain.invalid>
wrote:
>> Has anyone tried this? is it useful?
>
> It looks interesting, though it could be confused for trying to exactly
> mimic the actual markup, not just specify interesting parts.

What is the method name was be_html_including instead of be_html_with???
Phlip (Guest)
on 2009-03-10 21:19
(Received via mailing list)
Pat N. wrote:

>     Has anyone tried this? is it useful?

> It looks interesting, though it could be confused for trying to exactly
> mimic the actual markup, not just specify interesting parts.

It only specifies interesting parts. The gist writeup explained that,
for
example, it skipped over intermediate <ol><li> tags. And it naturally
skips
blanks in contents, and unlisted attributes.

It is exactly the same as the XPath version I posted before. That used
explicit
XPath queries to skip over uninteresting parts.

David C. wrote:

 > What is the method name was be_html_including instead of
be_html_with???

('be_html_including'.length - 'be_html_with'.length) / 17 =~ 30%.

So 30% fewer people would bother to type it!
Phlip (Guest)
on 2009-03-10 22:09
(Received via mailing list)
> I haven't tried it yet, but it does seem very useful. The project I'm
> focused on right now is all json all the time, so I don't personally
> have a real world case for this at the moment. Anybody doing an app w/
> html views willing to try this out?

I put it into my current project today (as a >cough< TestCase
assertion),
replaced a couple of xpath assertions with it, and showed it to my
colleagues.

I injected a fault, and show the diagnostic with the two batches of HTML
in it -
the reference and sample.

One of them was like, "Nice, but where's the syntax highlighting?"

This refers to eyes rolling --> @-/
Phlip (Guest)
on 2009-03-15 19:19
(Received via mailing list)
>>    response.body.should be_html_with{
>>      form :action => '/users' do
>>        fieldset do
>>          legend 'Personal Information'
>>          label 'First name'
>>          input :type => 'text', :name => 'user[first_name]'
>>        end
>>      end
>>    }

> Has anyone tried this? is it useful?

That assertion sucks! The actual sample HTML sez:

   <fieldset>
     <legend>Personal Information</legend>
     <ol>
       <li id="control_user_first_name">
         <label for="user_first_name">First name</label>
         <input type="text" name="user[first_name]" id="user_first_name"
/>
       </li>
     </ol>
   </fieldset>

The <legend> and <label> live in different containers, so they are not
peers of
each other. But the assertion specifies they are!

I think the assertion should fault until you specify at least this:

     response.body.should be_html_with{
       form :action => '/users' do
         fieldset do
           legend 'Personal Information'
           li do
             label 'First name'
             input :type => 'text', :name => 'user[first_name]'
           end
         end
       end
     }

Notice we have some conflicting requirements:

  - you can skip any tag
  - the reference should "look like" the sample (except it's in Ruby)

But you should not be able to skip a tag if its absence makes the
reference
"look different" from the sample. Hence, the test should require at
least one of
the <ol><li> tags that separate the two contexts...

(BTW the common verbiage for chemical tests of analytes here is "sample"
for the
substance submitted for analysis, and "reference" for the known sample
used to
calibrate the test.)

--
   Phlip
Zach D. (Guest)
on 2009-03-15 19:44
(Received via mailing list)
On Sun, Mar 15, 2009 at 1:05 PM, Phlip <removed_email_address@domain.invalid> 
wrote:
>> Has anyone tried this? is it useful?
>    </ol>
>  </fieldset>
>
> The <legend> and <label> live in different containers, so they are not peers
> of each other. But the assertion specifies they are!

I didn't have the expectation that they were peers of each other, just
that they both existed somewhere in a fieldset tag. Any helper or
matchers used for spec'ing views should be as liberal as possible
while still communicating enough about the semantics of the page for
the example to be meaningful.

I would not expect nor want a matcher to default to verifying direct
descendant, sibling, or adjacent nodes. Those are best verified by a
person looking at the page. What I do care about is that fields in are
within a fieldset (but not necessarily immediately next to each
other).

>          end
>        end
>      end
>    }
>

I don't like this, we are specifying the "li" but that provides no
meaning of the page, it's strictly markup for presentation.

> the substance submitted for analysis, and "reference" for the known sample
> used to calibrate the test.)
>
> --
>  Phlip
>
> _______________________________________________
> rspec-users mailing list
> removed_email_address@domain.invalid
> http://rubyforge.org/mailman/listinfo/rspec-users
>



--
Zach D.
http://www.continuousthinking.com
http://www.mutuallyhuman.com
Phlip (Guest)
on 2009-03-15 20:58
(Received via mailing list)
Zach D. wrote:

> other).
However, I constantly must write extra test code just to check things
are in the
right order. Specifically, I could not use my original assert_xhtml to
replace
tests that checked some <option> values appeared in collating order.
(Yes, tests
on the model also checked those fields appeared in collating order, AND
tests on
the controller checked thru the "assigns" that those fields were in
collating
order...)

I am not going to target strict relationships, just the general order.
But I
have to draw the line somewhere!
Pat M. (Guest)
on 2009-03-15 22:18
(Received via mailing list)
On Mar 15, 2009, at 10:33 AM, Zach D. wrote:

>>
>> id="user_first_name" />
> matchers used for spec'ing views should be as liberal as possible
> while still communicating enough about the semantics of the page for
> the example to be meaningful.
>
> I would not expect nor want a matcher to default to verifying direct
> descendant, sibling, or adjacent nodes. Those are best verified by a
> person looking at the page. What I do care about is that fields in are
> within a fieldset (but not necessarily immediately next to each
> other).

Both of those points make sense to me.  What about


  response.body.should be_html_with{
     form :action => '/users' do
       fieldset do
         legend 'Personal Information'

         anything do
           label 'First name'
           input :type => 'text', :name => 'user[first_name]'
  end
       end
     end
   }

I dunno.  Zach's original attempt hardly "sucks".  But maybe you want
to make the structure a bit more explicit?  Personally I think that it
becomes too coupled to the HTML, and "anything {}" is added noise, but
maybe that gets you moving in the right direction.

Pat
Phlip (Guest)
on 2009-03-16 01:44
(Received via mailing list)
Pat M. wrote:

> I dunno.  Zach's original attempt hardly "sucks".

That was David C.'s attempt - Zach seconded it. But I was
replying to myself.

More important, the tie-breaker here is very simple:

     When the assertion fails, can it
     tell you exactly how to fix things?

That means if you must make the assertion less strict, you should get a
clue
_how_ to make it less strict!

> maybe that gets you moving in the right direction.

Don't make me tell you under what circumstances I learned graph theory.
(-:

--
   Phlip
This topic is locked and can not be replied to.