Updated to latest rspec
[gitorious:georgyos-clone.git] / vendor / plugins / rspec-rails / spec / rails / matchers / assert_select_spec.rb
1 require File.dirname(__FILE__) + '/../../spec_helper'
2
3 # assert_select plugins for Rails
4 #
5 # Copyright (c) 2006 Assaf Arkin, under Creative Commons Attribution and/or MIT License
6 # Developed for http://co.mments.com
7 # Code and documention: http://labnotes.org
8
9 class AssertSelectController < ActionController::Base
10
11   def response=(content)
12     @content = content
13   end
14
15   #NOTE - this is commented because response is implemented in lib/spec/rails/context/controller
16   # def response(&block)
17   #   @update = block
18   # end
19   # 
20   def html()
21     render :text=>@content, :layout=>false, :content_type=>Mime::HTML
22     @content = nil
23   end
24
25   def rjs()
26     update = @update
27     render :update do |page|
28       update.call page
29     end
30     @update = nil
31   end
32
33   def xml()
34     render :text=>@content, :layout=>false, :content_type=>Mime::XML
35     @content = nil
36   end
37
38   def rescue_action(e)
39     raise e
40   end
41
42 end
43
44 class AssertSelectMailer < ActionMailer::Base
45
46   def test(html)
47     recipients "test <test@test.host>"
48     from "test@test.host"
49     subject "Test e-mail"
50     part :content_type=>"text/html", :body=>html
51   end
52
53 end
54
55 module AssertSelectSpecHelpers
56   def render_html(html)
57     @controller.response = html
58     get :html
59   end
60
61   def render_rjs(&block)
62     clear_response
63     @controller.response &block
64     get :rjs
65   end
66
67   def render_xml(xml)
68     @controller.response = xml
69     get :xml
70   end
71   
72   def first_non_rspec_line_in_backtrace_of(error)
73     rspec_path = File.join('rspec', 'lib', 'spec')
74     error.backtrace.reject { |line|
75       line =~ /#{rspec_path}/
76     }.first
77   end
78
79   private
80     # necessary for 1.2.1
81     def clear_response
82       render_html("")
83     end
84 end
85
86 unless defined?(SpecFailed)
87   SpecFailed = Spec::Expectations::ExpectationNotMetError 
88 end
89
90 describe "should have_tag", :type => :controller do
91   include AssertSelectSpecHelpers
92   controller_name :assert_select
93   integrate_views
94
95   it "should find specific numbers of elements" do
96     render_html %Q{<div id="1"></div><div id="2"></div>}
97     response.should have_tag( "div" )
98     response.should have_tag("div", 2)
99     lambda { response.should_not have_tag("div") }.should raise_error(SpecFailed, "should not have tag(\"div\"), but did")
100
101     lambda { response.should have_tag("div", 3) }.should raise_error(SpecFailed)
102     lambda { response.should have_tag("p") }.should raise_error(SpecFailed)
103   end
104
105   it "should expect to find elements when using true" do
106     render_html %Q{<div id="1"></div><div id="2"></div>}
107     response.should have_tag( "div", true )
108     lambda { response.should have_tag( "p", true )}.should raise_error(SpecFailed)
109   end
110
111   it "should expect to not find elements when using false" do
112     render_html %Q{<div id="1"></div><div id="2"></div>}
113     response.should have_tag( "p", false )
114     lambda { response.should have_tag( "div", false )}.should raise_error(SpecFailed)
115   end
116
117
118   it "should match submitted text using text or regexp" do
119     render_html %Q{<div id="1">foo</div><div id="2">foo</div>}
120     response.should have_tag("div", "foo")
121     response.should have_tag("div", /(foo|bar)/)
122     response.should have_tag("div", :text=>"foo")
123     response.should have_tag("div", :text=>/(foo|bar)/)
124
125     lambda { response.should have_tag("div", "bar") }.should raise_error(SpecFailed)
126     lambda { response.should have_tag("div", :text=>"bar") }.should raise_error(SpecFailed)
127     lambda { response.should have_tag("p", :text=>"foo") }.should raise_error(SpecFailed)
128
129     lambda { response.should have_tag("div", /foobar/) }.should raise_error(SpecFailed)
130     lambda { response.should have_tag("div", :text=>/foobar/) }.should raise_error(SpecFailed)
131     lambda { response.should have_tag("p", :text=>/foo/) }.should raise_error(SpecFailed)
132   end
133   
134   it "should use submitted message" do
135     render_html %Q{nothing here}
136     lambda {
137       response.should have_tag("div", {}, "custom message")
138     }.should raise_error(SpecFailed, /custom message/)
139   end
140
141   it "should match submitted html" do
142     render_html %Q{<p>\n<em>"This is <strong>not</strong> a big problem,"</em> he said.\n</p>}
143     text = "\"This is not a big problem,\" he said."
144     html = "<em>\"This is <strong>not</strong> a big problem,\"</em> he said."
145     response.should have_tag("p", text)
146     lambda { response.should have_tag("p", html) }.should raise_error(SpecFailed)
147     response.should have_tag("p", :html=>html)
148     lambda { response.should have_tag("p", :html=>text) }.should raise_error(SpecFailed)
149
150     # # No stripping for pre.
151     render_html %Q{<pre>\n<em>"This is <strong>not</strong> a big problem,"</em> he said.\n</pre>}
152     text = "\n\"This is not a big problem,\" he said.\n"
153     html = "\n<em>\"This is <strong>not</strong> a big problem,\"</em> he said.\n"
154     response.should have_tag("pre", text)
155     lambda { response.should have_tag("pre", html) }.should raise_error(SpecFailed)
156     response.should have_tag("pre", :html=>html)
157     lambda { response.should have_tag("pre", :html=>text) }.should raise_error(SpecFailed)
158   end
159
160   it "should match number of instances" do
161     render_html %Q{<div id="1">foo</div><div id="2">foo</div>}
162     response.should have_tag("div", 2)
163     lambda { response.should have_tag("div", 3) }.should raise_error(SpecFailed)
164     response.should have_tag("div", 1..2)
165     lambda { response.should have_tag("div", 3..4) }.should raise_error(SpecFailed)
166     response.should have_tag("div", :count=>2)
167     lambda { response.should have_tag("div", :count=>3) }.should raise_error(SpecFailed)
168     response.should have_tag("div", :minimum=>1)
169     response.should have_tag("div", :minimum=>2)
170     lambda { response.should have_tag("div", :minimum=>3) }.should raise_error(SpecFailed)
171     response.should have_tag("div", :maximum=>2)
172     response.should have_tag("div", :maximum=>3)
173     lambda { response.should have_tag("div", :maximum=>1) }.should raise_error(SpecFailed)
174     response.should have_tag("div", :minimum=>1, :maximum=>2)
175     lambda { response.should have_tag("div", :minimum=>3, :maximum=>4) }.should raise_error(SpecFailed)
176   end
177
178   it "substitution values" do
179     render_html %Q{<div id="1">foo</div><div id="2">foo</div><span id="3"></span>}
180     response.should have_tag("div#?", /\d+/) do |elements| #using do/end
181       elements.size.should == 2
182     end
183     response.should have_tag("div#?", /\d+/) { |elements| #using {}
184       elements.size.should == 2
185     }
186     lambda {
187       response.should have_tag("div#?", /\d+/) do |elements|
188         elements.size.should == 3
189       end
190     }.should raise_error(SpecFailed, "expected: 3,\n     got: 2 (using ==)")
191     
192     lambda {
193       response.should have_tag("div#?", /\d+/) { |elements|
194         elements.size.should == 3
195       }
196     }.should raise_error(SpecFailed, "expected: 3,\n     got: 2 (using ==)")
197
198     response.should have_tag("div#?", /\d+/) do |elements|
199       elements.size.should == 2
200       with_tag("#1")
201       with_tag("#2")
202       without_tag("#3")
203     end 
204   end
205   
206   #added for RSpec
207   it "nested tags in form" do
208     render_html %Q{
209       <form action="test">
210         <input type="text" name="email">
211       </form>
212       <form action="other">
213         <input type="text" name="other_input">
214       </form>
215     }
216     response.should have_tag("form[action=test]") { |form|
217       with_tag("input[type=text][name=email]")
218     }
219     response.should have_tag("form[action=test]") { |form|
220       with_tag("input[type=text][name=email]")
221     }
222     
223     lambda {
224       response.should have_tag("form[action=test]") { |form|
225         with_tag("input[type=text][name=other_input]")
226       }
227     }.should raise_error(SpecFailed)
228     
229     lambda {
230       response.should have_tag("form[action=test]") {
231         with_tag("input[type=text][name=other_input]")
232       }
233     }.should raise_error(SpecFailed)
234   end
235   
236   it "should report the correct line number for a nested failed expectation" do
237     render_html %Q{
238       <form action="test">
239         <input type="text" name="email">
240       </form>
241     }
242     begin
243       response.should have_tag("form[action=test]") {
244         @expected_error_line = __LINE__; should have_tag("input[type=text][name=other_input]")
245       }
246     rescue => e
247       first_non_rspec_line_in_backtrace_of(e).should =~ 
248         /#{File.basename(__FILE__)}:#{@expected_error_line}/
249     else
250       fail
251     end
252   end
253
254   it "should report the correct line number for a nested raised exception" do
255     render_html %Q{
256       <form action="test">
257         <input type="text" name="email">
258       </form>
259     }
260     begin
261       response.should have_tag("form[action=test]") {
262         @expected_error_line = __LINE__; raise "Failed!"
263       }
264     rescue => e
265       first_non_rspec_line_in_backtrace_of(e).should =~ 
266         /#{File.basename(__FILE__)}:#{@expected_error_line}/
267     else
268       fail
269     end
270   end
271
272   it "should report the correct line number for a nested failed test/unit assertion" do
273     pending "Doesn't work at the moment. Do we want to support this?" do
274       render_html %Q{
275         <form action="test">
276           <input type="text" name="email">
277         </form>
278       }
279       begin
280         response.should have_tag("form[action=test]") {
281           @expected_error_line = __LINE__; assert false
282         }
283       rescue => e
284         first_non_rspec_line_in_backtrace_of(e).should =~
285           /#{File.basename(__FILE__)}:#{@expected_error_line}/
286       else
287         fail
288       end
289     end
290   end
291
292   
293   it "beatles" do
294     unless defined?(BEATLES)
295       BEATLES = [
296         ["John", "Guitar"],
297         ["George", "Guitar"],
298         ["Paul", "Bass"],
299         ["Ringo", "Drums"]
300       ]
301     end
302
303     render_html %Q{
304       <div id="beatles">
305         <div class="beatle">
306           <h2>John</h2><p>Guitar</p>
307         </div>
308         <div class="beatle">
309           <h2>George</h2><p>Guitar</p>
310         </div>
311         <div class="beatle">
312           <h2>Paul</h2><p>Bass</p>
313         </div>
314         <div class="beatle">
315           <h2>Ringo</h2><p>Drums</p>
316         </div>
317       </div>          
318     }
319     response.should have_tag("div#beatles>div[class=\"beatle\"]", 4)
320
321     response.should have_tag("div#beatles>div.beatle") {
322       BEATLES.each { |name, instrument|
323         with_tag("div.beatle>h2", name)
324         with_tag("div.beatle>p", instrument)
325         without_tag("div.beatle>span")
326       }
327     }
328   end
329
330   it "assert_select_text_match" do
331     render_html %Q{<div id="1"><span>foo</span></div><div id="2"><span>bar</span></div>}
332     response.should have_tag("div") do |divs|
333       with_tag("div", "foo")
334       with_tag("div", "bar")
335       with_tag("div", /\w*/)
336       with_tag("div", /\w*/, :count=>2)
337       without_tag("div", :text=>"foo", :count=>2)
338       with_tag("div", :html=>"<span>bar</span>")
339       with_tag("div", :html=>"<span>bar</span>")
340       with_tag("div", :html=>/\w*/)
341       with_tag("div", :html=>/\w*/, :count=>2)
342       without_tag("div", :html=>"<span>foo</span>", :count=>2)
343     end
344   end
345
346
347   it "assert_select_from_rjs with one item" do
348     render_rjs do |page|
349       page.replace_html "test", "<div id=\"1\">foo</div>\n<div id=\"2\">foo</div>"
350     end
351     response.should have_tag("div") { |elements|
352       elements.size.should == 2
353       with_tag("#1")
354       with_tag("#2")
355     }
356     
357     lambda {
358       response.should have_tag("div") { |elements|
359         elements.size.should == 2
360         with_tag("#1")
361         with_tag("#3")
362       }
363     }.should raise_error(SpecFailed)
364
365     lambda {
366       response.should have_tag("div") { |elements|
367         elements.size.should == 2
368         with_tag("#1")
369         without_tag("#2")
370       }
371     }.should raise_error(SpecFailed, "should not have tag(\"#2\"), but did")
372
373     lambda {
374       response.should have_tag("div") { |elements|
375         elements.size.should == 3
376         with_tag("#1")
377         with_tag("#2")
378       }
379     }.should raise_error(SpecFailed)
380
381
382     response.should have_tag("div#?", /\d+/) { |elements|
383       with_tag("#1")
384       with_tag("#2")
385     }
386   end
387   
388   it "assert_select_from_rjs with multiple items" do
389     render_rjs do |page|
390       page.replace_html "test", "<div id=\"1\">foo</div>"
391       page.replace_html "test2", "<div id=\"2\">foo</div>"
392     end
393     response.should have_tag("div")
394     response.should have_tag("div") { |elements|
395       elements.size.should == 2
396       with_tag("#1")
397       with_tag("#2")
398     }
399
400     lambda {
401       response.should have_tag("div") { |elements|
402         with_tag("#3")
403       }
404     }.should raise_error(SpecFailed)
405   end
406 end
407
408 describe "css_select", :type => :controller do
409   include AssertSelectSpecHelpers
410   controller_name :assert_select
411   integrate_views
412
413   it "can select tags from html" do
414     render_html %Q{<div id="1"></div><div id="2"></div>}
415     css_select("div").size.should == 2
416     css_select("p").size.should == 0
417   end
418
419
420   it "can select nested tags from html" do
421     render_html %Q{<div id="1">foo</div><div id="2">foo</div>}
422     response.should have_tag("div#?", /\d+/) { |elements|
423       css_select(elements[0], "div").should have(1).element
424       css_select(elements[1], "div").should have(1).element
425     }
426     response.should have_tag("div") {
427       css_select("div").should have(2).elements
428       css_select("div").each { |element|
429         # Testing as a group is one thing
430         css_select("#1,#2").should have(2).elements
431         # Testing individually is another
432         css_select("#1").should have(1).element
433         css_select("#2").should have(1).element
434       }
435     }
436   end
437
438   it "can select nested tags from rjs (one result)" do
439     render_rjs do |page|
440       page.replace_html "test", "<div id=\"1\">foo</div>\n<div id=\"2\">foo</div>"
441     end
442     css_select("div").should have(2).elements
443     css_select("#1").should have(1).element
444     css_select("#2").should have(1).element
445   end
446
447   it "can select nested tags from rjs (two results)" do
448     render_rjs do |page|
449       page.replace_html "test", "<div id=\"1\">foo</div>"
450       page.replace_html "test2", "<div id=\"2\">foo</div>"
451     end
452     css_select("div").should have(2).elements
453     css_select("#1").should have(1).element
454     css_select("#2").should have(1).element
455   end
456   
457 end
458
459 describe "have_rjs behaviour_type", :type => :controller do
460   include AssertSelectSpecHelpers
461   controller_name :assert_select
462   integrate_views
463
464   before(:each) do
465     render_rjs do |page|
466       page.replace "test1", "<div id=\"1\">foo</div>"
467       page.replace_html "test2", "<div id=\"2\">bar</div><div id=\"3\">none</div>"
468       page.insert_html :top, "test3", "<div id=\"4\">loopy</div>"
469       page.hide "test4"
470       page["test5"].hide
471     end
472   end
473   
474   it "should pass if any rjs exists" do
475     response.should have_rjs
476   end
477   
478   it "should fail if no rjs exists" do
479     render_rjs do |page|
480     end
481     lambda do
482       response.should have_rjs
483     end.should raise_error(SpecFailed)
484   end
485   
486   it "should find all rjs from multiple statements" do
487     response.should have_rjs do
488       with_tag("#1")
489       with_tag("#2")
490       with_tag("#3")
491       # with_tag("#4")
492       # with_tag("#5")
493     end
494   end
495
496   it "should find by id" do
497     response.should have_rjs("test1") { |rjs|
498       rjs.size.should == 1
499       with_tag("div", 1)
500       with_tag("div#1", "foo")
501     }
502     
503     lambda do
504       response.should have_rjs("test1") { |rjs|
505         rjs.size.should == 1
506         without_tag("div#1", "foo")
507       }
508     end.should raise_error(SpecFailed, "should not have tag(\"div#1\", \"foo\"), but did")
509
510     response.should have_rjs("test2") { |rjs|
511       rjs.size.should == 2
512       with_tag("div", 2)
513       with_tag("div#2", "bar")
514       with_tag("div#3", "none")
515     }
516     # response.should have_rjs("test4")
517     # response.should have_rjs("test5")
518   end
519   
520   # specify "should find rjs using :hide" do
521   #   response.should have_rjs(:hide)
522   #   response.should have_rjs(:hide, "test4")
523   #   response.should have_rjs(:hide, "test5")
524   #   lambda do
525   #     response.should have_rjs(:hide, "test3")
526   #   end.should raise_error(SpecFailed)
527   # end
528
529   it "should find rjs using :replace" do
530     response.should have_rjs(:replace) { |rjs|
531       with_tag("div", 1)
532       with_tag("div#1", "foo")
533     }
534     response.should have_rjs(:replace, "test1") { |rjs|
535       with_tag("div", 1)
536       with_tag("div#1", "foo")
537     }
538     lambda {
539       response.should have_rjs(:replace, "test2")
540     }.should raise_error(SpecFailed)
541
542     lambda {
543       response.should have_rjs(:replace, "test3")
544     }.should raise_error(SpecFailed)
545   end
546
547   it "should find rjs using :replace_html" do
548     response.should have_rjs(:replace_html) { |rjs|
549       with_tag("div", 2)
550       with_tag("div#2", "bar")
551       with_tag("div#3", "none")
552     }
553
554     response.should have_rjs(:replace_html, "test2") { |rjs|
555       with_tag("div", 2)
556       with_tag("div#2", "bar")
557       with_tag("div#3", "none")
558     }
559
560     lambda {
561       response.should have_rjs(:replace_html, "test1")
562     }.should raise_error(SpecFailed)
563
564     lambda {
565       response.should have_rjs(:replace_html, "test3")
566     }.should raise_error(SpecFailed)
567   end
568     
569   it "should find rjs using :insert_html (non-positioned)" do
570     response.should have_rjs(:insert_html) { |rjs|
571       with_tag("div", 1)
572       with_tag("div#4", "loopy")
573     }
574
575     response.should have_rjs(:insert_html, "test3") { |rjs|
576       with_tag("div", 1)
577       with_tag("div#4", "loopy")
578     }
579
580     lambda {
581       response.should have_rjs(:insert_html, "test1")
582     }.should raise_error(SpecFailed)
583
584     lambda {
585       response.should have_rjs(:insert_html, "test2")
586     }.should raise_error(SpecFailed)
587   end
588
589   it "should find rjs using :insert (positioned)" do
590     render_rjs do |page|
591       page.insert_html :top, "test1", "<div id=\"1\">foo</div>"
592       page.insert_html :bottom, "test2", "<div id=\"2\">bar</div>"
593       page.insert_html :before, "test3", "<div id=\"3\">none</div>"
594       page.insert_html :after, "test4", "<div id=\"4\">loopy</div>"
595     end
596     response.should have_rjs(:insert, :top) do
597       with_tag("div", 1)
598       with_tag("#1")
599     end
600     response.should have_rjs(:insert, :top, "test1") do
601       with_tag("div", 1)
602       with_tag("#1")
603     end
604     lambda {
605       response.should have_rjs(:insert, :top, "test2")
606     }.should raise_error(SpecFailed)
607     response.should have_rjs(:insert, :bottom) {|rjs|
608       with_tag("div", 1)
609       with_tag("#2")
610     }
611     response.should have_rjs(:insert, :bottom, "test2") {|rjs|
612       with_tag("div", 1)
613       with_tag("#2")
614     }
615     response.should have_rjs(:insert, :before) {|rjs|
616       with_tag("div", 1)
617       with_tag("#3")
618     }
619     response.should have_rjs(:insert, :before, "test3") {|rjs|
620       with_tag("div", 1)
621       with_tag("#3")
622     }
623     response.should have_rjs(:insert, :after) {|rjs|
624       with_tag("div", 1)
625       with_tag("#4")
626     }
627     response.should have_rjs(:insert, :after, "test4") {|rjs|
628       with_tag("div", 1)
629       with_tag("#4")
630     }
631   end
632 end
633
634 describe "send_email behaviour_type", :type => :controller do
635   include AssertSelectSpecHelpers
636   controller_name :assert_select
637   integrate_views
638
639   before(:each) do
640     ActionMailer::Base.delivery_method = :test
641     ActionMailer::Base.perform_deliveries = true
642     ActionMailer::Base.deliveries = []
643   end
644
645   after(:each) do
646     ActionMailer::Base.deliveries.clear
647   end
648
649   it "should fail with nothing sent" do
650     response.should_not send_email
651     lambda {
652       response.should send_email{}
653     }.should raise_error(SpecFailed, /No e-mail in delivery list./)
654   end
655   
656   it "should pass otherwise" do
657     AssertSelectMailer.deliver_test "<div><p>foo</p><p>bar</p></div>"
658     response.should send_email
659     lambda {
660       response.should_not send_email
661     }.should raise_error(SpecFailed)
662     response.should send_email{}
663     response.should send_email {
664       with_tag("div:root") {
665         with_tag("p:first-child", "foo")
666         with_tag("p:last-child", "bar")
667       }
668     }
669     
670     lambda {
671       response.should_not send_email
672     }.should raise_error(SpecFailed, "should not send email, but did")
673   end
674
675 end
676
677 # describe "An rjs call to :visual_effect, a 'should have_rjs' spec with",
678 #   :type => :view do
679 #     
680 #   before do
681 #     render 'rjs_spec/visual_effect'
682 #   end
683
684 #   it "should pass with the correct element name" do
685 #     response.should have_rjs(:effect, :fade, 'mydiv')
686 #   end
687 #   
688 #   it "should fail the wrong element name" do
689 #     lambda {
690 #       response.should have_rjs(:effect, :fade, 'wrongname')
691 #     }.should raise_error(SpecFailed)
692 #   end
693 #   
694 #   it "should fail with the correct element but the wrong command" do
695 #     lambda {
696 #       response.should have_rjs(:effect, :puff, 'mydiv')
697 #     }.should raise_error(SpecFailed)
698 #   end
699 #   
700 # end
701 #   
702 # describe "An rjs call to :visual_effect for a toggle, a 'should have_rjs' spec with",
703 #   :type => :view do
704 #     
705 #   before do
706 #     render 'rjs_spec/visual_toggle_effect'
707 #   end
708 #   
709 #   it "should pass with the correct element name" do
710 #     response.should have_rjs(:effect, :toggle_blind, 'mydiv')
711 #   end
712 #   
713 #   it "should fail with the wrong element name" do
714 #     lambda {
715 #       response.should have_rjs(:effect, :toggle_blind, 'wrongname')
716 #     }.should raise_error(SpecFailed)
717 #   end
718 #   
719 #   it "should fail the correct element but the wrong command" do
720 #     lambda {
721 #       response.should have_rjs(:effect, :puff, 'mydiv')
722 #     }.should raise_error(SpecFailed)
723 #   end
724 #   
725 # end
726
727 describe "string.should have_tag", :type => :helper do
728   include AssertSelectSpecHelpers
729
730   it "should find root element" do
731     "<p>a paragraph</p>".should have_tag("p", "a paragraph")
732   end
733
734   it "should not find non-existent element" do
735     lambda do
736       "<p>a paragraph</p>".should have_tag("p", "wrong text")
737     end.should raise_error(SpecFailed)
738   end
739
740   it "should find child element" do
741     "<div><p>a paragraph</p></div>".should have_tag("p", "a paragraph")
742   end
743
744   it "should find nested element" do
745     "<div><p>a paragraph</p></div>".should have_tag("div") do
746       with_tag("p", "a paragraph")
747     end
748   end
749
750   it "should not find wrong nested element" do
751     lambda do
752       "<div><p>a paragraph</p></div>".should have_tag("div") do
753         with_tag("p", "wrong text")
754       end
755     end.should raise_error(SpecFailed)
756   end
757 end
758
759 describe "have_tag", :type => :controller do
760   include AssertSelectSpecHelpers
761   controller_name :assert_select
762   integrate_views
763
764   it "should work exactly the same as assert_select" do
765     render_html %Q{
766       <div id="wrapper">foo
767         <div class="piece">
768           <h3>Text</h3>
769         </div>
770         <div class="piece">
771           <h3>Another</h3>
772         </div>      
773       </div>
774     }
775
776     assert_select "#wrapper .piece h3", :text => "Text"
777     assert_select "#wrapper .piece h3", :text => "Another"
778
779     response.should have_tag("#wrapper .piece h3", :text => "Text")
780     response.should have_tag("#wrapper .piece h3", :text => "Another")
781   end
782 end
783
784 describe 'selecting in HTML that contains a mock with null_object' do
785   module HTML
786     class Document
787       def initialize_with_strict_error_checking(text, strict=false, xml=false)
788         initialize_without_strict_error_checking(text, true, xml)
789       end
790       alias_method :initialize_without_strict_error_checking, :initialize
791       alias_method :initialize, :initialize_with_strict_error_checking
792     end
793   end
794   
795   describe 'modified HTML::Document' do
796     it 'should raise error on valid HTML even though false is specified' do
797       lambda {HTML::Document.new("<b>#<Spec::Mocks::Mock:0x267b4f0></b>", false, false)}.should raise_error
798     end
799   end
800     
801   it 'should not print errors from assert_select' do
802     mock = mock("Dog", :null_object => true)
803     html = "<b>#{mock.colour}</b>"
804     lambda {html.should have_tag('b')}.should_not raise_error
805   end
806 end