diff options
Diffstat (limited to 'actionview')
30 files changed, 278 insertions, 124 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index 16361fd2eb..e2cd9f7558 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,5 +1,11 @@ ## Rails 6.0.0.beta1 (January 18, 2019) ## +* [Rename npm package](https://github.com/rails/rails/pull/34905) from + [`rails-ujs`](https://www.npmjs.com/package/rails-ujs) to + [`@rails/ujs`](https://www.npmjs.com/package/@rails/ujs). + + *Javan Makhmali* + * Remove deprecated `image_alt` helper. *Rafael Mendonça França* diff --git a/actionview/lib/action_view.rb b/actionview/lib/action_view.rb index c4a614fa6d..6ff2d70e35 100644 --- a/actionview/lib/action_view.rb +++ b/actionview/lib/action_view.rb @@ -45,6 +45,7 @@ module ActionView autoload :Rendering autoload :RoutingUrlFor autoload :Template + autoload :FileTemplate autoload :ViewPaths autoload_under "renderer" do diff --git a/actionview/lib/action_view/base.rb b/actionview/lib/action_view/base.rb index 6cb342a0a9..b143e13c96 100644 --- a/actionview/lib/action_view/base.rb +++ b/actionview/lib/action_view/base.rb @@ -3,6 +3,7 @@ require "active_support/core_ext/module/attr_internal" require "active_support/core_ext/module/attribute_accessors" require "active_support/ordered_options" +require "active_support/deprecation" require "action_view/log_subscriber" require "action_view/helpers" require "action_view/context" @@ -187,7 +188,7 @@ module ActionView #:nodoc: end end - attr_accessor :view_renderer + attr_reader :view_renderer attr_internal :config, :assigns delegate :lookup_context, to: :view_renderer @@ -197,17 +198,51 @@ module ActionView #:nodoc: @_assigns = new_assigns.each { |key, value| instance_variable_set("@#{key}", value) } end - def initialize(context = nil, assigns = {}, controller = nil, formats = nil) #:nodoc: + # :stopdoc: + + def self.build_renderer(context, controller, formats) + lookup_context = context.is_a?(ActionView::LookupContext) ? + context : ActionView::LookupContext.new(context) + lookup_context.formats = formats if formats + lookup_context.prefixes = controller._prefixes if controller + ActionView::Renderer.new(lookup_context) + end + + def self.empty + with_view_paths([]) + end + + def self.with_view_paths(view_paths, assigns = {}, controller = nil) + with_context ActionView::LookupContext.new(view_paths), assigns, controller + end + + def self.with_context(context, assigns = {}, controller = nil) + new ActionView::Renderer.new(context), assigns, controller + end + + NULL = Object.new + + # :startdoc: + + def initialize(renderer = nil, assigns = {}, controller = nil, formats = NULL) #:nodoc: @_config = ActiveSupport::InheritableOptions.new - if context.is_a?(ActionView::Renderer) - @view_renderer = context + if formats == NULL + formats = nil + else + ActiveSupport::Deprecation.warn <<~eowarn + Passing formats to ActionView::Base.new is deprecated + eowarn + end + + if renderer.is_a?(ActionView::Renderer) + @view_renderer = renderer else - lookup_context = context.is_a?(ActionView::LookupContext) ? - context : ActionView::LookupContext.new(context) - lookup_context.formats = formats if formats - lookup_context.prefixes = controller._prefixes if controller - @view_renderer = ActionView::Renderer.new(lookup_context) + ActiveSupport::Deprecation.warn <<~eowarn + ActionView::Base instances should be constructed with a view renderer, + assigments, and a controller. + eowarn + @view_renderer = self.class.build_renderer(renderer, controller, formats) end @cache_hit = {} diff --git a/actionview/lib/action_view/file_template.rb b/actionview/lib/action_view/file_template.rb new file mode 100644 index 0000000000..4921074383 --- /dev/null +++ b/actionview/lib/action_view/file_template.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require "action_view/template" + +module ActionView + class FileTemplate < Template + def initialize(filename, handler, details) + @filename = filename + + super(nil, filename, handler, details) + end + + def source + File.binread @filename + end + + def refresh(_) + self + end + + # Exceptions are marshalled when using the parallel test runner with DRb, so we need + # to ensure that references to the template object can be marshalled as well. This means forgoing + # the marshalling of the compiler mutex and instantiating that again on unmarshalling. + def marshal_dump # :nodoc: + [ @identifier, @handler, @compiled, @original_encoding, @locals, @virtual_path, @updated_at, @formats, @variants ] + end + + def marshal_load(array) # :nodoc: + @identifier, @handler, @compiled, @original_encoding, @locals, @virtual_path, @updated_at, @formats, @variants = *array + @compile_mutex = Mutex.new + end + end +end diff --git a/actionview/lib/action_view/lookup_context.rb b/actionview/lib/action_view/lookup_context.rb index 554d223c0e..c2f6439e26 100644 --- a/actionview/lib/action_view/lookup_context.rb +++ b/actionview/lib/action_view/lookup_context.rb @@ -3,6 +3,7 @@ require "concurrent/map" require "active_support/core_ext/module/remove_method" require "active_support/core_ext/module/attribute_accessors" +require "active_support/deprecation" require "action_view/template/resolver" module ActionView @@ -106,12 +107,6 @@ module ActionView module ViewPaths attr_reader :view_paths, :html_fallback_for_js - # Whenever setting view paths, makes a copy so that we can manipulate them in - # instance objects as we wish. - def view_paths=(paths) - @view_paths = ActionView::PathSet.new(Array(paths)) - end - def find(name, prefixes = [], partial = false, keys = [], options = {}) @view_paths.find(*args_for_lookup(name, prefixes, partial, keys, options)) end @@ -138,19 +133,34 @@ module ActionView # Adds fallbacks to the view paths. Useful in cases when you are rendering # a :file. def with_fallbacks - added_resolvers = 0 - self.class.fallbacks.each do |resolver| - next if view_paths.include?(resolver) - view_paths.push(resolver) - added_resolvers += 1 + view_paths = build_view_paths((@view_paths.paths + self.class.fallbacks).uniq) + + if block_given? + ActiveSupport::Deprecation.warn <<~eowarn + Calling `with_fallbacks` with a block is deprecated. Call methods on + the lookup context returned by `with_fallbacks` instead. + eowarn + + begin + _view_paths = @view_paths + @view_paths = view_paths + yield + ensure + @view_paths = _view_paths + end + else + ActionView::LookupContext.new(view_paths, @details, @prefixes) end - yield - ensure - added_resolvers.times { view_paths.pop } end private + # Whenever setting view paths, makes a copy so that we can manipulate them in + # instance objects as we wish. + def build_view_paths(paths) + ActionView::PathSet.new(Array(paths)) + end + def args_for_lookup(name, prefixes, partial, keys, details_options) name, prefixes = normalize_name(name, prefixes) details, details_key = detail_args_for(details_options) @@ -226,7 +236,7 @@ module ActionView @rendered_format = nil @details = initialize_details({}, details) - self.view_paths = view_paths + @view_paths = build_view_paths(view_paths) end def digest_cache diff --git a/actionview/lib/action_view/renderer/abstract_renderer.rb b/actionview/lib/action_view/renderer/abstract_renderer.rb index 20b2523cac..ae366ce54a 100644 --- a/actionview/lib/action_view/renderer/abstract_renderer.rb +++ b/actionview/lib/action_view/renderer/abstract_renderer.rb @@ -17,7 +17,7 @@ module ActionView # that new object is called in turn. This abstracts the setup and rendering # into a separate classes for partials and templates. class AbstractRenderer #:nodoc: - delegate :find_template, :find_file, :template_exists?, :any_templates?, :with_fallbacks, :with_layout_format, :formats, to: :@lookup_context + delegate :template_exists?, :any_templates?, :formats, to: :@lookup_context def initialize(lookup_context) @lookup_context = lookup_context @@ -38,8 +38,6 @@ module ActionView end def instrument(name, **options) # :doc: - options[:identifier] ||= (@template && @template.identifier) || @path - ActiveSupport::Notifications.instrument("render_#{name}.action_view", options) do |payload| yield payload end diff --git a/actionview/lib/action_view/renderer/partial_renderer.rb b/actionview/lib/action_view/renderer/partial_renderer.rb index f175c30aa1..478400e016 100644 --- a/actionview/lib/action_view/renderer/partial_renderer.rb +++ b/actionview/lib/action_view/renderer/partial_renderer.rb @@ -296,42 +296,43 @@ module ActionView def render(context, options, block) setup(context, options, block) - @template = find_partial + template = find_partial @lookup_context.rendered_format ||= begin - if @template && @template.formats.present? - @template.formats.first + if template && template.formats.first + template.formats.first else formats.first end end if @collection - render_collection + render_collection(context, template) else - render_partial + render_partial(context, template) end end private - def render_collection - instrument(:collection, count: @collection.size) do |payload| + def render_collection(view, template) + identifier = (template && template.identifier) || @path + instrument(:collection, identifier: identifier, count: @collection.size) do |payload| return nil if @collection.blank? if @options.key?(:spacer_template) - spacer = find_template(@options[:spacer_template], @locals.keys).render(@view, @locals) + spacer = find_template(@options[:spacer_template], @locals.keys).render(view, @locals) end - cache_collection_render(payload) do - @template ? collection_with_template : collection_without_template + cache_collection_render(payload, view, template) do + template ? collection_with_template(view, template) : collection_without_template(view) end.join(spacer).html_safe end end - def render_partial - instrument(:partial) do |payload| - view, locals, block = @view, @locals, @block + def render_partial(view, template) + instrument(:partial, identifier: template.identifier) do |payload| + locals, block = @locals, @block object, as = @object, @variable if !block && (layout = @options[:layout]) @@ -341,12 +342,12 @@ module ActionView object = locals[as] if object.nil? # Respect object when object is false locals[as] = object if @has_object - content = @template.render(view, locals) do |*name| + content = template.render(view, locals) do |*name| view._layout_for(*name, &block) end content = layout.render(view, locals) { content } if layout - payload[:cache_hit] = view.view_renderer.cache_hits[@template.virtual_path] + payload[:cache_hit] = view.view_renderer.cache_hits[template.virtual_path] content end end @@ -359,7 +360,6 @@ module ActionView # set to that string. Otherwise, the +options[:partial]+ object must # respond to +to_partial_path+ in order to setup the path. def setup(context, options, block) - @view = context @options = options @block = block @@ -381,10 +381,10 @@ module ActionView @collection = collection_from_object || collection_from_options if @collection - paths = @collection_data = @collection.map { |o| partial_path(o) } + paths = @collection_data = @collection.map { |o| partial_path(o, context) } @path = paths.uniq.one? ? paths.first : nil else - @path = partial_path + @path = partial_path(@object, context) end end @@ -423,8 +423,8 @@ module ActionView @lookup_context.find_template(path, prefixes, true, locals, @details) end - def collection_with_template - view, locals, template = @view, @locals, @template + def collection_with_template(view, template) + locals = @locals as, counter, iteration = @variable, @variable_counter, @variable_iteration if layout = @options[:layout] @@ -445,8 +445,8 @@ module ActionView end end - def collection_without_template - view, locals, collection_data = @view, @locals, @collection_data + def collection_without_template(view) + locals, collection_data = @locals, @collection_data cache = {} keys = @locals.keys @@ -474,7 +474,7 @@ module ActionView # # If +prefix_partial_path_with_controller_namespace+ is true, then this # method will prefix the partial paths with a namespace. - def partial_path(object = @object) + def partial_path(object, view) object = object.to_model if object.respond_to?(:to_model) path = if object.respond_to?(:to_partial_path) @@ -483,7 +483,7 @@ module ActionView raise ArgumentError.new("'#{object.inspect}' is not an ActiveModel-compatible object. It must implement :to_partial_path.") end - if @view.prefix_partial_path_with_controller_namespace + if view.prefix_partial_path_with_controller_namespace prefixed_partial_names[path] ||= merge_prefix_into_object_path(@context_prefix, path.dup) else path diff --git a/actionview/lib/action_view/renderer/partial_renderer/collection_caching.rb b/actionview/lib/action_view/renderer/partial_renderer/collection_caching.rb index 5aa6f77902..388f9e5e56 100644 --- a/actionview/lib/action_view/renderer/partial_renderer/collection_caching.rb +++ b/actionview/lib/action_view/renderer/partial_renderer/collection_caching.rb @@ -11,13 +11,13 @@ module ActionView end private - def cache_collection_render(instrumentation_payload) + def cache_collection_render(instrumentation_payload, view, template) return yield unless @options[:cached] # Result is a hash with the key represents the # key used for cache lookup and the value is the item # on which the partial is being rendered - keyed_collection = collection_by_cache_keys + keyed_collection = collection_by_cache_keys(view, template) # Pull all partials from cache # Result is a hash, key matches the entry in @@ -51,23 +51,21 @@ module ActionView @options[:cached].respond_to?(:call) end - def collection_by_cache_keys + def collection_by_cache_keys(view, template) seed = callable_cache_key? ? @options[:cached] : ->(i) { i } + digest_path = view.digest_path_from_virtual(template.virtual_path) + @collection.each_with_object({}) do |item, hash| - hash[expanded_cache_key(seed.call(item))] = item + hash[expanded_cache_key(seed.call(item), view, template, digest_path)] = item end end - def expanded_cache_key(key) - key = @view.combined_fragment_cache_key(@view.cache_fragment_name(key, virtual_path: @template.virtual_path, digest_path: digest_path)) + def expanded_cache_key(key, view, template, digest_path) + key = view.combined_fragment_cache_key(view.cache_fragment_name(key, virtual_path: template.virtual_path, digest_path: digest_path)) key.frozen? ? key.dup : key # #read_multi & #write may require mutability, Dalli 2.6.0. end - def digest_path - @digest_path ||= @view.digest_path_from_virtual(@template.virtual_path) - end - # `order_by` is an enumerable object containing keys of the cache, # all keys are passed in whether found already or not. # diff --git a/actionview/lib/action_view/renderer/template_renderer.rb b/actionview/lib/action_view/renderer/template_renderer.rb index fb5539e0db..c36baeffcd 100644 --- a/actionview/lib/action_view/renderer/template_renderer.rb +++ b/actionview/lib/action_view/renderer/template_renderer.rb @@ -12,7 +12,7 @@ module ActionView @lookup_context.rendered_format ||= (template.formats.first || formats.first) - render_template(context, template, options[:layout], options[:locals]) + render_template(context, template, options[:layout], options[:locals] || {}) end private @@ -28,7 +28,7 @@ module ActionView elsif options.key?(:html) Template::HTML.new(options[:html], formats.first) elsif options.key?(:file) - with_fallbacks { find_file(options[:file], nil, false, keys, @details) } + @lookup_context.with_fallbacks.find_file(options[:file], nil, false, keys, @details) elsif options.key?(:inline) handler = Template.handler_for_extension(options[:type] || "erb") Template.new(options[:inline], "inline template", handler, locals: keys) @@ -36,7 +36,7 @@ module ActionView if options[:template].respond_to?(:render) options[:template] else - find_template(options[:template], options[:prefixes], false, keys, @details) + @lookup_context.find_template(options[:template], options[:prefixes], false, keys, @details) end else raise ArgumentError, "You invoked render but did not give any of :partial, :template, :inline, :file, :plain, :html or :body option." @@ -45,9 +45,7 @@ module ActionView # Renders the given template. A string representing the layout can be # supplied as well. - def render_template(view, template, layout_name = nil, locals = nil) - locals ||= {} - + def render_template(view, template, layout_name, locals) render_with_layout(view, layout_name, locals) do |layout| instrument(:template, identifier: template.identifier, layout: layout.try(:virtual_path)) do template.render(view, locals) { |*name| view._layout_for(*name) } @@ -82,9 +80,9 @@ module ActionView when String begin if layout.start_with?("/") - with_fallbacks { find_template(layout, nil, false, [], details) } + @lookup_context.with_fallbacks.find_template(layout, nil, false, [], details) else - find_template(layout, nil, false, [], details) + @lookup_context.find_template(layout, nil, false, [], details) end rescue ActionView::MissingTemplate all_details = @details.merge(formats: @lookup_context.default_formats) diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb index 8ce8053011..3b2c264ed4 100644 --- a/actionview/lib/action_view/template.rb +++ b/actionview/lib/action_view/template.rb @@ -3,6 +3,7 @@ require "active_support/core_ext/object/try" require "active_support/core_ext/kernel/singleton_class" require "thread" +require "delegate" module ActionView # = Action View Template @@ -202,7 +203,9 @@ module ActionView # before passing the source on to the template engine, leaving a # blank line in its stead. def encode! - return unless source.encoding == Encoding::BINARY + source = self.source + + return source unless source.encoding == Encoding::BINARY # Look for # encoding: *. If we find one, we'll encode the # String in that encoding, otherwise, we'll use the @@ -277,6 +280,15 @@ module ActionView end end + class LegacyTemplate < DelegateClass(Template) # :nodoc: + attr_reader :source + + def initialize(template, source) + super(template) + @source = source + end + end + # Among other things, this method is responsible for properly setting # the encoding of the compiled template. # @@ -290,8 +302,8 @@ module ActionView # In general, this means that templates will be UTF-8 inside of Rails, # regardless of the original source encoding. def compile(mod) - encode! - code = @handler.call(self) + source = encode! + code = @handler.call(self, source) # Make sure that the resulting String to be eval'd is in the # encoding of the code @@ -312,7 +324,7 @@ module ActionView # handler is valid in the default_internal. This is for handlers # that handle encoding but screw up unless source.valid_encoding? - raise WrongEncodingError.new(@source, Encoding.default_internal) + raise WrongEncodingError.new(source, Encoding.default_internal) end mod.module_eval(source, identifier, 0) diff --git a/actionview/lib/action_view/template/handlers.rb b/actionview/lib/action_view/template/handlers.rb index 7ec76dcc3f..f2a2341b8e 100644 --- a/actionview/lib/action_view/template/handlers.rb +++ b/actionview/lib/action_view/template/handlers.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "active_support/deprecation" + module ActionView #:nodoc: # = Action View Template Handlers class Template #:nodoc: @@ -14,7 +16,7 @@ module ActionView #:nodoc: base.register_template_handler :erb, ERB.new base.register_template_handler :html, Html.new base.register_template_handler :builder, Builder.new - base.register_template_handler :ruby, :source.to_proc + base.register_template_handler :ruby, lambda { |_, source| source } end @@template_handlers = {} @@ -24,11 +26,35 @@ module ActionView #:nodoc: @@template_extensions ||= @@template_handlers.keys end + class LegacyHandlerWrapper < SimpleDelegator # :nodoc: + def call(view, source) + __getobj__.call(ActionView::Template::LegacyTemplate.new(view, source)) + end + end + # Register an object that knows how to handle template files with the given # extensions. This can be used to implement new template types. # The handler must respond to +:call+, which will be passed the template # and should return the rendered template as a String. def register_template_handler(*extensions, handler) + params = if handler.is_a?(Proc) + handler.parameters + else + handler.method(:call).parameters + end + + unless params.find_all { |type, _| type == :req }.length >= 2 + ActiveSupport::Deprecation.warn <<~eowarn + Single arity template handlers are deprecated. Template handlers must + now accept two parameters, the view object and the source for the view object. + Change: + >> #{handler.class}#call(#{params.map(&:last).join(", ")}) + To: + >> #{handler.class}#call(#{params.map(&:last).join(", ")}, source) + eowarn + handler = LegacyHandlerWrapper.new(handler) + end + raise(ArgumentError, "Extension is required") if extensions.empty? extensions.each do |extension| @@template_handlers[extension.to_sym] = handler diff --git a/actionview/lib/action_view/template/handlers/builder.rb b/actionview/lib/action_view/template/handlers/builder.rb index 61492ce448..e5413cd2a0 100644 --- a/actionview/lib/action_view/template/handlers/builder.rb +++ b/actionview/lib/action_view/template/handlers/builder.rb @@ -5,11 +5,11 @@ module ActionView class Builder class_attribute :default_format, default: :xml - def call(template) + def call(template, source) require_engine "xml = ::Builder::XmlMarkup.new(:indent => 2);" \ "self.output_buffer = xml.target!;" + - template.source + + source + ";xml.target!;" end diff --git a/actionview/lib/action_view/template/handlers/erb.rb b/actionview/lib/action_view/template/handlers/erb.rb index 7d1a6767d7..b6314a5bc3 100644 --- a/actionview/lib/action_view/template/handlers/erb.rb +++ b/actionview/lib/action_view/template/handlers/erb.rb @@ -28,8 +28,8 @@ module ActionView ENCODING_TAG = Regexp.new("\\A(<%#{ENCODING_FLAG}-?%>)[ \\t]*") - def self.call(template) - new.call(template) + def self.call(template, source) + new.call(template, source) end def supports_streaming? @@ -40,17 +40,17 @@ module ActionView true end - def call(template) + def call(template, source) # First, convert to BINARY, so in case the encoding is # wrong, we can still find an encoding tag # (<%# encoding %>) inside the String using a regular # expression - template_source = template.source.dup.force_encoding(Encoding::ASCII_8BIT) + template_source = source.dup.force_encoding(Encoding::ASCII_8BIT) erb = template_source.gsub(ENCODING_TAG, "") encoding = $2 - erb.force_encoding valid_encoding(template.source.dup, encoding) + erb.force_encoding valid_encoding(source.dup, encoding) # Always make sure we return a String in the default_internal erb.encode! diff --git a/actionview/lib/action_view/template/handlers/erb/erubi.rb b/actionview/lib/action_view/template/handlers/erb/erubi.rb index e155bae89d..15ca202024 100644 --- a/actionview/lib/action_view/template/handlers/erb/erubi.rb +++ b/actionview/lib/action_view/template/handlers/erb/erubi.rb @@ -26,7 +26,7 @@ module ActionView view = Class.new(ActionView::Base) { include action_view_erb_handler_context._routes.url_helpers class_eval("define_method(:_template) { |local_assigns, output_buffer| #{src} }", @filename || "(erubi)", 0) - }.new(action_view_erb_handler_context) + }.with_context(action_view_erb_handler_context) view.run(:_template, {}, ActionView::OutputBuffer.new) end diff --git a/actionview/lib/action_view/template/handlers/html.rb b/actionview/lib/action_view/template/handlers/html.rb index 27004a318c..65857d8587 100644 --- a/actionview/lib/action_view/template/handlers/html.rb +++ b/actionview/lib/action_view/template/handlers/html.rb @@ -3,7 +3,7 @@ module ActionView module Template::Handlers class Html < Raw - def call(template) + def call(template, source) "ActionView::OutputBuffer.new #{super}" end end diff --git a/actionview/lib/action_view/template/handlers/raw.rb b/actionview/lib/action_view/template/handlers/raw.rb index 5cd23a0060..57ebb169fc 100644 --- a/actionview/lib/action_view/template/handlers/raw.rb +++ b/actionview/lib/action_view/template/handlers/raw.rb @@ -3,8 +3,8 @@ module ActionView module Template::Handlers class Raw - def call(template) - "#{template.source.inspect}.html_safe;" + def call(template, source) + "#{source.inspect}.html_safe;" end end end diff --git a/actionview/lib/action_view/template/resolver.rb b/actionview/lib/action_view/template/resolver.rb index 12ae82f8c5..3b4594942b 100644 --- a/actionview/lib/action_view/template/resolver.rb +++ b/actionview/lib/action_view/template/resolver.rb @@ -226,9 +226,8 @@ module ActionView template_paths.map do |template| handler, format, variant = extract_handler_and_format_and_variant(template) - contents = File.binread(template) - Template.new(contents, File.expand_path(template), handler, + FileTemplate.new(File.expand_path(template), handler, virtual_path: path.virtual, format: format, variant: variant, diff --git a/actionview/lib/action_view/testing/resolvers.rb b/actionview/lib/action_view/testing/resolvers.rb index 1fad08a689..d6203b95c5 100644 --- a/actionview/lib/action_view/testing/resolvers.rb +++ b/actionview/lib/action_view/testing/resolvers.rb @@ -8,13 +8,15 @@ module ActionView #:nodoc: # useful for testing extensions that have no way of knowing what the file # system will look like at runtime. class FixtureResolver < PathResolver - attr_reader :hash - def initialize(hash = {}, pattern = nil) super(pattern) @hash = hash end + def data + @hash + end + def to_s @hash.keys.join(", ") end diff --git a/actionview/test/abstract_unit.rb b/actionview/test/abstract_unit.rb index d71944e938..acc2ed029b 100644 --- a/actionview/test/abstract_unit.rb +++ b/actionview/test/abstract_unit.rb @@ -48,7 +48,7 @@ module RenderERBUtils @view ||= begin path = ActionView::FileSystemResolver.new(FIXTURE_LOAD_PATH) view_paths = ActionView::PathSet.new([path]) - ActionView::Base.new(view_paths) + ActionView::Base.with_view_paths(view_paths) end end @@ -58,10 +58,10 @@ module RenderERBUtils template = ActionView::Template.new( string.strip, "test template", - ActionView::Template::Handlers::ERB, + ActionView::Template.handler_for_extension(:erb), {}) - template.render(ActionView::Base.new, {}).strip + template.render(ActionView::Base.empty, {}).strip end end diff --git a/actionview/test/actionpack/controller/layout_test.rb b/actionview/test/actionpack/controller/layout_test.rb index 6d5c97b7fd..838b564c5d 100644 --- a/actionview/test/actionpack/controller/layout_test.rb +++ b/actionview/test/actionpack/controller/layout_test.rb @@ -70,7 +70,7 @@ class LayoutAutoDiscoveryTest < ActionController::TestCase end def test_third_party_template_library_auto_discovers_layout - with_template_handler :mab, lambda { |template| template.source.inspect } do + with_template_handler :mab, lambda { |template, source| source.inspect } do @controller = ThirdPartyTemplateLibraryController.new get :hello assert_response :success @@ -212,7 +212,7 @@ class LayoutSetInResponseTest < ActionController::TestCase end def test_layout_set_when_using_render - with_template_handler :mab, lambda { |template| template.source.inspect } do + with_template_handler :mab, lambda { |template, source| source.inspect } do @controller = SetsLayoutInRenderController.new get :hello assert_includes @response.body, "layouts/third_party_template_library.mab" diff --git a/actionview/test/actionpack/controller/view_paths_test.rb b/actionview/test/actionpack/controller/view_paths_test.rb index 7f3fe0fa08..c5238dd746 100644 --- a/actionview/test/actionpack/controller/view_paths_test.rb +++ b/actionview/test/actionpack/controller/view_paths_test.rb @@ -77,7 +77,7 @@ class ViewLoadPathsTest < ActionController::TestCase end def test_template_appends_view_path_correctly - @controller.instance_variable_set :@template, ActionView::Base.new(TestController.view_paths, {}, @controller) + @controller.instance_variable_set :@template, ActionView::Base.with_view_paths(TestController.view_paths, {}, @controller) class_view_paths = TestController.view_paths @controller.append_view_path "foo" @@ -89,7 +89,7 @@ class ViewLoadPathsTest < ActionController::TestCase end def test_template_prepends_view_path_correctly - @controller.instance_variable_set :@template, ActionView::Base.new(TestController.view_paths, {}, @controller) + @controller.instance_variable_set :@template, ActionView::Base.with_view_paths(TestController.view_paths, {}, @controller) class_view_paths = TestController.view_paths @controller.prepend_view_path "baz" diff --git a/actionview/test/activerecord/multifetch_cache_test.rb b/actionview/test/activerecord/multifetch_cache_test.rb index 12be069e69..229b4e56d0 100644 --- a/actionview/test/activerecord/multifetch_cache_test.rb +++ b/actionview/test/activerecord/multifetch_cache_test.rb @@ -19,7 +19,7 @@ class MultifetchCacheTest < ActiveRecordTestCase def combined_fragment_cache_key(key) [ :views, key ] end - end.new(view_paths, {}) + end.with_view_paths(view_paths, {}) end def test_only_preloading_for_records_that_miss_the_cache diff --git a/actionview/test/template/capture_helper_test.rb b/actionview/test/template/capture_helper_test.rb index e172497c88..45070674ad 100644 --- a/actionview/test/template/capture_helper_test.rb +++ b/actionview/test/template/capture_helper_test.rb @@ -5,7 +5,7 @@ require "abstract_unit" class CaptureHelperTest < ActionView::TestCase def setup super - @av = ActionView::Base.new + @av = ActionView::Base.empty @view_flow = ActionView::OutputFlow.new end diff --git a/actionview/test/template/compiled_templates_test.rb b/actionview/test/template/compiled_templates_test.rb index 3cd6448e38..ded4786e62 100644 --- a/actionview/test/template/compiled_templates_test.rb +++ b/actionview/test/template/compiled_templates_test.rb @@ -72,13 +72,13 @@ class CompiledTemplatesTest < ActiveSupport::TestCase def render_with_cache(*args) view_paths = ActionController::Base.view_paths - ActionView::Base.new(view_paths, {}).render(*args) + ActionView::Base.with_view_paths(view_paths, {}).render(*args) end def render_without_cache(*args) path = ActionView::FileSystemResolver.new(FIXTURE_LOAD_PATH) view_paths = ActionView::PathSet.new([path]) - ActionView::Base.new(view_paths, {}).render(*args) + ActionView::Base.with_view_paths(view_paths, {}).render(*args) end def modify_template(template, content) diff --git a/actionview/test/template/dependency_tracker_test.rb b/actionview/test/template/dependency_tracker_test.rb index ef7aeac039..42cb14a18a 100644 --- a/actionview/test/template/dependency_tracker_test.rb +++ b/actionview/test/template/dependency_tracker_test.rb @@ -17,8 +17,8 @@ class FakeTemplate end end -Neckbeard = lambda { |template| template.source } -Bowtie = lambda { |template| template.source } +Neckbeard = lambda { |template, source| source } +Bowtie = lambda { |template, source| source } class DependencyTrackerTest < ActionView::TestCase def tracker diff --git a/actionview/test/template/lookup_context_test.rb b/actionview/test/template/lookup_context_test.rb index 68e151f154..290f832794 100644 --- a/actionview/test/template/lookup_context_test.rb +++ b/actionview/test/template/lookup_context_test.rb @@ -5,10 +5,14 @@ require "abstract_controller/rendering" class LookupContextTest < ActiveSupport::TestCase def setup - @lookup_context = ActionView::LookupContext.new(FIXTURE_LOAD_PATH, {}) + @lookup_context = build_lookup_context(FIXTURE_LOAD_PATH, {}) ActionView::LookupContext::DetailsKey.clear end + def build_lookup_context(paths, details) + ActionView::LookupContext.new(paths, details) + end + def teardown I18n.locale = :en end @@ -118,19 +122,32 @@ class LookupContextTest < ActiveSupport::TestCase test "adds fallbacks to view paths when required" do assert_equal 1, @lookup_context.view_paths.size - @lookup_context.with_fallbacks do - assert_equal 3, @lookup_context.view_paths.size - assert_includes @lookup_context.view_paths, ActionView::FallbackFileSystemResolver.new("") - assert_includes @lookup_context.view_paths, ActionView::FallbackFileSystemResolver.new("/") + assert_deprecated do + @lookup_context.with_fallbacks do + assert_equal 3, @lookup_context.view_paths.size + assert_includes @lookup_context.view_paths, ActionView::FallbackFileSystemResolver.new("") + assert_includes @lookup_context.view_paths, ActionView::FallbackFileSystemResolver.new("/") + end end + + @lookup_context = @lookup_context.with_fallbacks + + assert_equal 3, @lookup_context.view_paths.size + assert_includes @lookup_context.view_paths, ActionView::FallbackFileSystemResolver.new("") + assert_includes @lookup_context.view_paths, ActionView::FallbackFileSystemResolver.new("/") end test "add fallbacks just once in nested fallbacks calls" do - @lookup_context.with_fallbacks do + assert_deprecated do @lookup_context.with_fallbacks do - assert_equal 3, @lookup_context.view_paths.size + @lookup_context.with_fallbacks do + assert_equal 3, @lookup_context.view_paths.size + end end end + + @lookup_context = @lookup_context.with_fallbacks.with_fallbacks + assert_equal 3, @lookup_context.view_paths.size end test "generates a new details key for each details hash" do @@ -156,13 +173,13 @@ class LookupContextTest < ActiveSupport::TestCase end test "gives the key forward to the resolver, so it can be used as cache key" do - @lookup_context.view_paths = ActionView::FixtureResolver.new("test/_foo.erb" => "Foo") + @lookup_context = build_lookup_context(ActionView::FixtureResolver.new("test/_foo.erb" => "Foo"), {}) template = @lookup_context.find("foo", %w(test), true) assert_equal "Foo", template.source # Now we are going to change the template, but it won't change the returned template # since we will hit the cache. - @lookup_context.view_paths.first.hash["test/_foo.erb"] = "Bar" + @lookup_context.view_paths.first.data["test/_foo.erb"] = "Bar" template = @lookup_context.find("foo", %w(test), true) assert_equal "Foo", template.source @@ -185,7 +202,7 @@ class LookupContextTest < ActiveSupport::TestCase end test "can disable the cache on demand" do - @lookup_context.view_paths = ActionView::FixtureResolver.new("test/_foo.erb" => "Foo") + @lookup_context = build_lookup_context(ActionView::FixtureResolver.new("test/_foo.erb" => "Foo"), {}) old_template = @lookup_context.find("foo", %w(test), true) template = @lookup_context.find("foo", %w(test), true) @@ -221,12 +238,12 @@ class LookupContextWithFalseCaching < ActiveSupport::TestCase # Now we are going to change the template, but it won't change the returned template # since the timestamp is the same. - @resolver.hash["test/_foo.erb"][0] = "Bar" + @resolver.data["test/_foo.erb"][0] = "Bar" template = @lookup_context.find("foo", %w(test), true) assert_equal "Foo", template.source # Now update the timestamp. - @resolver.hash["test/_foo.erb"][1] = Time.now.utc + @resolver.data["test/_foo.erb"][1] = Time.now.utc template = @lookup_context.find("foo", %w(test), true) assert_equal "Bar", template.source end @@ -237,7 +254,7 @@ class LookupContextWithFalseCaching < ActiveSupport::TestCase template = @lookup_context.find("foo", %w(test), true) assert_equal "Foo", template.source - @resolver.hash.clear + @resolver.data.clear assert_raise ActionView::MissingTemplate do @lookup_context.find("foo", %w(test), true) end @@ -246,12 +263,12 @@ class LookupContextWithFalseCaching < ActiveSupport::TestCase test "if no template was cached in the first lookup, retrieval should work in the second call" do ActionView::Resolver.stub(:caching?, false) do - @resolver.hash.clear + @resolver.data.clear assert_raise ActionView::MissingTemplate do @lookup_context.find("foo", %w(test), true) end - @resolver.hash["test/_foo.erb"] = ["Foo", Time.utc(2000)] + @resolver.data["test/_foo.erb"] = ["Foo", Time.utc(2000)] template = @lookup_context.find("foo", %w(test), true) assert_equal "Foo", template.source end diff --git a/actionview/test/template/render_test.rb b/actionview/test/template/render_test.rb index afe68b7ff0..f5d251da20 100644 --- a/actionview/test/template/render_test.rb +++ b/actionview/test/template/render_test.rb @@ -15,7 +15,7 @@ module RenderTestCases def combined_fragment_cache_key(key) [ :views, key ] end - end.new(paths, @assigns) + end.with_view_paths(paths, @assigns) @controller_view = TestController.new.view_context @@ -336,6 +336,16 @@ module RenderTestCases assert_equal "Hello: davidHello: mary", @view.render(partial: "test/customer", collection: customers) end + def test_deprecated_constructor + assert_deprecated do + ActionView::Base.new + end + + assert_deprecated do + ActionView::Base.new ["/a"] + end + end + def test_render_partial_without_object_does_not_put_partial_name_to_local_assigns assert_equal "false", @view.render(partial: "test/partial_name_in_local_assigns") end @@ -440,13 +450,22 @@ module RenderTestCases assert_equal "Hello, World!", @view.render(inline: "Hello, World!", type: :bar) end - CustomHandler = lambda do |template| + CustomHandler = lambda do |template, source| "@output_buffer = ''.dup\n" \ - "@output_buffer << 'source: #{template.source.inspect}'\n" + "@output_buffer << 'source: #{source.inspect}'\n" end def test_render_inline_with_render_from_to_proc - ActionView::Template.register_template_handler :ruby_handler, :source.to_proc + ActionView::Template.register_template_handler :ruby_handler, lambda { |_, source| source } + assert_equal "3", @view.render(inline: "(1 + 2).to_s", type: :ruby_handler) + ensure + ActionView::Template.unregister_template_handler :ruby_handler + end + + def test_render_inline_with_render_from_to_proc_deprecated + assert_deprecated do + ActionView::Template.register_template_handler :ruby_handler, :source.to_proc + end assert_equal "3", @view.render(inline: "(1 + 2).to_s", type: :ruby_handler) ensure ActionView::Template.unregister_template_handler :ruby_handler diff --git a/actionview/test/template/streaming_render_test.rb b/actionview/test/template/streaming_render_test.rb index f196c42c4f..dda2095013 100644 --- a/actionview/test/template/streaming_render_test.rb +++ b/actionview/test/template/streaming_render_test.rb @@ -9,7 +9,7 @@ class SetupFiberedBase < ActiveSupport::TestCase def setup view_paths = ActionController::Base.view_paths @assigns = { secret: "in the sauce", name: nil } - @view = ActionView::Base.new(view_paths, @assigns) + @view = ActionView::Base.with_view_paths(view_paths, @assigns) @controller_view = TestController.new.view_context end diff --git a/actionview/test/template/test_case_test.rb b/actionview/test/template/test_case_test.rb index 976b6bc77e..ab3ababba4 100644 --- a/actionview/test/template/test_case_test.rb +++ b/actionview/test/template/test_case_test.rb @@ -52,7 +52,7 @@ module ActionView end test "retrieve non existing config values" do - assert_nil ActionView::Base.new.config.something_odd + assert_nil ActionView::Base.empty.config.something_odd end test "works without testing a helper module" do diff --git a/actionview/test/template/translation_helper_test.rb b/actionview/test/template/translation_helper_test.rb index e756348938..d04e68e182 100644 --- a/actionview/test/template/translation_helper_test.rb +++ b/actionview/test/template/translation_helper_test.rb @@ -36,7 +36,7 @@ class TranslationHelperTest < ActiveSupport::TestCase } } ) - @view = ::ActionView::Base.new(ActionController::Base.view_paths, {}) + @view = ::ActionView::Base.with_view_paths(ActionController::Base.view_paths, {}) end teardown do |