Should have_tag outside Rails

Hi

Google has not helped me here. I’m looking for a way to use the
have_tag
assert_select wrapper outside RSpec on Rails (but in a Rails project) so
I
can use it to check text strings.

Has anyone managed this?

Thanks
Ashley

On 17/03/2008, Ashley M. [email protected] wrote:

Has anyone managed this?

Cracked it. Really ugly, but my stories/helper.rb looks like this

ENV[“RAILS_ENV”] = “test_integration”
require File.expand_path(File.dirname(FILE) +
“/…/config/environment”)

We don’t want to use the story adapter because it interferes

starts creating transactions that stop multi-process testing (ie

story runner and mongrel) seeing each other’s data

#require ‘spec/rails/story_adapter’

Hack to let us use should have_tag without loading rspec_on_rails

module ActionController
class TestResponse

end

end

include Test::Unit::Assertions

require ‘action_controller/assertions’
include ActionController::Assertions

require ‘spec/rails/matchers/assert_select’
include Spec::Rails::Matchers

It’s just waiting to break, I know it.

Actually having done this and discussed assert_select with my team, I
think
I’ll write a have_tag matcher using Hpricot. That way I’m not putting
the
quality of our application in the hands of Rails code.

I thought I’d post this anyway for reference.

Ashley

On Mon, Mar 17, 2008 at 10:44 AM, Ashley M.
[email protected] wrote:

starts creating transactions that stop multi-process testing (ie

end

Actually having done this and discussed assert_select with my team, I think
I’ll write a have_tag matcher using Hpricot. That way I’m not putting the
quality of our application in the hands of Rails code.

I thought I’d post this anyway for reference.

Ashley

We discussed this in a ticket on lighthouse, and I ended up writing a
workalike that’s sitting atop hpricot. It’s not quite identical, but
generally close enough and so far does everything I’ve needed:

Patches and/or suggestions welcome if you need anything else out of it

Kyle

On 17 Mar 2008, at 18:41, Kyle H. wrote:

We discussed this in a ticket on lighthouse, and I ended up writing a
workalike that’s sitting atop hpricot. It’s not quite identical, but
generally close enough and so far does everything I’ve needed:

GitHub - pd/rspec_hpricot_matchers: have_tag() without Rails' assert_select()

Patches and/or suggestions welcome if you need anything else out of it

Kyle

Hi Kyle

That’s brilliant! I looked for something but couldn’t find anything.
I did some work on it this afternoon and got as far as

@elements.should have_tag(“#selector”, :count => 2)

but didn’t manage inner text comparisons or nested matchers.

I’m unfamiliar with git - what’s the best way to include that code in
a Rails app stored in SVN? RTFM link to the git docs or similar
welcome…

When I’ve finished this contract I hope to spend some time working on
open source code for story/runner selenium integration, if so I will
definitely put anything relevant back into that matcher.

Ashley

http://git.or.cz/course/svn.html

and also search google for “git for svn users”

Zach

On Mon, Mar 17, 2008 at 5:22 PM, Ashley M.

On 17/03/2008, Zach D. [email protected] wrote:

http://git.or.cz/course/svn.html

and also search google for “git for svn users”

Zach

Ta - I ended up doing a git clone into our SVN repo. Not sure if that’s
a
good idea but seems to work…

Ashley

On Tue, Mar 18, 2008 at 9:04 AM, Ashley M.
[email protected] wrote:

Kyle

Hi Kyle

Really impressed with that! Seems to be working ok in our app, only
starting to use it though. Here’s how I got it working in Rails:

I personally just toss things into vendor/gems, and add something
along these lines to environment.rb:

  config.load_paths += Dir[File.join('vendor', 'gems', '*',

‘lib’)].map do |libdir|
File.expand_path(libdir)
end

This’ll let it be loaded as a gem and you can put this in spec_helper:

require ‘rspec_hpricot_matchers’
Spec::Runner.configure do |config|
config.include(RspecHpricotMatchers)
end

I really like your undef magic for disabling the rspec_on_rails
matchers; hadn’t thought of doing that.

One problem you will run into, I’m sure, is nested expectation failure
messages:

body.should have_tag(‘ul’) do |ul|
ul.should have_tag(‘li’)
end

Fails with “expected body to have tag ‘ul’”, even if it’s the inner
‘li’ that was missing. I haven’t come up with a good way to fix this,
but it’s very annoying!

Kyle

On 18 Mar 2008, at 19:38, Kyle H. wrote:

end
Ah that’s neater than my way. Forgot about the Rails load path.
Don’t use rails regularly enough to memorise all these tricks…

Fails with “expected body to have tag ‘ul’”, even if it’s the inner
‘li’ that was missing. I haven’t come up with a good way to fix this,
but it’s very annoying!

Yep that one caught me! I’d like a neater solution too, not sure how
though. Just had a look at the code and it doesn’t look easy.

Because RSpec raises exceptions on your behalf when a match fails, you
only get chance to set the message and not tag any extra information
on there. Short of a really ugly hack, the only way round this I can
see would be extend RSpec’s ExpectationMatcherHandler and Expectation
to support retrieving another object from the matcher to go with
failure_message (maybe failure_data). Then you could collect those as
the exceptions bubble up to the top level matcher.

Or for a kludge you could subclass HpricotMatcherString < String,
attach the failures to it and pass instances of that up as failure
messages instead of plain strings. Nasty nasty nasty, but it would
give you everthing you need to generate a detailed message at the top.

Ashley

On 17/03/2008, Kyle H. [email protected] wrote:

We discussed this in a ticket on lighthouse, and I ended up writing a
workalike that’s sitting atop hpricot. It’s not quite identical, but
generally close enough and so far does everything I’ve needed:

GitHub - pd/rspec_hpricot_matchers: have_tag() without Rails' assert_select()

Patches and/or suggestions welcome if you need anything else out of it

Kyle

Hi Kyle

Really impressed with that! Seems to be working ok in our app, only
starting to use it though. Here’s how I got it working in Rails:

git clone into RAILS_ROOT/lib

However you are using a require that depends on
rspec_hpricot_matchers/lib
being in the load path, so for now I added this to spec_helper:

rspec_hpricot_matcher_lib_path = File.expand_path(
File.join(RAILS_ROOT, “/lib/rspec_hpricot_matchers/lib”))
$:.unshift(rspec_hpricot_matcher_lib_path) unless
$:.include?(rspec_hpricot_matcher_lib_path)

I could have changed the line:
require ‘rspec_hpricot_matchers/have_tag’

to something like (untested):
File.expand_path(
File.join(File.dirname(FILE), “/rspec_hpricot_matchers/lib”))

so it would work from any location - but I wasn’t sure how to get the
patch
back from git.

I also found it’s pretty easy to replace the RSpec assert_select
wrapper:
module Spec::Rails
module Matchers
undef_method :have_tag, :with_tag, :without_tag, :with_encoded
end

module Example
  class RailsExampleGroup
    include RspecHpricotMatchers
  end
end

end

Already rolling this out across the developers here, everyone seems
pretty
positive about it.

Any chance this will make it into RSpec, David?

Ashley