This looks pretty cool. I wonder if you’d have any interest in making
this a bit more rspec-friendly? Something like an option to run it
like this:
Here’s the spec. The sauce is below my signature.
it ‘should have a user form with the first name’ do
render ‘/users/new’
response.body.should be_xml_with do
xpath :form, :action => ‘/users’ do
xpath :fieldset do
xpath :‘legend[ contains(., “Personal Information”) ]’ and
xpath :‘label[ contains(., “First name”) ]’ and
xpath :input, :type => ‘text’, :name => ‘user[first_name]’
end
end
end
end
Now, two issues. Firstly, what is the point of writing verbiage,
designed for
review by the customer team, if they should not be expected to
understand
hardcore engineering gibberish beginning with “body.should be_xml_with
do”? A
sentence that is only partly English does more harm than good!
Secondly, when an xpath() fails, it prepares an elaborate and detailed
analysis
of the entire situation, packs this into a flunk(), and raises it in a
Test::Unit::AssertionFailedError.
Then RSpec then throws all that stuff away, and provides an incorrect
stack
trace to an internal error. Switching my ‘user[first_name]’ to
‘user[first_nome]’ provides this:
NoMethodError in ‘/users/new should have xpathic tags’
You have a nil object when you didn’t expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.first
./spec/views/users/new.html.erb_spec.rb:50:
So if I were to rescue my own AssertionFailedError, and pack it into a
failure_message, wouldn’t that effort be redundant?
–
Phlip
require ‘assert2/xpath’
Spec::Runner.configure do |c|
c.include Test::Unit::Assertions
end # TODO blog this
class BeXmlWith
def initialize(scope, &block)
@scope, @block = scope, block
end
def matches?(stwing, &block)
waz_xdoc = @xdoc
@block = block if block
@scope.assert_xhtml stwing
return (block || @block || proc{}).call
ensure
@xdoc = waz_xdoc
end
def failure_message
"yack yack yack"
end
def negative_failure_message
"yack yack yack"
end
end
def be_xml_with(&block)
BeXmlWith.new(self, &block)
end