aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/CHANGELOG6
-rw-r--r--actionpack/lib/abstract_controller/base.rb38
-rw-r--r--actionpack/lib/abstract_controller/callbacks.rb4
-rw-r--r--actionpack/lib/abstract_controller/layouts.rb6
-rw-r--r--actionpack/lib/abstract_controller/rendering.rb28
-rw-r--r--actionpack/lib/abstract_controller/view_paths.rb2
-rw-r--r--actionpack/lib/action_controller/log_subscriber.rb4
-rw-r--r--actionpack/lib/action_controller/metal/compatibility.rb11
-rw-r--r--actionpack/lib/action_controller/metal/implicit_render.rb16
-rw-r--r--actionpack/lib/action_controller/metal/instrumentation.rb2
-rw-r--r--actionpack/lib/action_controller/metal/params_wrapper.rb2
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb5
-rw-r--r--actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb2
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb9
-rw-r--r--actionpack/lib/action_view.rb1
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb8
-rw-r--r--actionpack/lib/action_view/helpers/date_helper.rb51
-rw-r--r--actionpack/lib/action_view/lookup_context.rb10
-rw-r--r--actionpack/lib/action_view/path_set.rb2
-rw-r--r--actionpack/lib/action_view/template/error.rb2
-rw-r--r--actionpack/lib/action_view/template/resolver.rb62
-rw-r--r--actionpack/lib/sprockets/railtie.rb2
-rw-r--r--actionpack/test/controller/new_base/render_implicit_action_test.rb8
-rw-r--r--actionpack/test/dispatch/request_test.rb7
-rw-r--r--actionpack/test/dispatch/show_exceptions_test.rb4
-rw-r--r--actionpack/test/template/capture_helper_test.rb16
-rw-r--r--actionpack/test/template/date_helper_test.rb59
-rw-r--r--actionpack/test/template/html-scanner/sanitizer_test.rb1
-rw-r--r--actionpack/test/template/lookup_context_test.rb14
-rw-r--r--actionpack/test/template/render_test.rb2
31 files changed, 282 insertions, 104 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 046b47cc32..23190ef406 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,9 @@
*Rails 3.1.0 (unreleased)*
+* Warn if we cannot verify CSRF token authenticity [José Valim]
+
+* Allow AM/PM format in datetime selectors [Aditya Sanghi]
+
* Only show dump of regular env methods on exception screen (not all the rack crap) [DHH]
* auto_link has been removed with no replacement. If you still use auto_link
@@ -114,8 +118,6 @@ tested.
Keys are dasherized. Values are JSON-encoded, except for strings and symbols. [Stephen Celis]
-* Added render :once. You can pass either a string or an array of strings and Rails will ensure they each of them are rendered just once. [José Valim]
-
* Deprecate old template handler API. The new API simply requires a template handler to respond to call. [José Valim]
* :rhtml and :rxml were finally removed as template handlers. [José Valim]
diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb
index 0951267fea..f67d0e558e 100644
--- a/actionpack/lib/abstract_controller/base.rb
+++ b/actionpack/lib/abstract_controller/base.rb
@@ -130,27 +130,39 @@ module AbstractController
self.class.action_methods
end
- # Returns true if the name can be considered an action. This can
- # be overridden in subclasses to modify the semantics of what
- # can be considered an action.
+ # Returns true if a method for the action is available and
+ # can be dispatched, false otherwise.
#
- # For instance, this is overriden by ActionController to add
- # the implicit rendering feature.
- #
- # ==== Parameters
- # * <tt>name</tt> - The name of an action to be tested
- #
- # ==== Returns
- # * <tt>TrueClass</tt>, <tt>FalseClass</tt>
- def action_method?(name)
- self.class.action_methods.include?(name)
+ # Notice that <tt>action_methods.include?("foo")</tt> may return
+ # false and <tt>available_action?("foo")</tt> returns true because
+ # available action consider actions that are also available
+ # through other means, for example, implicit render ones.
+ def available_action?(action_name)
+ method_for_action(action_name).present?
end
private
+ # Returns true if the name can be considered an action because
+ # it has a method defined in the controller.
+ #
+ # ==== Parameters
+ # * <tt>name</tt> - The name of an action to be tested
+ #
+ # ==== Returns
+ # * <tt>TrueClass</tt>, <tt>FalseClass</tt>
+ #
+ # :api: private
+ def action_method?(name)
+ self.class.action_methods.include?(name)
+ end
+
# Call the action. Override this in a subclass to modify the
# behavior around processing an action. This, and not #process,
# is the intended way to override action dispatching.
+ #
+ # Notice that the first argument is the method to be dispatched
+ # which is *not* necessarily the same as the action name.
def process_action(method_name, *args)
send_action(method_name, *args)
end
diff --git a/actionpack/lib/abstract_controller/callbacks.rb b/actionpack/lib/abstract_controller/callbacks.rb
index f7b2b7ff53..e8426bc52b 100644
--- a/actionpack/lib/abstract_controller/callbacks.rb
+++ b/actionpack/lib/abstract_controller/callbacks.rb
@@ -13,8 +13,8 @@ module AbstractController
# Override AbstractController::Base's process_action to run the
# process_action callbacks around the normal behavior.
- def process_action(method_name, *args)
- run_callbacks(:process_action, method_name) do
+ def process_action(*args)
+ run_callbacks(:process_action, action_name) do
super
end
end
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb
index d1b87b67ee..8f73e244d7 100644
--- a/actionpack/lib/abstract_controller/layouts.rb
+++ b/actionpack/lib/abstract_controller/layouts.rb
@@ -292,15 +292,15 @@ module AbstractController
end
end
- attr_writer :action_has_layout
+ attr_internal_writer :action_has_layout
def initialize(*)
- @action_has_layout = true
+ @_action_has_layout = true
super
end
def action_has_layout?
- @action_has_layout
+ @_action_has_layout
end
private
diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb
index f78365afdb..ab2c532859 100644
--- a/actionpack/lib/abstract_controller/rendering.rb
+++ b/actionpack/lib/abstract_controller/rendering.rb
@@ -32,9 +32,13 @@ module AbstractController
module Rendering
extend ActiveSupport::Concern
-
include AbstractController::ViewPaths
+ included do
+ config_accessor :protected_instance_variables, :instance_reader => false
+ self.protected_instance_variables = []
+ end
+
# Overwrite process to setup I18n proxy.
def process(*) #:nodoc:
old_config, I18n.config = I18n.config, I18nProxy.new(I18n.config, lookup_context)
@@ -53,14 +57,20 @@ module AbstractController
end
end
- attr_writer :view_context_class
+ attr_internal_writer :view_context_class
+
+ # Explicitly define protected_instance_variables so it can be
+ # inherited and overwritten by other modules if needed.
+ def protected_instance_variables
+ config.protected_instance_variables
+ end
def view_context_class
- @view_context_class || self.class.view_context_class
+ @_view_context_class || self.class.view_context_class
end
def initialize(*)
- @view_context_class = nil
+ @_view_context_class = nil
super
end
@@ -79,7 +89,7 @@ module AbstractController
# Returns an object that is able to render templates.
def view_renderer
- @view_renderer ||= ActionView::Renderer.new(lookup_context)
+ @_view_renderer ||= ActionView::Renderer.new(lookup_context)
end
# Normalize arguments, options and then delegates render_to_body and
@@ -112,13 +122,19 @@ module AbstractController
private
+ DEFAULT_PROTECTED_INSTANCE_VARIABLES = %w(
+ @_action_name @_response_body @_formats @_prefixes @_config
+ @_view_context_class @_view_renderer @_lookup_context
+ )
+
# This method should return a hash with assigns.
# You can overwrite this configuration per controller.
# :api: public
def view_assigns
hash = {}
variables = instance_variable_names
- variables -= protected_instance_variables if respond_to?(:protected_instance_variables)
+ variables -= protected_instance_variables
+ variables -= DEFAULT_PROTECTED_INSTANCE_VARIABLES
variables.each { |name| hash[name.to_s[1, name.length]] = instance_variable_get(name) }
hash
end
diff --git a/actionpack/lib/abstract_controller/view_paths.rb b/actionpack/lib/abstract_controller/view_paths.rb
index 0893459e24..6b7aae8c74 100644
--- a/actionpack/lib/abstract_controller/view_paths.rb
+++ b/actionpack/lib/abstract_controller/view_paths.rb
@@ -39,7 +39,7 @@ module AbstractController
# templates, i.e. view paths and details. Check ActionView::LookupContext for more
# information.
def lookup_context
- @lookup_context ||=
+ @_lookup_context ||=
ActionView::LookupContext.new(self.class._view_paths, details_for_lookup, _prefixes)
end
diff --git a/actionpack/lib/action_controller/log_subscriber.rb b/actionpack/lib/action_controller/log_subscriber.rb
index 3fae697cc3..8d813a8e38 100644
--- a/actionpack/lib/action_controller/log_subscriber.rb
+++ b/actionpack/lib/action_controller/log_subscriber.rb
@@ -7,8 +7,10 @@ module ActionController
def start_processing(event)
payload = event.payload
params = payload[:params].except(*INTERNAL_PARAMS)
+ format = payload[:format]
+ format = format.to_s.upcase if format.is_a?(Symbol)
- info " Processing by #{payload[:controller]}##{payload[:action]} as #{payload[:formats].first.to_s.upcase}"
+ info " Processing by #{payload[:controller]}##{payload[:action]} as #{format}"
info " Parameters: #{params.inspect}" unless params.empty?
end
diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb
index 006b9fd456..05dca445a4 100644
--- a/actionpack/lib/action_controller/metal/compatibility.rb
+++ b/actionpack/lib/action_controller/metal/compatibility.rb
@@ -18,13 +18,10 @@ module ActionController
delegate :default_charset=, :to => "ActionDispatch::Response"
end
- # TODO: Update protected instance variables list
- config_accessor :protected_instance_variables
- self.protected_instance_variables = %w(@assigns @performed_redirect @performed_render
- @variables_added @request_origin @url
- @parent_controller @action_name
- @before_filter_chain_aborted @_headers @_params
- @_response)
+ self.protected_instance_variables = %w(
+ @_status @_headers @_params @_env @_response @_request
+ @_view_runtime @_stream @_url_options @_action_has_layout
+ )
def rescue_action(env)
raise env["action_dispatch.rescue.exception"]
diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb
index 3ec0c4c6a4..e8e465d3ba 100644
--- a/actionpack/lib/action_controller/metal/implicit_render.rb
+++ b/actionpack/lib/action_controller/metal/implicit_render.rb
@@ -1,21 +1,19 @@
module ActionController
module ImplicitRender
def send_action(method, *args)
- if respond_to?(method, true)
- ret = super
- default_render unless response_body
- ret
- else
- default_render
- end
+ ret = super
+ default_render unless response_body
+ ret
end
def default_render(*args)
render(*args)
end
- def action_method?(action_name)
- super || template_exists?(action_name.to_s, _prefixes)
+ def method_for_action(action_name)
+ super || if template_exists?(action_name.to_s, _prefixes)
+ "default_render"
+ end
end
end
end
diff --git a/actionpack/lib/action_controller/metal/instrumentation.rb b/actionpack/lib/action_controller/metal/instrumentation.rb
index 4e54c2ad88..16cbbce2fb 100644
--- a/actionpack/lib/action_controller/metal/instrumentation.rb
+++ b/actionpack/lib/action_controller/metal/instrumentation.rb
@@ -19,7 +19,7 @@ module ActionController
:controller => self.class.name,
:action => self.action_name,
:params => request.filtered_parameters,
- :formats => request.formats.map(&:to_sym),
+ :format => request.format.ref,
:method => request.method,
:path => (request.fullpath rescue "unknown")
}
diff --git a/actionpack/lib/action_controller/metal/params_wrapper.rb b/actionpack/lib/action_controller/metal/params_wrapper.rb
index 21bbe17dc3..881af74147 100644
--- a/actionpack/lib/action_controller/metal/params_wrapper.rb
+++ b/actionpack/lib/action_controller/metal/params_wrapper.rb
@@ -125,7 +125,7 @@ module ActionController
# module is inherited.
def inherited(klass)
if klass._wrapper_options[:format].present?
- klass._set_wrapper_defaults(klass._wrapper_options)
+ klass._set_wrapper_defaults(klass._wrapper_options.slice(:format))
end
super
end
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
index 1cd93a188c..13044a7450 100644
--- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -73,7 +73,10 @@ module ActionController #:nodoc:
protected
# The actual before_filter that is used. Modify this to change how you handle unverified requests.
def verify_authenticity_token
- verified_request? || handle_unverified_request
+ unless verified_request?
+ logger.debug "WARNING: Can't verify CSRF token authenticity" if logger
+ handle_unverified_request
+ end
end
def handle_unverified_request
diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
index 09dd08898c..91a97c02ff 100644
--- a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
+++ b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
@@ -33,7 +33,7 @@ module HTML
result = super
# strip any comments, and if they have a newline at the end (ie. line with
# only a comment) strip that too
- result.gsub!(/<!--(.*?)-->[\n]?/m, "") if result
+ result = result.gsub(/<!--(.*?)-->[\n]?/m, "") if (result && result =~ /<!--(.*?)-->[\n]?/m)
# Recurse - handle all dirty nested tags
result == text ? result : sanitize(result, options)
end
diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb
index 2099fd069a..4b9d3141d5 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb
@@ -1,7 +1,7 @@
<h1>
<%=h @exception.class.to_s %>
<% if @request.parameters['controller'] %>
- in <%=h @request.parameters['controller'].classify.pluralize %>Controller<% if @request.parameters['action'] %>#<%=h @request.parameters['action'] %><% end %>
+ in <%=h @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%=h @request.parameters['action'] %><% end %>
<% end %>
</h1>
<pre><%=h @exception.message %></pre>
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 97e8ccc9a5..5097f6732d 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -224,6 +224,7 @@ module ActionDispatch
self.valid_conditions.push(:controller, :action)
@append = []
+ @prepend = []
@disable_clear_and_finalize = false
clear!
end
@@ -232,7 +233,6 @@ module ActionDispatch
clear! unless @disable_clear_and_finalize
eval_block(block)
finalize! unless @disable_clear_and_finalize
-
nil
end
@@ -240,6 +240,10 @@ module ActionDispatch
@append << block
end
+ def prepend(&block)
+ @prepend << block
+ end
+
def eval_block(block)
if block.arity == 1
raise "You are using the old router DSL which has been removed in Rails 3.1. " <<
@@ -262,8 +266,6 @@ module ActionDispatch
end
def clear!
- # Clear the controller cache so we may discover new ones
- @controller_constraints = nil
@finalized = false
routes.clear
named_routes.clear
@@ -271,6 +273,7 @@ module ActionDispatch
:parameters_key => PARAMETERS_KEY,
:request_class => request_class
)
+ @prepend.each { |blk| eval_block(blk) }
end
def install_helpers(destinations = [ActionController::Base, ActionView::Base], regenerate_code = false)
diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb
index 92b6f7c770..a67b61c1ef 100644
--- a/actionpack/lib/action_view.rb
+++ b/actionpack/lib/action_view.rb
@@ -50,6 +50,7 @@ module ActionView
autoload :Resolver
autoload :PathResolver
autoload :FileSystemResolver
+ autoload :OptimizedFileSystemResolver
autoload :FallbackFileSystemResolver
end
diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb
index ead7feb091..3b5f4e694f 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -135,8 +135,12 @@ module ActionView
# for elements that will be fragment cached.
def content_for(name, content = nil, &block)
content = capture(&block) if block_given?
- result = @view_flow.append(name, content) if content
- result unless content
+ if content
+ @view_flow.append(name, content)
+ nil
+ else
+ @view_flow.get(name)
+ end
end
# The same as +content_for+ but when used with streaming flushes
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index 9277359d5c..d2ddaafcb3 100644
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -94,9 +94,20 @@ module ActionView
when 43200..86399 then locale.t :about_x_months, :count => 1
when 86400..525599 then locale.t :x_months, :count => (distance_in_minutes.to_f / 43200.0).round
else
- distance_in_years = distance_in_minutes / 525600
- minute_offset_for_leap_year = (distance_in_years / 4) * 1440
- remainder = ((distance_in_minutes - minute_offset_for_leap_year) % 525600)
+ fyear = from_time.year
+ fyear += 1 if from_time.month >= 3
+ tyear = to_time.year
+ tyear -= 1 if to_time.month < 3
+ leap_years = (fyear > tyear) ? 0 : (fyear..tyear).count{|x| Date.leap?(x)}
+ minute_offset_for_leap_year = leap_years * 1440
+ # Discount the leap year days when calculating year distance.
+ # e.g. if there are 20 leap year days between 2 dates having the same day
+ # and month then the based on 365 days calculation
+ # the distance in years will come out to over 80 years when in written
+ # english it would read better as about 80 years.
+ minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year
+ remainder = (minutes_with_offset % 525600)
+ distance_in_years = (minutes_with_offset / 525600)
if remainder < 131400
locale.t(:about_x_years, :count => distance_in_years)
elsif remainder < 394200
@@ -207,7 +218,8 @@ module ActionView
# Returns a set of select tags (one for hour, minute and optionally second) pre-selected for accessing a
# specified time-based attribute (identified by +method+) on an object assigned to the template (identified by
- # +object+). You can include the seconds with <tt>:include_seconds</tt>.
+ # +object+). You can include the seconds with <tt>:include_seconds</tt>. You can get hours in the AM/PM format
+ # with <tt>:ampm</tt> option.
#
# This method will also generate 3 input hidden tags, for the actual year, month and day unless the option
# <tt>:ignore_date</tt> is set to +true+.
@@ -230,6 +242,9 @@ module ActionView
# time_select("post", "written_on", :prompt => {:hour => true}) # generic prompt for hours
# time_select("post", "written_on", :prompt => true) # generic prompts for all
#
+ # # You can set :ampm option to true which will show the hours as: 12 PM, 01 AM .. 11 PM.
+ # time_select 'game', 'game_time', {:ampm => true}
+ #
# The selects are prepared for multi-parameter assignment to an Active Record object.
#
# Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that
@@ -257,6 +272,9 @@ module ActionView
# # be stored in the trip variable in the departing attribute.
# datetime_select("trip", "departing", :default => 3.days.from_now)
#
+ # # Generate a datetime select with hours in the AM/PM format
+ # datetime_select("post", "written_on", :ampm => true)
+ #
# # Generates a datetime select that discards the type that, when POSTed, will be stored in the post variable
# # as the written_on attribute.
# datetime_select("post", "written_on", :discard_type => true)
@@ -306,6 +324,9 @@ module ActionView
# # my_date_time (four days after today)
# select_datetime(my_date_time, :discard_type => true)
#
+ # # Generate a datetime field with hours in the AM/PM format
+ # select_datetime(my_date_time, :ampm => true)
+ #
# # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
# # prefixed with 'payday' rather than 'date'
# select_datetime(my_date_time, :prefix => 'payday')
@@ -387,6 +408,9 @@ module ActionView
# # separated by ':' and includes an input for seconds
# select_time(my_time, :time_separator => ':', :include_seconds => true)
#
+ # # Generate a time select field with hours in the AM/PM format
+ # select_time(my_time, :ampm => true)
+ #
# # Generates a time select with a custom prompt. Use :prompt=>true for generic prompts.
# select_time(my_time, :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
# select_time(my_time, :prompt => {:hour => true}) # generic prompt for hours
@@ -468,6 +492,9 @@ module ActionView
# # generic prompt.
# select_hour(13, :prompt => 'Choose hour')
#
+ # # Generate a select field for hours in the AM/PM format
+ # select_hour(my_time, :ampm => true)
+ #
def select_hour(datetime, options = {}, html_options = {})
DateTimeSelector.new(datetime, options, html_options).select_hour
end
@@ -601,6 +628,15 @@ module ActionView
:year => 1, :month => 2, :day => 3, :hour => 4, :minute => 5, :second => 6
}.freeze
+ AMPM_TRANSLATION = Hash[
+ [[0, "12 AM"], [1, "01 AM"], [2, "02 AM"], [3, "03 AM"],
+ [4, "04 AM"], [5, "05 AM"], [6, "06 AM"], [7, "07 AM"],
+ [8, "08 AM"], [9, "09 AM"], [10, "10 AM"], [11, "11 AM"],
+ [12, "12 PM"], [13, "01 PM"], [14, "02 PM"], [15, "03 PM"],
+ [16, "04 PM"], [17, "05 PM"], [18, "06 PM"], [19, "07 PM"],
+ [20, "08 PM"], [21, "09 PM"], [22, "10 PM"], [23, "11 PM"]]
+ ].freeze
+
def initialize(datetime, options = {}, html_options = {})
@options = options.dup
@html_options = html_options.dup
@@ -692,7 +728,7 @@ module ActionView
if @options[:use_hidden] || @options[:discard_hour]
build_hidden(:hour, hour)
else
- build_options_and_select(:hour, hour, :end => 23)
+ build_options_and_select(:hour, hour, :end => 23, :ampm => @options[:ampm])
end
end
@@ -810,7 +846,7 @@ module ActionView
start = options.delete(:start) || 0
stop = options.delete(:end) || 59
step = options.delete(:step) || 1
- options.reverse_merge!({:leading_zeros => true})
+ options.reverse_merge!({:leading_zeros => true, :ampm => false})
leading_zeros = options.delete(:leading_zeros)
select_options = []
@@ -818,7 +854,8 @@ module ActionView
value = leading_zeros ? sprintf("%02d", i) : i
tag_options = { :value => value }
tag_options[:selected] = "selected" if selected == i
- select_options << content_tag(:option, value, tag_options)
+ text = options[:ampm] ? AMPM_TRANSLATION[i] : value
+ select_options << content_tag(:option, text, tag_options)
end
(select_options.join("\n") + "\n").html_safe
end
diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb
index 06975ffa2f..f0ed3425de 100644
--- a/actionpack/lib/action_view/lookup_context.rb
+++ b/actionpack/lib/action_view/lookup_context.rb
@@ -167,12 +167,12 @@ module ActionView
@frozen_formats = true
end
- # Overload formats= to reject ["*/*"] values.
+ # Overload formats= to expand ["*/*"] values and automatically
+ # add :html as fallback to :js.
def formats=(values)
- if values && values.size == 1
- value = values.first
- values = nil if value == "*/*"
- values << :html if value == :js
+ if values
+ values.concat(_formats_defaults) if values.delete "*/*"
+ values << :html if values == [:js]
end
super(values)
end
diff --git a/actionpack/lib/action_view/path_set.rb b/actionpack/lib/action_view/path_set.rb
index 8b840a6463..e0cb5d6a70 100644
--- a/actionpack/lib/action_view/path_set.rb
+++ b/actionpack/lib/action_view/path_set.rb
@@ -35,7 +35,7 @@ module ActionView #:nodoc:
each_with_index do |path, i|
path = path.to_s if path.is_a?(Pathname)
next unless path.is_a?(String)
- self[i] = FileSystemResolver.new(path)
+ self[i] = OptimizedFileSystemResolver.new(path)
end
end
end
diff --git a/actionpack/lib/action_view/template/error.rb b/actionpack/lib/action_view/template/error.rb
index e246646963..d4448a7b33 100644
--- a/actionpack/lib/action_view/template/error.rb
+++ b/actionpack/lib/action_view/template/error.rb
@@ -1,3 +1,4 @@
+require "active_support/core_ext/array/wrap"
require "active_support/core_ext/enumerable"
module ActionView
@@ -29,6 +30,7 @@ module ActionView
def initialize(paths, path, prefixes, partial, details, *)
@path = path
+ prefixes = Array.wrap(prefixes)
display_paths = paths.compact.map{ |p| p.to_s.inspect }.join(", ")
template_type = if partial
"partial"
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb
index 870897958a..2b9427ace5 100644
--- a/actionpack/lib/action_view/template/resolver.rb
+++ b/actionpack/lib/action_view/template/resolver.rb
@@ -10,17 +10,16 @@ module ActionView
attr_reader :name, :prefix, :partial, :virtual
alias_method :partial?, :partial
- def initialize(name, prefix, partial)
- @name, @prefix, @partial = name, prefix, partial
- rebuild(@name, @prefix, @partial)
+ def self.build(name, prefix, partial)
+ virtual = ""
+ virtual << "#{prefix}/" unless prefix.empty?
+ virtual << (partial ? "_#{name}" : name)
+ new name, prefix, partial, virtual
end
- def rebuild(name, prefix, partial)
- @virtual = ""
- @virtual << "#{prefix}/" unless prefix.empty?
- @virtual << (partial ? "_#{name}" : name)
-
- self.replace(@virtual)
+ def initialize(name, prefix, partial, virtual)
+ @name, @prefix, @partial = name, prefix, partial
+ super(virtual)
end
end
@@ -60,7 +59,7 @@ module ActionView
# Helpers that builds a path. Useful for building virtual paths.
def build_path(name, prefix, partial)
- Path.new(name, prefix, partial)
+ Path.build(name, prefix, partial)
end
# Handles templates caching. If a key is given and caching is on
@@ -112,7 +111,8 @@ module ActionView
end
end
- class PathResolver < Resolver
+ # An abstract class that implements a Resolver with path semantics.
+ class PathResolver < Resolver #:nodoc:
EXTENSIONS = [:locale, :formats, :handlers]
DEFAULT_PATTERN = ":prefix/:action{.:locale,}{.:formats,}{.:handlers,}"
@@ -124,13 +124,12 @@ module ActionView
private
def find_templates(name, prefix, partial, details)
- path = build_path(name, prefix, partial)
- extensions = Hash[EXTENSIONS.map { |ext| [ext, details[ext]] }.flatten(0)]
- query(path, extensions, details[:formats])
+ path = Path.build(name, prefix, partial)
+ query(path, details, details[:formats])
end
- def query(path, exts, formats)
- query = build_query(path, exts)
+ def query(path, details, formats)
+ query = build_query(path, details)
templates = []
sanitizer = Hash.new { |h,k| h[k] = Dir["#{File.dirname(k)}/*"] }
@@ -138,7 +137,7 @@ module ActionView
next if File.directory?(p) || !sanitizer[p].include?(p)
handler, format = extract_handler_and_format(p, formats)
- contents = File.open(p, "rb") {|io| io.read }
+ contents = File.open(p, "rb") { |io| io.read }
templates << Template.new(contents, File.expand_path(p), handler,
:virtual_path => path.virtual, :format => format, :updated_at => mtime(p))
@@ -147,18 +146,15 @@ module ActionView
templates
end
- # Helper for building query glob string based on resolver's pattern.
- def build_query(path, exts)
+ # Helper for building query glob string based on resolver's pattern.
+ def build_query(path, details)
query = @pattern.dup
query.gsub!(/\:prefix(\/)?/, path.prefix.empty? ? "" : "#{path.prefix}\\1") # prefix can be empty...
query.gsub!(/\:action/, path.partial? ? "_#{path.name}" : path.name)
- exts.each { |ext, variants|
+ details.each do |ext, variants|
query.gsub!(/\:#{ext}/, "{#{variants.compact.uniq.join(',')}}")
- }
-
- query.gsub!('.{html,', '.{html,text.html,')
- query.gsub!('.{text,', '.{text,text.plain,')
+ end
File.expand_path(query, @path)
end
@@ -235,9 +231,25 @@ module ActionView
alias :== :eql?
end
+ # An Optimized resolver for Rails' most common case.
+ class OptimizedFileSystemResolver < FileSystemResolver #:nodoc:
+ def build_query(path, details)
+ exts = EXTENSIONS.map { |ext| details[ext] }
+ query = File.join(@path, path)
+
+ exts.each do |ext|
+ query << "{"
+ ext.compact.each { |e| query << ".#{e}," }
+ query << "}"
+ end
+
+ query
+ end
+ end
+
# The same as FileSystemResolver but does not allow templates to store
# a virtual path since it is invalid for such resolvers.
- class FallbackFileSystemResolver < FileSystemResolver
+ class FallbackFileSystemResolver < FileSystemResolver #:nodoc:
def self.instances
[new(""), new("/")]
end
diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb
index 9c10decd60..0b4b0638b2 100644
--- a/actionpack/lib/sprockets/railtie.rb
+++ b/actionpack/lib/sprockets/railtie.rb
@@ -39,7 +39,7 @@ module Sprockets
end
end
- app.routes.append do
+ app.routes.prepend do
mount app.assets => assets.prefix
end
diff --git a/actionpack/test/controller/new_base/render_implicit_action_test.rb b/actionpack/test/controller/new_base/render_implicit_action_test.rb
index 3bb3016fdb..1e2191d417 100644
--- a/actionpack/test/controller/new_base/render_implicit_action_test.rb
+++ b/actionpack/test/controller/new_base/render_implicit_action_test.rb
@@ -33,10 +33,10 @@ module RenderImplicitAction
assert_status 200
end
- test "action_method? returns true for implicit actions" do
- assert SimpleController.new.action_method?(:hello_world)
- assert SimpleController.new.action_method?(:"hyphen-ated")
- assert SimpleController.new.action_method?(:not_implemented)
+ test "available_action? returns true for implicit actions" do
+ assert SimpleController.new.available_action?(:hello_world)
+ assert SimpleController.new.available_action?(:"hyphen-ated")
+ assert SimpleController.new.available_action?(:not_implemented)
end
end
end
diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb
index d128006404..25b1b4f745 100644
--- a/actionpack/test/dispatch/request_test.rb
+++ b/actionpack/test/dispatch/request_test.rb
@@ -358,6 +358,13 @@ class RequestTest < ActiveSupport::TestCase
assert request.head?
end
+ test "post masquerading as put" do
+ request = stub_request 'REQUEST_METHOD' => 'PUT', "rack.methodoverride.original_method" => "POST"
+ assert_equal "POST", request.method
+ assert_equal "PUT", request.request_method
+ assert request.put?
+ end
+
test "xml format" do
request = stub_request
request.expects(:parameters).at_least_once.returns({ :format => 'xml' })
diff --git a/actionpack/test/dispatch/show_exceptions_test.rb b/actionpack/test/dispatch/show_exceptions_test.rb
index cc57a6cba0..42f6c7f79f 100644
--- a/actionpack/test/dispatch/show_exceptions_test.rb
+++ b/actionpack/test/dispatch/show_exceptions_test.rb
@@ -131,11 +131,11 @@ class ShowExceptionsTest < ActionDispatch::IntegrationTest
'action_dispatch.request.parameters' => {
'action' => 'show',
'id' => 'unknown',
- 'controller' => 'featured_tiles'
+ 'controller' => 'featured_tile'
}
})
assert_response 500
- assert_match(/RuntimeError\n in FeaturedTilesController/, body)
+ assert_match(/RuntimeError\n in FeaturedTileController/, body)
end
test "sets the HTTP charset parameter" do
diff --git a/actionpack/test/template/capture_helper_test.rb b/actionpack/test/template/capture_helper_test.rb
index 592c7da060..a9157e711c 100644
--- a/actionpack/test/template/capture_helper_test.rb
+++ b/actionpack/test/template/capture_helper_test.rb
@@ -38,7 +38,15 @@ class CaptureHelperTest < ActionView::TestCase
assert_equal '&lt;em&gt;bar&lt;/em&gt;', string
end
- def test_content_for
+ def test_capture_used_for_read
+ content_for :foo, "foo"
+ assert_equal "foo", content_for(:foo)
+
+ content_for(:bar){ "bar" }
+ assert_equal "bar", content_for(:bar)
+ end
+
+ def test_content_for_question_mark
assert ! content_for?(:title)
content_for :title, 'title'
assert content_for?(:title)
@@ -49,14 +57,14 @@ class CaptureHelperTest < ActionView::TestCase
assert !content_for?(:title)
provide :title, "hi"
assert content_for?(:title)
- assert_equal "hi", @view_flow.get(:title)
+ assert_equal "hi", content_for(:title)
provide :title, "<p>title</p>"
- assert_equal "hi&lt;p&gt;title&lt;/p&gt;", @view_flow.get(:title)
+ assert_equal "hi&lt;p&gt;title&lt;/p&gt;", content_for(:title)
@view_flow = ActionView::OutputFlow.new
provide :title, "hi"
provide :title, "<p>title</p>".html_safe
- assert_equal "hi<p>title</p>", @view_flow.get(:title)
+ assert_equal "hi<p>title</p>", content_for(:title)
end
def test_with_output_buffer_swaps_the_output_buffer_given_no_argument
diff --git a/actionpack/test/template/date_helper_test.rb b/actionpack/test/template/date_helper_test.rb
index 12d2410f49..09c53a36f0 100644
--- a/actionpack/test/template/date_helper_test.rb
+++ b/actionpack/test/template/date_helper_test.rb
@@ -121,6 +121,10 @@ class DateHelperTest < ActionView::TestCase
start_date = Date.new 1975, 1, 31
end_date = Date.new 1977, 1, 31
assert_equal("about 2 years", distance_of_time_in_words(start_date, end_date))
+
+ start_date = Date.new 1982, 12, 3
+ end_date = Date.new 2010, 11, 30
+ assert_equal("almost 28 years", distance_of_time_in_words(start_date, end_date))
end
def test_distance_in_words_with_integers
@@ -416,6 +420,14 @@ class DateHelperTest < ActionView::TestCase
assert_dom_equal expected, select_hour(Time.mktime(2003, 8, 16, 8, 4, 18))
end
+ def test_select_hour_with_ampm
+ expected = %(<select id="date_hour" name="date[hour]">\n)
+ expected << %(<option value="00">12 AM</option>\n<option value="01">01 AM</option>\n<option value="02">02 AM</option>\n<option value="03">03 AM</option>\n<option value="04">04 AM</option>\n<option value="05">05 AM</option>\n<option value="06">06 AM</option>\n<option value="07">07 AM</option>\n<option value="08" selected="selected">08 AM</option>\n<option value="09">09 AM</option>\n<option value="10">10 AM</option>\n<option value="11">11 AM</option>\n<option value="12">12 PM</option>\n<option value="13">01 PM</option>\n<option value="14">02 PM</option>\n<option value="15">03 PM</option>\n<option value="16">04 PM</option>\n<option value="17">05 PM</option>\n<option value="18">06 PM</option>\n<option value="19">07 PM</option>\n<option value="20">08 PM</option>\n<option value="21">09 PM</option>\n<option value="22">10 PM</option>\n<option value="23">11 PM</option>\n)
+ expected << "</select>\n"
+
+ assert_dom_equal expected, select_hour(Time.mktime(2003, 8, 16, 8, 4, 18), :ampm => true)
+ end
+
def test_select_hour_with_disabled
expected = %(<select id="date_hour" name="date[hour]" disabled="disabled">\n)
expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n)
@@ -937,6 +949,35 @@ class DateHelperTest < ActionView::TestCase
assert_dom_equal expected, select_datetime(Time.mktime(2003, 8, 16, 8, 4, 18), :start_year => 2003, :end_year => 2005, :prefix => "date[first]")
end
+ def test_select_datetime_with_ampm
+ expected = %(<select id="date_first_year" name="date[first][year]">\n)
+ expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n)
+ expected << "</select>\n"
+
+ expected << %(<select id="date_first_month" name="date[first][month]">\n)
+ expected << %(<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n)
+ expected << "</select>\n"
+
+ expected << %(<select id="date_first_day" name="date[first][day]">\n)
+ expected << %(<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n)
+ expected << "</select>\n"
+
+ expected << " &mdash; "
+
+ expected << %(<select id="date_first_hour" name="date[first][hour]">\n)
+ expected << %(<option value="00">12 AM</option>\n<option value="01">01 AM</option>\n<option value="02">02 AM</option>\n<option value="03">03 AM</option>\n<option value="04">04 AM</option>\n<option value="05">05 AM</option>\n<option value="06">06 AM</option>\n<option value="07">07 AM</option>\n<option value="08" selected="selected">08 AM</option>\n<option value="09">09 AM</option>\n<option value="10">10 AM</option>\n<option value="11">11 AM</option>\n<option value="12">12 PM</option>\n<option value="13">01 PM</option>\n<option value="14">02 PM</option>\n<option value="15">03 PM</option>\n<option value="16">04 PM</option>\n<option value="17">05 PM</option>\n<option value="18">06 PM</option>\n<option value="19">07 PM</option>\n<option value="20">08 PM</option>\n<option value="21">09 PM</option>\n<option value="22">10 PM</option>\n<option value="23">11 PM</option>\n)
+ expected << "</select>\n"
+
+ expected << " : "
+
+ expected << %(<select id="date_first_minute" name="date[first][minute]">\n)
+ expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
+ expected << "</select>\n"
+
+ assert_dom_equal expected, select_datetime(Time.mktime(2003, 8, 16, 8, 4, 18), :start_year => 2003, :end_year => 2005, :prefix => "date[first]", :ampm => true)
+ end
+
+
def test_select_datetime_with_separators
expected = %(<select id="date_first_year" name="date[first][year]">\n)
expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n)
@@ -1136,6 +1177,24 @@ class DateHelperTest < ActionView::TestCase
assert_dom_equal expected, select_time(Time.mktime(2003, 8, 16, 8, 4, 18), :include_seconds => false)
end
+ def test_select_time_with_ampm
+ expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n)
+ expected << %(<input name="date[month]" id="date_month" value="8" type="hidden" />\n)
+ expected << %(<input name="date[day]" id="date_day" value="16" type="hidden" />\n)
+
+ expected << %(<select id="date_hour" name="date[hour]">\n)
+ expected << %(<option value="00">12 AM</option>\n<option value="01">01 AM</option>\n<option value="02">02 AM</option>\n<option value="03">03 AM</option>\n<option value="04">04 AM</option>\n<option value="05">05 AM</option>\n<option value="06">06 AM</option>\n<option value="07">07 AM</option>\n<option value="08" selected="selected">08 AM</option>\n<option value="09">09 AM</option>\n<option value="10">10 AM</option>\n<option value="11">11 AM</option>\n<option value="12">12 PM</option>\n<option value="13">01 PM</option>\n<option value="14">02 PM</option>\n<option value="15">03 PM</option>\n<option value="16">04 PM</option>\n<option value="17">05 PM</option>\n<option value="18">06 PM</option>\n<option value="19">07 PM</option>\n<option value="20">08 PM</option>\n<option value="21">09 PM</option>\n<option value="22">10 PM</option>\n<option value="23">11 PM</option>\n)
+ expected << "</select>\n"
+
+ expected << " : "
+
+ expected << %(<select id="date_minute" name="date[minute]">\n)
+ expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
+ expected << "</select>\n"
+
+ assert_dom_equal expected, select_time(Time.mktime(2003, 8, 16, 8, 4, 18), :include_seconds => false, :ampm => true)
+ end
+
def test_select_time_with_separator
expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n)
expected << %(<input name="date[month]" id="date_month" value="8" type="hidden" />\n)
diff --git a/actionpack/test/template/html-scanner/sanitizer_test.rb b/actionpack/test/template/html-scanner/sanitizer_test.rb
index fcc3782f04..678cb9eeeb 100644
--- a/actionpack/test/template/html-scanner/sanitizer_test.rb
+++ b/actionpack/test/template/html-scanner/sanitizer_test.rb
@@ -20,6 +20,7 @@ class SanitizerTest < ActionController::TestCase
assert_equal "This has a here.", sanitizer.sanitize("This has a <![CDATA[<section>]]> here.")
assert_equal "This has an unclosed ", sanitizer.sanitize("This has an unclosed <![CDATA[<section>]] here...")
[nil, '', ' '].each { |blank| assert_equal blank, sanitizer.sanitize(blank) }
+ assert_nothing_raised { sanitizer.sanitize("This is a frozen string with no tags".freeze) }
end
def test_strip_links
diff --git a/actionpack/test/template/lookup_context_test.rb b/actionpack/test/template/lookup_context_test.rb
index 5fb1fdc044..47b70f05ab 100644
--- a/actionpack/test/template/lookup_context_test.rb
+++ b/actionpack/test/template/lookup_context_test.rb
@@ -51,6 +51,11 @@ class LookupContextTest < ActiveSupport::TestCase
assert_equal Mime::SET, @lookup_context.formats
end
+ test "handles explicitly defined */* formats fallback to :js" do
+ @lookup_context.formats = [:js, Mime::ALL]
+ assert_equal [:js, *Mime::SET.symbols], @lookup_context.formats
+ end
+
test "adds :html fallback to :js formats" do
@lookup_context.formats = [:js]
assert_equal [:js, :html], @lookup_context.formats
@@ -251,4 +256,13 @@ class TestMissingTemplate < ActiveSupport::TestCase
end
assert_match %r{Missing partial parent/foo, child/foo with .* Searched in:\n \* "/Path/to/views"\n}, e.message
end
+
+ test "if a single prefix is passed as a string and the lookup fails, MissingTemplate accepts it" do
+ e = assert_raise ActionView::MissingTemplate do
+ details = {:handlers=>[], :formats=>[], :locale=>[]}
+ @lookup_context.view_paths.find("foo", "parent", true, details)
+ end
+ assert_match %r{Missing partial parent/foo with .* Searched in:\n \* "/Path/to/views"\n}, e.message
+ end
+
end
diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb
index d4e912c410..86d08a43a5 100644
--- a/actionpack/test/template/render_test.rb
+++ b/actionpack/test/template/render_test.rb
@@ -325,7 +325,7 @@ class CachedViewRenderTest < ActiveSupport::TestCase
# Ensure view path cache is primed
def setup
view_paths = ActionController::Base.view_paths
- assert_equal ActionView::FileSystemResolver, view_paths.first.class
+ assert_equal ActionView::OptimizedFileSystemResolver, view_paths.first.class
setup_view(view_paths)
end