actionview 6.0.0

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

Potentially problematic release.


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

Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +271 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.rdoc +40 -0
  5. data/lib/action_view.rb +98 -0
  6. data/lib/action_view/base.rb +312 -0
  7. data/lib/action_view/buffers.rb +67 -0
  8. data/lib/action_view/cache_expiry.rb +54 -0
  9. data/lib/action_view/context.rb +32 -0
  10. data/lib/action_view/dependency_tracker.rb +175 -0
  11. data/lib/action_view/digestor.rb +126 -0
  12. data/lib/action_view/flows.rb +76 -0
  13. data/lib/action_view/gem_version.rb +17 -0
  14. data/lib/action_view/helpers.rb +66 -0
  15. data/lib/action_view/helpers/active_model_helper.rb +55 -0
  16. data/lib/action_view/helpers/asset_tag_helper.rb +488 -0
  17. data/lib/action_view/helpers/asset_url_helper.rb +470 -0
  18. data/lib/action_view/helpers/atom_feed_helper.rb +205 -0
  19. data/lib/action_view/helpers/cache_helper.rb +271 -0
  20. data/lib/action_view/helpers/capture_helper.rb +216 -0
  21. data/lib/action_view/helpers/controller_helper.rb +36 -0
  22. data/lib/action_view/helpers/csp_helper.rb +26 -0
  23. data/lib/action_view/helpers/csrf_helper.rb +35 -0
  24. data/lib/action_view/helpers/date_helper.rb +1200 -0
  25. data/lib/action_view/helpers/debug_helper.rb +36 -0
  26. data/lib/action_view/helpers/form_helper.rb +2569 -0
  27. data/lib/action_view/helpers/form_options_helper.rb +896 -0
  28. data/lib/action_view/helpers/form_tag_helper.rb +920 -0
  29. data/lib/action_view/helpers/javascript_helper.rb +95 -0
  30. data/lib/action_view/helpers/number_helper.rb +456 -0
  31. data/lib/action_view/helpers/output_safety_helper.rb +70 -0
  32. data/lib/action_view/helpers/rendering_helper.rb +101 -0
  33. data/lib/action_view/helpers/sanitize_helper.rb +171 -0
  34. data/lib/action_view/helpers/tag_helper.rb +314 -0
  35. data/lib/action_view/helpers/tags.rb +44 -0
  36. data/lib/action_view/helpers/tags/base.rb +196 -0
  37. data/lib/action_view/helpers/tags/check_box.rb +66 -0
  38. data/lib/action_view/helpers/tags/checkable.rb +18 -0
  39. data/lib/action_view/helpers/tags/collection_check_boxes.rb +36 -0
  40. data/lib/action_view/helpers/tags/collection_helpers.rb +119 -0
  41. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +31 -0
  42. data/lib/action_view/helpers/tags/collection_select.rb +30 -0
  43. data/lib/action_view/helpers/tags/color_field.rb +27 -0
  44. data/lib/action_view/helpers/tags/date_field.rb +15 -0
  45. data/lib/action_view/helpers/tags/date_select.rb +74 -0
  46. data/lib/action_view/helpers/tags/datetime_field.rb +32 -0
  47. data/lib/action_view/helpers/tags/datetime_local_field.rb +21 -0
  48. data/lib/action_view/helpers/tags/datetime_select.rb +10 -0
  49. data/lib/action_view/helpers/tags/email_field.rb +10 -0
  50. data/lib/action_view/helpers/tags/file_field.rb +10 -0
  51. data/lib/action_view/helpers/tags/grouped_collection_select.rb +31 -0
  52. data/lib/action_view/helpers/tags/hidden_field.rb +10 -0
  53. data/lib/action_view/helpers/tags/label.rb +81 -0
  54. data/lib/action_view/helpers/tags/month_field.rb +15 -0
  55. data/lib/action_view/helpers/tags/number_field.rb +20 -0
  56. data/lib/action_view/helpers/tags/password_field.rb +14 -0
  57. data/lib/action_view/helpers/tags/placeholderable.rb +24 -0
  58. data/lib/action_view/helpers/tags/radio_button.rb +33 -0
  59. data/lib/action_view/helpers/tags/range_field.rb +10 -0
  60. data/lib/action_view/helpers/tags/search_field.rb +27 -0
  61. data/lib/action_view/helpers/tags/select.rb +43 -0
  62. data/lib/action_view/helpers/tags/tel_field.rb +10 -0
  63. data/lib/action_view/helpers/tags/text_area.rb +24 -0
  64. data/lib/action_view/helpers/tags/text_field.rb +34 -0
  65. data/lib/action_view/helpers/tags/time_field.rb +15 -0
  66. data/lib/action_view/helpers/tags/time_select.rb +10 -0
  67. data/lib/action_view/helpers/tags/time_zone_select.rb +22 -0
  68. data/lib/action_view/helpers/tags/translator.rb +39 -0
  69. data/lib/action_view/helpers/tags/url_field.rb +10 -0
  70. data/lib/action_view/helpers/tags/week_field.rb +15 -0
  71. data/lib/action_view/helpers/text_helper.rb +486 -0
  72. data/lib/action_view/helpers/translation_helper.rb +145 -0
  73. data/lib/action_view/helpers/url_helper.rb +676 -0
  74. data/lib/action_view/layouts.rb +433 -0
  75. data/lib/action_view/locale/en.yml +56 -0
  76. data/lib/action_view/log_subscriber.rb +96 -0
  77. data/lib/action_view/lookup_context.rb +316 -0
  78. data/lib/action_view/model_naming.rb +14 -0
  79. data/lib/action_view/path_set.rb +95 -0
  80. data/lib/action_view/railtie.rb +105 -0
  81. data/lib/action_view/record_identifier.rb +112 -0
  82. data/lib/action_view/renderer/abstract_renderer.rb +108 -0
  83. data/lib/action_view/renderer/partial_renderer.rb +563 -0
  84. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +103 -0
  85. data/lib/action_view/renderer/renderer.rb +68 -0
  86. data/lib/action_view/renderer/streaming_template_renderer.rb +105 -0
  87. data/lib/action_view/renderer/template_renderer.rb +108 -0
  88. data/lib/action_view/rendering.rb +171 -0
  89. data/lib/action_view/routing_url_for.rb +146 -0
  90. data/lib/action_view/tasks/cache_digests.rake +25 -0
  91. data/lib/action_view/template.rb +393 -0
  92. data/lib/action_view/template/error.rb +161 -0
  93. data/lib/action_view/template/handlers.rb +92 -0
  94. data/lib/action_view/template/handlers/builder.rb +25 -0
  95. data/lib/action_view/template/handlers/erb.rb +84 -0
  96. data/lib/action_view/template/handlers/erb/erubi.rb +87 -0
  97. data/lib/action_view/template/handlers/html.rb +11 -0
  98. data/lib/action_view/template/handlers/raw.rb +11 -0
  99. data/lib/action_view/template/html.rb +43 -0
  100. data/lib/action_view/template/inline.rb +22 -0
  101. data/lib/action_view/template/raw_file.rb +28 -0
  102. data/lib/action_view/template/resolver.rb +394 -0
  103. data/lib/action_view/template/sources.rb +13 -0
  104. data/lib/action_view/template/sources/file.rb +17 -0
  105. data/lib/action_view/template/text.rb +35 -0
  106. data/lib/action_view/template/types.rb +57 -0
  107. data/lib/action_view/test_case.rb +300 -0
  108. data/lib/action_view/testing/resolvers.rb +67 -0
  109. data/lib/action_view/unbound_template.rb +32 -0
  110. data/lib/action_view/version.rb +10 -0
  111. data/lib/action_view/view_paths.rb +129 -0
  112. data/lib/assets/compiled/rails-ujs.js +746 -0
  113. metadata +260 -0
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ class Template
5
+ module Sources
6
+ extend ActiveSupport::Autoload
7
+
8
+ eager_autoload do
9
+ autoload :File
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ class Template
5
+ module Sources
6
+ class File
7
+ def initialize(filename)
8
+ @filename = filename
9
+ end
10
+
11
+ def to_s
12
+ ::File.binread @filename
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView #:nodoc:
4
+ # = Action View Text Template
5
+ class Template #:nodoc:
6
+ class Text #:nodoc:
7
+ attr_accessor :type
8
+
9
+ def initialize(string)
10
+ @string = string.to_s
11
+ end
12
+
13
+ def identifier
14
+ "text template"
15
+ end
16
+
17
+ alias_method :inspect, :identifier
18
+
19
+ def to_str
20
+ @string
21
+ end
22
+
23
+ def render(*args)
24
+ to_str
25
+ end
26
+
27
+ def format
28
+ :text
29
+ end
30
+
31
+ def formats; Array(format); end
32
+ deprecate :formats
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/attribute_accessors"
4
+
5
+ module ActionView
6
+ class Template #:nodoc:
7
+ class Types
8
+ class Type
9
+ SET = Struct.new(:symbols).new([ :html, :text, :js, :css, :xml, :json ])
10
+
11
+ def self.[](type)
12
+ if type.is_a?(self)
13
+ type
14
+ else
15
+ new(type)
16
+ end
17
+ end
18
+
19
+ attr_reader :symbol
20
+
21
+ def initialize(symbol)
22
+ @symbol = symbol.to_sym
23
+ end
24
+
25
+ def to_s
26
+ @symbol.to_s
27
+ end
28
+ alias to_str to_s
29
+
30
+ def ref
31
+ @symbol
32
+ end
33
+ alias to_sym ref
34
+
35
+ def ==(type)
36
+ @symbol == type.to_sym unless type.blank?
37
+ end
38
+ end
39
+
40
+ cattr_accessor :type_klass
41
+
42
+ def self.delegate_to(klass)
43
+ self.type_klass = klass
44
+ end
45
+
46
+ delegate_to Type
47
+
48
+ def self.[](type)
49
+ type_klass[type]
50
+ end
51
+
52
+ def self.symbols
53
+ type_klass::SET.symbols
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,300 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/redefine_method"
4
+ require "action_controller"
5
+ require "action_controller/test_case"
6
+ require "action_view"
7
+
8
+ require "rails-dom-testing"
9
+
10
+ module ActionView
11
+ # = Action View Test Case
12
+ class TestCase < ActiveSupport::TestCase
13
+ class TestController < ActionController::Base
14
+ include ActionDispatch::TestProcess
15
+
16
+ attr_accessor :request, :response, :params
17
+
18
+ class << self
19
+ attr_writer :controller_path
20
+ end
21
+
22
+ def controller_path=(path)
23
+ self.class.controller_path = (path)
24
+ end
25
+
26
+ def initialize
27
+ super
28
+ self.class.controller_path = ""
29
+ @request = ActionController::TestRequest.create(self.class)
30
+ @response = ActionDispatch::TestResponse.new
31
+
32
+ @request.env.delete("PATH_INFO")
33
+ @params = ActionController::Parameters.new
34
+ end
35
+ end
36
+
37
+ module Behavior
38
+ extend ActiveSupport::Concern
39
+
40
+ include ActionDispatch::Assertions, ActionDispatch::TestProcess
41
+ include Rails::Dom::Testing::Assertions
42
+ include ActionController::TemplateAssertions
43
+ include ActionView::Context
44
+
45
+ include ActionDispatch::Routing::PolymorphicRoutes
46
+
47
+ include AbstractController::Helpers
48
+ include ActionView::Helpers
49
+ include ActionView::RecordIdentifier
50
+ include ActionView::RoutingUrlFor
51
+
52
+ include ActiveSupport::Testing::ConstantLookup
53
+
54
+ delegate :lookup_context, to: :controller
55
+ attr_accessor :controller, :output_buffer, :rendered
56
+
57
+ module ClassMethods
58
+ def tests(helper_class)
59
+ case helper_class
60
+ when String, Symbol
61
+ self.helper_class = "#{helper_class.to_s.underscore}_helper".camelize.safe_constantize
62
+ when Module
63
+ self.helper_class = helper_class
64
+ end
65
+ end
66
+
67
+ def determine_default_helper_class(name)
68
+ determine_constant_from_test_name(name) do |constant|
69
+ Module === constant && !(Class === constant)
70
+ end
71
+ end
72
+
73
+ def helper_method(*methods)
74
+ # Almost a duplicate from ActionController::Helpers
75
+ methods.flatten.each do |method|
76
+ _helpers.module_eval <<-end_eval, __FILE__, __LINE__ + 1
77
+ def #{method}(*args, &block) # def current_user(*args, &block)
78
+ _test_case.send(%(#{method}), *args, &block) # _test_case.send(%(current_user), *args, &block)
79
+ end # end
80
+ end_eval
81
+ end
82
+ end
83
+
84
+ attr_writer :helper_class
85
+
86
+ def helper_class
87
+ @helper_class ||= determine_default_helper_class(name)
88
+ end
89
+
90
+ def new(*)
91
+ include_helper_modules!
92
+ super
93
+ end
94
+
95
+ private
96
+
97
+ def include_helper_modules!
98
+ helper(helper_class) if helper_class
99
+ include _helpers
100
+ end
101
+ end
102
+
103
+ def setup_with_controller
104
+ @controller = ActionView::TestCase::TestController.new
105
+ @request = @controller.request
106
+ @view_flow = ActionView::OutputFlow.new
107
+ # empty string ensures buffer has UTF-8 encoding as
108
+ # new without arguments returns ASCII-8BIT encoded buffer like String#new
109
+ @output_buffer = ActiveSupport::SafeBuffer.new ""
110
+ @rendered = +""
111
+
112
+ make_test_case_available_to_view!
113
+ say_no_to_protect_against_forgery!
114
+ end
115
+
116
+ def config
117
+ @controller.config if @controller.respond_to?(:config)
118
+ end
119
+
120
+ def render(options = {}, local_assigns = {}, &block)
121
+ view.assign(view_assigns)
122
+ @rendered << output = view.render(options, local_assigns, &block)
123
+ output
124
+ end
125
+
126
+ def rendered_views
127
+ @_rendered_views ||= RenderedViewsCollection.new
128
+ end
129
+
130
+ def _routes
131
+ @controller._routes if @controller.respond_to?(:_routes)
132
+ end
133
+
134
+ # Need to experiment if this priority is the best one: rendered => output_buffer
135
+ class RenderedViewsCollection
136
+ def initialize
137
+ @rendered_views ||= Hash.new { |hash, key| hash[key] = [] }
138
+ end
139
+
140
+ def add(view, locals)
141
+ @rendered_views[view] ||= []
142
+ @rendered_views[view] << locals
143
+ end
144
+
145
+ def locals_for(view)
146
+ @rendered_views[view]
147
+ end
148
+
149
+ def rendered_views
150
+ @rendered_views.keys
151
+ end
152
+
153
+ def view_rendered?(view, expected_locals)
154
+ locals_for(view).any? do |actual_locals|
155
+ expected_locals.all? { |key, value| value == actual_locals[key] }
156
+ end
157
+ end
158
+ end
159
+
160
+ included do
161
+ setup :setup_with_controller
162
+ ActiveSupport.run_load_hooks(:action_view_test_case, self)
163
+ end
164
+
165
+ private
166
+
167
+ # Need to experiment if this priority is the best one: rendered => output_buffer
168
+ def document_root_element
169
+ Nokogiri::HTML::Document.parse(@rendered.blank? ? @output_buffer : @rendered).root
170
+ end
171
+
172
+ def say_no_to_protect_against_forgery!
173
+ _helpers.module_eval do
174
+ silence_redefinition_of_method :protect_against_forgery?
175
+ def protect_against_forgery?
176
+ false
177
+ end
178
+ end
179
+ end
180
+
181
+ def make_test_case_available_to_view!
182
+ test_case_instance = self
183
+ _helpers.module_eval do
184
+ unless private_method_defined?(:_test_case)
185
+ define_method(:_test_case) { test_case_instance }
186
+ private :_test_case
187
+ end
188
+ end
189
+ end
190
+
191
+ module Locals
192
+ attr_accessor :rendered_views
193
+
194
+ def render(options = {}, local_assigns = {})
195
+ case options
196
+ when Hash
197
+ if block_given?
198
+ rendered_views.add options[:layout], options[:locals]
199
+ elsif options.key?(:partial)
200
+ rendered_views.add options[:partial], options[:locals]
201
+ end
202
+ else
203
+ rendered_views.add options, local_assigns
204
+ end
205
+
206
+ super
207
+ end
208
+ end
209
+
210
+ # The instance of ActionView::Base that is used by +render+.
211
+ def view
212
+ @view ||= begin
213
+ view = @controller.view_context
214
+ view.singleton_class.include(_helpers)
215
+ view.extend(Locals)
216
+ view.rendered_views = rendered_views
217
+ view.output_buffer = output_buffer
218
+ view
219
+ end
220
+ end
221
+
222
+ alias_method :_view, :view
223
+
224
+ INTERNAL_IVARS = [
225
+ :@NAME,
226
+ :@failures,
227
+ :@assertions,
228
+ :@__io__,
229
+ :@_assertion_wrapped,
230
+ :@_assertions,
231
+ :@_result,
232
+ :@_routes,
233
+ :@controller,
234
+ :@_layouts,
235
+ :@_files,
236
+ :@_rendered_views,
237
+ :@method_name,
238
+ :@output_buffer,
239
+ :@_partials,
240
+ :@passed,
241
+ :@rendered,
242
+ :@request,
243
+ :@routes,
244
+ :@tagged_logger,
245
+ :@_templates,
246
+ :@options,
247
+ :@test_passed,
248
+ :@view,
249
+ :@view_context_class,
250
+ :@view_flow,
251
+ :@_subscribers,
252
+ :@html_document
253
+ ]
254
+
255
+ def _user_defined_ivars
256
+ instance_variables - INTERNAL_IVARS
257
+ end
258
+
259
+ # Returns a Hash of instance variables and their values, as defined by
260
+ # the user in the test case, which are then assigned to the view being
261
+ # rendered. This is generally intended for internal use and extension
262
+ # frameworks.
263
+ def view_assigns
264
+ Hash[_user_defined_ivars.map do |ivar|
265
+ [ivar[1..-1].to_sym, instance_variable_get(ivar)]
266
+ end]
267
+ end
268
+
269
+ def method_missing(selector, *args)
270
+ begin
271
+ routes = @controller.respond_to?(:_routes) && @controller._routes
272
+ rescue
273
+ # Don't call routes, if there is an error on _routes call
274
+ end
275
+
276
+ if routes &&
277
+ (routes.named_routes.route_defined?(selector) ||
278
+ routes.mounted_helpers.method_defined?(selector))
279
+ @controller.__send__(selector, *args)
280
+ else
281
+ super
282
+ end
283
+ end
284
+
285
+ def respond_to_missing?(name, include_private = false)
286
+ begin
287
+ routes = @controller.respond_to?(:_routes) && @controller._routes
288
+ rescue
289
+ # Don't call routes, if there is an error on _routes call
290
+ end
291
+
292
+ routes &&
293
+ (routes.named_routes.route_defined?(name) ||
294
+ routes.mounted_helpers.method_defined?(name))
295
+ end
296
+ end
297
+
298
+ include Behavior
299
+ end
300
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_view/template/resolver"
4
+
5
+ module ActionView #:nodoc:
6
+ # Use FixtureResolver in your tests to simulate the presence of files on the
7
+ # file system. This is used internally by Rails' own test suite, and is
8
+ # useful for testing extensions that have no way of knowing what the file
9
+ # system will look like at runtime.
10
+ class FixtureResolver < OptimizedFileSystemResolver
11
+ def initialize(hash = {}, pattern = nil)
12
+ super("")
13
+ if pattern
14
+ ActiveSupport::Deprecation.warn "Specifying a custom path for #{self.class} is deprecated. Implement a custom Resolver subclass instead."
15
+ @pattern = pattern
16
+ end
17
+ @hash = hash
18
+ @path = ""
19
+ end
20
+
21
+ def data
22
+ @hash
23
+ end
24
+
25
+ def to_s
26
+ @hash.keys.join(", ")
27
+ end
28
+
29
+ private
30
+
31
+ def query(path, exts, _, locals, cache:)
32
+ regex = build_regex(path, exts)
33
+
34
+ @hash.select do |_path, _|
35
+ ("/" + _path).match?(regex)
36
+ end.map do |_path, source|
37
+ handler, format, variant = extract_handler_and_format_and_variant(_path)
38
+
39
+ Template.new(source, _path, handler,
40
+ virtual_path: path.virtual,
41
+ format: format,
42
+ variant: variant,
43
+ locals: locals
44
+ )
45
+ end.sort_by do |t|
46
+ match = ("/" + t.identifier).match(regex)
47
+ EXTENSIONS.keys.reverse.map do |ext|
48
+ if ext == :variants && exts[ext] == :any
49
+ match[ext].nil? ? 0 : 1
50
+ elsif match[ext].nil?
51
+ exts[ext].length
52
+ else
53
+ found = match[ext].to_sym
54
+ exts[ext].index(found)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ class NullResolver < PathResolver
62
+ def query(path, exts, _, locals, cache:)
63
+ handler, format, variant = extract_handler_and_format_and_variant(path)
64
+ [ActionView::Template.new("Template generated by Null Resolver", path.virtual, handler, virtual_path: path.virtual, format: format, variant: variant, locals: locals)]
65
+ end
66
+ end
67
+ end