Assert2/xhtml specifies your HTML by example

Rubies:

assert_xhtml now works with RSpec. (Call it “.should be_html_with{}” !)

This is its Rails functional test aspect:

 get :edit_user, :id => users(:Moses).id
 scope = self

 assert_xhtml do
   form :action => '/users' do
     fieldset do
       legend 'Personal Information'
       label 'First name'
       input :type => 'text',
             :name => 'user[first_name]'
             :value => scope.users(:Moses).first_name
     end
   end
 end

The assertion tests your form “by example”. Your page must contain a
form with
the given action, and it must contain at least the listed elements,
attributes,
and text. Anything you don’t care about - anything your designers might
change -
you simply leave out of the example.

(The example is actually Nokogiri::HTML::Builder notation, so anything
Nokogiri
can do, the assertion can do. But that’s why we needed that ‘scope’
variable, as
a kind of “messenger rope”, to call your test-side methods inside the
block.
Otherwise, Nokogiri would dutifully convert them into HTML!)

Here’s a similar test, in RSpec:

it ‘should have a cute form’ do
render ‘/users/new’

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

end

Oh, except it has a bug in it! Here’s the diagnostic:

‘/users/new should have a cute form’ FAILED

Could not find this reference…

Personal Information First nome

…in these sample(s)…

Personal Information
  1. First name

Notice, as usual, the specification diagnostic only contained the start
of the
match. The example with worked.

That’s all there is to it. Write anything you like inside the block, and
if the
assertion can’t find it, it will explain why it can’t. Install the gem
like this:

gem install nokogiri assert2 # make sure the later is 0.3.9!

Then use require ‘assert2/xhtml’, in either the test/unit or RSpec
environments.

This project is wide-open for suggestions - with < 200 lines of code
there’s
plenty of room for more features!