actionpack 4.2.11.1 → 6.1.3.2

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

Potentially problematic release.


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

Files changed (187) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +291 -489
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +9 -9
  5. data/lib/abstract_controller/asset_paths.rb +2 -0
  6. data/lib/abstract_controller/base.rb +81 -51
  7. data/lib/{action_controller → abstract_controller}/caching/fragments.rb +64 -17
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/callbacks.rb +61 -33
  10. data/lib/abstract_controller/collector.rb +9 -13
  11. data/lib/abstract_controller/error.rb +6 -0
  12. data/lib/abstract_controller/helpers.rb +115 -99
  13. data/lib/abstract_controller/logger.rb +2 -0
  14. data/lib/abstract_controller/railties/routes_helpers.rb +21 -3
  15. data/lib/abstract_controller/rendering.rb +48 -47
  16. data/lib/abstract_controller/translation.rb +17 -8
  17. data/lib/abstract_controller/url_for.rb +2 -0
  18. data/lib/abstract_controller.rb +13 -5
  19. data/lib/action_controller/api/api_rendering.rb +16 -0
  20. data/lib/action_controller/api.rb +150 -0
  21. data/lib/action_controller/base.rb +29 -24
  22. data/lib/action_controller/caching.rb +12 -57
  23. data/lib/action_controller/form_builder.rb +50 -0
  24. data/lib/action_controller/log_subscriber.rb +17 -19
  25. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  26. data/lib/action_controller/metal/conditional_get.rb +134 -46
  27. data/lib/action_controller/metal/content_security_policy.rb +51 -0
  28. data/lib/action_controller/metal/cookies.rb +6 -4
  29. data/lib/action_controller/metal/data_streaming.rb +30 -50
  30. data/lib/action_controller/metal/default_headers.rb +17 -0
  31. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  32. data/lib/action_controller/metal/etag_with_template_digest.rb +21 -16
  33. data/lib/action_controller/metal/exceptions.rb +63 -15
  34. data/lib/action_controller/metal/flash.rb +9 -8
  35. data/lib/action_controller/metal/head.rb +26 -21
  36. data/lib/action_controller/metal/helpers.rb +37 -18
  37. data/lib/action_controller/metal/http_authentication.rb +81 -73
  38. data/lib/action_controller/metal/implicit_render.rb +53 -9
  39. data/lib/action_controller/metal/instrumentation.rb +32 -35
  40. data/lib/action_controller/metal/live.rb +102 -120
  41. data/lib/action_controller/metal/logging.rb +20 -0
  42. data/lib/action_controller/metal/mime_responds.rb +49 -47
  43. data/lib/action_controller/metal/parameter_encoding.rb +82 -0
  44. data/lib/action_controller/metal/params_wrapper.rb +83 -66
  45. data/lib/action_controller/metal/permissions_policy.rb +46 -0
  46. data/lib/action_controller/metal/redirecting.rb +53 -32
  47. data/lib/action_controller/metal/renderers.rb +87 -44
  48. data/lib/action_controller/metal/rendering.rb +77 -50
  49. data/lib/action_controller/metal/request_forgery_protection.rb +267 -103
  50. data/lib/action_controller/metal/rescue.rb +10 -17
  51. data/lib/action_controller/metal/streaming.rb +12 -11
  52. data/lib/action_controller/metal/strong_parameters.rb +714 -186
  53. data/lib/action_controller/metal/testing.rb +2 -17
  54. data/lib/action_controller/metal/url_for.rb +19 -10
  55. data/lib/action_controller/metal.rb +104 -87
  56. data/lib/action_controller/railtie.rb +28 -10
  57. data/lib/action_controller/railties/helpers.rb +3 -1
  58. data/lib/action_controller/renderer.rb +141 -0
  59. data/lib/action_controller/template_assertions.rb +11 -0
  60. data/lib/action_controller/test_case.rb +296 -422
  61. data/lib/action_controller.rb +34 -23
  62. data/lib/action_dispatch/http/cache.rb +107 -56
  63. data/lib/action_dispatch/http/content_disposition.rb +45 -0
  64. data/lib/action_dispatch/http/content_security_policy.rb +286 -0
  65. data/lib/action_dispatch/http/filter_parameters.rb +32 -25
  66. data/lib/action_dispatch/http/filter_redirect.rb +10 -12
  67. data/lib/action_dispatch/http/headers.rb +55 -22
  68. data/lib/action_dispatch/http/mime_negotiation.rb +79 -51
  69. data/lib/action_dispatch/http/mime_type.rb +153 -121
  70. data/lib/action_dispatch/http/mime_types.rb +20 -6
  71. data/lib/action_dispatch/http/parameters.rb +90 -40
  72. data/lib/action_dispatch/http/permissions_policy.rb +173 -0
  73. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  74. data/lib/action_dispatch/http/request.rb +226 -121
  75. data/lib/action_dispatch/http/response.rb +248 -113
  76. data/lib/action_dispatch/http/upload.rb +21 -7
  77. data/lib/action_dispatch/http/url.rb +182 -100
  78. data/lib/action_dispatch/journey/formatter.rb +90 -43
  79. data/lib/action_dispatch/journey/gtg/builder.rb +28 -41
  80. data/lib/action_dispatch/journey/gtg/simulator.rb +11 -16
  81. data/lib/action_dispatch/journey/gtg/transition_table.rb +23 -21
  82. data/lib/action_dispatch/journey/nfa/dot.rb +3 -14
  83. data/lib/action_dispatch/journey/nodes/node.rb +29 -15
  84. data/lib/action_dispatch/journey/parser.rb +17 -16
  85. data/lib/action_dispatch/journey/parser.y +4 -3
  86. data/lib/action_dispatch/journey/parser_extras.rb +12 -4
  87. data/lib/action_dispatch/journey/path/pattern.rb +58 -54
  88. data/lib/action_dispatch/journey/route.rb +100 -32
  89. data/lib/action_dispatch/journey/router/utils.rb +29 -18
  90. data/lib/action_dispatch/journey/router.rb +55 -51
  91. data/lib/action_dispatch/journey/routes.rb +17 -17
  92. data/lib/action_dispatch/journey/scanner.rb +26 -17
  93. data/lib/action_dispatch/journey/visitors.rb +98 -54
  94. data/lib/action_dispatch/journey.rb +5 -5
  95. data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
  96. data/lib/action_dispatch/middleware/callbacks.rb +3 -6
  97. data/lib/action_dispatch/middleware/cookies.rb +347 -217
  98. data/lib/action_dispatch/middleware/debug_exceptions.rb +135 -63
  99. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  100. data/lib/action_dispatch/middleware/debug_view.rb +66 -0
  101. data/lib/action_dispatch/middleware/exception_wrapper.rb +115 -71
  102. data/lib/action_dispatch/middleware/executor.rb +21 -0
  103. data/lib/action_dispatch/middleware/flash.rb +78 -54
  104. data/lib/action_dispatch/middleware/host_authorization.rb +130 -0
  105. data/lib/action_dispatch/middleware/public_exceptions.rb +32 -27
  106. data/lib/action_dispatch/middleware/reloader.rb +5 -91
  107. data/lib/action_dispatch/middleware/remote_ip.rb +53 -45
  108. data/lib/action_dispatch/middleware/request_id.rb +17 -10
  109. data/lib/action_dispatch/middleware/session/abstract_store.rb +41 -26
  110. data/lib/action_dispatch/middleware/session/cache_store.rb +24 -14
  111. data/lib/action_dispatch/middleware/session/cookie_store.rb +74 -75
  112. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -2
  113. data/lib/action_dispatch/middleware/show_exceptions.rb +28 -23
  114. data/lib/action_dispatch/middleware/ssl.rb +118 -35
  115. data/lib/action_dispatch/middleware/stack.rb +82 -41
  116. data/lib/action_dispatch/middleware/static.rb +156 -89
  117. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -14
  121. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
  122. data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +4 -2
  123. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  124. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
  125. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
  126. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +23 -4
  128. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
  129. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +15 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +105 -8
  132. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
  135. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
  136. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
  137. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  138. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
  139. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
  140. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +87 -64
  141. data/lib/action_dispatch/railtie.rb +27 -13
  142. data/lib/action_dispatch/request/session.rb +109 -61
  143. data/lib/action_dispatch/request/utils.rb +90 -23
  144. data/lib/action_dispatch/routing/endpoint.rb +9 -2
  145. data/lib/action_dispatch/routing/inspector.rb +141 -102
  146. data/lib/action_dispatch/routing/mapper.rb +811 -473
  147. data/lib/action_dispatch/routing/polymorphic_routes.rb +167 -143
  148. data/lib/action_dispatch/routing/redirection.rb +37 -27
  149. data/lib/action_dispatch/routing/route_set.rb +363 -331
  150. data/lib/action_dispatch/routing/routes_proxy.rb +32 -5
  151. data/lib/action_dispatch/routing/url_for.rb +66 -26
  152. data/lib/action_dispatch/routing.rb +36 -36
  153. data/lib/action_dispatch/system_test_case.rb +190 -0
  154. data/lib/action_dispatch/system_testing/browser.rb +86 -0
  155. data/lib/action_dispatch/system_testing/driver.rb +67 -0
  156. data/lib/action_dispatch/system_testing/server.rb +31 -0
  157. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +138 -0
  158. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +29 -0
  159. data/lib/action_dispatch/testing/assertion_response.rb +46 -0
  160. data/lib/action_dispatch/testing/assertions/response.rb +44 -22
  161. data/lib/action_dispatch/testing/assertions/routing.rb +47 -31
  162. data/lib/action_dispatch/testing/assertions.rb +6 -4
  163. data/lib/action_dispatch/testing/integration.rb +391 -220
  164. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  165. data/lib/action_dispatch/testing/test_process.rb +53 -22
  166. data/lib/action_dispatch/testing/test_request.rb +27 -34
  167. data/lib/action_dispatch/testing/test_response.rb +11 -11
  168. data/lib/action_dispatch.rb +35 -21
  169. data/lib/action_pack/gem_version.rb +6 -4
  170. data/lib/action_pack/version.rb +3 -1
  171. data/lib/action_pack.rb +4 -2
  172. metadata +78 -48
  173. data/lib/action_controller/metal/force_ssl.rb +0 -97
  174. data/lib/action_controller/metal/hide_actions.rb +0 -40
  175. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  176. data/lib/action_controller/middleware.rb +0 -39
  177. data/lib/action_controller/model_naming.rb +0 -12
  178. data/lib/action_dispatch/http/parameter_filter.rb +0 -72
  179. data/lib/action_dispatch/journey/backwards.rb +0 -5
  180. data/lib/action_dispatch/journey/nfa/builder.rb +0 -76
  181. data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
  182. data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -163
  183. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  184. data/lib/action_dispatch/middleware/params_parser.rb +0 -60
  185. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  186. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  187. data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -1,35 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/indifferent_access"
4
+
1
5
  module ActionDispatch
2
- class Request < Rack::Request
6
+ class Request
3
7
  class Utils # :nodoc:
8
+ mattr_accessor :perform_deep_munge, default: true
9
+
10
+ def self.each_param_value(params, &block)
11
+ case params
12
+ when Array
13
+ params.each { |element| each_param_value(element, &block) }
14
+ when Hash
15
+ params.each_value { |value| each_param_value(value, &block) }
16
+ when String
17
+ block.call params
18
+ end
19
+ end
20
+
21
+ def self.normalize_encode_params(params)
22
+ if perform_deep_munge
23
+ NoNilParamEncoder.normalize_encode_params params
24
+ else
25
+ ParamEncoder.normalize_encode_params params
26
+ end
27
+ end
28
+
29
+ def self.check_param_encoding(params)
30
+ case params
31
+ when Array
32
+ params.each { |element| check_param_encoding(element) }
33
+ when Hash
34
+ params.each_value { |value| check_param_encoding(value) }
35
+ when String
36
+ unless params.valid_encoding?
37
+ # Raise Rack::Utils::InvalidParameterError for consistency with Rack.
38
+ # ActionDispatch::Request#GET will re-raise as a BadRequest error.
39
+ raise Rack::Utils::InvalidParameterError, "Invalid encoding for parameter: #{params.scrub}"
40
+ end
41
+ end
42
+ end
43
+
44
+ def self.set_binary_encoding(request, params, controller, action)
45
+ CustomParamEncoder.encode(request, params, controller, action)
46
+ end
4
47
 
5
- mattr_accessor :perform_deep_munge
6
- self.perform_deep_munge = true
7
-
8
- class << self
9
- # Remove nils from the params hash
10
- def deep_munge(hash, keys = [])
11
- return hash unless perform_deep_munge
12
-
13
- hash.each do |k, v|
14
- keys << k
15
- case v
16
- when Array
17
- v.grep(Hash) { |x| deep_munge(x, keys) }
18
- v.compact!
19
- if v.empty?
20
- hash[k] = nil
21
- ActiveSupport::Notifications.instrument("deep_munge.action_controller", keys: keys)
48
+ class ParamEncoder # :nodoc:
49
+ # Convert nested Hash to HashWithIndifferentAccess.
50
+ def self.normalize_encode_params(params)
51
+ case params
52
+ when Array
53
+ handle_array params
54
+ when Hash
55
+ if params.has_key?(:tempfile)
56
+ ActionDispatch::Http::UploadedFile.new(params)
57
+ else
58
+ params.transform_values do |val|
59
+ normalize_encode_params(val)
60
+ end.with_indifferent_access
61
+ end
62
+ else
63
+ params
64
+ end
65
+ end
66
+
67
+ def self.handle_array(params)
68
+ params.map! { |el| normalize_encode_params(el) }
69
+ end
70
+ end
71
+
72
+ # Remove nils from the params hash.
73
+ class NoNilParamEncoder < ParamEncoder # :nodoc:
74
+ def self.handle_array(params)
75
+ list = super
76
+ list.compact!
77
+ list
78
+ end
79
+ end
80
+
81
+ class CustomParamEncoder # :nodoc:
82
+ def self.encode(request, params, controller, action)
83
+ return params unless controller && controller.valid_encoding? && encoding_template = action_encoding_template(request, controller, action)
84
+ params.except(:controller, :action).each do |key, value|
85
+ ActionDispatch::Request::Utils.each_param_value(value) do |param|
86
+ if encoding_template[key.to_s]
87
+ param.force_encoding(encoding_template[key.to_s])
22
88
  end
23
- when Hash
24
- deep_munge(v, keys)
25
89
  end
26
- keys.pop
27
90
  end
91
+ params
92
+ end
28
93
 
29
- hash
94
+ def self.action_encoding_template(request, controller, action) # :nodoc:
95
+ request.controller_class_for(controller).action_encoding_template(action)
96
+ rescue MissingController
97
+ nil
30
98
  end
31
99
  end
32
100
  end
33
101
  end
34
102
  end
35
-
@@ -1,10 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionDispatch
2
4
  module Routing
3
5
  class Endpoint # :nodoc:
4
6
  def dispatcher?; false; end
5
7
  def redirect?; false; end
6
- def matches?(req); true; end
7
- def app; self; end
8
+ def matches?(req); true; end
9
+ def app; self; end
10
+ def rack_app; app; end
11
+
12
+ def engine?
13
+ rack_app.is_a?(Class) && rack_app < Rails::Engine
14
+ end
8
15
  end
9
16
  end
10
17
  end
@@ -1,5 +1,7 @@
1
- require 'delegate'
2
- require 'active_support/core_ext/string/strip'
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+ require "io/console/size"
3
5
 
4
6
  module ActionDispatch
5
7
  module Routing
@@ -13,11 +15,7 @@ module ActionDispatch
13
15
  end
14
16
 
15
17
  def rack_app
16
- app.app
17
- end
18
-
19
- def verb
20
- super.source.gsub(/[$^]/, '')
18
+ app.rack_app
21
19
  end
22
20
 
23
21
  def path
@@ -28,23 +26,6 @@ module ActionDispatch
28
26
  super.to_s
29
27
  end
30
28
 
31
- def regexp
32
- __getobj__.path.to_regexp
33
- end
34
-
35
- def json_regexp
36
- str = regexp.inspect.
37
- sub('\\A' , '^').
38
- sub('\\Z' , '$').
39
- sub('\\z' , '$').
40
- sub(/^\// , '').
41
- sub(/\/[a-z]*$/ , '').
42
- gsub(/\(\?#.+\)/ , '').
43
- gsub(/\(\?-\w+:/ , '(').
44
- gsub(/\s/ , '')
45
- Regexp.new(str).source
46
- end
47
-
48
29
  def reqs
49
30
  @reqs ||= begin
50
31
  reqs = endpoint
@@ -54,25 +35,25 @@ module ActionDispatch
54
35
  end
55
36
 
56
37
  def controller
57
- requirements[:controller] || ':controller'
38
+ parts.include?(:controller) ? ":controller" : requirements[:controller]
58
39
  end
59
40
 
60
41
  def action
61
- requirements[:action] || ':action'
42
+ parts.include?(:action) ? ":action" : requirements[:action]
62
43
  end
63
44
 
64
45
  def internal?
65
- controller.to_s =~ %r{\Arails/(info|mailers|welcome)} || path =~ %r{\A#{Rails.application.config.assets.prefix}\z}
46
+ internal
66
47
  end
67
48
 
68
49
  def engine?
69
- rack_app.respond_to?(:routes)
50
+ app.engine?
70
51
  end
71
52
  end
72
53
 
73
54
  ##
74
55
  # This class is just used for displaying route information when someone
75
- # executes `rake routes` or looks at the RoutingError page.
56
+ # executes `bin/rails routes` or looks at the RoutingError page.
76
57
  # People should not use this class.
77
58
  class RoutesInspector # :nodoc:
78
59
  def initialize(routes)
@@ -80,13 +61,11 @@ module ActionDispatch
80
61
  @routes = routes
81
62
  end
82
63
 
83
- def format(formatter, filter = nil)
84
- routes_to_display = filter_routes(filter)
85
-
64
+ def format(formatter, filter = {})
65
+ routes_to_display = filter_routes(normalize_filter(filter))
86
66
  routes = collect_routes(routes_to_display)
87
-
88
67
  if routes.none?
89
- formatter.no_routes
68
+ formatter.no_routes(collect_routes(@routes), filter)
90
69
  return formatter.result
91
70
  end
92
71
 
@@ -102,95 +81,155 @@ module ActionDispatch
102
81
  end
103
82
 
104
83
  private
84
+ def normalize_filter(filter)
85
+ if filter[:controller]
86
+ { controller: /#{filter[:controller].underscore.sub(/_?controller\z/, "")}/ }
87
+ elsif filter[:grep]
88
+ { controller: /#{filter[:grep]}/, action: /#{filter[:grep]}/,
89
+ verb: /#{filter[:grep]}/, name: /#{filter[:grep]}/, path: /#{filter[:grep]}/ }
90
+ end
91
+ end
105
92
 
106
- def filter_routes(filter)
107
- if filter
108
- @routes.select { |route| route.defaults[:controller] == filter }
109
- else
110
- @routes
93
+ def filter_routes(filter)
94
+ if filter
95
+ @routes.select do |route|
96
+ route_wrapper = RouteWrapper.new(route)
97
+ filter.any? { |default, value| value.match?(route_wrapper.send(default)) }
98
+ end
99
+ else
100
+ @routes
101
+ end
111
102
  end
112
- end
113
103
 
114
- def collect_routes(routes)
115
- routes.collect do |route|
116
- RouteWrapper.new(route)
117
- end.reject do |route|
118
- route.internal?
119
- end.collect do |route|
120
- collect_engine_routes(route)
104
+ def collect_routes(routes)
105
+ routes.collect do |route|
106
+ RouteWrapper.new(route)
107
+ end.reject(&:internal?).collect do |route|
108
+ collect_engine_routes(route)
121
109
 
122
- { name: route.name,
123
- verb: route.verb,
124
- path: route.path,
125
- reqs: route.reqs,
126
- regexp: route.json_regexp }
110
+ { name: route.name,
111
+ verb: route.verb,
112
+ path: route.path,
113
+ reqs: route.reqs }
114
+ end
127
115
  end
128
- end
129
116
 
130
- def collect_engine_routes(route)
131
- name = route.endpoint
132
- return unless route.engine?
133
- return if @engines[name]
117
+ def collect_engine_routes(route)
118
+ name = route.endpoint
119
+ return unless route.engine?
120
+ return if @engines[name]
134
121
 
135
- routes = route.rack_app.routes
136
- if routes.is_a?(ActionDispatch::Routing::RouteSet)
137
- @engines[name] = collect_routes(routes.routes)
122
+ routes = route.rack_app.routes
123
+ if routes.is_a?(ActionDispatch::Routing::RouteSet)
124
+ @engines[name] = collect_routes(routes.routes)
125
+ end
138
126
  end
139
- end
140
127
  end
141
128
 
142
- class ConsoleFormatter
143
- def initialize
144
- @buffer = []
145
- end
129
+ module ConsoleFormatter
130
+ class Base
131
+ def initialize
132
+ @buffer = []
133
+ end
146
134
 
147
- def result
148
- @buffer.join("\n")
149
- end
135
+ def result
136
+ @buffer.join("\n")
137
+ end
150
138
 
151
- def section_title(title)
152
- @buffer << "\n#{title}:"
153
- end
139
+ def section_title(title)
140
+ end
154
141
 
155
- def section(routes)
156
- @buffer << draw_section(routes)
157
- end
142
+ def section(routes)
143
+ end
158
144
 
159
- def header(routes)
160
- @buffer << draw_header(routes)
145
+ def header(routes)
146
+ end
147
+
148
+ def no_routes(routes, filter)
149
+ @buffer <<
150
+ if routes.none?
151
+ <<~MESSAGE
152
+ You don't have any routes defined!
153
+
154
+ Please add some routes in config/routes.rb.
155
+ MESSAGE
156
+ elsif filter.key?(:controller)
157
+ "No routes were found for this controller."
158
+ elsif filter.key?(:grep)
159
+ "No routes were found for this grep pattern."
160
+ end
161
+
162
+ @buffer << "For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html."
163
+ end
161
164
  end
162
165
 
163
- def no_routes
164
- @buffer << <<-MESSAGE.strip_heredoc
165
- You don't have any routes defined!
166
+ class Sheet < Base
167
+ def section_title(title)
168
+ @buffer << "\n#{title}:"
169
+ end
166
170
 
167
- Please add some routes in config/routes.rb.
171
+ def section(routes)
172
+ @buffer << draw_section(routes)
173
+ end
168
174
 
169
- For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html.
170
- MESSAGE
171
- end
175
+ def header(routes)
176
+ @buffer << draw_header(routes)
177
+ end
172
178
 
173
- private
174
- def draw_section(routes)
175
- header_lengths = ['Prefix', 'Verb', 'URI Pattern'].map(&:length)
176
- name_width, verb_width, path_width = widths(routes).zip(header_lengths).map(&:max)
179
+ private
180
+ def draw_section(routes)
181
+ header_lengths = ["Prefix", "Verb", "URI Pattern"].map(&:length)
182
+ name_width, verb_width, path_width = widths(routes).zip(header_lengths).map(&:max)
177
183
 
178
- routes.map do |r|
179
- "#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}"
184
+ routes.map do |r|
185
+ "#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}"
186
+ end
180
187
  end
181
- end
182
188
 
183
- def draw_header(routes)
184
- name_width, verb_width, path_width = widths(routes)
189
+ def draw_header(routes)
190
+ name_width, verb_width, path_width = widths(routes)
185
191
 
186
- "#{"Prefix".rjust(name_width)} #{"Verb".ljust(verb_width)} #{"URI Pattern".ljust(path_width)} Controller#Action"
192
+ "#{"Prefix".rjust(name_width)} #{"Verb".ljust(verb_width)} #{"URI Pattern".ljust(path_width)} Controller#Action"
193
+ end
194
+
195
+ def widths(routes)
196
+ [routes.map { |r| r[:name].length }.max || 0,
197
+ routes.map { |r| r[:verb].length }.max || 0,
198
+ routes.map { |r| r[:path].length }.max || 0]
199
+ end
200
+ end
201
+
202
+ class Expanded < Base
203
+ def initialize(width: IO.console_size[1])
204
+ @width = width
205
+ super()
206
+ end
207
+
208
+ def section_title(title)
209
+ @buffer << "\n#{"[ #{title} ]"}"
187
210
  end
188
211
 
189
- def widths(routes)
190
- [routes.map { |r| r[:name].length }.max || 0,
191
- routes.map { |r| r[:verb].length }.max || 0,
192
- routes.map { |r| r[:path].length }.max || 0]
212
+ def section(routes)
213
+ @buffer << draw_expanded_section(routes)
193
214
  end
215
+
216
+ private
217
+ def draw_expanded_section(routes)
218
+ routes.map.each_with_index do |r, i|
219
+ <<~MESSAGE.chomp
220
+ #{route_header(index: i + 1)}
221
+ Prefix | #{r[:name]}
222
+ Verb | #{r[:verb]}
223
+ URI | #{r[:path]}
224
+ Controller#Action | #{r[:reqs]}
225
+ MESSAGE
226
+ end
227
+ end
228
+
229
+ def route_header(index:)
230
+ "--[ Route #{index} ]".ljust(@width, "-")
231
+ end
232
+ end
194
233
  end
195
234
 
196
235
  class HtmlTableFormatter
@@ -207,21 +246,21 @@ module ActionDispatch
207
246
  @buffer << @view.render(partial: "routes/route", collection: routes)
208
247
  end
209
248
 
210
- # the header is part of the HTML page, so we don't construct it here.
249
+ # The header is part of the HTML page, so we don't construct it here.
211
250
  def header(routes)
212
251
  end
213
252
 
214
- def no_routes
215
- @buffer << <<-MESSAGE.strip_heredoc
253
+ def no_routes(*)
254
+ @buffer << <<~MESSAGE
216
255
  <p>You don't have any routes defined!</p>
217
256
  <ul>
218
257
  <li>Please add some routes in <tt>config/routes.rb</tt>.</li>
219
258
  <li>
220
259
  For more information about routes, please see the Rails guide
221
- <a href="http://guides.rubyonrails.org/routing.html">Rails Routing from the Outside In</a>.
260
+ <a href="https://guides.rubyonrails.org/routing.html">Rails Routing from the Outside In</a>.
222
261
  </li>
223
262
  </ul>
224
- MESSAGE
263
+ MESSAGE
225
264
  end
226
265
 
227
266
  def result