RSpec Custom Matcher with Block
Hi,
I've been stumped about this for days now. I'm using RSpec for BDD, and tried creating a custom matcher to test for the existence of a form on a page.
The custom matcher is:
Code:
require 'webrat/core/matchers/have_selector'
module FormMatchers
class HaveAFormWithID
include Webrat::Matchers
def initialize id, &block
@id = id
@block = block
end
def matches? response, &block
@block ||= block
response.should have_selector('form#%s' % [@id]) do |form|
!@block or @block.call form
end
end
def description
"have a form with id #{@id}"
end
def failure_message
"expected to have a form with ID #{@id}"
end
def negative_failure_message
"expected not to have a form with ID #{@id}"
end
end
def have_a_form_with_id id, &block
HaveAFormWithID.new id, &block
end
end
An example of one of the examples using it:
Code:
it "should have a subject dropdown box" do
response.should have_a_contact_form do |form|
form.should have_selector('select', :id => 'subject')
end
end # it "should have a subject dropdown box"
That fails. However, if no block is passed, it passes, such as the following:
Code:
it "should show the contact form" do
response.should have_a_contact_form
end
Yes, I have a method have_a_contact_form that calls the have_a_form_with_id method.
Code:
def have_a_contact_form &block
have_a_form_with_id 'contact', &block
end
Anyway, when it fails, I get the error:
Code:
'/contact/index the contact form before it has been submitted should have a subject dropdown box' FAILED
expected following output to contain a <select id='subject'/> tag:
<form action="/contact.html" id="contact" method="post">
<div>
<label for="subject">Subject</label>
<select id="subject" name="subject"><option value=""></option>
<option value="feedback">Feedback</option>
<option value="questions">Questions</option>
<option value="suggestions">Suggestions</option>
<option value="other">Other</option></select>
</div>
</form>
As you can see, that selector clearly does exist on the page, so it confuses me why it is failing.
Thanks in advance for any help.
Brandon