diff options
author | Pratik Naik <pratiknaik@gmail.com> | 2009-08-31 22:11:50 +0100 |
---|---|---|
committer | Pratik Naik <pratiknaik@gmail.com> | 2009-08-31 22:11:50 +0100 |
commit | bae00bb1cc392e1cf408369809b9cf85468bef42 (patch) | |
tree | 17103af6eeb5de96c72beda1debce28950cc7fea /actionpack/lib/action_view | |
parent | 93c76b2fb08668bc4b8364cc8051476e6d1d15ba (diff) | |
parent | ffd2cf167040b60c26d97c01598560c87bd4b2d3 (diff) | |
download | rails-bae00bb1cc392e1cf408369809b9cf85468bef42.tar.gz rails-bae00bb1cc392e1cf408369809b9cf85468bef42.tar.bz2 rails-bae00bb1cc392e1cf408369809b9cf85468bef42.zip |
Merge commit 'mainstream/master'
Diffstat (limited to 'actionpack/lib/action_view')
-rw-r--r-- | actionpack/lib/action_view/base.rb | 29 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/form_helper.rb | 1 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/form_options_helper.rb | 70 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/prototype_helper.rb | 5 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/url_helper.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_view/locale/en.yml | 4 | ||||
-rw-r--r-- | actionpack/lib/action_view/paths.rb | 3 | ||||
-rw-r--r-- | actionpack/lib/action_view/render/partials.rb | 159 | ||||
-rw-r--r-- | actionpack/lib/action_view/render/rendering.rb | 79 | ||||
-rw-r--r-- | actionpack/lib/action_view/template/handler.rb | 6 | ||||
-rw-r--r-- | actionpack/lib/action_view/template/resolver.rb | 38 | ||||
-rw-r--r-- | actionpack/lib/action_view/template/template.rb | 28 | ||||
-rw-r--r-- | actionpack/lib/action_view/test_case.rb | 21 |
13 files changed, 278 insertions, 167 deletions
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index c171a5a8f5..ec1b07797b 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -175,6 +175,17 @@ module ActionView #:nodoc: attr_accessor :controller attr_internal :captures + def reset_formats(formats) + @formats = formats + + if defined?(ActionController) + # This is expensive, but we need to reset this when the format is updated, + # which currently only happens + Thread.current[:format_locale_key] = + ActionController::HashKey.get(self.class, formats, I18n.locale) + end + end + class << self delegate :erb_trim_mode=, :to => 'ActionView::TemplateHandlers::ERB' delegate :logger, :to => 'ActionController::Base', :allow_nil => true @@ -240,7 +251,7 @@ module ActionView #:nodoc: end def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil, formats = nil)#:nodoc: - @formats = formats || [:html] + @formats = formats @assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) } @controller = controller @helpers = self.class.helpers || Module.new @@ -255,15 +266,6 @@ module ActionView #:nodoc: @view_paths = self.class.process_view_paths(paths) end - def with_template(current_template) - _evaluate_assigns_and_ivars - last_template, self.template = template, current_template - last_formats, self.formats = formats, current_template.formats - yield - ensure - self.template, self.formats = last_template, last_formats - end - def punctuate_body!(part) flush_output_buffer response.body_parts << part @@ -272,18 +274,11 @@ module ActionView #:nodoc: # Evaluates the local assigns and controller ivars, pushes them to the view. def _evaluate_assigns_and_ivars #:nodoc: - @assigns_added ||= _copy_ivars_from_controller - end - - private - - def _copy_ivars_from_controller #:nodoc: if @controller variables = @controller.instance_variable_names variables -= @controller.protected_instance_variables if @controller.respond_to?(:protected_instance_variables) variables.each { |name| instance_variable_set(name, @controller.instance_variable_get(name)) } end - true end end diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 72f162cb20..81029102b1 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -738,6 +738,7 @@ module ActionView options = options.stringify_keys tag_value = options.delete("value") name_and_id = options.dup + name_and_id["id"] = name_and_id["for"] add_default_name_and_id_for_value(tag_value, name_and_id) options.delete("index") options["for"] ||= name_and_id["id"] diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index 8cb5882aab..3db5202e7d 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -162,6 +162,60 @@ module ActionView InstanceTag.new(object, method, self, options.delete(:object)).to_collection_select_tag(collection, value_method, text_method, options, html_options) end + + # Returns <tt><select></tt>, <tt><optgroup></tt> and <tt><option></tt> tags for the collection of existing return values of + # +method+ for +object+'s class. The value returned from calling +method+ on the instance +object+ will + # be selected. If calling +method+ returns +nil+, no selection is made without including <tt>:prompt</tt> + # or <tt>:include_blank</tt> in the +options+ hash. + # + # Parameters: + # * +object+ - The instance of the class to be used for the select tag + # * +method+ - The attribute of +object+ corresponding to the select tag + # * +collection+ - An array of objects representing the <tt><optgroup></tt> tags. + # * +group_method+ - The name of a method which, when called on a member of +collection+, returns an + # array of child objects representing the <tt><option></tt> tags. + # * +group_label_method+ - The name of a method which, when called on a member of +collection+, returns a + # string to be used as the +label+ attribute for its <tt><optgroup></tt> tag. + # * +option_key_method+ - The name of a method which, when called on a child object of a member of + # +collection+, returns a value to be used as the +value+ attribute for its <tt><option></tt> tag. + # * +option_value_method+ - The name of a method which, when called on a child object of a member of + # +collection+, returns a value to be used as the contents of its <tt><option></tt> tag. + # + # Example object structure for use with this method: + # class Continent < ActiveRecord::Base + # has_many :countries + # # attribs: id, name + # end + # class Country < ActiveRecord::Base + # belongs_to :continent + # # attribs: id, name, continent_id + # end + # class City < ActiveRecord::Base + # belongs_to :country + # # attribs: id, name, country_id + # end + # + # Sample usage: + # grouped_collection_select(:city, :country_id, @continents, :countries, :name, :id, :name) + # + # Possible output: + # <select name="city[country_id]"> + # <optgroup label="Africa"> + # <option value="1">South Africa</option> + # <option value="3">Somalia</option> + # </optgroup> + # <optgroup label="Europe"> + # <option value="7" selected="selected">Denmark</option> + # <option value="2">Ireland</option> + # </optgroup> + # </select> + # + def grouped_collection_select(object, method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {}) + InstanceTag.new(object, method, self, options.delete(:object)).to_grouped_collection_select_tag(collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options) + end + + + # Return select and option tags for the given object and method, using # #time_zone_options_for_select to generate the list of option tags. # @@ -490,6 +544,15 @@ module ActionView ) end + def to_grouped_collection_select_tag(collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options) + html_options = html_options.stringify_keys + add_default_name_and_id(html_options) + value = value(object) + content_tag( + "select", add_options(option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, value), options, value), html_options + ) + end + def to_time_zone_select_tag(priority_zones, options, html_options) html_options = html_options.stringify_keys add_default_name_and_id(html_options) @@ -508,7 +571,8 @@ module ActionView option_tags = "<option value=\"\">#{options[:include_blank] if options[:include_blank].kind_of?(String)}</option>\n" + option_tags end if value.blank? && options[:prompt] - ("<option value=\"\">#{options[:prompt].kind_of?(String) ? options[:prompt] : 'Please select'}</option>\n") + option_tags + prompt = options[:prompt].kind_of?(String) ? options[:prompt] : I18n.translate('support.select.prompt', :default => 'Please select') + "<option value=\"\">#{prompt}</option>\n" + option_tags else option_tags end @@ -524,6 +588,10 @@ module ActionView @template.collection_select(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options)) end + def grouped_collection_select(method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {}) + @template.grouped_collection_select(@object_name, method, collection, group_method, group_label_method, option_key_method, option_value_method, objectify_options(options), @default_options.merge(html_options)) + end + def time_zone_select(method, priority_zones = nil, options = {}, html_options = {}) @template.time_zone_select(@object_name, method, priority_zones, objectify_options(options), @default_options.merge(html_options)) end diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 624b537ad2..03f1dabb4e 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -991,12 +991,13 @@ module ActionView def render(*options_for_render) old_formats = @context && @context.formats - @context.formats = [:html] if @context + + @context.reset_formats([:html]) if @context Hash === options_for_render.first ? @context.render(*options_for_render) : options_for_render.first.to_s ensure - @context.formats = old_formats if @context + @context.reset_formats(old_formats) if @context end def javascript_object_for(object) diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index c5a6d1f084..b07304e361 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -568,7 +568,7 @@ module ActionView when confirm && popup "if (#{confirm_javascript_function(confirm)}) { #{popup_javascript_function(popup)} };return false;" when confirm && method - "if (#{confirm_javascript_function(confirm)}) { #{method_javascript_function(method)} };return false;" + "if (#{confirm_javascript_function(confirm)}) { #{method_javascript_function(method, url, href)} };return false;" when confirm "return #{confirm_javascript_function(confirm)};" when method diff --git a/actionpack/lib/action_view/locale/en.yml b/actionpack/lib/action_view/locale/en.yml index afe35691bc..c82cd07ec2 100644 --- a/actionpack/lib/action_view/locale/en.yml +++ b/actionpack/lib/action_view/locale/en.yml @@ -108,3 +108,7 @@ # The variable :count is also available body: "There were problems with the following fields:" + support: + select: + # default value for :prompt => true in FormOptionsHelper + prompt: "Please select"
\ No newline at end of file diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 4001757a9b..5524a3219a 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -34,7 +34,6 @@ module ActionView #:nodoc: end def find(path, details = {}, prefix = nil, partial = false) - # template_path = path.sub(/^\//, '') template_path = path each do |load_path| @@ -43,8 +42,6 @@ module ActionView #:nodoc: end end - # TODO: Have a fallback absolute path? - extension = details[:formats] || [] raise ActionView::MissingTemplate.new(self, "#{prefix}/#{path} - #{details.inspect} - partial: #{!!partial}") end diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index 64f08c447d..7f10f54d2e 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -173,77 +173,114 @@ module ActionView extend ActiveSupport::Concern class PartialRenderer - def self.partial_names - @partial_names ||= Hash.new {|h,k| h[k] = ActiveSupport::ConcurrentHash.new } - end + PARTIAL_NAMES = Hash.new {|h,k| h[k] = {} } + TEMPLATES = Hash.new {|h,k| h[k] = {} } - def self.formats - @formats ||= Hash.new {|h,k| h[k] = Hash.new{|h,k| h[k] = Hash.new {|h,k| h[k] = {}}}} - end + attr_reader :template def initialize(view_context, options, block) - partial = options[:partial] - @view = view_context - @options = options - @locals = options[:locals] || {} - @block = block - - # Set up some instance variables to speed up memoizing - @partial_names = self.class.partial_names[@view.controller.class] - @templates = self.class.formats - @format = view_context.formats - - # Set up the object and path - @object = partial.is_a?(String) ? options[:object] : partial - @path = partial_path(partial) + @partial_names = PARTIAL_NAMES[@view.controller.class] + + key = Thread.current[:format_locale_key] + @templates = TEMPLATES[key] if key + + setup(options, block) + end + + def setup(options, block) + partial = options[:partial] + + @options = options + @locals = options[:locals] || {} + @block = block + + if String === partial + @object = options[:object] + @path = partial + else + @object = partial + @path = partial_path(partial) + end end def render - return render_collection if collection - - template = find_template - render_template(template, @object || @locals[template.variable_name]) + if @collection = collection + render_collection + else + @template = template = find_template + render_template(template, @object || @locals[template.variable_name]) + end end def render_collection - # Even if no template is rendered, this will ensure that the MIME type - # for the empty response is the same as the provided template - @options[:_template] = default_template = find_template + @template = template = find_template - return nil if collection.blank? + return nil if @collection.blank? if @options.key?(:spacer_template) spacer = find_template(@options[:spacer_template]).render(@view, @locals) end - segments = [] + result = template ? collection_with_template(template) : collection_without_template + result.join(spacer) + end + + def collection_with_template(template) + options = @options + + segments, locals, as = [], @locals, options[:as] || template.variable_name + + counter_name = template.counter_name + locals[counter_name] = -1 + + @collection.each do |object| + locals[counter_name] += 1 + locals[as] = object + + segments << template.render(@view, locals) + end + + @template = template + segments + end + + def collection_without_template + options = @options + + segments, locals, as = [], @locals, options[:as] + index, template = -1, nil - collection.each_with_index do |object, index| - template = default_template || find_template(partial_path(object)) - @locals[template.counter_name] = index - segments << render_template(template, object) + @collection.each do |object| + template = find_template(partial_path(object)) + locals[template.counter_name] = (index += 1) + locals[template.variable_name] = object + + segments << template.render(@view, locals) end - segments.join(spacer) + @template = template + segments end def render_template(template, object = @object) - @options[:_template] ||= template + options, locals, view = @options, @locals, @view + locals[options[:as] || template.variable_name] = object - # TODO: is locals[:object] really necessary? - @locals[:object] = @locals[template.variable_name] = object - @locals[@options[:as]] = object if @options[:as] + content = template.render(view, locals) do |*name| + @view._layout_for(*name, &@block) + end - content = @view._render_single_template(template, @locals, &@block) - return content if @block || !@options[:layout] - find_template(@options[:layout]).render(@view, @locals) { content } + if @block || !options[:layout] + content + else + find_template(options[:layout]).render(@view, @locals) { content } + end end - private def collection - @collection ||= if @object.respond_to?(:to_ary) + if @object.respond_to?(:to_ary) @object elsif @options.key?(:collection) @options[:collection] || [] @@ -251,15 +288,19 @@ module ActionView end def find_template(path = @path) - return if !path - @templates[path][@view.controller_path][@format][I18n.locale] ||= begin - prefix = @view.controller.controller_path unless path.include?(?/) - @view.find(path, {:formats => @view.formats}, prefix, true) + unless @templates + path && _find_template(path) + else + path && @templates[path] ||= _find_template(path) end end + + def _find_template(path) + prefix = @view.controller.controller_path unless path.include?(?/) + @view.find(path, {:formats => @view.formats}, prefix, true) + end def partial_path(object = @object) - return object if object.is_a?(String) @partial_names[object.class] ||= begin return nil unless object.respond_to?(:to_model) @@ -272,14 +313,26 @@ module ActionView end def render_partial(options) - @assigns_added = false - # TODO: Handle other details here. - self.formats = options[:_details][:formats] if options[:_details] - _render_partial(options) + _evaluate_assigns_and_ivars + + details = options[:_details] + + # Is this needed + self.formats = details[:formats] if details + renderer = PartialRenderer.new(self, options, nil) + text = renderer.render + options[:_template] = renderer.template + text end def _render_partial(options, &block) #:nodoc: - PartialRenderer.new(self, options, block).render + if @renderer + @renderer.setup(options, block) + else + @renderer = PartialRenderer.new(self, options, block) + end + + @renderer.render end end diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index c7afc56e3b..b0b75918b7 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -12,8 +12,6 @@ module ActionView # as the locals hash. def render(options = {}, locals = {}, &block) #:nodoc: case options - when String, NilClass - _render_partial(:partial => options, :locals => locals || {}) when Hash layout = options[:layout] @@ -35,26 +33,8 @@ module ActionView end when :update update_page(&block) - end - end - - def _render_content(content, layout, locals) - return content unless layout - - locals ||= {} - - if controller && layout - @_layout = layout.identifier - logger.info("Rendering template within #{layout.identifier}") if logger - end - - begin - old_content, @_content_for[:layout] = @_content_for[:layout], content - - @cached_content_for_layout = @_content_for[:layout] - _render_single_template(layout, locals) - ensure - @_content_for[:layout] = old_content + else + _render_partial(:partial => options, :locals => locals) end end @@ -90,48 +70,25 @@ module ActionView # In this case, the layout would receive the block passed into <tt>render :layout</tt>, # and the Struct specified in the layout would be passed into the block. The result # would be <html>Hello David</html>. - def _layout_for(names, &block) - with_output_buffer do - # This is due to the potentially ambiguous use of yield when - # a block is passed in to a template *and* there is a content_for() - # of the same name. Suggested solution: require explicit use of content_for - # in these ambiguous cases. - # - # We would be able to continue supporting yield in all non-ambiguous - # cases. Question: should we deprecate yield in favor of content_for - # and reserve yield for cases where there is a yield into a real block? - if @_content_for.key?(names.first) || !block_given? - return @_content_for[names.first || :layout] - else - return yield(names) - end - end - end + def _layout_for(name = nil) + return @_content_for[name || :layout] if !block_given? || name - def _render_single_template(template, locals = {}, &block) - with_template(template) do - template.render(self, locals) do |*names| - _layout_for(names, &block) - end - end - rescue Exception => e - if e.is_a?(TemplateError) - e.sub_template_of(template) - raise e - else - raise TemplateError.new(template, assigns, e) + with_output_buffer do + return yield end end def _render_inline(inline, layout, options) handler = Template.handler_class_for_extension(options[:type] || "erb") template = Template.new(options[:inline], "inline #{options[:inline].inspect}", handler, {}) - content = _render_single_template(template, options[:locals] || {}) - layout ? _render_content(content, layout, options[:locals]) : content + locals = options[:locals] || {} + content = template.render(self, locals) + content = layout.render(self, locals) {|*name| _layout_for(*name) { content } } if layout + content end def _render_text(text, layout, options) - layout ? _render_content(text, layout, options[:locals]) : text + text = layout.render(self, options[:locals]) { text } if layout end # This is the API to render a ViewContext's template from a controller. @@ -141,7 +98,7 @@ module ActionView # _layout:: The layout, if any, to wrap the Template in # _partial:: true if the template is a partial def render_template(options) - @assigns_added = nil + _evaluate_assigns_and_ivars template, layout, partial = options.values_at(:_template, :_layout, :_partial) _render_template(template, layout, options, partial) end @@ -158,10 +115,18 @@ module ActionView content = if partial _render_partial_object(template, options) else - _render_single_template(template, locals) + template.render(self, locals) end - _render_content(content, layout, locals) + @cached_content_for_layout = content + @_content_for[:layout] = content + + if layout + @_layout = layout.identifier + logger.info("Rendering template within #{layout.identifier}") if logger + content = layout.render(self, locals) {|*name| _layout_for(*name) } + end + content end end end
\ No newline at end of file diff --git a/actionpack/lib/action_view/template/handler.rb b/actionpack/lib/action_view/template/handler.rb index 3071c78174..4bf58b9fa8 100644 --- a/actionpack/lib/action_view/template/handler.rb +++ b/actionpack/lib/action_view/template/handler.rb @@ -26,11 +26,7 @@ module ActionView self.default_format = Mime::HTML def self.call(template) - "#{name}.new(self).render(template, local_assigns)" - end - - def initialize(view = nil) - @view = view + raise "Need to implement #{self.class.name}#call(template)" end def render(template, local_assigns) diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index ebfc6cc8ce..0b4c62d4d0 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -4,7 +4,7 @@ require "action_view/template/template" module ActionView # Abstract superclass class Resolver - def initialize(options) + def initialize(options = {}) @cache = options[:cache] @cached = {} end @@ -41,8 +41,10 @@ module ActionView end def handler_glob - e = TemplateHandlers.extensions.map{|h| ".#{h},"}.join - "{#{e}}" + @handler_glob ||= begin + e = TemplateHandlers.extensions.map{|h| ".#{h}"}.join(",") + "{#{e}}" + end end def formats_glob @@ -60,6 +62,10 @@ module ActionView class FileSystemResolver < Resolver + def self.cached_glob + @@cached_glob ||= {} + end + def initialize(path, options = {}) raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver) super(options) @@ -105,20 +111,22 @@ module ActionView # :api: plugin def details_to_glob(name, details, prefix, partial, root) - path = "" - path << "#{prefix}/" unless prefix.empty? - path << (partial ? "_#{name}" : name) - - extensions = "" - [:locales, :formats].each do |k| - extensions << if exts = details[k] - '{' + exts.map {|e| ".#{e},"}.join + '}' - else - k == :formats ? formats_glob : '' + self.class.cached_glob[[name, prefix, partial, details, root]] ||= begin + path = "" + path << "#{prefix}/" unless prefix.empty? + path << (partial ? "_#{name}" : name) + + extensions = "" + [:locales, :formats].each do |k| + extensions << if exts = details[k] + '{' + exts.map {|e| ".#{e},"}.join + '}' + else + k == :formats ? formats_glob : '' + end end - end - "#{root}#{path}#{extensions}#{handler_glob}" + "#{root}#{path}#{extensions}#{handler_glob}" + end end # TODO: fix me diff --git a/actionpack/lib/action_view/template/template.rb b/actionpack/lib/action_view/template/template.rb index 33d3f79ad3..7d6964e3e3 100644 --- a/actionpack/lib/action_view/template/template.rb +++ b/actionpack/lib/action_view/template/template.rb @@ -26,9 +26,16 @@ module ActionView @details[:formats] = Array.wrap(format.to_sym) end - def render(view, locals, &blk) + def render(view, locals, &block) method_name = compile(locals, view) - view.send(method_name, locals, &blk) + view.send(method_name, locals, &block) + rescue Exception => e + if e.is_a?(TemplateError) + e.sub_template_of(self) + raise e + else + raise TemplateError.new(self, view.assigns, e) + end end # TODO: Figure out how to abstract this @@ -90,7 +97,22 @@ module ActionView raise ActionView::TemplateError.new(self, {}, e) end end - + + class LocalsKey + @hash_keys = Hash.new {|h,k| h[k] = Hash.new {|h,k| h[k] = {} } } + + def self.get(*locals) + @hash_keys[*locals] ||= new(klass, format, locale) + end + + attr_accessor :hash + def initialize(klass, format, locale) + @hash = locals.hash + end + + alias_method :eql?, :equal? + end + def build_method_name(locals) # TODO: is locals.keys.hash reliably the same? @method_names[locals.keys.hash] ||= diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index e51744d095..c2ccd1d3a5 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -9,14 +9,16 @@ module ActionView end attr_internal :rendered - alias_method :_render_template_without_template_tracking, :_render_single_template - def _render_single_template(template, local_assigns, &block) - if template.respond_to?(:identifier) && template.present? - @_rendered[:partials][template] += 1 if template.partial? - @_rendered[:template] ||= [] - @_rendered[:template] << template - end - _render_template_without_template_tracking(template, local_assigns, &block) + end + + class Template + alias_method :render_without_tracking, :render + def render(view, locals, &blk) + rendered = view.rendered + rendered[:partials][self] += 1 if partial? + rendered[:template] ||= [] + rendered[:template] << self + render_without_tracking(view, locals, &blk) end end @@ -68,9 +70,8 @@ module ActionView def initialize @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new - + @params = {} - send(:initialize_current_url) end end |