actionpack 3.2.19 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +850 -401
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -288
  5. data/lib/abstract_controller/asset_paths.rb +2 -2
  6. data/lib/abstract_controller/base.rb +39 -37
  7. data/lib/abstract_controller/callbacks.rb +101 -82
  8. data/lib/abstract_controller/collector.rb +7 -3
  9. data/lib/abstract_controller/helpers.rb +25 -13
  10. data/lib/abstract_controller/layouts.rb +74 -74
  11. data/lib/abstract_controller/logger.rb +1 -2
  12. data/lib/abstract_controller/rendering.rb +30 -13
  13. data/lib/abstract_controller/translation.rb +16 -1
  14. data/lib/abstract_controller/url_for.rb +6 -6
  15. data/lib/abstract_controller/view_paths.rb +1 -1
  16. data/lib/abstract_controller.rb +1 -8
  17. data/lib/action_controller/base.rb +46 -22
  18. data/lib/action_controller/caching/fragments.rb +23 -53
  19. data/lib/action_controller/caching.rb +46 -33
  20. data/lib/action_controller/deprecated/integration_test.rb +3 -0
  21. data/lib/action_controller/deprecated.rb +5 -1
  22. data/lib/action_controller/log_subscriber.rb +16 -8
  23. data/lib/action_controller/metal/conditional_get.rb +76 -32
  24. data/lib/action_controller/metal/data_streaming.rb +20 -26
  25. data/lib/action_controller/metal/exceptions.rb +19 -6
  26. data/lib/action_controller/metal/flash.rb +24 -9
  27. data/lib/action_controller/metal/force_ssl.rb +70 -12
  28. data/lib/action_controller/metal/head.rb +25 -4
  29. data/lib/action_controller/metal/helpers.rb +5 -9
  30. data/lib/action_controller/metal/hide_actions.rb +0 -1
  31. data/lib/action_controller/metal/http_authentication.rb +107 -83
  32. data/lib/action_controller/metal/implicit_render.rb +1 -1
  33. data/lib/action_controller/metal/instrumentation.rb +2 -1
  34. data/lib/action_controller/metal/live.rb +175 -0
  35. data/lib/action_controller/metal/mime_responds.rb +161 -47
  36. data/lib/action_controller/metal/params_wrapper.rb +112 -74
  37. data/lib/action_controller/metal/rack_delegation.rb +9 -3
  38. data/lib/action_controller/metal/redirecting.rb +15 -20
  39. data/lib/action_controller/metal/renderers.rb +11 -9
  40. data/lib/action_controller/metal/rendering.rb +9 -1
  41. data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
  42. data/lib/action_controller/metal/responder.rb +20 -19
  43. data/lib/action_controller/metal/streaming.rb +12 -18
  44. data/lib/action_controller/metal/strong_parameters.rb +520 -0
  45. data/lib/action_controller/metal/testing.rb +13 -18
  46. data/lib/action_controller/metal/url_for.rb +28 -25
  47. data/lib/action_controller/metal.rb +17 -32
  48. data/lib/action_controller/model_naming.rb +12 -0
  49. data/lib/action_controller/railtie.rb +33 -17
  50. data/lib/action_controller/railties/helpers.rb +22 -0
  51. data/lib/action_controller/record_identifier.rb +18 -72
  52. data/lib/action_controller/test_case.rb +251 -131
  53. data/lib/action_controller/vendor/html-scanner.rb +4 -19
  54. data/lib/action_controller.rb +15 -6
  55. data/lib/action_dispatch/http/cache.rb +63 -11
  56. data/lib/action_dispatch/http/filter_parameters.rb +18 -8
  57. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  58. data/lib/action_dispatch/http/headers.rb +49 -17
  59. data/lib/action_dispatch/http/mime_negotiation.rb +24 -1
  60. data/lib/action_dispatch/http/mime_type.rb +154 -100
  61. data/lib/action_dispatch/http/mime_types.rb +1 -1
  62. data/lib/action_dispatch/http/parameter_filter.rb +44 -46
  63. data/lib/action_dispatch/http/parameters.rb +28 -28
  64. data/lib/action_dispatch/http/rack_cache.rb +2 -3
  65. data/lib/action_dispatch/http/request.rb +64 -18
  66. data/lib/action_dispatch/http/response.rb +130 -35
  67. data/lib/action_dispatch/http/upload.rb +63 -20
  68. data/lib/action_dispatch/http/url.rb +98 -35
  69. data/lib/action_dispatch/journey/backwards.rb +5 -0
  70. data/lib/action_dispatch/journey/formatter.rb +146 -0
  71. data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
  72. data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
  73. data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
  74. data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
  75. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  76. data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
  77. data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
  78. data/lib/action_dispatch/journey/nodes/node.rb +124 -0
  79. data/lib/action_dispatch/journey/parser.rb +206 -0
  80. data/lib/action_dispatch/journey/parser.y +47 -0
  81. data/lib/action_dispatch/journey/parser_extras.rb +23 -0
  82. data/lib/action_dispatch/journey/path/pattern.rb +196 -0
  83. data/lib/action_dispatch/journey/route.rb +124 -0
  84. data/lib/action_dispatch/journey/router/strexp.rb +24 -0
  85. data/lib/action_dispatch/journey/router/utils.rb +54 -0
  86. data/lib/action_dispatch/journey/router.rb +166 -0
  87. data/lib/action_dispatch/journey/routes.rb +75 -0
  88. data/lib/action_dispatch/journey/scanner.rb +61 -0
  89. data/lib/action_dispatch/journey/visitors.rb +197 -0
  90. data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
  91. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  92. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  93. data/lib/action_dispatch/journey.rb +5 -0
  94. data/lib/action_dispatch/middleware/callbacks.rb +9 -4
  95. data/lib/action_dispatch/middleware/cookies.rb +259 -114
  96. data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
  97. data/lib/action_dispatch/middleware/exception_wrapper.rb +29 -3
  98. data/lib/action_dispatch/middleware/flash.rb +58 -58
  99. data/lib/action_dispatch/middleware/params_parser.rb +14 -29
  100. data/lib/action_dispatch/middleware/public_exceptions.rb +30 -14
  101. data/lib/action_dispatch/middleware/reloader.rb +6 -6
  102. data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
  103. data/lib/action_dispatch/middleware/request_id.rb +2 -6
  104. data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
  105. data/lib/action_dispatch/middleware/session/cookie_store.rb +82 -28
  106. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
  107. data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
  108. data/lib/action_dispatch/middleware/ssl.rb +70 -0
  109. data/lib/action_dispatch/middleware/stack.rb +6 -1
  110. data/lib/action_dispatch/middleware/static.rb +2 -1
  111. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
  112. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
  113. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +7 -9
  114. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
  115. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +127 -5
  116. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
  117. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
  118. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
  119. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
  120. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  121. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
  122. data/lib/action_dispatch/railtie.rb +16 -6
  123. data/lib/action_dispatch/request/session.rb +181 -0
  124. data/lib/action_dispatch/routing/inspector.rb +240 -0
  125. data/lib/action_dispatch/routing/mapper.rb +540 -291
  126. data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
  127. data/lib/action_dispatch/routing/redirection.rb +46 -29
  128. data/lib/action_dispatch/routing/route_set.rb +207 -164
  129. data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
  130. data/lib/action_dispatch/routing/url_for.rb +48 -33
  131. data/lib/action_dispatch/routing.rb +48 -83
  132. data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
  133. data/lib/action_dispatch/testing/assertions/response.rb +32 -40
  134. data/lib/action_dispatch/testing/assertions/routing.rb +42 -41
  135. data/lib/action_dispatch/testing/assertions/selector.rb +17 -22
  136. data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
  137. data/lib/action_dispatch/testing/integration.rb +65 -51
  138. data/lib/action_dispatch/testing/test_process.rb +9 -6
  139. data/lib/action_dispatch/testing/test_request.rb +7 -3
  140. data/lib/action_dispatch.rb +21 -15
  141. data/lib/action_pack/version.rb +7 -6
  142. data/lib/action_pack.rb +1 -1
  143. data/lib/action_view/base.rb +15 -34
  144. data/lib/action_view/buffers.rb +7 -1
  145. data/lib/action_view/context.rb +4 -4
  146. data/lib/action_view/dependency_tracker.rb +93 -0
  147. data/lib/action_view/digestor.rb +85 -0
  148. data/lib/action_view/flows.rb +1 -4
  149. data/lib/action_view/helpers/active_model_helper.rb +3 -4
  150. data/lib/action_view/helpers/asset_tag_helper.rb +215 -352
  151. data/lib/action_view/helpers/asset_url_helper.rb +355 -0
  152. data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
  153. data/lib/action_view/helpers/cache_helper.rb +150 -18
  154. data/lib/action_view/helpers/capture_helper.rb +44 -31
  155. data/lib/action_view/helpers/csrf_helper.rb +0 -2
  156. data/lib/action_view/helpers/date_helper.rb +269 -248
  157. data/lib/action_view/helpers/debug_helper.rb +10 -11
  158. data/lib/action_view/helpers/form_helper.rb +931 -537
  159. data/lib/action_view/helpers/form_options_helper.rb +341 -166
  160. data/lib/action_view/helpers/form_tag_helper.rb +190 -90
  161. data/lib/action_view/helpers/javascript_helper.rb +23 -16
  162. data/lib/action_view/helpers/number_helper.rb +148 -329
  163. data/lib/action_view/helpers/output_safety_helper.rb +3 -3
  164. data/lib/action_view/helpers/record_tag_helper.rb +17 -22
  165. data/lib/action_view/helpers/rendering_helper.rb +2 -2
  166. data/lib/action_view/helpers/sanitize_helper.rb +3 -6
  167. data/lib/action_view/helpers/tag_helper.rb +46 -33
  168. data/lib/action_view/helpers/tags/base.rb +147 -0
  169. data/lib/action_view/helpers/tags/check_box.rb +64 -0
  170. data/lib/action_view/helpers/tags/checkable.rb +16 -0
  171. data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
  172. data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
  173. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
  174. data/lib/action_view/helpers/tags/collection_select.rb +28 -0
  175. data/lib/action_view/helpers/tags/color_field.rb +25 -0
  176. data/lib/action_view/helpers/tags/date_field.rb +13 -0
  177. data/lib/action_view/helpers/tags/date_select.rb +72 -0
  178. data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
  179. data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
  180. data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
  181. data/lib/action_view/helpers/tags/email_field.rb +8 -0
  182. data/lib/action_view/helpers/tags/file_field.rb +8 -0
  183. data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
  184. data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
  185. data/lib/action_view/helpers/tags/label.rb +65 -0
  186. data/lib/action_view/helpers/tags/month_field.rb +13 -0
  187. data/lib/action_view/helpers/tags/number_field.rb +18 -0
  188. data/lib/action_view/helpers/tags/password_field.rb +12 -0
  189. data/lib/action_view/helpers/tags/radio_button.rb +31 -0
  190. data/lib/action_view/helpers/tags/range_field.rb +8 -0
  191. data/lib/action_view/helpers/tags/search_field.rb +24 -0
  192. data/lib/action_view/helpers/tags/select.rb +40 -0
  193. data/lib/action_view/helpers/tags/tel_field.rb +8 -0
  194. data/lib/action_view/helpers/tags/text_area.rb +18 -0
  195. data/lib/action_view/helpers/tags/text_field.rb +29 -0
  196. data/lib/action_view/helpers/tags/time_field.rb +13 -0
  197. data/lib/action_view/helpers/tags/time_select.rb +8 -0
  198. data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
  199. data/lib/action_view/helpers/tags/url_field.rb +8 -0
  200. data/lib/action_view/helpers/tags/week_field.rb +13 -0
  201. data/lib/action_view/helpers/tags.rb +39 -0
  202. data/lib/action_view/helpers/text_helper.rb +130 -114
  203. data/lib/action_view/helpers/translation_helper.rb +32 -16
  204. data/lib/action_view/helpers/url_helper.rb +211 -270
  205. data/lib/action_view/helpers.rb +2 -4
  206. data/lib/action_view/locale/en.yml +1 -105
  207. data/lib/action_view/log_subscriber.rb +6 -4
  208. data/lib/action_view/lookup_context.rb +15 -28
  209. data/lib/action_view/model_naming.rb +12 -0
  210. data/lib/action_view/path_set.rb +8 -20
  211. data/lib/action_view/railtie.rb +6 -22
  212. data/lib/action_view/record_identifier.rb +84 -0
  213. data/lib/action_view/renderer/abstract_renderer.rb +25 -19
  214. data/lib/action_view/renderer/partial_renderer.rb +158 -81
  215. data/lib/action_view/renderer/renderer.rb +8 -12
  216. data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
  217. data/lib/action_view/renderer/template_renderer.rb +12 -10
  218. data/lib/action_view/routing_url_for.rb +107 -0
  219. data/lib/action_view/template/error.rb +22 -12
  220. data/lib/action_view/template/handlers/builder.rb +1 -1
  221. data/lib/action_view/template/handlers/erb.rb +40 -19
  222. data/lib/action_view/template/handlers/raw.rb +11 -0
  223. data/lib/action_view/template/handlers.rb +12 -9
  224. data/lib/action_view/template/resolver.rb +107 -53
  225. data/lib/action_view/template/text.rb +12 -8
  226. data/lib/action_view/template/types.rb +57 -0
  227. data/lib/action_view/template.rb +25 -23
  228. data/lib/action_view/test_case.rb +67 -42
  229. data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
  230. data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
  231. data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +13 -2
  232. data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +9 -9
  233. data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
  234. data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
  235. data/lib/action_view/vendor/html-scanner.rb +20 -0
  236. data/lib/action_view.rb +17 -8
  237. metadata +184 -214
  238. data/lib/action_controller/caching/actions.rb +0 -185
  239. data/lib/action_controller/caching/pages.rb +0 -187
  240. data/lib/action_controller/caching/sweeping.rb +0 -97
  241. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  242. data/lib/action_controller/metal/compatibility.rb +0 -65
  243. data/lib/action_controller/metal/session_management.rb +0 -14
  244. data/lib/action_controller/railties/paths.rb +0 -25
  245. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  246. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  247. data/lib/action_dispatch/middleware/head.rb +0 -18
  248. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  249. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  250. data/lib/action_view/asset_paths.rb +0 -142
  251. data/lib/action_view/helpers/asset_paths.rb +0 -7
  252. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  253. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  254. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  255. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  256. data/lib/sprockets/assets.rake +0 -99
  257. data/lib/sprockets/bootstrap.rb +0 -37
  258. data/lib/sprockets/compressors.rb +0 -83
  259. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  260. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  261. data/lib/sprockets/helpers.rb +0 -6
  262. data/lib/sprockets/railtie.rb +0 -62
  263. data/lib/sprockets/static_compiler.rb +0 -56
@@ -8,7 +8,8 @@ module ActionDispatch
8
8
  #
9
9
  # <b>Tip:</b> If you need to generate URLs from your models or some other place,
10
10
  # then ActionController::UrlFor is what you're looking for. Read on for
11
- # an introduction.
11
+ # an introduction. In general, this module should not be included on its own,
12
+ # as it is usually included by url_helpers (as in Rails.application.routes.url_helpers).
12
13
  #
13
14
  # == URL generation from parameters
14
15
  #
@@ -17,8 +18,8 @@ module ActionDispatch
17
18
  # of parameters. For example, you've probably had the chance to write code
18
19
  # like this in one of your views:
19
20
  #
20
- # <%= link_to('Click here', :controller => 'users',
21
- # :action => 'new', :message => 'Welcome!') %>
21
+ # <%= link_to('Click here', controller: 'users',
22
+ # action: 'new', message: 'Welcome!') %>
22
23
  # # => "/users/new?message=Welcome%21"
23
24
  #
24
25
  # link_to, and all other functions that require URL generation functionality,
@@ -27,22 +28,22 @@ module ActionDispatch
27
28
  # the same path as the above example by using the following code:
28
29
  #
29
30
  # include UrlFor
30
- # url_for(:controller => 'users',
31
- # :action => 'new',
32
- # :message => 'Welcome!',
33
- # :only_path => true)
31
+ # url_for(controller: 'users',
32
+ # action: 'new',
33
+ # message: 'Welcome!',
34
+ # only_path: true)
34
35
  # # => "/users/new?message=Welcome%21"
35
36
  #
36
- # Notice the <tt>:only_path => true</tt> part. This is because UrlFor has no
37
+ # Notice the <tt>only_path: true</tt> part. This is because UrlFor has no
37
38
  # information about the website hostname that your Rails app is serving. So if you
38
39
  # want to include the hostname as well, then you must also pass the <tt>:host</tt>
39
40
  # argument:
40
41
  #
41
42
  # include UrlFor
42
- # url_for(:controller => 'users',
43
- # :action => 'new',
44
- # :message => 'Welcome!',
45
- # :host => 'www.example.com')
43
+ # url_for(controller: 'users',
44
+ # action: 'new',
45
+ # message: 'Welcome!',
46
+ # host: 'www.example.com')
46
47
  # # => "http://www.example.com/users/new?message=Welcome%21"
47
48
  #
48
49
  # By default, all controllers and views have access to a special version of url_for,
@@ -67,7 +68,7 @@ module ActionDispatch
67
68
  # This generates, among other things, the method <tt>users_path</tt>. By default,
68
69
  # this method is accessible from your controllers, views and mailers. If you need
69
70
  # to access this auto-generated method from other places (such as a model), then
70
- # you can do that by including ActionController::UrlFor in your class:
71
+ # you can do that by including Rails.application.routes.url_helpers in your class:
71
72
  #
72
73
  # class User < ActiveRecord::Base
73
74
  # include Rails.application.routes.url_helpers
@@ -84,18 +85,18 @@ module ActionDispatch
84
85
  include PolymorphicRoutes
85
86
 
86
87
  included do
87
- # TODO: with_routing extends @controller with url_helpers, trickling down to including this module which overrides its default_url_options
88
88
  unless method_defined?(:default_url_options)
89
89
  # Including in a class uses an inheritable hash. Modules get a plain hash.
90
90
  if respond_to?(:class_attribute)
91
91
  class_attribute :default_url_options
92
92
  else
93
- mattr_accessor :default_url_options
94
- remove_method :default_url_options
93
+ mattr_writer :default_url_options
95
94
  end
96
95
 
97
96
  self.default_url_options = {}
98
97
  end
98
+
99
+ include(*_url_for_modules) if respond_to?(:_url_for_modules)
99
100
  end
100
101
 
101
102
  def initialize(*)
@@ -103,6 +104,9 @@ module ActionDispatch
103
104
  super
104
105
  end
105
106
 
107
+ # Hook overridden in controller to add request information
108
+ # with `default_url_options`. Application logic should not
109
+ # go into url_options.
106
110
  def url_options
107
111
  default_url_options
108
112
  end
@@ -126,42 +130,53 @@ module ActionDispatch
126
130
  # * <tt>:port</tt> - Optionally specify the port to connect to.
127
131
  # * <tt>:anchor</tt> - An anchor name to be appended to the path.
128
132
  # * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2009/"
133
+ # * <tt>:script_name</tt> - Specifies application path relative to domain root. If provided, prepends application path.
129
134
  #
130
135
  # Any other key (<tt>:controller</tt>, <tt>:action</tt>, etc.) given to
131
136
  # +url_for+ is forwarded to the Routes module.
132
137
  #
133
- # Examples:
134
- #
135
- # url_for :controller => 'tasks', :action => 'testing', :host => 'somehost.org', :port => '8080'
138
+ # url_for controller: 'tasks', action: 'testing', host: 'somehost.org', port: '8080'
136
139
  # # => 'http://somehost.org:8080/tasks/testing'
137
- # url_for :controller => 'tasks', :action => 'testing', :host => 'somehost.org', :anchor => 'ok', :only_path => true
140
+ # url_for controller: 'tasks', action: 'testing', host: 'somehost.org', anchor: 'ok', only_path: true
138
141
  # # => '/tasks/testing#ok'
139
- # url_for :controller => 'tasks', :action => 'testing', :trailing_slash => true
142
+ # url_for controller: 'tasks', action: 'testing', trailing_slash: true
140
143
  # # => 'http://somehost.org/tasks/testing/'
141
- # url_for :controller => 'tasks', :action => 'testing', :host => 'somehost.org', :number => '33'
144
+ # url_for controller: 'tasks', action: 'testing', host: 'somehost.org', number: '33'
142
145
  # # => 'http://somehost.org/tasks/testing?number=33'
146
+ # url_for controller: 'tasks', action: 'testing', host: 'somehost.org', script_name: "/myapp"
147
+ # # => 'http://somehost.org/myapp/tasks/testing'
148
+ # url_for controller: 'tasks', action: 'testing', host: 'somehost.org', script_name: "/myapp", only_path: true
149
+ # # => '/myapp/tasks/testing'
143
150
  def url_for(options = nil)
144
151
  case options
152
+ when nil
153
+ _routes.url_for(url_options.symbolize_keys)
154
+ when Hash
155
+ _routes.url_for(options.symbolize_keys.reverse_merge!(url_options))
145
156
  when String
146
157
  options
147
- when nil, Hash
148
- _routes.url_for((options || {}).symbolize_keys.reverse_merge!(url_options))
149
158
  else
150
159
  polymorphic_url(options)
151
160
  end
152
161
  end
153
162
 
154
163
  protected
155
- def _with_routes(routes)
156
- old_routes, @_routes = @_routes, routes
157
- yield
158
- ensure
159
- @_routes = old_routes
160
- end
161
164
 
162
- def _routes_context
163
- self
164
- end
165
+ def optimize_routes_generation?
166
+ return @_optimized_routes if defined?(@_optimized_routes)
167
+ @_optimized_routes = _routes.optimize_routes_generation? && default_url_options.empty?
168
+ end
169
+
170
+ def _with_routes(routes)
171
+ old_routes, @_routes = @_routes, routes
172
+ yield
173
+ ensure
174
+ @_routes = old_routes
175
+ end
176
+
177
+ def _routes_context
178
+ self
179
+ end
165
180
  end
166
181
  end
167
182
  end
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  require 'active_support/core_ext/object/to_param'
2
3
  require 'active_support/core_ext/regexp'
3
4
 
@@ -60,7 +61,7 @@ module ActionDispatch
60
61
  # directory by using +scope+. +scope+ takes additional options which
61
62
  # apply to all enclosed routes.
62
63
  #
63
- # scope :path => "/cpanel", :as => 'admin' do
64
+ # scope path: "/cpanel", as: 'admin' do
64
65
  # resources :posts, :comments
65
66
  # end
66
67
  #
@@ -68,6 +69,22 @@ module ActionDispatch
68
69
  # <tt>Routing::Mapper::Scoping#namespace</tt>, and
69
70
  # <tt>Routing::Mapper::Scoping#scope</tt>.
70
71
  #
72
+ # == Non-resourceful routes
73
+ #
74
+ # For routes that don't fit the <tt>resources</tt> mold, you can use the HTTP helper
75
+ # methods <tt>get</tt>, <tt>post</tt>, <tt>patch</tt>, <tt>put</tt> and <tt>delete</tt>.
76
+ #
77
+ # get 'post/:id' => 'posts#show'
78
+ # post 'post/:id' => 'posts#create_comment'
79
+ #
80
+ # If your route needs to respond to more than one HTTP method (or all methods) then using the
81
+ # <tt>:via</tt> option on <tt>match</tt> is preferable.
82
+ #
83
+ # match 'post/:id' => 'posts#show', via: [:get, :post]
84
+ #
85
+ # Now, if you POST to <tt>/posts/:id</tt>, it will route to the <tt>create_comment</tt> action. A GET on the same
86
+ # URL will route to the <tt>show</tt> action.
87
+ #
71
88
  # == Named routes
72
89
  #
73
90
  # Routes can be named by passing an <tt>:as</tt> option,
@@ -77,22 +94,22 @@ module ActionDispatch
77
94
  # Example:
78
95
  #
79
96
  # # In routes.rb
80
- # match '/login' => 'accounts#login', :as => 'login'
97
+ # get '/login' => 'accounts#login', as: 'login'
81
98
  #
82
99
  # # With render, redirect_to, tests, etc.
83
100
  # redirect_to login_url
84
101
  #
85
102
  # Arguments can be passed as well.
86
103
  #
87
- # redirect_to show_item_path(:id => 25)
104
+ # redirect_to show_item_path(id: 25)
88
105
  #
89
106
  # Use <tt>root</tt> as a shorthand to name a route for the root path "/".
90
107
  #
91
108
  # # In routes.rb
92
- # root :to => 'blogs#index'
109
+ # root to: 'blogs#index'
93
110
  #
94
111
  # # would recognize http://www.example.com/ as
95
- # params = { :controller => 'blogs', :action => 'index' }
112
+ # params = { controller: 'blogs', action: 'index' }
96
113
  #
97
114
  # # and provide these named routes
98
115
  # root_url # => 'http://www.example.com/'
@@ -103,117 +120,70 @@ module ActionDispatch
103
120
  #
104
121
  # # In routes.rb
105
122
  # controller :blog do
106
- # match 'blog/show' => :list
107
- # match 'blog/delete' => :delete
108
- # match 'blog/edit/:id' => :edit
123
+ # get 'blog/show' => :list
124
+ # get 'blog/delete' => :delete
125
+ # get 'blog/edit/:id' => :edit
109
126
  # end
110
127
  #
111
128
  # # provides named routes for show, delete, and edit
112
- # link_to @article.title, show_path(:id => @article.id)
129
+ # link_to @article.title, show_path(id: @article.id)
113
130
  #
114
131
  # == Pretty URLs
115
132
  #
116
133
  # Routes can generate pretty URLs. For example:
117
134
  #
118
- # match '/articles/:year/:month/:day' => 'articles#find_by_id', :constraints => {
119
- # :year => /\d{4}/,
120
- # :month => /\d{1,2}/,
121
- # :day => /\d{1,2}/
135
+ # get '/articles/:year/:month/:day' => 'articles#find_by_id', constraints: {
136
+ # year: /\d{4}/,
137
+ # month: /\d{1,2}/,
138
+ # day: /\d{1,2}/
122
139
  # }
123
140
  #
124
141
  # Using the route above, the URL "http://localhost:3000/articles/2005/11/06"
125
142
  # maps to
126
143
  #
127
- # params = {:year => '2005', :month => '11', :day => '06'}
144
+ # params = {year: '2005', month: '11', day: '06'}
128
145
  #
129
146
  # == Regular Expressions and parameters
130
147
  # You can specify a regular expression to define a format for a parameter.
131
148
  #
132
149
  # controller 'geocode' do
133
- # match 'geocode/:postalcode' => :show, :constraints => {
134
- # :postalcode => /\d{5}(-\d{4})?/
150
+ # get 'geocode/:postalcode' => :show, constraints: {
151
+ # postalcode: /\d{5}(-\d{4})?/
135
152
  # }
136
153
  #
137
154
  # Constraints can include the 'ignorecase' and 'extended syntax' regular
138
155
  # expression modifiers:
139
156
  #
140
157
  # controller 'geocode' do
141
- # match 'geocode/:postalcode' => :show, :constraints => {
142
- # :postalcode => /hx\d\d\s\d[a-z]{2}/i
158
+ # get 'geocode/:postalcode' => :show, constraints: {
159
+ # postalcode: /hx\d\d\s\d[a-z]{2}/i
143
160
  # }
144
161
  # end
145
162
  #
146
163
  # controller 'geocode' do
147
- # match 'geocode/:postalcode' => :show, :constraints => {
148
- # :postalcode => /# Postcode format
164
+ # get 'geocode/:postalcode' => :show, constraints: {
165
+ # postalcode: /# Postcode format
149
166
  # \d{5} #Prefix
150
167
  # (-\d{4})? #Suffix
151
168
  # /x
152
169
  # }
153
170
  # end
154
171
  #
155
- # Using the multiline match modifier will raise an +ArgumentError+.
172
+ # Using the multiline modifier will raise an +ArgumentError+.
156
173
  # Encoding regular expression modifiers are silently ignored. The
157
174
  # match will always use the default encoding or ASCII.
158
175
  #
159
- # == Default route
160
- #
161
- # Consider the following route, which you will find commented out at the
162
- # bottom of your generated <tt>config/routes.rb</tt>:
163
- #
164
- # match ':controller(/:action(/:id))(.:format)'
165
- #
166
- # This route states that it expects requests to consist of a
167
- # <tt>:controller</tt> followed optionally by an <tt>:action</tt> that in
168
- # turn is followed optionally by an <tt>:id</tt>, which in turn is followed
169
- # optionally by a <tt>:format</tt>.
170
- #
171
- # Suppose you get an incoming request for <tt>/blog/edit/22</tt>, you'll end
172
- # up with:
173
- #
174
- # params = { :controller => 'blog',
175
- # :action => 'edit',
176
- # :id => '22'
177
- # }
178
- #
179
- # By not relying on default routes, you improve the security of your
180
- # application since not all controller actions, which includes actions you
181
- # might add at a later time, are exposed by default.
182
- #
183
- # == HTTP Methods
184
- #
185
- # Using the <tt>:via</tt> option when specifying a route allows you to restrict it to a specific HTTP method.
186
- # Possible values are <tt>:post</tt>, <tt>:get</tt>, <tt>:put</tt>, <tt>:delete</tt> and <tt>:any</tt>.
187
- # If your route needs to respond to more than one method you can use an array, e.g. <tt>[ :get, :post ]</tt>.
188
- # The default value is <tt>:any</tt> which means that the route will respond to any of the HTTP methods.
189
- #
190
- # Examples:
191
- #
192
- # match 'post/:id' => 'posts#show', :via => :get
193
- # match 'post/:id' => "posts#create_comment', :via => :post
194
- #
195
- # Now, if you POST to <tt>/posts/:id</tt>, it will route to the <tt>create_comment</tt> action. A GET on the same
196
- # URL will route to the <tt>show</tt> action.
197
- #
198
- # === HTTP helper methods
199
- #
200
- # An alternative method of specifying which HTTP method a route should respond to is to use the helper
201
- # methods <tt>get</tt>, <tt>post</tt>, <tt>put</tt> and <tt>delete</tt>.
202
- #
203
- # Examples:
176
+ # == External redirects
204
177
  #
205
- # get 'post/:id' => 'posts#show'
206
- # post 'post/:id' => "posts#create_comment'
178
+ # You can redirect any path to another path using the redirect helper in your router:
207
179
  #
208
- # This syntax is less verbose and the intention is more apparent to someone else reading your code,
209
- # however if your route needs to respond to more than one HTTP method (or all methods) then using the
210
- # <tt>:via</tt> option on <tt>match</tt> is preferable.
180
+ # get "/stories" => redirect("/posts")
211
181
  #
212
- # == External redirects
182
+ # == Unicode character routes
213
183
  #
214
- # You can redirect any path to another path using the redirect helper in your router:
184
+ # You can specify unicode character routes in your router:
215
185
  #
216
- # match "/stories" => redirect("/posts")
186
+ # get "こんにちは" => "welcome#index"
217
187
  #
218
188
  # == Routing to Rack Applications
219
189
  #
@@ -221,7 +191,7 @@ module ActionDispatch
221
191
  # index action in the PostsController, you can specify any Rack application
222
192
  # as the endpoint for a matcher:
223
193
  #
224
- # match "/application.js" => Sprockets
194
+ # get "/application.js" => Sprockets
225
195
  #
226
196
  # == Reloading routes
227
197
  #
@@ -239,7 +209,7 @@ module ActionDispatch
239
209
  # === +assert_routing+
240
210
  #
241
211
  # def test_movie_route_properly_splits
242
- # opts = {:controller => "plugin", :action => "checkout", :id => "2"}
212
+ # opts = {controller: "plugin", action: "checkout", id: "2"}
243
213
  # assert_routing "plugin/checkout/2", opts
244
214
  # end
245
215
  #
@@ -248,7 +218,7 @@ module ActionDispatch
248
218
  # === +assert_recognizes+
249
219
  #
250
220
  # def test_route_has_options
251
- # opts = {:controller => "plugin", :action => "show", :id => "12"}
221
+ # opts = {controller: "plugin", action: "show", id: "12"}
252
222
  # assert_recognizes opts, "/plugins/show/12"
253
223
  # end
254
224
  #
@@ -283,11 +253,6 @@ module ActionDispatch
283
253
  autoload :PolymorphicRoutes, 'action_dispatch/routing/polymorphic_routes'
284
254
 
285
255
  SEPARATORS = %w( / . ? ) #:nodoc:
286
- HTTP_METHODS = [:get, :head, :post, :put, :delete, :options] #:nodoc:
287
-
288
- # A helper module to hold URL related helpers.
289
- module Helpers #:nodoc:
290
- include PolymorphicRoutes
291
- end
256
+ HTTP_METHODS = [:get, :head, :post, :patch, :put, :delete, :options] #:nodoc:
292
257
  end
293
258
  end
@@ -1,36 +1,26 @@
1
- require 'action_controller/vendor/html-scanner'
1
+ require 'action_view/vendor/html-scanner'
2
2
 
3
3
  module ActionDispatch
4
4
  module Assertions
5
5
  module DomAssertions
6
6
  # \Test two HTML strings for equivalency (e.g., identical up to reordering of attributes)
7
7
  #
8
- # ==== Examples
9
- #
10
8
  # # assert that the referenced method generates the appropriate HTML string
11
9
  # assert_dom_equal '<a href="http://www.example.com">Apples</a>', link_to("Apples", "http://www.example.com")
12
- #
13
10
  def assert_dom_equal(expected, actual, message = "")
14
11
  expected_dom = HTML::Document.new(expected).root
15
12
  actual_dom = HTML::Document.new(actual).root
16
- full_message = build_message(message, "<?> expected to be == to\n<?>.", expected_dom.to_s, actual_dom.to_s)
17
-
18
- assert_block(full_message) { expected_dom == actual_dom }
13
+ assert_equal expected_dom, actual_dom
19
14
  end
20
15
 
21
16
  # The negated form of +assert_dom_equivalent+.
22
17
  #
23
- # ==== Examples
24
- #
25
18
  # # assert that the referenced method does not generate the specified HTML string
26
19
  # assert_dom_not_equal '<a href="http://www.example.com">Apples</a>', link_to("Oranges", "http://www.example.com")
27
- #
28
20
  def assert_dom_not_equal(expected, actual, message = "")
29
21
  expected_dom = HTML::Document.new(expected).root
30
22
  actual_dom = HTML::Document.new(actual).root
31
- full_message = build_message(message, "<?> expected to be != to\n<?>.", expected_dom.to_s, actual_dom.to_s)
32
-
33
- assert_block(full_message) { expected_dom != actual_dom }
23
+ assert_not_equal expected_dom, actual_dom
34
24
  end
35
25
  end
36
26
  end
@@ -1,14 +1,11 @@
1
- require 'active_support/core_ext/object/inclusion'
2
1
 
3
2
  module ActionDispatch
4
3
  module Assertions
5
4
  # A small suite of assertions that test responses from \Rails applications.
6
5
  module ResponseAssertions
7
- extend ActiveSupport::Concern
8
-
9
6
  # Asserts that the response is one of the following types:
10
7
  #
11
- # * <tt>:success</tt> - Status code was 200
8
+ # * <tt>:success</tt> - Status code was in the 200-299 range
12
9
  # * <tt>:redirect</tt> - Status code was in the 300-399 range
13
10
  # * <tt>:missing</tt> - Status code was 404
14
11
  # * <tt>:error</tt> - Status code was in the 500-599 range
@@ -17,36 +14,32 @@ module ActionDispatch
17
14
  # or its symbolic equivalent <tt>assert_response(:not_implemented)</tt>.
18
15
  # See Rack::Utils::SYMBOL_TO_STATUS_CODE for a full list.
19
16
  #
20
- # ==== Examples
21
- #
22
17
  # # assert that the response was a redirection
23
18
  # assert_response :redirect
24
19
  #
25
20
  # # assert that the response code was status code 401 (unauthorized)
26
21
  # assert_response 401
27
- #
28
22
  def assert_response(type, message = nil)
29
- validate_request!
23
+ message ||= "Expected response to be a <#{type}>, but was <#{@response.response_code}>"
30
24
 
31
- if type.in?([:success, :missing, :redirect, :error]) && @response.send("#{type}?")
32
- assert_block("") { true } # to count the assertion
33
- elsif type.is_a?(Fixnum) && @response.response_code == type
34
- assert_block("") { true } # to count the assertion
35
- elsif type.is_a?(Symbol) && @response.response_code == Rack::Utils::SYMBOL_TO_STATUS_CODE[type]
36
- assert_block("") { true } # to count the assertion
25
+ if Symbol === type
26
+ if [:success, :missing, :redirect, :error].include?(type)
27
+ assert @response.send("#{type}?"), message
28
+ else
29
+ code = Rack::Utils::SYMBOL_TO_STATUS_CODE[type]
30
+ assert_equal code, @response.response_code, message
31
+ end
37
32
  else
38
- flunk(build_message(message, "Expected response to be a <?>, but was <?>", type, @response.response_code))
33
+ assert_equal type, @response.response_code, message
39
34
  end
40
35
  end
41
36
 
42
37
  # Assert that the redirection options passed in match those of the redirect called in the latest action.
43
- # This match can be partial, such that <tt>assert_redirected_to(:controller => "weblog")</tt> will also
44
- # match the redirection of <tt>redirect_to(:controller => "weblog", :action => "show")</tt> and so on.
45
- #
46
- # ==== Examples
38
+ # This match can be partial, such that <tt>assert_redirected_to(controller: "weblog")</tt> will also
39
+ # match the redirection of <tt>redirect_to(controller: "weblog", action: "show")</tt> and so on.
47
40
  #
48
41
  # # assert that the redirection was to the "index" action on the WeblogController
49
- # assert_redirected_to :controller => "weblog", :action => "index"
42
+ # assert_redirected_to controller: "weblog", action: "index"
50
43
  #
51
44
  # # assert that the redirection was to the named route login_url
52
45
  # assert_redirected_to login_url
@@ -54,16 +47,17 @@ module ActionDispatch
54
47
  # # assert that the redirection was to the url for @customer
55
48
  # assert_redirected_to @customer
56
49
  #
50
+ # # asserts that the redirection matches the regular expression
51
+ # assert_redirected_to %r(\Ahttp://example.org)
57
52
  def assert_redirected_to(options = {}, message=nil)
58
53
  assert_response(:redirect, message)
59
- return true if options == @response.location
54
+ return true if options === @response.location
60
55
 
61
56
  redirect_is = normalize_argument_to_redirection(@response.location)
62
57
  redirect_expected = normalize_argument_to_redirection(options)
63
58
 
64
- if redirect_is != redirect_expected
65
- flunk(build_message(message, "Expected response to be a redirect to <?> but was a redirect to <?>", redirect_expected, redirect_is))
66
- end
59
+ message ||= "Expected response to be a redirect to <#{redirect_expected}> but was a redirect to <#{redirect_is}>"
60
+ assert_operator redirect_expected, :===, redirect_is, message
67
61
  end
68
62
 
69
63
  private
@@ -73,23 +67,21 @@ module ActionDispatch
73
67
  end
74
68
 
75
69
  def normalize_argument_to_redirection(fragment)
76
- case fragment
77
- when %r{^\w[A-Za-z\d+.-]*:.*}
78
- fragment
79
- when String
80
- @request.protocol + @request.host_with_port + fragment
81
- when :back
82
- raise RedirectBackError unless refer = @request.headers["Referer"]
83
- refer
84
- else
85
- @controller.url_for(fragment)
86
- end.gsub(/[\0\r\n]/, '')
87
- end
70
+ normalized = case fragment
71
+ when Regexp
72
+ fragment
73
+ when %r{^\w[A-Za-z\d+.-]*:.*}
74
+ fragment
75
+ when String
76
+ @request.protocol + @request.host_with_port + fragment
77
+ when :back
78
+ raise RedirectBackError unless refer = @request.headers["Referer"]
79
+ refer
80
+ else
81
+ @controller.url_for(fragment)
82
+ end
88
83
 
89
- def validate_request!
90
- unless @request.is_a?(ActionDispatch::Request)
91
- raise ArgumentError, "@request must be an ActionDispatch::Request"
92
- end
84
+ normalized.respond_to?(:delete) ? normalized.delete("\0\r\n") : normalized
93
85
  end
94
86
  end
95
87
  end