actionpack 4.2.10 → 7.2.0.rc1

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 (202) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +86 -600
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +13 -14
  5. data/lib/abstract_controller/asset_paths.rb +5 -1
  6. data/lib/abstract_controller/base.rb +166 -136
  7. data/lib/abstract_controller/caching/fragments.rb +149 -0
  8. data/lib/abstract_controller/caching.rb +68 -0
  9. data/lib/abstract_controller/callbacks.rb +126 -57
  10. data/lib/abstract_controller/collector.rb +13 -15
  11. data/lib/abstract_controller/deprecator.rb +9 -0
  12. data/lib/abstract_controller/error.rb +8 -0
  13. data/lib/abstract_controller/helpers.rb +181 -132
  14. data/lib/abstract_controller/logger.rb +5 -1
  15. data/lib/abstract_controller/railties/routes_helpers.rb +10 -3
  16. data/lib/abstract_controller/rendering.rb +56 -56
  17. data/lib/abstract_controller/translation.rb +29 -15
  18. data/lib/abstract_controller/url_for.rb +15 -11
  19. data/lib/abstract_controller.rb +21 -5
  20. data/lib/action_controller/api/api_rendering.rb +18 -0
  21. data/lib/action_controller/api.rb +154 -0
  22. data/lib/action_controller/base.rb +219 -155
  23. data/lib/action_controller/caching.rb +28 -68
  24. data/lib/action_controller/deprecator.rb +9 -0
  25. data/lib/action_controller/form_builder.rb +55 -0
  26. data/lib/action_controller/log_subscriber.rb +35 -22
  27. data/lib/action_controller/metal/allow_browser.rb +119 -0
  28. data/lib/action_controller/metal/basic_implicit_render.rb +17 -0
  29. data/lib/action_controller/metal/conditional_get.rb +259 -122
  30. data/lib/action_controller/metal/content_security_policy.rb +86 -0
  31. data/lib/action_controller/metal/cookies.rb +9 -5
  32. data/lib/action_controller/metal/data_streaming.rb +87 -104
  33. data/lib/action_controller/metal/default_headers.rb +21 -0
  34. data/lib/action_controller/metal/etag_with_flash.rb +22 -0
  35. data/lib/action_controller/metal/etag_with_template_digest.rb +35 -26
  36. data/lib/action_controller/metal/exceptions.rb +71 -24
  37. data/lib/action_controller/metal/flash.rb +26 -19
  38. data/lib/action_controller/metal/head.rb +45 -36
  39. data/lib/action_controller/metal/helpers.rb +80 -64
  40. data/lib/action_controller/metal/http_authentication.rb +297 -244
  41. data/lib/action_controller/metal/implicit_render.rb +57 -9
  42. data/lib/action_controller/metal/instrumentation.rb +76 -64
  43. data/lib/action_controller/metal/live.rb +238 -176
  44. data/lib/action_controller/metal/logging.rb +22 -0
  45. data/lib/action_controller/metal/mime_responds.rb +177 -166
  46. data/lib/action_controller/metal/parameter_encoding.rb +84 -0
  47. data/lib/action_controller/metal/params_wrapper.rb +145 -118
  48. data/lib/action_controller/metal/permissions_policy.rb +38 -0
  49. data/lib/action_controller/metal/rate_limiting.rb +62 -0
  50. data/lib/action_controller/metal/redirecting.rb +203 -64
  51. data/lib/action_controller/metal/renderers.rb +108 -65
  52. data/lib/action_controller/metal/rendering.rb +216 -56
  53. data/lib/action_controller/metal/request_forgery_protection.rb +496 -163
  54. data/lib/action_controller/metal/rescue.rb +19 -21
  55. data/lib/action_controller/metal/streaming.rb +179 -138
  56. data/lib/action_controller/metal/strong_parameters.rb +1058 -382
  57. data/lib/action_controller/metal/testing.rb +11 -17
  58. data/lib/action_controller/metal/url_for.rb +37 -21
  59. data/lib/action_controller/metal.rb +236 -138
  60. data/lib/action_controller/railtie.rb +89 -11
  61. data/lib/action_controller/railties/helpers.rb +5 -1
  62. data/lib/action_controller/renderer.rb +161 -0
  63. data/lib/action_controller/template_assertions.rb +13 -0
  64. data/lib/action_controller/test_case.rb +425 -497
  65. data/lib/action_controller.rb +44 -22
  66. data/lib/action_dispatch/constants.rb +34 -0
  67. data/lib/action_dispatch/deprecator.rb +9 -0
  68. data/lib/action_dispatch/http/cache.rb +119 -63
  69. data/lib/action_dispatch/http/content_disposition.rb +47 -0
  70. data/lib/action_dispatch/http/content_security_policy.rb +364 -0
  71. data/lib/action_dispatch/http/filter_parameters.rb +36 -34
  72. data/lib/action_dispatch/http/filter_redirect.rb +24 -12
  73. data/lib/action_dispatch/http/headers.rb +66 -31
  74. data/lib/action_dispatch/http/mime_negotiation.rb +106 -75
  75. data/lib/action_dispatch/http/mime_type.rb +196 -136
  76. data/lib/action_dispatch/http/mime_types.rb +25 -7
  77. data/lib/action_dispatch/http/parameters.rb +97 -45
  78. data/lib/action_dispatch/http/permissions_policy.rb +187 -0
  79. data/lib/action_dispatch/http/rack_cache.rb +6 -0
  80. data/lib/action_dispatch/http/request.rb +299 -170
  81. data/lib/action_dispatch/http/response.rb +311 -160
  82. data/lib/action_dispatch/http/upload.rb +52 -23
  83. data/lib/action_dispatch/http/url.rb +201 -125
  84. data/lib/action_dispatch/journey/formatter.rb +110 -50
  85. data/lib/action_dispatch/journey/gtg/builder.rb +37 -50
  86. data/lib/action_dispatch/journey/gtg/simulator.rb +20 -17
  87. data/lib/action_dispatch/journey/gtg/transition_table.rb +96 -36
  88. data/lib/action_dispatch/journey/nfa/dot.rb +5 -14
  89. data/lib/action_dispatch/journey/nodes/node.rb +100 -20
  90. data/lib/action_dispatch/journey/parser.rb +19 -17
  91. data/lib/action_dispatch/journey/parser.y +4 -3
  92. data/lib/action_dispatch/journey/parser_extras.rb +14 -4
  93. data/lib/action_dispatch/journey/path/pattern.rb +79 -63
  94. data/lib/action_dispatch/journey/route.rb +108 -44
  95. data/lib/action_dispatch/journey/router/utils.rb +41 -29
  96. data/lib/action_dispatch/journey/router.rb +64 -57
  97. data/lib/action_dispatch/journey/routes.rb +23 -21
  98. data/lib/action_dispatch/journey/scanner.rb +28 -17
  99. data/lib/action_dispatch/journey/visitors.rb +100 -54
  100. data/lib/action_dispatch/journey/visualizer/fsm.js +49 -24
  101. data/lib/action_dispatch/journey/visualizer/index.html.erb +1 -1
  102. data/lib/action_dispatch/journey.rb +7 -5
  103. data/lib/action_dispatch/log_subscriber.rb +25 -0
  104. data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
  105. data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
  106. data/lib/action_dispatch/middleware/callbacks.rb +7 -6
  107. data/lib/action_dispatch/middleware/cookies.rb +471 -328
  108. data/lib/action_dispatch/middleware/debug_exceptions.rb +149 -66
  109. data/lib/action_dispatch/middleware/debug_locks.rb +129 -0
  110. data/lib/action_dispatch/middleware/debug_view.rb +73 -0
  111. data/lib/action_dispatch/middleware/exception_wrapper.rb +275 -73
  112. data/lib/action_dispatch/middleware/executor.rb +32 -0
  113. data/lib/action_dispatch/middleware/flash.rb +143 -101
  114. data/lib/action_dispatch/middleware/host_authorization.rb +171 -0
  115. data/lib/action_dispatch/middleware/public_exceptions.rb +36 -27
  116. data/lib/action_dispatch/middleware/reloader.rb +10 -92
  117. data/lib/action_dispatch/middleware/remote_ip.rb +133 -107
  118. data/lib/action_dispatch/middleware/request_id.rb +29 -15
  119. data/lib/action_dispatch/middleware/server_timing.rb +78 -0
  120. data/lib/action_dispatch/middleware/session/abstract_store.rb +49 -27
  121. data/lib/action_dispatch/middleware/session/cache_store.rb +33 -16
  122. data/lib/action_dispatch/middleware/session/cookie_store.rb +86 -80
  123. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +15 -3
  124. data/lib/action_dispatch/middleware/show_exceptions.rb +66 -36
  125. data/lib/action_dispatch/middleware/ssl.rb +134 -36
  126. data/lib/action_dispatch/middleware/stack.rb +109 -44
  127. data/lib/action_dispatch/middleware/static.rb +159 -90
  128. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +7 -24
  132. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
  133. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +36 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +46 -36
  136. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +12 -0
  137. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +9 -0
  138. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +26 -7
  139. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +3 -3
  140. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
  141. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +16 -0
  142. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +139 -15
  143. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +23 -0
  144. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  145. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +6 -6
  146. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +7 -7
  147. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +9 -9
  148. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  149. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +4 -4
  150. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
  151. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +7 -4
  152. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +125 -93
  153. data/lib/action_dispatch/railtie.rb +44 -16
  154. data/lib/action_dispatch/request/session.rb +159 -69
  155. data/lib/action_dispatch/request/utils.rb +97 -23
  156. data/lib/action_dispatch/routing/endpoint.rb +11 -2
  157. data/lib/action_dispatch/routing/inspector.rb +195 -106
  158. data/lib/action_dispatch/routing/mapper.rb +1338 -955
  159. data/lib/action_dispatch/routing/polymorphic_routes.rb +234 -201
  160. data/lib/action_dispatch/routing/redirection.rb +78 -51
  161. data/lib/action_dispatch/routing/route_set.rb +460 -374
  162. data/lib/action_dispatch/routing/routes_proxy.rb +36 -12
  163. data/lib/action_dispatch/routing/url_for.rb +172 -124
  164. data/lib/action_dispatch/routing.rb +159 -158
  165. data/lib/action_dispatch/system_test_case.rb +206 -0
  166. data/lib/action_dispatch/system_testing/browser.rb +84 -0
  167. data/lib/action_dispatch/system_testing/driver.rb +85 -0
  168. data/lib/action_dispatch/system_testing/server.rb +33 -0
  169. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +164 -0
  170. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +23 -0
  171. data/lib/action_dispatch/testing/assertion_response.rb +48 -0
  172. data/lib/action_dispatch/testing/assertions/response.rb +71 -39
  173. data/lib/action_dispatch/testing/assertions/routing.rb +228 -103
  174. data/lib/action_dispatch/testing/assertions.rb +9 -6
  175. data/lib/action_dispatch/testing/integration.rb +486 -306
  176. data/lib/action_dispatch/testing/request_encoder.rb +60 -0
  177. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  178. data/lib/action_dispatch/testing/test_process.rb +35 -22
  179. data/lib/action_dispatch/testing/test_request.rb +29 -34
  180. data/lib/action_dispatch/testing/test_response.rb +48 -15
  181. data/lib/action_dispatch.rb +82 -40
  182. data/lib/action_pack/gem_version.rb +8 -4
  183. data/lib/action_pack/version.rb +6 -2
  184. data/lib/action_pack.rb +21 -18
  185. metadata +146 -56
  186. data/lib/action_controller/caching/fragments.rb +0 -103
  187. data/lib/action_controller/metal/force_ssl.rb +0 -97
  188. data/lib/action_controller/metal/hide_actions.rb +0 -40
  189. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  190. data/lib/action_controller/middleware.rb +0 -39
  191. data/lib/action_controller/model_naming.rb +0 -12
  192. data/lib/action_dispatch/http/parameter_filter.rb +0 -72
  193. data/lib/action_dispatch/journey/backwards.rb +0 -5
  194. data/lib/action_dispatch/journey/nfa/builder.rb +0 -76
  195. data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
  196. data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -163
  197. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  198. data/lib/action_dispatch/middleware/params_parser.rb +0 -60
  199. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +0 -27
  200. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  201. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  202. data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -1,261 +1,262 @@
1
- # encoding: UTF-8
2
- require 'active_support/core_ext/object/to_param'
3
- require 'active_support/core_ext/regexp'
4
- require 'active_support/dependencies/autoload'
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
5
4
 
6
5
  module ActionDispatch
7
6
  # The routing module provides URL rewriting in native Ruby. It's a way to
8
7
  # redirect incoming requests to controllers and actions. This replaces
9
- # mod_rewrite rules. Best of all, Rails' \Routing works with any web server.
10
- # Routes are defined in <tt>config/routes.rb</tt>.
8
+ # mod_rewrite rules. Best of all, Rails' Routing works with any web server.
9
+ # Routes are defined in `config/routes.rb`.
11
10
  #
12
11
  # Think of creating routes as drawing a map for your requests. The map tells
13
12
  # them where to go based on some predefined pattern:
14
13
  #
15
- # Rails.application.routes.draw do
16
- # Pattern 1 tells some request to go to one place
17
- # Pattern 2 tell them to go to another
18
- # ...
19
- # end
14
+ # Rails.application.routes.draw do
15
+ # Pattern 1 tells some request to go to one place
16
+ # Pattern 2 tell them to go to another
17
+ # ...
18
+ # end
20
19
  #
21
20
  # The following symbols are special:
22
21
  #
23
- # :controller maps to your controller name
24
- # :action maps to an action with your controllers
22
+ # :controller maps to your controller name
23
+ # :action maps to an action with your controllers
25
24
  #
26
- # Other names simply map to a parameter as in the case of <tt>:id</tt>.
25
+ # Other names simply map to a parameter as in the case of `:id`.
27
26
  #
28
- # == Resources
27
+ # ## Resources
29
28
  #
30
- # Resource routing allows you to quickly declare all of the common routes
31
- # for a given resourceful controller. Instead of declaring separate routes
32
- # for your +index+, +show+, +new+, +edit+, +create+, +update+ and +destroy+
33
- # actions, a resourceful route declares them in a single line of code:
29
+ # Resource routing allows you to quickly declare all of the common routes for a
30
+ # given resourceful controller. Instead of declaring separate routes for your
31
+ # `index`, `show`, `new`, `edit`, `create`, `update`, and `destroy` actions, a
32
+ # resourceful route declares them in a single line of code:
34
33
  #
35
- # resources :photos
34
+ # resources :photos
36
35
  #
37
- # Sometimes, you have a resource that clients always look up without
38
- # referencing an ID. A common example, /profile always shows the profile of
39
- # the currently logged in user. In this case, you can use a singular resource
40
- # to map /profile (rather than /profile/:id) to the show action.
36
+ # Sometimes, you have a resource that clients always look up without referencing
37
+ # an ID. A common example, /profile always shows the profile of the currently
38
+ # logged in user. In this case, you can use a singular resource to map /profile
39
+ # (rather than /profile/:id) to the show action.
41
40
  #
42
- # resource :profile
41
+ # resource :profile
43
42
  #
44
- # It's common to have resources that are logically children of other
45
- # resources:
43
+ # It's common to have resources that are logically children of other resources:
46
44
  #
47
- # resources :magazines do
48
- # resources :ads
49
- # end
45
+ # resources :magazines do
46
+ # resources :ads
47
+ # end
50
48
  #
51
49
  # You may wish to organize groups of controllers under a namespace. Most
52
- # commonly, you might group a number of administrative controllers under
53
- # an +admin+ namespace. You would place these controllers under the
54
- # <tt>app/controllers/admin</tt> directory, and you can group them together
55
- # in your router:
50
+ # commonly, you might group a number of administrative controllers under an
51
+ # `admin` namespace. You would place these controllers under the
52
+ # `app/controllers/admin` directory, and you can group them together in your
53
+ # router:
56
54
  #
57
- # namespace "admin" do
58
- # resources :posts, :comments
59
- # end
55
+ # namespace "admin" do
56
+ # resources :posts, :comments
57
+ # end
60
58
  #
61
- # Alternately, you can add prefixes to your path without using a separate
62
- # directory by using +scope+. +scope+ takes additional options which
63
- # apply to all enclosed routes.
59
+ # Alternatively, you can add prefixes to your path without using a separate
60
+ # directory by using `scope`. `scope` takes additional options which apply to
61
+ # all enclosed routes.
64
62
  #
65
- # scope path: "/cpanel", as: 'admin' do
66
- # resources :posts, :comments
67
- # end
63
+ # scope path: "/cpanel", as: 'admin' do
64
+ # resources :posts, :comments
65
+ # end
68
66
  #
69
- # For more, see <tt>Routing::Mapper::Resources#resources</tt>,
70
- # <tt>Routing::Mapper::Scoping#namespace</tt>, and
71
- # <tt>Routing::Mapper::Scoping#scope</tt>.
67
+ # For more, see Routing::Mapper::Resources#resources,
68
+ # Routing::Mapper::Scoping#namespace, and Routing::Mapper::Scoping#scope.
72
69
  #
73
- # == Non-resourceful routes
70
+ # ## Non-resourceful routes
74
71
  #
75
- # For routes that don't fit the <tt>resources</tt> mold, you can use the HTTP helper
76
- # methods <tt>get</tt>, <tt>post</tt>, <tt>patch</tt>, <tt>put</tt> and <tt>delete</tt>.
72
+ # For routes that don't fit the `resources` mold, you can use the HTTP helper
73
+ # methods `get`, `post`, `patch`, `put` and `delete`.
77
74
  #
78
- # get 'post/:id' => 'posts#show'
79
- # post 'post/:id' => 'posts#create_comment'
75
+ # get 'post/:id', to: 'posts#show'
76
+ # post 'post/:id', to: 'posts#create_comment'
80
77
  #
81
- # If your route needs to respond to more than one HTTP method (or all methods) then using the
82
- # <tt>:via</tt> option on <tt>match</tt> is preferable.
78
+ # Now, if you POST to `/posts/:id`, it will route to the `create_comment`
79
+ # action. A GET on the same URL will route to the `show` action.
83
80
  #
84
- # match 'post/:id' => 'posts#show', via: [:get, :post]
81
+ # If your route needs to respond to more than one HTTP method (or all methods)
82
+ # then using the `:via` option on `match` is preferable.
85
83
  #
86
- # Now, if you POST to <tt>/posts/:id</tt>, it will route to the <tt>create_comment</tt> action. A GET on the same
87
- # URL will route to the <tt>show</tt> action.
84
+ # match 'post/:id', to: 'posts#show', via: [:get, :post]
88
85
  #
89
- # == Named routes
86
+ # ## Named routes
90
87
  #
91
- # Routes can be named by passing an <tt>:as</tt> option,
92
- # allowing for easy reference within your source as +name_of_route_url+
93
- # for the full URL and +name_of_route_path+ for the URI path.
88
+ # Routes can be named by passing an `:as` option, allowing for easy reference
89
+ # within your source as `name_of_route_url` for the full URL and
90
+ # `name_of_route_path` for the URI path.
94
91
  #
95
92
  # Example:
96
93
  #
97
- # # In routes.rb
98
- # get '/login' => 'accounts#login', as: 'login'
94
+ # # In config/routes.rb
95
+ # get '/login', to: 'accounts#login', as: 'login'
99
96
  #
100
- # # With render, redirect_to, tests, etc.
101
- # redirect_to login_url
97
+ # # With render, redirect_to, tests, etc.
98
+ # redirect_to login_url
102
99
  #
103
100
  # Arguments can be passed as well.
104
101
  #
105
- # redirect_to show_item_path(id: 25)
102
+ # redirect_to show_item_path(id: 25)
106
103
  #
107
- # Use <tt>root</tt> as a shorthand to name a route for the root path "/".
104
+ # Use `root` as a shorthand to name a route for the root path "/".
108
105
  #
109
- # # In routes.rb
110
- # root to: 'blogs#index'
106
+ # # In config/routes.rb
107
+ # root to: 'blogs#index'
111
108
  #
112
- # # would recognize http://www.example.com/ as
113
- # params = { controller: 'blogs', action: 'index' }
109
+ # # would recognize http://www.example.com/ as
110
+ # params = { controller: 'blogs', action: 'index' }
114
111
  #
115
- # # and provide these named routes
116
- # root_url # => 'http://www.example.com/'
117
- # root_path # => '/'
112
+ # # and provide these named routes
113
+ # root_url # => 'http://www.example.com/'
114
+ # root_path # => '/'
118
115
  #
119
- # Note: when using +controller+, the route is simply named after the
120
- # method you call on the block parameter rather than map.
116
+ # Note: when using `controller`, the route is simply named after the method you
117
+ # call on the block parameter rather than map.
121
118
  #
122
- # # In routes.rb
123
- # controller :blog do
124
- # get 'blog/show' => :list
125
- # get 'blog/delete' => :delete
126
- # get 'blog/edit/:id' => :edit
127
- # end
119
+ # # In config/routes.rb
120
+ # controller :blog do
121
+ # get 'blog/show' => :list
122
+ # get 'blog/delete' => :delete
123
+ # get 'blog/edit' => :edit
124
+ # end
128
125
  #
129
- # # provides named routes for show, delete, and edit
130
- # link_to @article.title, show_path(id: @article.id)
126
+ # # provides named routes for show, delete, and edit
127
+ # link_to @article.title, blog_show_path(id: @article.id)
131
128
  #
132
- # == Pretty URLs
129
+ # ## Pretty URLs
133
130
  #
134
131
  # Routes can generate pretty URLs. For example:
135
132
  #
136
- # get '/articles/:year/:month/:day' => 'articles#find_by_id', constraints: {
137
- # year: /\d{4}/,
138
- # month: /\d{1,2}/,
139
- # day: /\d{1,2}/
140
- # }
133
+ # get '/articles/:year/:month/:day', to: 'articles#find_by_id', constraints: {
134
+ # year: /\d{4}/,
135
+ # month: /\d{1,2}/,
136
+ # day: /\d{1,2}/
137
+ # }
141
138
  #
142
139
  # Using the route above, the URL "http://localhost:3000/articles/2005/11/06"
143
140
  # maps to
144
141
  #
145
- # params = {year: '2005', month: '11', day: '06'}
142
+ # params = {year: '2005', month: '11', day: '06'}
146
143
  #
147
- # == Regular Expressions and parameters
144
+ # ## Regular Expressions and parameters
148
145
  # You can specify a regular expression to define a format for a parameter.
149
146
  #
150
- # controller 'geocode' do
151
- # get 'geocode/:postalcode' => :show, constraints: {
152
- # postalcode: /\d{5}(-\d{4})?/
153
- # }
147
+ # controller 'geocode' do
148
+ # get 'geocode/:postalcode', to: :show, constraints: {
149
+ # postalcode: /\d{5}(-\d{4})?/
150
+ # }
151
+ # end
154
152
  #
155
153
  # Constraints can include the 'ignorecase' and 'extended syntax' regular
156
154
  # expression modifiers:
157
155
  #
158
- # controller 'geocode' do
159
- # get 'geocode/:postalcode' => :show, constraints: {
160
- # postalcode: /hx\d\d\s\d[a-z]{2}/i
161
- # }
162
- # end
163
- #
164
- # controller 'geocode' do
165
- # get 'geocode/:postalcode' => :show, constraints: {
166
- # postalcode: /# Postcode format
167
- # \d{5} #Prefix
168
- # (-\d{4})? #Suffix
169
- # /x
170
- # }
171
- # end
156
+ # controller 'geocode' do
157
+ # get 'geocode/:postalcode', to: :show, constraints: {
158
+ # postalcode: /hx\d\d\s\d[a-z]{2}/i
159
+ # }
160
+ # end
161
+ #
162
+ # controller 'geocode' do
163
+ # get 'geocode/:postalcode', to: :show, constraints: {
164
+ # postalcode: /# Postalcode format
165
+ # \d{5} #Prefix
166
+ # (-\d{4})? #Suffix
167
+ # /x
168
+ # }
169
+ # end
172
170
  #
173
- # Using the multiline modifier will raise an +ArgumentError+.
174
- # Encoding regular expression modifiers are silently ignored. The
175
- # match will always use the default encoding or ASCII.
171
+ # Using the multiline modifier will raise an `ArgumentError`. Encoding regular
172
+ # expression modifiers are silently ignored. The match will always use the
173
+ # default encoding or ASCII.
176
174
  #
177
- # == External redirects
175
+ # ## External redirects
178
176
  #
179
- # You can redirect any path to another path using the redirect helper in your router:
177
+ # You can redirect any path to another path using the redirect helper in your
178
+ # router:
180
179
  #
181
- # get "/stories" => redirect("/posts")
180
+ # get "/stories", to: redirect("/posts")
182
181
  #
183
- # == Unicode character routes
182
+ # ## Unicode character routes
184
183
  #
185
184
  # You can specify unicode character routes in your router:
186
185
  #
187
- # get "こんにちは" => "welcome#index"
186
+ # get "こんにちは", to: "welcome#index"
188
187
  #
189
- # == Routing to Rack Applications
188
+ # ## Routing to Rack Applications
190
189
  #
191
- # Instead of a String, like <tt>posts#index</tt>, which corresponds to the
192
- # index action in the PostsController, you can specify any Rack application
193
- # as the endpoint for a matcher:
190
+ # Instead of a String, like `posts#index`, which corresponds to the index action
191
+ # in the PostsController, you can specify any Rack application as the endpoint
192
+ # for a matcher:
194
193
  #
195
- # get "/application.js" => Sprockets
194
+ # get "/application.js", to: Sprockets
196
195
  #
197
- # == Reloading routes
196
+ # ## Reloading routes
198
197
  #
199
198
  # You can reload routes if you feel you must:
200
199
  #
201
- # Rails.application.reload_routes!
200
+ # Rails.application.reload_routes!
202
201
  #
203
- # This will clear all named routes and reload routes.rb if the file has been modified from
204
- # last load. To absolutely force reloading, use <tt>reload!</tt>.
202
+ # This will clear all named routes and reload config/routes.rb if the file has
203
+ # been modified from last load. To absolutely force reloading, use `reload!`.
205
204
  #
206
- # == Testing Routes
205
+ # ## Testing Routes
207
206
  #
208
207
  # The two main methods for testing your routes:
209
208
  #
210
- # === +assert_routing+
211
- #
212
- # def test_movie_route_properly_splits
213
- # opts = {controller: "plugin", action: "checkout", id: "2"}
214
- # assert_routing "plugin/checkout/2", opts
215
- # end
209
+ # ### `assert_routing`
216
210
  #
217
- # +assert_routing+ lets you test whether or not the route properly resolves into options.
211
+ # def test_movie_route_properly_splits
212
+ # opts = {controller: "plugin", action: "checkout", id: "2"}
213
+ # assert_routing "plugin/checkout/2", opts
214
+ # end
218
215
  #
219
- # === +assert_recognizes+
216
+ # `assert_routing` lets you test whether or not the route properly resolves into
217
+ # options.
220
218
  #
221
- # def test_route_has_options
222
- # opts = {controller: "plugin", action: "show", id: "12"}
223
- # assert_recognizes opts, "/plugins/show/12"
224
- # end
219
+ # ### `assert_recognizes`
225
220
  #
226
- # Note the subtle difference between the two: +assert_routing+ tests that
227
- # a URL fits options while +assert_recognizes+ tests that a URL
228
- # breaks into parameters properly.
221
+ # def test_route_has_options
222
+ # opts = {controller: "plugin", action: "show", id: "12"}
223
+ # assert_recognizes opts, "/plugins/show/12"
224
+ # end
229
225
  #
230
- # In tests you can simply pass the URL or named route to +get+ or +post+.
226
+ # Note the subtle difference between the two: `assert_routing` tests that a URL
227
+ # fits options while `assert_recognizes` tests that a URL breaks into parameters
228
+ # properly.
231
229
  #
232
- # def send_to_jail
233
- # get '/jail'
234
- # assert_response :success
235
- # assert_template "jail/front"
236
- # end
230
+ # In tests you can simply pass the URL or named route to `get` or `post`.
237
231
  #
238
- # def goes_to_login
239
- # get login_url
240
- # #...
241
- # end
232
+ # def send_to_jail
233
+ # get '/jail'
234
+ # assert_response :success
235
+ # end
242
236
  #
243
- # == View a list of all your routes
237
+ # def goes_to_login
238
+ # get login_url
239
+ # #...
240
+ # end
244
241
  #
245
- # rake routes
242
+ # ## View a list of all your routes
246
243
  #
247
- # Target specific controllers by prefixing the command with <tt>CONTROLLER=x</tt>.
244
+ # $ bin/rails routes
248
245
  #
246
+ # Target a specific controller with `-c`, or grep routes using `-g`. Useful in
247
+ # conjunction with `--expanded` which displays routes vertically.
249
248
  module Routing
250
249
  extend ActiveSupport::Autoload
251
250
 
252
251
  autoload :Mapper
253
252
  autoload :RouteSet
254
- autoload :RoutesProxy
253
+ eager_autoload do
254
+ autoload :RoutesProxy
255
+ end
255
256
  autoload :UrlFor
256
257
  autoload :PolymorphicRoutes
257
258
 
258
- SEPARATORS = %w( / . ? ) #:nodoc:
259
- HTTP_METHODS = [:get, :head, :post, :patch, :put, :delete, :options] #:nodoc:
259
+ SEPARATORS = %w( / . ? ) # :nodoc:
260
+ HTTP_METHODS = [:get, :head, :post, :patch, :put, :delete, :options] # :nodoc:
260
261
  end
261
262
  end
@@ -0,0 +1,206 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ gem "capybara", ">= 3.26"
6
+
7
+ require "capybara/dsl"
8
+ require "capybara/minitest"
9
+ require "action_controller"
10
+ require "action_dispatch/system_testing/driver"
11
+ require "action_dispatch/system_testing/browser"
12
+ require "action_dispatch/system_testing/server"
13
+ require "action_dispatch/system_testing/test_helpers/screenshot_helper"
14
+ require "action_dispatch/system_testing/test_helpers/setup_and_teardown"
15
+
16
+ module ActionDispatch
17
+ # # System Testing
18
+ #
19
+ # System tests let you test applications in the browser. Because system tests
20
+ # use a real browser experience, you can test all of your JavaScript easily from
21
+ # your test suite.
22
+ #
23
+ # To create a system test in your application, extend your test class from
24
+ # `ApplicationSystemTestCase`. System tests use Capybara as a base and allow you
25
+ # to configure the settings through your `application_system_test_case.rb` file
26
+ # that is generated with a new application or scaffold.
27
+ #
28
+ # Here is an example system test:
29
+ #
30
+ # require "application_system_test_case"
31
+ #
32
+ # class Users::CreateTest < ApplicationSystemTestCase
33
+ # test "adding a new user" do
34
+ # visit users_path
35
+ # click_on 'New User'
36
+ #
37
+ # fill_in 'Name', with: 'Arya'
38
+ # click_on 'Create User'
39
+ #
40
+ # assert_text 'Arya'
41
+ # end
42
+ # end
43
+ #
44
+ # When generating an application or scaffold, an
45
+ # `application_system_test_case.rb` file will also be generated containing the
46
+ # base class for system testing. This is where you can change the driver, add
47
+ # Capybara settings, and other configuration for your system tests.
48
+ #
49
+ # require "test_helper"
50
+ #
51
+ # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
52
+ # driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
53
+ # end
54
+ #
55
+ # By default, `ActionDispatch::SystemTestCase` is driven by the Selenium driver,
56
+ # with the Chrome browser, and a browser size of 1400x1400.
57
+ #
58
+ # Changing the driver configuration options is easy. Let's say you want to use
59
+ # the Firefox browser instead of Chrome. In your
60
+ # `application_system_test_case.rb` file add the following:
61
+ #
62
+ # require "test_helper"
63
+ #
64
+ # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
65
+ # driven_by :selenium, using: :firefox
66
+ # end
67
+ #
68
+ # `driven_by` has a required argument for the driver name. The keyword arguments
69
+ # are `:using` for the browser and `:screen_size` to change the size of the
70
+ # browser screen. These two options are not applicable for headless drivers and
71
+ # will be silently ignored if passed.
72
+ #
73
+ # Headless browsers such as headless Chrome and headless Firefox are also
74
+ # supported. You can use these browsers by setting the `:using` argument to
75
+ # `:headless_chrome` or `:headless_firefox`.
76
+ #
77
+ # To use a headless driver, like Cuprite, update your Gemfile to use Cuprite
78
+ # instead of Selenium and then declare the driver name in the
79
+ # `application_system_test_case.rb` file. In this case, you would leave out the
80
+ # `:using` option because the driver is headless, but you can still use
81
+ # `:screen_size` to change the size of the browser screen, also you can use
82
+ # `:options` to pass options supported by the driver. Please refer to your
83
+ # driver documentation to learn about supported options.
84
+ #
85
+ # require "test_helper"
86
+ # require "capybara/cuprite"
87
+ #
88
+ # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
89
+ # driven_by :cuprite, screen_size: [1400, 1400], options:
90
+ # { js_errors: true }
91
+ # end
92
+ #
93
+ # Some drivers require browser capabilities to be passed as a block instead of
94
+ # through the `options` hash.
95
+ #
96
+ # As an example, if you want to add mobile emulation on chrome, you'll have to
97
+ # create an instance of selenium's `Chrome::Options` object and add capabilities
98
+ # with a block.
99
+ #
100
+ # The block will be passed an instance of `<Driver>::Options` where you can
101
+ # define the capabilities you want. Please refer to your driver documentation to
102
+ # learn about supported options.
103
+ #
104
+ # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
105
+ # driven_by :selenium, using: :chrome, screen_size: [1024, 768] do |driver_option|
106
+ # driver_option.add_emulation(device_name: 'iPhone 6')
107
+ # driver_option.add_extension('path/to/chrome_extension.crx')
108
+ # end
109
+ # end
110
+ #
111
+ # Because `ActionDispatch::SystemTestCase` is a shim between Capybara and Rails,
112
+ # any driver that is supported by Capybara is supported by system tests as long
113
+ # as you include the required gems and files.
114
+ class SystemTestCase < ActiveSupport::TestCase
115
+ include Capybara::DSL
116
+ include Capybara::Minitest::Assertions
117
+ include SystemTesting::TestHelpers::SetupAndTeardown
118
+ include SystemTesting::TestHelpers::ScreenshotHelper
119
+
120
+ DEFAULT_HOST = "http://127.0.0.1"
121
+
122
+ def initialize(*) # :nodoc:
123
+ super
124
+ self.class.driven_by(:selenium) unless self.class.driver?
125
+ self.class.driver.use
126
+ end
127
+
128
+ def self.start_application # :nodoc:
129
+ Capybara.app = Rack::Builder.new do
130
+ map "/" do
131
+ run Rails.application
132
+ end
133
+ end
134
+
135
+ SystemTesting::Server.new.run
136
+ end
137
+
138
+ class_attribute :driver, instance_accessor: false
139
+
140
+ # System Test configuration options
141
+ #
142
+ # The default settings are Selenium, using Chrome, with a screen size of
143
+ # 1400x1400.
144
+ #
145
+ # Examples:
146
+ #
147
+ # driven_by :cuprite
148
+ #
149
+ # driven_by :selenium, screen_size: [800, 800]
150
+ #
151
+ # driven_by :selenium, using: :chrome
152
+ #
153
+ # driven_by :selenium, using: :headless_chrome
154
+ #
155
+ # driven_by :selenium, using: :firefox
156
+ #
157
+ # driven_by :selenium, using: :headless_firefox
158
+ def self.driven_by(driver, using: :chrome, screen_size: [1400, 1400], options: {}, &capabilities)
159
+ driver_options = { using: using, screen_size: screen_size, options: options }
160
+
161
+ self.driver = SystemTesting::Driver.new(driver, **driver_options, &capabilities)
162
+ end
163
+
164
+ # Configuration for the System Test application server.
165
+ #
166
+ # By default this is localhost. This method allows the host and port to be specified manually.
167
+ def self.served_by(host:, port:)
168
+ Capybara.server_host = host
169
+ Capybara.server_port = port
170
+ end
171
+
172
+ private
173
+ def url_helpers
174
+ @url_helpers ||=
175
+ if ActionDispatch.test_app
176
+ Class.new do
177
+ include ActionDispatch.test_app.routes.url_helpers
178
+ include ActionDispatch.test_app.routes.mounted_helpers
179
+
180
+ def url_options
181
+ default_url_options.reverse_merge(host: app_host)
182
+ end
183
+
184
+ def app_host
185
+ Capybara.app_host || Capybara.current_session.server_url || DEFAULT_HOST
186
+ end
187
+ end.new
188
+ end
189
+ end
190
+
191
+ def method_missing(name, ...)
192
+ if url_helpers.respond_to?(name)
193
+ url_helpers.public_send(name, ...)
194
+ else
195
+ super
196
+ end
197
+ end
198
+
199
+ def respond_to_missing?(name, include_private = false)
200
+ url_helpers.respond_to?(name)
201
+ end
202
+ end
203
+ end
204
+
205
+ ActiveSupport.run_load_hooks :action_dispatch_system_test_case, ActionDispatch::SystemTestCase
206
+ ActionDispatch::SystemTestCase.start_application