Skip to content

Instantly share code, notes, and snippets.

@yura
Created February 12, 2009 09:19
Show Gist options
  • Save yura/62562 to your computer and use it in GitHub Desktop.
Save yura/62562 to your computer and use it in GitHub Desktop.
rspec complex custom matchers
module CustomUiMatchers
class HaveForm
def initialize(action, scope, &block)
@action, @scope, @block = action, scope, block
end
def matches?(response, &block)
@block = block if block
response.should @scope.have_tag('form[action=?]', @action) do |form|
@block.call.matches?(form)
end
end
def failure_message
"expected response to contain a form with '#{@action}' action but it didn't"
end
def negative_failure_message
"expected response to not contain a form with '#{@action}' action but it did"
end
end
# :call-seq:
# response.should have_form(action)
# response.should_not have_form(action)
#
# Accepts form action value
#
# == Examples
#
# response.should have_form(users_path)
# or
# response.should have_form(users_path) do
# with_field_set 'Personal Information' do
# with_text_field 'First Name', 'user[first_name]'
# end
# end
def have_form(action, &block)
HaveForm.new(action, self, &block)
end
end
require File.dirname(__FILE__) + '/../../spec_helper'
describe "/users/new" do
def mock_user(stubs = {})
@mock_user ||= mock_model(User, stubs)
end
before do
assigns[:user] = mock_user(:new_record? => true)
end
it "should have form to create a new user" do
render '/users/new'
response.should have_form(users_path) do
with_field_set 'Personal Information' do
with_text_field 'wrong', 'wrong' # there is no such field on the form. but it passes
with_text_field 'First Name', 'user[first_name]'
end
end
end
end
module CustomUiMatchers
class WithFieldSet
def initialize(scope, legend = nil, &block)
@scope, @legend, @block = scope, legend, block
end
def matches?(form, &block)
@block = block if block
form.should @scope.have_tag('fieldset') do
@scope.with_tag('legend', @legend) if @legend
@scope.with_tag('ol') do |ol|
@block.call.matches?(ol)
end
end
end
def failure_message
"expected response to contain a fieldset but it didn't"
end
def negative_failure_message
"expected response to not contain a fieldset but it did"
end
end
def with_field_set(legend = nil, &block)
WithFieldSet.new(self, legend, &block)
end
end
module CustomUiMatchers
class WithInput
def initialize(label, param_name, type, scope)
@label, @param_name, @type, @scope = label, param_name, type, scope
end
def matches?(ol)
ol.should @scope.have_tag 'li' do
@scope.with_tag('label', @label)
@scope.with_tag("input[type=#{@type}][name=?]", @param_name)
end
end
def failure_message
"expected response to contain input[type=#{@type}][name=#{@param_name}] labelled '#{@label}' but it didn't"
end
def negative_failure_message
"expected response to not contain input[type=#{@type}][name=#{@param_name}] labelled '#{@label}' but it did"
end
end
def with_text_field(label, param_name)
WithInput.new(label, param_name, 'text', self)
end
def with_password_field(label, param_name)
WithInput.new(label, param_name, 'password', self)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment