actionpack 3.2.19 → 4.2.11.3

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 (244) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +412 -503
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +11 -294
  5. data/lib/abstract_controller/asset_paths.rb +2 -2
  6. data/lib/abstract_controller/base.rb +52 -18
  7. data/lib/abstract_controller/callbacks.rb +87 -89
  8. data/lib/abstract_controller/collector.rb +17 -3
  9. data/lib/abstract_controller/helpers.rb +41 -14
  10. data/lib/abstract_controller/logger.rb +1 -2
  11. data/lib/abstract_controller/railties/routes_helpers.rb +3 -3
  12. data/lib/abstract_controller/rendering.rb +65 -118
  13. data/lib/abstract_controller/translation.rb +16 -1
  14. data/lib/abstract_controller/url_for.rb +7 -7
  15. data/lib/abstract_controller.rb +2 -10
  16. data/lib/action_controller/base.rb +61 -28
  17. data/lib/action_controller/caching/fragments.rb +30 -54
  18. data/lib/action_controller/caching.rb +38 -35
  19. data/lib/action_controller/log_subscriber.rb +35 -18
  20. data/lib/action_controller/metal/conditional_get.rb +103 -34
  21. data/lib/action_controller/metal/data_streaming.rb +20 -26
  22. data/lib/action_controller/metal/etag_with_template_digest.rb +50 -0
  23. data/lib/action_controller/metal/exceptions.rb +19 -6
  24. data/lib/action_controller/metal/flash.rb +41 -9
  25. data/lib/action_controller/metal/force_ssl.rb +70 -12
  26. data/lib/action_controller/metal/head.rb +30 -7
  27. data/lib/action_controller/metal/helpers.rb +11 -11
  28. data/lib/action_controller/metal/hide_actions.rb +0 -1
  29. data/lib/action_controller/metal/http_authentication.rb +140 -94
  30. data/lib/action_controller/metal/implicit_render.rb +1 -1
  31. data/lib/action_controller/metal/instrumentation.rb +11 -7
  32. data/lib/action_controller/metal/live.rb +328 -0
  33. data/lib/action_controller/metal/mime_responds.rb +161 -152
  34. data/lib/action_controller/metal/params_wrapper.rb +126 -81
  35. data/lib/action_controller/metal/rack_delegation.rb +10 -4
  36. data/lib/action_controller/metal/redirecting.rb +44 -41
  37. data/lib/action_controller/metal/renderers.rb +48 -19
  38. data/lib/action_controller/metal/rendering.rb +46 -11
  39. data/lib/action_controller/metal/request_forgery_protection.rb +250 -29
  40. data/lib/action_controller/metal/streaming.rb +30 -38
  41. data/lib/action_controller/metal/strong_parameters.rb +669 -0
  42. data/lib/action_controller/metal/testing.rb +12 -18
  43. data/lib/action_controller/metal/url_for.rb +31 -29
  44. data/lib/action_controller/metal.rb +31 -40
  45. data/lib/action_controller/model_naming.rb +12 -0
  46. data/lib/action_controller/railtie.rb +38 -18
  47. data/lib/action_controller/railties/helpers.rb +22 -0
  48. data/lib/action_controller/test_case.rb +359 -173
  49. data/lib/action_controller.rb +9 -16
  50. data/lib/action_dispatch/http/cache.rb +64 -11
  51. data/lib/action_dispatch/http/filter_parameters.rb +20 -10
  52. data/lib/action_dispatch/http/filter_redirect.rb +38 -0
  53. data/lib/action_dispatch/http/headers.rb +85 -17
  54. data/lib/action_dispatch/http/mime_negotiation.rb +55 -5
  55. data/lib/action_dispatch/http/mime_type.rb +167 -114
  56. data/lib/action_dispatch/http/mime_types.rb +2 -1
  57. data/lib/action_dispatch/http/parameter_filter.rb +44 -46
  58. data/lib/action_dispatch/http/parameters.rb +30 -46
  59. data/lib/action_dispatch/http/rack_cache.rb +2 -3
  60. data/lib/action_dispatch/http/request.rb +108 -45
  61. data/lib/action_dispatch/http/response.rb +247 -48
  62. data/lib/action_dispatch/http/upload.rb +60 -29
  63. data/lib/action_dispatch/http/url.rb +135 -45
  64. data/lib/action_dispatch/journey/backwards.rb +5 -0
  65. data/lib/action_dispatch/journey/formatter.rb +166 -0
  66. data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
  67. data/lib/action_dispatch/journey/gtg/simulator.rb +47 -0
  68. data/lib/action_dispatch/journey/gtg/transition_table.rb +157 -0
  69. data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
  70. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  71. data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
  72. data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
  73. data/lib/action_dispatch/journey/nodes/node.rb +128 -0
  74. data/lib/action_dispatch/journey/parser.rb +198 -0
  75. data/lib/action_dispatch/journey/parser.y +49 -0
  76. data/lib/action_dispatch/journey/parser_extras.rb +23 -0
  77. data/lib/action_dispatch/journey/path/pattern.rb +193 -0
  78. data/lib/action_dispatch/journey/route.rb +125 -0
  79. data/lib/action_dispatch/journey/router/strexp.rb +27 -0
  80. data/lib/action_dispatch/journey/router/utils.rb +93 -0
  81. data/lib/action_dispatch/journey/router.rb +144 -0
  82. data/lib/action_dispatch/journey/routes.rb +80 -0
  83. data/lib/action_dispatch/journey/scanner.rb +61 -0
  84. data/lib/action_dispatch/journey/visitors.rb +221 -0
  85. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  86. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  87. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  88. data/lib/action_dispatch/journey.rb +5 -0
  89. data/lib/action_dispatch/middleware/callbacks.rb +16 -11
  90. data/lib/action_dispatch/middleware/cookies.rb +346 -125
  91. data/lib/action_dispatch/middleware/debug_exceptions.rb +52 -24
  92. data/lib/action_dispatch/middleware/exception_wrapper.rb +75 -9
  93. data/lib/action_dispatch/middleware/flash.rb +85 -72
  94. data/lib/action_dispatch/middleware/params_parser.rb +16 -31
  95. data/lib/action_dispatch/middleware/public_exceptions.rb +39 -14
  96. data/lib/action_dispatch/middleware/reloader.rb +16 -7
  97. data/lib/action_dispatch/middleware/remote_ip.rb +132 -40
  98. data/lib/action_dispatch/middleware/request_id.rb +3 -7
  99. data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
  100. data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
  101. data/lib/action_dispatch/middleware/session/cookie_store.rb +84 -29
  102. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
  103. data/lib/action_dispatch/middleware/show_exceptions.rb +15 -44
  104. data/lib/action_dispatch/middleware/ssl.rb +72 -0
  105. data/lib/action_dispatch/middleware/stack.rb +6 -1
  106. data/lib/action_dispatch/middleware/static.rb +80 -23
  107. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +34 -0
  108. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  109. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +27 -0
  110. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
  111. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  112. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +16 -0
  113. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  114. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +133 -5
  115. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  116. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  117. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  121. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  122. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  123. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  124. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +200 -0
  125. data/lib/action_dispatch/railtie.rb +19 -6
  126. data/lib/action_dispatch/request/session.rb +193 -0
  127. data/lib/action_dispatch/request/utils.rb +35 -0
  128. data/lib/action_dispatch/routing/endpoint.rb +10 -0
  129. data/lib/action_dispatch/routing/inspector.rb +234 -0
  130. data/lib/action_dispatch/routing/mapper.rb +897 -436
  131. data/lib/action_dispatch/routing/polymorphic_routes.rb +213 -92
  132. data/lib/action_dispatch/routing/redirection.rb +97 -37
  133. data/lib/action_dispatch/routing/route_set.rb +432 -239
  134. data/lib/action_dispatch/routing/routes_proxy.rb +7 -4
  135. data/lib/action_dispatch/routing/url_for.rb +63 -34
  136. data/lib/action_dispatch/routing.rb +57 -89
  137. data/lib/action_dispatch/testing/assertions/dom.rb +2 -36
  138. data/lib/action_dispatch/testing/assertions/response.rb +24 -38
  139. data/lib/action_dispatch/testing/assertions/routing.rb +55 -54
  140. data/lib/action_dispatch/testing/assertions/selector.rb +2 -434
  141. data/lib/action_dispatch/testing/assertions/tag.rb +2 -137
  142. data/lib/action_dispatch/testing/assertions.rb +11 -7
  143. data/lib/action_dispatch/testing/integration.rb +88 -72
  144. data/lib/action_dispatch/testing/test_process.rb +9 -6
  145. data/lib/action_dispatch/testing/test_request.rb +13 -9
  146. data/lib/action_dispatch/testing/test_response.rb +1 -5
  147. data/lib/action_dispatch.rb +24 -21
  148. data/lib/action_pack/gem_version.rb +15 -0
  149. data/lib/action_pack/version.rb +5 -7
  150. data/lib/action_pack.rb +1 -1
  151. metadata +181 -292
  152. data/lib/abstract_controller/layouts.rb +0 -423
  153. data/lib/abstract_controller/view_paths.rb +0 -96
  154. data/lib/action_controller/caching/actions.rb +0 -185
  155. data/lib/action_controller/caching/pages.rb +0 -187
  156. data/lib/action_controller/caching/sweeping.rb +0 -97
  157. data/lib/action_controller/deprecated/integration_test.rb +0 -2
  158. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  159. data/lib/action_controller/deprecated.rb +0 -3
  160. data/lib/action_controller/metal/compatibility.rb +0 -65
  161. data/lib/action_controller/metal/responder.rb +0 -286
  162. data/lib/action_controller/metal/session_management.rb +0 -14
  163. data/lib/action_controller/railties/paths.rb +0 -25
  164. data/lib/action_controller/record_identifier.rb +0 -85
  165. data/lib/action_controller/vendor/html-scanner/html/document.rb +0 -68
  166. data/lib/action_controller/vendor/html-scanner/html/node.rb +0 -532
  167. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +0 -177
  168. data/lib/action_controller/vendor/html-scanner/html/selector.rb +0 -830
  169. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +0 -107
  170. data/lib/action_controller/vendor/html-scanner/html/version.rb +0 -11
  171. data/lib/action_controller/vendor/html-scanner.rb +0 -20
  172. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  173. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  174. data/lib/action_dispatch/middleware/head.rb +0 -18
  175. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  176. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +0 -31
  177. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -26
  178. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +0 -10
  179. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -2
  180. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +0 -15
  181. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -17
  182. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +0 -2
  183. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  184. data/lib/action_view/asset_paths.rb +0 -142
  185. data/lib/action_view/base.rb +0 -220
  186. data/lib/action_view/buffers.rb +0 -43
  187. data/lib/action_view/context.rb +0 -36
  188. data/lib/action_view/flows.rb +0 -79
  189. data/lib/action_view/helpers/active_model_helper.rb +0 -50
  190. data/lib/action_view/helpers/asset_paths.rb +0 -7
  191. data/lib/action_view/helpers/asset_tag_helper.rb +0 -457
  192. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  193. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  194. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  195. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  196. data/lib/action_view/helpers/atom_feed_helper.rb +0 -200
  197. data/lib/action_view/helpers/cache_helper.rb +0 -64
  198. data/lib/action_view/helpers/capture_helper.rb +0 -203
  199. data/lib/action_view/helpers/controller_helper.rb +0 -25
  200. data/lib/action_view/helpers/csrf_helper.rb +0 -32
  201. data/lib/action_view/helpers/date_helper.rb +0 -1062
  202. data/lib/action_view/helpers/debug_helper.rb +0 -40
  203. data/lib/action_view/helpers/form_helper.rb +0 -1486
  204. data/lib/action_view/helpers/form_options_helper.rb +0 -658
  205. data/lib/action_view/helpers/form_tag_helper.rb +0 -685
  206. data/lib/action_view/helpers/javascript_helper.rb +0 -110
  207. data/lib/action_view/helpers/number_helper.rb +0 -622
  208. data/lib/action_view/helpers/output_safety_helper.rb +0 -38
  209. data/lib/action_view/helpers/record_tag_helper.rb +0 -111
  210. data/lib/action_view/helpers/rendering_helper.rb +0 -90
  211. data/lib/action_view/helpers/sanitize_helper.rb +0 -259
  212. data/lib/action_view/helpers/tag_helper.rb +0 -160
  213. data/lib/action_view/helpers/text_helper.rb +0 -426
  214. data/lib/action_view/helpers/translation_helper.rb +0 -91
  215. data/lib/action_view/helpers/url_helper.rb +0 -693
  216. data/lib/action_view/helpers.rb +0 -60
  217. data/lib/action_view/locale/en.yml +0 -160
  218. data/lib/action_view/log_subscriber.rb +0 -28
  219. data/lib/action_view/lookup_context.rb +0 -254
  220. data/lib/action_view/path_set.rb +0 -89
  221. data/lib/action_view/railtie.rb +0 -55
  222. data/lib/action_view/renderer/abstract_renderer.rb +0 -41
  223. data/lib/action_view/renderer/partial_renderer.rb +0 -415
  224. data/lib/action_view/renderer/renderer.rb +0 -54
  225. data/lib/action_view/renderer/streaming_template_renderer.rb +0 -106
  226. data/lib/action_view/renderer/template_renderer.rb +0 -94
  227. data/lib/action_view/template/error.rb +0 -128
  228. data/lib/action_view/template/handlers/builder.rb +0 -26
  229. data/lib/action_view/template/handlers/erb.rb +0 -125
  230. data/lib/action_view/template/handlers.rb +0 -50
  231. data/lib/action_view/template/resolver.rb +0 -272
  232. data/lib/action_view/template/text.rb +0 -30
  233. data/lib/action_view/template.rb +0 -337
  234. data/lib/action_view/test_case.rb +0 -245
  235. data/lib/action_view/testing/resolvers.rb +0 -50
  236. data/lib/action_view.rb +0 -84
  237. data/lib/sprockets/assets.rake +0 -99
  238. data/lib/sprockets/bootstrap.rb +0 -37
  239. data/lib/sprockets/compressors.rb +0 -83
  240. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  241. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  242. data/lib/sprockets/helpers.rb +0 -6
  243. data/lib/sprockets/railtie.rb +0 -62
  244. data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,8 +1,10 @@
1
1
  require 'rack/session/abstract/id'
2
- require 'active_support/core_ext/object/blank'
3
2
  require 'active_support/core_ext/object/to_query'
4
- require 'active_support/core_ext/class/attribute'
5
3
  require 'active_support/core_ext/module/anonymous'
4
+ require 'active_support/core_ext/hash/keys'
5
+ require 'active_support/deprecation'
6
+
7
+ require 'rails-dom-testing'
6
8
 
7
9
  module ActionController
8
10
  module TemplateAssertions
@@ -13,142 +15,189 @@ module ActionController
13
15
  teardown :teardown_subscriptions
14
16
  end
15
17
 
18
+ RENDER_TEMPLATE_INSTANCE_VARIABLES = %w{partials templates layouts files}.freeze
19
+
16
20
  def setup_subscriptions
17
- @partials = Hash.new(0)
18
- @templates = Hash.new(0)
19
- @layouts = Hash.new(0)
21
+ RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
22
+ instance_variable_set("@_#{instance_variable}", Hash.new(0))
23
+ end
24
+
25
+ @_subscribers = []
20
26
 
21
- ActiveSupport::Notifications.subscribe("render_template.action_view") do |name, start, finish, id, payload|
27
+ @_subscribers << ActiveSupport::Notifications.subscribe("render_template.action_view") do |_name, _start, _finish, _id, payload|
22
28
  path = payload[:layout]
23
29
  if path
24
- @layouts[path] += 1
30
+ @_layouts[path] += 1
25
31
  if path =~ /^layouts\/(.*)/
26
- @layouts[$1] += 1
32
+ @_layouts[$1] += 1
27
33
  end
28
34
  end
29
35
  end
30
36
 
31
- ActiveSupport::Notifications.subscribe("!render_template.action_view") do |name, start, finish, id, payload|
32
- path = payload[:virtual_path]
33
- next unless path
34
- partial = path =~ /^.*\/_[^\/]*$/
35
- if partial
36
- @partials[path] += 1
37
- @partials[path.split("/").last] += 1
38
- @templates[path] += 1
37
+ @_subscribers << ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload|
38
+ if virtual_path = payload[:virtual_path]
39
+ partial = virtual_path =~ /^.*\/_[^\/]*$/
40
+
41
+ if partial
42
+ @_partials[virtual_path] += 1
43
+ @_partials[virtual_path.split("/").last] += 1
44
+ end
45
+
46
+ @_templates[virtual_path] += 1
39
47
  else
40
- @templates[path] += 1
48
+ path = payload[:identifier]
49
+ if path
50
+ @_files[path] += 1
51
+ @_files[path.split("/").last] += 1
52
+ end
41
53
  end
42
54
  end
43
55
  end
44
56
 
45
57
  def teardown_subscriptions
46
- ActiveSupport::Notifications.unsubscribe("render_template.action_view")
47
- ActiveSupport::Notifications.unsubscribe("!render_template.action_view")
58
+ return unless defined?(@_subscribers)
59
+
60
+ @_subscribers.each do |subscriber|
61
+ ActiveSupport::Notifications.unsubscribe(subscriber)
62
+ end
48
63
  end
49
64
 
50
65
  def process(*args)
51
- @partials = Hash.new(0)
52
- @templates = Hash.new(0)
53
- @layouts = Hash.new(0)
66
+ reset_template_assertion
54
67
  super
55
68
  end
56
69
 
70
+ def reset_template_assertion
71
+ RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
72
+ ivar_name = "@_#{instance_variable}"
73
+ if instance_variable_defined?(ivar_name)
74
+ instance_variable_get(ivar_name).clear
75
+ end
76
+ end
77
+ end
78
+
57
79
  # Asserts that the request was rendered with the appropriate template file or partials.
58
80
  #
59
- # ==== Examples
60
- #
61
81
  # # assert that the "new" view template was rendered
62
82
  # assert_template "new"
63
83
  #
84
+ # # assert that the exact template "admin/posts/new" was rendered
85
+ # assert_template %r{\Aadmin/posts/new\Z}
86
+ #
64
87
  # # assert that the layout 'admin' was rendered
65
- # assert_template :layout => 'admin'
66
- # assert_template :layout => 'layouts/admin'
67
- # assert_template :layout => :admin
88
+ # assert_template layout: 'admin'
89
+ # assert_template layout: 'layouts/admin'
90
+ # assert_template layout: :admin
68
91
  #
69
92
  # # assert that no layout was rendered
70
- # assert_template :layout => nil
71
- # assert_template :layout => false
93
+ # assert_template layout: nil
94
+ # assert_template layout: false
72
95
  #
73
96
  # # assert that the "_customer" partial was rendered twice
74
- # assert_template :partial => '_customer', :count => 2
97
+ # assert_template partial: '_customer', count: 2
75
98
  #
76
99
  # # assert that no partials were rendered
77
- # assert_template :partial => false
100
+ # assert_template partial: false
101
+ #
102
+ # # assert that a file was rendered
103
+ # assert_template file: "README.rdoc"
104
+ #
105
+ # # assert that no file was rendered
106
+ # assert_template file: nil
107
+ # assert_template file: false
78
108
  #
79
109
  # In a view test case, you can also assert that specific locals are passed
80
110
  # to partials:
81
111
  #
82
112
  # # assert that the "_customer" partial was rendered with a specific object
83
- # assert_template :partial => '_customer', :locals => { :customer => @customer }
84
- #
113
+ # assert_template partial: '_customer', locals: { customer: @customer }
85
114
  def assert_template(options = {}, message = nil)
86
- validate_request!
87
- # Force body to be read in case the template is being streamed
115
+ # Force body to be read in case the template is being streamed.
88
116
  response.body
89
117
 
90
118
  case options
91
- when NilClass, String, Symbol
119
+ when NilClass, Regexp, String, Symbol
92
120
  options = options.to_s if Symbol === options
93
- rendered = @templates
94
- msg = build_message(message,
95
- "expecting <?> but rendering with <?>",
96
- options, rendered.keys.join(', '))
97
- assert_block(msg) do
98
- if options
121
+ rendered = @_templates
122
+ msg = message || sprintf("expecting <%s> but rendering with <%s>",
123
+ options.inspect, rendered.keys)
124
+ matches_template =
125
+ case options
126
+ when String
127
+ !options.empty? && rendered.any? do |t, num|
128
+ options_splited = options.split(File::SEPARATOR)
129
+ t_splited = t.split(File::SEPARATOR)
130
+ t_splited.last(options_splited.size) == options_splited
131
+ end
132
+ when Regexp
99
133
  rendered.any? { |t,num| t.match(options) }
100
- else
101
- @templates.blank?
134
+ when NilClass
135
+ rendered.blank?
102
136
  end
103
- end
137
+ assert matches_template, msg
104
138
  when Hash
139
+ options.assert_valid_keys(:layout, :partial, :locals, :count, :file)
140
+
105
141
  if options.key?(:layout)
106
142
  expected_layout = options[:layout]
107
- msg = build_message(message,
108
- "expecting layout <?> but action rendered <?>",
109
- expected_layout, @layouts.keys)
143
+ msg = message || sprintf("expecting layout <%s> but action rendered <%s>",
144
+ expected_layout, @_layouts.keys)
110
145
 
111
146
  case expected_layout
112
147
  when String, Symbol
113
- assert(@layouts.keys.include?(expected_layout.to_s), msg)
148
+ assert_includes @_layouts.keys, expected_layout.to_s, msg
114
149
  when Regexp
115
- assert(@layouts.keys.any? {|l| l =~ expected_layout }, msg)
150
+ assert(@_layouts.keys.any? {|l| l =~ expected_layout }, msg)
116
151
  when nil, false
117
- assert(@layouts.empty?, msg)
152
+ assert(@_layouts.empty?, msg)
118
153
  end
119
154
  end
120
155
 
156
+ if options[:file]
157
+ assert_includes @_files.keys, options[:file]
158
+ elsif options.key?(:file)
159
+ assert @_files.blank?, "expected no files but #{@_files.keys} was rendered"
160
+ end
161
+
121
162
  if expected_partial = options[:partial]
122
163
  if expected_locals = options[:locals]
123
- if defined?(@locals)
124
- actual_locals = @locals[expected_partial.to_s.sub(/^_/,'')]
125
- expected_locals.each_pair do |k,v|
126
- assert_equal(v, actual_locals[k])
127
- end
164
+ if defined?(@_rendered_views)
165
+ view = expected_partial.to_s.sub(/^_/, '').sub(/\/_(?=[^\/]+\z)/, '/')
166
+
167
+ partial_was_not_rendered_msg = "expected %s to be rendered but it was not." % view
168
+ assert_includes @_rendered_views.rendered_views, view, partial_was_not_rendered_msg
169
+
170
+ msg = 'expecting %s to be rendered with %s but was with %s' % [expected_partial,
171
+ expected_locals,
172
+ @_rendered_views.locals_for(view)]
173
+ assert(@_rendered_views.view_rendered?(view, options[:locals]), msg)
128
174
  else
129
175
  warn "the :locals option to #assert_template is only supported in a ActionView::TestCase"
130
176
  end
131
177
  elsif expected_count = options[:count]
132
- actual_count = @partials[expected_partial]
133
- msg = build_message(message,
134
- "expecting ? to be rendered ? time(s) but rendered ? time(s)",
178
+ actual_count = @_partials[expected_partial]
179
+ msg = message || sprintf("expecting %s to be rendered %s time(s) but rendered %s time(s)",
135
180
  expected_partial, expected_count, actual_count)
136
181
  assert(actual_count == expected_count.to_i, msg)
137
182
  else
138
- msg = build_message(message,
139
- "expecting partial <?> but action rendered <?>",
140
- options[:partial], @partials.keys)
141
- assert(@partials.include?(expected_partial), msg)
183
+ msg = message || sprintf("expecting partial <%s> but action rendered <%s>",
184
+ options[:partial], @_partials.keys)
185
+ assert_includes @_partials, expected_partial, msg
142
186
  end
143
187
  elsif options.key?(:partial)
144
- assert @partials.empty?,
188
+ assert @_partials.empty?,
145
189
  "Expected no partials to be rendered"
146
190
  end
191
+ else
192
+ raise ArgumentError, "assert_template only accepts a String, Symbol, Hash, Regexp, or nil"
147
193
  end
148
194
  end
149
195
  end
150
196
 
151
197
  class TestRequest < ActionDispatch::TestRequest #:nodoc:
198
+ DEFAULT_ENV = ActionDispatch::TestRequest::DEFAULT_ENV.dup
199
+ DEFAULT_ENV.delete 'PATH_INFO'
200
+
152
201
  def initialize(env = {})
153
202
  super
154
203
 
@@ -156,13 +205,6 @@ module ActionController
156
205
  self.session_options = TestSession::DEFAULT_OPTIONS.merge(:id => SecureRandom.hex(16))
157
206
  end
158
207
 
159
- class Result < ::Array #:nodoc:
160
- def to_s() join '/' end
161
- def self.new_escaped(strings)
162
- new strings.collect {|str| uri_parser.unescape str}
163
- end
164
- end
165
-
166
208
  def assign_parameters(routes, controller_path, action, parameters = {})
167
209
  parameters = parameters.symbolize_keys.merge(:controller => controller_path, :action => action)
168
210
  extra_keys = routes.extra_keys(parameters)
@@ -176,22 +218,25 @@ module ActionController
176
218
  value = value.dup
177
219
  end
178
220
 
179
- if extra_keys.include?(key.to_sym)
221
+ if extra_keys.include?(key)
180
222
  non_path_parameters[key] = value
181
223
  else
182
224
  if value.is_a?(Array)
183
- value = Result.new(value.map(&:to_param))
225
+ value = value.map(&:to_param)
184
226
  else
185
227
  value = value.to_param
186
228
  end
187
229
 
188
- path_parameters[key.to_s] = value
230
+ path_parameters[key] = value
189
231
  end
190
232
  end
191
233
 
192
234
  # Clear the combined params hash in case it was already referenced.
193
235
  @env.delete("action_dispatch.request.parameters")
194
236
 
237
+ # Clear the filter cache variables so they're not stale
238
+ @filtered_parameters = @filtered_env = @filtered_path = nil
239
+
195
240
  params = self.request_parameters.dup
196
241
  %w(controller action only_path).each do |k|
197
242
  params.delete(k)
@@ -207,7 +252,6 @@ module ActionController
207
252
  @formats = nil
208
253
  @env.delete_if { |k, v| k =~ /^(action_dispatch|rack)\.request/ }
209
254
  @env.delete_if { |k, v| k =~ /^action_dispatch\.rescue/ }
210
- @symbolized_path_params = nil
211
255
  @method = @request_method = nil
212
256
  @fullpath = @ip = @remote_ip = @protocol = nil
213
257
  @env['action_dispatch.request.query_parameters'] = {}
@@ -220,33 +264,80 @@ module ActionController
220
264
  cookie_jar.update(@set_cookies)
221
265
  cookie_jar.recycle!
222
266
  end
267
+
268
+ private
269
+
270
+ def default_env
271
+ DEFAULT_ENV
272
+ end
223
273
  end
224
274
 
225
275
  class TestResponse < ActionDispatch::TestResponse
226
276
  def recycle!
227
- @status = 200
228
- @header = {}
229
- @writer = lambda { |x| @body << x }
230
- @block = nil
231
- @length = 0
232
- @body = []
233
- @charset = @content_type = nil
234
- @request = @template = nil
277
+ initialize
235
278
  end
236
279
  end
237
280
 
281
+ class LiveTestResponse < Live::Response
282
+ def recycle!
283
+ @body = nil
284
+ initialize
285
+ end
286
+
287
+ def body
288
+ @body ||= super
289
+ end
290
+
291
+ # Was the response successful?
292
+ alias_method :success?, :successful?
293
+
294
+ # Was the URL not found?
295
+ alias_method :missing?, :not_found?
296
+
297
+ # Were we redirected?
298
+ alias_method :redirect?, :redirection?
299
+
300
+ # Was there a server-side error?
301
+ alias_method :error?, :server_error?
302
+ end
303
+
304
+ # Methods #destroy and #load! are overridden to avoid calling methods on the
305
+ # @store object, which does not exist for the TestSession class.
238
306
  class TestSession < Rack::Session::Abstract::SessionHash #:nodoc:
239
307
  DEFAULT_OPTIONS = Rack::Session::Abstract::ID::DEFAULT_OPTIONS
240
308
 
241
309
  def initialize(session = {})
242
310
  super(nil, nil)
243
- replace(session.stringify_keys)
311
+ @id = SecureRandom.hex(16)
312
+ @data = stringify_keys(session)
244
313
  @loaded = true
245
314
  end
246
315
 
247
316
  def exists?
248
317
  true
249
318
  end
319
+
320
+ def keys
321
+ @data.keys
322
+ end
323
+
324
+ def values
325
+ @data.values
326
+ end
327
+
328
+ def destroy
329
+ clear
330
+ end
331
+
332
+ def fetch(key, *args, &block)
333
+ @data.fetch(key.to_s, *args, &block)
334
+ end
335
+
336
+ private
337
+
338
+ def load!
339
+ @id
340
+ end
250
341
  end
251
342
 
252
343
  # Superclass for ActionController functional tests. Functional tests allow you to
@@ -258,7 +349,7 @@ module ActionController
258
349
  # == Basic example
259
350
  #
260
351
  # Functional tests are written as follows:
261
- # 1. First, one uses the +get+, +post+, +put+, +delete+ or +head+ method to simulate
352
+ # 1. First, one uses the +get+, +post+, +patch+, +put+, +delete+ or +head+ method to simulate
262
353
  # an HTTP request.
263
354
  # 2. Then, one asserts whether the current state is as expected. "State" can be anything:
264
355
  # the controller's HTTP response, the database contents, etc.
@@ -268,17 +359,24 @@ module ActionController
268
359
  # class BooksControllerTest < ActionController::TestCase
269
360
  # def test_create
270
361
  # # Simulate a POST response with the given HTTP parameters.
271
- # post(:create, :book => { :title => "Love Hina" })
362
+ # post(:create, book: { title: "Love Hina" })
272
363
  #
273
364
  # # Assert that the controller tried to redirect us to
274
365
  # # the created book's URI.
275
366
  # assert_response :found
276
367
  #
277
368
  # # Assert that the controller really put the book in the database.
278
- # assert_not_nil Book.find_by_title("Love Hina")
369
+ # assert_not_nil Book.find_by(title: "Love Hina")
279
370
  # end
280
371
  # end
281
372
  #
373
+ # You can also send a real document in the simulated HTTP request.
374
+ #
375
+ # def test_create
376
+ # json = {book: { title: "Love Hina" }}.to_json
377
+ # post :create, json
378
+ # end
379
+ #
282
380
  # == Special instance variables
283
381
  #
284
382
  # ActionController::TestCase will also automatically provide the following instance
@@ -349,29 +447,29 @@ module ActionController
349
447
  # == \Testing named routes
350
448
  #
351
449
  # If you're using named routes, they can be easily tested using the original named routes' methods straight in the test case.
352
- # Example:
353
450
  #
354
- # assert_redirected_to page_url(:title => 'foo')
451
+ # assert_redirected_to page_url(title: 'foo')
355
452
  class TestCase < ActiveSupport::TestCase
356
453
  module Behavior
357
454
  extend ActiveSupport::Concern
358
455
  include ActionDispatch::TestProcess
456
+ include ActiveSupport::Testing::ConstantLookup
457
+ include Rails::Dom::Testing::Assertions
359
458
 
360
459
  attr_reader :response, :request
361
460
 
362
461
  module ClassMethods
363
462
 
364
463
  # Sets the controller class name. Useful if the name can't be inferred from test class.
365
- # Normalizes +controller_class+ before using. Examples:
464
+ # Normalizes +controller_class+ before using.
366
465
  #
367
466
  # tests WidgetController
368
467
  # tests :widget
369
468
  # tests 'widget'
370
- #
371
469
  def tests(controller_class)
372
470
  case controller_class
373
471
  when String, Symbol
374
- self.controller_class = "#{controller_class.to_s.underscore}_controller".camelize.constantize
472
+ self.controller_class = "#{controller_class.to_s.camelize}Controller".constantize
375
473
  when Class
376
474
  self.controller_class = controller_class
377
475
  else
@@ -380,7 +478,6 @@ module ActionController
380
478
  end
381
479
 
382
480
  def controller_class=(new_class)
383
- prepare_controller_class(new_class) if new_class
384
481
  self._controller_class = new_class
385
482
  end
386
483
 
@@ -393,38 +490,58 @@ module ActionController
393
490
  end
394
491
 
395
492
  def determine_default_controller_class(name)
396
- name.sub(/Test$/, '').safe_constantize
397
- end
398
-
399
- def prepare_controller_class(new_class)
400
- new_class.send :include, ActionController::TestCase::RaiseActionExceptions
493
+ determine_constant_from_test_name(name) do |constant|
494
+ Class === constant && constant < ActionController::Metal
495
+ end
401
496
  end
497
+ end
402
498
 
499
+ # Simulate a GET request with the given parameters.
500
+ #
501
+ # - +action+: The controller action to call.
502
+ # - +parameters+: The HTTP parameters that you want to pass. This may
503
+ # be +nil+, a hash, or a string that is appropriately encoded
504
+ # (<tt>application/x-www-form-urlencoded</tt> or <tt>multipart/form-data</tt>).
505
+ # - +session+: A hash of parameters to store in the session. This may be +nil+.
506
+ # - +flash+: A hash of parameters to store in the flash. This may be +nil+.
507
+ #
508
+ # You can also simulate POST, PATCH, PUT, DELETE, and HEAD requests with
509
+ # +post+, +patch+, +put+, +delete+, and +head+.
510
+ #
511
+ # Note that the request method is not verified. The different methods are
512
+ # available to make the tests more expressive.
513
+ def get(action, *args)
514
+ process(action, "GET", *args)
403
515
  end
404
516
 
405
- # Executes a request simulating GET HTTP method and set/volley the response
406
- def get(action, parameters = nil, session = nil, flash = nil)
407
- process(action, parameters, session, flash, "GET")
517
+ # Simulate a POST request with the given parameters and set/volley the response.
518
+ # See +get+ for more details.
519
+ def post(action, *args)
520
+ process(action, "POST", *args)
408
521
  end
409
522
 
410
- # Executes a request simulating POST HTTP method and set/volley the response
411
- def post(action, parameters = nil, session = nil, flash = nil)
412
- process(action, parameters, session, flash, "POST")
523
+ # Simulate a PATCH request with the given parameters and set/volley the response.
524
+ # See +get+ for more details.
525
+ def patch(action, *args)
526
+ process(action, "PATCH", *args)
413
527
  end
414
528
 
415
- # Executes a request simulating PUT HTTP method and set/volley the response
416
- def put(action, parameters = nil, session = nil, flash = nil)
417
- process(action, parameters, session, flash, "PUT")
529
+ # Simulate a PUT request with the given parameters and set/volley the response.
530
+ # See +get+ for more details.
531
+ def put(action, *args)
532
+ process(action, "PUT", *args)
418
533
  end
419
534
 
420
- # Executes a request simulating DELETE HTTP method and set/volley the response
421
- def delete(action, parameters = nil, session = nil, flash = nil)
422
- process(action, parameters, session, flash, "DELETE")
535
+ # Simulate a DELETE request with the given parameters and set/volley the response.
536
+ # See +get+ for more details.
537
+ def delete(action, *args)
538
+ process(action, "DELETE", *args)
423
539
  end
424
540
 
425
- # Executes a request simulating HEAD HTTP method and set/volley the response
426
- def head(action, parameters = nil, session = nil, flash = nil)
427
- process(action, parameters, session, flash, "HEAD")
541
+ # Simulate a HEAD request with the given parameters and set/volley the response.
542
+ # See +get+ for more details.
543
+ def head(action, *args)
544
+ process(action, "HEAD", *args)
428
545
  end
429
546
 
430
547
  def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
@@ -450,65 +567,129 @@ module ActionController
450
567
  end
451
568
  end
452
569
 
453
- def process(action, parameters = nil, session = nil, flash = nil, http_method = 'GET')
570
+ # Simulate a HTTP request to +action+ by specifying request method,
571
+ # parameters and set/volley the response.
572
+ #
573
+ # - +action+: The controller action to call.
574
+ # - +http_method+: Request method used to send the http request. Possible values
575
+ # are +GET+, +POST+, +PATCH+, +PUT+, +DELETE+, +HEAD+. Defaults to +GET+.
576
+ # - +parameters+: The HTTP parameters. This may be +nil+, a hash, or a
577
+ # string that is appropriately encoded (+application/x-www-form-urlencoded+
578
+ # or +multipart/form-data+).
579
+ # - +session+: A hash of parameters to store in the session. This may be +nil+.
580
+ # - +flash+: A hash of parameters to store in the flash. This may be +nil+.
581
+ #
582
+ # Example calling +create+ action and sending two params:
583
+ #
584
+ # process :create, 'POST', user: { name: 'Gaurish Sharma', email: 'user@example.com' }
585
+ #
586
+ # Example sending parameters, +nil+ session and setting a flash message:
587
+ #
588
+ # process :view, 'GET', { id: 7 }, nil, { notice: 'This is flash message' }
589
+ #
590
+ # To simulate +GET+, +POST+, +PATCH+, +PUT+, +DELETE+ and +HEAD+ requests
591
+ # prefer using #get, #post, #patch, #put, #delete and #head methods
592
+ # respectively which will make tests more expressive.
593
+ #
594
+ # Note that the request method is not verified.
595
+ def process(action, http_method = 'GET', *args)
596
+ check_required_ivars
597
+
598
+ if args.first.is_a?(String) && http_method != 'HEAD'
599
+ @request.env['RAW_POST_DATA'] = args.shift
600
+ end
601
+
602
+ parameters, session, flash = args
603
+ parameters ||= {}
604
+
454
605
  # Ensure that numbers and symbols passed as params are converted to
455
606
  # proper params, as is the case when engaging rack.
456
607
  parameters = paramify_values(parameters) if html_format?(parameters)
457
608
 
458
- # Sanity check for required instance variables so we can give an
459
- # understandable error message.
460
- %w(@routes @controller @request @response).each do |iv_name|
461
- if !(instance_variable_names.include?(iv_name) || instance_variable_names.include?(iv_name.to_sym)) || instance_variable_get(iv_name).nil?
462
- raise "#{iv_name} is nil: make sure you set it in your test's setup method."
463
- end
609
+ @html_document = nil
610
+ @html_scanner_document = nil
611
+
612
+ unless @controller.respond_to?(:recycle!)
613
+ @controller.extend(Testing::Functional)
464
614
  end
465
615
 
466
616
  @request.recycle!
467
617
  @response.recycle!
468
- @controller.response_body = nil
469
- @controller.formats = nil
470
- @controller.params = nil
618
+ @controller.recycle!
471
619
 
472
- @html_document = nil
473
620
  @request.env['REQUEST_METHOD'] = http_method
474
621
 
475
- parameters ||= {}
476
622
  controller_class_name = @controller.class.anonymous? ?
477
- "anonymous_controller" :
623
+ "anonymous" :
478
624
  @controller.class.controller_path
479
625
 
480
626
  @request.assign_parameters(@routes, controller_class_name, action.to_s, parameters)
481
627
 
482
- @request.session = ActionController::TestSession.new(session) if session
483
- @request.session["flash"] = @request.flash.update(flash || {})
484
- @request.session["flash"].sweep
628
+ @request.session.update(session) if session
629
+ @request.flash.update(flash || {})
630
+
631
+ @controller.request = @request
632
+ @controller.response = @response
485
633
 
486
- @controller.request = @request
487
634
  build_request_uri(action, parameters)
488
- @controller.class.class_eval { include Testing }
635
+
636
+ name = @request.parameters[:action]
637
+
489
638
  @controller.recycle!
490
- @controller.process_with_new_base_test(@request, @response)
639
+ @controller.process(name)
640
+
641
+ if cookies = @request.env['action_dispatch.cookies']
642
+ unless @response.committed?
643
+ cookies.write(@response)
644
+ end
645
+ end
646
+ @response.prepare!
647
+
491
648
  @assigns = @controller.respond_to?(:view_assigns) ? @controller.view_assigns : {}
492
- @request.session.delete('flash') if @request.session['flash'].blank?
649
+
650
+ if flash_value = @request.flash.to_session_value
651
+ @request.session['flash'] = flash_value
652
+ end
653
+
493
654
  @response
494
655
  end
495
656
 
496
657
  def setup_controller_request_and_response
497
- @request = TestRequest.new
498
- @response = TestResponse.new
658
+ @controller = nil unless defined? @controller
659
+
660
+ response_klass = TestResponse
499
661
 
500
662
  if klass = self.class.controller_class
501
- @controller ||= klass.new rescue nil
663
+ if klass < ActionController::Live
664
+ response_klass = LiveTestResponse
665
+ end
666
+ unless @controller
667
+ begin
668
+ @controller = klass.new
669
+ rescue
670
+ warn "could not construct controller #{klass}" if $VERBOSE
671
+ end
672
+ end
502
673
  end
503
674
 
504
- @request.env.delete('PATH_INFO')
675
+ @request = build_request
676
+ @response = build_response response_klass
677
+ @response.request = @request
505
678
 
506
- if defined?(@controller) && @controller
679
+ if @controller
507
680
  @controller.request = @request
508
681
  @controller.params = {}
509
682
  end
510
683
  end
511
684
 
685
+ def build_request
686
+ TestRequest.new
687
+ end
688
+
689
+ def build_response(klass)
690
+ klass.new
691
+ end
692
+
512
693
  included do
513
694
  include ActionController::TemplateAssertions
514
695
  include ActionDispatch::Assertions
@@ -516,18 +697,52 @@ module ActionController
516
697
  setup :setup_controller_request_and_response
517
698
  end
518
699
 
519
- private
700
+ private
701
+
702
+ def document_root_element
703
+ html_document.root
704
+ end
705
+
706
+ def check_required_ivars
707
+ # Sanity check for required instance variables so we can give an
708
+ # understandable error message.
709
+ [:@routes, :@controller, :@request, :@response].each do |iv_name|
710
+ if !instance_variable_defined?(iv_name) || instance_variable_get(iv_name).nil?
711
+ raise "#{iv_name} is nil: make sure you set it in your test's setup method."
712
+ end
713
+ end
714
+ end
520
715
 
521
716
  def build_request_uri(action, parameters)
522
717
  unless @request.env["PATH_INFO"]
523
718
  options = @controller.respond_to?(:url_options) ? @controller.__send__(:url_options).merge(parameters) : parameters
524
719
  options.update(
525
- :only_path => true,
526
720
  :action => action,
527
721
  :relative_url_root => nil,
528
- :_path_segments => @request.symbolized_path_parameters)
722
+ :_recall => @request.path_parameters)
723
+
724
+ if route_name = options.delete(:use_route)
725
+ ActiveSupport::Deprecation.warn <<-MSG.squish
726
+ Passing the `use_route` option in functional tests are deprecated.
727
+ Support for this option in the `process` method (and the related
728
+ `get`, `head`, `post`, `patch`, `put` and `delete` helpers) will
729
+ be removed in the next version without replacement.
730
+
731
+ Functional tests are essentially unit tests for controllers and
732
+ they should not require knowledge to how the application's routes
733
+ are configured. Instead, you should explicitly pass the appropiate
734
+ params to the `process` method.
735
+
736
+ Previously the engines guide also contained an incorrect example
737
+ that recommended using this option to test an engine's controllers
738
+ within the dummy application. That recommendation was incorrect
739
+ and has since been corrected. Instead, you should override the
740
+ `@routes` variable in the test case with `Foo::Engine.routes`. See
741
+ the updated engines guide for details.
742
+ MSG
743
+ end
529
744
 
530
- url, query_string = @routes.url_for(options).split("?", 2)
745
+ url, query_string = @routes.path_for(options, route_name).split("?", 2)
531
746
 
532
747
  @request.env["SCRIPT_NAME"] = @controller.config.relative_url_root
533
748
  @request.env["PATH_INFO"] = url
@@ -536,40 +751,11 @@ module ActionController
536
751
  end
537
752
 
538
753
  def html_format?(parameters)
539
- return true unless parameters.is_a?(Hash)
540
- format = Mime[parameters[:format]]
541
- format.nil? || format.html?
754
+ return true unless parameters.key?(:format)
755
+ Mime.fetch(parameters[:format]) { Mime['html'] }.html?
542
756
  end
543
757
  end
544
758
 
545
- # When the request.remote_addr remains the default for testing, which is 0.0.0.0, the exception is simply raised inline
546
- # (skipping the regular exception handling from rescue_action). If the request.remote_addr is anything else, the regular
547
- # rescue_action process takes place. This means you can test your rescue_action code by setting remote_addr to something else
548
- # than 0.0.0.0.
549
- #
550
- # The exception is stored in the exception accessor for further inspection.
551
- module RaiseActionExceptions
552
- def self.included(base)
553
- unless base.method_defined?(:exception) && base.method_defined?(:exception=)
554
- base.class_eval do
555
- attr_accessor :exception
556
- protected :exception, :exception=
557
- end
558
- end
559
- end
560
-
561
- protected
562
- def rescue_action_without_handler(e)
563
- self.exception = e
564
-
565
- if request.remote_addr == "0.0.0.0"
566
- raise(e)
567
- else
568
- super(e)
569
- end
570
- end
571
- end
572
-
573
759
  include Behavior
574
760
  end
575
761
  end