GitHub Sale: sign up for any paid plan this week and pay nothing until January 1, 2009!  [ hide ]

public
Fork of pd/rspec_hpricot_matchers
Description: have_tag() without Rails' assert_select()
Clone URL: git://github.com/kamal/rspec_hpricot_matchers.git
name age message
file .gitignore Tue Mar 04 19:26:22 -0800 2008 ignore pkg dir [pd]
file MIT-LICENSE Tue Mar 04 16:48:48 -0800 2008 MIT license [pd]
file README Tue Mar 04 17:27:48 -0800 2008 demonstrate that this passes rspec LH ticket #316 [pd]
file Rakefile Tue Mar 04 19:26:17 -0800 2008 spec and gem rake tasks [pd]
directory lib/ Mon Mar 10 17:47:05 -0700 2008 support have_tag(".foo", :count => 0) [pd]
directory spec/ Mon Mar 10 17:47:05 -0700 2008 support have_tag(".foo", :count => 0) [pd]
README
= rspec_hpricot_matchers

An implementation of have_tag(), as in rspec_on_rails, but sitting atop
Hpricot rather than merely wrapping assert_select().


== Usage

As its first argument, have_tag() accepts any CSS or XPath selectors
which are supported by Hpricot.

    body.should have_tag('form[@action*=session]')
    body.should have_tag('ul > li + li')

Expectations can be placed upon the inner text of the matched element
by providing another argument, which should be either a String or a
Regexp:

    body.should have_tag('h1', 'Welcome')
    body.should have_tag('p', /a very important blurb/i)

Expectations can be placed upon the number of matched elements by
passing an options hash:

    body.should have_tag('abbr', :count => 1)   # exactly one
    body.should have_tag('dt',   :minimum => 4) # at least 4
    body.should have_tag('dd',   :maximum => 4) # at most 4
    body.should have_tag('a.outgoing', /rspec/i, :count => 2)

The :count key also accepts a Range, making the following equivalent:

    body.should have_tag('tr',   :count => 3..5)
    body.should have_tag('tr',   :minimum => 3,
                                 :maximum => 5)


The usage of with_tag(), however, is no longer supported. Instead, a
block passed to have_tag() will have each matched element successively
yielded to it. If none of the blocks return without raising an
ExpectationNotMetError, the outer have_tag() is treated as having failed:

    body.should have_tag('thead') do |thead|
      thead.should have_tag('th', :count => 5)
    end

This also allows arbitrary expectations to be applied from within
the block, such as:

    body.should have_tag('dl dd.sha1') do |dd|
      dd.inner_text.length.should == 40
    end


== Notes

Currently, this implementation does not support substitution values
as assert_select did (by way of HTML::Selector):

    # Not yet supported:
    body.should have_tag('li[class=?]', dom_class)
    body.should have_tag('tr.person#?', /^person-\d+$/)

I personally rarely use these, and Hpricot's advanced selectors make
them mostly useless, as far as I can tell, so I am unlikely to
implement them myself.

This have_tag() further differs from the assert_select-based
implementation in that the nested have_tag() calls must *all* pass
on a single selected element in order to be true. This was a source
of confusion in RSpec ticket #316. There is a spec covering this
case if you need an example.