diff options
Diffstat (limited to 'actionpack/lib')
-rw-r--r-- | actionpack/lib/action_dispatch/testing/assertions/selector.rb | 98 |
1 files changed, 39 insertions, 59 deletions
diff --git a/actionpack/lib/action_dispatch/testing/assertions/selector.rb b/actionpack/lib/action_dispatch/testing/assertions/selector.rb index 7092b17042..3c19b23fa6 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/selector.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/selector.rb @@ -160,20 +160,12 @@ module ActionDispatch def assert_select(*args, &block) @selected ||= nil - parser = HTMLSelector.new(@selected, reponse_from_page, args) + filter = ArgumentFilter.new(@selected, response_from_page, args) - # Start with optional element followed by mandatory selector. - root = parser.root - - # First or second argument is the selector - selector = parser.css_selector - - # Next argument is used for equality tests. - equals = parser.equals - - # Last argument is the message we use if the assertion fails. - message = parser.message - #- message = "No match made with selector #{selector.inspect}" unless message + root = filter.root + selector = filter.css_selector + equals = filter.comparisons + message = filter.message matches = root.css(selector) # If text/html, narrow down to those elements that match it. @@ -348,22 +340,31 @@ module ActionDispatch @html_document.root end - class Selector #:nodoc: - attr_accessor :root, :css_selector + class ArgumentFilter #:nodoc: + attr_accessor :root, :css_selector, :comparisons, :message def initialize(selected, page, *args) - raise ArgumentError, "ArgumentsParser expects a block for parsing a nested call's arguments" unless block_given? - @selected = selected - @page = page + @selected, @page = selected, page + + # Start with optional element followed by mandatory selector. + @root = determine_root_from(args.shift) + + # First or second argument is the selector + selector = @css_selector_is_second_argument ? args.shift : args.first + unless selector.is_a? String + raise ArgumentError, "Expecting a selector as the first argument" + end + @css_selector = selector - @args = args + # Next argument is used for equality tests. + @comparisons = comparisons_from(args.shift) - # see +determine_root_from+ - @css_selector_is_second_argument = false - @root = determine_root_from(@args.shift) + # Last argument is the message we use if the assertion fails. + @message = args.shift - arg = @css_selector_is_second_argument ? @args.shift : @args.first - @css_selector = css_selector(arg) + if args.shift + raise ArgumentError, "Not expecting that last argument, you either have too many arguments, or they're the wrong type" + end end def determine_root_from(root_or_selector) @@ -372,64 +373,43 @@ module ActionDispatch elsif root_or_selector.is_a?(Nokogiri::XML::Node) # First argument is a node (tag or text, but also HTML root), # so we know what we're selecting from, - # we also know that the second argument is the selector @css_selector_is_second_argument = true root_or_selector elsif @selected - # root_or_selector is a selector since the first call failed + # nested call - wrap in document fragment Loofah.fragment('').tap { |f| f.add_child @selected } else @page end end - def css_selector_from(arg) - unless arg.is_a? String - raise ArgumentError, "Expecting a selector as the first argument" - end - arg - end - end - - class HTMLSelector < Selector - attr_accessor :equals, :message - def initialize(*) - super - @equals = assign_equals_from(@args.shift) - @message = @args.shift - - if @args.shift - raise ArgumentError, "Not expecting that last argument, you either have too many arguments, or they're the wrong type" - end - end - - def assign_equals_from(comparator) - equals = {} + def comparisons_from(comparator) + comparisons = {} case comparator when Hash - equals = comparator + comparisons = comparator when String, Regexp - equals[:text] = comparator + comparisons[:text] = comparator when Integer - equals[:count] = comparator + comparisons[:count] = comparator when Range - equals[:minimum] = comparator.begin - equals[:maximum] = comparator.end + comparisons[:minimum] = comparator.begin + comparisons[:maximum] = comparator.end when FalseClass - equals[:count] = 0 + comparisons[:count] = 0 when NilClass, TrueClass - equals[:minimum] = 1 + comparisons[:minimum] = 1 else raise ArgumentError, "I don't understand what you're trying to match" end # By default we're looking for at least one match. - if equals[:count] - equals[:minimum] = equals[:maximum] = equals[:count] + if comparisons[:count] + comparisons[:minimum] = comparisons[:maximum] = comparisons[:count] else - equals[:minimum] ||= 1 + comparisons[:minimum] ||= 1 end - equals + comparisons end end end |