diff options
author | Piotr Sarnacki <drogus@gmail.com> | 2012-08-28 11:24:29 +0200 |
---|---|---|
committer | Piotr Sarnacki <drogus@gmail.com> | 2012-08-28 11:24:29 +0200 |
commit | 4f093d81aca814b7433c4a1366985327b4ad0708 (patch) | |
tree | d8361811cbf1f5b3947c57cbe1be1016c2835b2d | |
parent | 1ec1eb2ff2ad5de70db7a632b93641a06a623a42 (diff) | |
parent | daa0ed3af2e6443e26d658282b8ed654b5a32926 (diff) | |
download | rails-4f093d81aca814b7433c4a1366985327b4ad0708.tar.gz rails-4f093d81aca814b7433c4a1366985327b4ad0708.tar.bz2 rails-4f093d81aca814b7433c4a1366985327b4ad0708.zip |
Merge branch 'actionview-decoupling'
This branch contains set of changes that will allow to extract Action
View out of Action Pack in the future. This work will be probably done
after Rails 4.0 release, because of a few deprecations that were done
to make decoupling possible.
49 files changed, 487 insertions, 232 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 3c8a0f48ab..2752c95520 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,5 +1,19 @@ ## Rails 4.0.0 (unreleased) ## +* Deprecate availbility of ActionView::RecordIdentifier in controllers by default. + It's view specific and can be easily included in controller manually if someone + really needs it. RecordIdentifier will be removed from ActionController::Base + in Rails 4.1 *Piotr Sarnacki* + +* Fix ActionView::RecordIdentifier to work as a singleton *Piotr Sarnacki* + +* Deprecate Template#mime_type, it will be removed in Rails 4.1 in favor of #type. + *Piotr Sarnacki* + +* Move vendored html-scanner from action_controller to action_view directory. If you + require it directly, please use 'action_view/vendor/html-scanner', reference to + 'action_controller/vendor/html-scanner' will be removed in Rails 4.1 *Piot Sarnacki* + * Fix handling of date selects when using both disabled and discard options. Fixes #7431. diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 31df9d605c..0b96c96a2c 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -12,6 +12,7 @@ module ActionController autoload :Middleware autoload_under "metal" do + autoload :AssetPaths autoload :Compatibility autoload :ConditionalGet autoload :Cookies @@ -58,7 +59,11 @@ end # All of these simply register additional autoloads require 'action_view' -require 'action_controller/vendor/html-scanner' +require 'action_view/vendor/html-scanner' + +ActiveSupport.on_load(:action_view) do + ActionView::RoutingUrlFor.send(:include, ActionDispatch::Routing::UrlFor) +end # Common Active Support usage in Action Controller require 'active_support/core_ext/class/attribute_accessors' diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index f829f5e8a2..0d79e046a1 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -183,8 +183,8 @@ module ActionController MODULES = [ AbstractController::Layouts, AbstractController::Translation, - AbstractController::AssetPaths, + AssetPaths, Helpers, HideActions, UrlFor, diff --git a/actionpack/lib/action_controller/metal/asset_paths.rb b/actionpack/lib/action_controller/metal/asset_paths.rb new file mode 100644 index 0000000000..3c1c95c042 --- /dev/null +++ b/actionpack/lib/action_controller/metal/asset_paths.rb @@ -0,0 +1,13 @@ +require 'action_controller/metal/exceptions' + +module ActionController + module AssetPaths + extend ActiveSupport::Concern + + include AbstractController::AssetPaths + + def invalid_asset_host!(help_message) + raise ActionController::RoutingError, "This asset host cannot be computed without a request in scope. #{help_message}" + end + end +end diff --git a/actionpack/lib/action_controller/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb index d3ac406618..bffd2a02d0 100644 --- a/actionpack/lib/action_controller/record_identifier.rb +++ b/actionpack/lib/action_controller/record_identifier.rb @@ -1,83 +1,20 @@ -require 'active_support/core_ext/module' -require 'action_controller/model_naming' +require 'active_support/deprecation' +require 'action_view/record_identifier' module ActionController - # The record identifier encapsulates a number of naming conventions for dealing with records, like Active Records or - # pretty much any other model type that has an id. These patterns are then used to try elevate the view actions to - # a higher logical level. - # - # # routes - # resources :posts - # - # # view - # <%= div_for(post) do %> <div id="post_45" class="post"> - # <%= post.body %> What a wonderful world! - # <% end %> </div> - # - # # controller - # def update - # post = Post.find(params[:id]) - # post.update_attributes(params[:post]) - # - # redirect_to(post) # Calls polymorphic_url(post) which in turn calls post_url(post) - # end - # - # As the example above shows, you can stop caring to a large extent what the actual id of the post is. - # You just know that one is being assigned and that the subsequent calls in redirect_to expect that - # same naming convention and allows you to write less code if you follow it. module RecordIdentifier - extend self + MESSAGE = 'method will no longer be included by default in controllers since Rails 4.1. ' + + 'If you would like to use it in controllers, please include ' + + 'ActionView::RecodIdentifier module.' - include ModelNaming - - JOIN = '_'.freeze - NEW = 'new'.freeze - - # The DOM class convention is to use the singular form of an object or class. - # - # dom_class(post) # => "post" - # dom_class(Person) # => "person" - # - # If you need to address multiple instances of the same class in the same view, you can prefix the dom_class: - # - # dom_class(post, :edit) # => "edit_post" - # dom_class(Person, :edit) # => "edit_person" - def dom_class(record_or_class, prefix = nil) - singular = model_name_from_record_or_class(record_or_class).param_key - prefix ? "#{prefix}#{JOIN}#{singular}" : singular - end - - # The DOM id convention is to use the singular form of an object or class with the id following an underscore. - # If no id is found, prefix with "new_" instead. - # - # dom_id(Post.find(45)) # => "post_45" - # dom_id(Post.new) # => "new_post" - # - # If you need to address multiple instances of the same class in the same view, you can prefix the dom_id: - # - # dom_id(Post.find(45), :edit) # => "edit_post_45" - # dom_id(Post.new, :custom) # => "custom_post" def dom_id(record, prefix = nil) - if record_id = record_key_for_dom_id(record) - "#{dom_class(record, prefix)}#{JOIN}#{record_id}" - else - dom_class(record, prefix || NEW) - end + ActiveSupport::Deprecation.warn 'dom_id ' + MESSAGE + ActionView::RecordIdentifier.dom_id(record, prefix) end - protected - - # Returns a string representation of the key attribute(s) that is suitable for use in an HTML DOM id. - # This can be overwritten to customize the default generated string representation if desired. - # If you need to read back a key from a dom_id in order to query for the underlying database record, - # you should write a helper like 'person_record_from_dom_id' that will extract the key either based - # on the default implementation (which just joins all key attributes with '_') or on your own - # overwritten version of the method. By default, this implementation passes the key string through a - # method that replaces all characters that are invalid inside DOM ids, with valid ones. You need to - # make sure yourself that your dom ids are valid, in case you overwrite this method. - def record_key_for_dom_id(record) - key = convert_to_model(record).to_key - key ? key.join('_') : key + def dom_class(record, prefix = nil) + ActiveSupport::Deprecation.warn 'dom_class ' + MESSAGE + ActionView::RecordIdentifier.dom_class(record, prefix) end end end diff --git a/actionpack/lib/action_controller/vendor/html-scanner.rb b/actionpack/lib/action_controller/vendor/html-scanner.rb index 879b31e60e..896208bc05 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner.rb +++ b/actionpack/lib/action_controller/vendor/html-scanner.rb @@ -1,20 +1,5 @@ -$LOAD_PATH << "#{File.dirname(__FILE__)}/html-scanner" +require 'action_view/vendor/html-scanner' +require 'active_support/deprecation' -module HTML - extend ActiveSupport::Autoload - - eager_autoload do - autoload :CDATA, 'html/node' - autoload :Document, 'html/document' - autoload :FullSanitizer, 'html/sanitizer' - autoload :LinkSanitizer, 'html/sanitizer' - autoload :Node, 'html/node' - autoload :Sanitizer, 'html/sanitizer' - autoload :Selector, 'html/selector' - autoload :Tag, 'html/node' - autoload :Text, 'html/node' - autoload :Tokenizer, 'html/tokenizer' - autoload :Version, 'html/version' - autoload :WhiteListSanitizer, 'html/sanitizer' - end -end +ActiveSupport::Deprecation.warn 'Vendored html-scanner was moved to action_view, please require "action_view/vendor/html-scanner" instead. ' + + 'This file will be removed in Rails 4.1' diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index 57b4678add..0ec355246e 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -101,3 +101,8 @@ module ActionDispatch end autoload :Mime, 'action_dispatch/http/mime_type' + +ActiveSupport.on_load(:action_view) do + ActionView::Base.default_formats ||= Mime::SET.symbols + ActionView::Template::Types.delegate_to Mime +end diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index f4c708ea33..5177944575 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -95,6 +95,8 @@ module ActionDispatch self.default_url_options = {} end + + include *_url_for_modules if respond_to?(:_url_for_modules) end def initialize(*) diff --git a/actionpack/lib/action_dispatch/testing/assertions/dom.rb b/actionpack/lib/action_dispatch/testing/assertions/dom.rb index 7dc3d0f97c..6c61d4e61a 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/dom.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/dom.rb @@ -1,4 +1,4 @@ -require 'action_controller/vendor/html-scanner' +require 'action_view/vendor/html-scanner' module ActionDispatch module Assertions diff --git a/actionpack/lib/action_dispatch/testing/assertions/selector.rb b/actionpack/lib/action_dispatch/testing/assertions/selector.rb index d19d116a1f..9388d44eef 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/selector.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/selector.rb @@ -1,4 +1,5 @@ -require 'action_controller/vendor/html-scanner' +require 'action_view/vendor/html-scanner' +require 'active_support/core_ext/object/inclusion' #-- # Copyright (c) 2006 Assaf Arkin (http://labnotes.org) diff --git a/actionpack/lib/action_dispatch/testing/assertions/tag.rb b/actionpack/lib/action_dispatch/testing/assertions/tag.rb index 68f1347e7c..2e38266aba 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/tag.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/tag.rb @@ -1,4 +1,4 @@ -require 'action_controller/vendor/html-scanner' +require 'action_view/vendor/html-scanner' module ActionDispatch module Assertions diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index 9d11c284f5..1cf6937578 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -36,6 +36,8 @@ module ActionView autoload :Helpers autoload :LookupContext autoload :PathSet + autoload :RecordIdentifier + autoload :RoutingUrlFor autoload :Template autoload_under "renderer" do diff --git a/actionpack/lib/action_view/asset_paths.rb b/actionpack/lib/action_view/asset_paths.rb index 81880d17ea..3ddd8bd552 100644 --- a/actionpack/lib/action_view/asset_paths.rb +++ b/actionpack/lib/action_view/asset_paths.rb @@ -1,6 +1,6 @@ require 'zlib' require 'active_support/core_ext/file' -require 'action_controller/metal/exceptions' +require 'active_support/core_ext/module/delegation' module ActionView class AssetPaths #:nodoc: @@ -8,6 +8,8 @@ module ActionView attr_reader :config, :controller + delegate :invalid_asset_host!, :to => :controller, :prefix => false + def initialize(config, controller = nil) @config = config @controller = controller @@ -97,10 +99,6 @@ module ActionView @config.default_asset_host_protocol || (has_request? ? :request : :relative) end - def invalid_asset_host!(help_message) - raise ActionController::RoutingError, "This asset host cannot be computed without a request in scope. #{help_message}" - end - # Pick an asset host for this source. Returns +nil+ if no host is set, # the host if no wildcard is set, the host interpolated with the # numbers 0-3 if it contains <tt>%d</tt> (the number is the source hash mod 4), diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 749332eca7..3464ec523e 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -146,6 +146,9 @@ module ActionView #:nodoc: cattr_accessor :prefix_partial_path_with_controller_namespace @@prefix_partial_path_with_controller_namespace = true + # Specify default_formats that can be rendered. + cattr_accessor :default_formats + class_attribute :_routes class_attribute :logger @@ -178,8 +181,6 @@ module ActionView #:nodoc: def initialize(context = nil, assigns = {}, controller = nil, formats = nil) #:nodoc: @_config = ActiveSupport::InheritableOptions.new - # Handle all these for backwards compatibility. - # TODO Provide a new API for AV::Base and deprecate this one. if context.is_a?(ActionView::Renderer) @view_renderer = context else diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index ceb56824fa..db4da6f9c8 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -222,6 +222,14 @@ module ActionView # auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", {:title => "Example RSS"}) # # => <link rel="alternate" type="application/rss+xml" title="Example RSS" href="http://www.example.com/feed" /> def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {}) + if !(type == :rss || type == :atom) && tag_options[:type].blank? + message = "You have passed type other than :rss or :atom to auto_discovery_link_tag and haven't supplied " + + "the :type option key. This behavior is deprecated and will be remove in Rails 4.1. You should pass " + + ":type option explicitly if you want to use other types, for example: " + + "auto_discovery_link_tag(:xml, '/feed.xml', :type => 'application/xml')" + ActiveSupport::Deprecation.warn message + end + tag( "link", "rel" => tag_options[:rel] || "alternate", diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index b79577bcd3..17fe7dc1b4 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -4,12 +4,12 @@ require 'action_view/helpers/tag_helper' require 'action_view/helpers/form_tag_helper' require 'action_view/helpers/active_model_helper' require 'action_view/helpers/tags' +require 'action_view/model_naming' require 'active_support/core_ext/class/attribute_accessors' require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/string/output_safety' require 'active_support/core_ext/array/extract_options' require 'active_support/core_ext/string/inflections' -require 'action_controller/model_naming' module ActionView # = Action View Form Helpers @@ -115,7 +115,7 @@ module ActionView include FormTagHelper include UrlHelper - include ActionController::ModelNaming + include ModelNaming # Creates a form that allows the user to create or update the attributes # of a specific model object. @@ -1156,7 +1156,7 @@ module ActionView end class FormBuilder - include ActionController::ModelNaming + include ModelNaming # The methods which wrap a form helper call. class_attribute :field_helpers diff --git a/actionpack/lib/action_view/helpers/record_tag_helper.rb b/actionpack/lib/action_view/helpers/record_tag_helper.rb index 9b35f076e5..dded9aab7c 100644 --- a/actionpack/lib/action_view/helpers/record_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/record_tag_helper.rb @@ -1,10 +1,8 @@ -require 'action_controller/record_identifier' - module ActionView # = Action View Record Tag Helpers module Helpers module RecordTagHelper - include ActionController::RecordIdentifier + include ActionView::RecordIdentifier # Produces a wrapper DIV element with id and class parameters that # relate to the specified Active Record object. Usage example: diff --git a/actionpack/lib/action_view/helpers/sanitize_helper.rb b/actionpack/lib/action_view/helpers/sanitize_helper.rb index aaf0e0344a..9c76c26ace 100644 --- a/actionpack/lib/action_view/helpers/sanitize_helper.rb +++ b/actionpack/lib/action_view/helpers/sanitize_helper.rb @@ -1,5 +1,5 @@ require 'active_support/core_ext/object/try' -require 'action_controller/vendor/html-scanner' +require 'action_view/vendor/html-scanner' module ActionView # = Action View Sanitize Helpers diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index fe3240fdc1..3f65791aa0 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -2,7 +2,6 @@ require 'action_view/helpers/javascript_helper' require 'active_support/core_ext/array/access' require 'active_support/core_ext/hash/keys' require 'active_support/core_ext/string/output_safety' -require 'action_dispatch' module ActionView # = Action View URL Helpers @@ -20,115 +19,34 @@ module ActionView extend ActiveSupport::Concern - include ActionDispatch::Routing::UrlFor include TagHelper - # We need to override url_options, _routes_context - # and optimize_routes_generation? to consider the controller. - - def url_options #:nodoc: - return super unless controller.respond_to?(:url_options) - controller.url_options - end - - def _routes_context #:nodoc: - controller - end - protected :_routes_context - - def optimize_routes_generation? #:nodoc: - controller.respond_to?(:optimize_routes_generation?) ? - controller.optimize_routes_generation? : super + module ClassMethods + def _url_for_modules + ActionView::RoutingUrlFor + end end - protected :optimize_routes_generation? - # Returns the URL for the set of +options+ provided. This takes the - # same options as +url_for+ in Action Controller (see the - # documentation for <tt>ActionController::Base#url_for</tt>). Note that by default - # <tt>:only_path</tt> is <tt>true</tt> so you'll get the relative "/controller/action" - # instead of the fully qualified URL like "http://example.com/controller/action". - # - # ==== Options - # * <tt>:anchor</tt> - Specifies the anchor name to be appended to the path. - # * <tt>:only_path</tt> - If true, returns the relative URL (omitting the protocol, host name, and port) (<tt>true</tt> by default unless <tt>:host</tt> is specified). - # * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2005/". Note that this - # is currently not recommended since it breaks caching. - # * <tt>:host</tt> - Overrides the default (current) host if provided. - # * <tt>:protocol</tt> - Overrides the default (current) protocol if provided. - # * <tt>:user</tt> - Inline HTTP authentication (only plucked out if <tt>:password</tt> is also present). - # * <tt>:password</tt> - Inline HTTP authentication (only plucked out if <tt>:user</tt> is also present). - # - # ==== Relying on named routes - # - # Passing a record (like an Active Record) instead of a hash as the options parameter will - # trigger the named route for that record. The lookup will happen on the name of the class. So passing a - # Workshop object will attempt to use the +workshop_path+ route. If you have a nested route, such as - # +admin_workshop_path+ you'll have to call that explicitly (it's impossible for +url_for+ to guess that route). - # - # ==== Implicit Controller Namespacing - # - # Controllers passed in using the +:controller+ option will retain their namespace unless it is an absolute one. - # - # ==== Examples - # <%= url_for(:action => 'index') %> - # # => /blog/ - # - # <%= url_for(:action => 'find', :controller => 'books') %> - # # => /books/find - # - # <%= url_for(:action => 'login', :controller => 'members', :only_path => false, :protocol => 'https') %> - # # => https://www.example.com/members/login/ - # - # <%= url_for(:action => 'play', :anchor => 'player') %> - # # => /messages/play/#player - # - # <%= url_for(:action => 'jump', :anchor => 'tax&ship') %> - # # => /testing/jump/#tax&ship - # - # <%= url_for(Workshop.new) %> - # # relies on Workshop answering a persisted? call (and in this case returning false) - # # => /workshops - # - # <%= url_for(@workshop) %> - # # calls @workshop.to_param which by default returns the id - # # => /workshops/5 - # - # # to_param can be re-defined in a model to provide different URL names: - # # => /workshops/1-workshop-name - # - # <%= url_for("http://www.example.com") %> - # # => http://www.example.com - # - # <%= url_for(:back) %> - # # if request.env["HTTP_REFERER"] is set to "http://www.example.com" - # # => http://www.example.com - # - # <%= url_for(:back) %> - # # if request.env["HTTP_REFERER"] is not set or is blank - # # => javascript:history.back() - # - # <%= url_for(:action => 'index', :controller => 'users') %> - # # Assuming an "admin" namespace - # # => /admin/users - # - # <%= url_for(:action => 'index', :controller => '/users') %> - # # Specify absolute path with beginning slash - # # => /users - def url_for(options = nil) + # Basic implementation of url_for to allow use helpers without routes existence + def url_for(options = nil) # :nodoc: case options when String options - when nil, Hash - options ||= {} - options = { :only_path => options[:host].nil? }.merge!(options.symbolize_keys) - super when :back - controller.request.env["HTTP_REFERER"] || 'javascript:history.back()' + _back_url else - polymorphic_path(options) + raise ArgumentError, "arguments passed to url_for can't be handled. Please require " + + "routes or provide your own implementation" end end + def _back_url # :nodoc: + referrer = controller.respond_to?(:request) && controller.request.env["HTTP_REFERER"] + referrer || 'javascript:history.back()' + end + protected :_back_url + + # Creates a link tag of the given +name+ using a URL created by the set of +options+. # See the valid options in the documentation for +url_for+. It's also possible to # pass a String instead of an options hash, which generates a link tag that uses the diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index f0ea92b018..af367ac28d 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -43,7 +43,7 @@ module ActionView end register_detail(:locale) { [I18n.locale, I18n.default_locale].uniq } - register_detail(:formats) { Mime::SET.symbols } + register_detail(:formats) { ActionView::Base.default_formats || [:html, :text, :js, :css, :xml, :json] } register_detail(:handlers){ Template::Handlers.extensions } class DetailsKey #:nodoc: diff --git a/actionpack/lib/action_view/model_naming.rb b/actionpack/lib/action_view/model_naming.rb new file mode 100644 index 0000000000..e09ebd60df --- /dev/null +++ b/actionpack/lib/action_view/model_naming.rb @@ -0,0 +1,12 @@ +module ActionView + module ModelNaming + # Converts the given object to an ActiveModel compliant one. + def convert_to_model(object) + object.respond_to?(:to_model) ? object.to_model : object + end + + def model_name_from_record_or_class(record_or_class) + (record_or_class.is_a?(Class) ? record_or_class : convert_to_model(record_or_class).class).model_name + end + end +end diff --git a/actionpack/lib/action_view/record_identifier.rb b/actionpack/lib/action_view/record_identifier.rb new file mode 100644 index 0000000000..2953654972 --- /dev/null +++ b/actionpack/lib/action_view/record_identifier.rb @@ -0,0 +1,84 @@ +require 'active_support/core_ext/module' +require 'action_view/model_naming' + +module ActionView + # The record identifier encapsulates a number of naming conventions for dealing with records, like Active Records or + # pretty much any other model type that has an id. These patterns are then used to try elevate the view actions to + # a higher logical level. + # + # # routes + # resources :posts + # + # # view + # <%= div_for(post) do %> <div id="post_45" class="post"> + # <%= post.body %> What a wonderful world! + # <% end %> </div> + # + # # controller + # def update + # post = Post.find(params[:id]) + # post.update_attributes(params[:post]) + # + # redirect_to(post) # Calls polymorphic_url(post) which in turn calls post_url(post) + # end + # + # As the example above shows, you can stop caring to a large extent what the actual id of the post is. + # You just know that one is being assigned and that the subsequent calls in redirect_to expect that + # same naming convention and allows you to write less code if you follow it. + module RecordIdentifier + extend self + extend ModelNaming + + include ModelNaming + + JOIN = '_'.freeze + NEW = 'new'.freeze + + # The DOM class convention is to use the singular form of an object or class. + # + # dom_class(post) # => "post" + # dom_class(Person) # => "person" + # + # If you need to address multiple instances of the same class in the same view, you can prefix the dom_class: + # + # dom_class(post, :edit) # => "edit_post" + # dom_class(Person, :edit) # => "edit_person" + def dom_class(record_or_class, prefix = nil) + singular = model_name_from_record_or_class(record_or_class).param_key + prefix ? "#{prefix}#{JOIN}#{singular}" : singular + end + + # The DOM id convention is to use the singular form of an object or class with the id following an underscore. + # If no id is found, prefix with "new_" instead. + # + # dom_id(Post.find(45)) # => "post_45" + # dom_id(Post.new) # => "new_post" + # + # If you need to address multiple instances of the same class in the same view, you can prefix the dom_id: + # + # dom_id(Post.find(45), :edit) # => "edit_post_45" + # dom_id(Post.new, :custom) # => "custom_post" + def dom_id(record, prefix = nil) + if record_id = record_key_for_dom_id(record) + "#{dom_class(record, prefix)}#{JOIN}#{record_id}" + else + dom_class(record, prefix || NEW) + end + end + + protected + + # Returns a string representation of the key attribute(s) that is suitable for use in an HTML DOM id. + # This can be overwritten to customize the default generated string representation if desired. + # If you need to read back a key from a dom_id in order to query for the underlying database record, + # you should write a helper like 'person_record_from_dom_id' that will extract the key either based + # on the default implementation (which just joins all key attributes with '_') or on your own + # overwritten version of the method. By default, this implementation passes the key string through a + # method that replaces all characters that are invalid inside DOM ids, with valid ones. You need to + # make sure yourself that your dom ids are valid, in case you overwrite this method. + def record_key_for_dom_id(record) + key = convert_to_model(record).to_key + key ? key.join('_') : key + end + end +end diff --git a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb index f46aabd2be..9cf6eb0c65 100644 --- a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb +++ b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb @@ -30,7 +30,7 @@ module ActionView # This is the same logging logic as in ShowExceptions middleware. # TODO Once "exceptron" is in, refactor this piece to simply re-use exceptron. def log_error(exception) #:nodoc: - logger = ActionController::Base.logger + logger = ActionView::Base.logger return unless logger message = "\n#{exception.class} (#{exception.message}):\n" diff --git a/actionpack/lib/action_view/routing_url_for.rb b/actionpack/lib/action_view/routing_url_for.rb new file mode 100644 index 0000000000..13fb6406e1 --- /dev/null +++ b/actionpack/lib/action_view/routing_url_for.rb @@ -0,0 +1,107 @@ +module ActionView + module RoutingUrlFor + + # Returns the URL for the set of +options+ provided. This takes the + # same options as +url_for+ in Action Controller (see the + # documentation for <tt>ActionController::Base#url_for</tt>). Note that by default + # <tt>:only_path</tt> is <tt>true</tt> so you'll get the relative "/controller/action" + # instead of the fully qualified URL like "http://example.com/controller/action". + # + # ==== Options + # * <tt>:anchor</tt> - Specifies the anchor name to be appended to the path. + # * <tt>:only_path</tt> - If true, returns the relative URL (omitting the protocol, host name, and port) (<tt>true</tt> by default unless <tt>:host</tt> is specified). + # * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2005/". Note that this + # is currently not recommended since it breaks caching. + # * <tt>:host</tt> - Overrides the default (current) host if provided. + # * <tt>:protocol</tt> - Overrides the default (current) protocol if provided. + # * <tt>:user</tt> - Inline HTTP authentication (only plucked out if <tt>:password</tt> is also present). + # * <tt>:password</tt> - Inline HTTP authentication (only plucked out if <tt>:user</tt> is also present). + # + # ==== Relying on named routes + # + # Passing a record (like an Active Record) instead of a hash as the options parameter will + # trigger the named route for that record. The lookup will happen on the name of the class. So passing a + # Workshop object will attempt to use the +workshop_path+ route. If you have a nested route, such as + # +admin_workshop_path+ you'll have to call that explicitly (it's impossible for +url_for+ to guess that route). + # + # ==== Implicit Controller Namespacing + # + # Controllers passed in using the +:controller+ option will retain their namespace unless it is an absolute one. + # + # ==== Examples + # <%= url_for(:action => 'index') %> + # # => /blog/ + # + # <%= url_for(:action => 'find', :controller => 'books') %> + # # => /books/find + # + # <%= url_for(:action => 'login', :controller => 'members', :only_path => false, :protocol => 'https') %> + # # => https://www.example.com/members/login/ + # + # <%= url_for(:action => 'play', :anchor => 'player') %> + # # => /messages/play/#player + # + # <%= url_for(:action => 'jump', :anchor => 'tax&ship') %> + # # => /testing/jump/#tax&ship + # + # <%= url_for(Workshop.new) %> + # # relies on Workshop answering a persisted? call (and in this case returning false) + # # => /workshops + # + # <%= url_for(@workshop) %> + # # calls @workshop.to_param which by default returns the id + # # => /workshops/5 + # + # # to_param can be re-defined in a model to provide different URL names: + # # => /workshops/1-workshop-name + # + # <%= url_for("http://www.example.com") %> + # # => http://www.example.com + # + # <%= url_for(:back) %> + # # if request.env["HTTP_REFERER"] is set to "http://www.example.com" + # # => http://www.example.com + # + # <%= url_for(:back) %> + # # if request.env["HTTP_REFERER"] is not set or is blank + # # => javascript:history.back() + # + # <%= url_for(:action => 'index', :controller => 'users') %> + # # Assuming an "admin" namespace + # # => /admin/users + # + # <%= url_for(:action => 'index', :controller => '/users') %> + # # Specify absolute path with beginning slash + # # => /users + def url_for(options = nil) + case options + when String + options + when nil, Hash + options ||= {} + options = { :only_path => options[:host].nil? }.merge!(options.symbolize_keys) + super + when :back + _back_url + else + polymorphic_path(options) + end + end + + def url_options #:nodoc: + return super unless controller.respond_to?(:url_options) + controller.url_options + end + + def _routes_context #:nodoc: + controller + end + protected :_routes_context + + def optimize_routes_generation? #:nodoc: + controller.respond_to?(:optimize_routes_generation?) ? + controller.optimize_routes_generation? : super + end + protected :optimize_routes_generation? + end +end diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index a04eac1d3f..379cdc8a25 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -1,5 +1,6 @@ require 'active_support/core_ext/object/try' require 'active_support/core_ext/kernel/singleton_class' +require 'active_support/deprecation' require 'thread' module ActionView @@ -92,6 +93,7 @@ module ActionView autoload :Error autoload :Handlers autoload :Text + autoload :Types end extend Template::Handlers @@ -121,7 +123,7 @@ module ActionView @locals = details[:locals] || [] @virtual_path = details[:virtual_path] @updated_at = details[:updated_at] || Time.now - @formats = Array(format).map { |f| f.is_a?(Mime::Type) ? f.ref : f } + @formats = Array(format).map { |f| f.respond_to?(:ref) ? f.ref : f } @compile_mutex = Mutex.new end @@ -147,9 +149,14 @@ module ActionView end def mime_type + ActiveSupport::Deprecation.warn 'Template#mime_type is deprecated and will be removed in Rails 4.1. Please use type method instead.' @mime_type ||= Mime::Type.lookup_by_extension(@formats.first.to_s) if @formats.first end + def type + @type ||= Types[@formats.first] if @formats.first + end + # Receives a view object and return a template similar to self by using @virtual_path. # # This method is useful if you have a template object but it does not contain its source diff --git a/actionpack/lib/action_view/template/handlers/builder.rb b/actionpack/lib/action_view/template/handlers/builder.rb index 34397c3bcf..d90b0c6378 100644 --- a/actionpack/lib/action_view/template/handlers/builder.rb +++ b/actionpack/lib/action_view/template/handlers/builder.rb @@ -3,7 +3,7 @@ module ActionView class Builder # Default format used by Builder. class_attribute :default_format - self.default_format = Mime::XML + self.default_format = :xml def call(template) require_engine diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 2bb656fac9..25c6fd4aa8 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -235,7 +235,7 @@ module ActionView extension = pieces.pop ActiveSupport::Deprecation.warn "The file #{path} did not specify a template handler. The default is currently ERB, but will change to RAW in the future." unless extension handler = Template.handler_for_extension(extension) - format = pieces.last && Mime[pieces.last] + format = pieces.last && Template::Types[pieces.last] [handler, format] end end diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb index 3af76dfcdb..859c7bc3ce 100644 --- a/actionpack/lib/action_view/template/text.rb +++ b/actionpack/lib/action_view/template/text.rb @@ -2,12 +2,12 @@ module ActionView #:nodoc: # = Action View Text Template class Template class Text #:nodoc: - attr_accessor :mime_type + attr_accessor :type - def initialize(string, mime_type = nil) - @string = string.to_s - @mime_type = Mime[mime_type] || mime_type if mime_type - @mime_type ||= Mime::TEXT + def initialize(string, type = nil) + @string = string.to_s + @type = Types[type] || type if type + @type ||= Types[:text] end def identifier @@ -27,7 +27,7 @@ module ActionView #:nodoc: end def formats - [@mime_type.to_sym] + [@type.to_sym] end end end diff --git a/actionpack/lib/action_view/template/types.rb b/actionpack/lib/action_view/template/types.rb new file mode 100644 index 0000000000..7611c9e708 --- /dev/null +++ b/actionpack/lib/action_view/template/types.rb @@ -0,0 +1,58 @@ +require 'set' +require 'active_support/core_ext/class/attribute_accessors' +require 'active_support/core_ext/object/blank' + +module ActionView + class Template + class Types + class Type + cattr_accessor :types + self.types = Set.new + + def self.register(*t) + types.merge(t.map { |type| type.to_s }) + end + + register :html, :text, :js, :css, :xml, :json + + def self.[](type) + return type if type.is_a?(self) + + if type.is_a?(Symbol) || types.member?(type.to_s) + new(type) + end + end + + attr_reader :symbol + + def initialize(symbol) + @symbol = symbol.to_sym + end + + delegate :to_s, :to_sym, :to => :symbol + alias to_str to_s + + def ref + to_sym || to_s + end + + def ==(type) + return false if type.blank? + symbol.to_sym == type.to_sym + end + end + + cattr_accessor :type_klass + + def self.delegate_to(klass) + self.type_klass = klass + end + + delegate_to Type + + def self.[](type) + type_klass[type] + end + end + end +end diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index 55f79bf761..434fc8cc14 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -38,10 +38,11 @@ module ActionView include ActionView::Context include ActionDispatch::Routing::PolymorphicRoutes - include ActionController::RecordIdentifier include AbstractController::Helpers include ActionView::Helpers + include ActionView::RecordIdentifier + include ActionView::RoutingUrlFor delegate :lookup_context, :to => :controller attr_accessor :controller, :output_buffer, :rendered diff --git a/actionpack/lib/action_view/vendor/html-scanner.rb b/actionpack/lib/action_view/vendor/html-scanner.rb new file mode 100644 index 0000000000..879b31e60e --- /dev/null +++ b/actionpack/lib/action_view/vendor/html-scanner.rb @@ -0,0 +1,20 @@ +$LOAD_PATH << "#{File.dirname(__FILE__)}/html-scanner" + +module HTML + extend ActiveSupport::Autoload + + eager_autoload do + autoload :CDATA, 'html/node' + autoload :Document, 'html/document' + autoload :FullSanitizer, 'html/sanitizer' + autoload :LinkSanitizer, 'html/sanitizer' + autoload :Node, 'html/node' + autoload :Sanitizer, 'html/sanitizer' + autoload :Selector, 'html/selector' + autoload :Tag, 'html/node' + autoload :Text, 'html/node' + autoload :Tokenizer, 'html/tokenizer' + autoload :Version, 'html/version' + autoload :WhiteListSanitizer, 'html/sanitizer' + end +end diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb b/actionpack/lib/action_view/vendor/html-scanner/html/document.rb index 386820300a..386820300a 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb +++ b/actionpack/lib/action_view/vendor/html-scanner/html/document.rb diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb b/actionpack/lib/action_view/vendor/html-scanner/html/node.rb index 4e1f016431..4e1f016431 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb +++ b/actionpack/lib/action_view/vendor/html-scanner/html/node.rb diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb b/actionpack/lib/action_view/vendor/html-scanner/html/sanitizer.rb index 6b4ececda2..6b4ececda2 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +++ b/actionpack/lib/action_view/vendor/html-scanner/html/sanitizer.rb diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb b/actionpack/lib/action_view/vendor/html-scanner/html/selector.rb index 1eadfc0390..1eadfc0390 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb +++ b/actionpack/lib/action_view/vendor/html-scanner/html/selector.rb diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/tokenizer.rb b/actionpack/lib/action_view/vendor/html-scanner/html/tokenizer.rb index 8ac8d34430..8ac8d34430 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +++ b/actionpack/lib/action_view/vendor/html-scanner/html/tokenizer.rb diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/version.rb b/actionpack/lib/action_view/vendor/html-scanner/html/version.rb index 6d645c3e14..6d645c3e14 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/version.rb +++ b/actionpack/lib/action_view/vendor/html-scanner/html/version.rb diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb index 9b0d4d0f4c..4ab5d92a2b 100644 --- a/actionpack/test/controller/action_pack_assertions_test.rb +++ b/actionpack/test/controller/action_pack_assertions_test.rb @@ -1,5 +1,5 @@ require 'abstract_unit' -require 'action_controller/vendor/html-scanner' +require 'action_view/vendor/html-scanner' require 'controller/fake_controllers' class ActionPackAssertionsController < ActionController::Base diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index b9513ccff4..9b42e7631f 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -1,5 +1,6 @@ require 'abstract_unit' require 'active_support/logger' +require 'controller/fake_models' require 'pp' # require 'pp' early to prevent hidden_methods from not picking up the pretty-print methods until too late # Provide some controller to run the tests on. @@ -63,6 +64,10 @@ end class RecordIdentifierController < ActionController::Base end +class RecordIdentifierWithoutDeprecationController < ActionController::Base + include ActionView::RecordIdentifier +end + class ControllerClassTests < ActiveSupport::TestCase def test_controller_path @@ -81,6 +86,42 @@ class ControllerClassTests < ActiveSupport::TestCase assert_respond_to RecordIdentifierController.new, :dom_id assert_respond_to RecordIdentifierController.new, :dom_class end + + def test_record_identifier_is_deprecated + record = Comment.new + record.save + + dom_id = nil + assert_deprecated 'dom_id method will no longer' do + dom_id = RecordIdentifierController.new.dom_id(record) + end + + assert_equal 'comment_1', dom_id + + dom_class = nil + assert_deprecated 'dom_class method will no longer' do + dom_class = RecordIdentifierController.new.dom_class(record) + end + assert_equal 'comment', dom_class + end + + def test_no_deprecation_when_action_view_record_identifier_is_included + record = Comment.new + record.save + + dom_id = nil + assert_not_deprecated do + dom_id = RecordIdentifierWithoutDeprecationController.new.dom_id(record) + end + + assert_equal 'comment_1', dom_id + + dom_class = nil + assert_not_deprecated do + dom_class = RecordIdentifierWithoutDeprecationController.new.dom_class(record) + end + assert_equal 'comment', dom_class + end end class ControllerInstanceTests < ActiveSupport::TestCase diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index f18bf33969..cf561d913a 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -1,6 +1,6 @@ require 'abstract_unit' require 'controller/fake_controllers' -require 'action_controller/vendor/html-scanner' +require 'action_view/vendor/html-scanner' class SessionTest < ActiveSupport::TestCase StubApp = lambda { |env| diff --git a/actionpack/test/controller/new_base/render_streaming_test.rb b/actionpack/test/controller/new_base/render_streaming_test.rb index bfca8c5c24..f4bdd3e1d4 100644 --- a/actionpack/test/controller/new_base/render_streaming_test.rb +++ b/actionpack/test/controller/new_base/render_streaming_test.rb @@ -85,7 +85,7 @@ module RenderStreaming test "rendering with template exception logs the exception" do io = StringIO.new - _old, ActionController::Base.logger = ActionController::Base.logger, ActiveSupport::Logger.new(io) + _old, ActionView::Base.logger = ActionView::Base.logger, ActiveSupport::Logger.new(io) begin get "/render_streaming/basic/template_exception" diff --git a/actionpack/test/controller/selector_test.rb b/actionpack/test/controller/selector_test.rb index 5e302da212..1e80c8601c 100644 --- a/actionpack/test/controller/selector_test.rb +++ b/actionpack/test/controller/selector_test.rb @@ -5,7 +5,7 @@ require 'abstract_unit' require 'controller/fake_controllers' -require 'action_controller/vendor/html-scanner' +require 'action_view/vendor/html-scanner' class SelectorTest < ActiveSupport::TestCase # diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index 6a44197525..25d85c47c7 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -65,7 +65,6 @@ class AssetTagHelperTest < ActionView::TestCase %(auto_discovery_link_tag) => %(<link href="http://www.example.com" rel="alternate" title="RSS" type="application/rss+xml" />), %(auto_discovery_link_tag(:rss)) => %(<link href="http://www.example.com" rel="alternate" title="RSS" type="application/rss+xml" />), %(auto_discovery_link_tag(:atom)) => %(<link href="http://www.example.com" rel="alternate" title="ATOM" type="application/atom+xml" />), - %(auto_discovery_link_tag(:xml)) => %(<link href="http://www.example.com" rel="alternate" title="XML" type="application/xml" />), %(auto_discovery_link_tag(:rss, :action => "feed")) => %(<link href="http://www.example.com" rel="alternate" title="RSS" type="application/rss+xml" />), %(auto_discovery_link_tag(:rss, "http://localhost/feed")) => %(<link href="http://localhost/feed" rel="alternate" title="RSS" type="application/rss+xml" />), %(auto_discovery_link_tag(:rss, "//localhost/feed")) => %(<link href="//localhost/feed" rel="alternate" title="RSS" type="application/rss+xml" />), @@ -299,6 +298,16 @@ class AssetTagHelperTest < ActionView::TestCase %(audio_tag(["audio.mp3", "audio.ogg"], :autobuffer => true, :controls => true)) => %(<audio autobuffer="autobuffer" controls="controls"><source src="/audios/audio.mp3" /><source src="/audios/audio.ogg" /></audio>) } + def test_autodiscovery_link_tag_deprecated_types + result = nil + assert_deprecated do + result = auto_discovery_link_tag(:xml) + end + + expected = %(<link href="http://www.example.com" rel="alternate" title="XML" type="application/xml" />) + assert_equal expected, result + end + def test_auto_discovery_link_tag AutoDiscoveryToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end diff --git a/actionpack/test/template/erb/helper.rb b/actionpack/test/template/erb/helper.rb index 799f9e4036..a1973068d5 100644 --- a/actionpack/test/template/erb/helper.rb +++ b/actionpack/test/template/erb/helper.rb @@ -1,5 +1,6 @@ module ERBTest class ViewContext + include ActionView::Helpers::UrlHelper include SharedTestRoutes.url_helpers include ActionView::Helpers::TagHelper include ActionView::Helpers::JavaScriptHelper @@ -20,4 +21,4 @@ module ERBTest "<%= #{str} do %>#{rest}<% end %>" end end -end
\ No newline at end of file +end diff --git a/actionpack/test/template/log_subscriber_test.rb b/actionpack/test/template/log_subscriber_test.rb index 1713ce935c..7f4c84929f 100644 --- a/actionpack/test/template/log_subscriber_test.rb +++ b/actionpack/test/template/log_subscriber_test.rb @@ -8,9 +8,10 @@ class AVLogSubscriberTest < ActiveSupport::TestCase def setup super - @controller = Object.new - @controller.stubs(:_prefixes).returns(%w(test)) - @view = ActionView::Base.new(ActionController::Base.view_paths, {}, @controller) + view_paths = ActionController::Base.view_paths + lookup_context = ActionView::LookupContext.new(view_paths, {}, ["test"]) + renderer = ActionView::Renderer.new(lookup_context) + @view = ActionView::Base.new(renderer, {}) Rails.stubs(:root).returns(File.expand_path(FIXTURE_LOAD_PATH)) ActionView::LogSubscriber.attach_to :action_view end diff --git a/actionpack/test/template/lookup_context_test.rb b/actionpack/test/template/lookup_context_test.rb index ef9c5ce10c..073bd14783 100644 --- a/actionpack/test/template/lookup_context_test.rb +++ b/actionpack/test/template/lookup_context_test.rb @@ -11,6 +11,17 @@ class LookupContextTest < ActiveSupport::TestCase I18n.locale = :en end + test "allows to override default_formats with ActionView::Base.default_formats" do + begin + formats = ActionView::Base.default_formats + ActionView::Base.default_formats = [:foo, :bar] + + assert_equal [:foo, :bar], ActionView::LookupContext.new([]).default_formats + ensure + ActionView::Base.default_formats = formats + end + end + test "process view paths on initialization" do assert_kind_of ActionView::PathSet, @lookup_context.view_paths end diff --git a/actionpack/test/controller/record_identifier_test.rb b/actionpack/test/template/record_identifier_test.rb index eb38b81e85..22038110a5 100644 --- a/actionpack/test/controller/record_identifier_test.rb +++ b/actionpack/test/template/record_identifier_test.rb @@ -2,7 +2,7 @@ require 'abstract_unit' require 'controller/fake_models' class RecordIdentifierTest < ActiveSupport::TestCase - include ActionController::RecordIdentifier + include ActionView::RecordIdentifier def setup @klass = Comment @@ -37,4 +37,13 @@ class RecordIdentifierTest < ActiveSupport::TestCase def test_dom_class_with_prefix assert_equal "custom_prefix_#{@singular}", dom_class(@record, :custom_prefix) end + + def test_dom_id_as_singleton_method + @record.save + assert_equal "#{@singular}_1", ActionView::RecordIdentifier.dom_id(@record) + end + + def test_dom_class_as_singleton_method + assert_equal @singular, ActionView::RecordIdentifier.dom_class(@record) + end end diff --git a/actionpack/test/template/template_test.rb b/actionpack/test/template/template_test.rb index 061f5bb53f..86ba5f3b4d 100644 --- a/actionpack/test/template/template_test.rb +++ b/actionpack/test/template/template_test.rb @@ -59,6 +59,13 @@ class TestERBTemplate < ActiveSupport::TestCase @context = Context.new end + def test_mime_type_is_deprecated + template = new_template + assert_deprecated 'Template#mime_type is deprecated and will be removed' do + template.mime_type + end + end + def test_basic_template @template = new_template assert_equal "Hello", render diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index f9f8c36fff..9c4271f19b 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -20,9 +20,9 @@ class UrlHelperTest < ActiveSupport::TestCase get "/article/:id" => "foo#article", :as => :article end + include ActionView::Helpers::UrlHelper include routes.url_helpers - include ActionView::Helpers::UrlHelper include ActionView::Helpers::JavaScriptHelper include ActionDispatch::Assertions::DomAssertions include ActionView::Context |