Skip to content
This repository
Browse code

Added functionality to assert_tag, so you can now do tests on the sib…

…lings of a node, to assert that some element comes before or after the element in question, or just to assert that some element exists as a sibling #1226 [Jamis Buck]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1291 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit 409bc0970aa6145dfaeb6d79363a74e0244002a0 1 parent 483931e
David Heinemeier Hansson authored May 06, 2005
2  actionpack/CHANGELOG
... ...
@@ -1,5 +1,7 @@
1 1
 *SVN*
2 2
 
  3
+* Added functionality to assert_tag, so you can now do tests on the siblings of a node, to assert that some element comes before or after the element in question, or just to assert that some element exists as a sibling #1226 [Jamis Buck]
  4
+
3 5
 * Added better error handling for regexp caching expiration
4 6
 
5 7
 * Fixed handling of requests coming from unknown HTTP methods not to kill the server
6  actionpack/lib/action_controller/assertions.rb
@@ -136,6 +136,12 @@ def assert_routing(path, options, defaults={}, extras={}, message=nil)
136 136
       #   meet the criteria described by the hash.
137 137
       # * <tt>:descendant</tt>: a hash. At least one of the node's descendants
138 138
       #   must meet the criteria described by the hash.
  139
+      # * <tt>:sibling</tt>: a hash. At least one of the node's siblings must
  140
+      #   meet the criteria described by the hash.
  141
+      # * <tt>:after</tt>: a hash. The node must be after any sibling meeting
  142
+      #   the criteria described by the hash, and at least one sibling must match.
  143
+      # * <tt>:before</tt>: a hash. The node must be before any sibling meeting
  144
+      #   the criteria described by the hash, and at least one sibling must match.
139 145
       # * <tt>:children</tt>: a hash, for counting children of a node. Accepts
140 146
       #   the keys:
141 147
       #   * <tt>:count</tt>: either a number or a range which must equal (or
54  actionpack/lib/action_controller/vendor/html-scanner/html/node.rb
@@ -13,7 +13,8 @@ def initialize(hash)
13 13
             # keys are valid, and require no further processing
14 14
           when :attributes then
15 15
             hash[k] = keys_to_strings(v)
16  
-          when :parent, :child, :ancestor, :descendant
  16
+          when :parent, :child, :ancestor, :descendant, :sibling, :before,
  17
+                  :after
17 18
             hash[k] = Conditions.new(v)
18 19
           when :children
19 20
             hash[k] = v = keys_to_symbols(v)
@@ -119,12 +120,20 @@ def validate_conditions(conditions)
119 120
     end
120 121
     
121 122
     class <<self
122  
-      def parse(parent, line, pos, content)
  123
+      def parse(parent, line, pos, content, strict=true)
123 124
         if content !~ /^<\S/
124 125
           Text.new(parent, line, pos, content)
125 126
         else
126 127
           scanner = StringScanner.new(content)
127  
-          scanner.skip(/</) or raise "expected <"
  128
+
  129
+          unless scanner.skip(/</)
  130
+            if strict
  131
+              raise "expected <"
  132
+            else
  133
+              return Text.new(parent, line, pos, content)
  134
+            end
  135
+          end
  136
+
128 137
           closing = ( scanner.scan(/\//) ? :close : nil )
129 138
           return Text.new(parent, line, pos, content) unless name = scanner.scan(/[\w:]+/)
130 139
           name.downcase!
@@ -158,7 +167,14 @@ def parse(parent, line, pos, content)
158 167
             closing = ( scanner.scan(/\//) ? :self : nil )
159 168
           end
160 169
           
161  
-          scanner.scan(/\s*>/) or raise "expected > (got #{scanner.rest.inspect} for #{content}, #{attributes.inspect})" 
  170
+          unless scanner.scan(/\s*>/)
  171
+            if strict
  172
+              raise "expected > (got #{scanner.rest.inspect} for #{content}, #{attributes.inspect})" 
  173
+            else
  174
+              # throw away all text until we find what we're looking for
  175
+              scanner.skip_until(/>/) or scanner.terminate
  176
+            end
  177
+          end
162 178
 
163 179
           Tag.new(parent, line, pos, name, attributes, closing)
164 180
         end
@@ -296,6 +312,12 @@ def tag?
296 312
     #   meet the criteria described by the hash.
297 313
     # * <tt>:descendant</tt>: a hash. At least one of the node's descendants
298 314
     #   must meet the criteria described by the hash.
  315
+    # * <tt>:sibling</tt>: a hash. At least one of the node's siblings must
  316
+    #   meet the criteria described by the hash.
  317
+    # * <tt>:after</tt>: a hash. The node must be after any sibling meeting
  318
+    #   the criteria described by the hash, and at least one sibling must match.
  319
+    # * <tt>:before</tt>: a hash. The node must be before any sibling meeting
  320
+    #   the criteria described by the hash, and at least one sibling must match.
299 321
     # * <tt>:children</tt>: a hash, for counting children of a node. Accepts the
300 322
     #   keys:
301 323
     # ** <tt>:count</tt>: either a number or a range which must equal (or
@@ -404,6 +426,30 @@ def match(conditions)
404 426
           end
405 427
         end
406 428
       end
  429
+
  430
+      # test siblings
  431
+      if conditions[:sibling] || conditions[:before] || conditions[:after]
  432
+        siblings = parent ? parent.children : []
  433
+        self_index = siblings.index(self)
  434
+
  435
+        if conditions[:sibling]
  436
+          return false unless siblings.detect do |s| 
  437
+            s != self && s.match(conditions[:sibling])
  438
+          end
  439
+        end
  440
+
  441
+        if conditions[:before]
  442
+          return false unless siblings[self_index+1..-1].detect do |s| 
  443
+            s != self && s.match(conditions[:before])
  444
+          end
  445
+        end
  446
+
  447
+        if conditions[:after]
  448
+          return false unless siblings[0,self_index].detect do |s| 
  449
+            s != self && s.match(conditions[:after])
  450
+          end
  451
+        end
  452
+      end
407 453
   
408 454
       true
409 455
     end
2  actionpack/lib/action_controller/vendor/html-scanner/html/tokenizer.rb
@@ -92,4 +92,4 @@ def consume_quoted_regions
92 92
       end
93 93
   end
94 94
   
95  
-end
  95
+end

0 notes on commit 409bc09

Please sign in to comment.
Something went wrong with that request. Please try again.