actionview 4.2.11.1 → 6.0.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +201 -192
- data/MIT-LICENSE +1 -1
- data/README.rdoc +9 -8
- data/lib/action_view/base.rb +144 -37
- data/lib/action_view/buffers.rb +18 -1
- data/lib/action_view/cache_expiry.rb +53 -0
- data/lib/action_view/context.rb +8 -12
- data/lib/action_view/dependency_tracker.rb +54 -20
- data/lib/action_view/digestor.rb +88 -85
- data/lib/action_view/flows.rb +11 -12
- data/lib/action_view/gem_version.rb +6 -4
- data/lib/action_view/helpers/active_model_helper.rb +16 -11
- data/lib/action_view/helpers/asset_tag_helper.rb +241 -82
- data/lib/action_view/helpers/asset_url_helper.rb +171 -67
- data/lib/action_view/helpers/atom_feed_helper.rb +19 -17
- data/lib/action_view/helpers/cache_helper.rb +112 -42
- data/lib/action_view/helpers/capture_helper.rb +20 -13
- data/lib/action_view/helpers/controller_helper.rb +15 -4
- data/lib/action_view/helpers/csp_helper.rb +26 -0
- data/lib/action_view/helpers/csrf_helper.rb +8 -6
- data/lib/action_view/helpers/date_helper.rb +230 -129
- data/lib/action_view/helpers/debug_helper.rb +7 -6
- data/lib/action_view/helpers/form_helper.rb +755 -129
- data/lib/action_view/helpers/form_options_helper.rb +130 -75
- data/lib/action_view/helpers/form_tag_helper.rb +116 -71
- data/lib/action_view/helpers/javascript_helper.rb +30 -14
- data/lib/action_view/helpers/number_helper.rb +84 -59
- data/lib/action_view/helpers/output_safety_helper.rb +36 -4
- data/lib/action_view/helpers/rendering_helper.rb +11 -8
- data/lib/action_view/helpers/sanitize_helper.rb +30 -31
- data/lib/action_view/helpers/tag_helper.rb +201 -75
- data/lib/action_view/helpers/tags/base.rb +138 -98
- data/lib/action_view/helpers/tags/check_box.rb +20 -19
- data/lib/action_view/helpers/tags/checkable.rb +4 -2
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +12 -34
- data/lib/action_view/helpers/tags/collection_helpers.rb +69 -36
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +6 -12
- data/lib/action_view/helpers/tags/collection_select.rb +4 -2
- data/lib/action_view/helpers/tags/color_field.rb +4 -3
- data/lib/action_view/helpers/tags/date_field.rb +2 -1
- data/lib/action_view/helpers/tags/date_select.rb +37 -36
- data/lib/action_view/helpers/tags/datetime_field.rb +4 -3
- data/lib/action_view/helpers/tags/datetime_local_field.rb +2 -1
- data/lib/action_view/helpers/tags/datetime_select.rb +2 -0
- data/lib/action_view/helpers/tags/email_field.rb +2 -0
- data/lib/action_view/helpers/tags/file_field.rb +2 -0
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +4 -2
- data/lib/action_view/helpers/tags/hidden_field.rb +2 -0
- data/lib/action_view/helpers/tags/label.rb +3 -2
- data/lib/action_view/helpers/tags/month_field.rb +2 -1
- data/lib/action_view/helpers/tags/number_field.rb +2 -0
- data/lib/action_view/helpers/tags/password_field.rb +3 -1
- data/lib/action_view/helpers/tags/placeholderable.rb +3 -1
- data/lib/action_view/helpers/tags/radio_button.rb +7 -6
- data/lib/action_view/helpers/tags/range_field.rb +2 -0
- data/lib/action_view/helpers/tags/search_field.rb +14 -9
- data/lib/action_view/helpers/tags/select.rb +11 -10
- data/lib/action_view/helpers/tags/tel_field.rb +2 -0
- data/lib/action_view/helpers/tags/text_area.rb +4 -2
- data/lib/action_view/helpers/tags/text_field.rb +8 -8
- data/lib/action_view/helpers/tags/time_field.rb +2 -1
- data/lib/action_view/helpers/tags/time_select.rb +2 -0
- data/lib/action_view/helpers/tags/time_zone_select.rb +3 -1
- data/lib/action_view/helpers/tags/translator.rb +15 -16
- data/lib/action_view/helpers/tags/url_field.rb +2 -0
- data/lib/action_view/helpers/tags/week_field.rb +2 -1
- data/lib/action_view/helpers/tags.rb +3 -1
- data/lib/action_view/helpers/text_helper.rb +56 -38
- data/lib/action_view/helpers/translation_helper.rb +91 -47
- data/lib/action_view/helpers/url_helper.rb +160 -105
- data/lib/action_view/helpers.rb +5 -3
- data/lib/action_view/layouts.rb +65 -61
- data/lib/action_view/log_subscriber.rb +61 -10
- data/lib/action_view/lookup_context.rb +147 -89
- data/lib/action_view/model_naming.rb +3 -1
- data/lib/action_view/path_set.rb +28 -23
- data/lib/action_view/railtie.rb +62 -6
- data/lib/action_view/record_identifier.rb +53 -26
- data/lib/action_view/renderer/abstract_renderer.rb +71 -13
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +103 -0
- data/lib/action_view/renderer/partial_renderer.rb +239 -225
- data/lib/action_view/renderer/renderer.rb +22 -8
- data/lib/action_view/renderer/streaming_template_renderer.rb +54 -54
- data/lib/action_view/renderer/template_renderer.rb +79 -73
- data/lib/action_view/rendering.rb +68 -44
- data/lib/action_view/routing_url_for.rb +33 -22
- data/lib/action_view/tasks/cache_digests.rake +25 -0
- data/lib/action_view/template/error.rb +44 -29
- data/lib/action_view/template/handlers/builder.rb +12 -13
- data/lib/action_view/template/handlers/erb/erubi.rb +87 -0
- data/lib/action_view/template/handlers/erb.rb +24 -86
- data/lib/action_view/template/handlers/html.rb +11 -0
- data/lib/action_view/template/handlers/raw.rb +4 -4
- data/lib/action_view/template/handlers.rb +38 -8
- data/lib/action_view/template/html.rb +19 -10
- data/lib/action_view/template/inline.rb +22 -0
- data/lib/action_view/template/raw_file.rb +28 -0
- data/lib/action_view/template/resolver.rb +217 -193
- data/lib/action_view/template/sources/file.rb +17 -0
- data/lib/action_view/template/sources.rb +13 -0
- data/lib/action_view/template/text.rb +11 -10
- data/lib/action_view/template/types.rb +18 -18
- data/lib/action_view/template.rb +146 -90
- data/lib/action_view/test_case.rb +52 -32
- data/lib/action_view/testing/resolvers.rb +46 -34
- data/lib/action_view/unbound_template.rb +31 -0
- data/lib/action_view/version.rb +3 -1
- data/lib/action_view/view_paths.rb +48 -31
- data/lib/action_view.rb +11 -8
- data/lib/assets/compiled/rails-ujs.js +746 -0
- metadata +38 -29
- data/lib/action_view/helpers/record_tag_helper.rb +0 -108
- data/lib/action_view/tasks/dependencies.rake +0 -23
@@ -1,23 +1,17 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/module/attribute_accessors"
|
3
4
|
|
4
5
|
module ActionView
|
5
|
-
class Template
|
6
|
+
class Template #:nodoc:
|
6
7
|
class Types
|
7
8
|
class Type
|
8
|
-
|
9
|
-
self.types = Set.new
|
10
|
-
|
11
|
-
def self.register(*t)
|
12
|
-
types.merge(t.map { |type| type.to_s })
|
13
|
-
end
|
14
|
-
|
15
|
-
register :html, :text, :js, :css, :xml, :json
|
9
|
+
SET = Struct.new(:symbols).new([ :html, :text, :js, :css, :xml, :json ])
|
16
10
|
|
17
11
|
def self.[](type)
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
if type.is_a?(self)
|
13
|
+
type
|
14
|
+
else
|
21
15
|
new(type)
|
22
16
|
end
|
23
17
|
end
|
@@ -28,16 +22,18 @@ module ActionView
|
|
28
22
|
@symbol = symbol.to_sym
|
29
23
|
end
|
30
24
|
|
31
|
-
|
25
|
+
def to_s
|
26
|
+
@symbol.to_s
|
27
|
+
end
|
32
28
|
alias to_str to_s
|
33
29
|
|
34
30
|
def ref
|
35
|
-
|
31
|
+
@symbol
|
36
32
|
end
|
33
|
+
alias to_sym ref
|
37
34
|
|
38
35
|
def ==(type)
|
39
|
-
|
40
|
-
symbol.to_sym == type.to_sym
|
36
|
+
@symbol == type.to_sym unless type.blank?
|
41
37
|
end
|
42
38
|
end
|
43
39
|
|
@@ -52,6 +48,10 @@ module ActionView
|
|
52
48
|
def self.[](type)
|
53
49
|
type_klass[type]
|
54
50
|
end
|
51
|
+
|
52
|
+
def self.symbols
|
53
|
+
type_klass::SET.symbols
|
54
|
+
end
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
data/lib/action_view/template.rb
CHANGED
@@ -1,12 +1,24 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/object/try"
|
4
|
+
require "active_support/core_ext/kernel/singleton_class"
|
5
|
+
require "active_support/deprecation"
|
6
|
+
require "thread"
|
7
|
+
require "delegate"
|
4
8
|
|
5
9
|
module ActionView
|
6
10
|
# = Action View Template
|
7
11
|
class Template
|
8
12
|
extend ActiveSupport::Autoload
|
9
13
|
|
14
|
+
def self.finalize_compiled_template_methods
|
15
|
+
ActiveSupport::Deprecation.warn "ActionView::Template.finalize_compiled_template_methods is deprecated and has no effect"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.finalize_compiled_template_methods=(_)
|
19
|
+
ActiveSupport::Deprecation.warn "ActionView::Template.finalize_compiled_template_methods= is deprecated and has no effect"
|
20
|
+
end
|
21
|
+
|
10
22
|
# === Encodings in ActionView::Template
|
11
23
|
#
|
12
24
|
# ActionView::Template is one of a few sources of potential
|
@@ -65,8 +77,7 @@ module ActionView
|
|
65
77
|
# If you want to provide an alternate mechanism for
|
66
78
|
# specifying encodings (like ERB does via <%# encoding: ... %>),
|
67
79
|
# you may indicate that you will handle encodings yourself
|
68
|
-
# by implementing <tt>
|
69
|
-
# on your handler.
|
80
|
+
# by implementing <tt>handles_encoding?</tt> on your handler.
|
70
81
|
#
|
71
82
|
# If you do, Rails will not try to encode the String
|
72
83
|
# into the default_internal, passing you the unaltered
|
@@ -87,48 +98,77 @@ module ActionView
|
|
87
98
|
# expected_encoding
|
88
99
|
# )
|
89
100
|
|
101
|
+
##
|
102
|
+
# :method: local_assigns
|
103
|
+
#
|
104
|
+
# Returns a hash with the defined local variables.
|
105
|
+
#
|
106
|
+
# Given this sub template rendering:
|
107
|
+
#
|
108
|
+
# <%= render "shared/header", { headline: "Welcome", person: person } %>
|
109
|
+
#
|
110
|
+
# You can use +local_assigns+ in the sub templates to access the local variables:
|
111
|
+
#
|
112
|
+
# local_assigns[:headline] # => "Welcome"
|
113
|
+
|
90
114
|
eager_autoload do
|
91
115
|
autoload :Error
|
116
|
+
autoload :RawFile
|
92
117
|
autoload :Handlers
|
93
118
|
autoload :HTML
|
119
|
+
autoload :Inline
|
120
|
+
autoload :Sources
|
94
121
|
autoload :Text
|
95
122
|
autoload :Types
|
96
123
|
end
|
97
124
|
|
98
125
|
extend Template::Handlers
|
99
126
|
|
100
|
-
|
127
|
+
attr_reader :identifier, :handler, :original_encoding, :updated_at
|
128
|
+
attr_reader :variable, :format, :variant, :locals, :virtual_path
|
101
129
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
Finalizer = proc do |method_name, mod|
|
107
|
-
proc do
|
108
|
-
mod.module_eval do
|
109
|
-
remove_possible_method method_name
|
110
|
-
end
|
130
|
+
def initialize(source, identifier, handler, format: nil, variant: nil, locals: nil, virtual_path: nil, updated_at: nil)
|
131
|
+
unless locals
|
132
|
+
ActiveSupport::Deprecation.warn "ActionView::Template#initialize requires a locals parameter"
|
133
|
+
locals = []
|
111
134
|
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def initialize(source, identifier, handler, details)
|
115
|
-
format = details[:format] || (handler.default_format if handler.respond_to?(:default_format))
|
116
135
|
|
117
136
|
@source = source
|
118
137
|
@identifier = identifier
|
119
138
|
@handler = handler
|
120
139
|
@compiled = false
|
121
|
-
@
|
122
|
-
@
|
123
|
-
|
124
|
-
@
|
125
|
-
|
126
|
-
|
140
|
+
@locals = locals
|
141
|
+
@virtual_path = virtual_path
|
142
|
+
|
143
|
+
@variable = if @virtual_path
|
144
|
+
base = @virtual_path[-1] == "/" ? "" : ::File.basename(@virtual_path)
|
145
|
+
base =~ /\A_?(.*?)(?:\.\w+)*\z/
|
146
|
+
$1.to_sym
|
147
|
+
end
|
148
|
+
|
149
|
+
if updated_at
|
150
|
+
ActiveSupport::Deprecation.warn "ActionView::Template#updated_at is deprecated"
|
151
|
+
@updated_at = updated_at
|
152
|
+
else
|
153
|
+
@updated_at = Time.now
|
154
|
+
end
|
155
|
+
@format = format
|
156
|
+
@variant = variant
|
127
157
|
@compile_mutex = Mutex.new
|
128
158
|
end
|
129
159
|
|
130
|
-
|
131
|
-
|
160
|
+
deprecate :original_encoding
|
161
|
+
deprecate :updated_at
|
162
|
+
deprecate def virtual_path=(_); end
|
163
|
+
deprecate def locals=(_); end
|
164
|
+
deprecate def formats=(_); end
|
165
|
+
deprecate def formats; Array(format); end
|
166
|
+
deprecate def variants=(_); end
|
167
|
+
deprecate def variants; [variant]; end
|
168
|
+
deprecate def refresh(_); self; end
|
169
|
+
|
170
|
+
# Returns whether the underlying handler supports streaming. If so,
|
171
|
+
# a streaming buffer *may* be passed when it starts rendering.
|
132
172
|
def supports_streaming?
|
133
173
|
handler.respond_to?(:supports_streaming?) && handler.supports_streaming?
|
134
174
|
end
|
@@ -139,40 +179,29 @@ module ActionView
|
|
139
179
|
# This method is instrumented as "!render_template.action_view". Notice that
|
140
180
|
# we use a bang in this instrumentation because you don't want to
|
141
181
|
# consume this in production. This is only slow if it's being listened to.
|
142
|
-
def render(view, locals, buffer=
|
143
|
-
|
182
|
+
def render(view, locals, buffer = ActionView::OutputBuffer.new, &block)
|
183
|
+
instrument_render_template do
|
144
184
|
compile!(view)
|
145
|
-
view.
|
185
|
+
view._run(method_name, self, locals, buffer, &block)
|
146
186
|
end
|
147
187
|
rescue => e
|
148
188
|
handle_render_error(view, e)
|
149
189
|
end
|
150
190
|
|
151
191
|
def type
|
152
|
-
@type ||= Types[
|
192
|
+
@type ||= Types[format]
|
153
193
|
end
|
154
194
|
|
155
|
-
|
156
|
-
|
157
|
-
# This method is useful if you have a template object but it does not contain its source
|
158
|
-
# anymore since it was already compiled. In such cases, all you need to do is to call
|
159
|
-
# refresh passing in the view object.
|
160
|
-
#
|
161
|
-
# Notice this method raises an error if the template to be refreshed does not have a
|
162
|
-
# virtual path set (true just for inline templates).
|
163
|
-
def refresh(view)
|
164
|
-
raise "A template needs to have a virtual path in order to be refreshed" unless @virtual_path
|
165
|
-
lookup = view.lookup_context
|
166
|
-
pieces = @virtual_path.split("/")
|
167
|
-
name = pieces.pop
|
168
|
-
partial = !!name.sub!(/^_/, "")
|
169
|
-
lookup.disable_cache do
|
170
|
-
lookup.find_template(name, [ pieces.join('/') ], partial, @locals)
|
171
|
-
end
|
195
|
+
def short_identifier
|
196
|
+
@short_identifier ||= defined?(Rails.root) ? identifier.sub("#{Rails.root}/", "") : identifier
|
172
197
|
end
|
173
198
|
|
174
199
|
def inspect
|
175
|
-
|
200
|
+
"#<#{self.class.name} #{short_identifier} locals=#{@locals.inspect}>"
|
201
|
+
end
|
202
|
+
|
203
|
+
def source
|
204
|
+
@source.to_s
|
176
205
|
end
|
177
206
|
|
178
207
|
# This method is responsible for properly setting the encoding of the
|
@@ -186,12 +215,14 @@ module ActionView
|
|
186
215
|
# before passing the source on to the template engine, leaving a
|
187
216
|
# blank line in its stead.
|
188
217
|
def encode!
|
189
|
-
|
218
|
+
source = self.source
|
219
|
+
|
220
|
+
return source unless source.encoding == Encoding::BINARY
|
190
221
|
|
191
222
|
# Look for # encoding: *. If we find one, we'll encode the
|
192
223
|
# String in that encoding, otherwise, we'll use the
|
193
224
|
# default external encoding.
|
194
|
-
if source.sub!(/\A#{ENCODING_FLAG}/,
|
225
|
+
if source.sub!(/\A#{ENCODING_FLAG}/, "")
|
195
226
|
encoding = magic_encoding = $1
|
196
227
|
else
|
197
228
|
encoding = Encoding.default_external
|
@@ -219,11 +250,23 @@ module ActionView
|
|
219
250
|
end
|
220
251
|
end
|
221
252
|
|
222
|
-
protected
|
223
253
|
|
254
|
+
# Exceptions are marshalled when using the parallel test runner with DRb, so we need
|
255
|
+
# to ensure that references to the template object can be marshalled as well. This means forgoing
|
256
|
+
# the marshalling of the compiler mutex and instantiating that again on unmarshalling.
|
257
|
+
def marshal_dump # :nodoc:
|
258
|
+
[ @source, @identifier, @handler, @compiled, @locals, @virtual_path, @updated_at, @format, @variant ]
|
259
|
+
end
|
260
|
+
|
261
|
+
def marshal_load(array) # :nodoc:
|
262
|
+
@source, @identifier, @handler, @compiled, @locals, @virtual_path, @updated_at, @format, @variant = *array
|
263
|
+
@compile_mutex = Mutex.new
|
264
|
+
end
|
265
|
+
|
266
|
+
private
|
224
267
|
# Compile a template. This method ensures a template is compiled
|
225
268
|
# just once and removes the source after it is compiled.
|
226
|
-
def compile!(view)
|
269
|
+
def compile!(view)
|
227
270
|
return if @compiled
|
228
271
|
|
229
272
|
# Templates can be used concurrently in threaded environments
|
@@ -235,23 +278,25 @@ module ActionView
|
|
235
278
|
# re-compilation
|
236
279
|
return if @compiled
|
237
280
|
|
238
|
-
|
239
|
-
mod = ActionView::CompiledTemplates
|
240
|
-
else
|
241
|
-
mod = view.singleton_class
|
242
|
-
end
|
281
|
+
mod = view.compiled_method_container
|
243
282
|
|
244
283
|
instrument("!compile_template") do
|
245
284
|
compile(mod)
|
246
285
|
end
|
247
286
|
|
248
|
-
# Just discard the source if we have a virtual path. This
|
249
|
-
# means we can get the template back.
|
250
|
-
@source = nil if @virtual_path
|
251
287
|
@compiled = true
|
252
288
|
end
|
253
289
|
end
|
254
290
|
|
291
|
+
class LegacyTemplate < DelegateClass(Template) # :nodoc:
|
292
|
+
attr_reader :source
|
293
|
+
|
294
|
+
def initialize(template, source)
|
295
|
+
super(template)
|
296
|
+
@source = source
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
255
300
|
# Among other things, this method is responsible for properly setting
|
256
301
|
# the encoding of the compiled template.
|
257
302
|
#
|
@@ -264,18 +309,16 @@ module ActionView
|
|
264
309
|
# encode the source into <tt>Encoding.default_internal</tt>.
|
265
310
|
# In general, this means that templates will be UTF-8 inside of Rails,
|
266
311
|
# regardless of the original source encoding.
|
267
|
-
def compile(mod)
|
268
|
-
encode!
|
269
|
-
|
270
|
-
code = @handler.call(self)
|
312
|
+
def compile(mod)
|
313
|
+
source = encode!
|
314
|
+
code = @handler.call(self, source)
|
271
315
|
|
272
316
|
# Make sure that the resulting String to be eval'd is in the
|
273
317
|
# encoding of the code
|
274
|
-
|
318
|
+
original_source = source
|
319
|
+
source = +<<-end_src
|
275
320
|
def #{method_name}(local_assigns, output_buffer)
|
276
|
-
|
277
|
-
ensure
|
278
|
-
@virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer
|
321
|
+
@virtual_path = #{@virtual_path.inspect};#{locals_code};#{code}
|
279
322
|
end
|
280
323
|
end_src
|
281
324
|
|
@@ -290,47 +333,60 @@ module ActionView
|
|
290
333
|
# handler is valid in the default_internal. This is for handlers
|
291
334
|
# that handle encoding but screw up
|
292
335
|
unless source.valid_encoding?
|
293
|
-
raise WrongEncodingError.new(
|
336
|
+
raise WrongEncodingError.new(source, Encoding.default_internal)
|
294
337
|
end
|
295
338
|
|
296
|
-
|
297
|
-
|
339
|
+
begin
|
340
|
+
mod.module_eval(source, identifier, 0)
|
341
|
+
rescue SyntaxError
|
342
|
+
# Account for when code in the template is not syntactically valid; e.g. if we're using
|
343
|
+
# ERB and the user writes <%= foo( %>, attempting to call a helper `foo` and interpolate
|
344
|
+
# the result into the template, but missing an end parenthesis.
|
345
|
+
raise SyntaxErrorInTemplate.new(self, original_source)
|
346
|
+
end
|
298
347
|
end
|
299
348
|
|
300
|
-
def handle_render_error(view, e)
|
349
|
+
def handle_render_error(view, e)
|
301
350
|
if e.is_a?(Template::Error)
|
302
351
|
e.sub_template_of(self)
|
303
352
|
raise e
|
304
353
|
else
|
305
|
-
|
306
|
-
unless template.source
|
307
|
-
template = refresh(view)
|
308
|
-
template.encode!
|
309
|
-
end
|
310
|
-
raise Template::Error.new(template, e)
|
354
|
+
raise Template::Error.new(self)
|
311
355
|
end
|
312
356
|
end
|
313
357
|
|
314
|
-
def locals_code
|
315
|
-
#
|
316
|
-
|
358
|
+
def locals_code
|
359
|
+
# Only locals with valid variable names get set directly. Others will
|
360
|
+
# still be available in local_assigns.
|
361
|
+
locals = @locals - Module::RUBY_RESERVED_KEYWORDS
|
362
|
+
locals = locals.grep(/\A@?(?![A-Z0-9])(?:[[:alnum:]_]|[^\0-\177])+\z/)
|
363
|
+
|
364
|
+
# Assign for the same variable is to suppress unused variable warning
|
365
|
+
locals.each_with_object(+"") { |key, code| code << "#{key} = local_assigns[:#{key}]; #{key} = #{key};" }
|
317
366
|
end
|
318
367
|
|
319
|
-
def method_name
|
368
|
+
def method_name
|
320
369
|
@method_name ||= begin
|
321
|
-
m = "_#{identifier_method_name}__#{@identifier.hash}_#{__id__}"
|
322
|
-
m.tr!(
|
370
|
+
m = +"_#{identifier_method_name}__#{@identifier.hash}_#{__id__}"
|
371
|
+
m.tr!("-", "_")
|
323
372
|
m
|
324
373
|
end
|
325
374
|
end
|
326
375
|
|
327
|
-
def identifier_method_name
|
328
|
-
|
376
|
+
def identifier_method_name
|
377
|
+
short_identifier.tr("^a-z_", "_")
|
378
|
+
end
|
379
|
+
|
380
|
+
def instrument(action, &block) # :doc:
|
381
|
+
ActiveSupport::Notifications.instrument("#{action}.action_view", instrument_payload, &block)
|
382
|
+
end
|
383
|
+
|
384
|
+
def instrument_render_template(&block)
|
385
|
+
ActiveSupport::Notifications.instrument("!render_template.action_view", instrument_payload, &block)
|
329
386
|
end
|
330
387
|
|
331
|
-
def
|
332
|
-
|
333
|
-
ActiveSupport::Notifications.instrument("#{action}.action_view", payload, &block)
|
388
|
+
def instrument_payload
|
389
|
+
{ virtual_path: @virtual_path, identifier: @identifier }
|
334
390
|
end
|
335
391
|
end
|
336
392
|
end
|
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
|
-
require 'action_controller'
|
3
|
-
require 'action_controller/test_case'
|
4
|
-
require 'action_view'
|
1
|
+
# frozen_string_literal: true
|
5
2
|
|
6
|
-
require
|
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"
|
7
9
|
|
8
10
|
module ActionView
|
9
11
|
# = Action View Test Case
|
@@ -18,17 +20,17 @@ module ActionView
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def controller_path=(path)
|
21
|
-
self.class.controller_path=(path)
|
23
|
+
self.class.controller_path = (path)
|
22
24
|
end
|
23
25
|
|
24
26
|
def initialize
|
25
27
|
super
|
26
28
|
self.class.controller_path = ""
|
27
|
-
@request = ActionController::TestRequest.
|
28
|
-
@response =
|
29
|
+
@request = ActionController::TestRequest.create(self.class)
|
30
|
+
@response = ActionDispatch::TestResponse.new
|
29
31
|
|
30
|
-
@request.env.delete(
|
31
|
-
@params =
|
32
|
+
@request.env.delete("PATH_INFO")
|
33
|
+
@params = ActionController::Parameters.new
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
@@ -49,7 +51,7 @@ module ActionView
|
|
49
51
|
|
50
52
|
include ActiveSupport::Testing::ConstantLookup
|
51
53
|
|
52
|
-
delegate :lookup_context, :
|
54
|
+
delegate :lookup_context, to: :controller
|
53
55
|
attr_accessor :controller, :output_buffer, :rendered
|
54
56
|
|
55
57
|
module ClassMethods
|
@@ -71,10 +73,11 @@ module ActionView
|
|
71
73
|
def helper_method(*methods)
|
72
74
|
# Almost a duplicate from ActionController::Helpers
|
73
75
|
methods.flatten.each do |method|
|
74
|
-
_helpers.module_eval <<-end_eval
|
76
|
+
_helpers.module_eval <<-end_eval, __FILE__, __LINE__ + 1
|
75
77
|
def #{method}(*args, &block) # def current_user(*args, &block)
|
76
|
-
_test_case.send(
|
78
|
+
_test_case.send(:'#{method}', *args, &block) # _test_case.send(:'current_user', *args, &block)
|
77
79
|
end # end
|
80
|
+
ruby2_keywords(:'#{method}') if respond_to?(:ruby2_keywords, true)
|
78
81
|
end_eval
|
79
82
|
end
|
80
83
|
end
|
@@ -91,21 +94,20 @@ module ActionView
|
|
91
94
|
end
|
92
95
|
|
93
96
|
private
|
94
|
-
|
95
97
|
def include_helper_modules!
|
96
98
|
helper(helper_class) if helper_class
|
97
99
|
include _helpers
|
98
100
|
end
|
99
|
-
|
100
101
|
end
|
101
102
|
|
102
103
|
def setup_with_controller
|
103
104
|
@controller = ActionView::TestCase::TestController.new
|
104
105
|
@request = @controller.request
|
106
|
+
@view_flow = ActionView::OutputFlow.new
|
105
107
|
# empty string ensures buffer has UTF-8 encoding as
|
106
108
|
# new without arguments returns ASCII-8BIT encoded buffer like String#new
|
107
|
-
@output_buffer = ActiveSupport::SafeBuffer.new
|
108
|
-
@rendered =
|
109
|
+
@output_buffer = ActiveSupport::SafeBuffer.new ""
|
110
|
+
@rendered = +""
|
109
111
|
|
110
112
|
make_test_case_available_to_view!
|
111
113
|
say_no_to_protect_against_forgery!
|
@@ -125,6 +127,10 @@ module ActionView
|
|
125
127
|
@_rendered_views ||= RenderedViewsCollection.new
|
126
128
|
end
|
127
129
|
|
130
|
+
def _routes
|
131
|
+
@controller._routes if @controller.respond_to?(:_routes)
|
132
|
+
end
|
133
|
+
|
128
134
|
# Need to experiment if this priority is the best one: rendered => output_buffer
|
129
135
|
class RenderedViewsCollection
|
130
136
|
def initialize
|
@@ -146,17 +152,17 @@ module ActionView
|
|
146
152
|
|
147
153
|
def view_rendered?(view, expected_locals)
|
148
154
|
locals_for(view).any? do |actual_locals|
|
149
|
-
expected_locals.all? {|key, value| value == actual_locals[key] }
|
155
|
+
expected_locals.all? { |key, value| value == actual_locals[key] }
|
150
156
|
end
|
151
157
|
end
|
152
158
|
end
|
153
159
|
|
154
160
|
included do
|
155
161
|
setup :setup_with_controller
|
162
|
+
ActiveSupport.run_load_hooks(:action_view_test_case, self)
|
156
163
|
end
|
157
164
|
|
158
165
|
private
|
159
|
-
|
160
166
|
# Need to experiment if this priority is the best one: rendered => output_buffer
|
161
167
|
def document_root_element
|
162
168
|
Nokogiri::HTML::Document.parse(@rendered.blank? ? @output_buffer : @rendered).root
|
@@ -164,7 +170,7 @@ module ActionView
|
|
164
170
|
|
165
171
|
def say_no_to_protect_against_forgery!
|
166
172
|
_helpers.module_eval do
|
167
|
-
|
173
|
+
silence_redefinition_of_method :protect_against_forgery?
|
168
174
|
def protect_against_forgery?
|
169
175
|
false
|
170
176
|
end
|
@@ -204,10 +210,10 @@ module ActionView
|
|
204
210
|
def view
|
205
211
|
@view ||= begin
|
206
212
|
view = @controller.view_context
|
207
|
-
view.singleton_class.
|
213
|
+
view.singleton_class.include(_helpers)
|
208
214
|
view.extend(Locals)
|
209
|
-
view.rendered_views =
|
210
|
-
view.output_buffer =
|
215
|
+
view.rendered_views = rendered_views
|
216
|
+
view.output_buffer = output_buffer
|
211
217
|
view
|
212
218
|
end
|
213
219
|
end
|
@@ -240,9 +246,9 @@ module ActionView
|
|
240
246
|
:@test_passed,
|
241
247
|
:@view,
|
242
248
|
:@view_context_class,
|
249
|
+
:@view_flow,
|
243
250
|
:@_subscribers,
|
244
|
-
:@html_document
|
245
|
-
:@html_scanner_document
|
251
|
+
:@html_document
|
246
252
|
]
|
247
253
|
|
248
254
|
def _user_defined_ivars
|
@@ -259,19 +265,33 @@ module ActionView
|
|
259
265
|
end]
|
260
266
|
end
|
261
267
|
|
262
|
-
def _routes
|
263
|
-
@controller._routes if @controller.respond_to?(:_routes)
|
264
|
-
end
|
265
|
-
|
266
268
|
def method_missing(selector, *args)
|
267
|
-
|
268
|
-
|
269
|
-
|
269
|
+
begin
|
270
|
+
routes = @controller.respond_to?(:_routes) && @controller._routes
|
271
|
+
rescue
|
272
|
+
# Don't call routes, if there is an error on _routes call
|
273
|
+
end
|
274
|
+
|
275
|
+
if routes &&
|
276
|
+
(routes.named_routes.route_defined?(selector) ||
|
277
|
+
routes.mounted_helpers.method_defined?(selector))
|
270
278
|
@controller.__send__(selector, *args)
|
271
279
|
else
|
272
280
|
super
|
273
281
|
end
|
274
282
|
end
|
283
|
+
|
284
|
+
def respond_to_missing?(name, include_private = false)
|
285
|
+
begin
|
286
|
+
routes = @controller.respond_to?(:_routes) && @controller._routes
|
287
|
+
rescue
|
288
|
+
# Don't call routes, if there is an error on _routes call
|
289
|
+
end
|
290
|
+
|
291
|
+
routes &&
|
292
|
+
(routes.named_routes.route_defined?(name) ||
|
293
|
+
routes.mounted_helpers.method_defined?(name))
|
294
|
+
end
|
275
295
|
end
|
276
296
|
|
277
297
|
include Behavior
|