actionpack 3.2.22.5 → 4.0.0.beta1

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 (265) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +641 -418
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -288
  5. data/lib/abstract_controller.rb +1 -8
  6. data/lib/abstract_controller/asset_paths.rb +2 -2
  7. data/lib/abstract_controller/base.rb +39 -37
  8. data/lib/abstract_controller/callbacks.rb +101 -82
  9. data/lib/abstract_controller/collector.rb +7 -3
  10. data/lib/abstract_controller/helpers.rb +23 -11
  11. data/lib/abstract_controller/layouts.rb +68 -73
  12. data/lib/abstract_controller/logger.rb +1 -2
  13. data/lib/abstract_controller/rendering.rb +22 -13
  14. data/lib/abstract_controller/translation.rb +16 -1
  15. data/lib/abstract_controller/url_for.rb +6 -6
  16. data/lib/abstract_controller/view_paths.rb +1 -1
  17. data/lib/action_controller.rb +15 -6
  18. data/lib/action_controller/base.rb +46 -22
  19. data/lib/action_controller/caching.rb +46 -33
  20. data/lib/action_controller/caching/fragments.rb +23 -53
  21. data/lib/action_controller/deprecated.rb +5 -1
  22. data/lib/action_controller/deprecated/integration_test.rb +3 -0
  23. data/lib/action_controller/log_subscriber.rb +11 -8
  24. data/lib/action_controller/metal.rb +16 -30
  25. data/lib/action_controller/metal/conditional_get.rb +76 -32
  26. data/lib/action_controller/metal/data_streaming.rb +20 -26
  27. data/lib/action_controller/metal/exceptions.rb +19 -6
  28. data/lib/action_controller/metal/flash.rb +24 -9
  29. data/lib/action_controller/metal/force_ssl.rb +32 -9
  30. data/lib/action_controller/metal/head.rb +25 -4
  31. data/lib/action_controller/metal/helpers.rb +6 -9
  32. data/lib/action_controller/metal/hide_actions.rb +1 -2
  33. data/lib/action_controller/metal/http_authentication.rb +105 -87
  34. data/lib/action_controller/metal/implicit_render.rb +1 -1
  35. data/lib/action_controller/metal/instrumentation.rb +2 -1
  36. data/lib/action_controller/metal/live.rb +141 -0
  37. data/lib/action_controller/metal/mime_responds.rb +161 -47
  38. data/lib/action_controller/metal/params_wrapper.rb +112 -74
  39. data/lib/action_controller/metal/rack_delegation.rb +9 -3
  40. data/lib/action_controller/metal/redirecting.rb +15 -20
  41. data/lib/action_controller/metal/renderers.rb +11 -9
  42. data/lib/action_controller/metal/rendering.rb +8 -0
  43. data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
  44. data/lib/action_controller/metal/responder.rb +20 -19
  45. data/lib/action_controller/metal/streaming.rb +12 -18
  46. data/lib/action_controller/metal/strong_parameters.rb +516 -0
  47. data/lib/action_controller/metal/testing.rb +13 -18
  48. data/lib/action_controller/metal/url_for.rb +27 -25
  49. data/lib/action_controller/model_naming.rb +12 -0
  50. data/lib/action_controller/railtie.rb +33 -17
  51. data/lib/action_controller/railties/helpers.rb +22 -0
  52. data/lib/action_controller/record_identifier.rb +18 -72
  53. data/lib/action_controller/test_case.rb +215 -123
  54. data/lib/action_controller/vendor/html-scanner.rb +4 -19
  55. data/lib/action_dispatch.rb +27 -19
  56. data/lib/action_dispatch/http/cache.rb +63 -11
  57. data/lib/action_dispatch/http/filter_parameters.rb +18 -8
  58. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  59. data/lib/action_dispatch/http/headers.rb +27 -19
  60. data/lib/action_dispatch/http/mime_negotiation.rb +25 -2
  61. data/lib/action_dispatch/http/mime_type.rb +145 -113
  62. data/lib/action_dispatch/http/mime_types.rb +1 -1
  63. data/lib/action_dispatch/http/parameter_filter.rb +44 -46
  64. data/lib/action_dispatch/http/parameters.rb +12 -5
  65. data/lib/action_dispatch/http/rack_cache.rb +2 -3
  66. data/lib/action_dispatch/http/request.rb +49 -18
  67. data/lib/action_dispatch/http/response.rb +129 -35
  68. data/lib/action_dispatch/http/upload.rb +60 -17
  69. data/lib/action_dispatch/http/url.rb +53 -31
  70. data/lib/action_dispatch/journey.rb +5 -0
  71. data/lib/action_dispatch/journey/backwards.rb +5 -0
  72. data/lib/action_dispatch/journey/formatter.rb +146 -0
  73. data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
  74. data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
  75. data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
  76. data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
  77. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  78. data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
  79. data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
  80. data/lib/action_dispatch/journey/nodes/node.rb +124 -0
  81. data/lib/action_dispatch/journey/parser.rb +206 -0
  82. data/lib/action_dispatch/journey/parser.y +47 -0
  83. data/lib/action_dispatch/journey/parser_extras.rb +23 -0
  84. data/lib/action_dispatch/journey/path/pattern.rb +196 -0
  85. data/lib/action_dispatch/journey/route.rb +116 -0
  86. data/lib/action_dispatch/journey/router.rb +164 -0
  87. data/lib/action_dispatch/journey/router/strexp.rb +24 -0
  88. data/lib/action_dispatch/journey/router/utils.rb +54 -0
  89. data/lib/action_dispatch/journey/routes.rb +75 -0
  90. data/lib/action_dispatch/journey/scanner.rb +61 -0
  91. data/lib/action_dispatch/journey/visitors.rb +189 -0
  92. data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
  93. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  94. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  95. data/lib/action_dispatch/middleware/callbacks.rb +9 -4
  96. data/lib/action_dispatch/middleware/cookies.rb +168 -57
  97. data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
  98. data/lib/action_dispatch/middleware/exception_wrapper.rb +27 -3
  99. data/lib/action_dispatch/middleware/flash.rb +58 -58
  100. data/lib/action_dispatch/middleware/params_parser.rb +14 -29
  101. data/lib/action_dispatch/middleware/public_exceptions.rb +31 -14
  102. data/lib/action_dispatch/middleware/reloader.rb +6 -6
  103. data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
  104. data/lib/action_dispatch/middleware/request_id.rb +2 -6
  105. data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
  106. data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
  107. data/lib/action_dispatch/middleware/session/cookie_store.rb +81 -7
  108. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
  109. data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
  110. data/lib/action_dispatch/middleware/ssl.rb +70 -0
  111. data/lib/action_dispatch/middleware/stack.rb +6 -1
  112. data/lib/action_dispatch/middleware/static.rb +5 -24
  113. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
  114. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
  115. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +3 -3
  116. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
  117. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +121 -5
  118. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
  119. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
  120. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
  121. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
  122. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  123. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
  124. data/lib/action_dispatch/railtie.rb +16 -6
  125. data/lib/action_dispatch/request/session.rb +181 -0
  126. data/lib/action_dispatch/routing.rb +41 -40
  127. data/lib/action_dispatch/routing/inspector.rb +240 -0
  128. data/lib/action_dispatch/routing/mapper.rb +501 -273
  129. data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
  130. data/lib/action_dispatch/routing/redirection.rb +46 -29
  131. data/lib/action_dispatch/routing/route_set.rb +203 -164
  132. data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
  133. data/lib/action_dispatch/routing/url_for.rb +48 -33
  134. data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
  135. data/lib/action_dispatch/testing/assertions/response.rb +32 -40
  136. data/lib/action_dispatch/testing/assertions/routing.rb +40 -39
  137. data/lib/action_dispatch/testing/assertions/selector.rb +15 -20
  138. data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
  139. data/lib/action_dispatch/testing/integration.rb +41 -22
  140. data/lib/action_dispatch/testing/test_process.rb +9 -6
  141. data/lib/action_dispatch/testing/test_request.rb +7 -3
  142. data/lib/action_pack.rb +1 -1
  143. data/lib/action_pack/version.rb +4 -4
  144. data/lib/action_view.rb +17 -8
  145. data/lib/action_view/base.rb +15 -34
  146. data/lib/action_view/buffers.rb +1 -1
  147. data/lib/action_view/context.rb +4 -4
  148. data/lib/action_view/dependency_tracker.rb +91 -0
  149. data/lib/action_view/digestor.rb +85 -0
  150. data/lib/action_view/flows.rb +1 -4
  151. data/lib/action_view/helpers.rb +2 -4
  152. data/lib/action_view/helpers/active_model_helper.rb +3 -4
  153. data/lib/action_view/helpers/asset_tag_helper.rb +211 -353
  154. data/lib/action_view/helpers/asset_url_helper.rb +354 -0
  155. data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
  156. data/lib/action_view/helpers/cache_helper.rb +150 -18
  157. data/lib/action_view/helpers/capture_helper.rb +42 -29
  158. data/lib/action_view/helpers/csrf_helper.rb +0 -2
  159. data/lib/action_view/helpers/date_helper.rb +268 -247
  160. data/lib/action_view/helpers/debug_helper.rb +10 -11
  161. data/lib/action_view/helpers/form_helper.rb +904 -547
  162. data/lib/action_view/helpers/form_options_helper.rb +341 -166
  163. data/lib/action_view/helpers/form_tag_helper.rb +188 -88
  164. data/lib/action_view/helpers/javascript_helper.rb +23 -16
  165. data/lib/action_view/helpers/number_helper.rb +148 -354
  166. data/lib/action_view/helpers/output_safety_helper.rb +3 -3
  167. data/lib/action_view/helpers/record_tag_helper.rb +17 -22
  168. data/lib/action_view/helpers/rendering_helper.rb +2 -4
  169. data/lib/action_view/helpers/sanitize_helper.rb +3 -6
  170. data/lib/action_view/helpers/tag_helper.rb +43 -37
  171. data/lib/action_view/helpers/tags.rb +39 -0
  172. data/lib/action_view/helpers/tags/base.rb +148 -0
  173. data/lib/action_view/helpers/tags/check_box.rb +64 -0
  174. data/lib/action_view/helpers/tags/checkable.rb +16 -0
  175. data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
  176. data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
  177. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
  178. data/lib/action_view/helpers/tags/collection_select.rb +28 -0
  179. data/lib/action_view/helpers/tags/color_field.rb +25 -0
  180. data/lib/action_view/helpers/tags/date_field.rb +13 -0
  181. data/lib/action_view/helpers/tags/date_select.rb +72 -0
  182. data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
  183. data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
  184. data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
  185. data/lib/action_view/helpers/tags/email_field.rb +8 -0
  186. data/lib/action_view/helpers/tags/file_field.rb +8 -0
  187. data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
  188. data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
  189. data/lib/action_view/helpers/tags/label.rb +65 -0
  190. data/lib/action_view/helpers/tags/month_field.rb +13 -0
  191. data/lib/action_view/helpers/tags/number_field.rb +18 -0
  192. data/lib/action_view/helpers/tags/password_field.rb +12 -0
  193. data/lib/action_view/helpers/tags/radio_button.rb +31 -0
  194. data/lib/action_view/helpers/tags/range_field.rb +8 -0
  195. data/lib/action_view/helpers/tags/search_field.rb +24 -0
  196. data/lib/action_view/helpers/tags/select.rb +41 -0
  197. data/lib/action_view/helpers/tags/tel_field.rb +8 -0
  198. data/lib/action_view/helpers/tags/text_area.rb +18 -0
  199. data/lib/action_view/helpers/tags/text_field.rb +29 -0
  200. data/lib/action_view/helpers/tags/time_field.rb +13 -0
  201. data/lib/action_view/helpers/tags/time_select.rb +8 -0
  202. data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
  203. data/lib/action_view/helpers/tags/url_field.rb +8 -0
  204. data/lib/action_view/helpers/tags/week_field.rb +13 -0
  205. data/lib/action_view/helpers/text_helper.rb +126 -113
  206. data/lib/action_view/helpers/translation_helper.rb +32 -16
  207. data/lib/action_view/helpers/url_helper.rb +200 -271
  208. data/lib/action_view/locale/en.yml +1 -105
  209. data/lib/action_view/log_subscriber.rb +6 -4
  210. data/lib/action_view/lookup_context.rb +15 -39
  211. data/lib/action_view/model_naming.rb +12 -0
  212. data/lib/action_view/path_set.rb +9 -39
  213. data/lib/action_view/railtie.rb +6 -22
  214. data/lib/action_view/record_identifier.rb +84 -0
  215. data/lib/action_view/renderer/abstract_renderer.rb +10 -19
  216. data/lib/action_view/renderer/partial_renderer.rb +144 -81
  217. data/lib/action_view/renderer/renderer.rb +2 -19
  218. data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
  219. data/lib/action_view/renderer/template_renderer.rb +14 -13
  220. data/lib/action_view/routing_url_for.rb +107 -0
  221. data/lib/action_view/template.rb +22 -21
  222. data/lib/action_view/template/error.rb +22 -12
  223. data/lib/action_view/template/handlers.rb +12 -9
  224. data/lib/action_view/template/handlers/builder.rb +1 -1
  225. data/lib/action_view/template/handlers/erb.rb +11 -16
  226. data/lib/action_view/template/handlers/raw.rb +11 -0
  227. data/lib/action_view/template/resolver.rb +111 -83
  228. data/lib/action_view/template/text.rb +12 -8
  229. data/lib/action_view/template/types.rb +57 -0
  230. data/lib/action_view/test_case.rb +66 -43
  231. data/lib/action_view/testing/resolvers.rb +3 -2
  232. data/lib/action_view/vendor/html-scanner.rb +20 -0
  233. data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
  234. data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
  235. data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +18 -7
  236. data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +1 -1
  237. data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
  238. data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
  239. metadata +135 -125
  240. data/lib/action_controller/caching/actions.rb +0 -185
  241. data/lib/action_controller/caching/pages.rb +0 -187
  242. data/lib/action_controller/caching/sweeping.rb +0 -97
  243. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  244. data/lib/action_controller/metal/compatibility.rb +0 -65
  245. data/lib/action_controller/metal/session_management.rb +0 -14
  246. data/lib/action_controller/railties/paths.rb +0 -25
  247. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  248. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  249. data/lib/action_dispatch/middleware/head.rb +0 -18
  250. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  251. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  252. data/lib/action_view/asset_paths.rb +0 -142
  253. data/lib/action_view/helpers/asset_paths.rb +0 -7
  254. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  255. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  256. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  257. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  258. data/lib/sprockets/assets.rake +0 -99
  259. data/lib/sprockets/bootstrap.rb +0 -37
  260. data/lib/sprockets/compressors.rb +0 -83
  261. data/lib/sprockets/helpers.rb +0 -6
  262. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  263. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  264. data/lib/sprockets/railtie.rb +0 -62
  265. data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/array/extract_options'
2
+
1
3
  module ActionDispatch
2
4
  module Routing
3
5
  class RoutesProxy #:nodoc:
@@ -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,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
@@ -1,6 +1,6 @@
1
1
  require 'uri'
2
- require 'active_support/core_ext/hash/diff'
3
2
  require 'active_support/core_ext/hash/indifferent_access'
3
+ require 'active_support/core_ext/string/access'
4
4
  require 'action_controller/metal/exceptions'
5
5
 
6
6
  module ActionDispatch
@@ -15,38 +15,40 @@ module ActionDispatch
15
15
  # and a :method containing the required HTTP verb.
16
16
  #
17
17
  # # assert that POSTing to /items will call the create action on ItemsController
18
- # assert_recognizes({:controller => 'items', :action => 'create'}, {:path => 'items', :method => :post})
18
+ # assert_recognizes({controller: 'items', action: 'create'}, {path: 'items', method: :post})
19
19
  #
20
20
  # You can also pass in +extras+ with a hash containing URL parameters that would normally be in the query string. This can be used
21
21
  # to assert that values in the query string string will end up in the params hash correctly. To test query strings you must use the
22
22
  # extras argument, appending the query string on the path directly will not work. For example:
23
23
  #
24
24
  # # assert that a path of '/items/list/1?view=print' returns the correct options
25
- # assert_recognizes({:controller => 'items', :action => 'list', :id => '1', :view => 'print'}, 'items/list/1', { :view => "print" })
25
+ # assert_recognizes({controller: 'items', action: 'list', id: '1', view: 'print'}, 'items/list/1', { view: "print" })
26
26
  #
27
27
  # The +message+ parameter allows you to pass in an error message that is displayed upon failure.
28
28
  #
29
- # ==== Examples
30
29
  # # Check the default route (i.e., the index action)
31
- # assert_recognizes({:controller => 'items', :action => 'index'}, 'items')
30
+ # assert_recognizes({controller: 'items', action: 'index'}, 'items')
32
31
  #
33
32
  # # Test a specific action
34
- # assert_recognizes({:controller => 'items', :action => 'list'}, 'items/list')
33
+ # assert_recognizes({controller: 'items', action: 'list'}, 'items/list')
35
34
  #
36
35
  # # Test an action with a parameter
37
- # assert_recognizes({:controller => 'items', :action => 'destroy', :id => '1'}, 'items/destroy/1')
36
+ # assert_recognizes({controller: 'items', action: 'destroy', id: '1'}, 'items/destroy/1')
38
37
  #
39
38
  # # Test a custom route
40
- # assert_recognizes({:controller => 'items', :action => 'show', :id => '1'}, 'view/item1')
41
- def assert_recognizes(expected_options, path, extras={}, message=nil)
39
+ # assert_recognizes({controller: 'items', action: 'show', id: '1'}, 'view/item1')
40
+ def assert_recognizes(expected_options, path, extras={}, msg=nil)
42
41
  request = recognized_request_for(path, extras)
43
42
 
44
43
  expected_options = expected_options.clone
45
- extras.each_key { |key| expected_options.delete key } unless extras.nil?
46
44
 
47
45
  expected_options.stringify_keys!
48
- msg = build_message(message, "The recognized options <?> did not match <?>, difference: <?>",
49
- request.path_parameters, expected_options, expected_options.diff(request.path_parameters))
46
+
47
+ msg = message(msg, "") {
48
+ sprintf("The recognized options <%s> did not match <%s>, difference:",
49
+ request.path_parameters, expected_options)
50
+ }
51
+
50
52
  assert_equal(expected_options, request.path_parameters, msg)
51
53
  end
52
54
 
@@ -56,25 +58,22 @@ module ActionDispatch
56
58
  #
57
59
  # The +defaults+ parameter is unused.
58
60
  #
59
- # ==== Examples
60
61
  # # Asserts that the default action is generated for a route with no action
61
- # assert_generates "/items", :controller => "items", :action => "index"
62
+ # assert_generates "/items", controller: "items", action: "index"
62
63
  #
63
64
  # # Tests that the list action is properly routed
64
- # assert_generates "/items/list", :controller => "items", :action => "list"
65
+ # assert_generates "/items/list", controller: "items", action: "list"
65
66
  #
66
67
  # # Tests the generation of a route with a parameter
67
- # assert_generates "/items/list/1", { :controller => "items", :action => "list", :id => "1" }
68
+ # assert_generates "/items/list/1", { controller: "items", action: "list", id: "1" }
68
69
  #
69
70
  # # Asserts that the generated route gives us our custom route
70
- # assert_generates "changesets/12", { :controller => 'scm', :action => 'show_diff', :revision => "12" }
71
+ # assert_generates "changesets/12", { controller: 'scm', action: 'show_diff', revision: "12" }
71
72
  def assert_generates(expected_path, options, defaults={}, extras = {}, message=nil)
72
73
  if expected_path =~ %r{://}
73
- begin
74
+ fail_on(URI::InvalidURIError) do
74
75
  uri = URI.parse(expected_path)
75
76
  expected_path = uri.path.to_s.empty? ? "/" : uri.path
76
- rescue URI::InvalidURIError => e
77
- raise ActionController::RoutingError, e.message
78
77
  end
79
78
  else
80
79
  expected_path = "/#{expected_path}" unless expected_path.first == '/'
@@ -84,10 +83,10 @@ module ActionDispatch
84
83
  generated_path, extra_keys = @routes.generate_extras(options, defaults)
85
84
  found_extras = options.reject {|k, v| ! extra_keys.include? k}
86
85
 
87
- msg = build_message(message, "found extras <?>, not <?>", found_extras, extras)
86
+ msg = message || sprintf("found extras <%s>, not <%s>", found_extras, extras)
88
87
  assert_equal(extras, found_extras, msg)
89
88
 
90
- msg = build_message(message, "The generated path <?> did not match <?>", generated_path,
89
+ msg = message || sprintf("The generated path <%s> did not match <%s>", generated_path,
91
90
  expected_path)
92
91
  assert_equal(expected_path, generated_path, msg)
93
92
  end
@@ -99,21 +98,20 @@ module ActionDispatch
99
98
  # The +extras+ hash allows you to specify options that would normally be provided as a query string to the action. The
100
99
  # +message+ parameter allows you to specify a custom error message to display upon failure.
101
100
  #
102
- # ==== Examples
103
101
  # # Assert a basic route: a controller with the default action (index)
104
- # assert_routing '/home', :controller => 'home', :action => 'index'
102
+ # assert_routing '/home', controller: 'home', action: 'index'
105
103
  #
106
104
  # # Test a route generated with a specific controller, action, and parameter (id)
107
- # assert_routing '/entries/show/23', :controller => 'entries', :action => 'show', :id => 23
105
+ # assert_routing '/entries/show/23', controller: 'entries', action: 'show', id: 23
108
106
  #
109
107
  # # Assert a basic route (controller + default action), with an error message if it fails
110
- # assert_routing '/store', { :controller => 'store', :action => 'index' }, {}, {}, 'Route for store index not generated properly'
108
+ # assert_routing '/store', { controller: 'store', action: 'index' }, {}, {}, 'Route for store index not generated properly'
111
109
  #
112
110
  # # Tests a route, providing a defaults hash
113
- # assert_routing 'controller/action/9', {:id => "9", :item => "square"}, {:controller => "controller", :action => "action"}, {}, {:item => "square"}
111
+ # assert_routing 'controller/action/9', {id: "9", item: "square"}, {controller: "controller", action: "action"}, {}, {item: "square"}
114
112
  #
115
113
  # # Tests a route with a HTTP method
116
- # assert_routing({ :method => 'put', :path => '/product/321' }, { :controller => "product", :action => "update", :id => "321" })
114
+ # assert_routing({ method: 'put', path: '/product/321' }, { controller: "product", action: "update", id: "321" })
117
115
  def assert_routing(path, options, defaults={}, extras={}, message=nil)
118
116
  assert_recognizes(options, path, extras, message)
119
117
 
@@ -131,16 +129,13 @@ module ActionDispatch
131
129
  # with a new RouteSet instance.
132
130
  #
133
131
  # The new instance is yielded to the passed block. Typically the block
134
- # will create some routes using <tt>map.draw { map.connect ... }</tt>:
132
+ # will create some routes using <tt>set.draw { match ... }</tt>:
135
133
  #
136
134
  # with_routing do |set|
137
- # set.draw do |map|
138
- # map.connect ':controller/:action/:id'
139
- # assert_equal(
140
- # ['/content/10/show', {}],
141
- # map.generate(:controller => 'content', :id => 10, :action => 'show')
142
- # end
135
+ # set.draw do
136
+ # resources :users
143
137
  # end
138
+ # assert_equal "/users", users_path
144
139
  # end
145
140
  #
146
141
  def with_routing
@@ -191,14 +186,12 @@ module ActionDispatch
191
186
  request = ActionController::TestRequest.new
192
187
 
193
188
  if path =~ %r{://}
194
- begin
189
+ fail_on(URI::InvalidURIError) do
195
190
  uri = URI.parse(path)
196
191
  request.env["rack.url_scheme"] = uri.scheme || "http"
197
192
  request.host = uri.host if uri.host
198
193
  request.port = uri.port if uri.port
199
194
  request.path = uri.path.to_s.empty? ? "/" : uri.path
200
- rescue URI::InvalidURIError => e
201
- raise ActionController::RoutingError, e.message
202
195
  end
203
196
  else
204
197
  path = "/#{path}" unless path.first == "/"
@@ -207,11 +200,19 @@ module ActionDispatch
207
200
 
208
201
  request.request_method = method if method
209
202
 
210
- params = @routes.recognize_path(path, { :method => method, :extras => extras })
203
+ params = fail_on(ActionController::RoutingError) do
204
+ @routes.recognize_path(path, { :method => method, :extras => extras })
205
+ end
211
206
  request.path_parameters = params.with_indifferent_access
212
207
 
213
208
  request
214
209
  end
210
+
211
+ def fail_on(exception_class)
212
+ yield
213
+ rescue exception_class => e
214
+ raise MiniTest::Assertion, e.message
215
+ end
215
216
  end
216
217
  end
217
218
  end