BasicObject
Selects content from the RJS response.
With no arguments, asserts that one or more elements are updated or inserted by RJS statements.
Use the id argument to narrow down the assertion to only statements that update or insert an element with that identifier.
Use the first argument to narrow down assertions to only statements of that type. Possible values are :replace, :replace_html, :show, :hide, :toggle, :remove</tta>, <tt>:insert_html and :redirect.
Use the argument :insert followed by an insertion position to narrow down the assertion to only statements that insert elements in that position. Possible values are :top, :bottom, :before and :after.
Use the argument :redirect followed by a path to check that an statement which redirects to the specified path is generated.
Using the :remove statement, you will be able to pass a block, but it will be ignored as there is no HTML passed for this statement.
Without a block, assert_select_rjs merely asserts that the response contains one or more RJS statements that replace or update content.
With a block, assert_select_rjs also selects all elements used in these statements and passes them to the block. Nested assertions are supported.
Calling assert_select_rjs with no arguments and using nested asserts asserts that the HTML content is returned by one or more RJS statements. Using assert_select directly makes the same assertion on the content, but without distinguishing whether the content is returned in an HTML or JavaScript.
# Replacing the element foo. # page.replace 'foo', ... assert_select_rjs :replace, "foo" # Replacing with the chained RJS proxy. # page[:foo].replace ... assert_select_rjs :chained_replace, 'foo' # Inserting into the element bar, top position. assert_select_rjs :insert, :top, "bar" # Remove the element bar assert_select_rjs :remove, "bar" # Changing the element foo, with an image. assert_select_rjs "foo" do assert_select "img[src=/images/logo.gif"" end # RJS inserts or updates a list with four items. assert_select_rjs do assert_select "ol>li", 4 end # The same, but shorter. assert_select "ol>li", 4 # Checking for a redirect. assert_select_rjs :redirect, root_path
# File lib/prototype-rails/selector_assertions.rb, line 84 def assert_select_rjs(*args, &block) rjs_type = args.first.is_a?(Symbol) ? args.shift : nil id = args.first.is_a?(String) ? args.shift : nil # If the first argument is a symbol, it's the type of RJS statement we're looking # for (update, replace, insertion, etc). Otherwise, we're looking for just about # any RJS statement. if rjs_type if rjs_type == :insert position = args.shift id = args.shift insertion = "insert_#{position}".to_sym raise ArgumentError, "Unknown RJS insertion type #{position}" unless RJS_STATEMENTS[insertion] statement = "(#{RJS_STATEMENTS[insertion]})" else raise ArgumentError, "Unknown RJS statement type #{rjs_type}" unless RJS_STATEMENTS[rjs_type] statement = "(#{RJS_STATEMENTS[rjs_type]})" end else statement = "#{RJS_STATEMENTS[:any]}" end # Next argument we're looking for is the element identifier. If missing, we pick # any element, otherwise we replace it in the statement. pattern = Regexp.new( id ? statement.gsub(RJS_ANY_ID, "\"#{id}\"") : statement ) # Duplicate the body since the next step involves destroying it. matches = nil case rjs_type when :remove, :show, :hide, :toggle matches = @response.body.match(pattern) else @response.body.gsub(pattern) do |match| html = unescape_rjs(match) matches ||= [] matches.concat HTML::Document.new(html).root.children.select { |n| n.tag? } "" end end if matches assert_block("") { true } # to count the assertion if block_given? && !([:remove, :show, :hide, :toggle].include? rjs_type) begin @selected ||= nil in_scope, @selected = @selected, matches yield matches ensure @selected = in_scope end end matches else # RJS statement not found. case rjs_type when :remove, :show, :hide, :toggle flunk_message = "No RJS statement that #{rjs_type.to_s}s '#{id}' was rendered." else flunk_message = "No RJS statement that replaces or inserts HTML content." end flunk args.shift || flunk_message end end
link_to_function("Show me more", nil, :id => "more_link") do |page|
page[:details].visual_effect :toggle_blind page[:more_link].replace_html "Show me less"
end
Produces: <a href="#" id="more_link" onclick="try { $("details").visualEffect("toggle_blind"); $("more_link").update("Show me less"); } catch (e) { alert('RJS error:\n\n' + e.toString()); alert('$(\"details\").visualEffect(\"toggle_blind\"); \n$(\"more_link\").update(\"Show me less\");'); throw e }; return false;">Show me more</a>
# File lib/prototype-rails/javascript_helper.rb, line 56 def link_to_function(name, *args, &block) html_options = args.extract_options!.symbolize_keys function = block_given? ? update_page(&block) : args[0] || '' onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;" href = html_options[:href] || '#' content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick)) end
# File lib/prototype-rails/rendering.rb, line 4 def render_with_update(options = {}, locals = {}, &block) if options == :update update_page(&block) else render_without_update(options, locals, &block) end end
assert_select and css_select call this to obtain the content in the HTML page, or from all the RJS statements, depending on the type of response.
# File lib/prototype-rails/selector_assertions.rb, line 174 def response_from_page_with_rjs content_type = @response.content_type if content_type && Mime::JS =~ content_type body = @response.body.dup root = HTML::Node.new(nil) while true next if body.sub!(RJS_STATEMENTS[:any]) do |match| html = unescape_rjs(match) matches = HTML::Document.new(html).root.children.select { |n| n.tag? } root.children.concat matches "" end break end root else response_from_page_without_rjs end end
Unescapes a RJS string.
# File lib/prototype-rails/selector_assertions.rb, line 199 def unescape_rjs(rjs_string) # RJS encodes double quotes and line breaks. unescaped= rjs_string.gsub('\"', '"') unescaped.gsub!(/\\\//, '/') unescaped.gsub!('\n', "\n") unescaped.gsub!('\076', '>') unescaped.gsub!('\074', '<') # RJS encodes non-ascii characters. unescaped.gsub!(RJS_PATTERN_UNICODE_ESCAPED_CHAR) {|u| [$1.hex].pack('U*')} unescaped end
Generated with the Darkfish Rdoc Generator 2.