changelog shortlog tags changeset manifest revisions annotate raw

vendor/plugins/rspec_on_rails/lib/spec/rails/example/render_observer.rb

changeset 16: 01fd3f10ae84
author: moriq@moriq.com
date: Mon Mar 10 10:13:18 2008 +0900 (16 years ago)
permissions: -rw-r--r--
description: add plugins rspec_on_rails
1require 'spec/mocks'
2
3module 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
10
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
50
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
67
68 protected
69
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
77
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
90end