class RSpec::Matchers::NokogiriMatcher
@private
@api
def classes_to_selector(classes)
def classes_to_selector(classes) case classes when Array classes.join('.') when String classes.gsub(/\s+/, '.') end end
def count_right?
def count_right? case @options[:count] when Integer ((@negative_failure_message=RIGHT_COUNT_MSG % [@document,@count,@tag]) && @count == @options[:count]) || (@failure_message=WRONG_COUNT_MSG % [@document,@options[:count],@tag,@count]; false) when Range ((@negative_failure_message=RIGHT_BETWEEN_COUNT_MSG % [@document,@options[:count].min,@options[:count].max,@tag,@count]) && @options[:count].member?(@count)) || (@failure_message=BETWEEN_COUNT_MSG % [@document,@options[:count].min,@options[:count].max,@tag,@count]; false) when nil if @options[:maximum] ((@negative_failure_message=RIGHT_AT_MOST_MSG % [@document,@options[:maximum],@tag,@count]) && @count <= @options[:maximum]) || (@failure_message=AT_MOST_MSG % [@document,@options[:maximum],@tag,@count]; false) elsif @options[:minimum] ((@negative_failure_message=RIGHT_AT_LEAST_MSG % [@document,@options[:minimum],@tag,@count]) && @count >= @options[:minimum]) || (@failure_message=AT_LEAST_MSG % [@document,@options[:minimum],@tag,@count]; false) else true end end end
def description
def description # TODO should it be more complicated? if @options.has_key?(:count) COUNT_DESC % [@options[:count],@tag] else TAG_FOUND_DESC % @tag end end
def initialize tag, options={}, &block
def initialize tag, options={}, &block @tag, @options, @block = tag.to_s, options, block if with_attrs = @options.delete(:with) if classes = with_attrs.delete(:class) @tag << '.' + classes_to_selector(classes) end selector = with_attrs.inject('') do |html_attrs_string, (k, v)| html_attrs_string << "[#{k}='#{v}']" html_attrs_string end @tag << selector end if without_attrs = @options.delete(:without) if classes = without_attrs.delete(:class) @tag << ":not(.#{classes_to_selector(classes)})" end end validate_options! end
def matches? document, &block
def matches? document, &block @block = block if block document = document.html if defined?(Capybara) && document.is_a?(Capybara::Session) case document when String @parent_scope = @current_scope = Nokogiri::HTML(document).css(@tag) @document = document else @parent_scope = document.current_scope @current_scope = document.parent_scope.css(@tag) @document = @parent_scope.to_html end if tag_presents? and text_right? and count_right? @current_scope = @parent_scope @block.call if @block true else false end end
def tag_presents?
def tag_presents? if @current_scope.first @count = @current_scope.count @negative_failure_message = TAG_FOUND_MSG % [@document, @tag, @count] true else @failure_message = TAG_NOT_FOUND_MSG % [@document, @tag] false end end
def text_right?
def text_right? return true unless @options[:text] case text=@options[:text] when Regexp new_scope = @current_scope.css(':regexp()',NokogiriRegexpHelper.new(text)) unless new_scope.empty? @count = new_scope.count @negative_failure_message = REGEXP_FOUND_MSG % [text.inspect,@tag,@document] true else @failure_message = REGEXP_NOT_FOUND_MSG % [text.inspect,@tag,@document] false end else new_scope = @current_scope.css(':content()',NokogiriTextHelper.new(text)) unless new_scope.empty? @count = new_scope.count @negative_failure_message = TEXT_FOUND_MSG % [text,@tag,@document] true else @failure_message = TEXT_NOT_FOUND_MSG % [text,@tag,@document] false end end end
def validate_options!
def validate_options! raise 'wrong :count specified' unless [Range, NilClass].include?(@options[:count].class) or @options[:count].is_a?(Integer) [:min, :minimum, :max, :maximum].each do |key| raise WRONG_COUNT_ERROR_MSG if @options.has_key?(key) and @options.has_key?(:count) end begin raise MIN_MAX_ERROR_MSG if @options[:minimum] > @options[:maximum] rescue NoMethodError # nil > 4 rescue ArgumentError # 2 < nil end begin begin raise BAD_RANGE_ERROR_MSG % [@options[:count].to_s] if @options[:count] && @options[:count].is_a?(Range) && (@options[:count].min.nil? or @options[:count].min < 0) rescue ArgumentError, "comparison of String with" # if @options[:count] == 'a'..'z' raise BAD_RANGE_ERROR_MSG % [@options[:count].to_s] end rescue TypeError # fix for 1.8.7 for 'rescue ArgumentError, "comparison of String with"' stroke raise BAD_RANGE_ERROR_MSG % [@options[:count].to_s] end @options[:minimum] ||= @options.delete(:min) @options[:maximum] ||= @options.delete(:max) @options[:text] = @options[:text].to_s if @options.has_key?(:text) && !@options[:text].is_a?(Regexp) end