actionpack 4.2.11.3 → 5.0.7.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +890 -384
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -3
  5. data/lib/abstract_controller/base.rb +28 -38
  6. data/lib/{action_controller → abstract_controller}/caching/fragments.rb +51 -11
  7. data/lib/abstract_controller/caching.rb +62 -0
  8. data/lib/abstract_controller/callbacks.rb +54 -19
  9. data/lib/abstract_controller/collector.rb +4 -9
  10. data/lib/abstract_controller/error.rb +4 -0
  11. data/lib/abstract_controller/helpers.rb +4 -3
  12. data/lib/abstract_controller/railties/routes_helpers.rb +2 -2
  13. data/lib/abstract_controller/rendering.rb +28 -18
  14. data/lib/abstract_controller/translation.rb +8 -7
  15. data/lib/abstract_controller.rb +6 -2
  16. data/lib/action_controller/api/api_rendering.rb +14 -0
  17. data/lib/action_controller/api.rb +147 -0
  18. data/lib/action_controller/base.rb +14 -11
  19. data/lib/action_controller/caching.rb +13 -58
  20. data/lib/action_controller/form_builder.rb +48 -0
  21. data/lib/action_controller/log_subscriber.rb +3 -10
  22. data/lib/action_controller/metal/basic_implicit_render.rb +11 -0
  23. data/lib/action_controller/metal/conditional_get.rb +106 -34
  24. data/lib/action_controller/metal/cookies.rb +1 -3
  25. data/lib/action_controller/metal/data_streaming.rb +14 -34
  26. data/lib/action_controller/metal/etag_with_template_digest.rb +8 -2
  27. data/lib/action_controller/metal/exceptions.rb +11 -6
  28. data/lib/action_controller/metal/force_ssl.rb +11 -11
  29. data/lib/action_controller/metal/head.rb +14 -8
  30. data/lib/action_controller/metal/helpers.rb +15 -6
  31. data/lib/action_controller/metal/http_authentication.rb +44 -35
  32. data/lib/action_controller/metal/implicit_render.rb +61 -6
  33. data/lib/action_controller/metal/instrumentation.rb +5 -5
  34. data/lib/action_controller/metal/live.rb +71 -88
  35. data/lib/action_controller/metal/mime_responds.rb +27 -42
  36. data/lib/action_controller/metal/params_wrapper.rb +9 -9
  37. data/lib/action_controller/metal/redirecting.rb +32 -9
  38. data/lib/action_controller/metal/renderers.rb +83 -40
  39. data/lib/action_controller/metal/rendering.rb +38 -6
  40. data/lib/action_controller/metal/request_forgery_protection.rb +126 -48
  41. data/lib/action_controller/metal/rescue.rb +3 -12
  42. data/lib/action_controller/metal/streaming.rb +4 -4
  43. data/lib/action_controller/metal/strong_parameters.rb +527 -134
  44. data/lib/action_controller/metal/testing.rb +1 -12
  45. data/lib/action_controller/metal/url_for.rb +12 -5
  46. data/lib/action_controller/metal.rb +88 -63
  47. data/lib/action_controller/railtie.rb +11 -7
  48. data/lib/action_controller/renderer.rb +113 -0
  49. data/lib/action_controller/template_assertions.rb +9 -0
  50. data/lib/action_controller/test_case.rb +311 -374
  51. data/lib/action_controller.rb +12 -9
  52. data/lib/action_dispatch/http/cache.rb +73 -34
  53. data/lib/action_dispatch/http/filter_parameters.rb +16 -12
  54. data/lib/action_dispatch/http/filter_redirect.rb +7 -8
  55. data/lib/action_dispatch/http/headers.rb +45 -14
  56. data/lib/action_dispatch/http/mime_negotiation.rb +42 -23
  57. data/lib/action_dispatch/http/mime_type.rb +126 -90
  58. data/lib/action_dispatch/http/mime_types.rb +3 -4
  59. data/lib/action_dispatch/http/parameter_filter.rb +19 -9
  60. data/lib/action_dispatch/http/parameters.rb +70 -40
  61. data/lib/action_dispatch/http/request.rb +144 -89
  62. data/lib/action_dispatch/http/response.rb +215 -102
  63. data/lib/action_dispatch/http/upload.rb +6 -2
  64. data/lib/action_dispatch/http/url.rb +117 -8
  65. data/lib/action_dispatch/journey/formatter.rb +47 -30
  66. data/lib/action_dispatch/journey/gtg/transition_table.rb +1 -1
  67. data/lib/action_dispatch/journey/nfa/dot.rb +0 -2
  68. data/lib/action_dispatch/journey/nfa/transition_table.rb +1 -46
  69. data/lib/action_dispatch/journey/nodes/node.rb +14 -4
  70. data/lib/action_dispatch/journey/parser.rb +2 -0
  71. data/lib/action_dispatch/journey/parser_extras.rb +8 -2
  72. data/lib/action_dispatch/journey/path/pattern.rb +38 -42
  73. data/lib/action_dispatch/journey/route.rb +88 -26
  74. data/lib/action_dispatch/journey/router/utils.rb +5 -5
  75. data/lib/action_dispatch/journey/router.rb +8 -10
  76. data/lib/action_dispatch/journey/routes.rb +14 -15
  77. data/lib/action_dispatch/journey/visitors.rb +89 -44
  78. data/lib/action_dispatch/middleware/callbacks.rb +10 -1
  79. data/lib/action_dispatch/middleware/cookies.rb +188 -134
  80. data/lib/action_dispatch/middleware/debug_exceptions.rb +128 -49
  81. data/lib/action_dispatch/middleware/debug_locks.rb +122 -0
  82. data/lib/action_dispatch/middleware/exception_wrapper.rb +21 -21
  83. data/lib/action_dispatch/middleware/executor.rb +19 -0
  84. data/lib/action_dispatch/middleware/flash.rb +66 -45
  85. data/lib/action_dispatch/middleware/params_parser.rb +32 -46
  86. data/lib/action_dispatch/middleware/public_exceptions.rb +2 -2
  87. data/lib/action_dispatch/middleware/reloader.rb +14 -58
  88. data/lib/action_dispatch/middleware/remote_ip.rb +29 -19
  89. data/lib/action_dispatch/middleware/request_id.rb +11 -6
  90. data/lib/action_dispatch/middleware/session/abstract_store.rb +23 -11
  91. data/lib/action_dispatch/middleware/session/cache_store.rb +9 -6
  92. data/lib/action_dispatch/middleware/session/cookie_store.rb +30 -24
  93. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +4 -0
  94. data/lib/action_dispatch/middleware/show_exceptions.rb +11 -9
  95. data/lib/action_dispatch/middleware/ssl.rb +124 -36
  96. data/lib/action_dispatch/middleware/stack.rb +44 -40
  97. data/lib/action_dispatch/middleware/static.rb +51 -35
  98. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
  99. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  100. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -1
  101. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  102. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
  103. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +59 -63
  104. data/lib/action_dispatch/railtie.rb +2 -2
  105. data/lib/action_dispatch/request/session.rb +69 -33
  106. data/lib/action_dispatch/request/utils.rb +51 -19
  107. data/lib/action_dispatch/routing/inspector.rb +32 -43
  108. data/lib/action_dispatch/routing/mapper.rb +515 -348
  109. data/lib/action_dispatch/routing/polymorphic_routes.rb +8 -14
  110. data/lib/action_dispatch/routing/redirection.rb +5 -4
  111. data/lib/action_dispatch/routing/route_set.rb +148 -240
  112. data/lib/action_dispatch/routing/url_for.rb +27 -10
  113. data/lib/action_dispatch/routing.rb +17 -13
  114. data/lib/action_dispatch/testing/assertion_response.rb +45 -0
  115. data/lib/action_dispatch/testing/assertions/response.rb +38 -20
  116. data/lib/action_dispatch/testing/assertions/routing.rb +16 -12
  117. data/lib/action_dispatch/testing/assertions.rb +1 -1
  118. data/lib/action_dispatch/testing/integration.rb +377 -149
  119. data/lib/action_dispatch/testing/request_encoder.rb +53 -0
  120. data/lib/action_dispatch/testing/test_process.rb +24 -20
  121. data/lib/action_dispatch/testing/test_request.rb +22 -31
  122. data/lib/action_dispatch/testing/test_response.rb +12 -4
  123. data/lib/action_dispatch.rb +4 -1
  124. data/lib/action_pack/gem_version.rb +4 -4
  125. data/lib/action_pack.rb +1 -1
  126. metadata +32 -34
  127. data/lib/action_controller/metal/hide_actions.rb +0 -40
  128. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  129. data/lib/action_controller/middleware.rb +0 -39
  130. data/lib/action_controller/model_naming.rb +0 -12
  131. data/lib/action_dispatch/journey/backwards.rb +0 -5
  132. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  133. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  134. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  135. data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
  136. /data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
@@ -2,19 +2,8 @@ module ActionController
2
2
  module Testing
3
3
  extend ActiveSupport::Concern
4
4
 
5
- include RackDelegation
6
-
7
- # TODO : Rewrite tests using controller.headers= to use Rack env
8
- def headers=(new_headers)
9
- @_response ||= ActionDispatch::Response.new
10
- @_response.headers.replace(new_headers)
11
- end
12
-
13
5
  # Behavior specific to functional tests
14
6
  module Functional # :nodoc:
15
- def set_response!(request)
16
- end
17
-
18
7
  def recycle!
19
8
  @_url_options = nil
20
9
  self.formats = nil
@@ -24,7 +13,7 @@ module ActionController
24
13
 
25
14
  module ClassMethods
26
15
  def before_filters
27
- _process_action_callbacks.find_all{|x| x.kind == :before}.map{|x| x.name}
16
+ _process_action_callbacks.find_all{|x| x.kind == :before}.map(&:name)
28
17
  end
29
18
  end
30
19
  end
@@ -4,7 +4,10 @@ module ActionController
4
4
  #
5
5
  # In addition to <tt>AbstractController::UrlFor</tt>, this module accesses the HTTP layer to define
6
6
  # url options like the +host+. In order to do so, this module requires the host class
7
- # to implement +env+ and +request+, which need to be a Rack-compatible.
7
+ # to implement +env+ which needs to be Rack-compatible and +request+
8
+ # which is either an instance of +ActionDispatch::Request+ or an object
9
+ # that responds to the +host+, +optional_port+, +protocol+ and
10
+ # +symbolized_path_parameter+ methods.
8
11
  #
9
12
  # class RootUrl
10
13
  # include ActionController::UrlFor
@@ -30,15 +33,19 @@ module ActionController
30
33
  :_recall => request.path_parameters
31
34
  }.merge!(super).freeze
32
35
 
33
- if (same_origin = _routes.equal?(env["action_dispatch.routes".freeze])) ||
34
- (script_name = env["ROUTES_#{_routes.object_id}_SCRIPT_NAME"]) ||
35
- (original_script_name = env['ORIGINAL_SCRIPT_NAME'.freeze])
36
+ if (same_origin = _routes.equal?(request.routes)) ||
37
+ (script_name = request.engine_script_name(_routes)) ||
38
+ (original_script_name = request.original_script_name)
36
39
 
37
40
  options = @_url_options.dup
38
41
  if original_script_name
39
42
  options[:original_script_name] = original_script_name
40
43
  else
41
- options[:script_name] = same_origin ? request.script_name.dup : script_name
44
+ if same_origin
45
+ options[:script_name] = request.script_name.empty? ? "".freeze : request.script_name.dup
46
+ else
47
+ options[:script_name] = script_name
48
+ end
42
49
  end
43
50
  options.freeze
44
51
  else
@@ -1,5 +1,7 @@
1
1
  require 'active_support/core_ext/array/extract_options'
2
2
  require 'action_dispatch/middleware/stack'
3
+ require 'action_dispatch/http/request'
4
+ require 'action_dispatch/http/response'
3
5
 
4
6
  module ActionController
5
7
  # Extend ActionDispatch middleware stack to make it aware of options
@@ -11,22 +13,14 @@ module ActionController
11
13
  #
12
14
  class MiddlewareStack < ActionDispatch::MiddlewareStack #:nodoc:
13
15
  class Middleware < ActionDispatch::MiddlewareStack::Middleware #:nodoc:
14
- def initialize(klass, *args, &block)
15
- options = args.extract_options!
16
- @only = Array(options.delete(:only)).map(&:to_s)
17
- @except = Array(options.delete(:except)).map(&:to_s)
18
- args << options unless options.empty?
19
- super
16
+ def initialize(klass, args, actions, strategy, block)
17
+ @actions = actions
18
+ @strategy = strategy
19
+ super(klass, args, block)
20
20
  end
21
21
 
22
22
  def valid?(action)
23
- if @only.present?
24
- @only.include?(action)
25
- elsif @except.present?
26
- !@except.include?(action)
27
- else
28
- true
29
- end
23
+ @strategy.call @actions, action
30
24
  end
31
25
  end
32
26
 
@@ -37,6 +31,32 @@ module ActionController
37
31
  middleware.valid?(action) ? middleware.build(a) : a
38
32
  end
39
33
  end
34
+
35
+ private
36
+
37
+ INCLUDE = ->(list, action) { list.include? action }
38
+ EXCLUDE = ->(list, action) { !list.include? action }
39
+ NULL = ->(list, action) { true }
40
+
41
+ def build_middleware(klass, args, block)
42
+ options = args.extract_options!
43
+ only = Array(options.delete(:only)).map(&:to_s)
44
+ except = Array(options.delete(:except)).map(&:to_s)
45
+ args << options unless options.empty?
46
+
47
+ strategy = NULL
48
+ list = nil
49
+
50
+ if only.any?
51
+ strategy = INCLUDE
52
+ list = only
53
+ elsif except.any?
54
+ strategy = EXCLUDE
55
+ list = except
56
+ end
57
+
58
+ Middleware.new(get_class(klass), args, list, strategy, block)
59
+ end
40
60
  end
41
61
 
42
62
  # <tt>ActionController::Metal</tt> is the simplest possible controller, providing a
@@ -98,11 +118,10 @@ module ActionController
98
118
  class Metal < AbstractController::Base
99
119
  abstract!
100
120
 
101
- attr_internal_writer :env
102
-
103
121
  def env
104
- @_env ||= {}
122
+ @_request.env
105
123
  end
124
+ deprecate :env
106
125
 
107
126
  # Returns the last part of the controller's name, underscored, without the ending
108
127
  # <tt>Controller</tt>. For instance, PostsController returns <tt>posts</tt>.
@@ -114,23 +133,23 @@ module ActionController
114
133
  @controller_name ||= name.demodulize.sub(/Controller$/, '').underscore
115
134
  end
116
135
 
136
+ def self.make_response!(request)
137
+ ActionDispatch::Response.new.tap do |res|
138
+ res.request = request
139
+ end
140
+ end
141
+
117
142
  # Delegates to the class' <tt>controller_name</tt>
118
143
  def controller_name
119
144
  self.class.controller_name
120
145
  end
121
146
 
122
- # The details below can be overridden to support a specific
123
- # Request and Response object. The default ActionController::Base
124
- # implementation includes RackDelegation, which makes a request
125
- # and response object available. You might wish to control the
126
- # environment and response manually for performance reasons.
127
-
128
- attr_internal :headers, :response, :request
147
+ attr_internal :response, :request
129
148
  delegate :session, :to => "@_request"
149
+ delegate :headers, :status=, :location=, :content_type=,
150
+ :status, :location, :content_type, :to => "@_response"
130
151
 
131
152
  def initialize
132
- @_headers = {"Content-Type" => "text/html"}
133
- @_status = 200
134
153
  @_request = nil
135
154
  @_response = nil
136
155
  @_routes = nil
@@ -145,60 +164,49 @@ module ActionController
145
164
  @_params = val
146
165
  end
147
166
 
148
- # Basic implementations for content_type=, location=, and headers are
149
- # provided to reduce the dependency on the RackDelegation module
150
- # in Renderer and Redirector.
151
-
152
- def content_type=(type)
153
- headers["Content-Type"] = type.to_s
154
- end
155
-
156
- def content_type
157
- headers["Content-Type"]
158
- end
159
-
160
- def location
161
- headers["Location"]
162
- end
163
-
164
- def location=(url)
165
- headers["Location"] = url
166
- end
167
+ alias :response_code :status # :nodoc:
167
168
 
168
- # Basic url_for that can be overridden for more robust functionality
169
+ # Basic url_for that can be overridden for more robust functionality.
169
170
  def url_for(string)
170
171
  string
171
172
  end
172
173
 
173
- def status
174
- @_status
175
- end
176
- alias :response_code :status # :nodoc:
177
-
178
- def status=(status)
179
- @_status = Rack::Utils.status_code(status)
180
- end
181
-
182
174
  def response_body=(body)
183
175
  body = [body] unless body.nil? || body.respond_to?(:each)
176
+ response.reset_body!
177
+ return unless body
178
+ response.body = body
184
179
  super
185
180
  end
186
181
 
187
182
  # Tests if render or redirect has already happened.
188
183
  def performed?
189
- response_body || (response && response.committed?)
184
+ response_body || response.committed?
190
185
  end
191
186
 
192
- def dispatch(name, request) #:nodoc:
193
- @_request = request
194
- @_env = request.env
195
- @_env['action_controller.instance'] = self
187
+ def dispatch(name, request, response) #:nodoc:
188
+ set_request!(request)
189
+ set_response!(response)
196
190
  process(name)
191
+ request.commit_flash
197
192
  to_a
198
193
  end
199
194
 
195
+ def set_response!(response) # :nodoc:
196
+ @_response = response
197
+ end
198
+
199
+ def set_request!(request) #:nodoc:
200
+ @_request = request
201
+ @_request.controller_instance = self
202
+ end
203
+
200
204
  def to_a #:nodoc:
201
- response ? response.to_a : [status, headers, response_body]
205
+ response.to_a
206
+ end
207
+
208
+ def reset_session
209
+ @_request.reset_session
202
210
  end
203
211
 
204
212
  class_attribute :middleware_stack
@@ -226,15 +234,32 @@ module ActionController
226
234
  req = ActionDispatch::Request.new env
227
235
  action(req.path_parameters[:action]).call(env)
228
236
  end
237
+ class << self; deprecate :call; end
229
238
 
230
239
  # Returns a Rack endpoint for the given action name.
231
- def self.action(name, klass = ActionDispatch::Request)
240
+ def self.action(name)
232
241
  if middleware_stack.any?
233
242
  middleware_stack.build(name) do |env|
234
- new.dispatch(name, klass.new(env))
243
+ req = ActionDispatch::Request.new(env)
244
+ res = make_response! req
245
+ new.dispatch(name, req, res)
235
246
  end
236
247
  else
237
- lambda { |env| new.dispatch(name, klass.new(env)) }
248
+ lambda { |env|
249
+ req = ActionDispatch::Request.new(env)
250
+ res = make_response! req
251
+ new.dispatch(name, req, res)
252
+ }
253
+ end
254
+ end
255
+
256
+ # Direct dispatch to the controller. Instantiates the controller, then
257
+ # executes the action named +name+.
258
+ def self.dispatch(name, req, res)
259
+ if middleware_stack.any?
260
+ middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env
261
+ else
262
+ new.dispatch(name, req, res)
238
263
  end
239
264
  end
240
265
  end
@@ -22,13 +22,17 @@ module ActionController
22
22
  initializer "action_controller.parameters_config" do |app|
23
23
  options = app.config.action_controller
24
24
 
25
- ActionController::Parameters.permit_all_parameters = options.delete(:permit_all_parameters) { false }
26
- if app.config.action_controller[:always_permitted_parameters]
27
- ActionController::Parameters.always_permitted_parameters =
28
- app.config.action_controller.delete(:always_permitted_parameters)
29
- end
30
- ActionController::Parameters.action_on_unpermitted_parameters = options.delete(:action_on_unpermitted_parameters) do
31
- (Rails.env.test? || Rails.env.development?) ? :log : false
25
+ ActiveSupport.on_load(:action_controller, run_once: true) do
26
+ ActionController::Parameters.permit_all_parameters = options.delete(:permit_all_parameters) { false }
27
+ if app.config.action_controller[:always_permitted_parameters]
28
+ ActionController::Parameters.always_permitted_parameters =
29
+ app.config.action_controller.delete(:always_permitted_parameters)
30
+ end
31
+ ActionController::Parameters.raise_on_unfiltered_parameters =
32
+ options.delete(:raise_on_unfiltered_parameters) { false }
33
+ ActionController::Parameters.action_on_unpermitted_parameters = options.delete(:action_on_unpermitted_parameters) do
34
+ (Rails.env.test? || Rails.env.development?) ? :log : false
35
+ end
32
36
  end
33
37
  end
34
38
 
@@ -0,0 +1,113 @@
1
+ require 'active_support/core_ext/hash/keys'
2
+
3
+ module ActionController
4
+ # ActionController::Renderer allows to render arbitrary templates
5
+ # without requirement of being in controller actions.
6
+ #
7
+ # You get a concrete renderer class by invoking ActionController::Base#renderer.
8
+ # For example,
9
+ #
10
+ # ApplicationController.renderer
11
+ #
12
+ # It allows you to call method #render directly.
13
+ #
14
+ # ApplicationController.renderer.render template: '...'
15
+ #
16
+ # You can use this shortcut in a controller, instead of the previous example:
17
+ #
18
+ # ApplicationController.render template: '...'
19
+ #
20
+ # #render allows you to use the same options that you can use when rendering in a controller.
21
+ # For example,
22
+ #
23
+ # FooController.render :action, locals: { ... }, assigns: { ... }
24
+ #
25
+ # The template will be rendered in a Rack environment which is accessible through
26
+ # ActionController::Renderer#env. You can set it up in two ways:
27
+ #
28
+ # * by changing renderer defaults, like
29
+ #
30
+ # ApplicationController.renderer.defaults # => hash with default Rack environment
31
+ #
32
+ # * by initializing an instance of renderer by passing it a custom environment.
33
+ #
34
+ # ApplicationController.renderer.new(method: 'post', https: true)
35
+ #
36
+ class Renderer
37
+ attr_reader :defaults, :controller
38
+
39
+ DEFAULTS = {
40
+ http_host: 'example.org',
41
+ https: false,
42
+ method: 'get',
43
+ script_name: '',
44
+ input: ''
45
+ }.freeze
46
+
47
+ # Create a new renderer instance for a specific controller class.
48
+ def self.for(controller, env = {}, defaults = DEFAULTS.dup)
49
+ new(controller, env, defaults)
50
+ end
51
+
52
+ # Create a new renderer for the same controller but with a new env.
53
+ def new(env = {})
54
+ self.class.new controller, env, defaults
55
+ end
56
+
57
+ # Create a new renderer for the same controller but with new defaults.
58
+ def with_defaults(defaults)
59
+ self.class.new controller, env, self.defaults.merge(defaults)
60
+ end
61
+
62
+ # Accepts a custom Rack environment to render templates in.
63
+ # It will be merged with the default Rack environment defined by
64
+ # +ActionController::Renderer::DEFAULTS+.
65
+ def initialize(controller, env, defaults)
66
+ @controller = controller
67
+ @defaults = defaults
68
+ @env = normalize_keys defaults.merge(env)
69
+ end
70
+
71
+ # Render templates with any options from ActionController::Base#render_to_string.
72
+ def render(*args)
73
+ raise 'missing controller' unless controller
74
+
75
+ request = ActionDispatch::Request.new @env
76
+ request.routes = controller._routes
77
+
78
+ instance = controller.new
79
+ instance.set_request! request
80
+ instance.set_response! controller.make_response!(request)
81
+ instance.render_to_string(*args)
82
+ end
83
+
84
+ private
85
+ def normalize_keys(env)
86
+ new_env = {}
87
+ env.each_pair { |k,v| new_env[rack_key_for(k)] = rack_value_for(k, v) }
88
+ new_env["rack.url_scheme"] = new_env["HTTPS"] == "on" ? "https" : "http"
89
+ new_env
90
+ end
91
+
92
+ RACK_KEY_TRANSLATION = {
93
+ http_host: 'HTTP_HOST',
94
+ https: 'HTTPS',
95
+ method: 'REQUEST_METHOD',
96
+ script_name: 'SCRIPT_NAME',
97
+ input: 'rack.input'
98
+ }
99
+
100
+ IDENTITY = ->(_) { _ }
101
+
102
+ RACK_VALUE_TRANSLATION = {
103
+ https: ->(v) { v ? 'on' : 'off' },
104
+ method: ->(v) { v.upcase },
105
+ }
106
+
107
+ def rack_key_for(key); RACK_KEY_TRANSLATION[key]; end
108
+
109
+ def rack_value_for(key, value)
110
+ RACK_VALUE_TRANSLATION.fetch(key, IDENTITY).call value
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,9 @@
1
+ module ActionController
2
+ module TemplateAssertions
3
+ def assert_template(options = {}, message = nil)
4
+ raise NoMethodError,
5
+ "assert_template has been extracted to a gem. To continue using it,
6
+ add `gem 'rails-controller-testing'` to your Gemfile."
7
+ end
8
+ end
9
+ end