forked from rspec/rspec-rails
-
Notifications
You must be signed in to change notification settings - Fork 0
/
controller_example_group.rb
178 lines (164 loc) · 5.08 KB
/
controller_example_group.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
module RSpec::Rails
# Extends ActionController::TestCase::Behavior to work with RSpec.
#
# == Examples
#
# == with stubs
#
# describe WidgetsController do
# describe "GET index" do
# it "assigns all widgets to @widgets" do
# widget = stub_model(Widget)
# Widget.stub(:all) { widget }
# get :index
# assigns(:widgets).should eq([widget])
# end
# end
# end
#
# === with a factory
#
# describe WidgetsController do
# describe "GET index" do
# it "assigns all widgets to @widgets" do
# widget = Factory(:widget)
# get :index
# assigns(:widgets).should eq([widget])
# end
# end
# end
#
# === with fixtures
#
# describe WidgetsController do
# describe "GET index" do
# fixtures :widgets
#
# it "assigns all widgets to @widgets" do
# get :index
# assigns(:widgets).should eq(Widget.all)
# end
# end
# end
#
# == Matchers
#
# In addition to the stock matchers from rspec-expectations, controller
# specs add these matchers, which delegate to rails' assertions:
#
# response.should render_template(*args)
# => delegates to assert_template(*args)
#
# response.should redirect_to(destination)
# => delegates to assert_redirected_to(destination)
#
# == Isolation from views
#
# RSpec's preferred approach to spec'ing controller behaviour is to isolate
# the controller from its collaborators. By default, therefore, controller
# example groups do not render views. This means that a view template need
# not even exist in order to run a controller spec, and you can still specify
# which template the controller should render.
#
# == View rendering
#
# If you prefer a more integrated approach, similar to that of
# Rails' functional tests, you can tell controller groups to
# render views with the +render_views+ declaration:
#
# describe WidgetsController do
# render_views
# ...
#
module ControllerExampleGroup
extend ActiveSupport::Concern
extend RSpec::Rails::ModuleInclusion
include RSpec::Rails::RailsExampleGroup
include ActionController::TestCase::Behavior
include RSpec::Rails::ViewRendering
include RSpec::Rails::Matchers::RedirectTo
include RSpec::Rails::Matchers::RenderTemplate
include RSpec::Rails::Matchers::RoutingMatchers
include RSpec::Rails::BrowserSimulators
webrat do
include Webrat::Matchers
include Webrat::Methods
end
capybara do
include Capybara
end
module ClassMethods
def controller_class
describes
end
# Supports a simple DSL for specifying behaviour of
# ApplicationController. Creates an anonymous subclass of
# ApplicationController and evals the +body+ in that context. Also sets
# up implicit routes for this controller, that are separate from those
# defined in <tt>config/routes.rb</tt>.
#
# == Examples
#
# describe ApplicationController do
# controller do
# def index
# raise ApplicationController::AccessDenied
# end
# end
#
# describe "handling AccessDenied exceptions" do
# it "redirects to the /401.html page" do
# get :index
# response.should redirect_to("/401.html")
# end
# end
# end
#
# If you would like to spec a subclass of ApplicationController, call
# controller like so:
#
# controller(ApplicationControllerSubclass) do
# # ....
# end
#
# NOTICE: Due to Ruby 1.8 scoping rules in anoymous subclasses, constants
# defined in +ApplicationController+ must be fully qualified (e.g.
# ApplicationController::AccessDenied) in the block passed to the
# +controller+ method. Any instance methods, filters, etc, that are
# defined in +ApplicationController+, however, are accessible from within
# the block.
def controller(base_class = ApplicationController, &body)
metadata[:example_group][:describes] = Class.new(base_class, &body)
metadata[:example_group][:describes].singleton_class.class_eval do
def name
"StubResourcesController"
end
end
before do
@orig_routes, @routes = @routes, ActionDispatch::Routing::RouteSet.new
@routes.draw { resources :stub_resources }
end
after do
@routes = @orig_routes
end
end
end
module InstanceMethods
attr_reader :controller, :routes
end
included do
subject { controller }
metadata[:type] = :controller
before do
@routes = ::Rails.application.routes
ActionController::Base.allow_forgery_protection = false
end
webrat do
before do
Webrat.configure {|c| c.mode = :rails}
end
end
end
RSpec.configure &include_self_when_dir_matches('spec','controllers')
end
end