Skip to content

Commit

Permalink
make :matches? slightly less hideously large
Browse files Browse the repository at this point in the history
  • Loading branch information
pd committed Mar 6, 2008
1 parent 5546245 commit cbc0bd5
Showing 1 changed file with 49 additions and 36 deletions.
85 changes: 49 additions & 36 deletions lib/rspec_hpricot_matchers/have_tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,52 +11,23 @@ def initialize(selector, inner_text_or_options, options, &block)
end
end

def matches?(actual)
def matches?(actual, &block)
@actual = actual
@hdoc = if Hpricot === @actual
@actual
elsif @actual.respond_to?(:body)
Hpricot(@actual.body)
else
Hpricot(@actual.to_s)
end
@hdoc = hdoc_for(@actual)

matched_elements = @hdoc.search(@selector)
return false if matched_elements.empty?

if @inner_text
matched_elements = matched_elements.select do |e|
case @inner_text
when Regexp
e.inner_text =~ @inner_text
else
e.inner_text == @inner_text
end
end
matched_elements = filter_on_inner_text(matched_elements)
end

if block_given?
matched_elements = matched_elements.select do |e|
begin
yield e
rescue Spec::Expectations::ExpectationNotMetError
false
else
true
end
end
if block
matched_elements = filter_on_nested_expectations(matched_elements, block)
end

@actual_count = matched_elements.length
if @options[:count]
return false unless @options[:count] === matched_elements.length
end
if @options[:minimum]
return false unless matched_elements.length >= @options[:minimum]
end
if @options[:maximum]
return false unless matched_elements.length <= @options[:maximum]
end
return false if not acceptable_count?(@actual_count)

!matched_elements.empty?
end
Expand All @@ -68,10 +39,52 @@ def failure_message

def negative_failure_message
explanation = @actual_count ? "but found #{@actual_count}" : "but did"
"did not expect\n#{@hdoc.to_s}\nto have #{failure_count_phrase} #{failure_selector_phrase}, #{explanation}"
"expected\n#{@hdoc.to_s}\nnot to have #{failure_count_phrase} #{failure_selector_phrase}, #{explanation}"
end

private
def hdoc_for(input)
if Hpricot === input
input
elsif input.respond_to?(:body)
Hpricot(input.body)
else
Hpricot(input.to_s)
end
end

def filter_on_inner_text(elements)
elements.select do |el|
next(el.inner_text =~ @inner_text) if @inner_text.is_a?(Regexp)
el.inner_text == @inner_text
end
end

def filter_on_nested_expectations(elements, block)
elements.select do |el|
begin
block.call(el)
rescue Spec::Expectations::ExpectationNotMetError
false
else
true
end
end
end

def acceptable_count?(actual_count)
if @options[:count]
return false unless @options[:count] === actual_count
end
if @options[:minimum]
return false unless actual_count >= @options[:minimum]
end
if @options[:maximum]
return false unless actual_count <= @options[:maximum]
end
true
end

def failure_count_phrase
if @options[:count]
"#{@options[:count]} elements matching"
Expand Down

0 comments on commit cbc0bd5

Please sign in to comment.