Use classes instead of DSL for matchers

This commit is contained in:
Jonas Nicklas 2011-02-06 14:36:42 +01:00
parent 50775ab787
commit d03fba859b
1 changed files with 45 additions and 35 deletions

View File

@ -1,45 +1,55 @@
module Capybara
module RSpecMatchers
extend ::RSpec::Matchers::DSL
class HaveSelector
def initialize(*args)
@args = args
end
%w[css xpath selector].each do |type|
matcher "have_#{type}" do |*args|
match_for_should do |actual|
wrap(actual).send("has_#{type}?", *args)
end
def matches?(actual)
@actual = wrap(actual)
@actual.has_selector?(*@args)
end
match_for_should_not do |actual|
wrap(actual).send("has_no_#{type}?", *args)
end
def does_not_match?(actual)
@actual = wrap(actual)
@actual.has_no_selector?(*@args)
end
failure_message_for_should do |actual|
if normalized[:selector].failure_message
normalized[:selector].failure_message.call(wrap(actual))
else
"expected #{normalized[:selector].name} #{normalized[:locator].inspect} to return something from:\n#{actual.inspect}"
end
end
failure_message_for_should_not do |actual|
"expected #{normalized[:selector].name} #{normalized[:locator].inspect} not to return anything from:\n#{actual.inspect}"
end
define_method :wrap do |actual|
if actual.respond_to?("has_#{type}?")
actual
else
Capybara.string(actual.to_s)
end
end
define_method :normalized do
@normalized ||= if type == "selector"
Capybara::Selector.normalize(*args)
else
Capybara::Selector.normalize(type.to_sym, *args)
end
def failure_message_for_should
if normalized[:selector].failure_message
normalized[:selector].failure_message.call(@actual)
else
"expected #{normalized[:selector].name} #{normalized[:locator].inspect} to return something"
end
end
def failure_message_for_should_not
"expected #{normalized[:selector].name} #{normalized[:locator].inspect} not to return anything"
end
def wrap(actual)
if actual.respond_to?("has_selector?")
actual
else
Capybara.string(actual.to_s)
end
end
def normalized
@normalized ||= Capybara::Selector.normalize(*@args)
end
end
def have_selector(*args)
HaveSelector.new(*args)
end
def have_xpath(*args)
HaveSelector.new(:xpath, *args)
end
def have_css(*args)
HaveSelector.new(:css, *args)
end
end
end