Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #8428 (new enhancement)

Opened 2 years ago

Last modified 2 years ago

[PATCH] Make multiple assert_select calls sensitive to order

Reported by: wincent Assigned to: core
Priority: normal Milestone: 2.x
Component: ActionPack Version: edge
Severity: normal Keywords:
Cc:

Description

I'm currently using RSpec to write view specs using have_tag and with_tag; these methods are really just wrappers for Rails' assert_select method, so I am filing this request here.

Specifically, assert_select allows me to test for the presence of multiple tags, but it doesn't allow me to test that the tags appear in a specific order.

Take the following RSpec example, for instance, which aims to test that alternating (odd, even, odd, even) rows are rendered to the view:

it 'should display the login names, display names and email address in alternating rows' do

response.should have_tag('div.odd>div') do

with_tag('div', 'example login name 1') with_tag('div', 'example display name 1') with_tag('div', 'example email address 1')

end response.should have_tag('div.even>div') do

with_tag('div', 'example login name 2') with_tag('div', 'example display name 2') with_tag('div', 'example email address 2')

end

end

I can change the order of the have_tag blocks and I can also change the order of the with_tag calls within each block without breaking the specs. Or to put it alternatively, my view can render the "odd" and "even" divs in a different order, or the nested divs inside each, without breaking the specs.

In many cases, this might not matter. But what if I want to test for alternating divs (odd, even, odd even)? I can add multiple have_tag assertions but their order won't be considered, so I'm not really testing the alternation, only for existence.

I originally posted a question about this to the RSpec users mailing list:

http://rubyforge.org/pipermail/rspec-users/2007-May/001639.html

I was advised that assert_select would need to be extended to implement order-sensitivity, hence this enhancement request.

Attachments

rails_1_2_3_patch.txt (1.0 kB) - added by wincent on 05/24/07 13:36:47.
patch against 1.2.3

Change History

05/22/07 02:50:22 changed by kevinclark

Want to give it a shot? Empty enhancement requests aren't taken care of as often as you'd hope, and I'd hate to see this collect dust.

05/24/07 13:36:23 changed by wincent

Ok, there has been some further discussion about this on the RSpec users mailing list (link already posted above).

I've come up with a patch against actionpack/lib/action_controller/assertions/selector_assertions.rb that implements order sensitivity. This patch is against the current stable release (1.2.3) but I imagine it could be ported to the trunk/edge fairly easily. Will attach the patch in a moment.

I'm doing all my testing using RSpec so I don't know how this interacts for people using Test::Unit. At least in the case of RSpec the "scope" for order sensitivity is a single example ("it") block. That is, all calls to "have_tag" and "with_tag" within a single example must appear in the correct order or an exception will be raised. As soon as you start a new example block things fall out of scope and the order comparison is conveniently reset.

The thrown exception will look something like this:

selector order mismatch ('<div class="label">Display name:</div>' at position 109 appears before '<div class="info">example login name 1</div>' at position 150)

Limitations/problems/issues to be resolved include:

- I'm not really familiar with the conventions used by Rails internally so I am not sure what type of exception should be thrown; for now I am just throwing a String

- The diagnostic info included in the exception string may be too long if one or both of the selectors are really long

- The behaviour is not optional and applies by default; although I want ordered behaviour by default I can imagine that others might not, so some means of making this optional would need to be implemented

- This will probably break a large number of specs/tests written without ordered behaviour in mind

05/24/07 13:36:47 changed by wincent

  • attachment rails_1_2_3_patch.txt added.

patch against 1.2.3

05/27/07 18:29:44 changed by josh

  • summary changed from Make multiple assert_select calls sensitive to order to [PATCH] Make multiple assert_select calls sensitive to order.