Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 216 lines (195 sloc) 7.351 kB
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
1 module RSpec
2 module Rails
a640902 @cupakromer Address yard warnings
cupakromer authored
3 # @private
4 ControllerAssertionDelegator = RSpec::Rails::AssertionDelegator.new(
5 ActionDispatch::Assertions::RoutingAssertions
6 )
7
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
8 # Container module for controller spec functionality.
9 module ControllerExampleGroup
10 extend ActiveSupport::Concern
11 include RSpec::Rails::RailsExampleGroup
12 include ActionController::TestCase::Behavior
13 include RSpec::Rails::ViewRendering
14 include RSpec::Rails::Matchers::RedirectTo
15 include RSpec::Rails::Matchers::RenderTemplate
16 include RSpec::Rails::Matchers::RoutingMatchers
a640902 @cupakromer Address yard warnings
cupakromer authored
17 include ControllerAssertionDelegator
d4ff873 @justinko Initial support for choosing webrat or capybara
justinko authored
18
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
19 # Class-level DSL for controller specs.
20 module ClassMethods
21 # @private
22 def controller_class
23 described_class
ac0f2d1 @alindeman Falls back to ApplicationController if cannot be inferred
alindeman authored
24 end
a2caa56 @alindeman Infer base class of anonymous controllers
alindeman authored
25
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
26 # Supports a simple DSL for specifying behavior of ApplicationController.
27 # Creates an anonymous subclass of ApplicationController and evals the
28 # `body` in that context. Also sets up implicit routes for this
29 # controller, that are separate from those defined in "config/routes.rb".
30 #
31 # @note Due to Ruby 1.8 scoping rules in anonymous subclasses, constants
32 # defined in `ApplicationController` must be fully qualified (e.g.
33 # `ApplicationController::AccessDenied`) in the block passed to the
34 # `controller` method. Any instance methods, filters, etc, that are
35 # defined in `ApplicationController`, however, are accessible from
36 # within the block.
37 #
38 # @example
39 # describe ApplicationController do
40 # controller do
41 # def index
42 # raise ApplicationController::AccessDenied
43 # end
44 # end
45 #
46 # describe "handling AccessDenied exceptions" do
47 # it "redirects to the /401.html page" do
48 # get :index
49 # response.should redirect_to("/401.html")
50 # end
51 # end
52 # end
53 #
54 # If you would like to spec a subclass of ApplicationController, call
55 # controller like so:
56 #
57 # controller(ApplicationControllerSubclass) do
58 # # ....
59 # end
60 def controller(base_class = nil, &body)
61 if RSpec.configuration.infer_base_class_for_anonymous_controllers?
62 base_class ||= controller_class
63 end
64 base_class ||= defined?(ApplicationController) ? ApplicationController : ActionController::Base
65
66 new_controller_class = Class.new(base_class) do
67 def self.name
68 root_controller = defined?(ApplicationController) ? ApplicationController : ActionController::Base
69 if superclass == root_controller || superclass.abstract?
70 "AnonymousController"
71 else
f4c3b50 @yujinakayama Fix error with inheritance of outer group's anonymous controller
yujinakayama authored
72 superclass.name
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
73 end
910993e @alindeman Small cleanups for #911
alindeman authored
74 end
4b74b1f @billychan spec and cucumber passed
billychan authored
75 end
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
76 new_controller_class.class_exec(&body)
77 (class << self; self; end).__send__(:define_method, :controller_class) { new_controller_class }
883fe01 @dchelimsky revert changes that broke controller specs
dchelimsky authored
78
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
79 before do
80 @orig_routes = routes
81 resource_name = if @controller.respond_to?(:controller_name)
82 @controller.controller_name.to_sym
83 else
84 :anonymous
85 end
86 resource_path = if @controller.respond_to?(:controller_path)
87 @controller.controller_path
88 else
89 resource_name.to_s
90 end
91 resource_module = resource_path.rpartition('/').first.presence
92 resource_as = 'anonymous_' + resource_path.tr('/', '_')
93 self.routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
94 r.draw do
95 resources resource_name,
96 :as => resource_as,
97 :module => resource_module,
98 :path => resource_path
99 end
8dd3a33 @cupakromer Fix anonymous controllers namespaced routes.
cupakromer authored
100 end
101 end
883fe01 @dchelimsky revert changes that broke controller specs
dchelimsky authored
102
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
103 after do
104 self.routes = @orig_routes
105 @orig_routes = nil
106 end
883fe01 @dchelimsky revert changes that broke controller specs
dchelimsky authored
107 end
12ce292 @alindeman Exposes a method (similar to routing specs) to set the routes in cont…
alindeman authored
108
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
109 # Specifies the routeset that will be used for the example group. This
110 # is most useful when testing Rails engines.
111 #
112 # @example
113 # describe MyEngine::PostsController do
114 # routes { MyEngine::Engine.routes }
115 #
116 # # ...
117 # end
ffea148 @davydovanton Replace &block in arguments to yield construction
davydovanton authored
118 def routes
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
119 before do
ffea148 @davydovanton Replace &block in arguments to yield construction
davydovanton authored
120 self.routes = yield
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
121 end
12ce292 @alindeman Exposes a method (similar to routing specs) to set the routes in cont…
alindeman authored
122 end
123 end
10c66e2 @dchelimsky Add controller attr_reader to controller specs
dchelimsky authored
124
cd67b84 @cupakromer Reach minimal 100% doc coverage.
cupakromer authored
125 # @!attribute [r]
126 # Returns the controller object instance under test.
127 attr_reader :controller
128
129 # @!attribute [r]
130 # Returns the Rails routes used for the spec.
131 attr_reader :routes
cdf69d0 @alindeman Allow use of URL helpers even when using anonymous controller
alindeman authored
132
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
133 # @private
134 #
135 # RSpec Rails uses this to make Rails routes easily available to specs.
136 def routes=(routes)
137 @routes = routes
138 assertion_instance.instance_variable_set(:@routes, routes)
139 end
b4b490c @alindeman Routing matchers are supported in controller specs in Rails 4
alindeman authored
140
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
141 # @private
142 module BypassRescue
143 def rescue_with_handler(exception)
144 raise exception
145 end
e373d79 @lenny Re-introduced :bypass_rescue in ControllerExampleGroup
lenny authored
146 end
147
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
148 # Extends the controller with a module that overrides
149 # `rescue_with_handler` to raise the exception passed to it. Use this to
150 # specify that an action _should_ raise an exception given appropriate
151 # conditions.
152 #
153 # @example
154 # describe ProfilesController do
155 # it "raises a 403 when a non-admin user tries to view another user's profile" do
156 # profile = create_profile
157 # login_as profile.user
158 #
159 # expect do
160 # bypass_rescue
161 # get :show, :id => profile.id + 1
162 # end.to raise_error(/403 Forbidden/)
163 # end
164 # end
165 def bypass_rescue
166 controller.extend(BypassRescue)
167 end
a550d08 @dchelimsky override method via extend (avoids warning from Ruby)
dchelimsky authored
168
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
169 # If method is a named_route, delegates to the RouteSet associated with
170 # this controller.
171 def method_missing(method, *args, &block)
759446b @joker1007 Fix controller route lookup for Rails 4.2
joker1007 authored
172 if route_available?(method)
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
173 controller.send(method, *args, &block)
174 else
175 super
176 end
cdf69d0 @alindeman Allow use of URL helpers even when using anonymous controller
alindeman authored
177 end
f25472e @dchelimsky move instance methods into InstanceMethods in modules that extend
dchelimsky authored
178
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
179 included do
180 subject { controller }
d546278 @alindeman Revert "`subject` is defined as a method rather than with the `subjec…
alindeman authored
181
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
182 before do
183 self.routes = ::Rails.application.routes
184 end
b17436f Resets ActionController::Base.allow_forgery_protection to its origina…
Mark Dimas authored
185
f6c277f @cupakromer Add Rubocop style standards to build.
cupakromer authored
186 around do |ex|
187 previous_allow_forgery_protection_value = ActionController::Base.allow_forgery_protection
188 begin
189 ActionController::Base.allow_forgery_protection = false
190 ex.call
191 ensure
192 ActionController::Base.allow_forgery_protection = previous_allow_forgery_protection_value
193 end
b17436f Resets ActionController::Base.allow_forgery_protection to its origina…
Mark Dimas authored
194 end
a6a35a6 @dchelimsky move top-level modules to RSpec::Rails namespace
dchelimsky authored
195 end
759446b @joker1007 Fix controller route lookup for Rails 4.2
joker1007 authored
196
197 private
198
199 def route_available?(method)
200 (defined?(@routes) && route_defined?(routes, method)) ||
201 (defined?(@orig_routes) && route_defined?(@orig_routes, method))
202 end
203
204 def route_defined?(routes, method)
205 return false if routes.nil?
206
207 if routes.named_routes.respond_to?(:route_defined?)
208 routes.named_routes.route_defined?(method)
209 else
210 routes.named_routes.helpers.include?(method)
211 end
212 end
d862af7 @dchelimsky include Rspec::Matchers
dchelimsky authored
213 end
a92d898 @dchelimsky clean up ControllerExampleGroupBehaviour
dchelimsky authored
214 end
15e1656 @dchelimsky prototype controller example group
dchelimsky authored
215 end
Something went wrong with that request. Please try again.