From: Phlip Date: 2009-03-26T21:51:48+09:00 Subject: [ANN] assert2-0.4.6 provides assert_xhtml, an alternative to assert_select Rubyists: Consider the following monstrosity, coded using assert_select: assert_select "div#logo_box img[src=/0000/0001/logo.gif][alt=My Company]" Now, behold it rewritten to use assert_xhtml: assert_xhtml do div.logo_box! do img :src => /logo.gif$/, :alt => 'My Company' end end That sample contains more Ruby; it's not just one big string. Still not convinced? Oh, I forgot the around the ! Try this: assert_xhtml do div.logo_box! do a :href => '/' do img :src => /logo.gif$/, :alt => 'My Company' end end end And we had an issue with the small logo sneaking into the logo_box once. Let's exclude it: assert_xhtml do div.logo_box do a :href => '/' do img :src => /logo.gif$/, :alt => 'My Company' end without!{ img :src => /mini_logo.gif/ } end end Imagine adding all that to assert_select - it would get much harder to read, and more complex. assert_xhtml uses Nokogiri::HTML::Builder notation, so anything it can build, you can query. Version 0.4.6 adds all the following features. To begin, enter: gem install nokogiri assert2 == require 'assert2/xhtml' == All assert{ 2.0 } dependencies are optional. If you have Nokogiri (>=1.2.2), you can test Rails views like this: user = users(:Moses) get :edit_user, :id => user.id assert_xhtml do form :action => '/users' do fieldset do legend 'Personal Information' label 'First name' input :type => 'text', :name => 'user[first_name]' :value => user.first_name end end end That's a Rails functional test on a form. The assertion expects the form to target the given action, and contain a fieldset, a legend, a label, and a populated text input field. The assertion forgives any other details, such as intervening structural tags, excess spaces, or extra attributes; and complains if any required detail is missing, out of order, or ill-formed. The DSL inside that block is Nokogiri::HTML::Builder notation. Generally speaking, anything Nokogiri can build, you can specify. === arguments === Call assert_xhtml(my_xml){} to interrogate your XML. When called without an argument, the method reads @response.body. === without! === Every assert* has a matching deny* method. assert_xhtml recognizes the special element without! as a request to fail if the given elements do indeed appear in your output: get :info, :record_id => record.id assert_xhtml do div :class => :content do without!{ div :class => :download } end end That assertion will fail if the outer
tag does not exist, or if any inner
does exist. The without! element respects your document layout. This assertion passes... assert_xhtml SAMPLE_LIST do ul{ li{ ul{ li 'Sales report' without!{ li 'All Sales report criteria' } } } } end ...even though the target document contains an
  • All Sales report criteria
  • :
    • model
      • Billings report
      • Sales report
      • Billings criteria
      • Common system
    • controller
      • All Sales report criteria
      • All Billings reports
    The two
  • elements appear in different
      lists, so the assertion does not associate them. The committee does not yet know what without!{ without!{} } does, so please do not rely on its current behavior, whatever that is! === escapes === Certain elements, such as