Upgraded Rails and RSpec
[monkeycharger.git] / vendor / plugins / rspec / rspec_on_rails / lib / spec / rails / example / behaviour / render_observer.rb
blob285e8b6578a080a68a8cd469d0f22cc8d949fa4e
1 require 'spec/mocks'
3 module Spec
4   module Rails
5     module Example
6       # Provides specialized mock-like behaviour for controller and view examples,
7       # allowing you to mock or stub calls to render with specific arguments while
8       # ignoring all other calls.
9       module RenderObserver
11         # Similar to mocking +render+ with the exception that calls to +render+ with
12         # any other options are passed on to the receiver (i.e. controller in
13         # controller examples, template in view examples).
14         #
15         # This is necessary because Rails uses the +render+ method on both
16         # controllers and templates as a dispatcher to render different kinds of
17         # things, sometimes resulting in many calls to the render method within one
18         # request. This approach makes it impossible to use a normal mock object, which
19         # is designed to observe all incoming messages with a given name.
20         #
21         # +expect_render+ is auto-verifying, so failures will be reported without
22         # requiring you to explicitly request verification.
23         #
24         # Also, +expect_render+ uses parts of RSpec's mock expectation framework. Because
25         # it wraps only a subset of the framework, using this will create no conflict with
26         # other mock frameworks if you choose to use them. Additionally, the object returned
27         # by expect_render is an RSpec mock object, which means that you can call any of the
28         # chained methods available in RSpec's mocks.
29         #
30         # == Controller Examples
31         #
32         #   controller.expect_render(:partial => 'thing', :object => thing)
33         #   controller.expect_render(:partial => 'thing', :collection => things).once
34         #
35         #   controller.stub_render(:partial => 'thing', :object => thing)
36         #   controller.stub_render(:partial => 'thing', :collection => things).twice
37         #
38         # == View Examples
39         #
40         #   template.expect_render(:partial => 'thing', :object => thing)
41         #   template.expect_render(:partial => 'thing', :collection => things)
42         #
43         #   template.stub_render(:partial => 'thing', :object => thing)
44         #   template.stub_render(:partial => 'thing', :collection => things)
45         #
46         def expect_render(opts={})
47           register_verify_after_each
48           expect_render_mock_proxy.should_receive(:render, :expected_from => caller(1)[0]).with(opts)
49         end
51         # This is exactly like expect_render, with the exception that the call to render will not
52         # be verified. Use this if you are trying to isolate your example from a complicated render
53         # operation but don't care whether it is called or not.
54         def stub_render(opts={})
55           register_verify_after_each
56           expect_render_mock_proxy.stub!(:render, :expected_from => caller(1)[0]).with(opts)
57         end
58   
59         def verify_rendered # :nodoc:
60           expect_render_mock_proxy.rspec_verify
61         end
62   
63         def unregister_verify_after_each #:nodoc:
64           proc = verify_rendered_proc
65           Spec::Example::ExampleGroup.remove_after(:each, &proc)
66         end
68         protected
70         def verify_rendered_proc #:nodoc:
71           template = self
72           @verify_rendered_proc ||= Proc.new do
73             template.verify_rendered
74             template.unregister_verify_after_each
75           end
76         end
78         def register_verify_after_each #:nodoc:
79           proc = verify_rendered_proc
80           Spec::Example::ExampleGroup.after(:each, &proc)
81         end
82   
83         def expect_render_mock_proxy #:nodoc:
84           @expect_render_mock_proxy ||= Spec::Mocks::Mock.new("expect_render_mock_proxy")
85         end
86   
87       end
88     end
89   end
90 end