<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -396,54 +396,31 @@ module ActionController
       #   # The same, but shorter.
       #   assert_select &quot;ol&gt;li&quot;, 4
       def assert_select_rjs(*args, &amp;block)
-        rjs_type = nil
-        arg      = args.shift
+        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 arg.is_a?(Symbol)
-          rjs_type = arg
-
+        if rjs_type
           if rjs_type == :insert
-            arg = args.shift
-            position  = arg
-            insertion = &quot;insert_#{arg}&quot;.to_sym
-            raise ArgumentError, &quot;Unknown RJS insertion type #{arg}&quot; unless RJS_STATEMENTS[insertion]
+            position  = args.shift
+            insertion = &quot;insert_#{position}&quot;.to_sym
+            raise ArgumentError, &quot;Unknown RJS insertion type #{position}&quot; unless RJS_STATEMENTS[insertion]
             statement = &quot;(#{RJS_STATEMENTS[insertion]})&quot;
           else
             raise ArgumentError, &quot;Unknown RJS statement type #{rjs_type}&quot; unless RJS_STATEMENTS[rjs_type]
             statement = &quot;(#{RJS_STATEMENTS[rjs_type]})&quot;
           end
-          arg = args.shift
         else
           statement = &quot;#{RJS_STATEMENTS[:any]}&quot;
         end
-        position ||= Regexp.new(RJS_INSERTIONS.join('|'))
 
         # Next argument we're looking for is the element identifier. If missing, we pick
-        # any element.
-        if arg.is_a?(String)
-          id = Regexp.quote(arg)
-          arg = args.shift
-        else
-          id = &quot;[^\&quot;]*&quot;
-        end
-
-        pattern =
-          case rjs_type
-            when :chained_replace, :chained_replace_html
-              Regexp.new(&quot;\\$\\(\&quot;#{id}\&quot;\\)#{statement}\\(#{RJS_PATTERN_HTML}\\)&quot;, Regexp::MULTILINE)
-            when :remove, :show, :hide, :toggle
-              Regexp.new(&quot;#{statement}\\(\&quot;#{id}\&quot;\\)&quot;)
-            when :replace, :replace_html
-              Regexp.new(&quot;#{statement}\\(\&quot;#{id}\&quot;, #{RJS_PATTERN_HTML}\\)&quot;)
-            when :insert, :insert_html
-              Regexp.new(&quot;Element.insert\\(\\\&quot;#{id}\\\&quot;, \\{ #{position}: #{RJS_PATTERN_HTML} \\}\\);&quot;)
-             else
-              Regexp.union(Regexp.new(&quot;#{statement}\\(\&quot;#{id}\&quot;, #{RJS_PATTERN_HTML}\\)&quot;),
-                Regexp.new(&quot;Element.insert\\(\\\&quot;#{id}\\\&quot;, \\{ #{position}: #{RJS_PATTERN_HTML} \\}\\);&quot;))
-           end
+        # any element, otherwise we replace it in the statement.
+        pattern = Regexp.new(
+          id ? statement.gsub(RJS_ANY_ID, &quot;\&quot;#{id}\&quot;&quot;) : statement
+        )
 
         # Duplicate the body since the next step involves destroying it.
         matches = nil
@@ -588,26 +565,23 @@ module ActionController
 
       protected
         unless const_defined?(:RJS_STATEMENTS)
-          RJS_STATEMENTS = {
-            :replace              =&gt; /Element\.replace/,
-            :replace_html         =&gt; /Element\.update/,
-            :chained_replace      =&gt; /\.replace/,
-            :chained_replace_html =&gt; /\.update/,
-            :remove               =&gt; /Element\.remove/,
-            :show                 =&gt; /Element\.show/,
-            :hide                 =&gt; /Element\.hide/,
-            :toggle                 =&gt; /Element\.toggle/
+          RJS_PATTERN_HTML  = &quot;\&quot;((\\\\\&quot;|[^\&quot;])*)\&quot;&quot;
+          RJS_ANY_ID        = &quot;\&quot;([^\&quot;])*\&quot;&quot;
+          RJS_STATEMENTS    = {
+            :chained_replace      =&gt; &quot;\\$\\(#{RJS_ANY_ID}\\)\\.replace\\(#{RJS_PATTERN_HTML}\\)&quot;,
+            :chained_replace_html =&gt; &quot;\\$\\(#{RJS_ANY_ID}\\)\\.update\\(#{RJS_PATTERN_HTML}\\)&quot;,
+            :replace_html         =&gt; &quot;Element\\.update\\(#{RJS_ANY_ID}, #{RJS_PATTERN_HTML}\\)&quot;,
+            :replace              =&gt; &quot;Element\\.replace\\(#{RJS_ANY_ID}, #{RJS_PATTERN_HTML}\\)&quot;
           }
-          RJS_STATEMENTS[:any] = Regexp.new(&quot;(#{RJS_STATEMENTS.values.join('|')})&quot;)
-          RJS_PATTERN_HTML = /&quot;((\\&quot;|[^&quot;])*)&quot;/
-          RJS_INSERTIONS = [:top, :bottom, :before, :after]
+          [:remove, :show, :hide, :toggle].each do |action|
+            RJS_STATEMENTS[action] = &quot;Element\\.#{action}\\(#{RJS_ANY_ID}\\)&quot;
+          end
+          RJS_INSERTIONS = [&quot;top&quot;, &quot;bottom&quot;, &quot;before&quot;, &quot;after&quot;]
           RJS_INSERTIONS.each do |insertion|
-            RJS_STATEMENTS[&quot;insert_#{insertion}&quot;.to_sym] = /Element.insert\(\&quot;([^\&quot;]*)\&quot;, \{ #{insertion.to_s.downcase}: #{RJS_PATTERN_HTML} \}\);/
+            RJS_STATEMENTS[&quot;insert_#{insertion}&quot;.to_sym] = &quot;Element.insert\\(#{RJS_ANY_ID}, \\{ #{insertion}: #{RJS_PATTERN_HTML} \\}\\)&quot;
           end
-          RJS_STATEMENTS[:insert_html] = Regexp.new(RJS_INSERTIONS.collect do |insertion|
-            /Element.insert\(\&quot;([^\&quot;]*)\&quot;, \{ #{insertion.to_s.downcase}: #{RJS_PATTERN_HTML} \}\);/
-          end.join('|'))
-          RJS_PATTERN_EVERYTHING = Regexp.new(&quot;#{RJS_STATEMENTS[:any]}\\(\&quot;([^\&quot;]*)\&quot;, #{RJS_PATTERN_HTML}\\)&quot;, Regexp::MULTILINE)
+          RJS_STATEMENTS[:insert_html] = &quot;Element.insert\\(#{RJS_ANY_ID}, \\{ (#{RJS_INSERTIONS.join('|')}): #{RJS_PATTERN_HTML} \\}\\)&quot;
+          RJS_STATEMENTS[:any] = Regexp.new(&quot;(#{RJS_STATEMENTS.values.join('|')})&quot;)
           RJS_PATTERN_UNICODE_ESCAPED_CHAR = /\\u([0-9a-zA-Z]{4})/
         end
 
@@ -621,8 +595,8 @@ module ActionController
             root = HTML::Node.new(nil)
 
             while true
-              next if body.sub!(RJS_PATTERN_EVERYTHING) do |match|
-                html = unescape_rjs($3)
+              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
                 &quot;&quot;</diff>
      <filename>actionpack/lib/action_controller/assertions/selector_assertions.rb</filename>
    </modified>
    <modified>
      <diff>@@ -599,6 +599,11 @@ class AssertSelectTest &lt; Test::Unit::TestCase
     end
   end
 
+  def test_assert_select_rjs_raise_errors
+    assert_raises(ArgumentError) { assert_select_rjs(:destroy) }
+    assert_raises(ArgumentError) { assert_select_rjs(:insert, :left) }
+  end
+
   # Simple selection from a single result.
   def test_nested_assert_select_rjs_with_single_result
     render_rjs do |page|</diff>
      <filename>actionpack/test/controller/assert_select_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>6450d6ca76603bc5d1b1a6cdcb77e33e35f53d83</id>
    </parent>
  </parents>
  <author>
    <name>miloops</name>
    <email>miloops@gmail.com</email>
  </author>
  <url>http://github.com/rails/rails/commit/11eb29f60ab79caf22f7ca715500e32d9a1b03a2</url>
  <id>11eb29f60ab79caf22f7ca715500e32d9a1b03a2</id>
  <committed-date>2008-08-29T17:52:26-07:00</committed-date>
  <authored-date>2008-08-07T09:07:53-07:00</authored-date>
  <message>Make assert_select_rjs code more readable, make use of unused constants and use more simple Regexps.

[#540 state:resolved]

Signed-off-by: Jeremy Kemper &lt;jeremy@bitsweat.net&gt;</message>
  <tree>336a2bc66ca6916237d3df51fcd5cce976431c7e</tree>
  <committer>
    <name>Jeremy Kemper</name>
    <email>jeremy@bitsweat.net</email>
  </committer>
</commit>
