Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
have_tag() without Rails' assert_select()
Ruby
Branch: master
Pull request Compare This branch is 1 commit ahead of nickh:master.

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib
spec
.gitignore
MIT-LICENSE
README.textile
Rakefile
VERSION
rspec_tag_matchers.gemspec

README.textile

RSPEC_TAG_MATCHER

Implementation of have_tag() RSpec matcher using Nokogiri.

Description

An implementation of rspec_on_rails’ have_tag() matcher which does not depend on Rails’ assert_select(). Using Nokogiri instead, the matcher is available to non-Rails projects, and enjoys the full flexibility of Nokogiri’s advanced and blazing fast CSS and XPath selector support.

Installation

Gem:

sudo gem install rspec_tag_matchers --source http://gemcutter.org

Dependencies:

  • rspec (stating the obvious)

Configuration

In spec_helper.rb:

  require 'rspec_tag_matchers'
  
  Spec::Runner.configure do |config|
    config.include(RspecTagMatchers)
  end

Usage

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

  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):

Note supported:

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

I (Kyle Hargraves, original author) 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.

Origin

This project was originally forked from:

http://github.com/pd/rspec_hpricot_matchers

License

Original work:

Released under the MIT license.
Copyright © 2008 Kyle Hargraves

Something went wrong with that request. Please try again.