Upgraded Rails and RSpec
[monkeycharger.git] / vendor / rails / actionpack / test / controller / assert_select_test.rb
blobb0f3d6cedc75f2be9a60b5a2cd85580093a95e65
1 #--
2 # Copyright (c) 2006 Assaf Arkin (http://labnotes.org)
3 # Under MIT and/or CC By license.
4 #++
6 require "#{File.dirname(__FILE__)}/../abstract_unit"
7 require "#{File.dirname(__FILE__)}/fake_controllers"
10 unless defined?(ActionMailer)
11   begin
12     $:.unshift(File.dirname(__FILE__) + "/../../../actionmailer/lib")
13     require 'action_mailer'
14   rescue LoadError
15     require 'rubygems'
16     gem 'actionmailer'
17   end
18 end
20 class AssertSelectTest < Test::Unit::TestCase
21   class AssertSelectController < ActionController::Base
22     def response_with=(content)
23       @content = content
24     end
26     def response_with(&block)
27       @update = block
28     end
30     def html()
31       render :text=>@content, :layout=>false, :content_type=>Mime::HTML
32       @content = nil
33     end
35     def rjs()
36       render :update do |page|
37         @update.call page
38       end
39       @update = nil
40     end
42     def xml()
43       render :text=>@content, :layout=>false, :content_type=>Mime::XML
44       @content = nil
45     end
47     def rescue_action(e)
48       raise e
49     end
50   end
52   class AssertSelectMailer < ActionMailer::Base
53     def test(html)
54       recipients "test <test@test.host>"
55       from "test@test.host"
56       subject "Test e-mail"
57       part :content_type=>"text/html", :body=>html
58     end
59   end
61   AssertionFailedError = Test::Unit::AssertionFailedError
63   def setup
64     @controller = AssertSelectController.new
65     @request    = ActionController::TestRequest.new
66     @response   = ActionController::TestResponse.new
67     ActionMailer::Base.delivery_method = :test
68     ActionMailer::Base.perform_deliveries = true
69     ActionMailer::Base.deliveries = []
70   end
73   def teardown
74     ActionMailer::Base.deliveries.clear
75   end
76   
77   def assert_failure(message, &block)
78     e = assert_raises(AssertionFailedError, &block)
79     assert_match(message, e.message) if Regexp === message
80     assert_equal(message, e.message) if String === message
81   end
83   #
84   # Test assert select.
85   #
87   def test_assert_select
88     render_html %Q{<div id="1"></div><div id="2"></div>}
89     assert_select "div", 2
90     assert_failure(/Expected at least 3 elements matching \"div\", found 2/) { assert_select "div", 3 }
91     assert_failure(/Expected at least 1 element matching \"p\", found 0/) { assert_select "p" }
92   end
95   def test_equality_true_false
96     render_html %Q{<div id="1"></div><div id="2"></div>}
97     assert_nothing_raised               { assert_select "div" }
98     assert_raises(AssertionFailedError) { assert_select "p" }
99     assert_nothing_raised               { assert_select "div", true }
100     assert_raises(AssertionFailedError) { assert_select "p", true }
101     assert_raises(AssertionFailedError) { assert_select "div", false }
102     assert_nothing_raised               { assert_select "p", false }
103   end
106   def test_equality_string_and_regexp
107     render_html %Q{<div id="1">foo</div><div id="2">foo</div>}
108     assert_nothing_raised               { assert_select "div", "foo" }
109     assert_raises(AssertionFailedError) { assert_select "div", "bar" }
110     assert_nothing_raised               { assert_select "div", :text=>"foo" }
111     assert_raises(AssertionFailedError) { assert_select "div", :text=>"bar" }
112     assert_nothing_raised               { assert_select "div", /(foo|bar)/ }
113     assert_raises(AssertionFailedError) { assert_select "div", /foobar/ }
114     assert_nothing_raised               { assert_select "div", :text=>/(foo|bar)/ }
115     assert_raises(AssertionFailedError) { assert_select "div", :text=>/foobar/ }
116     assert_raises(AssertionFailedError) { assert_select "p", :text=>/foobar/ }
117   end
120   def test_equality_of_html
121     render_html %Q{<p>\n<em>"This is <strong>not</strong> a big problem,"</em> he said.\n</p>}
122     text = "\"This is not a big problem,\" he said."
123     html = "<em>\"This is <strong>not</strong> a big problem,\"</em> he said."
124     assert_nothing_raised               { assert_select "p", text }
125     assert_raises(AssertionFailedError) { assert_select "p", html }
126     assert_nothing_raised               { assert_select "p", :html=>html }
127     assert_raises(AssertionFailedError) { assert_select "p", :html=>text }
128     # No stripping for pre.
129     render_html %Q{<pre>\n<em>"This is <strong>not</strong> a big problem,"</em> he said.\n</pre>}
130     text = "\n\"This is not a big problem,\" he said.\n"
131     html = "\n<em>\"This is <strong>not</strong> a big problem,\"</em> he said.\n"
132     assert_nothing_raised               { assert_select "pre", text }
133     assert_raises(AssertionFailedError) { assert_select "pre", html }
134     assert_nothing_raised               { assert_select "pre", :html=>html }
135     assert_raises(AssertionFailedError) { assert_select "pre", :html=>text }
136   end
139   def test_counts
140     render_html %Q{<div id="1">foo</div><div id="2">foo</div>}
141     assert_nothing_raised               { assert_select "div", 2 }
142     assert_failure(/Expected at least 3 elements matching \"div\", found 2/) do
143       assert_select "div", 3
144     end
145     assert_nothing_raised               { assert_select "div", 1..2 }
146     assert_failure(/Expected between 3 and 4 elements matching \"div\", found 2/) do
147       assert_select "div", 3..4
148     end
149     assert_nothing_raised               { assert_select "div", :count=>2 }
150     assert_failure(/Expected at least 3 elements matching \"div\", found 2/) do
151       assert_select "div", :count=>3
152     end
153     assert_nothing_raised               { assert_select "div", :minimum=>1 }
154     assert_nothing_raised               { assert_select "div", :minimum=>2 }
155     assert_failure(/Expected at least 3 elements matching \"div\", found 2/) do
156       assert_select "div", :minimum=>3
157     end
158     assert_nothing_raised               { assert_select "div", :maximum=>2 }
159     assert_nothing_raised               { assert_select "div", :maximum=>3 }
160     assert_failure(/Expected at most 1 element matching \"div\", found 2/) do
161       assert_select "div", :maximum=>1
162     end
163     assert_nothing_raised               { assert_select "div", :minimum=>1, :maximum=>2 }
164     assert_failure(/Expected between 3 and 4 elements matching \"div\", found 2/) do
165       assert_select "div", :minimum=>3, :maximum=>4
166     end
167   end
170   def test_substitution_values
171     render_html %Q{<div id="1">foo</div><div id="2">foo</div>}
172     assert_select "div#?", /\d+/ do |elements|
173       assert_equal 2, elements.size
174     end
175     assert_select "div" do
176       assert_select "div#?", /\d+/ do |elements|
177         assert_equal 2, elements.size
178         assert_select "#1"
179         assert_select "#2"
180       end
181     end
182   end
184   
185   def test_nested_assert_select
186     render_html %Q{<div id="1">foo</div><div id="2">foo</div>}
187     assert_select "div" do |elements|
188       assert_equal 2, elements.size
189       assert_select elements[0], "#1"
190       assert_select elements[1], "#2"
191     end
192     assert_select "div" do
193       assert_select "div" do |elements|
194         assert_equal 2, elements.size
195         # Testing in a group is one thing
196         assert_select "#1,#2"
197         # Testing individually is another.
198         assert_select "#1"
199         assert_select "#2"
200         assert_select "#3", false
201       end
202     end
203     
204     assert_failure(/Expected at least 1 element matching \"#4\", found 0\./) do
205       assert_select "div" do
206         assert_select "#4"
207       end
208     end
209   end
212   def test_assert_select_text_match
213     render_html %Q{<div id="1"><span>foo</span></div><div id="2"><span>bar</span></div>}
214     assert_select "div" do
215       assert_nothing_raised               { assert_select "div", "foo" }
216       assert_nothing_raised               { assert_select "div", "bar" }
217       assert_nothing_raised               { assert_select "div", /\w*/ }
218       assert_nothing_raised               { assert_select "div", /\w*/, :count=>2 }
219       assert_raises(AssertionFailedError) { assert_select "div", :text=>"foo", :count=>2 }
220       assert_nothing_raised               { assert_select "div", :html=>"<span>bar</span>" }
221       assert_nothing_raised               { assert_select "div", :html=>"<span>bar</span>" }
222       assert_nothing_raised               { assert_select "div", :html=>/\w*/ }
223       assert_nothing_raised               { assert_select "div", :html=>/\w*/, :count=>2 }
224       assert_raises(AssertionFailedError) { assert_select "div", :html=>"<span>foo</span>", :count=>2 }
225     end
226   end
229   # With single result.
230   def test_assert_select_from_rjs_with_single_result
231     render_rjs do |page|
232       page.replace_html "test", "<div id=\"1\">foo</div>\n<div id=\"2\">foo</div>"
233     end
234     assert_select "div" do |elements|
235       assert elements.size == 2
236       assert_select "#1"
237       assert_select "#2"
238     end
239     assert_select "div#?", /\d+/ do |elements|
240       assert_select "#1"
241       assert_select "#2"
242     end
243   end
245   # With multiple results.
246   def test_assert_select_from_rjs_with_multiple_results
247     render_rjs do |page|
248       page.replace_html "test", "<div id=\"1\">foo</div>"
249       page.replace_html "test2", "<div id=\"2\">foo</div>"
250     end
251     assert_select "div" do |elements|
252       assert elements.size == 2
253       assert_select "#1"
254       assert_select "#2"
255     end
256   end
259   #
260   # Test css_select.
261   #
264   def test_css_select
265     render_html %Q{<div id="1"></div><div id="2"></div>}
266     assert 2, css_select("div").size
267     assert 0, css_select("p").size
268   end
271   def test_nested_css_select
272     render_html %Q{<div id="1">foo</div><div id="2">foo</div>}
273     assert_select "div#?", /\d+/ do |elements|
274       assert_equal 1, css_select(elements[0], "div").size
275       assert_equal 1, css_select(elements[1], "div").size
276     end
277     assert_select "div" do
278       assert_equal 2, css_select("div").size
279       css_select("div").each do |element|
280         # Testing as a group is one thing
281         assert !css_select("#1,#2").empty?
282         # Testing individually is another
283         assert !css_select("#1").empty?
284         assert !css_select("#2").empty?
285       end
286     end
287   end
290   # With one result.
291   def test_css_select_from_rjs_with_single_result
292     render_rjs do |page|
293       page.replace_html "test", "<div id=\"1\">foo</div>\n<div id=\"2\">foo</div>"
294     end
295     assert_equal 2, css_select("div").size
296     assert_equal 1, css_select("#1").size
297     assert_equal 1, css_select("#2").size
298   end
300   # With multiple results.
301   def test_css_select_from_rjs_with_multiple_results
302     render_rjs do |page|
303       page.replace_html "test", "<div id=\"1\">foo</div>"
304       page.replace_html "test2", "<div id=\"2\">foo</div>"
305     end
307     assert_equal 2, css_select("div").size
308     assert_equal 1, css_select("#1").size
309     assert_equal 1, css_select("#2").size
310   end
313   #
314   # Test assert_select_rjs.
315   #
318   # Test that we can pick up all statements in the result.
319   def test_assert_select_rjs_picks_up_all_statements
320     render_rjs do |page|
321       page.replace "test", "<div id=\"1\">foo</div>"
322       page.replace_html "test2", "<div id=\"2\">foo</div>"
323       page.insert_html :top, "test3", "<div id=\"3\">foo</div>"
324     end
326     found = false
327     assert_select_rjs do
328       assert_select "#1"
329       assert_select "#2"
330       assert_select "#3"
331       found = true
332     end
333     assert found
334   end
336   # Test that we fail if there is nothing to pick.
337   def test_assert_select_rjs_fails_if_nothing_to_pick
338     render_rjs { }
339     assert_raises(AssertionFailedError) { assert_select_rjs }
340   end
342   def test_assert_select_rjs_with_unicode
343     # Test that non-ascii characters (which are converted into \uXXXX in RJS) are decoded correctly.
344     render_rjs do |page|
345       page.replace "test", "<div id=\"1\">\343\203\201\343\202\261\343\203\203\343\203\210</div>"
346     end
347     assert_select_rjs do
348       assert_select "#1", :text => "\343\203\201\343\202\261\343\203\203\343\203\210"
349       assert_select "#1", "\343\203\201\343\202\261\343\203\203\343\203\210"
350       assert_select "#1", Regexp.new("\343\203\201..\343\203\210",0,'U')
351       assert_raises(AssertionFailedError) { assert_select "#1", Regexp.new("\343\203\201.\343\203\210",0,'U') }
352     end
353   end
355   def test_assert_select_rjs_with_id
356     # Test that we can pick up all statements in the result.
357     render_rjs do |page|
358       page.replace "test1", "<div id=\"1\">foo</div>"
359       page.replace_html "test2", "<div id=\"2\">foo</div>"
360       page.insert_html :top, "test3", "<div id=\"3\">foo</div>"
361     end
362     assert_select_rjs "test1" do
363       assert_select "div", 1
364       assert_select "#1"
365     end
366     assert_select_rjs "test2" do
367       assert_select "div", 1
368       assert_select "#2"
369     end
370     assert_select_rjs "test3" do
371       assert_select "div", 1
372       assert_select "#3"
373     end
374     assert_raises(AssertionFailedError) { assert_select_rjs "test4" }
375   end
378   def test_assert_select_rjs_for_replace
379     render_rjs do |page|
380       page.replace "test1", "<div id=\"1\">foo</div>"
381       page.replace_html "test2", "<div id=\"2\">foo</div>"
382       page.insert_html :top, "test3", "<div id=\"3\">foo</div>"
383     end
384     # Replace.
385     assert_select_rjs :replace do
386       assert_select "div", 1
387       assert_select "#1"
388     end
389     assert_select_rjs :replace, "test1" do
390       assert_select "div", 1
391       assert_select "#1"
392     end
393     assert_raises(AssertionFailedError) { assert_select_rjs :replace, "test2" }
394     # Replace HTML.
395     assert_select_rjs :replace_html do
396       assert_select "div", 1
397       assert_select "#2"
398     end
399     assert_select_rjs :replace_html, "test2" do
400       assert_select "div", 1
401       assert_select "#2"
402     end
403     assert_raises(AssertionFailedError) { assert_select_rjs :replace_html, "test1" }
404   end
406   def test_assert_select_rjs_for_chained_replace
407     render_rjs do |page|
408       page['test1'].replace "<div id=\"1\">foo</div>"
409       page['test2'].replace_html "<div id=\"2\">foo</div>"
410       page.insert_html :top, "test3", "<div id=\"3\">foo</div>"
411     end
412     # Replace.
413     assert_select_rjs :chained_replace do
414       assert_select "div", 1
415       assert_select "#1"
416     end
417     assert_select_rjs :chained_replace, "test1" do
418       assert_select "div", 1
419       assert_select "#1"
420     end
421     assert_raises(AssertionFailedError) { assert_select_rjs :chained_replace, "test2" }
422     # Replace HTML.
423     assert_select_rjs :chained_replace_html do
424       assert_select "div", 1
425       assert_select "#2"
426     end
427     assert_select_rjs :chained_replace_html, "test2" do
428       assert_select "div", 1
429       assert_select "#2"
430     end
431     assert_raises(AssertionFailedError) { assert_select_rjs :replace_html, "test1" }
432   end
434   # Simple remove
435   def test_assert_select_rjs_for_remove
436     render_rjs do |page|
437       page.remove "test1"
438     end
440     assert_select_rjs :remove, "test1"
441   end
443   def test_assert_select_rjs_for_remove_ignores_block
444     render_rjs do |page|
445       page.remove "test1"
446     end
448     assert_nothing_raised do
449       assert_select_rjs :remove, "test1" do
450         assert_select "p"
451       end
452     end
453   end
455   # Simple show
456   def test_assert_select_rjs_for_show
457     render_rjs do |page|
458       page.show "test1"
459     end
461     assert_select_rjs :show, "test1"
462   end
464   def test_assert_select_rjs_for_show_ignores_block
465     render_rjs do |page|
466       page.show "test1"
467     end
469     assert_nothing_raised do
470       assert_select_rjs :show, "test1" do
471         assert_select "p"
472       end
473     end
474   end
475   
476   # Simple hide
477   def test_assert_select_rjs_for_hide
478     render_rjs do |page|
479       page.hide "test1"
480     end
482     assert_select_rjs :hide, "test1"
483   end
485   def test_assert_select_rjs_for_hide_ignores_block
486     render_rjs do |page|
487       page.hide "test1"
488     end
490     assert_nothing_raised do
491       assert_select_rjs :hide, "test1" do
492         assert_select "p"
493       end
494     end
495   end
496   
497   # Simple toggle
498   def test_assert_select_rjs_for_toggle
499     render_rjs do |page|
500       page.toggle "test1"
501     end
503     assert_select_rjs :toggle, "test1"
504   end
506   def test_assert_select_rjs_for_toggle_ignores_block
507     render_rjs do |page|
508       page.toggle "test1"
509     end
511     assert_nothing_raised do
512       assert_select_rjs :toggle, "test1" do
513         assert_select "p"
514       end
515     end
516   end
517   
518   # Non-positioned insert.
519   def test_assert_select_rjs_for_nonpositioned_insert
520     render_rjs do |page|
521       page.replace "test1", "<div id=\"1\">foo</div>"
522       page.replace_html "test2", "<div id=\"2\">foo</div>"
523       page.insert_html :top, "test3", "<div id=\"3\">foo</div>"
524     end
525     assert_select_rjs :insert_html do
526       assert_select "div", 1
527       assert_select "#3"
528     end
529     assert_select_rjs :insert_html, "test3" do
530       assert_select "div", 1
531       assert_select "#3"
532     end
533     assert_raises(AssertionFailedError) { assert_select_rjs :insert_html, "test1" }
534   end
536   # Positioned insert.
537   def test_assert_select_rjs_for_positioned_insert
538     render_rjs do |page|
539       page.insert_html :top, "test1", "<div id=\"1\">foo</div>"
540       page.insert_html :bottom, "test2", "<div id=\"2\">foo</div>"
541       page.insert_html :before, "test3", "<div id=\"3\">foo</div>"
542       page.insert_html :after, "test4", "<div id=\"4\">foo</div>"
543     end
544     assert_select_rjs :insert, :top do
545       assert_select "div", 1
546       assert_select "#1"
547     end
548     assert_select_rjs :insert, :bottom do
549       assert_select "div", 1
550       assert_select "#2"
551     end
552     assert_select_rjs :insert, :before do
553       assert_select "div", 1
554       assert_select "#3"
555     end
556     assert_select_rjs :insert, :after do
557       assert_select "div", 1
558       assert_select "#4"
559     end
560     assert_select_rjs :insert_html do
561       assert_select "div", 4
562     end
563   end
564   
565   # Simple selection from a single result.
566   def test_nested_assert_select_rjs_with_single_result
567     render_rjs do |page|
568       page.replace_html "test", "<div id=\"1\">foo</div>\n<div id=\"2\">foo</div>"
569     end
571     assert_select_rjs "test" do |elements|
572       assert_equal 2, elements.size
573       assert_select "#1"
574       assert_select "#2"
575     end
576   end
578   # Deal with two results.
579   def test_nested_assert_select_rjs_with_two_results
580     render_rjs do |page|
581       page.replace_html "test", "<div id=\"1\">foo</div>"
582       page.replace_html "test2", "<div id=\"2\">foo</div>"
583     end
585     assert_select_rjs "test" do |elements|
586       assert_equal 1, elements.size
587       assert_select "#1"
588     end
590     assert_select_rjs "test2" do |elements|
591       assert_equal 1, elements.size
592       assert_select "#2"
593     end
594   end
597   def test_feed_item_encoded
598     render_xml <<-EOF
599 <rss version="2.0">
600   <channel>
601     <item>
602       <description>
603         <![CDATA[
604           <p>Test 1</p>
605         ]]>
606       </description>
607     </item>
608     <item>
609       <description>
610         <![CDATA[
611           <p>Test 2</p>
612         ]]>
613       </description>
614     </item>
615   </channel>
616 </rss>
618     assert_select "channel item description" do
619       # Test element regardless of wrapper.
620       assert_select_encoded do
621         assert_select "p", :count=>2, :text=>/Test/
622       end
623       # Test through encoded wrapper.
624       assert_select_encoded do
625         assert_select "encoded p", :count=>2, :text=>/Test/
626       end
627       # Use :root instead (recommended)
628       assert_select_encoded do
629         assert_select ":root p", :count=>2, :text=>/Test/
630       end
631       # Test individually.
632       assert_select "description" do |elements|
633         assert_select_encoded elements[0] do
634           assert_select "p", "Test 1"
635         end
636         assert_select_encoded elements[1] do
637           assert_select "p", "Test 2"
638         end
639       end
640     end
642     # Test that we only un-encode element itself.
643     assert_select "channel item" do
644       assert_select_encoded do
645         assert_select "p", 0
646       end
647     end
648   end
651   #
652   # Test assert_select_email
653   #
655   def test_assert_select_email
656     assert_raises(AssertionFailedError) { assert_select_email {} }
657     AssertSelectMailer.deliver_test "<div><p>foo</p><p>bar</p></div>"
658     assert_select_email do
659       assert_select "div:root" do
660         assert_select "p:first-child", "foo"
661         assert_select "p:last-child", "bar"
662       end
663     end
664   end
667   protected
668     def render_html(html)
669       @controller.response_with = html
670       get :html
671     end
673     def render_rjs(&block)
674       @controller.response_with &block
675       get :rjs
676     end
678     def render_xml(xml)
679       @controller.response_with = xml
680       get :xml
681     end